Apply 0014-whisperv6-notifications patches to status-go/whisper module

This commit is contained in:
Dmitry 2018-09-24 10:39:02 +03:00
parent 4d5a3acbfd
commit 536333e998
2 changed files with 121 additions and 8 deletions

View File

@ -316,6 +316,16 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (hexutil.
return result, err
}
// UninstallFilter is alias for Unsubscribe
func (api *PublicWhisperAPI) UninstallFilter(id string) {
api.w.Unsubscribe(id)
}
// Unsubscribe disables and removes an existing filter.
func (api *PublicWhisperAPI) Unsubscribe(id string) {
api.w.Unsubscribe(id)
}
//go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go
// Criteria holds various filter options for inbound messages.

View File

@ -408,9 +408,9 @@ func (whisper *Whisper) NewKeyPair() (string, error) {
return "", fmt.Errorf("failed to generate valid key")
}
id, err := GenerateRandomID()
id, err := toDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize)
if err != nil {
return "", fmt.Errorf("failed to generate ID: %s", err)
return "", err
}
whisper.keyMu.Lock()
@ -425,11 +425,16 @@ func (whisper *Whisper) NewKeyPair() (string, error) {
// DeleteKeyPair deletes the specified key if it exists.
func (whisper *Whisper) DeleteKeyPair(key string) bool {
deterministicID, err := toDeterministicID(key, keyIDSize)
if err != nil {
return false
}
whisper.keyMu.Lock()
defer whisper.keyMu.Unlock()
if whisper.privateKeys[key] != nil {
delete(whisper.privateKeys, key)
if whisper.privateKeys[deterministicID] != nil {
delete(whisper.privateKeys, deterministicID)
return true
}
return false
@ -437,31 +442,73 @@ func (whisper *Whisper) DeleteKeyPair(key string) bool {
// AddKeyPair imports a asymmetric private key and returns it identifier.
func (whisper *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
id, err := GenerateRandomID()
id, err := makeDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize)
if err != nil {
return "", fmt.Errorf("failed to generate ID: %s", err)
return "", err
}
if whisper.HasKeyPair(id) {
return id, nil // no need to re-inject
}
whisper.keyMu.Lock()
whisper.privateKeys[id] = key
whisper.keyMu.Unlock()
log.Info("Whisper identity added", "id", id, "pubkey", common.ToHex(crypto.FromECDSAPub(&key.PublicKey)))
return id, nil
}
// SelectKeyPair adds cryptographic identity, and makes sure
// that it is the only private key known to the node.
func (whisper *Whisper) SelectKeyPair(key *ecdsa.PrivateKey) error {
id, err := makeDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIDSize)
if err != nil {
return err
}
whisper.keyMu.Lock()
defer whisper.keyMu.Unlock()
whisper.privateKeys = make(map[string]*ecdsa.PrivateKey) // reset key store
whisper.privateKeys[id] = key
log.Info("Whisper identity selected", "id", id, "key", common.ToHex(crypto.FromECDSAPub(&key.PublicKey)))
return nil
}
// DeleteKeyPairs removes all cryptographic identities known to the node
func (whisper *Whisper) DeleteKeyPairs() error {
whisper.keyMu.Lock()
defer whisper.keyMu.Unlock()
whisper.privateKeys = make(map[string]*ecdsa.PrivateKey)
return nil
}
// HasKeyPair checks if the whisper node is configured with the private key
// of the specified public pair.
func (whisper *Whisper) HasKeyPair(id string) bool {
deterministicID, err := toDeterministicID(id, keyIDSize)
if err != nil {
return false
}
whisper.keyMu.RLock()
defer whisper.keyMu.RUnlock()
return whisper.privateKeys[id] != nil
return whisper.privateKeys[deterministicID] != nil
}
// GetPrivateKey retrieves the private key of the specified identity.
func (whisper *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
deterministicID, err := toDeterministicID(id, keyIDSize)
if err != nil {
return nil, err
}
whisper.keyMu.RLock()
defer whisper.keyMu.RUnlock()
key := whisper.privateKeys[id]
key := whisper.privateKeys[deterministicID]
if key == nil {
return nil, fmt.Errorf("invalid id")
}
@ -493,6 +540,23 @@ func (whisper *Whisper) GenerateSymKey() (string, error) {
return id, nil
}
// AddSymKey stores the key with a given id.
func (whisper *Whisper) AddSymKey(id string, key []byte) (string, error) {
deterministicID, err := toDeterministicID(id, keyIDSize)
if err != nil {
return "", err
}
whisper.keyMu.Lock()
defer whisper.keyMu.Unlock()
if whisper.symKeys[deterministicID] != nil {
return "", fmt.Errorf("key already exists: %v", id)
}
whisper.symKeys[deterministicID] = key
return deterministicID, nil
}
// AddSymKeyDirect stores the key, and returns its id.
func (whisper *Whisper) AddSymKeyDirect(key []byte) (string, error) {
if len(key) != aesKeyLength {
@ -1039,6 +1103,33 @@ func GenerateRandomID() (id string, err error) {
return id, err
}
// makeDeterministicID generates a deterministic ID, based on a given input
func makeDeterministicID(input string, keyLen int) (id string, err error) {
buf := pbkdf2.Key([]byte(input), nil, 4096, keyLen, sha256.New)
if !validateDataIntegrity(buf, keyIDSize) {
return "", fmt.Errorf("error in GenerateDeterministicID: failed to generate key")
}
id = common.Bytes2Hex(buf)
return id, err
}
// toDeterministicID reviews incoming id, and transforms it to format
// expected internally be private key store. Originally, public keys
// were used as keys, now random keys are being used. And in order to
// make it easier to consume, we now allow both random IDs and public
// keys to be passed.
func toDeterministicID(id string, expectedLen int) (string, error) {
if len(id) != (expectedLen * 2) { // we received hex key, so number of chars in id is doubled
var err error
id, err = makeDeterministicID(id, expectedLen)
if err != nil {
return "", err
}
}
return id, nil
}
func isFullNode(bloom []byte) bool {
if bloom == nil {
return true
@ -1074,3 +1165,15 @@ func addBloom(a, b []byte) []byte {
}
return c
}
// SelectedKeyPairID returns the id of currently selected key pair.
// It helps distinguish between different users w/o exposing the user identity itself.
func (whisper *Whisper) SelectedKeyPairID() string {
whisper.keyMu.RLock()
defer whisper.keyMu.RUnlock()
for id := range whisper.privateKeys {
return id
}
return ""
}