diff --git a/whisper/whisperv5/api.go b/whisper/whisperv5/api.go index 9de29a6fee..1093906a39 100644 --- a/whisper/whisperv5/api.go +++ b/whisper/whisperv5/api.go @@ -224,35 +224,30 @@ func (api *PublicWhisperAPI) Subscribe(args WhisperFilterArgs) (string, error) { filter.Topics = append(filter.Topics, args.Topics...) + err := ValidateKeyID(args.Key) + if err != nil { + info := "NewFilter: " + err.Error() + log.Error(info) + return "", errors.New(info) + } + if len(args.SignedWith) > 0 { if !ValidatePublicKey(filter.Src) { - info := "NewFilter: Invalid 'From' address" + info := "NewFilter: Invalid 'SignedWith' field" log.Error(info) return "", errors.New(info) } } - err := ValidateKeyID(args.Key) - if err != nil { - return "", err - } - - if !ValidatePublicKey(filter.Src) { - info := "NewFilter: 'SignedWith' public key is invalid" - log.Error(info) - return "", errors.New(info) - } - if args.Symmetric { if len(args.Topics) == 0 { info := "NewFilter: at least one topic must be specified with symmetric encryption" log.Error(info) return "", errors.New(info) } - symKey, err := api.whisper.GetSymKey(args.Key) if err != nil { - info := "NewFilter: invalid key ID: " + args.Key + info := "NewFilter: invalid key ID" log.Error(info) return "", errors.New(info) } @@ -267,7 +262,7 @@ func (api *PublicWhisperAPI) Subscribe(args WhisperFilterArgs) (string, error) { } else { filter.KeyAsym, err = api.whisper.GetPrivateKey(args.Key) if err != nil { - info := "NewFilter: invalid key ID: " + args.Key + info := "NewFilter: invalid key ID" log.Error(info) return "", errors.New(info) } @@ -326,6 +321,12 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { Padding: args.Padding, } + if len(args.Key) == 0 { + info := "Post: key is missing" + log.Error(info) + return errors.New(info) + } + if len(args.SignWith) > 0 { params.Src, err = api.whisper.GetPrivateKey(args.SignWith) if err != nil { @@ -358,6 +359,11 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { log.Error(err.Error()) return err } + if !validateSymmetricKey(params.KeySym) { + info := "Post: key for symmetric encryption is invalid" + log.Error(info) + return errors.New(info) + } if len(params.Topic) == 0 { info := "Post: topic is missing for symmetric encryption" log.Error(info) @@ -366,7 +372,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { } else if args.Type == "asym" { params.Dst = crypto.ToECDSAPub(common.FromHex(args.Key)) if !ValidatePublicKey(params.Dst) { - info := "NewFilter: 'SignWith' public key is invalid" + info := "Post: public key for asymmetric encryption is invalid" log.Error(info) return errors.New(info) } diff --git a/whisper/whisperv5/api_test.go b/whisper/whisperv5/api_test.go index 558f125446..e9df3f9a53 100644 --- a/whisper/whisperv5/api_test.go +++ b/whisper/whisperv5/api_test.go @@ -323,6 +323,11 @@ func TestIntegrationAsym(t *testing.T) { t.Fatalf("failed HasIdentity: false negative.") } + sigPubKey, err := api.GetPublicKey(sig) + if err != nil { + t.Fatalf("failed GetPublicKey: %s.", err) + } + key, err := api.NewKeyPair() if err != nil { t.Fatalf("failed NewIdentity(): %s.", err) @@ -331,13 +336,18 @@ func TestIntegrationAsym(t *testing.T) { t.Fatalf("wrong key") } + dstPubKey, err := api.GetPublicKey(key) + if err != nil { + t.Fatalf("failed GetPublicKey: %s.", err) + } + var topics [2]TopicType topics[0] = TopicType{0x00, 0x64, 0x00, 0xff} topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79} var f WhisperFilterArgs f.Symmetric = false f.Key = key - f.SignedWith = sig + f.SignedWith = sigPubKey f.Topics = topics[:] f.MinPoW = DefaultMinimumPoW / 2 f.AllowP2P = true @@ -348,9 +358,10 @@ func TestIntegrationAsym(t *testing.T) { } var p PostArgs + p.Type = "asym" p.TTL = 2 - p.SignWith = f.SignedWith - p.Key = f.Key + p.SignWith = sig + p.Key = dstPubKey p.Padding = []byte("test string") p.Payload = []byte("extended test string") p.PowTarget = DefaultMinimumPoW @@ -407,12 +418,17 @@ func TestIntegrationSym(t *testing.T) { sig, err := api.NewKeyPair() if err != nil { - t.Fatalf("failed NewIdentity: %s.", err) + t.Fatalf("failed NewKeyPair: %s.", err) } if len(sig) == 0 { t.Fatalf("wrong signature") } + sigPubKey, err := api.GetPublicKey(sig) + if err != nil { + t.Fatalf("failed GetPublicKey: %s.", err) + } + exist, err := api.HasKeyPair(sig) if err != nil { t.Fatalf("failed HasIdentity: %s.", err) @@ -429,7 +445,7 @@ func TestIntegrationSym(t *testing.T) { f.Key = symKeyID f.Topics = topics[:] f.MinPoW = 0.324 - f.SignedWith = sig + f.SignedWith = sigPubKey f.AllowP2P = false id, err := api.Subscribe(f) @@ -441,7 +457,7 @@ func TestIntegrationSym(t *testing.T) { p.Type = "sym" p.TTL = 1 p.Key = symKeyID - p.SignWith = f.SignedWith + p.SignWith = sig p.Padding = []byte("test string") p.Payload = []byte("extended test string") p.PowTarget = DefaultMinimumPoW @@ -536,6 +552,7 @@ func TestIntegrationSymWithFilter(t *testing.T) { var p PostArgs p.Type = "sym" p.TTL = 1 + p.Key = symKeyID p.SignWith = sigKeyID p.Padding = []byte("test string") p.Payload = []byte("extended test string") diff --git a/whisper/whisperv5/whisper.go b/whisper/whisperv5/whisper.go index 42cca2ee12..e4637dc6ad 100644 --- a/whisper/whisperv5/whisper.go +++ b/whisper/whisperv5/whisper.go @@ -50,9 +50,8 @@ type Whisper struct { filters *Filters privateKeys map[string]*ecdsa.PrivateKey - //identities map[string]*ecdsa.PrivateKey - symKeys map[string][]byte - keyMu sync.RWMutex + symKeys map[string][]byte + keyMu sync.RWMutex envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node expirations map[uint32]*set.SetNonTS // Message expiration pool @@ -238,13 +237,13 @@ func (w *Whisper) HasKeyPair(id string) bool { return w.privateKeys[id] != nil } -// GetIdentity retrieves the private key of the specified public identity. -func (w *Whisper) GetPrivateKey(pubKey string) (*ecdsa.PrivateKey, error) { +// GetIdentity retrieves the private key of the specified identity. +func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { w.keyMu.RLock() defer w.keyMu.RUnlock() - key := w.privateKeys[pubKey] + key := w.privateKeys[id] if key == nil { - return nil, fmt.Errorf("invalid id") + return nil, fmt.Errorf("GetPrivateKey: invalid id") } return key, nil } @@ -367,7 +366,7 @@ func (w *Whisper) GetFilter(id string) *Filter { func (w *Whisper) Unsubscribe(id string) error { ok := w.filters.Uninstall(id) if !ok { - return fmt.Errorf("Invalid ID") + return fmt.Errorf("Unsubscribe: Invalid ID") } return nil } @@ -722,8 +721,9 @@ func (s *Statistics) reset() { } func ValidateKeyID(id string) error { - if len(id) != keyIdSize*2 { - return fmt.Errorf("Wrong size of key ID") + const target = keyIdSize * 2 + if len(id) != target { + return fmt.Errorf("Wrong size of key ID (expected %d bytes, got %d)", target, len(id)) } return nil }