Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2008-2017 Tobias Brunner
3: * Copyright (C) 2009 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
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>.
10: *
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
14: * for more details.
15: */
16:
17: #include <openssl/opensslconf.h>
18:
19: #ifndef OPENSSL_NO_RSA
20:
21: #include "openssl_rsa_public_key.h"
22: #include "openssl_hasher.h"
23: #include "openssl_util.h"
24:
25: #include <utils/debug.h>
26: #include <credentials/keys/signature_params.h>
27:
28: #include <openssl/bn.h>
29: #include <openssl/evp.h>
30: #include <openssl/rsa.h>
31: #include <openssl/x509.h>
32:
33: #if OPENSSL_VERSION_NUMBER < 0x10100000L
34: OPENSSL_KEY_FALLBACK(RSA, key, n, e, d)
35: #endif
36:
37: typedef struct private_openssl_rsa_public_key_t private_openssl_rsa_public_key_t;
38:
39: /**
40: * Private data structure with signing context.
41: */
42: struct private_openssl_rsa_public_key_t {
43: /**
44: * Public interface for this signer.
45: */
46: openssl_rsa_public_key_t public;
47:
48: /**
49: * RSA object from OpenSSL
50: */
51: RSA *rsa;
52:
53: /**
54: * reference counter
55: */
56: refcount_t ref;
57: };
58:
59:
60: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
61:
62: /**
63: * Verify RSA signature
64: */
65: static bool verify_signature(private_openssl_rsa_public_key_t *this,
66: const EVP_MD *md, rsa_pss_params_t *pss,
67: chunk_t data, chunk_t signature)
68: {
69: EVP_PKEY_CTX *pctx = NULL;
70: EVP_MD_CTX *mctx = NULL;
71: EVP_PKEY *key;
72: int rsa_size = RSA_size(this->rsa);
73: bool valid = FALSE;
74:
75: /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */
76: if (signature.len > rsa_size)
77: {
78: signature = chunk_skip(signature, signature.len - rsa_size);
79: }
80:
81: mctx = EVP_MD_CTX_create();
82: key = EVP_PKEY_new();
83: if (!mctx || !key)
84: {
85: goto error;
86: }
87: if (!EVP_PKEY_set1_RSA(key, this->rsa))
88: {
89: goto error;
90: }
91: if (EVP_DigestVerifyInit(mctx, &pctx, md, NULL, key) <= 0)
92: {
93: goto error;
94: }
95: if (pss)
96: {
97: const EVP_MD *mgf1md = openssl_get_md(pss->mgf1_hash);
98: if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
99: EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, pss->salt_len) <= 0 ||
100: EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md) <= 0)
101: {
102: goto error;
103: }
104: }
105: if (EVP_DigestVerifyUpdate(mctx, data.ptr, data.len) <= 0)
106: {
107: goto error;
108: }
109: valid = (EVP_DigestVerifyFinal(mctx, signature.ptr, signature.len) == 1);
110:
111: error:
112: if (key)
113: {
114: EVP_PKEY_free(key);
115: }
116: if (mctx)
117: {
118: EVP_MD_CTX_destroy(mctx);
119: }
120: return valid;
121: }
122:
123: /**
124: * Verification of a signature without hashing
125: */
126: static bool verify_plain_signature(private_openssl_rsa_public_key_t *this,
127: chunk_t data, chunk_t signature)
128: {
129: char *buf;
130: int len, rsa_size = RSA_size(this->rsa);
131: bool valid = FALSE;
132:
133: /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */
134: if (signature.len > rsa_size)
135: {
136: signature = chunk_skip(signature, signature.len - rsa_size);
137: }
138: buf = malloc(rsa_size);
139: len = RSA_public_decrypt(signature.len, signature.ptr, buf, this->rsa,
140: RSA_PKCS1_PADDING);
141: if (len != -1)
142: {
143: valid = chunk_equals_const(data, chunk_create(buf, len));
144: }
145: free(buf);
146: return valid;
147: }
148:
149: /**
150: * Verification of an EMSA PKCS1 signature described in PKCS#1
151: */
152: static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
153: int type, chunk_t data, chunk_t signature)
154: {
155: const EVP_MD *md;
156:
157: if (type == NID_undef)
158: {
159: return verify_plain_signature(this, data, signature);
160: }
161: md = EVP_get_digestbynid(type);
162: return md && verify_signature(this, md, NULL, data, signature);
163: }
164:
165: /**
166: * Verification of an EMSA PSS signature described in PKCS#1
167: */
168: static bool verify_emsa_pss_signature(private_openssl_rsa_public_key_t *this,
169: rsa_pss_params_t *params, chunk_t data,
170: chunk_t signature)
171: {
172: const EVP_MD *md;
173:
174: if (!params)
175: {
176: return FALSE;
177: }
178: md = openssl_get_md(params->hash);
179: return md && verify_signature(this, md, params, data, signature);
180: }
181:
182: #else /* OPENSSL_VERSION_NUMBER < 1.0 */
183:
184: /**
185: * Verification of an EMSA PKCS1 signature described in PKCS#1
186: */
187: static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
188: int type, chunk_t data, chunk_t signature)
189: {
190: bool valid = FALSE;
191: int rsa_size = RSA_size(this->rsa);
192:
193: /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */
194: if (signature.len > rsa_size)
195: {
196: signature = chunk_skip(signature, signature.len - rsa_size);
197: }
198:
199: if (type == NID_undef)
200: {
201: char *buf;
202: int len;
203:
204: buf = malloc(rsa_size);
205: len = RSA_public_decrypt(signature.len, signature.ptr, buf, this->rsa,
206: RSA_PKCS1_PADDING);
207: if (len != -1)
208: {
209: valid = chunk_equals_const(data, chunk_create(buf, len));
210: }
211: free(buf);
212: }
213: else
214: {
215: EVP_MD_CTX *ctx;
216: EVP_PKEY *key;
217: const EVP_MD *hasher;
218:
219: hasher = EVP_get_digestbynid(type);
220: if (!hasher)
221: {
222: return FALSE;
223: }
224:
225: ctx = EVP_MD_CTX_create();
226: key = EVP_PKEY_new();
227:
228: if (!ctx || !key)
229: {
230: goto error;
231: }
232: if (!EVP_PKEY_set1_RSA(key, this->rsa))
233: {
234: goto error;
235: }
236: if (!EVP_VerifyInit_ex(ctx, hasher, NULL))
237: {
238: goto error;
239: }
240: if (!EVP_VerifyUpdate(ctx, data.ptr, data.len))
241: {
242: goto error;
243: }
244: valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1);
245:
246: error:
247: if (key)
248: {
249: EVP_PKEY_free(key);
250: }
251: if (ctx)
252: {
253: EVP_MD_CTX_destroy(ctx);
254: }
255: }
256: return valid;
257: }
258:
259: #endif /* OPENSSL_VERSION_NUMBER < 1.0 */
260:
261: METHOD(public_key_t, get_type, key_type_t,
262: private_openssl_rsa_public_key_t *this)
263: {
264: return KEY_RSA;
265: }
266:
267: METHOD(public_key_t, verify, bool,
268: private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
269: void *params, chunk_t data, chunk_t signature)
270: {
271: switch (scheme)
272: {
273: case SIGN_RSA_EMSA_PKCS1_NULL:
274: return verify_emsa_pkcs1_signature(this, NID_undef, data, signature);
275: case SIGN_RSA_EMSA_PKCS1_SHA2_224:
276: return verify_emsa_pkcs1_signature(this, NID_sha224, data, signature);
277: case SIGN_RSA_EMSA_PKCS1_SHA2_256:
278: return verify_emsa_pkcs1_signature(this, NID_sha256, data, signature);
279: case SIGN_RSA_EMSA_PKCS1_SHA2_384:
280: return verify_emsa_pkcs1_signature(this, NID_sha384, data, signature);
281: case SIGN_RSA_EMSA_PKCS1_SHA2_512:
282: return verify_emsa_pkcs1_signature(this, NID_sha512, data, signature);
283: case SIGN_RSA_EMSA_PKCS1_SHA1:
284: return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
285: case SIGN_RSA_EMSA_PKCS1_MD5:
286: return verify_emsa_pkcs1_signature(this, NID_md5, data, signature);
287: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
288: case SIGN_RSA_EMSA_PSS:
289: return verify_emsa_pss_signature(this, params, data, signature);
290: #endif
291: default:
292: DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
293: signature_scheme_names, scheme);
294: return FALSE;
295: }
296: }
297:
298: METHOD(public_key_t, encrypt, bool,
299: private_openssl_rsa_public_key_t *this, encryption_scheme_t scheme,
300: chunk_t plain, chunk_t *crypto)
301: {
302: int padding, len;
303: char *encrypted;
304:
305: switch (scheme)
306: {
307: case ENCRYPT_RSA_PKCS1:
308: padding = RSA_PKCS1_PADDING;
309: break;
310: case ENCRYPT_RSA_OAEP_SHA1:
311: padding = RSA_PKCS1_OAEP_PADDING;
312: break;
313: default:
314: DBG1(DBG_LIB, "decryption scheme %N not supported via openssl",
315: encryption_scheme_names, scheme);
316: return FALSE;
317: }
318: encrypted = malloc(RSA_size(this->rsa));
319: len = RSA_public_encrypt(plain.len, plain.ptr, encrypted,
320: this->rsa, padding);
321: if (len < 0)
322: {
323: DBG1(DBG_LIB, "RSA decryption failed");
324: free(encrypted);
325: return FALSE;
326: }
327: *crypto = chunk_create(encrypted, len);
328: return TRUE;
329: }
330:
331: METHOD(public_key_t, get_keysize, int,
332: private_openssl_rsa_public_key_t *this)
333: {
334: return RSA_size(this->rsa) * 8;
335: }
336:
337: /**
338: * Calculate fingerprint from a RSA key, also used in rsa private key.
339: */
340: bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp)
341: {
342: hasher_t *hasher;
343: chunk_t key;
344: u_char *p;
345:
346: if (lib->encoding->get_cache(lib->encoding, type, rsa, fp))
347: {
348: return TRUE;
349: }
350: switch (type)
351: {
352: case KEYID_PUBKEY_SHA1:
353: key = chunk_alloc(i2d_RSAPublicKey(rsa, NULL));
354: p = key.ptr;
355: i2d_RSAPublicKey(rsa, &p);
356: break;
357: case KEYID_PUBKEY_INFO_SHA1:
358: key = chunk_alloc(i2d_RSA_PUBKEY(rsa, NULL));
359: p = key.ptr;
360: i2d_RSA_PUBKEY(rsa, &p);
361: break;
362: default:
363: {
364: const BIGNUM *bn_n, *bn_e;
365: chunk_t n = chunk_empty, e = chunk_empty;
366: bool success = FALSE;
367:
368: RSA_get0_key(rsa, &bn_n, &bn_e, NULL);
369: if (openssl_bn2chunk(bn_n, &n) &&
370: openssl_bn2chunk(bn_e, &e))
371: {
372: success = lib->encoding->encode(lib->encoding, type, rsa, fp,
373: CRED_PART_RSA_MODULUS, n,
374: CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
375: }
376: chunk_free(&n);
377: chunk_free(&e);
378: return success;
379: }
380: }
381: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
382: if (!hasher || !hasher->allocate_hash(hasher, key, fp))
383: {
384: DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed");
385: DESTROY_IF(hasher);
386: free(key.ptr);
387: return FALSE;
388: }
389: free(key.ptr);
390: hasher->destroy(hasher);
391: lib->encoding->cache(lib->encoding, type, rsa, *fp);
392: return TRUE;
393: }
394:
395: METHOD(public_key_t, get_fingerprint, bool,
396: private_openssl_rsa_public_key_t *this, cred_encoding_type_t type,
397: chunk_t *fingerprint)
398: {
399: return openssl_rsa_fingerprint(this->rsa, type, fingerprint);
400: }
401:
402: METHOD(public_key_t, get_encoding, bool,
403: private_openssl_rsa_public_key_t *this, cred_encoding_type_t type,
404: chunk_t *encoding)
405: {
406: bool success = FALSE;
407: u_char *p;
408:
409: switch (type)
410: {
411: case PUBKEY_SPKI_ASN1_DER:
412: case PUBKEY_PEM:
413: {
414: *encoding = chunk_alloc(i2d_RSA_PUBKEY(this->rsa, NULL));
415: p = encoding->ptr;
416: i2d_RSA_PUBKEY(this->rsa, &p);
417: success = TRUE;
418:
419: if (type == PUBKEY_PEM)
420: {
421: chunk_t asn1_encoding = *encoding;
422:
423: success = lib->encoding->encode(lib->encoding, PUBKEY_PEM,
424: NULL, encoding, CRED_PART_RSA_PUB_ASN1_DER,
425: asn1_encoding, CRED_PART_END);
426: chunk_clear(&asn1_encoding);
427: }
428: return success;
429: }
430: case PUBKEY_ASN1_DER:
431: {
432: *encoding = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL));
433: p = encoding->ptr;
434: i2d_RSAPublicKey(this->rsa, &p);
435: return TRUE;
436: }
437: default:
438: {
439: const BIGNUM *bn_n, *bn_e;
440: chunk_t n = chunk_empty, e = chunk_empty;
441:
442: RSA_get0_key(this->rsa, &bn_n, &bn_e, NULL);
443: if (openssl_bn2chunk(bn_n, &n) &&
444: openssl_bn2chunk(bn_e, &e))
445: {
446: success = lib->encoding->encode(lib->encoding, type, NULL,
447: encoding, CRED_PART_RSA_MODULUS, n,
448: CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
449: }
450: chunk_free(&n);
451: chunk_free(&e);
452: return success;
453: }
454: }
455: }
456:
457: METHOD(public_key_t, get_ref, public_key_t*,
458: private_openssl_rsa_public_key_t *this)
459: {
460: ref_get(&this->ref);
461: return &this->public.key;
462: }
463:
464: METHOD(public_key_t, destroy, void,
465: private_openssl_rsa_public_key_t *this)
466: {
467: if (ref_put(&this->ref))
468: {
469: if (this->rsa)
470: {
471: lib->encoding->clear_cache(lib->encoding, this->rsa);
472: RSA_free(this->rsa);
473: }
474: free(this);
475: }
476: }
477:
478: /**
479: * Generic private constructor
480: */
481: static private_openssl_rsa_public_key_t *create_empty()
482: {
483: private_openssl_rsa_public_key_t *this;
484:
485: INIT(this,
486: .public = {
487: .key = {
488: .get_type = _get_type,
489: .verify = _verify,
490: .encrypt = _encrypt,
491: .equals = public_key_equals,
492: .get_keysize = _get_keysize,
493: .get_fingerprint = _get_fingerprint,
494: .has_fingerprint = public_key_has_fingerprint,
495: .get_encoding = _get_encoding,
496: .get_ref = _get_ref,
497: .destroy = _destroy,
498: },
499: },
500: .ref = 1,
501: );
502:
503: return this;
504: }
505:
506: /**
507: * See header.
508: */
509: openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type,
510: va_list args)
511: {
512: private_openssl_rsa_public_key_t *this;
513: chunk_t blob, n, e;
514:
515: n = e = blob = chunk_empty;
516: while (TRUE)
517: {
518: switch (va_arg(args, builder_part_t))
519: {
520: case BUILD_BLOB_ASN1_DER:
521: blob = va_arg(args, chunk_t);
522: continue;
523: case BUILD_RSA_MODULUS:
524: n = va_arg(args, chunk_t);
525: continue;
526: case BUILD_RSA_PUB_EXP:
527: e = va_arg(args, chunk_t);
528: continue;
529: case BUILD_END:
530: break;
531: default:
532: return NULL;
533: }
534: break;
535: }
536:
537: this = create_empty();
538: if (blob.ptr)
539: {
540: switch (type)
541: {
542: case KEY_ANY:
543: this->rsa = d2i_RSA_PUBKEY(NULL, (const u_char**)&blob.ptr,
544: blob.len);
545: break;
546: case KEY_RSA:
547: this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&blob.ptr,
548: blob.len);
549: break;
550: default:
551: break;
552: }
553: if (this->rsa)
554: {
555: return &this->public;
556: }
557: }
558: else if (n.ptr && e.ptr && type == KEY_RSA)
559: {
560: BIGNUM *bn_n, *bn_e;
561:
562: this->rsa = RSA_new();
563: bn_n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL);
564: bn_e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL);
565: if (RSA_set0_key(this->rsa, bn_n, bn_e, NULL))
566: {
567: return &this->public;
568: }
569: }
570: destroy(this);
571: return NULL;
572: }
573:
574: #endif /* OPENSSL_NO_RSA */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>