2 * Copyright (C) 2005-2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include "gcrypt_rsa_private_key.h"
22 #include <asn1/asn1.h>
23 #include <asn1/asn1_parser.h>
25 typedef struct private_gcrypt_rsa_private_key_t private_gcrypt_rsa_private_key_t
;
28 * Private data of a gcrypt_rsa_private_key_t object.
30 struct private_gcrypt_rsa_private_key_t
{
35 gcrypt_rsa_private_key_t
public;
38 * gcrypt S-expression representing an RSA key
43 * Keyid formed as a SHA-1 hash of a publicKey object
45 identification_t
* keyid
;
48 * Keyid formed as a SHA-1 hash of a publicKeyInfo object
50 identification_t
* keyid_info
;
59 * Implemented in gcrypt_rsa_public_key.c
61 public_key_t
*gcrypt_rsa_public_key_create_from_sexp(gcry_sexp_t key
);
64 * find a token in a S-expression. If a key is given, its length is used to
65 * pad the output to a given length.
67 chunk_t
gcrypt_rsa_find_token(gcry_sexp_t sexp
, char *name
, gcry_sexp_t key
)
70 chunk_t data
= chunk_empty
, tmp
;
73 token
= gcry_sexp_find_token(sexp
, name
, 1);
76 data
.ptr
= (char*)gcry_sexp_nth_data(token
, 1, &data
.len
);
85 /* gcrypt might return more bytes than necessary. Truncate
86 * to key lenght if key given, or prepend zeros if needed */
87 len
= gcry_pk_get_nbits(key
);
88 len
= len
/ 8 + (len
% 8 ?
1 : 0);
91 tmp
= chunk_alloc(len
);
93 memset(tmp
.ptr
, 0, tmp
.len
- len
);
94 memcpy(tmp
.ptr
+ len
, data
.ptr
, data
.len
);
97 else if (len
< data
.len
)
99 data
= chunk_clone(chunk_skip(data
, data
.len
- len
));
103 data
= chunk_clone(data
);
108 data
= chunk_clone(data
);
111 gcry_sexp_release(token
);
117 * Sign a chunk of data with direct PKCS#1 encoding, no hash OID
119 static bool sign_raw(private_gcrypt_rsa_private_key_t
*this,
120 chunk_t data
, chunk_t
*signature
)
127 /* EM = 0x00 || 0x01 || PS || 0x00 || T
128 * PS = 0xFF padding, with length to fill em
131 k
= gcry_pk_get_nbits(this->key
) / 8;
132 if (data
.len
> k
- 3)
137 memset(em
.ptr
, 0xFF, em
.len
);
140 em
.ptr
[em
.len
- data
.len
- 1] = 0x00;
141 memcpy(em
.ptr
+ em
.len
- data
.len
, data
.ptr
, data
.len
);
143 err
= gcry_sexp_build(&in
, NULL
, "(data(flags raw)(value %b))",
148 DBG1("building signature S-expression failed: %s", gpg_strerror(err
));
151 err
= gcry_pk_sign(&out
, in
, this->key
);
152 gcry_sexp_release(in
);
155 DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err
));
158 *signature
= gcrypt_rsa_find_token(out
, "s", this->key
);
159 gcry_sexp_release(out
);
160 return !!signature
->len
;
164 * Sign a chunk of data using hashing and PKCS#1 encoding
166 static bool sign_pkcs1(private_gcrypt_rsa_private_key_t
*this,
167 hash_algorithm_t hash_algorithm
, char *hash_name
,
168 chunk_t data
, chunk_t
*signature
)
176 hash_oid
= hasher_algorithm_to_oid(hash_algorithm
);
177 if (hash_oid
== OID_UNKNOWN
)
181 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, hash_algorithm
);
186 hasher
->allocate_hash(hasher
, data
, &hash
);
187 hasher
->destroy(hasher
);
189 err
= gcry_sexp_build(&in
, NULL
, "(data(flags pkcs1)(hash %s %b))",
190 hash_name
, hash
.len
, hash
.ptr
);
194 DBG1("building signature S-expression failed: %s", gpg_strerror(err
));
197 err
= gcry_pk_sign(&out
, in
, this->key
);
198 gcry_sexp_release(in
);
201 DBG1("creating pkcs1 signature failed: %s", gpg_strerror(err
));
204 *signature
= gcrypt_rsa_find_token(out
, "s", this->key
);
205 gcry_sexp_release(out
);
206 return !!signature
->len
;
210 * Implementation of gcrypt_rsa_private_key.destroy.
212 static key_type_t
get_type(private_gcrypt_rsa_private_key_t
*this)
218 * Implementation of gcrypt_rsa_private_key.destroy.
220 static bool sign(private_gcrypt_rsa_private_key_t
*this, signature_scheme_t scheme
,
221 chunk_t data
, chunk_t
*sig
)
225 case SIGN_RSA_EMSA_PKCS1_NULL
:
226 return sign_raw(this, data
, sig
);
227 case SIGN_RSA_EMSA_PKCS1_SHA1
:
228 return sign_pkcs1(this, HASH_SHA1
, "sha1", data
, sig
);
229 case SIGN_RSA_EMSA_PKCS1_SHA256
:
230 return sign_pkcs1(this, HASH_SHA256
, "sha256", data
, sig
);
231 case SIGN_RSA_EMSA_PKCS1_SHA384
:
232 return sign_pkcs1(this, HASH_SHA384
, "sha384", data
, sig
);
233 case SIGN_RSA_EMSA_PKCS1_SHA512
:
234 return sign_pkcs1(this, HASH_SHA512
, "sha512", data
, sig
);
235 case SIGN_RSA_EMSA_PKCS1_MD5
:
236 return sign_pkcs1(this, HASH_MD5
, "md5", data
, sig
);
238 DBG1("signature scheme %N not supported in RSA",
239 signature_scheme_names
, scheme
);
245 * Implementation of gcrypt_rsa_private_key.destroy.
247 static bool decrypt(private_gcrypt_rsa_private_key_t
*this,
248 chunk_t encrypted
, chunk_t
*plain
)
255 err
= gcry_sexp_build(&in
, NULL
, "(enc-val(flags)(rsa(a %b)))",
256 encrypted
.len
, encrypted
.ptr
);
259 DBG1("building decryption S-expression failed: %s", gpg_strerror(err
));
262 err
= gcry_pk_decrypt(&out
, in
, this->key
);
263 gcry_sexp_release(in
);
266 DBG1("decrypting pkcs1 data failed: %s", gpg_strerror(err
));
269 padded
.ptr
= (u_char
*)gcry_sexp_nth_data(out
, 1, &padded
.len
);
270 /* result is padded, but gcrypt strips leading zero:
271 * 00 | 02 | RANDOM | 00 | DATA */
272 if (padded
.ptr
&& padded
.len
> 2 && padded
.ptr
[0] == 0x02)
274 pos
= memchr(padded
.ptr
, 0x00, padded
.len
- 1);
278 *plain
= chunk_clone(chunk_create(
279 pos
, padded
.len
- (pos
- padded
.ptr
)));
282 gcry_sexp_release(out
);
285 DBG1("decrypted data has invalid pkcs1 padding");
292 * Implementation of gcrypt_rsa_private_key.get_keysize.
294 static size_t get_keysize(private_gcrypt_rsa_private_key_t
*this)
296 return gcry_pk_get_nbits(this->key
) / 8;
300 * Implementation of gcrypt_rsa_private_key.destroy.
302 static identification_t
* get_id(private_gcrypt_rsa_private_key_t
*this,
307 case ID_PUBKEY_INFO_SHA1
:
308 return this->keyid_info
;
317 * Implementation of gcrypt_rsa_private_key.get_public_key.
319 static public_key_t
* get_public_key(private_gcrypt_rsa_private_key_t
*this)
321 return gcrypt_rsa_public_key_create_from_sexp(this->key
);
325 * Implementation of gcrypt_rsa_private_key.equals.
327 static bool equals(private_gcrypt_rsa_private_key_t
*this, private_key_t
*other
)
329 identification_t
*keyid
;
331 if (&this->public.interface
== other
)
335 if (other
->get_type(other
) != KEY_RSA
)
339 keyid
= other
->get_id(other
, ID_PUBKEY_SHA1
);
340 if (keyid
&& keyid
->equals(keyid
, this->keyid
))
344 keyid
= other
->get_id(other
, ID_PUBKEY_INFO_SHA1
);
345 if (keyid
&& keyid
->equals(keyid
, this->keyid_info
))
353 * Implementation of gcrypt_rsa_private_key.belongs_to.
355 static bool belongs_to(private_gcrypt_rsa_private_key_t
*this,
356 public_key_t
*public)
358 identification_t
*keyid
;
360 if (public->get_type(public) != KEY_RSA
)
364 keyid
= public->get_id(public, ID_PUBKEY_SHA1
);
365 if (keyid
&& keyid
->equals(keyid
, this->keyid
))
369 keyid
= public->get_id(public, ID_PUBKEY_INFO_SHA1
);
370 if (keyid
&& keyid
->equals(keyid
, this->keyid_info
))
378 * Implementation of private_key_t.get_encoding.
380 static chunk_t
get_encoding(private_gcrypt_rsa_private_key_t
*this)
382 chunk_t cp
, cq
, cd
, cexp1
= chunk_empty
, cexp2
= chunk_empty
;
383 gcry_mpi_t p
= NULL
, q
= NULL
, d
= NULL
, exp1
, exp2
;
386 /* p and q are swapped, gcrypt expects p < q */
387 cp
= gcrypt_rsa_find_token(this->key
, "q", NULL
);
388 cq
= gcrypt_rsa_find_token(this->key
, "p", NULL
);
389 cd
= gcrypt_rsa_find_token(this->key
, "d", NULL
);
391 err
= gcry_mpi_scan(&p
, GCRYMPI_FMT_USG
, cp
.ptr
, cp
.len
, NULL
)
392 | gcry_mpi_scan(&q
, GCRYMPI_FMT_USG
, cq
.ptr
, cq
.len
, NULL
)
393 | gcry_mpi_scan(&d
, GCRYMPI_FMT_USG
, cd
.ptr
, cd
.len
, NULL
);
402 DBG1("scanning mpi for export failed: %s", gpg_strerror(err
));
406 gcry_mpi_sub_ui(p
, p
, 1);
407 exp1
= gcry_mpi_new(gcry_pk_get_nbits(this->key
));
408 gcry_mpi_mod(exp1
, d
, p
);
411 gcry_mpi_sub_ui(q
, q
, 1);
412 exp2
= gcry_mpi_new(gcry_pk_get_nbits(this->key
));
413 gcry_mpi_mod(exp1
, d
, q
);
416 err
= gcry_mpi_aprint(GCRYMPI_FMT_USG
, &cexp1
.ptr
, &cexp1
.len
, exp1
)
417 | gcry_mpi_aprint(GCRYMPI_FMT_USG
, &cexp2
.ptr
, &cexp2
.len
, exp2
);
420 gcry_mpi_release(exp1
);
421 gcry_mpi_release(exp2
);
425 DBG1("printing mpi for export failed: %s", gpg_strerror(err
));
434 return asn1_wrap(ASN1_SEQUENCE
, "cmmmmmmmm", ASN1_INTEGER_0
,
435 asn1_integer("m", gcrypt_rsa_find_token(this->key
, "n", NULL
)),
436 asn1_integer("m", gcrypt_rsa_find_token(this->key
, "e", NULL
)),
437 asn1_integer("m", cd
),
438 asn1_integer("m", cp
),
439 asn1_integer("m", cq
),
440 asn1_integer("m", cexp1
),
441 asn1_integer("m", cexp2
),
442 asn1_integer("m", gcrypt_rsa_find_token(this->key
, "u", NULL
)));
446 * Implementation of gcrypt_rsa_private_key.get_ref.
448 static private_key_t
* get_ref(private_gcrypt_rsa_private_key_t
*this)
451 return &this->public.interface
;
455 * Implementation of gcrypt_rsa_private_key.destroy.
457 static void destroy(private_gcrypt_rsa_private_key_t
*this)
459 if (ref_put(&this->ref
))
461 DESTROY_IF(this->keyid
);
462 DESTROY_IF(this->keyid_info
);
463 gcry_sexp_release(this->key
);
469 * Internal generic constructor
471 static private_gcrypt_rsa_private_key_t
*gcrypt_rsa_private_key_create_empty()
473 private_gcrypt_rsa_private_key_t
*this = malloc_thing(private_gcrypt_rsa_private_key_t
);
475 this->public.interface
.get_type
= (key_type_t (*)(private_key_t
*this))get_type
;
476 this->public.interface
.sign
= (bool (*)(private_key_t
*this, signature_scheme_t scheme
, chunk_t data
, chunk_t
*signature
))sign
;
477 this->public.interface
.decrypt
= (bool (*)(private_key_t
*this, chunk_t crypto
, chunk_t
*plain
))decrypt
;
478 this->public.interface
.get_keysize
= (size_t (*) (private_key_t
*this))get_keysize
;
479 this->public.interface
.get_id
= (identification_t
* (*) (private_key_t
*this,id_type_t
))get_id
;
480 this->public.interface
.get_public_key
= (public_key_t
* (*)(private_key_t
*this))get_public_key
;
481 this->public.interface
.equals
= (bool (*) (private_key_t
*, private_key_t
*))equals
;
482 this->public.interface
.belongs_to
= (bool (*) (private_key_t
*this, public_key_t
*public))belongs_to
;
483 this->public.interface
.get_encoding
= (chunk_t(*)(private_key_t
*))get_encoding
;
484 this->public.interface
.get_ref
= (private_key_t
* (*)(private_key_t
*this))get_ref
;
485 this->public.interface
.destroy
= (void (*)(private_key_t
*this))destroy
;
489 this->keyid_info
= NULL
;
496 * build the keyids of a private/public key
498 bool gcrypt_rsa_build_keyids(gcry_sexp_t key
, identification_t
**keyid
,
499 identification_t
**keyid_info
)
501 chunk_t publicKeyInfo
, publicKey
, hash
;
504 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
507 DBG1("SHA1 hash algorithm not supported, unable to use RSA");
510 publicKey
= asn1_wrap(ASN1_SEQUENCE
, "mm",
511 asn1_integer("m", gcrypt_rsa_find_token(key
, "n", NULL
)),
512 asn1_integer("m", gcrypt_rsa_find_token(key
, "e", NULL
)));
513 hasher
->allocate_hash(hasher
, publicKey
, &hash
);
514 *keyid
= identification_create_from_encoding(ID_PUBKEY_SHA1
, hash
);
517 publicKeyInfo
= asn1_wrap(ASN1_SEQUENCE
, "cm",
518 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION
),
519 asn1_bitstring("m", publicKey
));
520 hasher
->allocate_hash(hasher
, publicKeyInfo
, &hash
);
521 *keyid_info
= identification_create_from_encoding(ID_PUBKEY_INFO_SHA1
, hash
);
524 hasher
->destroy(hasher
);
525 chunk_free(&publicKeyInfo
);
531 * Generate an RSA key of specified key size
533 static gcrypt_rsa_private_key_t
*generate(size_t key_size
)
535 private_gcrypt_rsa_private_key_t
*this;
536 gcry_sexp_t param
, key
;
539 err
= gcry_sexp_build(¶m
, NULL
, "(genkey(rsa(nbits %d)))", key_size
);
542 DBG1("building S-expression failed: %s", gpg_strerror(err
));
546 err
= gcry_pk_genkey(&key
, param
);
547 gcry_sexp_release(param
);
550 DBG1("generating RSA key failed: %s", gpg_strerror(err
));
553 this = gcrypt_rsa_private_key_create_empty();
556 if (!gcrypt_rsa_build_keyids(this->key
, &this->keyid
, &this->keyid_info
))
562 return &this->public;
566 * ASN.1 definition of a PKCS#1 RSA private key
568 static const asn1Object_t privkeyObjects
[] = {
569 { 0, "RSAPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
570 { 1, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 1 */
571 { 1, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
572 { 1, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
573 { 1, "privateExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
574 { 1, "prime1", ASN1_INTEGER
, ASN1_BODY
}, /* 5 */
575 { 1, "prime2", ASN1_INTEGER
, ASN1_BODY
}, /* 6 */
576 { 1, "exponent1", ASN1_INTEGER
, ASN1_BODY
}, /* 7 */
577 { 1, "exponent2", ASN1_INTEGER
, ASN1_BODY
}, /* 8 */
578 { 1, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 9 */
579 { 1, "otherPrimeInfos", ASN1_SEQUENCE
, ASN1_OPT
|
580 ASN1_LOOP
}, /* 10 */
581 { 2, "otherPrimeInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
582 { 3, "prime", ASN1_INTEGER
, ASN1_BODY
}, /* 12 */
583 { 3, "exponent", ASN1_INTEGER
, ASN1_BODY
}, /* 13 */
584 { 3, "coefficient", ASN1_INTEGER
, ASN1_BODY
}, /* 14 */
585 { 1, "end opt or loop", ASN1_EOC
, ASN1_END
}, /* 15 */
586 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
588 #define PRIV_KEY_VERSION 1
589 #define PRIV_KEY_MODULUS 2
590 #define PRIV_KEY_PUB_EXP 3
591 #define PRIV_KEY_PRIV_EXP 4
592 #define PRIV_KEY_PRIME1 5
593 #define PRIV_KEY_PRIME2 6
594 #define PRIV_KEY_EXP1 7
595 #define PRIV_KEY_EXP2 8
596 #define PRIV_KEY_COEFF 9
599 * load private key from a ASN1 encoded blob
601 static gcrypt_rsa_private_key_t
*load(chunk_t blob
)
603 private_gcrypt_rsa_private_key_t
*this;
604 asn1_parser_t
*parser
;
607 bool success
= FALSE
;
608 chunk_t n
, e
, d
, u
, p
, q
;
611 n
= e
= d
= u
= p
= q
= chunk_empty
;
613 parser
= asn1_parser_create(privkeyObjects
, blob
);
614 parser
->set_flags(parser
, FALSE
, TRUE
);
616 while (parser
->iterate(parser
, &objectID
, &object
))
620 case PRIV_KEY_VERSION
:
621 if (object
.len
> 0 && *object
.ptr
!= 0)
626 case PRIV_KEY_MODULUS
:
629 case PRIV_KEY_PUB_EXP
:
632 case PRIV_KEY_PRIV_EXP
:
635 case PRIV_KEY_PRIME1
:
636 /* p and q are swapped, as gcrypt expects p < q */
639 case PRIV_KEY_PRIME2
:
650 success
= parser
->success(parser
);
653 parser
->destroy(parser
);
660 this = gcrypt_rsa_private_key_create_empty();
661 err
= gcry_sexp_build(&this->key
, NULL
,
662 "(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",
663 n
.len
, n
.ptr
, e
.len
, e
.ptr
, d
.len
, d
.ptr
,
664 p
.len
, p
.ptr
, q
.len
, q
.ptr
, u
.len
, u
.ptr
);
667 DBG1("loading private key failed: %s", gpg_strerror(err
));
671 err
= gcry_pk_testkey(this->key
);
674 DBG1("private key sanity check failed: %s", gpg_strerror(err
));
678 if (!gcrypt_rsa_build_keyids(this->key
, &this->keyid
, &this->keyid_info
))
683 return &this->public;
686 typedef struct private_builder_t private_builder_t
;
689 * Builder implementation for key loading/generation
691 struct private_builder_t
{
692 /** implements the builder interface */
694 /** loaded/generated private key */
695 gcrypt_rsa_private_key_t
*key
;
699 * Implementation of builder_t.build
701 static gcrypt_rsa_private_key_t
*build(private_builder_t
*this)
703 gcrypt_rsa_private_key_t
*key
= this->key
;
710 * Implementation of builder_t.add
712 static void add(private_builder_t
*this, builder_part_t part
, ...)
720 case BUILD_BLOB_ASN1_DER
:
722 va_start(args
, part
);
723 this->key
= load(va_arg(args
, chunk_t
));
729 va_start(args
, part
);
730 this->key
= generate(va_arg(args
, u_int
));
740 destroy((private_gcrypt_rsa_private_key_t
*)this->key
);
742 builder_cancel(&this->public);
746 * Builder construction function
748 builder_t
*gcrypt_rsa_private_key_builder(key_type_t type
)
750 private_builder_t
*this;
757 this = malloc_thing(private_builder_t
);
760 this->public.add
= (void(*)(builder_t
*this, builder_part_t part
, ...))add
;
761 this->public.build
= (void*(*)(builder_t
*this))build
;
763 return &this->public;