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