diff options
Diffstat (limited to 'src/gnunet/service/dht/blocks/gns.go')
-rw-r--r-- | src/gnunet/service/dht/blocks/gns.go | 108 |
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) | ||
145 | func (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 |
144 | func (b *GNSBlock) Bytes() []byte { | 150 | func (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 |
182 | func (b *GNSBlock) Prepare(enums.BlockType, util.AbsoluteTime) {} | 192 | func (b *GNSBlock) Prepare(enums.BlockType, util.AbsoluteTime) {} |
183 | 193 | ||
194 | // SetData sets the data for the GNS block | ||
195 | func (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 | ||
201 | func (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. | ||
227 | type 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. | ||
234 | func 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. | ||
243 | func (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. | ||
249 | func (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. | ||
262 | func (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 | ||
275 | func (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). | ||
285 | type 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. | ||
294 | func (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 | } | ||