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_rsa_private_key.h"
18 #include "openssl_rsa_public_key.h"
22 #include <openssl/evp.h>
23 #include <openssl/rsa.h>
24 #include <openssl/engine.h>
27 * Public exponent to use for key generation.
29 #define PUBLIC_EXPONENT 0x10001
31 typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t
;
34 * Private data of a openssl_rsa_private_key_t object.
36 struct private_openssl_rsa_private_key_t
{
38 * Public interface for this signer.
40 openssl_rsa_private_key_t
public;
43 * RSA object from OpenSSL
48 * TRUE if the key is from an OpenSSL ENGINE and might not be readable
59 * Build an EMPSA PKCS1 signature described in PKCS#1
61 static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t
*this,
62 int type
, chunk_t data
, chunk_t
*sig
)
66 *sig
= chunk_alloc(RSA_size(this->rsa
));
68 if (type
== NID_undef
)
70 if (RSA_private_encrypt(data
.len
, data
.ptr
, sig
->ptr
, this->rsa
,
71 RSA_PKCS1_PADDING
) == sig
->len
)
83 hasher
= EVP_get_digestbynid(type
);
89 ctx
= EVP_MD_CTX_create();
95 if (!EVP_PKEY_set1_RSA(key
, this->rsa
))
99 if (!EVP_SignInit_ex(ctx
, hasher
, NULL
))
103 if (!EVP_SignUpdate(ctx
, data
.ptr
, data
.len
))
107 if (EVP_SignFinal(ctx
, sig
->ptr
, &len
, key
))
119 EVP_MD_CTX_destroy(ctx
);
130 * Implementation of openssl_rsa_private_key.get_type.
132 static key_type_t
get_type(private_openssl_rsa_private_key_t
*this)
138 * Implementation of openssl_rsa_private_key.sign.
140 static bool sign(private_openssl_rsa_private_key_t
*this, signature_scheme_t scheme
,
141 chunk_t data
, chunk_t
*signature
)
145 case SIGN_RSA_EMSA_PKCS1_NULL
:
146 return build_emsa_pkcs1_signature(this, NID_undef
, data
, signature
);
147 case SIGN_RSA_EMSA_PKCS1_SHA1
:
148 return build_emsa_pkcs1_signature(this, NID_sha1
, data
, signature
);
149 case SIGN_RSA_EMSA_PKCS1_SHA224
:
150 return build_emsa_pkcs1_signature(this, NID_sha224
, data
, signature
);
151 case SIGN_RSA_EMSA_PKCS1_SHA256
:
152 return build_emsa_pkcs1_signature(this, NID_sha256
, data
, signature
);
153 case SIGN_RSA_EMSA_PKCS1_SHA384
:
154 return build_emsa_pkcs1_signature(this, NID_sha384
, data
, signature
);
155 case SIGN_RSA_EMSA_PKCS1_SHA512
:
156 return build_emsa_pkcs1_signature(this, NID_sha512
, data
, signature
);
157 case SIGN_RSA_EMSA_PKCS1_MD5
:
158 return build_emsa_pkcs1_signature(this, NID_md5
, data
, signature
);
160 DBG1("signature scheme %N not supported in RSA",
161 signature_scheme_names
, scheme
);
167 * Implementation of openssl_rsa_private_key.decrypt.
169 static bool decrypt(private_openssl_rsa_private_key_t
*this,
170 chunk_t crypto
, chunk_t
*plain
)
172 DBG1("RSA private key decryption not implemented");
177 * Implementation of openssl_rsa_private_key.get_keysize.
179 static size_t get_keysize(private_openssl_rsa_private_key_t
*this)
181 return RSA_size(this->rsa
);
185 * Implementation of openssl_rsa_private_key.get_public_key.
187 static public_key_t
* get_public_key(private_openssl_rsa_private_key_t
*this)
193 enc
= chunk_alloc(i2d_RSAPublicKey(this->rsa
, NULL
));
195 i2d_RSAPublicKey(this->rsa
, &p
);
196 key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
197 BUILD_BLOB_ASN1_DER
, enc
, BUILD_END
);
203 * Implementation of public_key_t.get_fingerprint.
205 static bool get_fingerprint(private_openssl_rsa_private_key_t
*this,
206 key_encoding_type_t type
, chunk_t
*fingerprint
)
212 if (lib
->encoding
->get_cache(lib
->encoding
, type
, this, fingerprint
))
216 enc
= chunk_alloc(i2d_RSAPublicKey(this->rsa
, NULL
));
218 i2d_RSAPublicKey(this->rsa
, &p
);
219 success
= lib
->encoding
->encode(lib
->encoding
, type
, this, fingerprint
,
220 KEY_PART_RSA_PUB_ASN1_DER
, enc
, KEY_PART_END
);
226 * Implementation of public_key_t.get_encoding.
228 static bool get_encoding(private_openssl_rsa_private_key_t
*this,
229 key_encoding_type_t type
, chunk_t
*encoding
)
239 enc
= chunk_alloc(i2d_RSAPrivateKey(this->rsa
, NULL
));
241 i2d_RSAPrivateKey(this->rsa
, &p
);
242 success
= lib
->encoding
->encode(lib
->encoding
, type
, NULL
, encoding
,
243 KEY_PART_RSA_PUB_ASN1_DER
, enc
, KEY_PART_END
);
249 * Implementation of openssl_rsa_private_key.get_ref.
251 static private_openssl_rsa_private_key_t
* get_ref(private_openssl_rsa_private_key_t
*this)
258 * Implementation of openssl_rsa_private_key.destroy.
260 static void destroy(private_openssl_rsa_private_key_t
*this)
262 if (ref_put(&this->ref
))
268 lib
->encoding
->clear_cache(lib
->encoding
, this);
274 * Internal generic constructor
276 static private_openssl_rsa_private_key_t
*create_empty(void)
278 private_openssl_rsa_private_key_t
*this = malloc_thing(private_openssl_rsa_private_key_t
);
280 this->public.interface
.get_type
= (key_type_t (*) (private_key_t
*))get_type
;
281 this->public.interface
.sign
= (bool (*) (private_key_t
*, signature_scheme_t
, chunk_t
, chunk_t
*))sign
;
282 this->public.interface
.decrypt
= (bool (*) (private_key_t
*, chunk_t
, chunk_t
*))decrypt
;
283 this->public.interface
.get_keysize
= (size_t (*) (private_key_t
*))get_keysize
;
284 this->public.interface
.get_public_key
= (public_key_t
* (*) (private_key_t
*))get_public_key
;
285 this->public.interface
.equals
= private_key_equals
;
286 this->public.interface
.belongs_to
= private_key_belongs_to
;
287 this->public.interface
.get_fingerprint
= (bool(*)(private_key_t
*, key_encoding_type_t type
, chunk_t
*fp
))get_fingerprint
;
288 this->public.interface
.get_encoding
= (bool(*)(private_key_t
*, key_encoding_type_t type
, chunk_t
*encoding
))get_encoding
;
289 this->public.interface
.get_ref
= (private_key_t
* (*) (private_key_t
*))get_ref
;
290 this->public.interface
.destroy
= (void (*) (private_key_t
*))destroy
;
292 this->engine
= FALSE
;
299 * Generate an RSA key of specified key size
301 static openssl_rsa_private_key_t
*generate(size_t key_size
)
303 private_openssl_rsa_private_key_t
*this = create_empty();
305 this->rsa
= RSA_generate_key(key_size
, PUBLIC_EXPONENT
, NULL
, NULL
);
307 return &this->public;
311 * load private key from an ASN1 encoded blob
313 static openssl_rsa_private_key_t
*load(chunk_t blob
)
315 u_char
*p
= blob
.ptr
;
316 private_openssl_rsa_private_key_t
*this = create_empty();
318 this->rsa
= d2i_RSAPrivateKey(NULL
, (const u_char
**)&p
, blob
.len
);
324 if (!RSA_check_key(this->rsa
))
329 return &this->public;
333 * load private key from a smart card
335 static openssl_rsa_private_key_t
*load_from_smartcard(char *keyid
, char *pin
)
337 private_openssl_rsa_private_key_t
*this = NULL
;
339 char *engine_id
= lib
->settings
->get_str(lib
->settings
,
340 "library.plugins.openssl.engine_id", "pkcs11");
342 ENGINE
*engine
= ENGINE_by_id(engine_id
);
345 DBG1("engine '%s' is not available", engine_id
);
349 if (!ENGINE_init(engine
))
351 DBG1("failed to initialize engine '%s'", engine_id
);
355 if (!ENGINE_ctrl_cmd_string(engine
, "PIN", pin
, 0))
357 DBG1("failed to set PIN on engine '%s'", engine_id
);
361 key
= ENGINE_load_private_key(engine
, keyid
, NULL
, NULL
);
365 DBG1("failed to load private key with ID '%s' from engine '%s'", keyid
,
371 this = create_empty();
372 this->rsa
= EVP_PKEY_get1_RSA(key
);
375 return &this->public;
382 typedef struct private_builder_t private_builder_t
;
385 * Builder implementation for key loading/generation
387 struct private_builder_t
{
388 /** implements the builder interface */
390 /** loaded/generated private key */
391 openssl_rsa_private_key_t
*key
;
392 /** temporary stored smartcard key ID */
394 /** temporary stored smartcard pin */
399 * Implementation of builder_t.build
401 static openssl_rsa_private_key_t
*build(private_builder_t
*this)
403 openssl_rsa_private_key_t
*key
= this->key
;
405 if (this->keyid
&& this->pin
)
407 key
= load_from_smartcard(this->keyid
, this->pin
);
414 * Implementation of builder_t.add
416 static void add(private_builder_t
*this, builder_part_t part
, ...)
424 case BUILD_BLOB_ASN1_DER
:
426 va_start(args
, part
);
427 this->key
= load(va_arg(args
, chunk_t
));
433 va_start(args
, part
);
434 this->key
= generate(va_arg(args
, u_int
));
438 case BUILD_SMARTCARD_KEYID
:
440 va_start(args
, part
);
441 this->keyid
= va_arg(args
, char*);
445 case BUILD_SMARTCARD_PIN
:
447 va_start(args
, part
);
448 this->pin
= va_arg(args
, char*);
458 destroy((private_openssl_rsa_private_key_t
*)this->key
);
460 builder_cancel(&this->public);
464 * Builder construction function
466 builder_t
*openssl_rsa_private_key_builder(key_type_t type
)
468 private_builder_t
*this;
475 this = malloc_thing(private_builder_t
);
478 this->public.add
= (void(*)(builder_t
*this, builder_part_t part
, ...))add
;
479 this->public.build
= (void*(*)(builder_t
*this))build
;
483 return &this->public;