aboutsummaryrefslogtreecommitdiff
path: root/src/gnsrecord/gnsrecord_crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnsrecord/gnsrecord_crypto.c')
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c142
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)