updated copyright information
[strongswan.git] / src / libstrongswan / crypto / rsa / rsa_private_key.c
1 /**
2 * @file rsa_private_key.c
3 *
4 * @brief Implementation of rsa_private_key_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <gmp.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <string.h>
28
29 #include "rsa_public_key.h"
30 #include "rsa_private_key.h"
31
32 #include <asn1/asn1.h>
33 #include <asn1/pem.h>
34 #include <utils/randomizer.h>
35
36 /**
37 * OIDs for hash algorithms are defined in rsa_public_key.c.
38 */
39 extern u_int8_t md2_oid[18];
40 extern u_int8_t md5_oid[18];
41 extern u_int8_t sha1_oid[15];
42 extern u_int8_t sha256_oid[19];
43 extern u_int8_t sha384_oid[19];
44 extern u_int8_t sha512_oid[19];
45
46
47 /**
48 * Public exponent to use for key generation.
49 */
50 #define PUBLIC_EXPONENT 0x10001
51
52
53 typedef struct private_rsa_private_key_t private_rsa_private_key_t;
54
55 /**
56 * Private data of a rsa_private_key_t object.
57 */
58 struct private_rsa_private_key_t {
59 /**
60 * Public interface for this signer.
61 */
62 rsa_private_key_t public;
63
64 /**
65 * Version of key, as encoded in PKCS#1
66 */
67 u_int version;
68
69 /**
70 * Public modulus.
71 */
72 mpz_t n;
73
74 /**
75 * Public exponent.
76 */
77 mpz_t e;
78
79 /**
80 * Private prime 1.
81 */
82 mpz_t p;
83
84 /**
85 * Private Prime 2.
86 */
87 mpz_t q;
88
89 /**
90 * Private exponent.
91 */
92 mpz_t d;
93
94 /**
95 * Private exponent 1.
96 */
97 mpz_t exp1;
98
99 /**
100 * Private exponent 2.
101 */
102 mpz_t exp2;
103
104 /**
105 * Private coefficient.
106 */
107 mpz_t coeff;
108
109 /**
110 * Keysize in bytes.
111 */
112 size_t k;
113
114 /**
115 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
116 */
117 chunk_t keyid;
118
119
120 /**
121 * @brief Implements the RSADP algorithm specified in PKCS#1.
122 *
123 * @param this calling object
124 * @param data data to process
125 * @return processed data
126 */
127 chunk_t (*rsadp) (private_rsa_private_key_t *this, chunk_t data);
128
129 /**
130 * @brief Implements the RSASP1 algorithm specified in PKCS#1.
131 * @param this calling object
132 * @param data data to process
133 * @return processed data
134 */
135 chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data);
136
137 /**
138 * @brief Generate a prime value.
139 *
140 * @param this calling object
141 * @param prime_size size of the prime, in bytes
142 * @param[out] prime uninitialized mpz
143 */
144 status_t (*compute_prime) (private_rsa_private_key_t *this, size_t prime_size, mpz_t *prime);
145
146 };
147
148 /* ASN.1 definition of a PKCS#1 RSA private key */
149 static const asn1Object_t privkey_objects[] = {
150 { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
151 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
152 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
153 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
154 { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
155 { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
156 { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
157 { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
158 { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
159 { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
160 { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
161 ASN1_LOOP }, /* 10 */
162 { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
163 { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
164 { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
165 { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
166 { 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
167 };
168
169 #define PRIV_KEY_VERSION 1
170 #define PRIV_KEY_MODULUS 2
171 #define PRIV_KEY_PUB_EXP 3
172 #define PRIV_KEY_PRIV_EXP 4
173 #define PRIV_KEY_PRIME1 5
174 #define PRIV_KEY_PRIME2 6
175 #define PRIV_KEY_EXP1 7
176 #define PRIV_KEY_EXP2 8
177 #define PRIV_KEY_COEFF 9
178 #define PRIV_KEY_ROOF 16
179
180 static private_rsa_private_key_t *rsa_private_key_create_empty(void);
181
182 /**
183 * Implementation of private_rsa_private_key_t.compute_prime.
184 */
185 static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size, mpz_t *prime)
186 {
187 randomizer_t *randomizer;
188 chunk_t random_bytes;
189 status_t status;
190
191 randomizer = randomizer_create();
192 mpz_init(*prime);
193
194 do
195 {
196 status = randomizer->allocate_random_bytes(randomizer, prime_size, &random_bytes);
197 if (status != SUCCESS)
198 {
199 randomizer->destroy(randomizer);
200 mpz_clear(*prime);
201 return FAILED;
202 }
203
204 /* make sure most significant bit is set */
205 random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
206
207 /* convert chunk to mpz value */
208 mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
209
210 /* get next prime */
211 mpz_nextprime (*prime, *prime);
212
213 free(random_bytes.ptr);
214 }
215 /* check if it isnt too large */
216 while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
217
218 randomizer->destroy(randomizer);
219 return SUCCESS;
220 }
221
222 /**
223 * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
224 */
225 static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data)
226 {
227 mpz_t t1, t2;
228 chunk_t decrypted;
229
230 mpz_init(t1);
231 mpz_init(t2);
232
233 mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
234
235 mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
236 mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
237 mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
238 mpz_mod(t2, t2, this->p);
239 mpz_mul(t2, t2, this->coeff);
240 mpz_mod(t2, t2, this->p);
241
242 mpz_mul(t2, t2, this->q); /* m = m2 + h q */
243 mpz_add(t1, t1, t2);
244
245 decrypted.len = this->k;
246 decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
247
248 mpz_clear(t1);
249 mpz_clear(t2);
250
251 return decrypted;
252 }
253
254 /**
255 * Implementation of rsa_private_key.build_emsa_signature.
256 */
257 static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this, hash_algorithm_t hash_algorithm, chunk_t data, chunk_t *signature)
258 {
259 hasher_t *hasher;
260 chunk_t hash;
261 chunk_t em;
262 chunk_t oid;
263
264 /* get oid string prepended to hash */
265 switch (hash_algorithm)
266 {
267 case HASH_MD2:
268 {
269 oid.ptr = md2_oid;
270 oid.len = sizeof(md2_oid);
271 break;
272 }
273 case HASH_MD5:
274 {
275 oid.ptr = md5_oid;
276 oid.len = sizeof(md5_oid);
277 break;
278 }
279 case HASH_SHA1:
280 {
281 oid.ptr = sha1_oid;
282 oid.len = sizeof(sha1_oid);
283 break;
284 }
285 case HASH_SHA256:
286 {
287 oid.ptr = sha256_oid;
288 oid.len = sizeof(sha256_oid);
289 break;
290 }
291 case HASH_SHA384:
292 {
293 oid.ptr = sha384_oid;
294 oid.len = sizeof(sha384_oid);
295 break;
296 }
297 case HASH_SHA512:
298 {
299 oid.ptr = sha512_oid;
300 oid.len = sizeof(sha512_oid);
301 break;
302 }
303 default:
304 {
305 return NOT_SUPPORTED;
306 }
307 }
308
309 /* get hasher */
310 hasher = hasher_create(hash_algorithm);
311 if (hasher == NULL)
312 {
313 return NOT_SUPPORTED;
314 }
315
316 /* build hash */
317 hasher->allocate_hash(hasher, data, &hash);
318 hasher->destroy(hasher);
319
320 /* build chunk to rsa-decrypt:
321 * EM = 0x00 || 0x01 || PS || 0x00 || T.
322 * PS = 0xFF padding, with length to fill em
323 * T = oid || hash
324 */
325 em.len = this->k;
326 em.ptr = malloc(em.len);
327
328 /* fill em with padding */
329 memset(em.ptr, 0xFF, em.len);
330 /* set magic bytes */
331 *(em.ptr) = 0x00;
332 *(em.ptr+1) = 0x01;
333 *(em.ptr + em.len - hash.len - oid.len - 1) = 0x00;
334 /* set hash */
335 memcpy(em.ptr + em.len - hash.len, hash.ptr, hash.len);
336 /* set oid */
337 memcpy(em.ptr + em.len - hash.len - oid.len, oid.ptr, oid.len);
338
339 /* build signature */
340 *signature = this->rsasp1(this, em);
341
342 free(hash.ptr);
343 free(em.ptr);
344
345 return SUCCESS;
346 }
347
348 /**
349 * Implementation of rsa_private_key.get_key.
350 */
351 static status_t get_key(private_rsa_private_key_t *this, chunk_t *key)
352 {
353 chunk_t n, e, p, q, d, exp1, exp2, coeff;
354
355 n.len = this->k;
356 n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, this->n);
357 e.len = this->k;
358 e.ptr = mpz_export(NULL, NULL, 1, e.len, 1, 0, this->e);
359 p.len = this->k;
360 p.ptr = mpz_export(NULL, NULL, 1, p.len, 1, 0, this->p);
361 q.len = this->k;
362 q.ptr = mpz_export(NULL, NULL, 1, q.len, 1, 0, this->q);
363 d.len = this->k;
364 d.ptr = mpz_export(NULL, NULL, 1, d.len, 1, 0, this->d);
365 exp1.len = this->k;
366 exp1.ptr = mpz_export(NULL, NULL, 1, exp1.len, 1, 0, this->exp1);
367 exp2.len = this->k;
368 exp2.ptr = mpz_export(NULL, NULL, 1, exp2.len, 1, 0, this->exp2);
369 coeff.len = this->k;
370 coeff.ptr = mpz_export(NULL, NULL, 1, coeff.len, 1, 0, this->coeff);
371
372 key->len = this->k * 8;
373 key->ptr = malloc(key->len);
374 memcpy(key->ptr + this->k * 0, n.ptr , n.len);
375 memcpy(key->ptr + this->k * 1, e.ptr, e.len);
376 memcpy(key->ptr + this->k * 2, p.ptr, p.len);
377 memcpy(key->ptr + this->k * 3, q.ptr, q.len);
378 memcpy(key->ptr + this->k * 4, d.ptr, d.len);
379 memcpy(key->ptr + this->k * 5, exp1.ptr, exp1.len);
380 memcpy(key->ptr + this->k * 6, exp2.ptr, exp2.len);
381 memcpy(key->ptr + this->k * 7, coeff.ptr, coeff.len);
382
383 free(n.ptr);
384 free(e.ptr);
385 free(p.ptr);
386 free(q.ptr);
387 free(d.ptr);
388 free(exp1.ptr);
389 free(exp2.ptr);
390 free(coeff.ptr);
391
392 return SUCCESS;
393 }
394
395 /**
396 * Implementation of rsa_private_key.save_key.
397 */
398 static status_t save_key(private_rsa_private_key_t *this, char *file)
399 {
400 return NOT_SUPPORTED;
401 }
402
403 /**
404 * Implementation of rsa_private_key.get_public_key.
405 */
406 rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
407 {
408 return NULL;
409 }
410
411 /**
412 * Implementation of rsa_private_key.belongs_to.
413 */
414 static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public)
415 {
416 return chunk_equals(this->keyid, public->get_keyid(public));
417 }
418
419 /**
420 * Check the loaded key if it is valid and usable
421 * TODO: Log errors
422 */
423 static status_t check(private_rsa_private_key_t *this)
424 {
425 mpz_t t, u, q1;
426 status_t status = SUCCESS;
427
428 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
429 * We actually require more (for security).
430 */
431 if (this->k < 512/8)
432 {
433 return FAILED;
434 }
435
436 /* we picked a max modulus size to simplify buffer allocation */
437 if (this->k > 8192/8)
438 {
439 return FAILED;
440 }
441
442 mpz_init(t);
443 mpz_init(u);
444 mpz_init(q1);
445
446 /* check that n == p * q */
447 mpz_mul(u, this->p, this->q);
448 if (mpz_cmp(u, this->n) != 0)
449 {
450 status = FAILED;
451 }
452
453 /* check that e divides neither p-1 nor q-1 */
454 mpz_sub_ui(t, this->p, 1);
455 mpz_mod(t, t, this->e);
456 if (mpz_cmp_ui(t, 0) == 0)
457 {
458 status = FAILED;
459 }
460
461 mpz_sub_ui(t, this->q, 1);
462 mpz_mod(t, t, this->e);
463 if (mpz_cmp_ui(t, 0) == 0)
464 {
465 status = FAILED;
466 }
467
468 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
469 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
470 mpz_sub_ui(q1, this->q, 1);
471 mpz_sub_ui(u, this->p, 1);
472 mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
473 mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
474 mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
475
476 mpz_mul(t, this->d, this->e);
477 mpz_mod(t, t, u);
478 if (mpz_cmp_ui(t, 1) != 0)
479 {
480 status = FAILED;
481 }
482
483 /* check that exp1 is d mod (p-1) */
484 mpz_sub_ui(u, this->p, 1);
485 mpz_mod(t, this->d, u);
486 if (mpz_cmp(t, this->exp1) != 0)
487 {
488 status = FAILED;
489 }
490
491 /* check that exp2 is d mod (q-1) */
492 mpz_sub_ui(u, this->q, 1);
493 mpz_mod(t, this->d, u);
494 if (mpz_cmp(t, this->exp2) != 0)
495 {
496 status = FAILED;
497 }
498
499 /* check that coeff is (q^-1) mod p */
500 mpz_mul(t, this->coeff, this->q);
501 mpz_mod(t, t, this->p);
502 if (mpz_cmp_ui(t, 1) != 0)
503 {
504 status = FAILED;
505 }
506
507 mpz_clear(t);
508 mpz_clear(u);
509 mpz_clear(q1);
510 return status;
511 }
512
513 /**
514 * Implementation of rsa_private_key.clone.
515 */
516 static rsa_private_key_t* _clone(private_rsa_private_key_t *this)
517 {
518 private_rsa_private_key_t *clone = rsa_private_key_create_empty();
519
520 mpz_init_set(clone->n, this->n);
521 mpz_init_set(clone->e, this->e);
522 mpz_init_set(clone->p, this->p);
523 mpz_init_set(clone->q, this->q);
524 mpz_init_set(clone->d, this->d);
525 mpz_init_set(clone->exp1, this->exp1);
526 mpz_init_set(clone->exp2, this->exp2);
527 mpz_init_set(clone->coeff, this->coeff);
528 clone->keyid = chunk_clone(this->keyid);
529 clone->k = this->k;
530
531 return &clone->public;
532 }
533
534 /**
535 * Implementation of rsa_private_key.destroy.
536 */
537 static void destroy(private_rsa_private_key_t *this)
538 {
539 mpz_clear(this->n);
540 mpz_clear(this->e);
541 mpz_clear(this->p);
542 mpz_clear(this->q);
543 mpz_clear(this->d);
544 mpz_clear(this->exp1);
545 mpz_clear(this->exp2);
546 mpz_clear(this->coeff);
547 free(this->keyid.ptr);
548 free(this);
549 }
550
551 /**
552 * Internal generic constructor
553 */
554 static private_rsa_private_key_t *rsa_private_key_create_empty(void)
555 {
556 private_rsa_private_key_t *this = malloc_thing(private_rsa_private_key_t);
557
558 /* public functions */
559 this->public.build_emsa_pkcs1_signature = (status_t (*) (rsa_private_key_t*,hash_algorithm_t,chunk_t,chunk_t*))build_emsa_pkcs1_signature;
560 this->public.get_key = (status_t (*) (rsa_private_key_t*,chunk_t*))get_key;
561 this->public.save_key = (status_t (*) (rsa_private_key_t*,char*))save_key;
562 this->public.get_public_key = (rsa_public_key_t *(*) (rsa_private_key_t*))get_public_key;
563 this->public.belongs_to = (bool (*) (rsa_private_key_t*,rsa_public_key_t*))belongs_to;
564 this->public.clone = (rsa_private_key_t*(*)(rsa_private_key_t*))_clone;
565 this->public.destroy = (void (*) (rsa_private_key_t*))destroy;
566
567 /* private functions */
568 this->rsadp = rsadp;
569 this->rsasp1 = rsadp; /* same algorithm */
570 this->compute_prime = compute_prime;
571
572 return this;
573 }
574
575 /*
576 * See header
577 */
578 rsa_private_key_t *rsa_private_key_create(size_t key_size)
579 {
580 mpz_t p, q, n, e, d, exp1, exp2, coeff;
581 mpz_t m, q1, t;
582 private_rsa_private_key_t *this;
583
584 this = rsa_private_key_create_empty();
585 key_size = key_size / 8;
586
587 /* Get values of primes p and q */
588 if (this->compute_prime(this, key_size/2, &p) != SUCCESS)
589 {
590 free(this);
591 return NULL;
592 }
593 if (this->compute_prime(this, key_size/2, &q) != SUCCESS)
594 {
595 mpz_clear(p);
596 free(this);
597 return NULL;
598 }
599
600 mpz_init(t);
601 mpz_init(n);
602 mpz_init(d);
603 mpz_init(exp1);
604 mpz_init(exp2);
605 mpz_init(coeff);
606
607 /* Swapping Primes so p is larger then q */
608 if (mpz_cmp(p, q) < 0)
609 {
610 mpz_set(t, p);
611 mpz_set(p, q);
612 mpz_set(q, t);
613 }
614
615 mpz_mul(n, p, q); /* n = p*q */
616 mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
617 mpz_init_set(m, p); /* m = p */
618 mpz_sub_ui(m, m, 1); /* m = m -1 */
619 mpz_init_set(q1, q); /* q1 = q */
620 mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
621 mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
622 mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
623 mpz_divexact(m, m, t); /* m = m / t */
624 mpz_gcd(t, m, e); /* t = gcd(m, e) (greatest common divisor) */
625
626 mpz_invert(d, e, m); /* e has an inverse mod m */
627 if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
628 {
629 mpz_add(d, d, m);
630 }
631 mpz_sub_ui(t, p, 1); /* t = p-1 */
632 mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
633 mpz_sub_ui(t, q, 1); /* t = q-1 */
634 mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
635
636 mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
637 if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
638 {
639 mpz_add(coeff, coeff, p);
640 }
641
642 mpz_clear(q1);
643 mpz_clear(m);
644 mpz_clear(t);
645
646 /* apply values */
647 *(this->p) = *p;
648 *(this->q) = *q;
649 *(this->n) = *n;
650 *(this->e) = *e;
651 *(this->d) = *d;
652 *(this->exp1) = *exp1;
653 *(this->exp2) = *exp2;
654 *(this->coeff) = *coeff;
655
656 /* set key size in bytes */
657 this->k = key_size;
658
659 return &this->public;
660 }
661
662 /*
663 * see header
664 */
665 rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
666 {
667 asn1_ctx_t ctx;
668 chunk_t object;
669 u_int level;
670 int objectID = 0;
671 private_rsa_private_key_t *this;
672
673 this = rsa_private_key_create_empty();
674
675 mpz_init(this->n);
676 mpz_init(this->e);
677 mpz_init(this->p);
678 mpz_init(this->q);
679 mpz_init(this->d);
680 mpz_init(this->exp1);
681 mpz_init(this->exp2);
682 mpz_init(this->coeff);
683
684 asn1_init(&ctx, blob, 0, FALSE);
685
686 while (objectID < PRIV_KEY_ROOF)
687 {
688 if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
689 {
690 destroy(this);
691 return FALSE;
692 }
693 switch (objectID)
694 {
695 case PRIV_KEY_VERSION:
696 if (object.len > 0 && *object.ptr != 0)
697 {
698 destroy(this);
699 return NULL;
700 }
701 break;
702 case PRIV_KEY_MODULUS:
703 mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
704 break;
705 case PRIV_KEY_PUB_EXP:
706 mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
707 break;
708 case PRIV_KEY_PRIV_EXP:
709 mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
710 break;
711 case PRIV_KEY_PRIME1:
712 mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
713 break;
714 case PRIV_KEY_PRIME2:
715 mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
716 break;
717 case PRIV_KEY_EXP1:
718 mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
719 break;
720 case PRIV_KEY_EXP2:
721 mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
722 break;
723 case PRIV_KEY_COEFF:
724 mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
725 break;
726 }
727 objectID++;
728 }
729
730 this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
731
732 /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
733 {
734 chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(this->n, this->e);
735 hasher_t *hasher = hasher_create(HASH_SHA1);
736
737 hasher->allocate_hash(hasher, publicKeyInfo, &this->keyid);
738 hasher->destroy(hasher);
739 free(publicKeyInfo.ptr);
740 }
741
742 if (check(this) != SUCCESS)
743 {
744 destroy(this);
745 return NULL;
746 }
747 else
748 {
749 return &this->public;
750 }
751 }
752
753 /*
754 * see header
755 */
756 rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase)
757 {
758 bool pgp = FALSE;
759 chunk_t chunk = CHUNK_INITIALIZER;
760 rsa_private_key_t *key = NULL;
761
762 if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
763 return NULL;
764
765 key = rsa_private_key_create_from_chunk(chunk);
766 free(chunk.ptr);
767 return key;
768 }