[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet-go] branch master updated: Changes based on security audit "ngie-gnunetr5n".,
gnunet <=