gcrypt RSA private key implementation
[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
60 */
61 static chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name)
62 {
63 gcry_sexp_t token;
64 chunk_t data = chunk_empty;
65
66 token = gcry_sexp_find_token(sexp, name, 1);
67 if (token)
68 {
69 data.ptr = (char*)gcry_sexp_nth_data(token, 1, &data.len);
70 if (!data.ptr)
71 {
72 data.len = 0;
73 }
74 data = chunk_clone(data);
75 gcry_sexp_release(token);
76 }
77 return data;
78 }
79
80 /**
81 * Implementation of gcrypt_rsa_private_key_t.build_emsa_pkcs1_signature.
82 */
83 static bool sign_pkcs1(private_gcrypt_rsa_private_key_t *this,
84 hash_algorithm_t hash_algorithm, char *hash_name,
85 chunk_t data, chunk_t *signature)
86 {
87 hasher_t *hasher;
88 chunk_t hash;
89 gcry_error_t err;
90 gcry_sexp_t in, out;
91 int hash_oid;
92
93 hash_oid = hasher_algorithm_to_oid(hash_algorithm);
94 if (hash_oid == OID_UNKNOWN)
95 {
96 return FALSE;
97 }
98 hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
99 if (!hasher)
100 {
101 return FALSE;
102 }
103 hasher->allocate_hash(hasher, data, &hash);
104 hasher->destroy(hasher);
105
106 err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
107 hash_name, hash.len, hash.ptr);
108 chunk_free(&hash);
109 if (err)
110 {
111 DBG1("building signature S-expression failed: %s", gpg_strerror(err));
112 return FALSE;
113 }
114 err = gcry_pk_sign(&out, in, this->key);
115 gcry_sexp_release(in);
116 if (err)
117 {
118 DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err));
119 return FALSE;
120 }
121 *signature = gcrypt_rsa_find_token(out, "s");
122 gcry_sexp_release(out);
123 return !!signature->len;
124 }
125
126 /**
127 * Implementation of gcrypt_rsa_private_key.destroy.
128 */
129 static key_type_t get_type(private_gcrypt_rsa_private_key_t *this)
130 {
131 return KEY_RSA;
132 }
133
134 /**
135 * Implementation of gcrypt_rsa_private_key.destroy.
136 */
137 static bool sign(private_gcrypt_rsa_private_key_t *this, signature_scheme_t scheme,
138 chunk_t data, chunk_t *sig)
139 {
140 switch (scheme)
141 {
142 case SIGN_DEFAULT:
143 /* default is EMSA-PKCS1 using SHA1 */
144 case SIGN_RSA_EMSA_PKCS1_SHA1:
145 return sign_pkcs1(this, HASH_SHA1, "sha1", data, sig);
146 case SIGN_RSA_EMSA_PKCS1_SHA256:
147 return sign_pkcs1(this, HASH_SHA256, "sha256", data, sig);
148 case SIGN_RSA_EMSA_PKCS1_SHA384:
149 return sign_pkcs1(this, HASH_SHA384, "sha384", data, sig);
150 case SIGN_RSA_EMSA_PKCS1_SHA512:
151 return sign_pkcs1(this, HASH_SHA512, "sha512", data, sig);
152 case SIGN_RSA_EMSA_PKCS1_MD5:
153 return sign_pkcs1(this, HASH_MD5, "md5", data, sig);
154 default:
155 DBG1("signature scheme %N not supported in RSA",
156 signature_scheme_names, scheme);
157 return FALSE;
158 }
159 }
160
161 /**
162 * Implementation of gcrypt_rsa_private_key.destroy.
163 */
164 static bool decrypt(private_gcrypt_rsa_private_key_t *this,
165 chunk_t crypto, chunk_t *plain)
166 {
167 DBG1("RSA private key decryption not implemented");
168 return FALSE;
169 }
170
171 /**
172 * Implementation of gcrypt_rsa_private_key.get_keysize.
173 */
174 static size_t get_keysize(private_gcrypt_rsa_private_key_t *this)
175 {
176 return gcry_pk_get_nbits(this->key) / 8;
177 }
178
179 /**
180 * Implementation of gcrypt_rsa_private_key.destroy.
181 */
182 static identification_t* get_id(private_gcrypt_rsa_private_key_t *this,
183 id_type_t type)
184 {
185 switch (type)
186 {
187 case ID_PUBKEY_INFO_SHA1:
188 return this->keyid_info;
189 case ID_PUBKEY_SHA1:
190 return this->keyid;
191 default:
192 return NULL;
193 }
194 }
195
196 /**
197 * Implementation of gcrypt_rsa_private_key.get_public_key.
198 */
199 static public_key_t* get_public_key(private_gcrypt_rsa_private_key_t *this)
200 {
201 return NULL;
202 }
203
204 /**
205 * Implementation of gcrypt_rsa_private_key.equals.
206 */
207 static bool equals(private_gcrypt_rsa_private_key_t *this, private_key_t *other)
208 {
209 identification_t *keyid;
210
211 if (&this->public.interface == other)
212 {
213 return TRUE;
214 }
215 if (other->get_type(other) != KEY_RSA)
216 {
217 return FALSE;
218 }
219 keyid = other->get_id(other, ID_PUBKEY_SHA1);
220 if (keyid && keyid->equals(keyid, this->keyid))
221 {
222 return TRUE;
223 }
224 keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
225 if (keyid && keyid->equals(keyid, this->keyid_info))
226 {
227 return TRUE;
228 }
229 return FALSE;
230 }
231
232 /**
233 * Implementation of gcrypt_rsa_private_key.belongs_to.
234 */
235 static bool belongs_to(private_gcrypt_rsa_private_key_t *this,
236 public_key_t *public)
237 {
238 identification_t *keyid;
239
240 if (public->get_type(public) != KEY_RSA)
241 {
242 return FALSE;
243 }
244 keyid = public->get_id(public, ID_PUBKEY_SHA1);
245 if (keyid && keyid->equals(keyid, this->keyid))
246 {
247 return TRUE;
248 }
249 keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
250 if (keyid && keyid->equals(keyid, this->keyid_info))
251 {
252 return TRUE;
253 }
254 return FALSE;
255 }
256
257 /**
258 * Implementation of private_key_t.get_encoding.
259 */
260 static chunk_t get_encoding(private_gcrypt_rsa_private_key_t *this)
261 {
262 chunk_t cp, cq, cd, cexp1 = chunk_empty, cexp2 = chunk_empty;
263 gcry_mpi_t p = NULL, q = NULL, d = NULL, exp1, exp2;
264 gcry_error_t err;
265
266 /* p and q are swapped, gcrypt expects p < q */
267 cp = gcrypt_rsa_find_token(this->key, "q");
268 cq = gcrypt_rsa_find_token(this->key, "p");
269 cd = gcrypt_rsa_find_token(this->key, "d");
270
271 err = gcry_mpi_scan(&p, GCRYMPI_FMT_USG, cp.ptr, cp.len, NULL)
272 | gcry_mpi_scan(&q, GCRYMPI_FMT_USG, cq.ptr, cq.len, NULL)
273 | gcry_mpi_scan(&d, GCRYMPI_FMT_USG, cd.ptr, cd.len, NULL);
274 if (err)
275 {
276 gcry_mpi_release(p);
277 gcry_mpi_release(q);
278 gcry_mpi_release(d);
279 chunk_clear(&cp);
280 chunk_clear(&cq);
281 chunk_clear(&cd);
282 DBG1("scanning mpi for export failed: %s", gpg_strerror(err));
283 return chunk_empty;
284 }
285
286 gcry_mpi_sub_ui(p, p, 1);
287 exp1 = gcry_mpi_new(gcry_pk_get_nbits(this->key));
288 gcry_mpi_mod(exp1, d, p);
289 gcry_mpi_release(p);
290
291 gcry_mpi_sub_ui(q, q, 1);
292 exp2 = gcry_mpi_new(gcry_pk_get_nbits(this->key));
293 gcry_mpi_mod(exp1, d, q);
294 gcry_mpi_release(q);
295
296 err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &cexp1.ptr, &cexp1.len, exp1)
297 | gcry_mpi_aprint(GCRYMPI_FMT_USG, &cexp2.ptr, &cexp2.len, exp2);
298
299 gcry_mpi_release(d);
300 gcry_mpi_release(exp1);
301 gcry_mpi_release(exp2);
302
303 if (err)
304 {
305 DBG1("printing mpi for export failed: %s", gpg_strerror(err));
306 chunk_clear(&cp);
307 chunk_clear(&cq);
308 chunk_clear(&cd);
309 chunk_clear(&cexp1);
310 chunk_clear(&cexp2);
311 return chunk_empty;
312 }
313
314 return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm", ASN1_INTEGER_0,
315 asn1_wrap(ASN1_INTEGER, "m", gcrypt_rsa_find_token(this->key, "n")),
316 asn1_wrap(ASN1_INTEGER, "m", gcrypt_rsa_find_token(this->key, "e")),
317 asn1_wrap(ASN1_INTEGER, "m", cd),
318 asn1_wrap(ASN1_INTEGER, "m", cp),
319 asn1_wrap(ASN1_INTEGER, "m", cq),
320 asn1_wrap(ASN1_INTEGER, "m", cexp1),
321 asn1_wrap(ASN1_INTEGER, "m", cexp2),
322 asn1_wrap(ASN1_INTEGER, "m", gcrypt_rsa_find_token(this->key, "u")));
323 }
324
325 /**
326 * Implementation of gcrypt_rsa_private_key.get_ref.
327 */
328 static private_key_t* get_ref(private_gcrypt_rsa_private_key_t *this)
329 {
330 ref_get(&this->ref);
331 return &this->public.interface;
332 }
333
334 /**
335 * Implementation of gcrypt_rsa_private_key.destroy.
336 */
337 static void destroy(private_gcrypt_rsa_private_key_t *this)
338 {
339 if (ref_put(&this->ref))
340 {
341 DESTROY_IF(this->keyid);
342 DESTROY_IF(this->keyid_info);
343 gcry_sexp_release(this->key);
344 free(this);
345 }
346 }
347
348 /**
349 * Internal generic constructor
350 */
351 static private_gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_create_empty()
352 {
353 private_gcrypt_rsa_private_key_t *this = malloc_thing(private_gcrypt_rsa_private_key_t);
354
355 this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
356 this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
357 this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
358 this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
359 this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
360 this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
361 this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
362 this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
363 this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
364 this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
365 this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
366
367 this->key = NULL;
368 this->keyid = NULL;
369 this->keyid_info = NULL;
370 this->ref = 1;
371
372 return this;
373 }
374
375 /**
376 * build the keyids of a private/public key
377 */
378 static bool gcrypt_rsa_build_keyids(gcry_sexp_t key, identification_t **keyid,
379 identification_t **keyid_info)
380 {
381 chunk_t publicKeyInfo, publicKey, hash;
382 hasher_t *hasher;
383
384 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
385 if (!hasher)
386 {
387 DBG1("SHA1 hash algorithm not supported, unable to use RSA");
388 return FALSE;
389 }
390 publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
391 asn1_wrap(ASN1_INTEGER, "m", gcrypt_rsa_find_token(key, "n")),
392 asn1_wrap(ASN1_INTEGER, "m", gcrypt_rsa_find_token(key, "e")));
393 hasher->allocate_hash(hasher, publicKey, &hash);
394 *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
395 chunk_free(&hash);
396
397 publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
398 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
399 asn1_bitstring("m", publicKey));
400 hasher->allocate_hash(hasher, publicKeyInfo, &hash);
401 *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
402 chunk_free(&hash);
403
404 hasher->destroy(hasher);
405 chunk_free(&publicKeyInfo);
406
407 return TRUE;
408 }
409
410 /**
411 * Generate an RSA key of specified key size
412 */
413 static gcrypt_rsa_private_key_t *generate(size_t key_size)
414 {
415 private_gcrypt_rsa_private_key_t *this;
416 gcry_sexp_t param, key;
417 gcry_error_t err;
418
419 err = gcry_sexp_build(&param, NULL, "(genkey(rsa(nbits %d)))", key_size);
420 if (err)
421 {
422 DBG1("building S-expression failed: %s", gpg_strerror(err));
423 return NULL;
424 }
425
426 err = gcry_pk_genkey(&key, param);
427 gcry_sexp_release(param);
428 if (err)
429 {
430 DBG1("generating RSA key failed: %s", gpg_strerror(err));
431 return NULL;
432 }
433 this = gcrypt_rsa_private_key_create_empty();
434 this->key = key;
435
436 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
437 {
438 destroy(this);
439 return NULL;
440 }
441
442 return &this->public;
443 }
444
445 /**
446 * ASN.1 definition of a PKCS#1 RSA private key
447 */
448 static const asn1Object_t privkeyObjects[] = {
449 { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
450 { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
451 { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
452 { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
453 { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
454 { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
455 { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
456 { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
457 { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
458 { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
459 { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
460 ASN1_LOOP }, /* 10 */
461 { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
462 { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
463 { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
464 { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
465 { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 15 */
466 { 0, "exit", ASN1_EOC, ASN1_EXIT }
467 };
468 #define PRIV_KEY_VERSION 1
469 #define PRIV_KEY_MODULUS 2
470 #define PRIV_KEY_PUB_EXP 3
471 #define PRIV_KEY_PRIV_EXP 4
472 #define PRIV_KEY_PRIME1 5
473 #define PRIV_KEY_PRIME2 6
474 #define PRIV_KEY_EXP1 7
475 #define PRIV_KEY_EXP2 8
476 #define PRIV_KEY_COEFF 9
477
478 /**
479 * load private key from a ASN1 encoded blob
480 */
481 static gcrypt_rsa_private_key_t *load(chunk_t blob)
482 {
483 private_gcrypt_rsa_private_key_t *this;
484 asn1_parser_t *parser;
485 chunk_t object;
486 int objectID ;
487 bool success = FALSE;
488 chunk_t n, e, d, u, p, q;
489 gcry_error_t err;
490
491 parser = asn1_parser_create(privkeyObjects, blob);
492 parser->set_flags(parser, FALSE, TRUE);
493
494 while (parser->iterate(parser, &objectID, &object))
495 {
496 switch (objectID)
497 {
498 case PRIV_KEY_VERSION:
499 if (object.len > 0 && *object.ptr != 0)
500 {
501 goto end;
502 }
503 break;
504 case PRIV_KEY_MODULUS:
505 n = object;
506 break;
507 case PRIV_KEY_PUB_EXP:
508 e = object;
509 break;
510 case PRIV_KEY_PRIV_EXP:
511 d = object;
512 break;
513 case PRIV_KEY_PRIME1:
514 /* p and q are swapped, as gcrypt expects p < q */
515 q = object;
516 break;
517 case PRIV_KEY_PRIME2:
518 p = object;
519 break;
520 case PRIV_KEY_EXP1:
521 case PRIV_KEY_EXP2:
522 break;
523 case PRIV_KEY_COEFF:
524 u = object;
525 break;
526 }
527 }
528 success = parser->success(parser);
529
530 end:
531 parser->destroy(parser);
532
533 if (!success)
534 {
535 return NULL;
536 }
537
538 this = gcrypt_rsa_private_key_create_empty();
539 err = gcry_sexp_build(&this->key, NULL,
540 "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",
541 n.len, n.ptr, e.len, e.ptr, d.len, d.ptr,
542 p.len, p.ptr, q.len, q.ptr, u.len, u.ptr);
543 if (err)
544 {
545 DBG1("loading private key failed: %s", gpg_strerror(err));
546 free(this);
547 return NULL;
548 }
549 err = gcry_pk_testkey(this->key);
550 if (err)
551 {
552 DBG1("private key sanity check failed: %s", gpg_strerror(err));
553 destroy(this);
554 return NULL;
555 }
556 if (!gcrypt_rsa_build_keyids(this->key, &this->keyid, &this->keyid_info))
557 {
558 destroy(this);
559 return NULL;
560 }
561 return &this->public;
562 }
563
564 typedef struct private_builder_t private_builder_t;
565
566 /**
567 * Builder implementation for key loading/generation
568 */
569 struct private_builder_t {
570 /** implements the builder interface */
571 builder_t public;
572 /** loaded/generated private key */
573 gcrypt_rsa_private_key_t *key;
574 };
575
576 /**
577 * Implementation of builder_t.build
578 */
579 static gcrypt_rsa_private_key_t *build(private_builder_t *this)
580 {
581 gcrypt_rsa_private_key_t *key = this->key;
582
583 free(this);
584 return key;
585 }
586
587 /**
588 * Implementation of builder_t.add
589 */
590 static void add(private_builder_t *this, builder_part_t part, ...)
591 {
592 if (!this->key)
593 {
594 va_list args;
595
596 switch (part)
597 {
598 case BUILD_BLOB_ASN1_DER:
599 {
600 va_start(args, part);
601 this->key = load(va_arg(args, chunk_t));
602 va_end(args);
603 return;
604 }
605 case BUILD_KEY_SIZE:
606 {
607 va_start(args, part);
608 this->key = generate(va_arg(args, u_int));
609 va_end(args);
610 return;
611 }
612 default:
613 break;
614 }
615 }
616 if (this->key)
617 {
618 destroy((private_gcrypt_rsa_private_key_t*)this->key);
619 }
620 builder_cancel(&this->public);
621 }
622
623 /**
624 * Builder construction function
625 */
626 builder_t *gcrypt_rsa_private_key_builder(key_type_t type)
627 {
628 private_builder_t *this;
629
630 if (type != KEY_RSA)
631 {
632 return NULL;
633 }
634
635 this = malloc_thing(private_builder_t);
636
637 this->key = NULL;
638 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
639 this->public.build = (void*(*)(builder_t *this))build;
640
641 return &this->public;
642 }
643