diff options
Diffstat (limited to 'src/util/crypto_rsa.c')
-rw-r--r-- | src/util/crypto_rsa.c | 753 |
1 files changed, 370 insertions, 383 deletions
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index 7f0c81692..d29566ac8 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c | |||
@@ -66,13 +66,13 @@ struct RsaPrivateKeyBinaryEncoded | |||
66 | * Total size of the structure, in bytes, in big-endian! | 66 | * Total size of the structure, in bytes, in big-endian! |
67 | */ | 67 | */ |
68 | uint16_t len GNUNET_PACKED; | 68 | uint16_t len GNUNET_PACKED; |
69 | uint16_t sizen GNUNET_PACKED; /* in big-endian! */ | 69 | uint16_t sizen GNUNET_PACKED; /* in big-endian! */ |
70 | uint16_t sizee GNUNET_PACKED; /* in big-endian! */ | 70 | uint16_t sizee GNUNET_PACKED; /* in big-endian! */ |
71 | uint16_t sized GNUNET_PACKED; /* in big-endian! */ | 71 | uint16_t sized GNUNET_PACKED; /* in big-endian! */ |
72 | uint16_t sizep GNUNET_PACKED; /* in big-endian! */ | 72 | uint16_t sizep GNUNET_PACKED; /* in big-endian! */ |
73 | uint16_t sizeq GNUNET_PACKED; /* in big-endian! */ | 73 | uint16_t sizeq GNUNET_PACKED; /* in big-endian! */ |
74 | uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */ | 74 | uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */ |
75 | uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */ | 75 | uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */ |
76 | /* followed by the actual values */ | 76 | /* followed by the actual values */ |
77 | }; | 77 | }; |
78 | 78 | ||
@@ -98,10 +98,10 @@ static void | |||
98 | adjust (unsigned char *buf, size_t size, size_t target) | 98 | adjust (unsigned char *buf, size_t size, size_t target) |
99 | { | 99 | { |
100 | if (size < target) | 100 | if (size < target) |
101 | { | 101 | { |
102 | memmove (&buf[target - size], buf, size); | 102 | memmove (&buf[target - size], buf, size); |
103 | memset (buf, 0, target - size); | 103 | memset (buf, 0, target - size); |
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | /** | 107 | /** |
@@ -115,9 +115,9 @@ GNUNET_CRYPTO_rsa_key_create () | |||
115 | gcry_sexp_t s_keyparam; | 115 | gcry_sexp_t s_keyparam; |
116 | 116 | ||
117 | GNUNET_assert (0 == | 117 | GNUNET_assert (0 == |
118 | gcry_sexp_build (&s_keyparam, NULL, | 118 | gcry_sexp_build (&s_keyparam, NULL, |
119 | "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))", | 119 | "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))", |
120 | HOSTKEY_LEN)); | 120 | HOSTKEY_LEN)); |
121 | GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam)); | 121 | GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam)); |
122 | gcry_sexp_release (s_keyparam); | 122 | gcry_sexp_release (s_keyparam); |
123 | #if EXTRA_CHECKS | 123 | #if EXTRA_CHECKS |
@@ -140,7 +140,7 @@ GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) | |||
140 | 140 | ||
141 | static int | 141 | static int |
142 | key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, | 142 | key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, |
143 | const char *elems) | 143 | const char *elems) |
144 | { | 144 | { |
145 | gcry_sexp_t list, l2; | 145 | gcry_sexp_t list, l2; |
146 | const char *s; | 146 | const char *s; |
@@ -148,44 +148,44 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, | |||
148 | 148 | ||
149 | list = gcry_sexp_find_token (sexp, topname, 0); | 149 | list = gcry_sexp_find_token (sexp, topname, 0); |
150 | if (!list) | 150 | if (!list) |
151 | { | 151 | { |
152 | return 1; | 152 | return 1; |
153 | } | 153 | } |
154 | l2 = gcry_sexp_cadr (list); | 154 | l2 = gcry_sexp_cadr (list); |
155 | gcry_sexp_release (list); | 155 | gcry_sexp_release (list); |
156 | list = l2; | 156 | list = l2; |
157 | if (!list) | 157 | if (!list) |
158 | { | 158 | { |
159 | return 2; | 159 | return 2; |
160 | } | 160 | } |
161 | 161 | ||
162 | idx = 0; | 162 | idx = 0; |
163 | for (s = elems; *s; s++, idx++) | 163 | for (s = elems; *s; s++, idx++) |
164 | { | ||
165 | l2 = gcry_sexp_find_token (list, s, 1); | ||
166 | if (!l2) | ||
164 | { | 167 | { |
165 | l2 = gcry_sexp_find_token (list, s, 1); | 168 | for (i = 0; i < idx; i++) |
166 | if (!l2) | 169 | { |
167 | { | 170 | gcry_free (array[i]); |
168 | for (i = 0; i < idx; i++) | 171 | array[i] = NULL; |
169 | { | 172 | } |
170 | gcry_free (array[i]); | 173 | gcry_sexp_release (list); |
171 | array[i] = NULL; | 174 | return 3; /* required parameter not found */ |
172 | } | ||
173 | gcry_sexp_release (list); | ||
174 | return 3; /* required parameter not found */ | ||
175 | } | ||
176 | array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); | ||
177 | gcry_sexp_release (l2); | ||
178 | if (!array[idx]) | ||
179 | { | ||
180 | for (i = 0; i < idx; i++) | ||
181 | { | ||
182 | gcry_free (array[i]); | ||
183 | array[i] = NULL; | ||
184 | } | ||
185 | gcry_sexp_release (list); | ||
186 | return 4; /* required parameter is invalid */ | ||
187 | } | ||
188 | } | 175 | } |
176 | array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); | ||
177 | gcry_sexp_release (l2); | ||
178 | if (!array[idx]) | ||
179 | { | ||
180 | for (i = 0; i < idx; i++) | ||
181 | { | ||
182 | gcry_free (array[i]); | ||
183 | array[i] = NULL; | ||
184 | } | ||
185 | gcry_sexp_release (list); | ||
186 | return 4; /* required parameter is invalid */ | ||
187 | } | ||
188 | } | ||
189 | gcry_sexp_release (list); | 189 | gcry_sexp_release (list); |
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
@@ -197,10 +197,9 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname, | |||
197 | */ | 197 | */ |
198 | void | 198 | void |
199 | GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey | 199 | GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey |
200 | *priv, | 200 | *priv, |
201 | struct | 201 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded |
202 | GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded | 202 | *pub) |
203 | *pub) | ||
204 | { | 203 | { |
205 | gcry_mpi_t skey[2]; | 204 | gcry_mpi_t skey[2]; |
206 | size_t size; | 205 | size_t size; |
@@ -213,25 +212,24 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey | |||
213 | rc = key_from_sexp (skey, priv->sexp, "rsa", "ne"); | 212 | rc = key_from_sexp (skey, priv->sexp, "rsa", "ne"); |
214 | GNUNET_assert (0 == rc); | 213 | GNUNET_assert (0 == rc); |
215 | pub->len = | 214 | pub->len = |
216 | htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - | 215 | htons (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - |
217 | sizeof (pub->padding)); | 216 | sizeof (pub->padding)); |
218 | pub->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); | 217 | pub->sizen = htons (GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); |
219 | pub->padding = 0; | 218 | pub->padding = 0; |
220 | size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; | 219 | size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; |
221 | GNUNET_assert (0 == | 220 | GNUNET_assert (0 == |
222 | gcry_mpi_print (GCRYMPI_FMT_USG, &pub->key[0], size, &size, | 221 | gcry_mpi_print (GCRYMPI_FMT_USG, &pub->key[0], size, &size, |
223 | skey[0])); | 222 | skey[0])); |
224 | adjust (&pub->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); | 223 | adjust (&pub->key[0], size, GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); |
225 | size = | 224 | size = GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; |
226 | GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; | ||
227 | GNUNET_assert (0 == | 225 | GNUNET_assert (0 == |
228 | gcry_mpi_print (GCRYMPI_FMT_USG, | 226 | gcry_mpi_print (GCRYMPI_FMT_USG, |
229 | &pub->key | 227 | &pub->key |
230 | [GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], | 228 | [GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size, |
231 | size, &size, skey[1])); | 229 | &size, skey[1])); |
232 | adjust (&pub->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size, | 230 | adjust (&pub->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], size, |
233 | GNUNET_CRYPTO_RSA_KEY_LENGTH - | 231 | GNUNET_CRYPTO_RSA_KEY_LENGTH - |
234 | GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); | 232 | GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH); |
235 | gcry_mpi_release (skey[0]); | 233 | gcry_mpi_release (skey[0]); |
236 | gcry_mpi_release (skey[1]); | 234 | gcry_mpi_release (skey[1]); |
237 | } | 235 | } |
@@ -245,7 +243,7 @@ GNUNET_CRYPTO_rsa_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey | |||
245 | */ | 243 | */ |
246 | static struct GNUNET_CRYPTO_RsaPrivateKey * | 244 | static struct GNUNET_CRYPTO_RsaPrivateKey * |
247 | public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded | 245 | public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded |
248 | *publicKey) | 246 | *publicKey) |
249 | { | 247 | { |
250 | struct GNUNET_CRYPTO_RsaPrivateKey *ret; | 248 | struct GNUNET_CRYPTO_RsaPrivateKey *ret; |
251 | gcry_sexp_t result; | 249 | gcry_sexp_t result; |
@@ -259,38 +257,36 @@ public2PrivateKey (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded | |||
259 | (ntohs (publicKey->len) != | 257 | (ntohs (publicKey->len) != |
260 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - | 258 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) - |
261 | sizeof (publicKey->padding))) | 259 | sizeof (publicKey->padding))) |
262 | { | 260 | { |
263 | GNUNET_break (0); | 261 | GNUNET_break (0); |
264 | return NULL; | 262 | return NULL; |
265 | } | 263 | } |
266 | size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; | 264 | size = GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; |
267 | rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size); | 265 | rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size); |
268 | if (rc) | 266 | if (rc) |
269 | { | 267 | { |
270 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 268 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
271 | return NULL; | 269 | return NULL; |
272 | } | 270 | } |
273 | size = | 271 | size = GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; |
274 | GNUNET_CRYPTO_RSA_KEY_LENGTH - GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH; | 272 | rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG, |
275 | rc = | 273 | &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], |
276 | gcry_mpi_scan (&e, GCRYMPI_FMT_USG, | 274 | size, &size); |
277 | &publicKey->key[GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH], | ||
278 | size, &size); | ||
279 | if (rc) | 275 | if (rc) |
280 | { | 276 | { |
281 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 277 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
282 | gcry_mpi_release (n); | 278 | gcry_mpi_release (n); |
283 | return NULL; | 279 | return NULL; |
284 | } | 280 | } |
285 | rc = gcry_sexp_build (&result, &erroff, "(public-key(rsa(n %m)(e %m)))", n, | 281 | rc = gcry_sexp_build (&result, &erroff, "(public-key(rsa(n %m)(e %m)))", n, |
286 | e); | 282 | e); |
287 | gcry_mpi_release (n); | 283 | gcry_mpi_release (n); |
288 | gcry_mpi_release (e); | 284 | gcry_mpi_release (e); |
289 | if (rc) | 285 | if (rc) |
290 | { | 286 | { |
291 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ | 287 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ |
292 | return NULL; | 288 | return NULL; |
293 | } | 289 | } |
294 | ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); | 290 | ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); |
295 | ret->sexp = result; | 291 | ret->sexp = result; |
296 | return ret; | 292 | return ret; |
@@ -316,10 +312,10 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) | |||
316 | 312 | ||
317 | #if EXTRA_CHECKS | 313 | #if EXTRA_CHECKS |
318 | if (gcry_pk_testkey (hostkey->sexp)) | 314 | if (gcry_pk_testkey (hostkey->sexp)) |
319 | { | 315 | { |
320 | GNUNET_break (0); | 316 | GNUNET_break (0); |
321 | return NULL; | 317 | return NULL; |
322 | } | 318 | } |
323 | #endif | 319 | #endif |
324 | 320 | ||
325 | memset (pkv, 0, sizeof (gcry_mpi_t) * 6); | 321 | memset (pkv, 0, sizeof (gcry_mpi_t) * 6); |
@@ -337,21 +333,21 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) | |||
337 | GNUNET_assert (0 == rc); | 333 | GNUNET_assert (0 == rc); |
338 | size = sizeof (struct RsaPrivateKeyBinaryEncoded); | 334 | size = sizeof (struct RsaPrivateKeyBinaryEncoded); |
339 | for (i = 0; i < 6; i++) | 335 | for (i = 0; i < 6; i++) |
336 | { | ||
337 | if (pkv[i] != NULL) | ||
340 | { | 338 | { |
341 | if (pkv[i] != NULL) | 339 | GNUNET_assert (0 == |
342 | { | 340 | gcry_mpi_aprint (GCRYMPI_FMT_USG, |
343 | GNUNET_assert (0 == | 341 | (unsigned char **) &pbu[i], &sizes[i], |
344 | gcry_mpi_aprint (GCRYMPI_FMT_USG, | 342 | pkv[i])); |
345 | (unsigned char **) &pbu[i], | 343 | size += sizes[i]; |
346 | &sizes[i], pkv[i])); | ||
347 | size += sizes[i]; | ||
348 | } | ||
349 | else | ||
350 | { | ||
351 | pbu[i] = NULL; | ||
352 | sizes[i] = 0; | ||
353 | } | ||
354 | } | 344 | } |
345 | else | ||
346 | { | ||
347 | pbu[i] = NULL; | ||
348 | sizes[i] = 0; | ||
349 | } | ||
350 | } | ||
355 | GNUNET_assert (size < 65536); | 351 | GNUNET_assert (size < 65536); |
356 | retval = GNUNET_malloc (size); | 352 | retval = GNUNET_malloc (size); |
357 | retval->len = htons (size); | 353 | retval->len = htons (size); |
@@ -376,12 +372,12 @@ rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey) | |||
376 | retval->sizedmq1 = htons (0); | 372 | retval->sizedmq1 = htons (0); |
377 | memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]); | 373 | memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]); |
378 | for (i = 0; i < 6; i++) | 374 | for (i = 0; i < 6; i++) |
379 | { | 375 | { |
380 | if (pkv[i] != NULL) | 376 | if (pkv[i] != NULL) |
381 | gcry_mpi_release (pkv[i]); | 377 | gcry_mpi_release (pkv[i]); |
382 | if (pbu[i] != NULL) | 378 | if (pbu[i] != NULL) |
383 | free (pbu[i]); | 379 | free (pbu[i]); |
384 | } | 380 | } |
385 | return retval; | 381 | return retval; |
386 | } | 382 | } |
387 | 383 | ||
@@ -397,7 +393,7 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) | |||
397 | { | 393 | { |
398 | struct GNUNET_CRYPTO_RsaPrivateKey *ret; | 394 | struct GNUNET_CRYPTO_RsaPrivateKey *ret; |
399 | const struct RsaPrivateKeyBinaryEncoded *encoding = | 395 | const struct RsaPrivateKeyBinaryEncoded *encoding = |
400 | (const struct RsaPrivateKeyBinaryEncoded *) buf; | 396 | (const struct RsaPrivateKeyBinaryEncoded *) buf; |
401 | gcry_sexp_t res; | 397 | gcry_sexp_t res; |
402 | gcry_mpi_t n, e, d, p, q, u; | 398 | gcry_mpi_t n, e, d, p, q, u; |
403 | int rc; | 399 | int rc; |
@@ -412,122 +408,121 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) | |||
412 | pos = 0; | 408 | pos = 0; |
413 | size = ntohs (encoding->sizen); | 409 | size = ntohs (encoding->sizen); |
414 | rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, | 410 | rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, |
415 | &((const unsigned char *) (&encoding[1]))[pos], size, | 411 | &((const unsigned char *) (&encoding[1]))[pos], size, |
416 | &size); | 412 | &size); |
417 | pos += ntohs (encoding->sizen); | 413 | pos += ntohs (encoding->sizen); |
418 | if (rc) | 414 | if (rc) |
419 | { | 415 | { |
420 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 416 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
421 | return NULL; | 417 | return NULL; |
422 | } | 418 | } |
423 | size = ntohs (encoding->sizee); | 419 | size = ntohs (encoding->sizee); |
424 | rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG, | 420 | rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG, |
425 | &((const unsigned char *) (&encoding[1]))[pos], size, | 421 | &((const unsigned char *) (&encoding[1]))[pos], size, |
426 | &size); | 422 | &size); |
427 | pos += ntohs (encoding->sizee); | 423 | pos += ntohs (encoding->sizee); |
428 | if (rc) | 424 | if (rc) |
429 | { | 425 | { |
430 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 426 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
431 | gcry_mpi_release (n); | 427 | gcry_mpi_release (n); |
432 | return NULL; | 428 | return NULL; |
433 | } | 429 | } |
434 | size = ntohs (encoding->sized); | 430 | size = ntohs (encoding->sized); |
435 | rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG, | 431 | rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG, |
436 | &((const unsigned char *) (&encoding[1]))[pos], size, | 432 | &((const unsigned char *) (&encoding[1]))[pos], size, |
437 | &size); | 433 | &size); |
438 | pos += ntohs (encoding->sized); | 434 | pos += ntohs (encoding->sized); |
439 | if (rc) | 435 | if (rc) |
436 | { | ||
437 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
438 | gcry_mpi_release (n); | ||
439 | gcry_mpi_release (e); | ||
440 | return NULL; | ||
441 | } | ||
442 | /* swap p and q! */ | ||
443 | size = ntohs (encoding->sizep); | ||
444 | if (size > 0) | ||
445 | { | ||
446 | rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG, | ||
447 | &((const unsigned char *) (&encoding[1]))[pos], size, | ||
448 | &size); | ||
449 | pos += ntohs (encoding->sizep); | ||
450 | if (rc) | ||
440 | { | 451 | { |
441 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 452 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
442 | gcry_mpi_release (n); | 453 | gcry_mpi_release (n); |
443 | gcry_mpi_release (e); | 454 | gcry_mpi_release (e); |
455 | gcry_mpi_release (d); | ||
444 | return NULL; | 456 | return NULL; |
445 | } | 457 | } |
446 | /* swap p and q! */ | 458 | } |
447 | size = ntohs (encoding->sizep); | ||
448 | if (size > 0) | ||
449 | { | ||
450 | rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG, | ||
451 | &((const unsigned char *) (&encoding[1]))[pos], | ||
452 | size, &size); | ||
453 | pos += ntohs (encoding->sizep); | ||
454 | if (rc) | ||
455 | { | ||
456 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
457 | gcry_mpi_release (n); | ||
458 | gcry_mpi_release (e); | ||
459 | gcry_mpi_release (d); | ||
460 | return NULL; | ||
461 | } | ||
462 | } | ||
463 | else | 459 | else |
464 | q = NULL; | 460 | q = NULL; |
465 | size = ntohs (encoding->sizeq); | 461 | size = ntohs (encoding->sizeq); |
466 | if (size > 0) | 462 | if (size > 0) |
463 | { | ||
464 | rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG, | ||
465 | &((const unsigned char *) (&encoding[1]))[pos], size, | ||
466 | &size); | ||
467 | pos += ntohs (encoding->sizeq); | ||
468 | if (rc) | ||
467 | { | 469 | { |
468 | rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG, | 470 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
469 | &((const unsigned char *) (&encoding[1]))[pos], | 471 | gcry_mpi_release (n); |
470 | size, &size); | 472 | gcry_mpi_release (e); |
471 | pos += ntohs (encoding->sizeq); | 473 | gcry_mpi_release (d); |
472 | if (rc) | 474 | if (q != NULL) |
473 | { | 475 | gcry_mpi_release (q); |
474 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 476 | return NULL; |
475 | gcry_mpi_release (n); | ||
476 | gcry_mpi_release (e); | ||
477 | gcry_mpi_release (d); | ||
478 | if (q != NULL) | ||
479 | gcry_mpi_release (q); | ||
480 | return NULL; | ||
481 | } | ||
482 | } | 477 | } |
478 | } | ||
483 | else | 479 | else |
484 | p = NULL; | 480 | p = NULL; |
485 | pos += ntohs (encoding->sizedmp1); | 481 | pos += ntohs (encoding->sizedmp1); |
486 | pos += ntohs (encoding->sizedmq1); | 482 | pos += ntohs (encoding->sizedmq1); |
487 | size = | 483 | size = |
488 | ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos; | 484 | ntohs (encoding->len) - sizeof (struct RsaPrivateKeyBinaryEncoded) - pos; |
489 | if (size > 0) | 485 | if (size > 0) |
486 | { | ||
487 | rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG, | ||
488 | &((const unsigned char *) (&encoding[1]))[pos], size, | ||
489 | &size); | ||
490 | if (rc) | ||
490 | { | 491 | { |
491 | rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG, | 492 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
492 | &((const unsigned char *) (&encoding[1]))[pos], | 493 | gcry_mpi_release (n); |
493 | size, &size); | 494 | gcry_mpi_release (e); |
494 | if (rc) | 495 | gcry_mpi_release (d); |
495 | { | 496 | if (p != NULL) |
496 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | 497 | gcry_mpi_release (p); |
497 | gcry_mpi_release (n); | 498 | if (q != NULL) |
498 | gcry_mpi_release (e); | 499 | gcry_mpi_release (q); |
499 | gcry_mpi_release (d); | 500 | return NULL; |
500 | if (p != NULL) | ||
501 | gcry_mpi_release (p); | ||
502 | if (q != NULL) | ||
503 | gcry_mpi_release (q); | ||
504 | return NULL; | ||
505 | } | ||
506 | } | 501 | } |
502 | } | ||
507 | else | 503 | else |
508 | u = NULL; | 504 | u = NULL; |
509 | 505 | ||
510 | if ((p != NULL) && (q != NULL) && (u != NULL)) | 506 | if ((p != NULL) && (q != NULL) && (u != NULL)) |
507 | { | ||
508 | rc = gcry_sexp_build (&res, &size, /* erroff */ | ||
509 | "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))", | ||
510 | n, e, d, p, q, u); | ||
511 | } | ||
512 | else | ||
513 | { | ||
514 | if ((p != NULL) && (q != NULL)) | ||
511 | { | 515 | { |
512 | rc = gcry_sexp_build (&res, &size, /* erroff */ | 516 | rc = gcry_sexp_build (&res, &size, /* erroff */ |
513 | "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))", | 517 | "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))", |
514 | n, e, d, p, q, u); | 518 | n, e, d, p, q); |
515 | } | 519 | } |
516 | else | 520 | else |
517 | { | 521 | { |
518 | if ((p != NULL) && (q != NULL)) | 522 | rc = gcry_sexp_build (&res, &size, /* erroff */ |
519 | { | 523 | "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d); |
520 | rc = gcry_sexp_build (&res, &size, /* erroff */ | ||
521 | "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))", | ||
522 | n, e, d, p, q); | ||
523 | } | ||
524 | else | ||
525 | { | ||
526 | rc = gcry_sexp_build (&res, &size, /* erroff */ | ||
527 | "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, | ||
528 | d); | ||
529 | } | ||
530 | } | 524 | } |
525 | } | ||
531 | gcry_mpi_release (n); | 526 | gcry_mpi_release (n); |
532 | gcry_mpi_release (e); | 527 | gcry_mpi_release (e); |
533 | gcry_mpi_release (d); | 528 | gcry_mpi_release (d); |
@@ -542,10 +537,10 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len) | |||
542 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 537 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
543 | #if EXTRA_CHECKS | 538 | #if EXTRA_CHECKS |
544 | if (gcry_pk_testkey (res)) | 539 | if (gcry_pk_testkey (res)) |
545 | { | 540 | { |
546 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); | 541 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); |
547 | return NULL; | 542 | return NULL; |
548 | } | 543 | } |
549 | #endif | 544 | #endif |
550 | ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); | 545 | ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey)); |
551 | ret->sexp = res; | 546 | ret->sexp = res; |
@@ -582,172 +577,165 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) | |||
582 | if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) | 577 | if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) |
583 | return NULL; | 578 | return NULL; |
584 | while (GNUNET_YES != GNUNET_DISK_file_test (filename)) | 579 | while (GNUNET_YES != GNUNET_DISK_file_test (filename)) |
580 | { | ||
581 | fd = GNUNET_DISK_file_open (filename, | ||
582 | GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | ||
583 | | GNUNET_DISK_OPEN_FAILIFEXISTS, | ||
584 | GNUNET_DISK_PERM_USER_READ | | ||
585 | GNUNET_DISK_PERM_USER_WRITE); | ||
586 | if (NULL == fd) | ||
585 | { | 587 | { |
586 | fd = GNUNET_DISK_file_open (filename, | 588 | if (errno == EEXIST) |
587 | GNUNET_DISK_OPEN_WRITE | | 589 | { |
588 | GNUNET_DISK_OPEN_CREATE | | 590 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) |
589 | GNUNET_DISK_OPEN_FAILIFEXISTS, | 591 | { |
590 | GNUNET_DISK_PERM_USER_READ | | 592 | /* must exist but not be accessible, fail for good! */ |
591 | GNUNET_DISK_PERM_USER_WRITE); | 593 | if (0 != ACCESS (filename, R_OK)) |
592 | if (NULL == fd) | 594 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename); |
593 | { | 595 | else |
594 | if (errno == EEXIST) | 596 | GNUNET_break (0); /* what is going on!? */ |
595 | { | 597 | return NULL; |
596 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | 598 | } |
597 | { | 599 | continue; |
598 | /* must exist but not be accessible, fail for good! */ | 600 | } |
599 | if (0 != ACCESS (filename, R_OK)) | 601 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); |
600 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", | 602 | return NULL; |
601 | filename); | 603 | } |
602 | else | 604 | cnt = 0; |
603 | GNUNET_break (0); /* what is going on!? */ | 605 | |
604 | return NULL; | 606 | while (GNUNET_YES != |
605 | } | 607 | GNUNET_DISK_file_lock (fd, 0, |
606 | continue; | 608 | sizeof (struct RsaPrivateKeyBinaryEncoded), |
607 | } | 609 | GNUNET_YES)) |
608 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | 610 | { |
609 | return NULL; | 611 | sleep (1); |
610 | } | 612 | if (0 == ++cnt % 10) |
611 | cnt = 0; | 613 | { |
612 | 614 | ec = errno; | |
613 | while (GNUNET_YES != | 615 | LOG (GNUNET_ERROR_TYPE_ERROR, |
614 | GNUNET_DISK_file_lock (fd, 0, | 616 | _("Could not aquire lock on file `%s': %s...\n"), filename, |
615 | sizeof (struct | 617 | STRERROR (ec)); |
616 | RsaPrivateKeyBinaryEncoded), | 618 | } |
617 | GNUNET_YES)) | ||
618 | { | ||
619 | sleep (1); | ||
620 | if (0 == ++cnt % 10) | ||
621 | { | ||
622 | ec = errno; | ||
623 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
624 | _("Could not aquire lock on file `%s': %s...\n"), filename, | ||
625 | STRERROR (ec)); | ||
626 | } | ||
627 | } | ||
628 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
629 | _("Creating a new private key. This may take a while.\n")); | ||
630 | ret = GNUNET_CRYPTO_rsa_key_create (); | ||
631 | GNUNET_assert (ret != NULL); | ||
632 | enc = rsa_encode_key (ret); | ||
633 | GNUNET_assert (enc != NULL); | ||
634 | GNUNET_assert (ntohs (enc->len) == | ||
635 | GNUNET_DISK_file_write (fd, enc, ntohs (enc->len))); | ||
636 | GNUNET_free (enc); | ||
637 | |||
638 | GNUNET_DISK_file_sync (fd); | ||
639 | if (GNUNET_YES != | ||
640 | GNUNET_DISK_file_unlock (fd, 0, | ||
641 | sizeof (struct | ||
642 | RsaPrivateKeyBinaryEncoded))) | ||
643 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", 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 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
648 | _("I am host `%s'. Stored new private key in `%s'.\n"), | ||
649 | GNUNET_i2s (&pid), filename); | ||
650 | return ret; | ||
651 | } | 619 | } |
620 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
621 | _("Creating a new private key. This may take a while.\n")); | ||
622 | ret = GNUNET_CRYPTO_rsa_key_create (); | ||
623 | GNUNET_assert (ret != NULL); | ||
624 | enc = rsa_encode_key (ret); | ||
625 | GNUNET_assert (enc != NULL); | ||
626 | GNUNET_assert (ntohs (enc->len) == | ||
627 | GNUNET_DISK_file_write (fd, enc, ntohs (enc->len))); | ||
628 | GNUNET_free (enc); | ||
629 | |||
630 | GNUNET_DISK_file_sync (fd); | ||
631 | if (GNUNET_YES != | ||
632 | GNUNET_DISK_file_unlock (fd, 0, | ||
633 | sizeof (struct RsaPrivateKeyBinaryEncoded))) | ||
634 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
635 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); | ||
636 | GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); | ||
637 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); | ||
638 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
639 | _("I am host `%s'. Stored new private key in `%s'.\n"), | ||
640 | GNUNET_i2s (&pid), filename); | ||
641 | return ret; | ||
642 | } | ||
652 | /* hostkey file exists already, read it! */ | 643 | /* hostkey file exists already, read it! */ |
653 | fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, | 644 | fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, |
654 | GNUNET_DISK_PERM_NONE); | 645 | GNUNET_DISK_PERM_NONE); |
655 | if (NULL == fd) | 646 | if (NULL == fd) |
647 | { | ||
648 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
649 | return NULL; | ||
650 | } | ||
651 | cnt = 0; | ||
652 | while (1) | ||
653 | { | ||
654 | if (GNUNET_YES != | ||
655 | GNUNET_DISK_file_lock (fd, 0, | ||
656 | sizeof (struct RsaPrivateKeyBinaryEncoded), | ||
657 | GNUNET_NO)) | ||
656 | { | 658 | { |
657 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename); | 659 | if (0 == ++cnt % 60) |
660 | { | ||
661 | ec = errno; | ||
662 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
663 | _("Could not aquire lock on file `%s': %s...\n"), filename, | ||
664 | STRERROR (ec)); | ||
665 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
666 | _ | ||
667 | ("This may be ok if someone is currently generating a hostkey.\n")); | ||
668 | } | ||
669 | sleep (1); | ||
670 | continue; | ||
671 | } | ||
672 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
673 | { | ||
674 | /* eh, what!? File we opened is now gone!? */ | ||
675 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); | ||
676 | if (GNUNET_YES != | ||
677 | GNUNET_DISK_file_unlock (fd, 0, | ||
678 | sizeof (struct RsaPrivateKeyBinaryEncoded))) | ||
679 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
680 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); | ||
681 | |||
658 | return NULL; | 682 | return NULL; |
659 | } | 683 | } |
660 | cnt = 0; | 684 | if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES)) |
661 | while (1) | 685 | fs = 0; |
686 | if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded)) | ||
662 | { | 687 | { |
688 | /* maybe we got the read lock before the hostkey generating | ||
689 | * process had a chance to get the write lock; give it up! */ | ||
663 | if (GNUNET_YES != | 690 | if (GNUNET_YES != |
664 | GNUNET_DISK_file_lock (fd, 0, | 691 | GNUNET_DISK_file_unlock (fd, 0, |
665 | sizeof (struct RsaPrivateKeyBinaryEncoded), | 692 | sizeof (struct RsaPrivateKeyBinaryEncoded))) |
666 | GNUNET_NO)) | 693 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); |
667 | { | 694 | if (0 == ++cnt % 10) |
668 | if (0 == ++cnt % 60) | 695 | { |
669 | { | 696 | LOG (GNUNET_ERROR_TYPE_ERROR, |
670 | ec = errno; | 697 | _ |
671 | LOG (GNUNET_ERROR_TYPE_ERROR, | 698 | ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"), |
672 | _("Could not aquire lock on file `%s': %s...\n"), filename, | 699 | filename, (unsigned int) fs, |
673 | STRERROR (ec)); | 700 | (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded)); |
674 | LOG (GNUNET_ERROR_TYPE_ERROR, | 701 | LOG (GNUNET_ERROR_TYPE_ERROR, |
675 | _ | 702 | _ |
676 | ("This may be ok if someone is currently generating a hostkey.\n")); | 703 | ("This may be ok if someone is currently generating a hostkey.\n")); |
677 | } | 704 | } |
678 | sleep (1); | 705 | sleep (2); /* wait a bit longer! */ |
679 | continue; | 706 | continue; |
680 | } | ||
681 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
682 | { | ||
683 | /* eh, what!? File we opened is now gone!? */ | ||
684 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); | ||
685 | if (GNUNET_YES != | ||
686 | GNUNET_DISK_file_unlock (fd, 0, | ||
687 | sizeof (struct | ||
688 | RsaPrivateKeyBinaryEncoded))) | ||
689 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
690 | GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); | ||
691 | |||
692 | return NULL; | ||
693 | } | ||
694 | if (GNUNET_YES != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES)) | ||
695 | fs = 0; | ||
696 | if (fs < sizeof (struct RsaPrivateKeyBinaryEncoded)) | ||
697 | { | ||
698 | /* maybe we got the read lock before the hostkey generating | ||
699 | * process had a chance to get the write lock; give it up! */ | ||
700 | if (GNUNET_YES != | ||
701 | GNUNET_DISK_file_unlock (fd, 0, | ||
702 | sizeof (struct | ||
703 | RsaPrivateKeyBinaryEncoded))) | ||
704 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | ||
705 | if (0 == ++cnt % 10) | ||
706 | { | ||
707 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
708 | _ | ||
709 | ("When trying to read hostkey file `%s' I found %u bytes but I need at least %u.\n"), | ||
710 | filename, (unsigned int) fs, | ||
711 | (unsigned int) sizeof (struct RsaPrivateKeyBinaryEncoded)); | ||
712 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
713 | _ | ||
714 | ("This may be ok if someone is currently generating a hostkey.\n")); | ||
715 | } | ||
716 | sleep (2); /* wait a bit longer! */ | ||
717 | continue; | ||
718 | } | ||
719 | break; | ||
720 | } | 707 | } |
708 | break; | ||
709 | } | ||
721 | enc = GNUNET_malloc (fs); | 710 | enc = GNUNET_malloc (fs); |
722 | GNUNET_assert (fs == GNUNET_DISK_file_read (fd, enc, fs)); | 711 | GNUNET_assert (fs == GNUNET_DISK_file_read (fd, enc, fs)); |
723 | len = ntohs (enc->len); | 712 | len = ntohs (enc->len); |
724 | ret = NULL; | 713 | ret = NULL; |
725 | if ((len != fs) || | 714 | if ((len != fs) || |
726 | (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len)))) | 715 | (NULL == (ret = GNUNET_CRYPTO_rsa_decode_key ((char *) enc, len)))) |
716 | { | ||
717 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
718 | _("File `%s' does not contain a valid private key. Deleting it.\n"), | ||
719 | filename); | ||
720 | if (0 != UNLINK (filename)) | ||
727 | { | 721 | { |
728 | LOG (GNUNET_ERROR_TYPE_ERROR, | 722 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); |
729 | _ | ||
730 | ("File `%s' does not contain a valid private key. Deleting it.\n"), | ||
731 | filename); | ||
732 | if (0 != UNLINK (filename)) | ||
733 | { | ||
734 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); | ||
735 | } | ||
736 | } | 723 | } |
724 | } | ||
737 | GNUNET_free (enc); | 725 | GNUNET_free (enc); |
738 | if (GNUNET_YES != | 726 | if (GNUNET_YES != |
739 | GNUNET_DISK_file_unlock (fd, 0, | 727 | GNUNET_DISK_file_unlock (fd, 0, |
740 | sizeof (struct RsaPrivateKeyBinaryEncoded))) | 728 | sizeof (struct RsaPrivateKeyBinaryEncoded))) |
741 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); | 729 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); |
742 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); | 730 | GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); |
743 | if (ret != NULL) | 731 | if (ret != NULL) |
744 | { | 732 | { |
745 | GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); | 733 | GNUNET_CRYPTO_rsa_key_get_public (ret, &pub); |
746 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); | 734 | GNUNET_CRYPTO_hash (&pub, sizeof (pub), &pid.hashPubKey); |
747 | LOG (GNUNET_ERROR_TYPE_INFO, | 735 | LOG (GNUNET_ERROR_TYPE_INFO, |
748 | _("I am host `%s'. Read private key from `%s'.\n"), | 736 | _("I am host `%s'. Read private key from `%s'.\n"), GNUNET_i2s (&pid), |
749 | GNUNET_i2s (&pid), filename); | 737 | filename); |
750 | } | 738 | } |
751 | return ret; | 739 | return ret; |
752 | } | 740 | } |
753 | 741 | ||
@@ -764,9 +752,9 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) | |||
764 | */ | 752 | */ |
765 | int | 753 | int |
766 | GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, | 754 | GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, |
767 | const struct | 755 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded |
768 | GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey, | 756 | *publicKey, |
769 | struct GNUNET_CRYPTO_RsaEncryptedData *target) | 757 | struct GNUNET_CRYPTO_RsaEncryptedData *target) |
770 | { | 758 | { |
771 | gcry_sexp_t result; | 759 | gcry_sexp_t result; |
772 | gcry_sexp_t data; | 760 | gcry_sexp_t data; |
@@ -782,10 +770,10 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, | |||
782 | return GNUNET_SYSERR; | 770 | return GNUNET_SYSERR; |
783 | isize = size; | 771 | isize = size; |
784 | GNUNET_assert (0 == | 772 | GNUNET_assert (0 == |
785 | gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize)); | 773 | gcry_mpi_scan (&val, GCRYMPI_FMT_USG, block, isize, &isize)); |
786 | GNUNET_assert (0 == | 774 | GNUNET_assert (0 == |
787 | gcry_sexp_build (&data, &erroff, | 775 | gcry_sexp_build (&data, &erroff, |
788 | "(data (flags pkcs1)(value %m))", val)); | 776 | "(data (flags pkcs1)(value %m))", val)); |
789 | gcry_mpi_release (val); | 777 | gcry_mpi_release (val); |
790 | GNUNET_assert (0 == gcry_pk_encrypt (&result, data, pubkey->sexp)); | 778 | GNUNET_assert (0 == gcry_pk_encrypt (&result, data, pubkey->sexp)); |
791 | gcry_sexp_release (data); | 779 | gcry_sexp_release (data); |
@@ -795,11 +783,11 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, | |||
795 | gcry_sexp_release (result); | 783 | gcry_sexp_release (result); |
796 | isize = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData); | 784 | isize = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData); |
797 | GNUNET_assert (0 == | 785 | GNUNET_assert (0 == |
798 | gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) target, | 786 | gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) target, |
799 | isize, &isize, rval)); | 787 | isize, &isize, rval)); |
800 | gcry_mpi_release (rval); | 788 | gcry_mpi_release (rval); |
801 | adjust (&target->encoding[0], isize, | 789 | adjust (&target->encoding[0], isize, |
802 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); | 790 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); |
803 | return GNUNET_OK; | 791 | return GNUNET_OK; |
804 | } | 792 | } |
805 | 793 | ||
@@ -815,8 +803,8 @@ GNUNET_CRYPTO_rsa_encrypt (const void *block, size_t size, | |||
815 | */ | 803 | */ |
816 | ssize_t | 804 | ssize_t |
817 | GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key, | 805 | GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key, |
818 | const struct GNUNET_CRYPTO_RsaEncryptedData * | 806 | const struct GNUNET_CRYPTO_RsaEncryptedData * block, |
819 | block, void *result, size_t max) | 807 | void *result, size_t max) |
820 | { | 808 | { |
821 | gcry_sexp_t resultsexp; | 809 | gcry_sexp_t resultsexp; |
822 | gcry_sexp_t data; | 810 | gcry_sexp_t data; |
@@ -831,22 +819,21 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key, | |||
831 | #endif | 819 | #endif |
832 | size = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData); | 820 | size = sizeof (struct GNUNET_CRYPTO_RsaEncryptedData); |
833 | GNUNET_assert (0 == | 821 | GNUNET_assert (0 == |
834 | gcry_mpi_scan (&val, GCRYMPI_FMT_USG, &block->encoding[0], | 822 | gcry_mpi_scan (&val, GCRYMPI_FMT_USG, &block->encoding[0], |
835 | size, &size)); | 823 | size, &size)); |
836 | GNUNET_assert (0 == | 824 | GNUNET_assert (0 == |
837 | gcry_sexp_build (&data, &erroff, | 825 | gcry_sexp_build (&data, &erroff, "(enc-val(flags)(rsa(a %m)))", |
838 | "(enc-val(flags)(rsa(a %m)))", val)); | 826 | val)); |
839 | gcry_mpi_release (val); | 827 | gcry_mpi_release (val); |
840 | GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, key->sexp)); | 828 | GNUNET_assert (0 == gcry_pk_decrypt (&resultsexp, data, key->sexp)); |
841 | gcry_sexp_release (data); | 829 | gcry_sexp_release (data); |
842 | /* resultsexp has format "(value %m)" */ | 830 | /* resultsexp has format "(value %m)" */ |
843 | GNUNET_assert (NULL != | 831 | GNUNET_assert (NULL != |
844 | (val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG))); | 832 | (val = gcry_sexp_nth_mpi (resultsexp, 1, GCRYMPI_FMT_USG))); |
845 | gcry_sexp_release (resultsexp); | 833 | gcry_sexp_release (resultsexp); |
846 | tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8); | 834 | tmp = GNUNET_malloc (max + HOSTKEY_LEN / 8); |
847 | size = max + HOSTKEY_LEN / 8; | 835 | size = max + HOSTKEY_LEN / 8; |
848 | GNUNET_assert (0 == | 836 | GNUNET_assert (0 == gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val)); |
849 | gcry_mpi_print (GCRYMPI_FMT_USG, tmp, size, &size, val)); | ||
850 | gcry_mpi_release (val); | 837 | gcry_mpi_release (val); |
851 | endp = tmp; | 838 | endp = tmp; |
852 | endp += (size - max); | 839 | endp += (size - max); |
@@ -867,8 +854,8 @@ GNUNET_CRYPTO_rsa_decrypt (const struct GNUNET_CRYPTO_RsaPrivateKey * key, | |||
867 | */ | 854 | */ |
868 | int | 855 | int |
869 | GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | 856 | GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, |
870 | const struct GNUNET_CRYPTO_RsaSignaturePurpose | 857 | const struct GNUNET_CRYPTO_RsaSignaturePurpose *purpose, |
871 | *purpose, struct GNUNET_CRYPTO_RsaSignature *sig) | 858 | struct GNUNET_CRYPTO_RsaSignature *sig) |
872 | { | 859 | { |
873 | gcry_sexp_t result; | 860 | gcry_sexp_t result; |
874 | gcry_sexp_t data; | 861 | gcry_sexp_t data; |
@@ -884,10 +871,10 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | |||
884 | buff = GNUNET_malloc (bufSize); | 871 | buff = GNUNET_malloc (bufSize); |
885 | memcpy (buff, FORMATSTRING, bufSize); | 872 | memcpy (buff, FORMATSTRING, bufSize); |
886 | memcpy (&buff | 873 | memcpy (&buff |
887 | [bufSize - | 874 | [bufSize - |
888 | strlen | 875 | strlen |
889 | ("0123456789012345678901234567890123456789012345678901234567890123))") | 876 | ("0123456789012345678901234567890123456789012345678901234567890123))") |
890 | - 1], &hc, sizeof (GNUNET_HashCode)); | 877 | - 1], &hc, sizeof (GNUNET_HashCode)); |
891 | GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); | 878 | GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); |
892 | GNUNET_free (buff); | 879 | GNUNET_free (buff); |
893 | GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp)); | 880 | GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp)); |
@@ -896,8 +883,8 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | |||
896 | gcry_sexp_release (result); | 883 | gcry_sexp_release (result); |
897 | ssize = sizeof (struct GNUNET_CRYPTO_RsaSignature); | 884 | ssize = sizeof (struct GNUNET_CRYPTO_RsaSignature); |
898 | GNUNET_assert (0 == | 885 | GNUNET_assert (0 == |
899 | gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) sig, | 886 | gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) sig, ssize, |
900 | ssize, &ssize, rval)); | 887 | &ssize, rval)); |
901 | gcry_mpi_release (rval); | 888 | gcry_mpi_release (rval); |
902 | adjust (sig->sig, ssize, sizeof (struct GNUNET_CRYPTO_RsaSignature)); | 889 | adjust (sig->sig, ssize, sizeof (struct GNUNET_CRYPTO_RsaSignature)); |
903 | return GNUNET_OK; | 890 | return GNUNET_OK; |
@@ -915,11 +902,11 @@ GNUNET_CRYPTO_rsa_sign (const struct GNUNET_CRYPTO_RsaPrivateKey *key, | |||
915 | */ | 902 | */ |
916 | int | 903 | int |
917 | GNUNET_CRYPTO_rsa_verify (uint32_t purpose, | 904 | GNUNET_CRYPTO_rsa_verify (uint32_t purpose, |
918 | const struct GNUNET_CRYPTO_RsaSignaturePurpose | 905 | const struct GNUNET_CRYPTO_RsaSignaturePurpose |
919 | *validate, | 906 | *validate, |
920 | const struct GNUNET_CRYPTO_RsaSignature *sig, | 907 | const struct GNUNET_CRYPTO_RsaSignature *sig, |
921 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded | 908 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded |
922 | *publicKey) | 909 | *publicKey) |
923 | { | 910 | { |
924 | gcry_sexp_t data; | 911 | gcry_sexp_t data; |
925 | gcry_sexp_t sigdata; | 912 | gcry_sexp_t sigdata; |
@@ -933,44 +920,44 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose, | |||
933 | int rc; | 920 | int rc; |
934 | 921 | ||
935 | if (purpose != ntohl (validate->purpose)) | 922 | if (purpose != ntohl (validate->purpose)) |
936 | return GNUNET_SYSERR; /* purpose mismatch */ | 923 | return GNUNET_SYSERR; /* purpose mismatch */ |
937 | GNUNET_CRYPTO_hash (validate, ntohl (validate->size), &hc); | 924 | GNUNET_CRYPTO_hash (validate, ntohl (validate->size), &hc); |
938 | size = sizeof (struct GNUNET_CRYPTO_RsaSignature); | 925 | size = sizeof (struct GNUNET_CRYPTO_RsaSignature); |
939 | GNUNET_assert (0 == | 926 | GNUNET_assert (0 == |
940 | gcry_mpi_scan (&val, GCRYMPI_FMT_USG, | 927 | gcry_mpi_scan (&val, GCRYMPI_FMT_USG, |
941 | (const unsigned char *) sig, size, &size)); | 928 | (const unsigned char *) sig, size, &size)); |
942 | GNUNET_assert (0 == | 929 | GNUNET_assert (0 == |
943 | gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))", | 930 | gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))", |
944 | val)); | 931 | val)); |
945 | gcry_mpi_release (val); | 932 | gcry_mpi_release (val); |
946 | bufSize = strlen (FORMATSTRING) + 1; | 933 | bufSize = strlen (FORMATSTRING) + 1; |
947 | buff = GNUNET_malloc (bufSize); | 934 | buff = GNUNET_malloc (bufSize); |
948 | memcpy (buff, FORMATSTRING, bufSize); | 935 | memcpy (buff, FORMATSTRING, bufSize); |
949 | memcpy (&buff | 936 | memcpy (&buff |
950 | [strlen (FORMATSTRING) - | 937 | [strlen (FORMATSTRING) - |
951 | strlen | 938 | strlen |
952 | ("0123456789012345678901234567890123456789012345678901234567890123))")], | 939 | ("0123456789012345678901234567890123456789012345678901234567890123))")], |
953 | &hc, sizeof (GNUNET_HashCode)); | 940 | &hc, sizeof (GNUNET_HashCode)); |
954 | GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); | 941 | GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0)); |
955 | GNUNET_free (buff); | 942 | GNUNET_free (buff); |
956 | hostkey = public2PrivateKey (publicKey); | 943 | hostkey = public2PrivateKey (publicKey); |
957 | if (hostkey == NULL) | 944 | if (hostkey == NULL) |
958 | { | 945 | { |
959 | gcry_sexp_release (data); | 946 | gcry_sexp_release (data); |
960 | gcry_sexp_release (sigdata); | 947 | gcry_sexp_release (sigdata); |
961 | return GNUNET_SYSERR; | 948 | return GNUNET_SYSERR; |
962 | } | 949 | } |
963 | rc = gcry_pk_verify (sigdata, data, hostkey->sexp); | 950 | rc = gcry_pk_verify (sigdata, data, hostkey->sexp); |
964 | GNUNET_CRYPTO_rsa_key_free (hostkey); | 951 | GNUNET_CRYPTO_rsa_key_free (hostkey); |
965 | gcry_sexp_release (data); | 952 | gcry_sexp_release (data); |
966 | gcry_sexp_release (sigdata); | 953 | gcry_sexp_release (sigdata); |
967 | if (rc) | 954 | if (rc) |
968 | { | 955 | { |
969 | LOG (GNUNET_ERROR_TYPE_WARNING, | 956 | LOG (GNUNET_ERROR_TYPE_WARNING, |
970 | _("RSA signature verification failed at %s:%d: %s\n"), __FILE__, | 957 | _("RSA signature verification failed at %s:%d: %s\n"), __FILE__, |
971 | __LINE__, gcry_strerror (rc)); | 958 | __LINE__, gcry_strerror (rc)); |
972 | return GNUNET_SYSERR; | 959 | return GNUNET_SYSERR; |
973 | } | 960 | } |
974 | return GNUNET_OK; | 961 | return GNUNET_OK; |
975 | } | 962 | } |
976 | 963 | ||