status-go/_assets/patches/geth/0004-whisper-notifications....

221 lines
6.8 KiB
Diff

diff --git a/whisper/whisperv2/whisper.go b/whisper/whisperv2/whisper.go
index 61c36918d..908346999 100644
--- a/whisper/whisperv2/whisper.go
+++ b/whisper/whisperv2/whisper.go
@@ -134,6 +134,13 @@ func (self *Whisper) NewIdentity() *ecdsa.PrivateKey {
return key
}
+// AddIdentity adds identity into the known identities list (for message decryption).
+func (self *Whisper) AddIdentity(key *ecdsa.PrivateKey) {
+ self.keysMu.Lock()
+ self.keys[string(crypto.FromECDSAPub(&key.PublicKey))] = key
+ self.keysMu.Unlock()
+}
+
// HasIdentity checks if the the whisper node is configured with the private key
// of the specified public pair.
func (self *Whisper) HasIdentity(key *ecdsa.PublicKey) bool {
diff --git a/whisper/whisperv5/api.go b/whisper/whisperv5/api.go
index 96c4b0e6c..e3c2f4a97 100644
--- a/whisper/whisperv5/api.go
+++ b/whisper/whisperv5/api.go
@@ -313,6 +313,16 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er
return true, api.w.Send(env)
}
+// 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.
diff --git a/whisper/whisperv5/whisper.go b/whisper/whisperv5/whisper.go
index 85849ccce..c39e8b3e0 100644
--- a/whisper/whisperv5/whisper.go
+++ b/whisper/whisperv5/whisper.go
@@ -250,9 +256,9 @@ func (w *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
}
w.keyMu.Lock()
@@ -265,45 +271,94 @@ func (w *Whisper) NewKeyPair() (string, error) {
return id, nil
}
-// DeleteKeyPair deletes the specified key if it exists.
-func (w *Whisper) DeleteKeyPair(key string) bool {
+// AddIdentity adds cryptographic identity into the known
+// identities list (for message decryption).
+func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
+ id, err := makeDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIdSize)
+ if err != nil {
+ return "", err
+ }
+ if w.HasKeyPair(id) {
+ return id, nil // no need to re-inject
+ }
+
w.keyMu.Lock()
defer w.keyMu.Unlock()
- if w.privateKeys[key] != nil {
- delete(w.privateKeys, key)
- return true
- }
- return false
+ w.privateKeys[id] = key
+ log.Info("Whisper identity added", "id", id, "pubkey", common.ToHex(crypto.FromECDSAPub(&key.PublicKey)))
+
+ return id, nil
}
-// AddKeyPair imports a asymmetric private key and returns it identifier.
-func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
- id, err := GenerateRandomID()
+// SelectKeyPair adds cryptographic identity, and makes sure
+// that it is the only private key known to the node.
+func (w *Whisper) SelectKeyPair(key *ecdsa.PrivateKey) error {
+ id, err := makeDeterministicID(common.ToHex(crypto.FromECDSAPub(&key.PublicKey)), keyIdSize)
if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
+ return err
}
w.keyMu.Lock()
+ defer w.keyMu.Unlock()
+
+ w.privateKeys = make(map[string]*ecdsa.PrivateKey) // reset key store
w.privateKeys[id] = key
- w.keyMu.Unlock()
- return id, nil
+ 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 (w *Whisper) DeleteKeyPairs() error {
+ w.keyMu.Lock()
+ defer w.keyMu.Unlock()
+
+ w.privateKeys = make(map[string]*ecdsa.PrivateKey)
+
+ return nil
+}
+
+// DeleteKeyPair deletes the specified key if it exists.
+func (w *Whisper) DeleteKeyPair(id string) bool {
+ deterministicID, err := toDeterministicID(id, keyIdSize)
+ if err != nil {
+ return false
+ }
+
+ w.keyMu.Lock()
+ defer w.keyMu.Unlock()
+
+ if w.privateKeys[deterministicID] != nil {
+ delete(w.privateKeys, deterministicID)
+ return true
+ }
+ return false
}
// HasKeyPair checks if the the whisper node is configured with the private key
// of the specified public pair.
func (w *Whisper) HasKeyPair(id string) bool {
+ deterministicID, err := toDeterministicID(id, keyIdSize)
+ if err != nil {
+ return false
+ }
+
w.keyMu.RLock()
defer w.keyMu.RUnlock()
- return w.privateKeys[id] != nil
+ return w.privateKeys[deterministicID] != nil
}
// GetPrivateKey retrieves the private key of the specified identity.
func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
+ deterministicID, err := toDeterministicID(id, keyIdSize)
+ if err != nil {
+ return nil, err
+ }
+
w.keyMu.RLock()
defer w.keyMu.RUnlock()
- key := w.privateKeys[id]
+ key := w.privateKeys[deterministicID]
if key == nil {
return nil, fmt.Errorf("invalid id")
}
@@ -336,6 +391,23 @@ func (w *Whisper) GenerateSymKey() (string, error) {
return id, nil
}
+// AddSymKey stores the key with a given id.
+func (w *Whisper) AddSymKey(id string, key []byte) (string, error) {
+ deterministicID, err := toDeterministicID(id, keyIdSize)
+ if err != nil {
+ return "", err
+ }
+
+ w.keyMu.Lock()
+ defer w.keyMu.Unlock()
+
+ if w.symKeys[deterministicID] != nil {
+ return "", fmt.Errorf("key already exists: %v", id)
+ }
+ w.symKeys[deterministicID] = key
+ return deterministicID, nil
+}
+
// AddSymKeyDirect stores the key, and returns its id.
func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
if len(key) != aesKeyLength {
@@ -856,3 +941,30 @@ func GenerateRandomID() (id string, err error) {
id = common.Bytes2Hex(buf)
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 !validateSymmetricKey(buf) {
+ 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
+}