gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet-go] branch master updated: Changes based on security audit "ngie


From: gnunet
Subject: [gnunet-go] branch master updated: Changes based on security audit "ngie-gnunetr5n".
Date: Tue, 24 Jan 2023 11:47:17 +0100

This is an automated email from the git hooks/post-receive script.

bernd-fix pushed a commit to branch master
in repository gnunet-go.

The following commit(s) were added to refs/heads/master by this push:
     new 5ea40b9  Changes based on security audit "ngie-gnunetr5n".
5ea40b9 is described below

commit 5ea40b971a196afd4783d64ea1932864c9688030
Author: Bernd Fix <brf@hoi-polloi.org>
AuthorDate: Tue Jan 24 11:46:09 2023 +0100

    Changes based on security audit "ngie-gnunetr5n".
---
 src/gnunet/service/dht/blocks/filters.go |  5 ++-
 src/gnunet/service/dht/blocks/gns.go     |  7 ++-
 src/gnunet/service/dht/blocks/hello.go   |  8 ++--
 src/gnunet/service/dht/messages.go       | 77 ++++++++++++++------------------
 src/gnunet/service/dht/module.go         |  4 +-
 src/gnunet/service/dht/routingtable.go   |  9 ++--
 src/gnunet/service/dht/service.go        |  7 +++
 src/gnunet/transport/endpoint.go         | 21 +++++----
 src/gnunet/util/peer.go                  | 10 ++++-
 9 files changed, 81 insertions(+), 67 deletions(-)

diff --git a/src/gnunet/service/dht/blocks/filters.go 
b/src/gnunet/service/dht/blocks/filters.go
index e7d961f..273b082 100644
--- a/src/gnunet/service/dht/blocks/filters.go
+++ b/src/gnunet/service/dht/blocks/filters.go
@@ -37,10 +37,13 @@ type PeerFilter struct {
        BF *BloomFilter
 }
 
+// PeerFilterSize is 128 bytes (fixed).
+const PeerFilterSize = 128
+
 // NewPeerFilter creates an empty peer filter instance.
 func NewPeerFilter() *PeerFilter {
        return &PeerFilter{
-               BF: NewBloomFilter(128),
+               BF: NewBloomFilter(PeerFilterSize),
        }
 }
 
diff --git a/src/gnunet/service/dht/blocks/gns.go 
b/src/gnunet/service/dht/blocks/gns.go
index e419279..e08488c 100644
--- a/src/gnunet/service/dht/blocks/gns.go
+++ b/src/gnunet/service/dht/blocks/gns.go
@@ -39,6 +39,9 @@ var (
        ErrBlockCantDecrypt     = errors.New("can't decrypt block type")
 )
 
+// GNSContext for key derivation
+const GNSContext = "gns"
+
 //----------------------------------------------------------------------
 // Query key for GNS lookups
 //----------------------------------------------------------------------
@@ -62,7 +65,7 @@ func (q *GNSQuery) Verify(b Block) (err error) {
                // verify derived key
                dkey := blk.DerivedKeySig.ZoneKey
                var dkey2 *crypto.ZoneKey
-               if dkey2, _, err = q.Zone.Derive(q.Label, "gns"); err != nil {
+               if dkey2, _, err = q.Zone.Derive(q.Label, GNSContext); err != 
nil {
                        return
                }
                if !dkey.Equal(dkey2) {
@@ -102,7 +105,7 @@ func NewGNSQuery(zkey *crypto.ZoneKey, label string) 
*GNSQuery {
        // derive a public key from (pkey,label) and set the repository
        // key as the SHA512 hash of the binary key representation.
        // (key blinding)
-       pd, _, err := zkey.Derive(label, "gns")
+       pd, _, err := zkey.Derive(label, GNSContext)
        if err != nil {
                logger.Printf(logger.ERROR, "[NewGNSQuery] failed: %s", 
err.Error())
                return nil
diff --git a/src/gnunet/service/dht/blocks/hello.go 
b/src/gnunet/service/dht/blocks/hello.go
index 5b14aa1..da67521 100644
--- a/src/gnunet/service/dht/blocks/hello.go
+++ b/src/gnunet/service/dht/blocks/hello.go
@@ -123,13 +123,13 @@ func ParseHelloBlockFromURL(u string, checkExpiry bool) 
(h *HelloBlock, err erro
 
        // (1) parse peer public key (peer ID)
        var buf []byte
-       if buf, err = util.DecodeStringToBinary(p[0], 32); err != nil {
+       if buf, err = util.DecodeStringToBinary(p[0], util.PeerPublicKeySize); 
err != nil {
                return
        }
        h.PeerID = util.NewPeerID(buf)
 
        // (2) parse signature
-       if buf, err = util.DecodeStringToBinary(p[1], 64); err != nil {
+       if buf, err = util.DecodeStringToBinary(p[1], util.PeerSignatureSize); 
err != nil {
                return
        }
        h.Signature = util.NewPeerSignature(buf)
@@ -315,12 +315,14 @@ type _SignedData struct {
        AddrHash *crypto.HashCode         // address hash
 }
 
+const _SignedDataSize = 80 // (8 + 8 + 64)
+
 // SignedData assembles a data block for sign and verify operations.
 func (h *HelloBlock) SignedData() []byte {
        // assemble signed data
        sd := &_SignedData{
                Purpose: &crypto.SignaturePurpose{
-                       Size:    80,
+                       Size:    _SignedDataSize,
                        Purpose: enums.SIG_HELLO,
                },
                Expire:   h.Expire_,
diff --git a/src/gnunet/service/dht/messages.go 
b/src/gnunet/service/dht/messages.go
index 9fedd10..912203d 100644
--- a/src/gnunet/service/dht/messages.go
+++ b/src/gnunet/service/dht/messages.go
@@ -37,6 +37,9 @@ import (
 // Handle DHT messages from the network
 //----------------------------------------------------------------------
 
+// MaxSortResults is the max. number of sorted results
+const MaxSortResults = 10
+
 // HandleMessage handles a DHT request/response message. Responses are sent
 // to the specified responder.
 //
@@ -154,12 +157,12 @@ func (m *Module) HandleMessage(ctx context.Context, 
sender *util.PeerID, msgIn m
                                        // create total result list
                                        if len(results) == 0 {
                                                results = lclResults
-                                       } else if len(results)+len(lclResults) 
<= 10 {
+                                       } else if len(results)+len(lclResults) 
<= MaxSortResults {
                                                // handle few results directly
                                                results = append(results, 
lclResults...)
                                        } else {
                                                // compile a new sorted list 
from results.
-                                               list := 
store.NewSortedDHTResults(10)
+                                               list := 
store.NewSortedDHTResults(MaxSortResults)
                                                for pos, res := range results {
                                                        list.Add(res, pos)
                                                }
@@ -313,24 +316,7 @@ func (m *Module) HandleMessage(ctx context.Context, sender 
*util.PeerID, msgIn m
                // if the put is for a HELLO block, add the sender to the
                // routing table (9.3.2.9)
                if msg.BType == enums.BLOCK_TYPE_DHT_HELLO {
-                       // get addresses from HELLO block
-                       hello, err := blocks.ParseHelloBlockFromBytes(msg.Block)
-                       if err != nil {
-                               logger.Printf(logger.ERROR, "[%s] failed to 
parse HELLO block: %s", label, err.Error())
-                       } else {
-                               // check state of bucket for given address
-                               if m.rtable.Check(NewPeerAddress(hello.PeerID)) 
== 0 {
-                                       // we could add the sender to the 
routing table
-                                       for _, addr := range hello.Addresses() {
-                                               if 
transport.CanHandleAddress(addr) {
-                                                       // try to connect to 
peer (triggers EV_CONNECTED on success)
-                                                       if err := 
m.core.TryConnect(sender, addr); err != nil {
-                                                               
logger.Printf(logger.ERROR, "[%s] try-connection to %s failed: %s", label, 
addr.URI(), err.Error())
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
+                       m.addSender(msg.Block, label, sender)
                }
                //--------------------------------------------------------------
                // check if we need to forward
@@ -418,24 +404,7 @@ func (m *Module) HandleMessage(ctx context.Context, sender 
*util.PeerID, msgIn m
                // if the put is for a HELLO block, add the originator to the
                // routing table (9.5.2.5)
                if btype == enums.BLOCK_TYPE_DHT_HELLO {
-                       // get addresses from HELLO block
-                       hello, err := blocks.ParseHelloBlockFromBytes(msg.Block)
-                       if err != nil {
-                               logger.Printf(logger.ERROR, "[%s] failed to 
parse HELLO block: %s", label, err.Error())
-                       } else {
-                               // check state of bucket for given address
-                               if m.rtable.Check(NewPeerAddress(hello.PeerID)) 
== 0 {
-                                       // we could add the originator to the 
routing table
-                                       for _, addr := range hello.Addresses() {
-                                               if 
transport.CanHandleAddress(addr) {
-                                                       // try to connect to 
peer (triggers EV_CONNECTED on success)
-                                                       if err := 
m.core.TryConnect(sender, addr); err != nil {
-                                                               
logger.Printf(logger.ERROR, "[%s] try-connection to %s failed: %s", label, 
addr.URI(), err.Error())
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
+                       m.addSender(msg.Block, label, sender)
                }
                // message forwarding to responder
                logger.Printf(logger.DBG, "[%s] result key = %s", label, 
msg.Query.Short())
@@ -451,12 +420,10 @@ func (m *Module) HandleMessage(ctx context.Context, 
sender *util.PeerID, msgIn m
                                        logger.Printf(logger.DBG, "[%s] Result 
handler not suitable (%s != %s) -- skipped", label, rh.Type(), btype)
                                        continue
                                }
-                               /*
-                                       if 
rh.Flags()&enums.DHT_RO_FIND_APPROXIMATE != 
msg.Flags&enums.DHT_RO_FIND_APPROXIMATE {
-                                               logger.Printf(logger.DBG, "[%s] 
Result handler asked for match, got approx -- ignored", label)
-                                               continue
-                                       }
-                               */
+                               if rh.Flags()&enums.DHT_RO_FIND_APPROXIMATE == 
0 && msg.Flags&enums.DHT_RO_FIND_APPROXIMATE != 0 {
+                                       logger.Printf(logger.DBG, "[%s] Result 
handler asked for match, got approx -- ignored", label)
+                                       continue
+                               }
                                
//--------------------------------------------------------------
                                // check task list for handler (9.5.2.6)
                                if rh.Flags()&enums.DHT_RO_FIND_APPROXIMATE == 
0 && blkKey != nil && !blkKey.Equal(rh.Key()) {
@@ -588,6 +555,28 @@ func (m *Module) HandleMessage(ctx context.Context, sender 
*util.PeerID, msgIn m
 // Helpers
 //----------------------------------------------------------------------
 
+// add a HELLO block sender to routing table
+func (m *Module) addSender(block []byte, label string, sender *util.PeerID) {
+       // get addresses from HELLO block
+       hello, err := blocks.ParseHelloBlockFromBytes(block)
+       if err != nil {
+               logger.Printf(logger.ERROR, "[%s] failed to parse HELLO block: 
%s", label, err.Error())
+       } else {
+               // check state of bucket for given address
+               if m.rtable.Check(NewPeerAddress(hello.PeerID)) == 0 {
+                       // we could add the sender to the routing table
+                       for _, addr := range hello.Addresses() {
+                               if transport.CanHandleAddress(addr) {
+                                       // try to connect to peer (triggers 
EV_CONNECTED on success)
+                                       if err := m.core.TryConnect(sender, 
addr); err != nil {
+                                               logger.Printf(logger.ERROR, 
"[%s] try-connection to %s failed: %s", label, addr.URI(), err.Error())
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
 // send a result back to caller
 func (m *Module) sendResult(ctx context.Context, query blocks.Query, blk 
blocks.Block, pth *path.Path, back transport.Responder) error {
        // assemble result message
diff --git a/src/gnunet/service/dht/module.go b/src/gnunet/service/dht/module.go
index 9f3aaa0..a954a37 100644
--- a/src/gnunet/service/dht/module.go
+++ b/src/gnunet/service/dht/module.go
@@ -142,7 +142,7 @@ func NewModule(ctx context.Context, c *core.Core, cfg 
*config.DHTConfig) (m *Mod
        c.Register("dht", listener)
 
        // run periodic tasks (8.2. peer discovery)
-       ticker := time.NewTicker(5 * time.Minute)
+       ticker := time.NewTicker(DiscoveryPeriod)
        key := crypto.Hash(m.core.PeerID().Bytes())
        flags := uint16(enums.DHT_RO_FIND_APPROXIMATE | 
enums.DHT_RO_DEMULTIPLEX_EVERYWHERE | enums.DHT_RO_DISCOVERY)
        var resCh <-chan blocks.Block
@@ -230,7 +230,7 @@ func (m *Module) Get(ctx context.Context, query 
blocks.Query) <-chan blocks.Bloc
        ttl, ok := util.GetParam[time.Duration](query.Params(), "timeout")
        if !ok {
                // defaults to 10 minutes
-               ttl = 10 * time.Minute
+               ttl = DefaultGetTTL
        }
        lctx, cancel := context.WithTimeout(ctx, ttl)
 
diff --git a/src/gnunet/service/dht/routingtable.go 
b/src/gnunet/service/dht/routingtable.go
index a119bbe..d08433d 100644
--- a/src/gnunet/service/dht/routingtable.go
+++ b/src/gnunet/service/dht/routingtable.go
@@ -36,7 +36,8 @@ import (
 
 // Routing table constants
 const (
-       numK = 20 // number of entries per k-bucket
+       numK    = 20  // number of entries per k-bucket
+       numBits = 512 // number of bits in SHA-512 value
 )
 
 //======================================================================
@@ -86,7 +87,7 @@ func (addr *PeerAddress) Equal(p *PeerAddress) bool {
 // bucket index (smaller index = less distant).
 func (addr *PeerAddress) Distance(p *PeerAddress) (*math.Int, int) {
        r := util.Distance(addr.Key.Data, p.Key.Data)
-       return r, 512 - r.BitLen()
+       return r, numBits - r.BitLen()
 }
 
 //======================================================================
@@ -115,7 +116,7 @@ func NewRoutingTable(ref *PeerAddress, cfg 
*config.RoutingConfig) *RoutingTable
        rt := &RoutingTable{
                ref:        ref,
                list:       util.NewMap[string, *PeerAddress](),
-               buckets:    make([]*Bucket, 512),
+               buckets:    make([]*Bucket, numBits),
                l2nse:      -1,
                inProcess:  make(map[int]struct{}),
                cfg:        cfg,
@@ -368,7 +369,7 @@ func (rt *RoutingTable) heartbeat(ctx context.Context) {
 func (rt *RoutingTable) LookupHello(addr *PeerAddress, rf blocks.ResultFilter, 
approx bool, label string) (results []*store.DHTResult) {
        // iterate over cached HELLOs to find matches;
        // approximate search is guided by distance
-       list := store.NewSortedDHTResults(10)
+       list := store.NewSortedDHTResults(MaxSortResults)
        _ = rt.helloCache.ProcessRange(func(key string, hb *blocks.HelloBlock, 
_ int) error {
                // check if block is excluded by result filter
                if !rf.Contains(hb) {
diff --git a/src/gnunet/service/dht/service.go 
b/src/gnunet/service/dht/service.go
index f5b6abd..b2e067a 100644
--- a/src/gnunet/service/dht/service.go
+++ b/src/gnunet/service/dht/service.go
@@ -22,6 +22,7 @@ import (
        "context"
        "fmt"
        "io"
+       "time"
 
        "gnunet/config"
        "gnunet/core"
@@ -37,6 +38,12 @@ var (
        ErrInvalidResponseType = fmt.Errorf("invald response type")
 )
 
+// Time constants
+var (
+       DefaultGetTTL   = 10 * time.Minute // timeout for GET requests
+       DiscoveryPeriod = 5 * time.Minute  // time between peer discovery runs
+)
+
 //----------------------------------------------------------------------
 // "GNUnet R5N DHT" service implementation
 //----------------------------------------------------------------------
diff --git a/src/gnunet/transport/endpoint.go b/src/gnunet/transport/endpoint.go
index 83a3cc8..095e642 100644
--- a/src/gnunet/transport/endpoint.go
+++ b/src/gnunet/transport/endpoint.go
@@ -24,8 +24,8 @@ import (
        "errors"
        "gnunet/message"
        "gnunet/util"
+       "io"
        "net"
-       "strings"
        "sync"
        "time"
 
@@ -41,6 +41,7 @@ var (
        ErrEndpNoConnection     = errors.New("no connection on endpoint")
        ErrEndpMaybeSent        = errors.New("message may have been sent - 
can't know")
        ErrEndpWriteShort       = errors.New("write too short")
+       ErrEndpReadShort        = errors.New("read too short")
 )
 
 // Endpoint represents a local endpoint that can send and receive messages.
@@ -120,16 +121,13 @@ func (ep *PaketEndpoint) Run(ctx context.Context, hdlr 
chan *Message) (err error
                        // read next message
                        tm, err := ep.read()
                        if err != nil {
-                               // leave go routine if already dead
-                               if !active {
-                                       return
+                               // leave go routine if already dead or closed 
by client
+                               if !active || err == io.EOF {
+                                       break
                                }
                                logger.Println(logger.WARN, "[pkt_ep] read 
failed: "+err.Error())
-                               // gracefully ignore unknown message types
-                               if strings.HasPrefix(err.Error(), "unknown 
message type") {
-                                       continue
-                               }
-                               break
+                               // gracefully ignore failed messages
+                               continue
                        }
                        // label message
                        tm.Label = ep.addr.String()
@@ -158,6 +156,11 @@ func (ep *PaketEndpoint) read() (tm *Message, err error) {
        )
        switch ep.addr.Network() {
        case "ip+udp":
+               // check for minimum size (32 byte peer id + 4 byte header)
+               if n < 36 {
+                       err = ErrEndpReadShort
+                       return
+               }
                // parse peer id and message in sequence
                peer = util.NewPeerID(ep.buf[:32])
                rdr := bytes.NewBuffer(util.Clone(ep.buf[32:n]))
diff --git a/src/gnunet/util/peer.go b/src/gnunet/util/peer.go
index 9646966..0064e96 100644
--- a/src/gnunet/util/peer.go
+++ b/src/gnunet/util/peer.go
@@ -33,6 +33,9 @@ type PeerPublicKey struct {
        Data []byte `size:"(Size)"` // Ed25519 public key data
 }
 
+// PeerPublicKeySize is the size of a binary representation
+const PeerPublicKeySize = 32
+
 // NewPeerPublicKey creates a key instance from binary data
 func NewPeerPublicKey(data []byte) *PeerPublicKey {
        pk := new(PeerPublicKey)
@@ -51,7 +54,7 @@ func NewPeerPublicKey(data []byte) *PeerPublicKey {
 
 // Size returns the length of the binary data
 func (pk *PeerPublicKey) Size() uint {
-       return 32
+       return PeerPublicKeySize
 }
 
 // Verify peer signature
@@ -115,6 +118,9 @@ type PeerSignature struct {
        Data []byte `size:"(Size)"`
 }
 
+// PeerSignatureSize is the size of the binary representation
+const PeerSignatureSize = 64
+
 // NewPeerSignature is a EdDSA signatre with the private peer key
 func NewPeerSignature(data []byte) *PeerSignature {
        s := new(PeerSignature)
@@ -133,7 +139,7 @@ func NewPeerSignature(data []byte) *PeerSignature {
 
 // Size returns the length of the binary data
 func (s *PeerSignature) Size() uint {
-       return 64
+       return PeerSignatureSize
 }
 
 // Bytes returns the binary representation of a peer signature.

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]