whisper: big refactoring complete

This commit is contained in:
Vlad 2017-03-05 12:07:54 +01:00
parent a25228a27c
commit cd1c987c92
3 changed files with 55 additions and 32 deletions

View file

@ -224,35 +224,30 @@ func (api *PublicWhisperAPI) Subscribe(args WhisperFilterArgs) (string, error) {
filter.Topics = append(filter.Topics, args.Topics...) 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 len(args.SignedWith) > 0 {
if !ValidatePublicKey(filter.Src) { if !ValidatePublicKey(filter.Src) {
info := "NewFilter: Invalid 'From' address" info := "NewFilter: Invalid 'SignedWith' field"
log.Error(info) log.Error(info)
return "", errors.New(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 args.Symmetric {
if len(args.Topics) == 0 { if len(args.Topics) == 0 {
info := "NewFilter: at least one topic must be specified with symmetric encryption" info := "NewFilter: at least one topic must be specified with symmetric encryption"
log.Error(info) log.Error(info)
return "", errors.New(info) return "", errors.New(info)
} }
symKey, err := api.whisper.GetSymKey(args.Key) symKey, err := api.whisper.GetSymKey(args.Key)
if err != nil { if err != nil {
info := "NewFilter: invalid key ID: " + args.Key info := "NewFilter: invalid key ID"
log.Error(info) log.Error(info)
return "", errors.New(info) return "", errors.New(info)
} }
@ -267,7 +262,7 @@ func (api *PublicWhisperAPI) Subscribe(args WhisperFilterArgs) (string, error) {
} else { } else {
filter.KeyAsym, err = api.whisper.GetPrivateKey(args.Key) filter.KeyAsym, err = api.whisper.GetPrivateKey(args.Key)
if err != nil { if err != nil {
info := "NewFilter: invalid key ID: " + args.Key info := "NewFilter: invalid key ID"
log.Error(info) log.Error(info)
return "", errors.New(info) return "", errors.New(info)
} }
@ -326,6 +321,12 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
Padding: args.Padding, 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 { if len(args.SignWith) > 0 {
params.Src, err = api.whisper.GetPrivateKey(args.SignWith) params.Src, err = api.whisper.GetPrivateKey(args.SignWith)
if err != nil { if err != nil {
@ -358,6 +359,11 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
log.Error(err.Error()) log.Error(err.Error())
return err 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 { if len(params.Topic) == 0 {
info := "Post: topic is missing for symmetric encryption" info := "Post: topic is missing for symmetric encryption"
log.Error(info) log.Error(info)
@ -366,7 +372,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
} else if args.Type == "asym" { } else if args.Type == "asym" {
params.Dst = crypto.ToECDSAPub(common.FromHex(args.Key)) params.Dst = crypto.ToECDSAPub(common.FromHex(args.Key))
if !ValidatePublicKey(params.Dst) { if !ValidatePublicKey(params.Dst) {
info := "NewFilter: 'SignWith' public key is invalid" info := "Post: public key for asymmetric encryption is invalid"
log.Error(info) log.Error(info)
return errors.New(info) return errors.New(info)
} }

View file

@ -323,6 +323,11 @@ func TestIntegrationAsym(t *testing.T) {
t.Fatalf("failed HasIdentity: false negative.") t.Fatalf("failed HasIdentity: false negative.")
} }
sigPubKey, err := api.GetPublicKey(sig)
if err != nil {
t.Fatalf("failed GetPublicKey: %s.", err)
}
key, err := api.NewKeyPair() key, err := api.NewKeyPair()
if err != nil { if err != nil {
t.Fatalf("failed NewIdentity(): %s.", err) t.Fatalf("failed NewIdentity(): %s.", err)
@ -331,13 +336,18 @@ func TestIntegrationAsym(t *testing.T) {
t.Fatalf("wrong key") t.Fatalf("wrong key")
} }
dstPubKey, err := api.GetPublicKey(key)
if err != nil {
t.Fatalf("failed GetPublicKey: %s.", err)
}
var topics [2]TopicType var topics [2]TopicType
topics[0] = TopicType{0x00, 0x64, 0x00, 0xff} topics[0] = TopicType{0x00, 0x64, 0x00, 0xff}
topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79} topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
var f WhisperFilterArgs var f WhisperFilterArgs
f.Symmetric = false f.Symmetric = false
f.Key = key f.Key = key
f.SignedWith = sig f.SignedWith = sigPubKey
f.Topics = topics[:] f.Topics = topics[:]
f.MinPoW = DefaultMinimumPoW / 2 f.MinPoW = DefaultMinimumPoW / 2
f.AllowP2P = true f.AllowP2P = true
@ -348,9 +358,10 @@ func TestIntegrationAsym(t *testing.T) {
} }
var p PostArgs var p PostArgs
p.Type = "asym"
p.TTL = 2 p.TTL = 2
p.SignWith = f.SignedWith p.SignWith = sig
p.Key = f.Key p.Key = dstPubKey
p.Padding = []byte("test string") p.Padding = []byte("test string")
p.Payload = []byte("extended test string") p.Payload = []byte("extended test string")
p.PowTarget = DefaultMinimumPoW p.PowTarget = DefaultMinimumPoW
@ -407,12 +418,17 @@ func TestIntegrationSym(t *testing.T) {
sig, err := api.NewKeyPair() sig, err := api.NewKeyPair()
if err != nil { if err != nil {
t.Fatalf("failed NewIdentity: %s.", err) t.Fatalf("failed NewKeyPair: %s.", err)
} }
if len(sig) == 0 { if len(sig) == 0 {
t.Fatalf("wrong signature") t.Fatalf("wrong signature")
} }
sigPubKey, err := api.GetPublicKey(sig)
if err != nil {
t.Fatalf("failed GetPublicKey: %s.", err)
}
exist, err := api.HasKeyPair(sig) exist, err := api.HasKeyPair(sig)
if err != nil { if err != nil {
t.Fatalf("failed HasIdentity: %s.", err) t.Fatalf("failed HasIdentity: %s.", err)
@ -429,7 +445,7 @@ func TestIntegrationSym(t *testing.T) {
f.Key = symKeyID f.Key = symKeyID
f.Topics = topics[:] f.Topics = topics[:]
f.MinPoW = 0.324 f.MinPoW = 0.324
f.SignedWith = sig f.SignedWith = sigPubKey
f.AllowP2P = false f.AllowP2P = false
id, err := api.Subscribe(f) id, err := api.Subscribe(f)
@ -441,7 +457,7 @@ func TestIntegrationSym(t *testing.T) {
p.Type = "sym" p.Type = "sym"
p.TTL = 1 p.TTL = 1
p.Key = symKeyID p.Key = symKeyID
p.SignWith = f.SignedWith p.SignWith = sig
p.Padding = []byte("test string") p.Padding = []byte("test string")
p.Payload = []byte("extended test string") p.Payload = []byte("extended test string")
p.PowTarget = DefaultMinimumPoW p.PowTarget = DefaultMinimumPoW
@ -536,6 +552,7 @@ func TestIntegrationSymWithFilter(t *testing.T) {
var p PostArgs var p PostArgs
p.Type = "sym" p.Type = "sym"
p.TTL = 1 p.TTL = 1
p.Key = symKeyID
p.SignWith = sigKeyID p.SignWith = sigKeyID
p.Padding = []byte("test string") p.Padding = []byte("test string")
p.Payload = []byte("extended test string") p.Payload = []byte("extended test string")

View file

@ -50,9 +50,8 @@ type Whisper struct {
filters *Filters filters *Filters
privateKeys map[string]*ecdsa.PrivateKey privateKeys map[string]*ecdsa.PrivateKey
//identities map[string]*ecdsa.PrivateKey symKeys map[string][]byte
symKeys map[string][]byte keyMu sync.RWMutex
keyMu sync.RWMutex
envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node
expirations map[uint32]*set.SetNonTS // Message expiration pool expirations map[uint32]*set.SetNonTS // Message expiration pool
@ -238,13 +237,13 @@ func (w *Whisper) HasKeyPair(id string) bool {
return w.privateKeys[id] != nil return w.privateKeys[id] != nil
} }
// GetIdentity retrieves the private key of the specified public identity. // GetIdentity retrieves the private key of the specified identity.
func (w *Whisper) GetPrivateKey(pubKey string) (*ecdsa.PrivateKey, error) { func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
w.keyMu.RLock() w.keyMu.RLock()
defer w.keyMu.RUnlock() defer w.keyMu.RUnlock()
key := w.privateKeys[pubKey] key := w.privateKeys[id]
if key == nil { if key == nil {
return nil, fmt.Errorf("invalid id") return nil, fmt.Errorf("GetPrivateKey: invalid id")
} }
return key, nil return key, nil
} }
@ -367,7 +366,7 @@ func (w *Whisper) GetFilter(id string) *Filter {
func (w *Whisper) Unsubscribe(id string) error { func (w *Whisper) Unsubscribe(id string) error {
ok := w.filters.Uninstall(id) ok := w.filters.Uninstall(id)
if !ok { if !ok {
return fmt.Errorf("Invalid ID") return fmt.Errorf("Unsubscribe: Invalid ID")
} }
return nil return nil
} }
@ -722,8 +721,9 @@ func (s *Statistics) reset() {
} }
func ValidateKeyID(id string) error { func ValidateKeyID(id string) error {
if len(id) != keyIdSize*2 { const target = keyIdSize * 2
return fmt.Errorf("Wrong size of key ID") if len(id) != target {
return fmt.Errorf("Wrong size of key ID (expected %d bytes, got %d)", target, len(id))
} }
return nil return nil
} }