aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/service/dht/blocks/gns.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/service/dht/blocks/gns.go')
-rw-r--r--src/gnunet/service/dht/blocks/gns.go108
1 files changed, 105 insertions, 3 deletions
diff --git a/src/gnunet/service/dht/blocks/gns.go b/src/gnunet/service/dht/blocks/gns.go
index 6b41b0b..0c32085 100644
--- a/src/gnunet/service/dht/blocks/gns.go
+++ b/src/gnunet/service/dht/blocks/gns.go
@@ -47,7 +47,7 @@ type GNSQuery struct {
47 GenericQuery 47 GenericQuery
48 Zone *crypto.ZoneKey // Public zone key 48 Zone *crypto.ZoneKey // Public zone key
49 Label string // Atomic label 49 Label string // Atomic label
50 derived *crypto.ZoneKey // Derived zone key from (pkey,label) 50 derived *crypto.ZoneKey // Derived zone key from (zone,label)
51} 51}
52 52
53// Verify the integrity of the block data from a signature. 53// Verify the integrity of the block data from a signature.
@@ -103,6 +103,7 @@ func NewGNSQuery(zkey *crypto.ZoneKey, label string) *GNSQuery {
103 pd, _, err := zkey.Derive(label, "gns") 103 pd, _, err := zkey.Derive(label, "gns")
104 if err != nil { 104 if err != nil {
105 logger.Printf(logger.ERROR, "[NewGNSQuery] failed: %s", err.Error()) 105 logger.Printf(logger.ERROR, "[NewGNSQuery] failed: %s", err.Error())
106 return nil
106 } 107 }
107 gq := crypto.Hash(pd.Bytes()) 108 gq := crypto.Hash(pd.Bytes())
108 return &GNSQuery{ 109 return &GNSQuery{
@@ -140,6 +141,11 @@ type GNSBlock struct {
140 data []byte // decrypted data 141 data []byte // decrypted data
141} 142}
142 143
144// Payload returns the decrypted block data (or nil)
145func (b *GNSBlock) Payload() []byte {
146 return util.Clone(b.data)
147}
148
143// Bytes return th binary representation of block 149// Bytes return th binary representation of block
144func (b *GNSBlock) Bytes() []byte { 150func (b *GNSBlock) Bytes() []byte {
145 buf, _ := data.Marshal(b) 151 buf, _ := data.Marshal(b)
@@ -167,8 +173,12 @@ func NewGNSBlock() Block {
167 return &GNSBlock{ 173 return &GNSBlock{
168 DerivedKeySig: nil, 174 DerivedKeySig: nil,
169 Body: &SignedGNSBlockData{ 175 Body: &SignedGNSBlockData{
170 Purpose: new(crypto.SignaturePurpose), 176 Purpose: &crypto.SignaturePurpose{
171 Data: nil, 177 Size: 16,
178 Purpose: enums.SIG_GNS_RECORD_SIGN,
179 },
180 Expire: util.AbsoluteTimeNever(),
181 Data: nil,
172 }, 182 },
173 checked: false, 183 checked: false,
174 verified: false, 184 verified: false,
@@ -181,6 +191,23 @@ func NewGNSBlock() Block {
181// Not required for GNS blocks 191// Not required for GNS blocks
182func (b *GNSBlock) Prepare(enums.BlockType, util.AbsoluteTime) {} 192func (b *GNSBlock) Prepare(enums.BlockType, util.AbsoluteTime) {}
183 193
194// SetData sets the data for the GNS block
195func (b *GNSBlock) SetData(data []byte) {
196 b.Body.Data = data
197 b.Body.Purpose.Size = uint32(len(data) + 16)
198}
199
200// Sign the block with a derived private key
201func (b *GNSBlock) Sign(sk *crypto.ZonePrivate) error {
202 // get signed data
203 buf, err := data.Marshal(b.Body)
204 if err == nil {
205 // generate signature
206 b.DerivedKeySig, err = sk.Sign(buf)
207 }
208 return err
209}
210
184// Verify the integrity of the block data from a signature. 211// Verify the integrity of the block data from a signature.
185// Only the cryptographic signature is verified; the formal correctness of 212// Only the cryptographic signature is verified; the formal correctness of
186// the association between the block and a GNS label in a GNS zone can't 213// the association between the block and a GNS label in a GNS zone can't
@@ -193,3 +220,78 @@ func (b *GNSBlock) Verify() (ok bool, err error) {
193 } 220 }
194 return b.DerivedKeySig.Verify(buf) 221 return b.DerivedKeySig.Verify(buf)
195} 222}
223
224// RecordSet ist the GNUnet data structure for a list of resource records
225// in a GNSBlock. As part of GNUnet messages, the record set is padded so that
226// the binary size of (records||padding) is the smallest power of two.
227type RecordSet struct {
228 Count uint32 `order:"big"` // number of resource records
229 Records []*ResourceRecord `size:"Count"` // list of resource records
230 Padding []byte `size:"*"` // padding
231}
232
233// NewRecordSet returns an empty resource record set.
234func NewRecordSet() *RecordSet {
235 return &RecordSet{
236 Count: 0,
237 Records: make([]*ResourceRecord, 0),
238 Padding: make([]byte, 0),
239 }
240}
241
242// AddRecord to append a resource record to the set.
243func (rs *RecordSet) AddRecord(rec *ResourceRecord) {
244 rs.Count++
245 rs.Records = append(rs.Records, rec)
246}
247
248// SetPadding (re-)calculates and allocates the padding.
249func (rs *RecordSet) SetPadding() {
250 size := 0
251 for _, rr := range rs.Records {
252 size += int(rr.Size) + 20
253 }
254 n := 1
255 for n < size {
256 n <<= 1
257 }
258 rs.Padding = make([]byte, n-size)
259}
260
261// Expire returns the earliest expiration timestamp for the records.
262func (rs *RecordSet) Expire() util.AbsoluteTime {
263 var expires util.AbsoluteTime
264 for i, rr := range rs.Records {
265 if i == 0 {
266 expires = rr.Expire
267 } else if rr.Expire.Compare(expires) < 0 {
268 expires = rr.Expire
269 }
270 }
271 return expires
272}
273
274// Bytes returns the binary representation
275func (rs *RecordSet) Bytes() []byte {
276 buf, err := data.Marshal(rs)
277 if err != nil {
278 return nil
279 }
280 return buf
281}
282
283// ResourceRecord is the GNUnet-specific representation of resource
284// records (not to be confused with DNS resource records).
285type ResourceRecord struct {
286 Expire util.AbsoluteTime // Expiration time for the record
287 Size uint32 `order:"big"` // Number of bytes in 'Data'
288 RType enums.GNSType `order:"big"` // Type of the GNS/DNS record
289 Flags enums.GNSFlag `order:"big"` // Flags for the record
290 Data []byte `size:"Size"` // Record data
291}
292
293// String returns a human-readable representation of the message.
294func (r *ResourceRecord) String() string {
295 return fmt.Sprintf("GNSResourceRecord{type=%s,expire=%s,flags=%d,size=%d}",
296 r.RType.String(), r.Expire, r.Flags, r.Size)
297}