gcrypt uses component builder to build public- from private-key
[strongswan.git] / src / libstrongswan / plugins / gcrypt / gcrypt_rsa_private_key.c
1 /*
2 * Copyright (C) 2005-2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <gcrypt.h>
17
18 #include "gcrypt_rsa_private_key.h"
19
20 #include <debug.h>
21 #include <asn1/oid.h>
22 #include <asn1/asn1.h>
23 #include <asn1/asn1_parser.h>
24
25 typedef struct private_gcrypt_rsa_private_key_t private_gcrypt_rsa_private_key_t;
26
27 /**
28 * Private data of a gcrypt_rsa_private_key_t object.
29 */
30 struct private_gcrypt_rsa_private_key_t {
31
32 /**
33 * Public interface
34 */
35 gcrypt_rsa_private_key_t public;
36
37 /**
38 * gcrypt S-expression representing an RSA key
39 */
40 gcry_sexp_t key;
41
42 /**
43 * Keyid formed as a SHA-1 hash of a publicKey object
44 */
45 identification_t* keyid;
46
47 /**
48 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
49 */
50 identification_t* keyid_info;
51
52 /**
53 * reference count
54 */
55 refcount_t ref;
56 };
57
58 /**
59 * find a token in a S-expression. If a key is given, its length is used to
60 * pad the output to a given length.
61 */
62 chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name, gcry_sexp_t key)
63 {
64 gcry_sexp_t token;
65 chunk_t data = chunk_empty, tmp;
66 size_t len = 0;
67
68 token = gcry_sexp_find_token(sexp, name, 1);
69 if (token)
70 {
71 data.ptr = (char*)gcry_sexp_nth_data(token, 1, &data.len);
72 if (!data.ptr)
73 {
74 data.len = 0;
75 }
76 else
77 {
78 if (key)
79 {
80 /* gcrypt might return more bytes than necessary. Truncate
81 * to key lenght if key given, or prepend zeros if needed */
82 len = gcry_pk_get_nbits(key);
83 len = len / 8 + (len % 8 ? 1 : 0);
84 if (len > data.len)
85 {
86 tmp = chunk_alloc(len);
87 len -= data.len;
88 memset(tmp.ptr, 0, tmp.len - len);
89 memcpy(tmp.ptr + len, data.ptr, data.len);
90 data = tmp;
91 }
92 else if (len < data.len)
93 {
94 data = chunk_clone(chunk_skip(data, data.len - len));
95 }
96 else
97 {
98 data = chunk_clone(data);
99 }
100 }
101 else
102 {
103 data = chunk_clone(data);
104 }
105 }
106 gcry_sexp_release(token);
107 }
108 return data;
109 }
110
111 /**
112 * Sign a chunk of data with direct PKCS#1 encoding, no hash OID
113 */
114 static bool sign_raw(private_gcrypt_rsa_private_key_t *this,
115 chunk_t data, chunk_t *signature)
116 {
117 gcry_sexp_t in, out;
118 gcry_error_t err;
119 chunk_t em;
120 size_t k;
121
122 /* EM = 0x00 || 0x01 || PS || 0x00 || T
123 * PS = 0xFF padding, with length to fill em
124 * T = data
125 */
126 k = gcry_pk_get_nbits(this->key) / 8;
127 if (data.len > k - 3)
128 {
129 return FALSE;
130 }
131 em = chunk_alloc(k);
132 memset(em.ptr, 0xFF, em.len);
133 em.ptr[0] = 0x00;
134 em.ptr[1] = 0x01;
135 em.ptr[em.len - data.len - 1] = 0x00;
136 memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
137
138 err = gcry_sexp_build(&in, NULL, "(data(flags raw)(value %b))",
139 em.len, em.ptr);
140 chunk_free(&em);
141 if (err)
142 {
143 DBG1("building signature S-expression failed: %s", gpg_strerror(err));
144 return FALSE;
145 }
146 err = gcry_pk_sign(&out, in, this->key);
147 gcry_sexp_release(in);
148 if (err)
149 {
150 DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err));
151 return FALSE;
152 }
153 *signature = gcrypt_rsa_find_token(out, "s", this->key);
154 gcry_sexp_release(out);
155 return !!signature->len;
156 }
157
158 /**
159 * Sign a chunk of data using hashing and PKCS#1 encoding
160 */
161 static bool sign_pkcs1(private_gcrypt_rsa_private_key_t *this,
162 hash_algorithm_t hash_algorithm, char *hash_name,
163 chunk_t data, chunk_t *signature)
164 {
165 hasher_t *hasher;
166 chunk_t hash;
167 gcry_error_t err;
168 gcry_sexp_t in, out;
169 int hash_oid;
170
171 hash_oid = hasher_algorithm_to_oid(hash_algorithm);
172 if (hash_oid == OID_UNKNOWN)
173 {
174 return FALSE;
175 }
176 hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
177 if (!hasher)
178 {
179 return FALSE;
180 }
181 hasher->allocate_hash(hasher, data, &hash);
182 hasher->destroy(hasher);
183
184 err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
185 hash_name, hash.len, hash.ptr);
186 chunk_free(&hash);
187 if (err)
188 {
189 DBG1("building signature S-expression failed: %s", gpg_strerror(err));
190 return FALSE;
191 }
192 err = gcry_pk_sign(&out, in, this->key);
193 gcry_sexp_release(in);
194 if (err)
195 {
196 DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err));
197 return FALSE;
198 }
199 *signature = gcrypt_rsa_find_token(out, "s", this->key);
200 gcry_sexp_release(out);
201 return !!signature->len;
202 }
203
204 /**
205 * Implementation of gcrypt_rsa_private_key.destroy.
206 */
207 static key_type_t get_type(private_gcrypt_rsa_private_key_t *this)
208 {
209 return KEY_RSA;
210 }
211
212 /**
213 * Implementation of gcrypt_rsa_private_key.destroy.
214 */
215 static bool sign(private_gcrypt_rsa_private_key_t *this, signature_scheme_t scheme,
216 chunk_t data, chunk_t *sig)
217 {
218 switch (scheme)
219 {
220 case SIGN_RSA_EMSA_PKCS1_NULL:
221 return sign_raw(this, data, sig);
222 case SIGN_RSA_EMSA_PKCS1_SHA1:
223 return sign_pkcs1(this, HASH_SHA1, "sha1", data, sig);
224 case SIGN_RSA_EMSA_PKCS1_SHA224:
225 return sign_pkcs1(this, HASH_SHA224, "sha224", data, sig);
226 case SIGN_RSA_EMSA_PKCS1_SHA256:
227 return sign_pkcs1(this, HASH_SHA256, "sha256", data, sig);
228 case SIGN_RSA_EMSA_PKCS1_SHA384:
229 return sign_pkcs1(this, HASH_SHA384, "sha384", data, sig);
230 case SIGN_RSA_EMSA_PKCS1_SHA512:
231 return sign_pkcs1(this, HASH_SHA512, "sha512", data, sig);
232 case SIGN_RSA_EMSA_PKCS1_MD5:
233 return sign_pkcs1(this, HASH_MD5, "md5", data, sig);
234 default:
235 DBG1("signature scheme %N not supported in RSA",
236 signature_scheme_names, scheme);
237 return FALSE;
238 }
239 }
240
241 /**
242 * Implementation of gcrypt_rsa_private_key.destroy.
243 */
244 static bool decrypt(private_gcrypt_rsa_private_key_t *this,
245 chunk_t encrypted, chunk_t *plain)
246 {
247 gcry_error_t err;
248 gcry_sexp_t in, out;
249 chunk_t padded;
250 u_char *pos = NULL;;
251
252 err = gcry_sexp_build(&in, NULL, "(enc-val(flags)(rsa(a %b)))",
253 encrypted.len, encrypted.ptr);
254 if (err)
255 {
256 DBG1("building decryption S-expression failed: %s", gpg_strerror(err));
257 return FALSE;
258 }
259 err = gcry_pk_decrypt(&out, in, this->key);
260 gcry_sexp_release(in);
261 if (err)
262 {
263 DBG1("decrypting pkcs1 data failed: %s", gpg_strerror(err));
264 return FALSE;
265 }
266 padded.ptr = (u_char*)gcry_sexp_nth_data(out, 1, &padded.len);
267 /* result is padded, but gcrypt strips leading zero:
268 * 00 | 02 | RANDOM | 00 | DATA */
269 if (padded.ptr && padded.len > 2 && padded.ptr[0] == 0x02)
270 {
271 pos = memchr(padded.ptr, 0x00, padded.len - 1);
272 if (pos)
273 {
274 pos++;
275 *plain = chunk_clone(chunk_create(
276 pos, padded.len - (pos - padded.ptr)));
277 }
278 }
279 gcry_sexp_release(out);
280 if (!pos)
281 {
282 DBG1("decrypted data has invalid pkcs1 padding");
283 return FALSE;
284 }
285 return TRUE;
286 }
287
288 /**
289 * Implementation of gcrypt_rsa_private_key.get_keysize.
290 */
291 static size_t get_keysize(private_gcrypt_rsa_private_key_t *this)
292 {
293 return gcry_pk_get_nbits(this->key) / 8;
294 }
295
296 /**
297 * Implementation of gcrypt_rsa_private_key.destroy.
298 */
299 static identification_t* get_id(private_gcrypt_rsa_private_key_t *this,
300 id_type_t type)
301 {
302 switch (type)
303 {
304 case ID_PUBKEY_INFO_SHA1:
305 return this->keyid_info;
306 case ID_PUBKEY_SHA1:
307 return this->keyid;
308 default:
309 return NULL;
310 }
311 }
312
313 /**
314 * Implementation of gcrypt_rsa_private_key.get_public_key.
315 */
316 static public_key_t* get_public_key(private_gcrypt_rsa_private_key_t *this)
317 {
318 chunk_t n, e;
319 public_key_t *public;
320
321 n = gcrypt_rsa_find_token(this->key, "n", NULL);
322 e = gcrypt_rsa_find_token(this->key, "e", NULL);
323
324 public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
325 BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
326 chunk_free(&n);
327 chunk_free(&e);
328
329 return public;
330 }
331
332 /**
333 * Implementation of gcrypt_rsa_private_key.equals.
334 */
335 static bool equals(private_gcrypt_rsa_private_key_t *this, private_key_t *other)
336 {
337 identification_t *keyid;
338
339 if (&this->public.interface == other)
340 {
341 return TRUE;
342 }
343 if (other->get_type(other) != KEY_RSA)
344 {
345 return FALSE;
346 }
347 keyid = other->get_id(other, ID_PUBKEY_SHA1);
348 if (keyid && keyid->equals(keyid, this->keyid))
349 {
350 return TRUE;
351 }
352 keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
353 if (keyid && keyid->equals(keyid, this->keyid_info))
354 {
355 return TRUE;
356 }
357 return FALSE;
358 }
359
360 /**
361 * Implementation of gcrypt_rsa_private_key.belongs_to.
362 */
363 static bool belongs_to(private_gcrypt_rsa_private_key_t *this,
364 public_key_t *public)
365 {
366 identification_t *keyid;
367
368 if (public->get_type(public) != KEY_RSA)
369 {
370 return FALSE;
371 }
372 keyid = public->get_id(public, ID_PUBKEY_SHA1);
373 if (keyid && keyid->equals(keyid, this->keyid))
374 {
375 return TRUE;
376 }
377 keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
378 if (keyid && keyid->equals(keyid, this->keyid_info))
379 {
380 return TRUE;
381 }
382 return FALSE;
383 }
384
385 /**
386 * Implementation of private_key_t.get_encoding.
387 */
388 static chunk_t get_encoding(private_gcrypt_rsa_private_key_t *this)
389 {
390 chunk_t cp, cq, cd, cexp1 = chunk_empty, cexp2 = chunk_empty;
391 gcry_mpi_t p = NULL, q = NULL, d = NULL, exp1, exp2;
392 gcry_error_t err;
393
394 /* p and q are swapped, gcrypt expects p < q */
395 cp = gcrypt_rsa_find_token(this->key, "q", NULL);
396 cq = gcrypt_rsa_find_token(this->key, "p", NULL);
397 cd = gcrypt_rsa_find_token(this->key, "d", NULL);
398
399 err = gcry_mpi_scan(&p, GCRYMPI_FMT_USG, cp.ptr, cp.len, NULL)
400 | gcry_mpi_scan(&q, GCRYMPI_FMT_USG, cq.ptr, cq.len, NULL)
401 | gcry_mpi_scan(&d, GCRYMPI_FMT_USG, cd.ptr, cd.len, NULL);
402 if (err)
403 {
404 gcry_mpi_release(p);
405 gcry_mpi_release(q);
406 gcry_mpi_release(d);
407 chunk_clear(&cp);
408 chunk_clear(&cq);
409 chunk_clear(&cd);
410 DBG1("scanning mpi for export failed: %s", gpg_strerror(err));
411 return chunk_empty;
412 }
413
414 gcry_mpi_sub_ui(p, p, 1);
415 exp1 = gcry_mpi_new(gcry_pk_get_nbits(this->key));
416 gcry_mpi_mod(exp1, d, p);
417 gcry_mpi_release(p);
418
419 gcry_mpi_sub_ui(q, q, 1);
420 exp2 = gcry_mpi_new(gcry_pk_get_nbits(this->key));
421 gcry_mpi_mod(exp1, d, q);
422 gcry_mpi_release(q);
423
424 err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &cexp1.ptr, &cexp1.len, exp1)
425 | gcry_mpi_aprint(GCRYMPI_FMT_USG, &cexp2.ptr, &cexp2.len, exp2);
426
427 gcry_mpi_release(d);
428 gcry_mpi_release(exp1);
429 gcry_mpi_release(exp2);
430
431 if (err)
432 {
433 DBG1("printing mpi for export failed: %s", gpg_strerror(err));
434 chunk_clear(&cp);
435 chunk_clear(&cq);
436 chunk_clear(&cd);
437 chunk_clear(&cexp1);
438 chunk_clear(&cexp2);
439 return chunk_empty;
440 }
441
442 return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm", ASN1_INTEGER_0,
443 asn1_integer("m", gcrypt_rsa_find_token(this->key, "n", NULL)),
444 asn1_integer("m", gcrypt_rsa_find_token(this->key, "e", NULL)),
445 asn1_integer("m", cd),
446 asn1_integer("m", cp),
447 asn1_integer("m", cq),
448 asn1_integer("m", cexp1),
449 asn1_integer("m", cexp2),
450 asn1_integer("m", gcrypt_rsa_find_token(this->key, "u", NULL)));
451 }
452
453 /**
454 * Implementation of gcrypt_rsa_private_key.get_ref.
455 */
456 static private_key_t* get_ref(private_gcrypt_rsa_private_key_t *this)
457 {
458 ref_get(&this->ref);
459 return &this->public.interface;
460 }
461
462 /**
463 * Implementation of gcrypt_rsa_private_key.destroy.
464 */
465 static void destroy(private_gcrypt_rsa_private_key_t *this)
466 {
467 if (ref_put(&this->ref))
468 {
469 DESTROY_IF(this->keyid);
470 DESTROY_IF(this->keyid_info);
471 gcry_sexp_release(this->key);
472 free(this);
473 }
474 }
475
476 /**
477 * Internal generic constructor
478 */
479 static private_gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_create_empty()
480 {
481 private_gcrypt_rsa_private_key_t *this = malloc_thing(private_gcrypt_rsa_private_key_t);
482
483 this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
484 this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
485 this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
486 this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
487 this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
488 this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
489 this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
490 this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
491 this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
492 this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
493 this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
494
495 this->key = NULL;
496 this->keyid = NULL;
497 this->keyid_info = NULL;
498 this->ref = 1;
499
500 return this;
501 }
502
503 /**
504 * build the keyids of a private/public key
505 */
506 bool gcrypt_rsa_build_keyids(gcry_sexp_t key, identification_t **keyid,
507 identification_t **keyid_info)
508 {
509 chunk_t publicKeyInfo, publicKey, hash;
510 hasher_t *hasher;
511
512 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
513 if (!hasher)
514 {
515 DBG1("SHA1 hash algorithm not supported, unable to use RSA");
516 return FALSE;
517 }
518 publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
519 asn1_integer("m", gcrypt_rsa_find_token(key, "n", NULL)),
520 asn1_integer("m", gcrypt_rsa_find_token(key, "e", NULL)));
521 hasher->allocate_hash(hasher, publicKey, &hash);
522 *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
523 chunk_free(&hash);
524
525 publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
526 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
527 asn1_bitstring("m", publicKey));
528 hasher->allocate_hash(hasher, publicKeyInfo, &hash);
529 *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
530 chunk_free(&hash);
531
532 hasher->destroy(hasher);
533 chunk_free(&publicKeyInfo);
534
535 return TRUE;
536 }
537
538 /**
539 * Generate an RSA key of specified key size
540 */
541 static gcrypt_rsa_private_key_t *generate(size_t key_size)
542 {
543 private_gcrypt_rsa_private_key_t *this;
544 gcry_sexp_t param, key;
545 gcry_error_t err;
546
547 err = gcry_sexp_build(&param, NULL, "(genkey(rsa(nbits %d)))", key_size);
548 if (err)
549 {
550 DBG1("building S-expression failed: %s", gpg_strerror(err));
551 return NULL;
552 }
553
554 err = gcry_pk_genkey(&key, param);
555 gcry_sexp_release(param);
556 if (err)
557 {
558 DBG1("generating RSA key failed: %s", gpg_strerror(err));
559 return NULL;
560 }
561 this = gcrypt_rsa_private_key_create_empty();
562 this->key = key;
563
564 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
565 {
566 destroy(this);
567 return NULL;
568 }
569
570 return &this->public;
571 }
572
573 /**
574 * Load a private key from components
575 */
576 static gcrypt_rsa_private_key_t *load(chunk_t n, chunk_t e, chunk_t d,
577 chunk_t p, chunk_t q, chunk_t u)
578 {
579 gcry_error_t err;
580 private_gcrypt_rsa_private_key_t *this = gcrypt_rsa_private_key_create_empty();
581
582 err = gcry_sexp_build(&this->key, NULL,
583 "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",
584 n.len, n.ptr, e.len, e.ptr, d.len, d.ptr,
585 p.len, p.ptr, q.len, q.ptr, u.len, u.ptr);
586 if (err)
587 {
588 DBG1("loading private key failed: %s", gpg_strerror(err));
589 free(this);
590 return NULL;
591 }
592 err = gcry_pk_testkey(this->key);
593 if (err)
594 {
595 DBG1("private key sanity check failed: %s", gpg_strerror(err));
596 destroy(this);
597 return NULL;
598 }
599 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
600 {
601 destroy(this);
602 return NULL;
603 }
604 return &this->public;
605 }
606
607 typedef struct private_builder_t private_builder_t;
608
609 /**
610 * Builder implementation for key loading/generation
611 */
612 struct private_builder_t {
613 /** implements the builder interface */
614 builder_t public;
615 /** key size, if generating */
616 u_int key_size;
617 /** rsa key parameters */
618 chunk_t n, e, d, p, q, u;
619 };
620
621 /**
622 * Implementation of builder_t.build
623 */
624 static gcrypt_rsa_private_key_t *build(private_builder_t *this)
625 {
626 gcrypt_rsa_private_key_t *key = NULL;
627
628 if (this->key_size)
629 {
630 key = generate(this->key_size);
631 }
632 else
633 {
634 key = load(this->n, this->e, this->d, this->p, this->q, this->u);
635 }
636 free(this);
637 return key;
638 }
639
640 /**
641 * Implementation of builder_t.add
642 */
643 static void add(private_builder_t *this, builder_part_t part, ...)
644 {
645 va_list args;
646
647 va_start(args, part);
648 switch (part)
649 {
650 case BUILD_KEY_SIZE:
651 this->key_size = va_arg(args, u_int);
652 return;
653 case BUILD_RSA_MODULUS:
654 this->n = va_arg(args, chunk_t);
655 break;
656 case BUILD_RSA_PUB_EXP:
657 this->e = va_arg(args, chunk_t);
658 break;
659 case BUILD_RSA_PRIV_EXP:
660 this->d = va_arg(args, chunk_t);
661 break;
662 case BUILD_RSA_PRIME1:
663 /* swap p and q, gcrypt expects p < q */
664 this->q = va_arg(args, chunk_t);
665 break;
666 case BUILD_RSA_PRIME2:
667 this->p = va_arg(args, chunk_t);
668 break;
669 case BUILD_RSA_EXP1:
670 case BUILD_RSA_EXP2:
671 /* not required for gcrypt */
672 break;
673 case BUILD_RSA_COEFF:
674 this->u = va_arg(args, chunk_t);
675 break;
676 default:
677 builder_cancel(&this->public);
678 break;
679 }
680 va_end(args);
681 }
682
683 /**
684 * Builder construction function
685 */
686 builder_t *gcrypt_rsa_private_key_builder(key_type_t type)
687 {
688 private_builder_t *this;
689
690 if (type != KEY_RSA)
691 {
692 return NULL;
693 }
694
695 this = malloc_thing(private_builder_t);
696
697 this->key_size = 0;
698 this->n = this->e = this->d = this->p = this->q = this->u = chunk_empty;
699 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
700 this->public.build = (void*(*)(builder_t *this))build;
701
702 return &this->public;
703 }
704