diff options
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 504 |
1 files changed, 257 insertions, 247 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index d34be30c4..c87adaa1b 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "gnunet_tun_lib.h" | 35 | #include "gnunet_tun_lib.h" |
36 | 36 | ||
37 | 37 | ||
38 | #define LOG(kind, ...) GNUNET_log_from(kind, "gnsrecord", __VA_ARGS__) | 38 | #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__) |
39 | 39 | ||
40 | 40 | ||
41 | /** | 41 | /** |
@@ -47,10 +47,10 @@ | |||
47 | * @param pub public key to use for KDF | 47 | * @param pub public key to use for KDF |
48 | */ | 48 | */ |
49 | static void | 49 | static void |
50 | derive_block_aes_key(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | 50 | derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, |
51 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | 51 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, |
52 | const char *label, | 52 | const char *label, |
53 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 53 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) |
54 | { | 54 | { |
55 | static const char ctx_key[] = "gns-aes-ctx-key"; | 55 | static const char ctx_key[] = "gns-aes-ctx-key"; |
56 | static const char ctx_iv[] = "gns-aes-ctx-iv"; | 56 | static const char ctx_iv[] = "gns-aes-ctx-iv"; |
@@ -60,27 +60,29 @@ derive_block_aes_key(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
60 | * how derive_h is done in crypto_ecc.c. | 60 | * how derive_h is done in crypto_ecc.c. |
61 | */ | 61 | */ |
62 | #ifdef GNUNET_PROTOCOL_V12 | 62 | #ifdef GNUNET_PROTOCOL_V12 |
63 | GNUNET_CRYPTO_kdf(skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | 63 | GNUNET_CRYPTO_kdf (skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), |
64 | ctx_key, strlen(ctx_key), | 64 | ctx_key, strlen (ctx_key), |
65 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 65 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
66 | label, strlen(label), | 66 | label, strlen (label), |
67 | NULL, 0); | 67 | NULL, 0); |
68 | GNUNET_CRYPTO_kdf(iv, sizeof(struct GNUNET_CRYPTO_SymmetricInitializationVector), | 68 | GNUNET_CRYPTO_kdf (iv, sizeof(struct |
69 | ctx_iv, strlen(ctx_iv), | 69 | GNUNET_CRYPTO_SymmetricInitializationVector), |
70 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 70 | ctx_iv, strlen (ctx_iv), |
71 | label, strlen(label), | 71 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
72 | NULL, 0); | 72 | label, strlen (label), |
73 | NULL, 0); | ||
73 | #else | 74 | #else |
74 | GNUNET_CRYPTO_kdf(skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), | 75 | GNUNET_CRYPTO_kdf (skey, sizeof(struct GNUNET_CRYPTO_SymmetricSessionKey), |
75 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 76 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
76 | label, strlen(label), | 77 | label, strlen (label), |
77 | ctx_key, strlen(ctx_key), | 78 | ctx_key, strlen (ctx_key), |
78 | NULL, 0); | 79 | NULL, 0); |
79 | GNUNET_CRYPTO_kdf(iv, sizeof(struct GNUNET_CRYPTO_SymmetricInitializationVector), | 80 | GNUNET_CRYPTO_kdf (iv, sizeof(struct |
80 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), | 81 | GNUNET_CRYPTO_SymmetricInitializationVector), |
81 | label, strlen(label), | 82 | pub, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey), |
82 | ctx_iv, strlen(ctx_iv), | 83 | label, strlen (label), |
83 | NULL, 0); | 84 | ctx_iv, strlen (ctx_iv), |
85 | NULL, 0); | ||
84 | #endif | 86 | #endif |
85 | } | 87 | } |
86 | 88 | ||
@@ -97,98 +99,101 @@ derive_block_aes_key(struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | |||
97 | * @return NULL on error (block too large) | 99 | * @return NULL on error (block too large) |
98 | */ | 100 | */ |
99 | struct GNUNET_GNSRECORD_Block * | 101 | struct GNUNET_GNSRECORD_Block * |
100 | block_create(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 102 | block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, |
101 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, | 103 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey, |
102 | struct GNUNET_TIME_Absolute expire, | 104 | struct GNUNET_TIME_Absolute expire, |
103 | const char *label, | 105 | const char *label, |
104 | const struct GNUNET_GNSRECORD_Data *rd, | 106 | const struct GNUNET_GNSRECORD_Data *rd, |
105 | unsigned int rd_count) | 107 | unsigned int rd_count) |
106 | { | 108 | { |
107 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size(rd_count, | 109 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, |
108 | rd); | 110 | rd); |
109 | struct GNUNET_GNSRECORD_Block *block; | 111 | struct GNUNET_GNSRECORD_Block *block; |
110 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; | 112 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; |
111 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 113 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
112 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 114 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; |
113 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL(rd_count)]; | 115 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
114 | uint32_t rd_count_nbo; | 116 | uint32_t rd_count_nbo; |
115 | struct GNUNET_TIME_Absolute now; | 117 | struct GNUNET_TIME_Absolute now; |
116 | 118 | ||
117 | if (payload_len < 0) | 119 | if (payload_len < 0) |
118 | { | 120 | { |
119 | GNUNET_break(0); | 121 | GNUNET_break (0); |
120 | return NULL; | 122 | return NULL; |
121 | } | 123 | } |
122 | if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) | 124 | if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) |
123 | { | 125 | { |
124 | GNUNET_break(0); | 126 | GNUNET_break (0); |
125 | return NULL; | 127 | return NULL; |
126 | } | 128 | } |
127 | /* convert relative to absolute times */ | 129 | /* convert relative to absolute times */ |
128 | now = GNUNET_TIME_absolute_get(); | 130 | now = GNUNET_TIME_absolute_get (); |
129 | for (unsigned int i = 0; i < rd_count; i++) | 131 | for (unsigned int i = 0; i < rd_count; i++) |
132 | { | ||
133 | rdc[i] = rd[i]; | ||
134 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
130 | { | 135 | { |
131 | rdc[i] = rd[i]; | 136 | struct GNUNET_TIME_Relative t; |
132 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
133 | { | ||
134 | struct GNUNET_TIME_Relative t; | ||
135 | 137 | ||
136 | /* encrypted blocks must never have relative expiration times, convert! */ | 138 | /* encrypted blocks must never have relative expiration times, convert! */ |
137 | rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | 139 | rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
138 | t.rel_value_us = rdc[i].expiration_time; | 140 | t.rel_value_us = rdc[i].expiration_time; |
139 | rdc[i].expiration_time = GNUNET_TIME_absolute_add(now, t).abs_value_us; | 141 | rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us; |
140 | } | ||
141 | } | 142 | } |
143 | } | ||
142 | /* serialize */ | 144 | /* serialize */ |
143 | rd_count_nbo = htonl(rd_count); | 145 | rd_count_nbo = htonl (rd_count); |
144 | { | 146 | { |
145 | char payload[sizeof(uint32_t) + payload_len]; | 147 | char payload[sizeof(uint32_t) + payload_len]; |
146 | 148 | ||
147 | GNUNET_memcpy(payload, | 149 | GNUNET_memcpy (payload, |
148 | &rd_count_nbo, | 150 | &rd_count_nbo, |
149 | sizeof(uint32_t)); | 151 | sizeof(uint32_t)); |
150 | GNUNET_assert(payload_len == | 152 | GNUNET_assert (payload_len == |
151 | GNUNET_GNSRECORD_records_serialize(rd_count, | 153 | GNUNET_GNSRECORD_records_serialize (rd_count, |
152 | rdc, | 154 | rdc, |
153 | payload_len, | 155 | payload_len, |
154 | &payload[sizeof(uint32_t)])); | 156 | &payload[sizeof(uint32_t) |
155 | block = GNUNET_malloc(sizeof(struct GNUNET_GNSRECORD_Block) + | 157 | ])); |
156 | sizeof(uint32_t) + | 158 | block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block) |
157 | payload_len); | 159 | + sizeof(uint32_t) |
158 | block->purpose.size = htonl(sizeof(uint32_t) + | 160 | + payload_len); |
159 | payload_len + | 161 | block->purpose.size = htonl (sizeof(uint32_t) |
160 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + | 162 | + payload_len |
161 | sizeof(struct GNUNET_TIME_AbsoluteNBO)); | 163 | + sizeof(struct |
162 | block->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | 164 | GNUNET_CRYPTO_EccSignaturePurpose) |
163 | block->expiration_time = GNUNET_TIME_absolute_hton(expire); | 165 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)); |
166 | block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | ||
167 | block->expiration_time = GNUNET_TIME_absolute_hton (expire); | ||
164 | /* encrypt and sign */ | 168 | /* encrypt and sign */ |
165 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive(key, | 169 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, |
166 | label, | 170 | label, |
167 | "gns"); | 171 | "gns"); |
168 | GNUNET_CRYPTO_ecdsa_key_get_public(dkey, | 172 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, |
169 | &block->derived_key); | 173 | &block->derived_key); |
170 | derive_block_aes_key(&iv, | 174 | derive_block_aes_key (&iv, |
171 | &skey, | 175 | &skey, |
172 | label, | 176 | label, |
173 | pkey); | 177 | pkey); |
174 | GNUNET_break(payload_len + sizeof(uint32_t) == | 178 | GNUNET_break (payload_len + sizeof(uint32_t) == |
175 | GNUNET_CRYPTO_symmetric_encrypt(payload, | 179 | GNUNET_CRYPTO_symmetric_encrypt (payload, |
176 | payload_len + sizeof(uint32_t), | 180 | payload_len |
177 | &skey, | 181 | + sizeof(uint32_t), |
178 | &iv, | 182 | &skey, |
179 | &block[1])); | 183 | &iv, |
184 | &block[1])); | ||
180 | } | 185 | } |
181 | if (GNUNET_OK != | 186 | if (GNUNET_OK != |
182 | GNUNET_CRYPTO_ecdsa_sign(dkey, | 187 | GNUNET_CRYPTO_ecdsa_sign (dkey, |
183 | &block->purpose, | 188 | &block->purpose, |
184 | &block->signature)) | 189 | &block->signature)) |
185 | { | 190 | { |
186 | GNUNET_break(0); | 191 | GNUNET_break (0); |
187 | GNUNET_free(dkey); | 192 | GNUNET_free (dkey); |
188 | GNUNET_free(block); | 193 | GNUNET_free (block); |
189 | return NULL; | 194 | return NULL; |
190 | } | 195 | } |
191 | GNUNET_free(dkey); | 196 | GNUNET_free (dkey); |
192 | return block; | 197 | return block; |
193 | } | 198 | } |
194 | 199 | ||
@@ -204,29 +209,30 @@ block_create(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
204 | * @return NULL on error (block too large) | 209 | * @return NULL on error (block too large) |
205 | */ | 210 | */ |
206 | struct GNUNET_GNSRECORD_Block * | 211 | struct GNUNET_GNSRECORD_Block * |
207 | GNUNET_GNSRECORD_block_create(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 212 | GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, |
208 | struct GNUNET_TIME_Absolute expire, | 213 | struct GNUNET_TIME_Absolute expire, |
209 | const char *label, | 214 | const char *label, |
210 | const struct GNUNET_GNSRECORD_Data *rd, | 215 | const struct GNUNET_GNSRECORD_Data *rd, |
211 | unsigned int rd_count) | 216 | unsigned int rd_count) |
212 | { | 217 | { |
213 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; | 218 | struct GNUNET_CRYPTO_EcdsaPublicKey pkey; |
214 | 219 | ||
215 | GNUNET_CRYPTO_ecdsa_key_get_public(key, | 220 | GNUNET_CRYPTO_ecdsa_key_get_public (key, |
216 | &pkey); | 221 | &pkey); |
217 | return block_create(key, | 222 | return block_create (key, |
218 | &pkey, | 223 | &pkey, |
219 | expire, | 224 | expire, |
220 | label, | 225 | label, |
221 | rd, | 226 | rd, |
222 | rd_count); | 227 | rd_count); |
223 | } | 228 | } |
224 | 229 | ||
225 | 230 | ||
226 | /** | 231 | /** |
227 | * Line in cache mapping private keys to public keys. | 232 | * Line in cache mapping private keys to public keys. |
228 | */ | 233 | */ |
229 | struct KeyCacheLine { | 234 | struct KeyCacheLine |
235 | { | ||
230 | /** | 236 | /** |
231 | * A private key. | 237 | * A private key. |
232 | */ | 238 | */ |
@@ -252,33 +258,33 @@ struct KeyCacheLine { | |||
252 | * @return NULL on error (block too large) | 258 | * @return NULL on error (block too large) |
253 | */ | 259 | */ |
254 | struct GNUNET_GNSRECORD_Block * | 260 | struct GNUNET_GNSRECORD_Block * |
255 | GNUNET_GNSRECORD_block_create2(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | 261 | GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, |
256 | struct GNUNET_TIME_Absolute expire, | 262 | struct GNUNET_TIME_Absolute expire, |
257 | const char *label, | 263 | const char *label, |
258 | const struct GNUNET_GNSRECORD_Data *rd, | 264 | const struct GNUNET_GNSRECORD_Data *rd, |
259 | unsigned int rd_count) | 265 | unsigned int rd_count) |
260 | { | 266 | { |
261 | #define CSIZE 64 | 267 | #define CSIZE 64 |
262 | static struct KeyCacheLine cache[CSIZE]; | 268 | static struct KeyCacheLine cache[CSIZE]; |
263 | struct KeyCacheLine *line; | 269 | struct KeyCacheLine *line; |
264 | 270 | ||
265 | line = &cache[(*(unsigned int *)key) % CSIZE]; | 271 | line = &cache[(*(unsigned int *) key) % CSIZE]; |
266 | if (0 != memcmp(&line->key, | 272 | if (0 != memcmp (&line->key, |
267 | key, | 273 | key, |
268 | sizeof(*key))) | 274 | sizeof(*key))) |
269 | { | 275 | { |
270 | /* cache miss, recompute */ | 276 | /* cache miss, recompute */ |
271 | line->key = *key; | 277 | line->key = *key; |
272 | GNUNET_CRYPTO_ecdsa_key_get_public(key, | 278 | GNUNET_CRYPTO_ecdsa_key_get_public (key, |
273 | &line->pkey); | 279 | &line->pkey); |
274 | } | 280 | } |
275 | #undef CSIZE | 281 | #undef CSIZE |
276 | return block_create(key, | 282 | return block_create (key, |
277 | &line->pkey, | 283 | &line->pkey, |
278 | expire, | 284 | expire, |
279 | label, | 285 | label, |
280 | rd, | 286 | rd, |
281 | rd_count); | 287 | rd_count); |
282 | } | 288 | } |
283 | 289 | ||
284 | 290 | ||
@@ -291,12 +297,12 @@ GNUNET_GNSRECORD_block_create2(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
291 | * @return #GNUNET_OK if the signature is valid | 297 | * @return #GNUNET_OK if the signature is valid |
292 | */ | 298 | */ |
293 | int | 299 | int |
294 | GNUNET_GNSRECORD_block_verify(const struct GNUNET_GNSRECORD_Block *block) | 300 | GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block) |
295 | { | 301 | { |
296 | return GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, | 302 | return GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, |
297 | &block->purpose, | 303 | &block->purpose, |
298 | &block->signature, | 304 | &block->signature, |
299 | &block->derived_key); | 305 | &block->derived_key); |
300 | } | 306 | } |
301 | 307 | ||
302 | 308 | ||
@@ -312,124 +318,126 @@ GNUNET_GNSRECORD_block_verify(const struct GNUNET_GNSRECORD_Block *block) | |||
312 | * not well-formed | 318 | * not well-formed |
313 | */ | 319 | */ |
314 | int | 320 | int |
315 | GNUNET_GNSRECORD_block_decrypt(const struct GNUNET_GNSRECORD_Block *block, | 321 | GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, |
316 | const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, | 322 | const struct |
317 | const char *label, | 323 | GNUNET_CRYPTO_EcdsaPublicKey *zone_key, |
318 | GNUNET_GNSRECORD_RecordCallback proc, | 324 | const char *label, |
319 | void *proc_cls) | 325 | GNUNET_GNSRECORD_RecordCallback proc, |
326 | void *proc_cls) | ||
320 | { | 327 | { |
321 | size_t payload_len = ntohl(block->purpose.size) - | 328 | size_t payload_len = ntohl (block->purpose.size) |
322 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) - | 329 | - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
323 | sizeof(struct GNUNET_TIME_AbsoluteNBO); | 330 | - sizeof(struct GNUNET_TIME_AbsoluteNBO); |
324 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 331 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
325 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 332 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; |
326 | 333 | ||
327 | if (ntohl(block->purpose.size) < | 334 | if (ntohl (block->purpose.size) < |
328 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) + | 335 | sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) |
329 | sizeof(struct GNUNET_TIME_AbsoluteNBO)) | 336 | + sizeof(struct GNUNET_TIME_AbsoluteNBO)) |
330 | { | 337 | { |
331 | GNUNET_break_op(0); | 338 | GNUNET_break_op (0); |
332 | return GNUNET_SYSERR; | 339 | return GNUNET_SYSERR; |
333 | } | 340 | } |
334 | derive_block_aes_key(&iv, | 341 | derive_block_aes_key (&iv, |
335 | &skey, | 342 | &skey, |
336 | label, | 343 | label, |
337 | zone_key); | 344 | zone_key); |
338 | { | 345 | { |
339 | char payload[payload_len]; | 346 | char payload[payload_len]; |
340 | uint32_t rd_count; | 347 | uint32_t rd_count; |
341 | 348 | ||
342 | GNUNET_break(payload_len == | 349 | GNUNET_break (payload_len == |
343 | GNUNET_CRYPTO_symmetric_decrypt(&block[1], payload_len, | 350 | GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, |
344 | &skey, &iv, | 351 | &skey, &iv, |
345 | payload)); | 352 | payload)); |
346 | GNUNET_memcpy(&rd_count, | 353 | GNUNET_memcpy (&rd_count, |
347 | payload, | 354 | payload, |
348 | sizeof(uint32_t)); | 355 | sizeof(uint32_t)); |
349 | rd_count = ntohl(rd_count); | 356 | rd_count = ntohl (rd_count); |
350 | if (rd_count > 2048) | 357 | if (rd_count > 2048) |
351 | { | ||
352 | /* limit to sane value */ | ||
353 | GNUNET_break_op(0); | ||
354 | return GNUNET_SYSERR; | ||
355 | } | ||
356 | { | 358 | { |
357 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)]; | 359 | /* limit to sane value */ |
360 | GNUNET_break_op (0); | ||
361 | return GNUNET_SYSERR; | ||
362 | } | ||
363 | { | ||
364 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)]; | ||
358 | unsigned int j; | 365 | unsigned int j; |
359 | struct GNUNET_TIME_Absolute now; | 366 | struct GNUNET_TIME_Absolute now; |
360 | 367 | ||
361 | if (GNUNET_OK != | 368 | if (GNUNET_OK != |
362 | GNUNET_GNSRECORD_records_deserialize(payload_len - sizeof(uint32_t), | 369 | GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t), |
363 | &payload[sizeof(uint32_t)], | 370 | &payload[sizeof(uint32_t)], |
364 | rd_count, | 371 | rd_count, |
365 | rd)) | 372 | rd)) |
366 | { | 373 | { |
367 | GNUNET_break_op(0); | 374 | GNUNET_break_op (0); |
368 | return GNUNET_SYSERR; | 375 | return GNUNET_SYSERR; |
369 | } | 376 | } |
370 | /* hide expired records */ | 377 | /* hide expired records */ |
371 | now = GNUNET_TIME_absolute_get(); | 378 | now = GNUNET_TIME_absolute_get (); |
372 | j = 0; | 379 | j = 0; |
373 | for (unsigned int i = 0; i < rd_count; i++) | 380 | for (unsigned int i = 0; i < rd_count; i++) |
381 | { | ||
382 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
374 | { | 383 | { |
375 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | 384 | /* encrypted blocks must never have relative expiration times, skip! */ |
376 | { | 385 | GNUNET_break_op (0); |
377 | /* encrypted blocks must never have relative expiration times, skip! */ | 386 | continue; |
378 | GNUNET_break_op(0); | 387 | } |
379 | continue; | ||
380 | } | ||
381 | 388 | ||
382 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) | 389 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) |
383 | { | 390 | { |
384 | int include_record = GNUNET_YES; | 391 | int include_record = GNUNET_YES; |
385 | /* Shadow record, figure out if we have a not expired active record */ | 392 | /* Shadow record, figure out if we have a not expired active record */ |
386 | for (unsigned int k = 0; k < rd_count; k++) | 393 | for (unsigned int k = 0; k < rd_count; k++) |
387 | { | 394 | { |
388 | if (k == i) | 395 | if (k == i) |
389 | continue; | 396 | continue; |
390 | if (rd[i].expiration_time < now.abs_value_us) | 397 | if (rd[i].expiration_time < now.abs_value_us) |
391 | include_record = GNUNET_NO; /* Shadow record is expired */ | 398 | include_record = GNUNET_NO; /* Shadow record is expired */ |
392 | if ((rd[k].record_type == rd[i].record_type) && | 399 | if ((rd[k].record_type == rd[i].record_type) && |
393 | (rd[k].expiration_time >= now.abs_value_us) && | 400 | (rd[k].expiration_time >= now.abs_value_us) && |
394 | (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))) | 401 | (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))) |
395 | { | ||
396 | include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ | ||
397 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
398 | "Ignoring shadow record\n"); | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | if (GNUNET_YES == include_record) | ||
403 | { | ||
404 | rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */ | ||
405 | if (j != i) | ||
406 | rd[j] = rd[i]; | ||
407 | j++; | ||
408 | } | ||
409 | } | ||
410 | else if (rd[i].expiration_time >= now.abs_value_us) | ||
411 | { | ||
412 | /* Include this record */ | ||
413 | if (j != i) | ||
414 | rd[j] = rd[i]; | ||
415 | j++; | ||
416 | } | ||
417 | else | ||
418 | { | 402 | { |
419 | struct GNUNET_TIME_Absolute at; | 403 | include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ |
420 | 404 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | |
421 | at.abs_value_us = rd[i].expiration_time; | 405 | "Ignoring shadow record\n"); |
422 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 406 | break; |
423 | "Excluding record that expired %s (%llu ago)\n", | ||
424 | GNUNET_STRINGS_absolute_time_to_string(at), | ||
425 | (unsigned long long)rd[i].expiration_time - now.abs_value_us); | ||
426 | } | 407 | } |
408 | } | ||
409 | if (GNUNET_YES == include_record) | ||
410 | { | ||
411 | rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */ | ||
412 | if (j != i) | ||
413 | rd[j] = rd[i]; | ||
414 | j++; | ||
415 | } | ||
416 | } | ||
417 | else if (rd[i].expiration_time >= now.abs_value_us) | ||
418 | { | ||
419 | /* Include this record */ | ||
420 | if (j != i) | ||
421 | rd[j] = rd[i]; | ||
422 | j++; | ||
427 | } | 423 | } |
424 | else | ||
425 | { | ||
426 | struct GNUNET_TIME_Absolute at; | ||
427 | |||
428 | at.abs_value_us = rd[i].expiration_time; | ||
429 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
430 | "Excluding record that expired %s (%llu ago)\n", | ||
431 | GNUNET_STRINGS_absolute_time_to_string (at), | ||
432 | (unsigned long long) rd[i].expiration_time | ||
433 | - now.abs_value_us); | ||
434 | } | ||
435 | } | ||
428 | rd_count = j; | 436 | rd_count = j; |
429 | if (NULL != proc) | 437 | if (NULL != proc) |
430 | proc(proc_cls, | 438 | proc (proc_cls, |
431 | rd_count, | 439 | rd_count, |
432 | (0 != rd_count) ? rd : NULL); | 440 | (0 != rd_count) ? rd : NULL); |
433 | } | 441 | } |
434 | } | 442 | } |
435 | return GNUNET_OK; | 443 | return GNUNET_OK; |
@@ -444,17 +452,18 @@ GNUNET_GNSRECORD_block_decrypt(const struct GNUNET_GNSRECORD_Block *block, | |||
444 | * @param query hash to use for the query | 452 | * @param query hash to use for the query |
445 | */ | 453 | */ |
446 | void | 454 | void |
447 | GNUNET_GNSRECORD_query_from_private_key(const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 455 | GNUNET_GNSRECORD_query_from_private_key (const struct |
448 | const char *label, | 456 | GNUNET_CRYPTO_EcdsaPrivateKey *zone, |
449 | struct GNUNET_HashCode *query) | 457 | const char *label, |
458 | struct GNUNET_HashCode *query) | ||
450 | { | 459 | { |
451 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | 460 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; |
452 | 461 | ||
453 | GNUNET_CRYPTO_ecdsa_key_get_public(zone, | 462 | GNUNET_CRYPTO_ecdsa_key_get_public (zone, |
454 | &pub); | 463 | &pub); |
455 | GNUNET_GNSRECORD_query_from_public_key(&pub, | 464 | GNUNET_GNSRECORD_query_from_public_key (&pub, |
456 | label, | 465 | label, |
457 | query); | 466 | query); |
458 | } | 467 | } |
459 | 468 | ||
460 | 469 | ||
@@ -466,18 +475,19 @@ GNUNET_GNSRECORD_query_from_private_key(const struct GNUNET_CRYPTO_EcdsaPrivateK | |||
466 | * @param query hash to use for the query | 475 | * @param query hash to use for the query |
467 | */ | 476 | */ |
468 | void | 477 | void |
469 | GNUNET_GNSRECORD_query_from_public_key(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, | 478 | GNUNET_GNSRECORD_query_from_public_key (const struct |
470 | const char *label, | 479 | GNUNET_CRYPTO_EcdsaPublicKey *pub, |
471 | struct GNUNET_HashCode *query) | 480 | const char *label, |
481 | struct GNUNET_HashCode *query) | ||
472 | { | 482 | { |
473 | struct GNUNET_CRYPTO_EcdsaPublicKey pd; | 483 | struct GNUNET_CRYPTO_EcdsaPublicKey pd; |
474 | GNUNET_CRYPTO_ecdsa_public_key_derive(pub, | 484 | GNUNET_CRYPTO_ecdsa_public_key_derive (pub, |
475 | label, | 485 | label, |
476 | "gns", | 486 | "gns", |
477 | &pd); | 487 | &pd); |
478 | GNUNET_CRYPTO_hash(&pd, | 488 | GNUNET_CRYPTO_hash (&pd, |
479 | sizeof(pd), | 489 | sizeof(pd), |
480 | query); | 490 | query); |
481 | } | 491 | } |
482 | 492 | ||
483 | 493 | ||