c9928e6f4fb2f7f28674e04cd1a596ae2ce13c4d
[strongswan.git] / src / libstrongswan / plugins / gmp / gmp_rsa_private_key.c
1 /*
2 * Copyright (C) 2005-2008 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * $Id$
17 */
18
19 #include <gmp.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <string.h>
23
24 #include "gmp_rsa_private_key.h"
25 #include "gmp_rsa_public_key.h"
26
27 #include <debug.h>
28 #include <asn1/asn1.h>
29 #include <utils/randomizer.h>
30 #include <crypto/hashers/hasher.h>
31
32 /**
33 * Public exponent to use for key generation.
34 */
35 #define PUBLIC_EXPONENT 0x10001
36
37 typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t;
38
39 /**
40 * Private data of a gmp_rsa_private_key_t object.
41 */
42 struct private_gmp_rsa_private_key_t {
43 /**
44 * Public interface for this signer.
45 */
46 gmp_rsa_private_key_t public;
47
48 /**
49 * Version of key, as encoded in PKCS#1
50 */
51 u_int version;
52
53 /**
54 * Public modulus.
55 */
56 mpz_t n;
57
58 /**
59 * Public exponent.
60 */
61 mpz_t e;
62
63 /**
64 * Private prime 1.
65 */
66 mpz_t p;
67
68 /**
69 * Private Prime 2.
70 */
71 mpz_t q;
72
73 /**
74 * Private exponent.
75 */
76 mpz_t d;
77
78 /**
79 * Private exponent 1.
80 */
81 mpz_t exp1;
82
83 /**
84 * Private exponent 2.
85 */
86 mpz_t exp2;
87
88 /**
89 * Private coefficient.
90 */
91 mpz_t coeff;
92
93 /**
94 * Keysize in bytes.
95 */
96 size_t k;
97
98 /**
99 * Keyid formed as a SHA-1 hash of a publicKey object
100 */
101 identification_t* keyid;
102
103 /**
104 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
105 */
106 identification_t* keyid_info;
107
108 /**
109 * reference count
110 */
111 refcount_t ref;
112 };
113
114 /* ASN.1 definition of a PKCS#1 RSA private key */
115 static const asn1Object_t privkey_objects[] = {
116 { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
117 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
118 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
119 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
120 { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
121 { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
122 { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
123 { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
124 { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
125 { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
126 { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
127 ASN1_LOOP }, /* 10 */
128 { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
129 { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
130 { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
131 { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
132 { 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
133 };
134
135 #define PRIV_KEY_VERSION 1
136 #define PRIV_KEY_MODULUS 2
137 #define PRIV_KEY_PUB_EXP 3
138 #define PRIV_KEY_PRIV_EXP 4
139 #define PRIV_KEY_PRIME1 5
140 #define PRIV_KEY_PRIME2 6
141 #define PRIV_KEY_EXP1 7
142 #define PRIV_KEY_EXP2 8
143 #define PRIV_KEY_COEFF 9
144 #define PRIV_KEY_ROOF 16
145
146 /**
147 * shared functions, implemented in gmp_rsa_public_key.c
148 */
149 bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
150 identification_t **keyid_info);
151 gmp_rsa_public_key_t *gmp_rsa_public_key_create_from_n_e(mpz_t n, mpz_t e);
152
153 /**
154 * Auxiliary function overwriting private key material with
155 * pseudo-random bytes before releasing it
156 */
157 static void mpz_clear_randomized(mpz_t z)
158 {
159 size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
160 u_int8_t *random_bytes = alloca(len);
161
162 randomizer_t *randomizer = randomizer_create();
163
164 randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes);
165
166 /* overwrite mpz_t with pseudo-random bytes before clearing it */
167 mpz_import(z, len, 1, 1, 1, 0, random_bytes);
168 mpz_clear(z);
169
170 randomizer->destroy(randomizer);
171 }
172
173 /**
174 * Create a mpz prime of at least prime_size
175 */
176 static status_t compute_prime(private_gmp_rsa_private_key_t *this,
177 size_t prime_size, mpz_t *prime)
178 {
179 randomizer_t *randomizer;
180 chunk_t random_bytes;
181 status_t status;
182
183 randomizer = randomizer_create();
184 mpz_init(*prime);
185
186 do
187 {
188 status = randomizer->allocate_random_bytes(randomizer, prime_size,
189 &random_bytes);
190 if (status != SUCCESS)
191 {
192 randomizer->destroy(randomizer);
193 mpz_clear(*prime);
194 return FAILED;
195 }
196 /* make sure most significant bit is set */
197 random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
198
199 mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
200 mpz_nextprime (*prime, *prime);
201 chunk_free_randomized(&random_bytes);
202 }
203 /* check if it isn't too large */
204 while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
205
206 randomizer->destroy(randomizer);
207 return SUCCESS;
208 }
209
210 /**
211 * PKCS#1 RSADP function
212 */
213 static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data)
214 {
215 mpz_t t1, t2;
216 chunk_t decrypted;
217
218 mpz_init(t1);
219 mpz_init(t2);
220
221 mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
222
223 mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
224 mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
225 mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
226 mpz_mod(t2, t2, this->p);
227 mpz_mul(t2, t2, this->coeff);
228 mpz_mod(t2, t2, this->p);
229
230 mpz_mul(t2, t2, this->q); /* m = m2 + h q */
231 mpz_add(t1, t1, t2);
232
233 decrypted.len = this->k;
234 decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
235
236 mpz_clear_randomized(t1);
237 mpz_clear_randomized(t2);
238
239 return decrypted;
240 }
241
242 /**
243 * PKCS#1 RSASP1 function
244 */
245 static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
246 {
247 return rsadp(this, data);
248 }
249
250 /**
251 * Implementation of gmp_rsa_private_key_t.build_emsa_pkcs1_signature.
252 */
253 static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
254 hash_algorithm_t hash_algorithm,
255 chunk_t data, chunk_t *signature)
256 {
257 hasher_t *hasher;
258 chunk_t em, digestInfo, hash;
259 int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
260
261 if (hash_oid == OID_UNKNOWN)
262 {
263 return FALSE;
264 }
265
266 /* get hasher */
267 hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
268 if (hasher == NULL)
269 {
270 return FALSE;
271 }
272
273 /* build hash */
274 hasher->allocate_hash(hasher, data, &hash);
275 hasher->destroy(hasher);
276
277 /* build DER-encoded digestInfo */
278 digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
279 asn1_algorithmIdentifier(hash_oid),
280 asn1_simple_object(ASN1_OCTET_STRING, hash)
281 );
282 chunk_free(&hash);
283
284 /* build chunk to rsa-decrypt:
285 * EM = 0x00 || 0x01 || PS || 0x00 || T.
286 * PS = 0xFF padding, with length to fill em
287 * T = encoded_hash
288 */
289 em.len = this->k;
290 em.ptr = malloc(em.len);
291
292 /* fill em with padding */
293 memset(em.ptr, 0xFF, em.len);
294 /* set magic bytes */
295 *(em.ptr) = 0x00;
296 *(em.ptr+1) = 0x01;
297 *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
298 /* set DER-encoded hash */
299 memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
300
301 /* build signature */
302 *signature = rsasp1(this, em);
303
304 free(digestInfo.ptr);
305 free(em.ptr);
306
307 return TRUE;
308 }
309
310 /**
311 * Implementation of gmp_rsa_private_key.destroy.
312 */
313 static key_type_t get_type(private_gmp_rsa_private_key_t *this)
314 {
315 return KEY_RSA;
316 }
317
318 /**
319 * Implementation of gmp_rsa_private_key.destroy.
320 */
321 static bool sign(private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
322 chunk_t data, chunk_t *signature)
323 {
324 switch (scheme)
325 {
326 case SIGN_DEFAULT:
327 /* default is EMSA-PKCS1 using SHA1 */
328 case SIGN_RSA_EMSA_PKCS1_SHA1:
329 return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
330 case SIGN_RSA_EMSA_PKCS1_SHA256:
331 return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
332 case SIGN_RSA_EMSA_PKCS1_SHA384:
333 return build_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
334 case SIGN_RSA_EMSA_PKCS1_SHA512:
335 return build_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
336 case SIGN_RSA_EMSA_PKCS1_MD5:
337 return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
338 default:
339 DBG1("signature scheme %N not supported in RSA",
340 signature_scheme_names, scheme);
341 return FALSE;
342 }
343 }
344
345 /**
346 * Implementation of gmp_rsa_private_key.destroy.
347 */
348 static bool decrypt(private_gmp_rsa_private_key_t *this,
349 chunk_t crypto, chunk_t *plain)
350 {
351 DBG1("RSA private key decryption not implemented");
352 return FALSE;
353 }
354
355 /**
356 * Implementation of gmp_rsa_private_key.destroy.
357 */
358 static size_t get_keysize(private_gmp_rsa_private_key_t *this)
359 {
360 return this->k;
361 }
362
363 /**
364 * Implementation of gmp_rsa_private_key.destroy.
365 */
366 static identification_t* get_id(private_gmp_rsa_private_key_t *this,
367 id_type_t type)
368 {
369 switch (type)
370 {
371 case ID_PUBKEY_INFO_SHA1:
372 return this->keyid_info;
373 case ID_PUBKEY_SHA1:
374 return this->keyid;
375 default:
376 return NULL;
377 }
378 }
379
380 /**
381 * Implementation of gmp_rsa_private_key.destroy.
382 */
383 static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this)
384 {
385 return gmp_rsa_public_key_create_from_n_e(this->n, this->e);
386 }
387
388 /**
389 * Implementation of gmp_rsa_private_key.destroy.
390 */
391 static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public)
392 {
393 identification_t *keyid;
394
395 if (public->get_type(public) != KEY_RSA)
396 {
397 return FALSE;
398 }
399 keyid = public->get_id(public, ID_PUBKEY_SHA1);
400 if (keyid && keyid->equals(keyid, this->keyid))
401 {
402 return TRUE;
403 }
404 keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
405 if (keyid && keyid->equals(keyid, this->keyid_info))
406 {
407 return TRUE;
408 }
409 return FALSE;
410 }
411
412 /**
413 * convert a MP integer into a DER coded ASN.1 object
414 */
415 chunk_t gmp_mpz_to_asn1(const mpz_t value)
416 {
417 size_t bits = mpz_sizeinbase(value, 2); /* size in bits */
418 chunk_t n;
419
420 n.len = 1 + bits / 8; /* size in bytes */
421 n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
422
423 return asn1_wrap(ASN1_INTEGER, "m", n);
424 }
425
426 /**
427 * Implementation of private_key_t.get_encoding.
428 */
429 static chunk_t get_encoding(private_gmp_rsa_private_key_t *this)
430 {
431 return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
432 ASN1_INTEGER_0,
433 gmp_mpz_to_asn1(this->n),
434 gmp_mpz_to_asn1(this->e),
435 gmp_mpz_to_asn1(this->d),
436 gmp_mpz_to_asn1(this->p),
437 gmp_mpz_to_asn1(this->q),
438 gmp_mpz_to_asn1(this->exp1),
439 gmp_mpz_to_asn1(this->exp2),
440 gmp_mpz_to_asn1(this->coeff));
441 }
442
443 /**
444 * Implementation of gmp_rsa_private_key.destroy.
445 */
446 static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *this)
447 {
448 ref_get(&this->ref);
449 return this;
450
451 }
452
453 /**
454 * Implementation of gmp_rsa_private_key.destroy.
455 */
456 static void destroy(private_gmp_rsa_private_key_t *this)
457 {
458 if (ref_put(&this->ref))
459 {
460 mpz_clear_randomized(this->n);
461 mpz_clear_randomized(this->e);
462 mpz_clear_randomized(this->p);
463 mpz_clear_randomized(this->q);
464 mpz_clear_randomized(this->d);
465 mpz_clear_randomized(this->exp1);
466 mpz_clear_randomized(this->exp2);
467 mpz_clear_randomized(this->coeff);
468 DESTROY_IF(this->keyid);
469 DESTROY_IF(this->keyid_info);
470 free(this);
471 }
472 }
473
474 /**
475 * Check the loaded key if it is valid and usable
476 */
477 static status_t check(private_gmp_rsa_private_key_t *this)
478 {
479 mpz_t t, u, q1;
480 status_t status = SUCCESS;
481
482 /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
483 * We actually require more (for security).
484 */
485 if (this->k < 512/8)
486 {
487 DBG1("key shorter than 512 bits");
488 return FAILED;
489 }
490
491 /* we picked a max modulus size to simplify buffer allocation */
492 if (this->k > 8192/8)
493 {
494 DBG1("key larger thant 8192 bits");
495 return FAILED;
496 }
497
498 mpz_init(t);
499 mpz_init(u);
500 mpz_init(q1);
501
502 /* check that n == p * q */
503 mpz_mul(u, this->p, this->q);
504 if (mpz_cmp(u, this->n) != 0)
505 {
506 status = FAILED;
507 }
508
509 /* check that e divides neither p-1 nor q-1 */
510 mpz_sub_ui(t, this->p, 1);
511 mpz_mod(t, t, this->e);
512 if (mpz_cmp_ui(t, 0) == 0)
513 {
514 status = FAILED;
515 }
516
517 mpz_sub_ui(t, this->q, 1);
518 mpz_mod(t, t, this->e);
519 if (mpz_cmp_ui(t, 0) == 0)
520 {
521 status = FAILED;
522 }
523
524 /* check that d is e^-1 (mod lcm(p-1, q-1)) */
525 /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
526 mpz_sub_ui(q1, this->q, 1);
527 mpz_sub_ui(u, this->p, 1);
528 mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
529 mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
530 mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
531
532 mpz_mul(t, this->d, this->e);
533 mpz_mod(t, t, u);
534 if (mpz_cmp_ui(t, 1) != 0)
535 {
536 status = FAILED;
537 }
538
539 /* check that exp1 is d mod (p-1) */
540 mpz_sub_ui(u, this->p, 1);
541 mpz_mod(t, this->d, u);
542 if (mpz_cmp(t, this->exp1) != 0)
543 {
544 status = FAILED;
545 }
546
547 /* check that exp2 is d mod (q-1) */
548 mpz_sub_ui(u, this->q, 1);
549 mpz_mod(t, this->d, u);
550 if (mpz_cmp(t, this->exp2) != 0)
551 {
552 status = FAILED;
553 }
554
555 /* check that coeff is (q^-1) mod p */
556 mpz_mul(t, this->coeff, this->q);
557 mpz_mod(t, t, this->p);
558 if (mpz_cmp_ui(t, 1) != 0)
559 {
560 status = FAILED;
561 }
562
563 mpz_clear_randomized(t);
564 mpz_clear_randomized(u);
565 mpz_clear_randomized(q1);
566 if (status != SUCCESS)
567 {
568 DBG1("key integrity tests failed");
569 }
570 return status;
571 }
572
573 /**
574 * Internal generic constructor
575 */
576 static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void)
577 {
578 private_gmp_rsa_private_key_t *this = malloc_thing(private_gmp_rsa_private_key_t);
579
580 this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
581 this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
582 this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
583 this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
584 this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
585 this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
586 this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
587 this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
588 this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
589 this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
590
591 this->keyid = NULL;
592 this->keyid_info = NULL;
593 this->ref = 1;
594
595 return this;
596 }
597
598 /**
599 * Generate an RSA key of specified key size
600 */
601 static gmp_rsa_private_key_t *generate(size_t key_size)
602 {
603 mpz_t p, q, n, e, d, exp1, exp2, coeff;
604 mpz_t m, q1, t;
605 private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
606
607 key_size = key_size / 8;
608
609 /* Get values of primes p and q */
610 if (compute_prime(this, key_size/2, &p) != SUCCESS)
611 {
612 free(this);
613 return NULL;
614 }
615 if (compute_prime(this, key_size/2, &q) != SUCCESS)
616 {
617 mpz_clear(p);
618 free(this);
619 return NULL;
620 }
621
622 mpz_init(t);
623 mpz_init(n);
624 mpz_init(d);
625 mpz_init(exp1);
626 mpz_init(exp2);
627 mpz_init(coeff);
628
629 /* Swapping Primes so p is larger then q */
630 if (mpz_cmp(p, q) < 0)
631 {
632 mpz_swap(p, q);
633 }
634
635 mpz_mul(n, p, q); /* n = p*q */
636 mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
637 mpz_init_set(m, p); /* m = p */
638 mpz_sub_ui(m, m, 1); /* m = m -1 */
639 mpz_init_set(q1, q); /* q1 = q */
640 mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
641 mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
642 mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
643 mpz_divexact(m, m, t); /* m = m / t */
644 mpz_gcd(t, m, e); /* t = gcd(m, e) */
645
646 mpz_invert(d, e, m); /* e has an inverse mod m */
647 if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
648 {
649 mpz_add(d, d, m);
650 }
651 mpz_sub_ui(t, p, 1); /* t = p-1 */
652 mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
653 mpz_sub_ui(t, q, 1); /* t = q-1 */
654 mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
655
656 mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
657 if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
658 {
659 mpz_add(coeff, coeff, p);
660 }
661
662 mpz_clear_randomized(q1);
663 mpz_clear_randomized(m);
664 mpz_clear_randomized(t);
665
666 /* apply values */
667 *(this->p) = *p;
668 *(this->q) = *q;
669 *(this->n) = *n;
670 *(this->e) = *e;
671 *(this->d) = *d;
672 *(this->exp1) = *exp1;
673 *(this->exp2) = *exp2;
674 *(this->coeff) = *coeff;
675
676 /* set key size in bytes */
677 this->k = key_size;
678
679 return &this->public;
680 }
681
682 /**
683 * load private key from a ASN1 encoded blob
684 */
685 static gmp_rsa_private_key_t *load(chunk_t blob)
686 {
687 asn1_ctx_t ctx;
688 chunk_t object;
689 u_int level;
690 int objectID = 0;
691 private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
692
693 mpz_init(this->n);
694 mpz_init(this->e);
695 mpz_init(this->p);
696 mpz_init(this->q);
697 mpz_init(this->d);
698 mpz_init(this->exp1);
699 mpz_init(this->exp2);
700 mpz_init(this->coeff);
701
702 asn1_init(&ctx, blob, 0, FALSE, TRUE);
703
704 while (objectID < PRIV_KEY_ROOF)
705 {
706 if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
707 {
708 chunk_free_randomized(&blob);
709 destroy(this);
710 return NULL;
711 }
712 switch (objectID)
713 {
714 case PRIV_KEY_VERSION:
715 if (object.len > 0 && *object.ptr != 0)
716 {
717 chunk_free_randomized(&blob);
718 destroy(this);
719 return NULL;
720 }
721 break;
722 case PRIV_KEY_MODULUS:
723 mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
724 break;
725 case PRIV_KEY_PUB_EXP:
726 mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
727 break;
728 case PRIV_KEY_PRIV_EXP:
729 mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
730 break;
731 case PRIV_KEY_PRIME1:
732 mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
733 break;
734 case PRIV_KEY_PRIME2:
735 mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
736 break;
737 case PRIV_KEY_EXP1:
738 mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
739 break;
740 case PRIV_KEY_EXP2:
741 mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
742 break;
743 case PRIV_KEY_COEFF:
744 mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
745 break;
746 }
747 objectID++;
748 }
749 chunk_free_randomized(&blob);
750
751 this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
752 if (!gmp_rsa_public_key_build_id(this->n, this->e,
753 &this->keyid, &this->keyid_info))
754 {
755 destroy(this);
756 return NULL;
757 }
758
759 if (check(this) != SUCCESS)
760 {
761 destroy(this);
762 return NULL;
763 }
764 return &this->public;
765 }
766
767 typedef struct private_builder_t private_builder_t;
768 /**
769 * Builder implementation for key loading/generation
770 */
771 struct private_builder_t {
772 /** implements the builder interface */
773 builder_t public;
774 /** loaded/generated private key */
775 gmp_rsa_private_key_t *key;
776 };
777
778 /**
779 * Implementation of builder_t.build
780 */
781 static gmp_rsa_private_key_t *build(private_builder_t *this)
782 {
783 gmp_rsa_private_key_t *key = this->key;
784
785 free(this);
786 return key;
787 }
788
789 /**
790 * Implementation of builder_t.add
791 */
792 static void add(private_builder_t *this, builder_part_t part, ...)
793 {
794 va_list args;
795
796 if (this->key)
797 {
798 DBG1("ignoring surplus build part %N", builder_part_names, part);
799 return;
800 }
801
802 switch (part)
803 {
804 case BUILD_BLOB_ASN1_DER:
805 {
806 va_start(args, part);
807 this->key = load(va_arg(args, chunk_t));
808 va_end(args);
809 break;
810 }
811 case BUILD_KEY_SIZE:
812 {
813 va_start(args, part);
814 this->key = generate(va_arg(args, u_int));
815 va_end(args);
816 break;
817 }
818 default:
819 DBG1("ignoring unsupported build part %N", builder_part_names, part);
820 break;
821 }
822 }
823
824 /**
825 * Builder construction function
826 */
827 builder_t *gmp_rsa_private_key_builder(key_type_t type)
828 {
829 private_builder_t *this;
830
831 if (type != KEY_RSA)
832 {
833 return NULL;
834 }
835
836 this = malloc_thing(private_builder_t);
837
838 this->key = NULL;
839 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
840 this->public.build = (void*(*)(builder_t *this))build;
841
842 return &this->public;
843 }
844