diff options
Diffstat (limited to 'src/gnsrecord/gnsrecord_crypto.c')
-rw-r--r-- | src/gnsrecord/gnsrecord_crypto.c | 142 |
1 files changed, 85 insertions, 57 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index cebc842f3..295d31100 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -1,21 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2009-2013 GNUnet e.V. | 3 | Copyright (C) 2009-2013, 2018 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | it under the terms of the GNU General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
7 | by the Free Software Foundation; either version 3, or (at your | 7 | by the Free Software Foundation, either version 3 of the License, |
8 | option) any later version. | 8 | or (at your option) any later version. |
9 | 9 | ||
10 | GNUnet is distributed in the hope that it will be useful, but | 10 | GNUnet is distributed in the hope that it will be useful, but |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with GNUnet; see the file COPYING. If not, write to the | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | 17 | */ |
20 | 18 | ||
21 | /** | 19 | /** |
@@ -87,19 +85,26 @@ block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
87 | const struct GNUNET_GNSRECORD_Data *rd, | 85 | const struct GNUNET_GNSRECORD_Data *rd, |
88 | unsigned int rd_count) | 86 | unsigned int rd_count) |
89 | { | 87 | { |
90 | size_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, | 88 | ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, |
91 | rd); | 89 | rd); |
92 | char payload[sizeof (uint32_t) + payload_len]; | ||
93 | struct GNUNET_GNSRECORD_Block *block; | 90 | struct GNUNET_GNSRECORD_Block *block; |
94 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; | 91 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; |
95 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | 92 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; |
96 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 93 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; |
97 | struct GNUNET_GNSRECORD_Data rdc[rd_count]; | 94 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL(rd_count)]; |
98 | uint32_t rd_count_nbo; | 95 | uint32_t rd_count_nbo; |
99 | struct GNUNET_TIME_Absolute now; | 96 | struct GNUNET_TIME_Absolute now; |
100 | 97 | ||
98 | if (payload_len < 0) | ||
99 | { | ||
100 | GNUNET_break (0); | ||
101 | return NULL; | ||
102 | } | ||
101 | if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) | 103 | if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) |
104 | { | ||
105 | GNUNET_break (0); | ||
102 | return NULL; | 106 | return NULL; |
107 | } | ||
103 | /* convert relative to absolute times */ | 108 | /* convert relative to absolute times */ |
104 | now = GNUNET_TIME_absolute_get (); | 109 | now = GNUNET_TIME_absolute_get (); |
105 | for (unsigned int i=0;i<rd_count;i++) | 110 | for (unsigned int i=0;i<rd_count;i++) |
@@ -117,39 +122,43 @@ block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
117 | } | 122 | } |
118 | /* serialize */ | 123 | /* serialize */ |
119 | rd_count_nbo = htonl (rd_count); | 124 | rd_count_nbo = htonl (rd_count); |
120 | GNUNET_memcpy (payload, | 125 | { |
121 | &rd_count_nbo, | 126 | char payload[sizeof (uint32_t) + payload_len]; |
122 | sizeof (uint32_t)); | 127 | |
123 | GNUNET_assert (payload_len == | 128 | GNUNET_memcpy (payload, |
124 | GNUNET_GNSRECORD_records_serialize (rd_count, | 129 | &rd_count_nbo, |
125 | rdc, | 130 | sizeof (uint32_t)); |
126 | payload_len, | 131 | GNUNET_assert (payload_len == |
127 | &payload[sizeof (uint32_t)])); | 132 | GNUNET_GNSRECORD_records_serialize (rd_count, |
128 | block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + | 133 | rdc, |
129 | sizeof (uint32_t) + | 134 | payload_len, |
130 | payload_len); | 135 | &payload[sizeof (uint32_t)])); |
131 | block->purpose.size = htonl (sizeof (uint32_t) + | 136 | block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + |
132 | payload_len + | 137 | sizeof (uint32_t) + |
133 | sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | 138 | payload_len); |
134 | sizeof (struct GNUNET_TIME_AbsoluteNBO)); | 139 | block->purpose.size = htonl (sizeof (uint32_t) + |
135 | block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); | 140 | payload_len + |
136 | block->expiration_time = GNUNET_TIME_absolute_hton (expire); | 141 | sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |
137 | /* encrypt and sign */ | 142 | sizeof (struct GNUNET_TIME_AbsoluteNBO)); |
138 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, | 143 | block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); |
139 | label, | 144 | block->expiration_time = GNUNET_TIME_absolute_hton (expire); |
140 | "gns"); | 145 | /* encrypt and sign */ |
141 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, | 146 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, |
142 | &block->derived_key); | 147 | label, |
143 | derive_block_aes_key (&iv, | 148 | "gns"); |
144 | &skey, | 149 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, |
145 | label, | 150 | &block->derived_key); |
146 | pkey); | 151 | derive_block_aes_key (&iv, |
147 | GNUNET_break (payload_len + sizeof (uint32_t) == | 152 | &skey, |
148 | GNUNET_CRYPTO_symmetric_encrypt (payload, | 153 | label, |
149 | payload_len + sizeof (uint32_t), | 154 | pkey); |
150 | &skey, | 155 | GNUNET_break (payload_len + sizeof (uint32_t) == |
151 | &iv, | 156 | GNUNET_CRYPTO_symmetric_encrypt (payload, |
152 | &block[1])); | 157 | payload_len + sizeof (uint32_t), |
158 | &skey, | ||
159 | &iv, | ||
160 | &block[1])); | ||
161 | } | ||
153 | if (GNUNET_OK != | 162 | if (GNUNET_OK != |
154 | GNUNET_CRYPTO_ecdsa_sign (dkey, | 163 | GNUNET_CRYPTO_ecdsa_sign (dkey, |
155 | &block->purpose, | 164 | &block->purpose, |
@@ -246,6 +255,7 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
246 | GNUNET_CRYPTO_ecdsa_key_get_public (key, | 255 | GNUNET_CRYPTO_ecdsa_key_get_public (key, |
247 | &line->pkey); | 256 | &line->pkey); |
248 | } | 257 | } |
258 | #undef CSIZE | ||
249 | return block_create (key, | 259 | return block_create (key, |
250 | &line->pkey, | 260 | &line->pkey, |
251 | expire, | 261 | expire, |
@@ -304,18 +314,21 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
304 | GNUNET_break_op (0); | 314 | GNUNET_break_op (0); |
305 | return GNUNET_SYSERR; | 315 | return GNUNET_SYSERR; |
306 | } | 316 | } |
307 | derive_block_aes_key (&iv, &skey, label, zone_key); | 317 | derive_block_aes_key (&iv, |
318 | &skey, | ||
319 | label, | ||
320 | zone_key); | ||
308 | { | 321 | { |
309 | char payload[payload_len]; | 322 | char payload[payload_len]; |
310 | uint32_t rd_count; | 323 | uint32_t rd_count; |
311 | 324 | ||
312 | GNUNET_break (payload_len == | 325 | GNUNET_break (payload_len == |
313 | GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, | 326 | GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, |
314 | &skey, &iv, | 327 | &skey, &iv, |
315 | payload)); | 328 | payload)); |
316 | GNUNET_memcpy (&rd_count, | 329 | GNUNET_memcpy (&rd_count, |
317 | payload, | 330 | payload, |
318 | sizeof (uint32_t)); | 331 | sizeof (uint32_t)); |
319 | rd_count = ntohl (rd_count); | 332 | rd_count = ntohl (rd_count); |
320 | if (rd_count > 2048) | 333 | if (rd_count > 2048) |
321 | { | 334 | { |
@@ -324,7 +337,7 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
324 | return GNUNET_SYSERR; | 337 | return GNUNET_SYSERR; |
325 | } | 338 | } |
326 | { | 339 | { |
327 | struct GNUNET_GNSRECORD_Data rd[rd_count]; | 340 | struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)]; |
328 | unsigned int j; | 341 | unsigned int j; |
329 | struct GNUNET_TIME_Absolute now; | 342 | struct GNUNET_TIME_Absolute now; |
330 | 343 | ||
@@ -359,10 +372,15 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
359 | continue; | 372 | continue; |
360 | if (rd[i].expiration_time < now.abs_value_us) | 373 | if (rd[i].expiration_time < now.abs_value_us) |
361 | include_record = GNUNET_NO; /* Shadow record is expired */ | 374 | include_record = GNUNET_NO; /* Shadow record is expired */ |
362 | if ((rd[k].record_type == rd[i].record_type) | 375 | if ( (rd[k].record_type == rd[i].record_type) && |
363 | && (rd[k].expiration_time >= now.abs_value_us) | 376 | (rd[k].expiration_time >= now.abs_value_us) && |
364 | && (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))) | 377 | (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ) |
378 | { | ||
365 | include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ | 379 | include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */ |
380 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
381 | "Ignoring shadow record\n"); | ||
382 | break; | ||
383 | } | ||
366 | } | 384 | } |
367 | if (GNUNET_YES == include_record) | 385 | if (GNUNET_YES == include_record) |
368 | { | 386 | { |
@@ -379,6 +397,16 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block, | |||
379 | rd[j] = rd[i]; | 397 | rd[j] = rd[i]; |
380 | j++; | 398 | j++; |
381 | } | 399 | } |
400 | else | ||
401 | { | ||
402 | struct GNUNET_TIME_Absolute at; | ||
403 | |||
404 | at.abs_value_us = rd[i].expiration_time; | ||
405 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
406 | "Excluding record that expired %s (%llu ago)\n", | ||
407 | GNUNET_STRINGS_absolute_time_to_string (at), | ||
408 | (unsigned long long) rd[i].expiration_time - now.abs_value_us); | ||
409 | } | ||
382 | } | 410 | } |
383 | rd_count = j; | 411 | rd_count = j; |
384 | if (NULL != proc) | 412 | if (NULL != proc) |