2 * Copyright (C) 2009 Martin Willi
3 * Copyright (C) 2008 Tobias Brunner
4 * Hochschule fuer Technik Rapperswil
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>.
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
17 #include <openssl/opensslconf.h>
19 #ifndef OPENSSL_NO_RSA
21 #include "openssl_rsa_private_key.h"
22 #include "openssl_rsa_public_key.h"
24 #include <utils/debug.h>
26 #include <openssl/evp.h>
27 #include <openssl/rsa.h>
28 #ifndef OPENSSL_NO_ENGINE
29 #include <openssl/engine.h>
30 #endif /* OPENSSL_NO_ENGINE */
33 * Public exponent to use for key generation.
35 #define PUBLIC_EXPONENT 0x10001
37 typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t
;
40 * Private data of a openssl_rsa_private_key_t object.
42 struct private_openssl_rsa_private_key_t
{
44 * Public interface for this signer.
46 openssl_rsa_private_key_t
public;
49 * RSA object from OpenSSL
54 * TRUE if the key is from an OpenSSL ENGINE and might not be readable
64 /* implemented in rsa public key */
65 bool openssl_rsa_fingerprint(RSA
*rsa
, cred_encoding_type_t type
, chunk_t
*fp
);
68 * Build an EMPSA PKCS1 signature described in PKCS#1
70 static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t
*this,
71 int type
, chunk_t data
, chunk_t
*sig
)
75 *sig
= chunk_alloc(RSA_size(this->rsa
));
77 if (type
== NID_undef
)
79 if (RSA_private_encrypt(data
.len
, data
.ptr
, sig
->ptr
, this->rsa
,
80 RSA_PKCS1_PADDING
) == sig
->len
)
92 hasher
= EVP_get_digestbynid(type
);
98 ctx
= EVP_MD_CTX_create();
104 if (!EVP_PKEY_set1_RSA(key
, this->rsa
))
108 if (!EVP_SignInit_ex(ctx
, hasher
, NULL
))
112 if (!EVP_SignUpdate(ctx
, data
.ptr
, data
.len
))
116 if (EVP_SignFinal(ctx
, sig
->ptr
, &len
, key
))
128 EVP_MD_CTX_destroy(ctx
);
139 METHOD(private_key_t
, get_type
, key_type_t
,
140 private_openssl_rsa_private_key_t
*this)
145 METHOD(private_key_t
, sign
, bool,
146 private_openssl_rsa_private_key_t
*this, signature_scheme_t scheme
,
147 chunk_t data
, chunk_t
*signature
)
151 case SIGN_RSA_EMSA_PKCS1_NULL
:
152 return build_emsa_pkcs1_signature(this, NID_undef
, data
, signature
);
153 case SIGN_RSA_EMSA_PKCS1_SHA1
:
154 return build_emsa_pkcs1_signature(this, NID_sha1
, data
, signature
);
155 case SIGN_RSA_EMSA_PKCS1_SHA224
:
156 return build_emsa_pkcs1_signature(this, NID_sha224
, data
, signature
);
157 case SIGN_RSA_EMSA_PKCS1_SHA256
:
158 return build_emsa_pkcs1_signature(this, NID_sha256
, data
, signature
);
159 case SIGN_RSA_EMSA_PKCS1_SHA384
:
160 return build_emsa_pkcs1_signature(this, NID_sha384
, data
, signature
);
161 case SIGN_RSA_EMSA_PKCS1_SHA512
:
162 return build_emsa_pkcs1_signature(this, NID_sha512
, data
, signature
);
163 case SIGN_RSA_EMSA_PKCS1_MD5
:
164 return build_emsa_pkcs1_signature(this, NID_md5
, data
, signature
);
166 DBG1(DBG_LIB
, "signature scheme %N not supported in RSA",
167 signature_scheme_names
, scheme
);
172 METHOD(private_key_t
, decrypt
, bool,
173 private_openssl_rsa_private_key_t
*this, encryption_scheme_t scheme
,
174 chunk_t crypto
, chunk_t
*plain
)
181 case ENCRYPT_RSA_PKCS1
:
182 padding
= RSA_PKCS1_PADDING
;
184 case ENCRYPT_RSA_OAEP_SHA1
:
185 padding
= RSA_PKCS1_OAEP_PADDING
;
188 DBG1(DBG_LIB
, "encryption scheme %N not supported via openssl",
189 encryption_scheme_names
, scheme
);
192 decrypted
= malloc(RSA_size(this->rsa
));
193 len
= RSA_private_decrypt(crypto
.len
, crypto
.ptr
, decrypted
,
197 DBG1(DBG_LIB
, "RSA decryption failed");
201 *plain
= chunk_create(decrypted
, len
);
205 METHOD(private_key_t
, get_keysize
, int,
206 private_openssl_rsa_private_key_t
*this)
208 return RSA_size(this->rsa
) * 8;
211 METHOD(private_key_t
, get_public_key
, public_key_t
*,
212 private_openssl_rsa_private_key_t
*this)
218 enc
= chunk_alloc(i2d_RSAPublicKey(this->rsa
, NULL
));
220 i2d_RSAPublicKey(this->rsa
, &p
);
221 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
222 BUILD_BLOB_ASN1_DER
, enc
, BUILD_END
);
227 METHOD(private_key_t
, get_fingerprint
, bool,
228 private_openssl_rsa_private_key_t
*this, cred_encoding_type_t type
,
229 chunk_t
*fingerprint
)
231 return openssl_rsa_fingerprint(this->rsa
, type
, fingerprint
);
234 METHOD(private_key_t
, get_encoding
, bool,
235 private_openssl_rsa_private_key_t
*this, cred_encoding_type_t type
,
246 case PRIVKEY_ASN1_DER
:
251 *encoding
= chunk_alloc(i2d_RSAPrivateKey(this->rsa
, NULL
));
253 i2d_RSAPrivateKey(this->rsa
, &p
);
255 if (type
== PRIVKEY_PEM
)
257 chunk_t asn1_encoding
= *encoding
;
259 success
= lib
->encoding
->encode(lib
->encoding
, PRIVKEY_PEM
,
260 NULL
, encoding
, CRED_PART_RSA_PRIV_ASN1_DER
,
261 asn1_encoding
, CRED_PART_END
);
262 chunk_clear(&asn1_encoding
);
271 METHOD(private_key_t
, get_ref
, private_key_t
*,
272 private_openssl_rsa_private_key_t
*this)
275 return &this->public.key
;
278 METHOD(private_key_t
, destroy
, void,
279 private_openssl_rsa_private_key_t
*this)
281 if (ref_put(&this->ref
))
285 lib
->encoding
->clear_cache(lib
->encoding
, this->rsa
);
293 * Internal generic constructor
295 static private_openssl_rsa_private_key_t
*create_empty()
297 private_openssl_rsa_private_key_t
*this;
302 .get_type
= _get_type
,
305 .get_keysize
= _get_keysize
,
306 .get_public_key
= _get_public_key
,
307 .equals
= private_key_equals
,
308 .belongs_to
= private_key_belongs_to
,
309 .get_fingerprint
= _get_fingerprint
,
310 .has_fingerprint
= private_key_has_fingerprint
,
311 .get_encoding
= _get_encoding
,
325 openssl_rsa_private_key_t
*openssl_rsa_private_key_gen(key_type_t type
,
328 private_openssl_rsa_private_key_t
*this;
335 switch (va_arg(args
, builder_part_t
))
338 key_size
= va_arg(args
, u_int
);
352 if (!e
|| !BN_set_word(e
, PUBLIC_EXPONENT
))
357 if (!rsa
|| !RSA_generate_key_ex(rsa
, key_size
, e
, NULL
))
361 this = create_empty();
364 return &this->public;
381 openssl_rsa_private_key_t
*openssl_rsa_private_key_load(key_type_t type
,
384 private_openssl_rsa_private_key_t
*this;
385 chunk_t blob
, n
, e
, d
, p
, q
, exp1
, exp2
, coeff
;
387 blob
= n
= e
= d
= p
= q
= exp1
= exp2
= coeff
= chunk_empty
;
390 switch (va_arg(args
, builder_part_t
))
392 case BUILD_BLOB_ASN1_DER
:
393 blob
= va_arg(args
, chunk_t
);
395 case BUILD_RSA_MODULUS
:
396 n
= va_arg(args
, chunk_t
);
398 case BUILD_RSA_PUB_EXP
:
399 e
= va_arg(args
, chunk_t
);
401 case BUILD_RSA_PRIV_EXP
:
402 d
= va_arg(args
, chunk_t
);
404 case BUILD_RSA_PRIME1
:
405 p
= va_arg(args
, chunk_t
);
407 case BUILD_RSA_PRIME2
:
408 q
= va_arg(args
, chunk_t
);
411 exp1
= va_arg(args
, chunk_t
);
414 exp2
= va_arg(args
, chunk_t
);
416 case BUILD_RSA_COEFF
:
417 coeff
= va_arg(args
, chunk_t
);
427 this = create_empty();
430 this->rsa
= d2i_RSAPrivateKey(NULL
, (const u_char
**)&blob
.ptr
, blob
.len
);
431 if (this->rsa
&& RSA_check_key(this->rsa
))
433 return &this->public;
436 else if (n
.ptr
&& e
.ptr
&& d
.ptr
&& p
.ptr
&& q
.ptr
&& coeff
.ptr
)
438 this->rsa
= RSA_new();
439 this->rsa
->n
= BN_bin2bn((const u_char
*)n
.ptr
, n
.len
, NULL
);
440 this->rsa
->e
= BN_bin2bn((const u_char
*)e
.ptr
, e
.len
, NULL
);
441 this->rsa
->d
= BN_bin2bn((const u_char
*)d
.ptr
, d
.len
, NULL
);
442 this->rsa
->p
= BN_bin2bn((const u_char
*)p
.ptr
, p
.len
, NULL
);
443 this->rsa
->q
= BN_bin2bn((const u_char
*)q
.ptr
, q
.len
, NULL
);
446 this->rsa
->dmp1
= BN_bin2bn((const u_char
*)exp1
.ptr
, exp1
.len
, NULL
);
450 this->rsa
->dmq1
= BN_bin2bn((const u_char
*)exp2
.ptr
, exp2
.len
, NULL
);
452 this->rsa
->iqmp
= BN_bin2bn((const u_char
*)coeff
.ptr
, coeff
.len
, NULL
);
453 if (RSA_check_key(this->rsa
))
455 return &this->public;
462 #ifndef OPENSSL_NO_ENGINE
464 * Login to engine with a PIN specified for a keyid
466 static bool login(ENGINE
*engine
, chunk_t keyid
)
468 enumerator_t
*enumerator
;
469 shared_key_t
*shared
;
470 identification_t
*id
;
473 bool found
= FALSE
, success
= FALSE
;
475 id
= identification_create_from_encoding(ID_KEY_ID
, keyid
);
476 enumerator
= lib
->credmgr
->create_shared_enumerator(lib
->credmgr
,
477 SHARED_PIN
, id
, NULL
);
478 while (enumerator
->enumerate(enumerator
, &shared
, NULL
, NULL
))
481 key
= shared
->get_key(shared
);
482 if (snprintf(pin
, sizeof(pin
),
483 "%.*s", (int)key
.len
, key
.ptr
) >= sizeof(pin
))
487 if (ENGINE_ctrl_cmd_string(engine
, "PIN", pin
, 0))
494 DBG1(DBG_CFG
, "setting PIN on engine failed");
497 enumerator
->destroy(enumerator
);
501 DBG1(DBG_CFG
, "no PIN found for %#B", &keyid
);
505 #endif /* OPENSSL_NO_ENGINE */
510 openssl_rsa_private_key_t
*openssl_rsa_private_key_connect(key_type_t type
,
513 #ifndef OPENSSL_NO_ENGINE
514 private_openssl_rsa_private_key_t
*this;
515 char *engine_id
= NULL
;
517 chunk_t keyid
= chunk_empty
;;
524 switch (va_arg(args
, builder_part_t
))
526 case BUILD_PKCS11_KEYID
:
527 keyid
= va_arg(args
, chunk_t
);
529 case BUILD_PKCS11_SLOT
:
530 slot
= va_arg(args
, int);
532 case BUILD_PKCS11_MODULE
:
533 engine_id
= va_arg(args
, char*);
542 if (!keyid
.len
|| keyid
.len
> 40)
547 memset(keyname
, 0, sizeof(keyname
));
550 snprintf(keyname
, sizeof(keyname
), "%d:", slot
);
552 if (sizeof(keyname
) - strlen(keyname
) <= keyid
.len
* 4 / 3 + 1)
556 chunk_to_hex(keyid
, keyname
+ strlen(keyname
), FALSE
);
560 engine_id
= lib
->settings
->get_str(lib
->settings
,
561 "libstrongswan.plugins.openssl.engine_id", "pkcs11");
563 engine
= ENGINE_by_id(engine_id
);
566 DBG2(DBG_LIB
, "engine '%s' is not available", engine_id
);
569 if (!ENGINE_init(engine
))
571 DBG1(DBG_LIB
, "failed to initialize engine '%s'", engine_id
);
575 if (!login(engine
, keyid
))
577 DBG1(DBG_LIB
, "login to engine '%s' failed", engine_id
);
581 key
= ENGINE_load_private_key(engine
, keyname
, NULL
, NULL
);
584 DBG1(DBG_LIB
, "failed to load private key with ID '%s' from "
585 "engine '%s'", keyname
, engine_id
);
591 this = create_empty();
592 this->rsa
= EVP_PKEY_get1_RSA(key
);
600 return &this->public;
601 #else /* OPENSSL_NO_ENGINE */
603 #endif /* OPENSSL_NO_ENGINE */
606 #endif /* OPENSSL_NO_RSA */