205220a3f061053347f406fe16b37eb759ebfa51
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_rsa_private_key.c
1 /*
2 * Copyright (C) 2008 Tobias Brunner
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 * $Id$
16 */
17
18 #include "openssl_rsa_private_key.h"
19 #include "openssl_rsa_public_key.h"
20
21 #include <debug.h>
22
23 #include <openssl/evp.h>
24 #include <openssl/rsa.h>
25
26 /**
27 * Public exponent to use for key generation.
28 */
29 #define PUBLIC_EXPONENT 0x10001
30
31 typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t;
32
33 /**
34 * Private data of a openssl_rsa_private_key_t object.
35 */
36 struct private_openssl_rsa_private_key_t {
37 /**
38 * Public interface for this signer.
39 */
40 openssl_rsa_private_key_t public;
41
42 /**
43 * RSA object from OpenSSL
44 */
45 RSA *rsa;
46
47 /**
48 * Keyid formed as a SHA-1 hash of a privateKey object
49 */
50 identification_t* keyid;
51
52 /**
53 * Keyid formed as a SHA-1 hash of a privateKeyInfo object
54 */
55 identification_t* keyid_info;
56
57 /**
58 * reference count
59 */
60 refcount_t ref;
61 };
62
63 /**
64 * shared functions, implemented in openssl_rsa_public_key.c
65 */
66 bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
67 identification_t **keyid_info);
68
69
70 openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e);
71
72
73 /**
74 * Build an EMPSA PKCS1 signature described in PKCS#1
75 */
76 static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
77 int type, chunk_t data, chunk_t *signature)
78 {
79 bool success = FALSE;
80 u_int len;
81 const EVP_MD *hasher = EVP_get_digestbynid(type);
82 if (!hasher)
83 {
84 return FALSE;
85 }
86
87 EVP_MD_CTX *ctx = EVP_MD_CTX_create();
88 EVP_PKEY *key = EVP_PKEY_new();
89 if (!ctx || !key)
90 {
91 goto error;
92 }
93
94 if (!EVP_PKEY_set1_RSA(key, this->rsa))
95 {
96 goto error;
97 }
98
99 if (!EVP_SignInit_ex(ctx, hasher, NULL))
100 {
101 goto error;
102 }
103
104 if (!EVP_SignUpdate(ctx, data.ptr, data.len))
105 {
106 goto error;
107 }
108
109 *signature = chunk_alloc(RSA_size(this->rsa));
110
111 if (!EVP_SignFinal(ctx, signature->ptr, &len, key))
112 {
113 goto error;
114 }
115 signature->len = len;
116
117 success = TRUE;
118
119 error:
120 if (key)
121 {
122 EVP_PKEY_free(key);
123 }
124 if (ctx)
125 {
126 EVP_MD_CTX_destroy(ctx);
127 }
128 return success;
129 }
130
131 /**
132 * Implementation of openssl_rsa_private_key.destroy.
133 */
134 static key_type_t get_type(private_openssl_rsa_private_key_t *this)
135 {
136 return KEY_RSA;
137 }
138
139 /**
140 * Implementation of openssl_rsa_private_key.destroy.
141 */
142 static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
143 chunk_t data, chunk_t *signature)
144 {
145 switch (scheme)
146 {
147 case SIGN_DEFAULT:
148 /* default is EMSA-PKCS1 using SHA1 */
149 case SIGN_RSA_EMSA_PKCS1_SHA1:
150 return build_emsa_pkcs1_signature(this, NID_sha1, 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);
159 default:
160 DBG1("signature scheme %N not supported in RSA",
161 signature_scheme_names, scheme);
162 return FALSE;
163 }
164 }
165
166 /**
167 * Implementation of openssl_rsa_private_key.destroy.
168 */
169 static bool decrypt(private_openssl_rsa_private_key_t *this,
170 chunk_t crypto, chunk_t *plain)
171 {
172 DBG1("RSA private key decryption not implemented");
173 return FALSE;
174 }
175
176 /**
177 * Implementation of openssl_rsa_private_key.destroy.
178 */
179 static size_t get_keysize(private_openssl_rsa_private_key_t *this)
180 {
181 return RSA_size(this->rsa);
182 }
183
184 /**
185 * Implementation of openssl_rsa_private_key.destroy.
186 */
187 static identification_t* get_id(private_openssl_rsa_private_key_t *this,
188 id_type_t type)
189 {
190 switch (type)
191 {
192 case ID_PUBKEY_INFO_SHA1:
193 return this->keyid_info;
194 case ID_PUBKEY_SHA1:
195 return this->keyid;
196 default:
197 return NULL;
198 }
199 }
200
201 /**
202 * Implementation of openssl_rsa_private_key.destroy.
203 */
204 static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
205 {
206 return openssl_rsa_public_key_create_from_n_e(this->rsa->n, this->rsa->e);
207 }
208
209 /**
210 * Implementation of openssl_rsa_private_key.destroy.
211 */
212 static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public)
213 {
214 identification_t *keyid;
215
216 if (public->get_type(public) != KEY_RSA)
217 {
218 return FALSE;
219 }
220 keyid = public->get_id(public, ID_PUBKEY_SHA1);
221 if (keyid && keyid->equals(keyid, this->keyid))
222 {
223 return TRUE;
224 }
225 keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
226 if (keyid && keyid->equals(keyid, this->keyid_info))
227 {
228 return TRUE;
229 }
230 return FALSE;
231 }
232
233 /**
234 * Implementation of private_key_t.get_encoding.
235 */
236 static chunk_t get_encoding(private_openssl_rsa_private_key_t *this)
237 {
238 chunk_t enc = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL));
239 u_char *p = enc.ptr;
240 i2d_RSAPrivateKey(this->rsa, &p);
241 return enc;
242 }
243
244 /**
245 * Implementation of openssl_rsa_private_key.destroy.
246 */
247 static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_key_t *this)
248 {
249 ref_get(&this->ref);
250 return this;
251
252 }
253
254 /**
255 * Implementation of openssl_rsa_private_key.destroy.
256 */
257 static void destroy(private_openssl_rsa_private_key_t *this)
258 {
259 if (ref_put(&this->ref))
260 {
261 if (this->rsa)
262 {
263 RSA_free(this->rsa);
264 }
265 DESTROY_IF(this->keyid);
266 DESTROY_IF(this->keyid_info);
267 free(this);
268 }
269 }
270
271 /**
272 * Internal generic constructor
273 */
274 static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(void)
275 {
276 private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t);
277
278 this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
279 this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
280 this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
281 this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
282 this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
283 this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
284 this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
285 this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
286 this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
287 this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
288
289 this->keyid = NULL;
290 this->keyid_info = NULL;
291 this->ref = 1;
292
293 return this;
294 }
295
296 /**
297 * Generate an RSA key of specified key size
298 */
299 static openssl_rsa_private_key_t *generate(size_t key_size)
300 {
301 private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
302
303 this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL);
304
305 if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
306 {
307 destroy(this);
308 return NULL;
309 }
310
311 return &this->public;
312 }
313
314 /**
315 * load private key from an ASN1 encoded blob
316 */
317 static openssl_rsa_private_key_t *load(chunk_t blob)
318 {
319 u_char *p = blob.ptr;
320 private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
321
322 this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&p, blob.len);
323
324 chunk_clear(&blob);
325
326 if (!this->rsa)
327 {
328 destroy(this);
329 return NULL;
330 }
331
332 if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
333 {
334 destroy(this);
335 return NULL;
336 }
337
338 if (!RSA_check_key(this->rsa))
339 {
340 destroy(this);
341 return NULL;
342 }
343
344 return &this->public;
345 }
346
347 typedef struct private_builder_t private_builder_t;
348 /**
349 * Builder implementation for key loading/generation
350 */
351 struct private_builder_t {
352 /** implements the builder interface */
353 builder_t public;
354 /** loaded/generated private key */
355 openssl_rsa_private_key_t *key;
356 };
357
358 /**
359 * Implementation of builder_t.build
360 */
361 static openssl_rsa_private_key_t *build(private_builder_t *this)
362 {
363 openssl_rsa_private_key_t *key = this->key;
364
365 free(this);
366 return key;
367 }
368
369 /**
370 * Implementation of builder_t.add
371 */
372 static void add(private_builder_t *this, builder_part_t part, ...)
373 {
374 if (!this->key)
375 {
376 va_list args;
377 chunk_t chunk;
378
379 switch (part)
380 {
381 case BUILD_BLOB_ASN1_DER:
382 {
383 va_start(args, part);
384 chunk = va_arg(args, chunk_t);
385 this->key = load(chunk_clone(chunk));
386 va_end(args);
387 return;
388 }
389 case BUILD_KEY_SIZE:
390 {
391 va_start(args, part);
392 this->key = generate(va_arg(args, u_int));
393 va_end(args);
394 return;
395 }
396 default:
397 break;
398 }
399 }
400 if (this->key)
401 {
402 destroy((private_openssl_rsa_private_key_t*)this->key);
403 }
404 builder_cancel(&this->public);
405 }
406
407 /**
408 * Builder construction function
409 */
410 builder_t *openssl_rsa_private_key_builder(key_type_t type)
411 {
412 private_builder_t *this;
413
414 if (type != KEY_RSA)
415 {
416 return NULL;
417 }
418
419 this = malloc_thing(private_builder_t);
420
421 this->key = NULL;
422 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
423 this->public.build = (void*(*)(builder_t *this))build;
424
425 return &this->public;
426 }
427