aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_rsa.c')
-rw-r--r--src/util/crypto_rsa.c634
1 files changed, 308 insertions, 326 deletions
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c
index e0f56dea0..6be2f53c0 100644
--- a/src/util/crypto_rsa.c
+++ b/src/util/crypto_rsa.c
@@ -92,10 +92,10 @@ static void
92adjust (unsigned char *buf, size_t size, size_t target) 92adjust (unsigned char *buf, size_t size, size_t target)
93{ 93{
94 if (size < target) 94 if (size < target)
95 { 95 {
96 memmove (&buf[target - size], buf, size); 96 memmove (&buf[target - size], buf, size);
97 memset (buf, 0, target - size); 97 memset (buf, 0, target - size);
98 } 98 }
99} 99}
100 100
101/** 101/**
@@ -142,44 +142,44 @@ key_from_sexp (gcry_mpi_t * array,
142 142
143 list = gcry_sexp_find_token (sexp, topname, 0); 143 list = gcry_sexp_find_token (sexp, topname, 0);
144 if (!list) 144 if (!list)
145 { 145 {
146 return 1; 146 return 1;
147 } 147 }
148 l2 = gcry_sexp_cadr (list); 148 l2 = gcry_sexp_cadr (list);
149 gcry_sexp_release (list); 149 gcry_sexp_release (list);
150 list = l2; 150 list = l2;
151 if (!list) 151 if (!list)
152 { 152 {
153 return 2; 153 return 2;
154 } 154 }
155 155
156 idx = 0; 156 idx = 0;
157 for (s = elems; *s; s++, idx++) 157 for (s = elems; *s; s++, idx++)
158 {
159 l2 = gcry_sexp_find_token (list, s, 1);
160 if (!l2)
158 { 161 {
159 l2 = gcry_sexp_find_token (list, s, 1); 162 for (i = 0; i < idx; i++)
160 if (!l2) 163 {
161 { 164 gcry_free (array[i]);
162 for (i = 0; i < idx; i++) 165 array[i] = NULL;
163 { 166 }
164 gcry_free (array[i]); 167 gcry_sexp_release (list);
165 array[i] = NULL; 168 return 3; /* required parameter not found */
166 } 169 }
167 gcry_sexp_release (list); 170 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
168 return 3; /* required parameter not found */ 171 gcry_sexp_release (l2);
169 } 172 if (!array[idx])
170 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); 173 {
171 gcry_sexp_release (l2); 174 for (i = 0; i < idx; i++)
172 if (!array[idx]) 175 {
173 { 176 gcry_free (array[i]);
174 for (i = 0; i < idx; i++) 177 array[i] = NULL;
175 { 178 }
176 gcry_free (array[i]); 179 gcry_sexp_release (list);
177 array[i] = NULL; 180 return 4; /* required parameter is invalid */
178 }
179 gcry_sexp_release (list);
180 return 4; /* required parameter is invalid */
181 }
182 } 181 }
182 }
183 gcry_sexp_release (list); 183 gcry_sexp_release (list);
184 return 0; 184 return 0;
185} 185}
@@ -193,8 +193,7 @@ void
193GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey 193GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
194 *priv, 194 *priv,
195 struct 195 struct
196 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded 196 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub)
197 *pub)
198{ 197{
199 gcry_mpi_t skey[2]; 198 gcry_mpi_t skey[2];
200 size_t size; 199 size_t size;
@@ -207,16 +206,15 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey
207 rc = key_from_sexp (skey, priv->sexp, "rsa", "ne"); 206 rc = key_from_sexp (skey, priv->sexp, "rsa", "ne");
208 GNUNET_assert (0 == rc); 207 GNUNET_assert (0 == rc);
209 pub->len = 208 pub->len =
210 htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - 209 htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) -
211 sizeof (pub->padding)); 210 sizeof (pub->padding));
212 pub->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); 211 pub->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
213 pub->padding = 0; 212 pub->padding = 0;
214 size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; 213 size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
215 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, 214 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG,
216 &pub->key[0], size, &size, skey[0])); 215 &pub->key[0], size, &size, skey[0]));
217 adjust (&pub->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); 216 adjust (&pub->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH);
218 size = 217 size = GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
219 GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
220 GNUNET_assert (0 == 218 GNUNET_assert (0 ==
221 gcry_mpi_print (GCRYMPI_FMT_USG, 219 gcry_mpi_print (GCRYMPI_FMT_USG,
222 &pub->key 220 &pub->key
@@ -252,38 +250,36 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
252 (ntohs (publicKey->len) != 250 (ntohs (publicKey->len) !=
253 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - 251 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) -
254 sizeof (publicKey->padding))) 252 sizeof (publicKey->padding)))
255 { 253 {
256 GNUNET_break (0); 254 GNUNET_break (0);
257 return NULL; 255 return NULL;
258 } 256 }
259 size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; 257 size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
260 rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size); 258 rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size);
261 if (rc) 259 if (rc)
262 { 260 {
263 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 261 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
264 return NULL; 262 return NULL;
265 } 263 }
266 size = 264 size = GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH;
267 GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; 265 rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
268 rc = 266 &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
269 gcry_mpi_scan (&e, GCRYMPI_FMT_USG, 267 size, &size);
270 &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH],
271 size, &size);
272 if (rc) 268 if (rc)
273 { 269 {
274 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 270 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
275 gcry_mpi_release (n); 271 gcry_mpi_release (n);
276 return NULL; 272 return NULL;
277 } 273 }
278 rc = gcry_sexp_build (&result, 274 rc = gcry_sexp_build (&result,
279 &erroff, "(public-key(rsa(n %m)(e %m)))", n, e); 275 &erroff, "(public-key(rsa(n %m)(e %m)))", n, e);
280 gcry_mpi_release (n); 276 gcry_mpi_release (n);
281 gcry_mpi_release (e); 277 gcry_mpi_release (e);
282 if (rc) 278 if (rc)
283 { 279 {
284 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ 280 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */
285 return NULL; 281 return NULL;
286 } 282 }
287 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); 283 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
288 ret->sexp = result; 284 ret->sexp = result;
289 return ret; 285 return ret;
@@ -309,10 +305,10 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
309 305
310#if EXTRA_CHECKS 306#if EXTRA_CHECKS
311 if (gcry_pk_testkey (hostkey->sexp)) 307 if (gcry_pk_testkey (hostkey->sexp))
312 { 308 {
313 GNUNET_break (0); 309 GNUNET_break (0);
314 return NULL; 310 return NULL;
315 } 311 }
316#endif 312#endif
317 313
318 memset (pkv, 0, sizeof (gcry_mpi_t) * 6); 314 memset (pkv, 0, sizeof (gcry_mpi_t) * 6);
@@ -330,20 +326,20 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
330 GNUNET_assert (0 == rc); 326 GNUNET_assert (0 == rc);
331 size = sizeof (struct RsaPrivateKeyBinaryEncoded); 327 size = sizeof (struct RsaPrivateKeyBinaryEncoded);
332 for (i = 0; i < 6; i++) 328 for (i = 0; i < 6; i++)
329 {
330 if (pkv[i] != NULL)
333 { 331 {
334 if (pkv[i] != NULL) 332 GNUNET_assert (0 == gcry_mpi_aprint (GCRYMPI_FMT_USG,
335 { 333 (unsigned char **) &pbu[i],
336 GNUNET_assert (0 == gcry_mpi_aprint (GCRYMPI_FMT_USG, 334 &sizes[i], pkv[i]));
337 (unsigned char **) &pbu[i], 335 size += sizes[i];
338 &sizes[i], pkv[i]));
339 size += sizes[i];
340 }
341 else
342 {
343 pbu[i] = NULL;
344 sizes[i] = 0;
345 }
346 } 336 }
337 else
338 {
339 pbu[i] = NULL;
340 sizes[i] = 0;
341 }
342 }
347 GNUNET_assert (size < 65536); 343 GNUNET_assert (size < 65536);
348 retval = GNUNET_malloc (size); 344 retval = GNUNET_malloc (size);
349 retval->len = htons (size); 345 retval->len = htons (size);
@@ -368,12 +364,12 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey)
368 retval->sizedmq1 = htons (0); 364 retval->sizedmq1 = htons (0);
369 memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]); 365 memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]);
370 for (i = 0; i < 6; i++) 366 for (i = 0; i < 6; i++)
371 { 367 {
372 if (pkv[i] != NULL) 368 if (pkv[i] != NULL)
373 gcry_mpi_release (pkv[i]); 369 gcry_mpi_release (pkv[i]);
374 if (pbu[i] != NULL) 370 if (pbu[i] != NULL)
375 free (pbu[i]); 371 free (pbu[i]);
376 } 372 }
377 return retval; 373 return retval;
378} 374}
379 375
@@ -388,7 +384,8 @@ struct GNUNET_CRYPTO_RsaPrivateKey *
388GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) 384GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
389{ 385{
390 struct GNUNET_CRYPTO_RsaPrivateKey *ret; 386 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
391 const struct RsaPrivateKeyBinaryEncoded *encoding = (const struct RsaPrivateKeyBinaryEncoded *)buf; 387 const struct RsaPrivateKeyBinaryEncoded *encoding =
388 (const struct RsaPrivateKeyBinaryEncoded *) buf;
392 gcry_sexp_t res; 389 gcry_sexp_t res;
393 gcry_mpi_t n, e, d, p, q, u; 390 gcry_mpi_t n, e, d, p, q, u;
394 int rc; 391 int rc;
@@ -396,7 +393,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
396 int pos; 393 int pos;
397 uint16_t enc_len; 394 uint16_t enc_len;
398 395
399 enc_len = ntohs(encoding->len); 396 enc_len = ntohs (encoding->len);
400 if (len != enc_len) 397 if (len != enc_len)
401 return NULL; 398 return NULL;
402 399
@@ -408,10 +405,10 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
408 size, &size); 405 size, &size);
409 pos += ntohs (encoding->sizen); 406 pos += ntohs (encoding->sizen);
410 if (rc) 407 if (rc)
411 { 408 {
412 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 409 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
413 return NULL; 410 return NULL;
414 } 411 }
415 size = ntohs (encoding->sizee); 412 size = ntohs (encoding->sizee);
416 rc = gcry_mpi_scan (&e, 413 rc = gcry_mpi_scan (&e,
417 GCRYMPI_FMT_USG, 414 GCRYMPI_FMT_USG,
@@ -419,11 +416,11 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
419 size, &size); 416 size, &size);
420 pos += ntohs (encoding->sizee); 417 pos += ntohs (encoding->sizee);
421 if (rc) 418 if (rc)
422 { 419 {
423 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 420 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
424 gcry_mpi_release (n); 421 gcry_mpi_release (n);
425 return NULL; 422 return NULL;
426 } 423 }
427 size = ntohs (encoding->sized); 424 size = ntohs (encoding->sized);
428 rc = gcry_mpi_scan (&d, 425 rc = gcry_mpi_scan (&d,
429 GCRYMPI_FMT_USG, 426 GCRYMPI_FMT_USG,
@@ -431,100 +428,99 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
431 size, &size); 428 size, &size);
432 pos += ntohs (encoding->sized); 429 pos += ntohs (encoding->sized);
433 if (rc) 430 if (rc)
431 {
432 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
433 gcry_mpi_release (n);
434 gcry_mpi_release (e);
435 return NULL;
436 }
437 /* swap p and q! */
438 size = ntohs (encoding->sizep);
439 if (size > 0)
440 {
441 rc = gcry_mpi_scan (&q,
442 GCRYMPI_FMT_USG,
443 &((const unsigned char *) (&encoding[1]))[pos],
444 size, &size);
445 pos += ntohs (encoding->sizep);
446 if (rc)
434 { 447 {
435 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 448 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
436 gcry_mpi_release (n); 449 gcry_mpi_release (n);
437 gcry_mpi_release (e); 450 gcry_mpi_release (e);
451 gcry_mpi_release (d);
438 return NULL; 452 return NULL;
439 } 453 }
440 /* swap p and q! */ 454 }
441 size = ntohs (encoding->sizep);
442 if (size > 0)
443 {
444 rc = gcry_mpi_scan (&q,
445 GCRYMPI_FMT_USG,
446 &((const unsigned char *) (&encoding[1]))[pos],
447 size, &size);
448 pos += ntohs (encoding->sizep);
449 if (rc)
450 {
451 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
452 gcry_mpi_release (n);
453 gcry_mpi_release (e);
454 gcry_mpi_release (d);
455 return NULL;
456 }
457 }
458 else 455 else
459 q = NULL; 456 q = NULL;
460 size = ntohs (encoding->sizeq); 457 size = ntohs (encoding->sizeq);
461 if (size > 0) 458 if (size > 0)
459 {
460 rc = gcry_mpi_scan (&p,
461 GCRYMPI_FMT_USG,
462 &((const unsigned char *) (&encoding[1]))[pos],
463 size, &size);
464 pos += ntohs (encoding->sizeq);
465 if (rc)
462 { 466 {
463 rc = gcry_mpi_scan (&p, 467 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
464 GCRYMPI_FMT_USG, 468 gcry_mpi_release (n);
465 &((const unsigned char *) (&encoding[1]))[pos], 469 gcry_mpi_release (e);
466 size, &size); 470 gcry_mpi_release (d);
467 pos += ntohs (encoding->sizeq); 471 if (q != NULL)
468 if (rc) 472 gcry_mpi_release (q);
469 { 473 return NULL;
470 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
471 gcry_mpi_release (n);
472 gcry_mpi_release (e);
473 gcry_mpi_release (d);
474 if (q != NULL)
475 gcry_mpi_release (q);
476 return NULL;
477 }
478 } 474 }
475 }
479 else 476 else
480 p = NULL; 477 p = NULL;
481 pos += ntohs (encoding->sizedmp1); 478 pos += ntohs (encoding->sizedmp1);
482 pos += ntohs (encoding->sizedmq1); 479 pos += ntohs (encoding->sizedmq1);
483 size = 480 size =
484 ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos; 481 ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos;
485 if (size > 0) 482 if (size > 0)
483 {
484 rc = gcry_mpi_scan (&u,
485 GCRYMPI_FMT_USG,
486 &((const unsigned char *) (&encoding[1]))[pos],
487 size, &size);
488 if (rc)
486 { 489 {
487 rc = gcry_mpi_scan (&u, 490 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
488 GCRYMPI_FMT_USG, 491 gcry_mpi_release (n);
489 &((const unsigned char *) (&encoding[1]))[pos], 492 gcry_mpi_release (e);
490 size, &size); 493 gcry_mpi_release (d);
491 if (rc) 494 if (p != NULL)
492 { 495 gcry_mpi_release (p);
493 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 496 if (q != NULL)
494 gcry_mpi_release (n); 497 gcry_mpi_release (q);
495 gcry_mpi_release (e); 498 return NULL;
496 gcry_mpi_release (d);
497 if (p != NULL)
498 gcry_mpi_release (p);
499 if (q != NULL)
500 gcry_mpi_release (q);
501 return NULL;
502 }
503 } 499 }
500 }
504 else 501 else
505 u = NULL; 502 u = NULL;
506 503
507 if ((p != NULL) && (q != NULL) && (u != NULL)) 504 if ((p != NULL) && (q != NULL) && (u != NULL))
505 {
506 rc = gcry_sexp_build (&res, &size, /* erroff */
507 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
508 n, e, d, p, q, u);
509 }
510 else
511 {
512 if ((p != NULL) && (q != NULL))
508 { 513 {
509 rc = gcry_sexp_build (&res, &size, /* erroff */ 514 rc = gcry_sexp_build (&res, &size, /* erroff */
510 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))", 515 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
511 n, e, d, p, q, u); 516 n, e, d, p, q);
512 } 517 }
513 else 518 else
514 { 519 {
515 if ((p != NULL) && (q != NULL)) 520 rc = gcry_sexp_build (&res, &size, /* erroff */
516 { 521 "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
517 rc = gcry_sexp_build (&res, &size, /* erroff */
518 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
519 n, e, d, p, q);
520 }
521 else
522 {
523 rc = gcry_sexp_build (&res, &size, /* erroff */
524 "(private-key(rsa(n %m)(e %m)(d %m)))",
525 n, e, d);
526 }
527 } 522 }
523 }
528 gcry_mpi_release (n); 524 gcry_mpi_release (n);
529 gcry_mpi_release (e); 525 gcry_mpi_release (e);
530 gcry_mpi_release (d); 526 gcry_mpi_release (d);
@@ -539,10 +535,10 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len)
539 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 535 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
540#if EXTRA_CHECKS 536#if EXTRA_CHECKS
541 if (gcry_pk_testkey (res)) 537 if (gcry_pk_testkey (res))
542 { 538 {
543 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); 539 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
544 return NULL; 540 return NULL;
545 } 541 }
546#endif 542#endif
547 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); 543 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
548 ret->sexp = res; 544 ret->sexp = res;
@@ -579,167 +575,156 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
579 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) 575 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
580 return NULL; 576 return NULL;
581 while (GNUNET_YES != GNUNET_DISK_file_test (filename)) 577 while (GNUNET_YES != GNUNET_DISK_file_test (filename))
578 {
579 fd = GNUNET_DISK_file_open (filename,
580 GNUNET_DISK_OPEN_WRITE |
581 GNUNET_DISK_OPEN_CREATE |
582 GNUNET_DISK_OPEN_FAILIFEXISTS,
583 GNUNET_DISK_PERM_USER_READ |
584 GNUNET_DISK_PERM_USER_WRITE);
585 if (NULL == fd)
582 { 586 {
583 fd = GNUNET_DISK_file_open (filename, 587 if (errno == EEXIST)
584 GNUNET_DISK_OPEN_WRITE | 588 {
585 GNUNET_DISK_OPEN_CREATE | 589 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
586 GNUNET_DISK_OPEN_FAILIFEXISTS,
587 GNUNET_DISK_PERM_USER_READ |
588 GNUNET_DISK_PERM_USER_WRITE);
589 if (NULL == fd)
590 { 590 {
591 if (errno == EEXIST) 591 /* must exist but not be accessible, fail for good! */
592 { 592 if (0 != ACCESS (filename, R_OK))
593 if (GNUNET_YES != GNUNET_DISK_file_test (filename)) 593 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
594 { 594 "access", filename);
595 /* must exist but not be accessible, fail for good! */ 595 else
596 if (0 != ACCESS (filename, R_OK)) 596 GNUNET_break (0); /* what is going on!? */
597 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
598 "access", filename);
599 else
600 GNUNET_break (0); /* what is going on!? */
601 return NULL;
602 }
603 continue;
604 }
605 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
606 "open", filename);
607 return NULL; 597 return NULL;
608 } 598 }
609 cnt = 0; 599 continue;
600 }
601 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename);
602 return NULL;
603 }
604 cnt = 0;
610 605
611 while (GNUNET_YES != 606 while (GNUNET_YES !=
612 GNUNET_DISK_file_lock (fd, 0, 607 GNUNET_DISK_file_lock (fd, 0,
613 sizeof (struct 608 sizeof (struct
614 RsaPrivateKeyBinaryEncoded), 609 RsaPrivateKeyBinaryEncoded),
615 GNUNET_YES)) 610 GNUNET_YES))
616 { 611 {
617 sleep (1); 612 sleep (1);
618 if (0 == ++cnt % 10) 613 if (0 == ++cnt % 10)
619 { 614 {
620 ec = errno; 615 ec = errno;
621 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 616 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
622 _ 617 _
623 ("Could not aquire lock on file `%s': %s...\n"), 618 ("Could not aquire lock on file `%s': %s...\n"),
624 filename, STRERROR (ec)); 619 filename, STRERROR (ec));
625 } 620 }
626 }
627 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
628 _("Creating a new private key. This may take a while.\n"));
629 ret = GNUNET_CRYPTO_rsa_key_create ();
630 GNUNET_assert (ret != NULL);
631 enc = rsa_encode_key (ret);
632 GNUNET_assert (enc != NULL);
633 GNUNET_assert (ntohs (enc->len) ==
634 GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
635 GNUNET_free (enc);
636
637 GNUNET_DISK_file_sync (fd);
638 if (GNUNET_YES !=
639 GNUNET_DISK_file_unlock (fd, 0,
640 sizeof (struct
641 RsaPrivateKeyBinaryEncoded)))
642 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl",
643 filename);
644 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
645 GNUNET_CRYPTO_rsa_key_get_public (ret, &pub);
646 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
647 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
648 _("I am host `%s'. Stored new private key in `%s'.\n"),
649 GNUNET_i2s (&pid),
650 filename);
651 return ret;
652 } 621 }
622 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
623 _("Creating a new private key. This may take a while.\n"));
624 ret = GNUNET_CRYPTO_rsa_key_create ();
625 GNUNET_assert (ret != NULL);
626 enc = rsa_encode_key (ret);
627 GNUNET_assert (enc != NULL);
628 GNUNET_assert (ntohs (enc->len) ==
629 GNUNET_DISK_file_write (fd, enc, ntohs (enc->len)));
630 GNUNET_free (enc);
631
632 GNUNET_DISK_file_sync (fd);
633 if (GNUNET_YES !=
634 GNUNET_DISK_file_unlock (fd, 0,
635 sizeof (struct RsaPrivateKeyBinaryEncoded)))
636 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
637 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
638 GNUNET_CRYPTO_rsa_key_get_public (ret, &pub);
639 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
640 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
641 _("I am host `%s'. Stored new private key in `%s'.\n"),
642 GNUNET_i2s (&pid), filename);
643 return ret;
644 }
653 /* hostkey file exists already, read it! */ 645 /* hostkey file exists already, read it! */
654 fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, 646 fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
655 GNUNET_DISK_PERM_NONE); 647 GNUNET_DISK_PERM_NONE);
656 if (NULL == fd) 648 if (NULL == fd)
657 { 649 {
658 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename); 650 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename);
659 return NULL; 651 return NULL;
660 } 652 }
661 cnt = 0; 653 cnt = 0;
662 while (1) 654 while (1)
655 {
656 if (GNUNET_YES !=
657 GNUNET_DISK_file_lock (fd, 0,
658 sizeof (struct RsaPrivateKeyBinaryEncoded),
659 GNUNET_NO))
663 { 660 {
661 if (0 == ++cnt % 60)
662 {
663 ec = errno;
664 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
665 _("Could not aquire lock on file `%s': %s...\n"),
666 filename, STRERROR (ec));
667 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
668 _
669 ("This may be ok if someone is currently generating a hostkey.\n"));
670 }
671 sleep (1);
672 continue;
673 }
674 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
675 {
676 /* eh, what!? File we opened is now gone!? */
677 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
664 if (GNUNET_YES != 678 if (GNUNET_YES !=
665 GNUNET_DISK_file_lock (fd, 0, 679 GNUNET_DISK_file_unlock (fd, 0,
666 sizeof (struct RsaPrivateKeyBinaryEncoded), 680 sizeof (struct RsaPrivateKeyBinaryEncoded)))
667 GNUNET_NO)) 681 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
668 { 682 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
669 if (0 == ++cnt % 60)
670 {
671 ec = errno;
672 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
673 _("Could not aquire lock on file `%s': %s...\n"),
674 filename, STRERROR (ec));
675 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
676 _
677 ("This may be ok if someone is currently generating a hostkey.\n"));
678 }
679 sleep (1);
680 continue;
681 }
682 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
683 {
684 /* eh, what!? File we opened is now gone!? */
685 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
686 "stat", filename);
687 if (GNUNET_YES !=
688 GNUNET_DISK_file_unlock (fd, 0,
689 sizeof (struct
690 RsaPrivateKeyBinaryEncoded)))
691 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl",
692 filename);
693 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
694 683
695 return NULL; 684 return NULL;
696 } 685 }
697 if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES)) 686 if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES))
698 fs = 0; 687 fs = 0;
699 if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded)) 688 if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded))
700 { 689 {
701 /* maybe we got the read lock before the hostkey generating 690 /* maybe we got the read lock before the hostkey generating
702 process had a chance to get the write lock; give it up! */ 691 * process had a chance to get the write lock; give it up! */
703 if (GNUNET_YES != 692 if (GNUNET_YES !=
704 GNUNET_DISK_file_unlock (fd, 0, 693 GNUNET_DISK_file_unlock (fd, 0,
705 sizeof (struct 694 sizeof (struct RsaPrivateKeyBinaryEncoded)))
706 RsaPrivateKeyBinaryEncoded))) 695 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
707 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", 696 if (0 == ++cnt % 10)
708 filename); 697 {
709 if (0 == ++cnt % 10) 698 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
710 { 699 _
711 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 700 ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"),
712 _ 701 filename, (unsigned int) fs,
713 ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"), 702 (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded));
714 filename, (unsigned int) fs, 703 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
715 (unsigned int) sizeof (struct 704 _
716 RsaPrivateKeyBinaryEncoded)); 705 ("This may be ok if someone is currently generating a hostkey.\n"));
717 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 706 }
718 _ 707 sleep (2); /* wait a bit longer! */
719 ("This may be ok if someone is currently generating a hostkey.\n")); 708 continue;
720 }
721 sleep (2); /* wait a bit longer! */
722 continue;
723 }
724 break;
725 } 709 }
710 break;
711 }
726 enc = GNUNET_malloc (fs); 712 enc = GNUNET_malloc (fs);
727 GNUNET_assert (fs == GNUNET_DISK_file_read (fd, enc, fs)); 713 GNUNET_assert (fs == GNUNET_DISK_file_read (fd, enc, fs));
728 len = ntohs (enc->len); 714 len = ntohs (enc->len);
729 ret = NULL; 715 ret = NULL;
730 if ((len != fs) || (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *)enc, len)))) 716 if ((len != fs) ||
717 (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len))))
718 {
719 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
720 _
721 ("File `%s' does not contain a valid private key. Deleting it.\n"),
722 filename);
723 if (0 != UNLINK (filename))
731 { 724 {
732 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 725 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
733 _
734 ("File `%s' does not contain a valid private key. Deleting it.\n"),
735 filename);
736 if (0 != UNLINK (filename))
737 {
738 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
739 "unlink",
740 filename);
741 }
742 } 726 }
727 }
743 GNUNET_free (enc); 728 GNUNET_free (enc);
744 if (GNUNET_YES != 729 if (GNUNET_YES !=
745 GNUNET_DISK_file_unlock (fd, 0, 730 GNUNET_DISK_file_unlock (fd, 0,
@@ -747,14 +732,13 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename)
747 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); 732 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
748 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); 733 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
749 if (ret != NULL) 734 if (ret != NULL)
750 { 735 {
751 GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); 736 GNUNET_CRYPTO_rsa_key_get_public (ret, &pub);
752 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); 737 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey);
753 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 738 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
754 _("I am host `%s'. Read private key from `%s'.\n"), 739 _("I am host `%s'. Read private key from `%s'.\n"),
755 GNUNET_i2s (&pid), 740 GNUNET_i2s (&pid), filename);
756 filename); 741 }
757 }
758 return ret; 742 return ret;
759} 743}
760 744
@@ -853,8 +837,7 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key,
853 gcry_sexp_release (resultsexp); 837 gcry_sexp_release (resultsexp);
854 tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8); 838 tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8);
855 size = max + HOSTKEY_LEN / 8; 839 size = max + HOSTKEY_LEN / 8;
856 GNUNET_assert (0 == 840 GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val));
857 gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val));
858 gcry_mpi_release (val); 841 gcry_mpi_release (val);
859 endp = tmp; 842 endp = tmp;
860 endp += (size - max); 843 endp += (size - max);
@@ -946,8 +929,7 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
946 size = sizeof (struct GNUNET_CRYPTO_RsaSignature); 929 size = sizeof (struct GNUNET_CRYPTO_RsaSignature);
947 GNUNET_assert (0 == gcry_mpi_scan (&val, 930 GNUNET_assert (0 == gcry_mpi_scan (&val,
948 GCRYMPI_FMT_USG, 931 GCRYMPI_FMT_USG,
949 (const unsigned char *) sig, size, 932 (const unsigned char *) sig, size, &size));
950 &size));
951 GNUNET_assert (0 == 933 GNUNET_assert (0 ==
952 gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))", 934 gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))",
953 val)); 935 val));
@@ -963,22 +945,22 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose,
963 GNUNET_free (buff); 945 GNUNET_free (buff);
964 hostkey = public2PrivateKey (publicKey); 946 hostkey = public2PrivateKey (publicKey);
965 if (hostkey == NULL) 947 if (hostkey == NULL)
966 { 948 {
967 gcry_sexp_release (data); 949 gcry_sexp_release (data);
968 gcry_sexp_release (sigdata); 950 gcry_sexp_release (sigdata);
969 return GNUNET_SYSERR; 951 return GNUNET_SYSERR;
970 } 952 }
971 rc = gcry_pk_verify (sigdata, data, hostkey->sexp); 953 rc = gcry_pk_verify (sigdata, data, hostkey->sexp);
972 GNUNET_CRYPTO_rsa_key_free (hostkey); 954 GNUNET_CRYPTO_rsa_key_free (hostkey);
973 gcry_sexp_release (data); 955 gcry_sexp_release (data);
974 gcry_sexp_release (sigdata); 956 gcry_sexp_release (sigdata);
975 if (rc) 957 if (rc)
976 { 958 {
977 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 959 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
978 _("RSA signature verification failed at %s:%d: %s\n"), 960 _("RSA signature verification failed at %s:%d: %s\n"),
979 __FILE__, __LINE__, gcry_strerror (rc)); 961 __FILE__, __LINE__, gcry_strerror (rc));
980 return GNUNET_SYSERR; 962 return GNUNET_SYSERR;
981 } 963 }
982 return GNUNET_OK; 964 return GNUNET_OK;
983} 965}
984 966