gnunet-go

GNUnet Bindings for Go
Log | Files | Refs | README | LICENSE

commit 9cae276c86826c5ccdea54e351289ea9cb86a632
parent a048e9c08195a3ed11e7f864e270d372668b129e
Author: Bernd Fix <brf@hoi-polloi.org>
Date:   Wed, 18 Sep 2019 23:26:22 +0200

Process DHT responses for GNS block GET requests.

Diffstat:
Msrc/gnunet/message/msg_core.go | 24++++++++++++++----------
Msrc/gnunet/message/msg_dht.go | 6++++--
Msrc/gnunet/service/gns/gns.go | 46+++++++++++++++++++++++++++++++++++++++-------
Msrc/gnunet/service/gns/record.go | 17++++++++++++-----
4 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/src/gnunet/message/msg_core.go b/src/gnunet/message/msg_core.go @@ -11,13 +11,17 @@ import ( "gnunet/util" ) +type PeerID struct { + Key []byte `size:"32"` +} + type EphKeyBlock struct { - SignSize uint32 `order:"big"` // length of signed block - SigPurpose uint32 `order:"big"` // signature purpose: SIG_ECC_KEY - CreateTime uint64 `order:"big"` // Time of key creation - ExpireTime uint64 `order:"big"` // Time of key expiration - EphemeralKey []byte `size:"32"` // Ephemeral EdDSA public key - PeerID []byte `size:"32"` // Peer identity (EdDSA public key) + SignSize uint32 `order:"big"` // length of signed block + SigPurpose uint32 `order:"big"` // signature purpose: SIG_ECC_KEY + CreateTime uint64 `order:"big"` // Time of key creation + ExpireTime uint64 `order:"big"` // Time of key expiration + EphemeralKey []byte `size:"32"` // Ephemeral EdDSA public key + PeerID *PeerID // Peer identity (EdDSA public key) } type EphemeralKeyMsg struct { @@ -40,14 +44,14 @@ func NewEphemeralKeyMsg() *EphemeralKeyMsg { CreateTime: util.GetAbsoluteTimeNow(), ExpireTime: util.GetAbsoluteTimeOffset(12 * time.Hour), EphemeralKey: make([]byte, 32), - PeerID: make([]byte, 32), + PeerID: new(PeerID), }, } } func (m *EphemeralKeyMsg) String() string { return fmt.Sprintf("EphKeyMsg{%s,%s,%s,%d}", - util.EncodeBinaryToString(m.SignedBlock.PeerID), + util.EncodeBinaryToString(m.SignedBlock.PeerID.Key), util.EncodeBinaryToString(m.SignedBlock.EphemeralKey), util.Timestamp(m.SignedBlock.ExpireTime), m.SenderStatus) @@ -59,7 +63,7 @@ func (msg *EphemeralKeyMsg) Header() *MessageHeader { } func (m *EphemeralKeyMsg) Public() *ed25519.PublicKey { - return ed25519.NewPublicKeyFromBytes(m.SignedBlock.PeerID) + return ed25519.NewPublicKeyFromBytes(m.SignedBlock.PeerID.Key) } func (m *EphemeralKeyMsg) Verify(pub *ed25519.PublicKey) (bool, error) { @@ -76,7 +80,7 @@ func (m *EphemeralKeyMsg) Verify(pub *ed25519.PublicKey) (bool, error) { func NewEphemeralKey(peerId []byte, ltPrv *ed25519.PrivateKey) (*ed25519.PrivateKey, *EphemeralKeyMsg, error) { msg := NewEphemeralKeyMsg() - copy(msg.SignedBlock.PeerID, peerId) + copy(msg.SignedBlock.PeerID.Key, peerId) seed := util.NewRndArray(32) prv := ed25519.NewPrivateKeyFromSeed(seed) copy(msg.SignedBlock.EphemeralKey, prv.Public().Bytes()) diff --git a/src/gnunet/message/msg_dht.go b/src/gnunet/message/msg_dht.go @@ -38,7 +38,7 @@ func NewDHTClientGetMsg(key *crypto.HashCode) *DHTClientGetMsg { Type: uint32(enums.BLOCK_TYPE_ANY), Key: key, Id: 0, - XQuery: make([]byte, 0), + XQuery: nil, } } @@ -75,7 +75,9 @@ type DHTClientResultMsg struct { Id uint64 `order:"big"` // Unique ID of the matching GET request Expire uint64 `order:"big"` // Expiration time Key *crypto.HashCode // The key that was searched for - Data []byte `size:"*"` // put path, get path and actual data + PutPath []*PeerID `size:"PutPathLen"` // put path + GetPath []*PeerID `size:"GetPathLen"` // get path + Data []byte `size:"*"` // data returned for query } // NewDHTClientResultMsg creates a new default DHTClientResultMsg object. diff --git a/src/gnunet/service/gns/gns.go b/src/gnunet/service/gns/gns.go @@ -6,6 +6,7 @@ import ( "time" "github.com/bfix/gospel/crypto/ed25519" + "github.com/bfix/gospel/data" "github.com/bfix/gospel/logger" "gnunet/config" "gnunet/crypto" @@ -75,7 +76,7 @@ func (s *GNSService) ServeClient(mc *transport.MsgChannel) { } // handle block if block != nil { - logger.Printf(logger.DBG, "[gns] Received block data: %s\n", hex.EncodeToString(block.Block.Data)) + logger.Printf(logger.DBG, "[gns] Received block data: %s\n", hex.EncodeToString(block.Block.data)) // get records from block records, err := block.Records() @@ -126,20 +127,20 @@ func (s *GNSService) Lookup(m *message.GNSLookupMsg) (block *GNSBlock, err error // try namecache lookup first if block, err = s.LookupNamecache(query, pkey, label); err != nil { - logger.Printf(logger.ERROR, "gns.Lookup(namecache): %s\n", err.Error()) + logger.Printf(logger.ERROR, "[gns] Lookup(Namecache): %s\n", err.Error()) block = nil return } if block == nil { - logger.Println(logger.DBG, "gns.Lookup(namecache): no block found") + logger.Println(logger.DBG, "[gns] Lookup(Namecache): no block found") if int(m.Options) == enums.GNS_LO_DEFAULT { // get the block from the DHT if block, err = s.LookupDHT(query, pkey, label); err != nil || block == nil { if err != nil { - logger.Printf(logger.ERROR, "gns.Lookup(dht): %s\n", err.Error()) + logger.Printf(logger.ERROR, "[gns] Lookup(DHT): %s\n", err.Error()) block = nil } else { - logger.Println(logger.DBG, "gns.Lookup(dht): no block found") + logger.Println(logger.DBG, "[gns] Lookup(DHT): no block found") } // lookup fails completely -- no result } @@ -183,7 +184,7 @@ func (s *GNSService) LookupNamecache(query *crypto.HashCode, zoneKey *ed25519.Pu break } - // assemble the GNSBlock from message + // assemble GNSBlock from message block = new(GNSBlock) block.Signature = m.Signature block.DerivedKey = m.DerivedKey @@ -192,7 +193,7 @@ func (s *GNSService) LookupNamecache(query *crypto.HashCode, zoneKey *ed25519.Pu sb.Purpose.Purpose = enums.SIG_GNS_RECORD_SIGN sb.Purpose.Size = uint32(16 + len(m.EncData)) sb.Expire = m.Expire - sb.Data = m.EncData + sb.EncData = m.EncData block.Block = sb // verify and decrypt block @@ -206,6 +207,12 @@ func (s *GNSService) LookupNamecache(query *crypto.HashCode, zoneKey *ed25519.Pu return } +// StoreNamecache +func (s *GNSService) StoreNamecache(query *crypto.HashCode, block *GNSBlock) error { + logger.Println(logger.WARN, "[gns] StoreNamecache() not implemented yet!") + return nil +} + // LookupDHT func (s *GNSService) LookupDHT(query *crypto.HashCode, zoneKey *ed25519.PublicKey, label string) (block *GNSBlock, err error) { logger.Printf(logger.DBG, "[gns] LookupDHT(%s)...\n", hex.EncodeToString(query.Bits)) @@ -243,6 +250,31 @@ func (s *GNSService) LookupDHT(query *crypto.HashCode, zoneKey *ed25519.PublicKe logger.Printf(logger.ERROR, "[gns] block expired at %s\n", util.Timestamp(m.Expire)) break } + // check if result is of requested type + if int(m.Type) != enums.BLOCK_TYPE_GNS_NAMERECORD { + logger.Println(logger.ERROR, "[gns] DHT response has wrong type") + break + } + + // get GNSBlock from message + block = NewGNSBlock() + if err = data.Unmarshal(block, m.Data); err != nil { + logger.Printf(logger.ERROR, "[gns] can't read GNS block: %s\n", err.Error()) + break + } + // verify and decrypt block + if err = block.Verify(zoneKey, label); err != nil { + break + } + if err = block.Decrypt(zoneKey, label); err != nil { + break + } + + // we got a result from DHT that was not in the namecache, + // so store it there now. + if err = s.StoreNamecache(query, block); err != nil { + logger.Printf(logger.ERROR, "[gns] can't store block in Namecache: %s\n", err.Error()) + } } return } diff --git a/src/gnunet/service/gns/record.go b/src/gnunet/service/gns/record.go @@ -30,7 +30,10 @@ func NewGNSRecordSet() *GNSRecordSet { type SignedBlockData struct { Purpose *crypto.SignaturePurpose // Size and purpose of signature (8 bytes) Expire uint64 `order:"big"` // Expiration time of the block. - Data []byte `size:"*"` // (encrypted) GNSRecordSet + EncData []byte `size:"*"` // encrypted GNSRecordSet + + // transient data (not serialized) + data []byte // unencrypted GNSRecord set } type GNSBlock struct { @@ -38,6 +41,7 @@ type GNSBlock struct { DerivedKey []byte `size:"32"` // Derived key used for signing Block *SignedBlockData + // transient data (not serialized) checked bool // block integrity checked verified bool // block signature verified (internal) decrypted bool // block data decrypted (internal) @@ -45,7 +49,7 @@ type GNSBlock struct { func (b *GNSBlock) String() string { return fmt.Sprintf("GNSBlock{Verified=%v,Decrypted=%v,data=[%d]}", - b.verified, b.decrypted, len(b.Block.Data)) + b.verified, b.decrypted, len(b.Block.EncData)) } func (b *GNSBlock) Records() ([]*message.GNSResourceRecord, error) { @@ -55,7 +59,7 @@ func (b *GNSBlock) Records() ([]*message.GNSResourceRecord, error) { } // parse block data into record set rs := NewGNSRecordSet() - if err := data.Unmarshal(rs, b.Block.Data); err != nil { + if err := data.Unmarshal(rs, b.Block.data); err != nil { return nil, err } return rs.Records, nil @@ -92,7 +96,7 @@ func (b *GNSBlock) Verify(zoneKey *ed25519.PublicKey, label string) (err error) func (b *GNSBlock) Decrypt(zoneKey *ed25519.PublicKey, label string) (err error) { // decrypt payload - b.Block.Data, err = DecryptBlock(b.Block.Data, zoneKey, label) + b.Block.data, err = DecryptBlock(b.Block.EncData, zoneKey, label) b.decrypted = true return } @@ -102,7 +106,10 @@ func NewGNSBlock() *GNSBlock { Signature: make([]byte, 64), DerivedKey: make([]byte, 32), Block: &SignedBlockData{ - Data: nil, + Purpose: new(crypto.SignaturePurpose), + Expire: 0, + EncData: nil, + data: nil, }, checked: false, verified: false,