diff --git a/swarm/pss/api.go b/swarm/pss/api.go index 587382d729..17e483d256 100644 --- a/swarm/pss/api.go +++ b/swarm/pss/api.go @@ -157,14 +157,23 @@ func (pssapi *API) StringToTopic(topicstring string) (Topic, error) { } func (pssapi *API) SendAsym(pubkeyhex string, topic Topic, msg hexutil.Bytes) error { + if !checkMsg(msg) { + return errors.New("invalid message") + } return pssapi.Pss.SendAsym(pubkeyhex, topic, msg[:]) } func (pssapi *API) SendSym(symkeyhex string, topic Topic, msg hexutil.Bytes) error { + if !checkMsg(msg) { + return errors.New("invalid message") + } return pssapi.Pss.SendSym(symkeyhex, topic, msg[:]) } func (pssapi *API) SendRaw(addr hexutil.Bytes, topic Topic, msg hexutil.Bytes) error { + if !checkMsg(msg) { + return errors.New("invalid message") + } return pssapi.Pss.SendRaw(PssAddress(addr), topic, msg[:]) } @@ -177,3 +186,10 @@ func (pssapi *API) GetPeerTopics(pubkeyhex string) ([]Topic, error) { func (pssapi *API) GetPeerAddress(pubkeyhex string, topic Topic) (PssAddress, error) { return pssapi.Pss.getPeerAddress(pubkeyhex, topic) } + +func checkMsg(msg []byte) bool { + if msg == nil || len(msg) == 0 { + return false + } + return true +} diff --git a/swarm/pss/pss.go b/swarm/pss/pss.go index d0986d280b..40bb408fa4 100644 --- a/swarm/pss/pss.go +++ b/swarm/pss/pss.go @@ -396,9 +396,11 @@ func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error { // raw is simplest handler contingency to check, so check that first var isRaw bool if pssmsg.isRaw() { - if !p.topicHandlerCaps[psstopic].raw { - log.Debug("No handler for raw message", "topic", psstopic) - return nil + if _, ok := p.topicHandlerCaps[psstopic]; ok { + if !p.topicHandlerCaps[psstopic].raw { + log.Debug("No handler for raw message", "topic", psstopic) + return nil + } } isRaw = true } @@ -529,6 +531,9 @@ func (p *Pss) isSelfPossibleRecipient(msg *PssMsg, prox bool) bool { // The value in `address` will be used as a routing hint for the // public key / topic association func (p *Pss) SetPeerPublicKey(pubkey *ecdsa.PublicKey, topic Topic, address *PssAddress) error { + if !checkAddress(address) { + return errors.New("invalid address") + } pubkeybytes := crypto.FromECDSAPub(pubkey) if len(pubkeybytes) == 0 { return fmt.Errorf("invalid public key: %v", pubkey) @@ -570,6 +575,9 @@ func (p *Pss) GenerateSymmetricKey(topic Topic, address *PssAddress, addToCache // Returns a string id that can be used to retrieve the key bytes // from the whisper backend (see pss.GetSymmetricKey()) func (p *Pss) SetSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool) (string, error) { + if !checkAddress(address) { + return "", errors.New("invalid address") + } return p.setSymmetricKey(key, topic, address, addtocache, true) } @@ -770,8 +778,10 @@ func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error { // if we have a proxhandler on this topic // also deliver message to ourselves - if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic].prox { - return p.process(pssMsg, true, true) + if _, ok := p.topicHandlerCaps[topic]; ok { + if p.isSelfPossibleRecipient(pssMsg, true) && p.topicHandlerCaps[topic].prox { + return p.process(pssMsg, true, true) + } } return nil } @@ -1034,3 +1044,10 @@ func (p *Pss) digestBytes(msg []byte) pssDigest { copy(digest[:], key[:digestLength]) return digest } + +func checkAddress(addr *PssAddress) bool { + if len(*addr) > addressLength { + return false + } + return true +} diff --git a/swarm/pss/pss_test.go b/swarm/pss/pss_test.go index 72f62acd94..0f25c85d3b 100644 --- a/swarm/pss/pss_test.go +++ b/swarm/pss/pss_test.go @@ -1008,6 +1008,28 @@ func TestRawAllow(t *testing.T) { } } +// BELOW HERE ARE TESTS USING THE SIMULATION FRAMEWORK + +// tests that the API layer can handle edge case values +func TestApi(t *testing.T) { + clients, err := setupNetwork(2, true) + if err != nil { + t.Fatal(err) + } + + topic := "0xdeadbeef" + + err = clients[0].Call(nil, "pss_sendRaw", "0x", topic, "0x666f6f") + if err != nil { + t.Fatal(err) + } + + err = clients[0].Call(nil, "pss_sendRaw", "0xabcdef", topic, "0x") + if err == nil { + t.Fatal("expected error on empty msg") + } +} + // verifies that nodes can send and receive raw (verbatim) messages func TestSendRaw(t *testing.T) { t.Run("32", testSendRaw)