Return to botan_rsa_public_key.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / botan |
1.1 misho 1: /*
2: * Copyright (C) 2018 Tobias Brunner
3: * Copyright (C) 2018 Andreas Steffen
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * Copyright (C) 2018 René Korthaus
7: * Rohde & Schwarz Cybersecurity GmbH
8: *
9: * Permission is hereby granted, free of charge, to any person obtaining a copy
10: * of this software and associated documentation files (the "Software"), to deal
11: * in the Software without restriction, including without limitation the rights
12: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13: * copies of the Software, and to permit persons to whom the Software is
14: * furnished to do so, subject to the following conditions:
15: *
16: * The above copyright notice and this permission notice shall be included in
17: * all copies or substantial portions of the Software.
18: *
19: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25: * THE SOFTWARE.
26: */
27:
28: #include "botan_rsa_public_key.h"
29:
30: #include <botan/build.h>
31:
32: #ifdef BOTAN_HAS_RSA
33:
34: #include "botan_util.h"
35:
36: #include <asn1/oid.h>
37: #include <asn1/asn1.h>
38: #include <asn1/asn1_parser.h>
39:
40: #include <utils/debug.h>
41:
42: #include <botan/ffi.h>
43:
44: typedef struct private_botan_rsa_public_key_t private_botan_rsa_public_key_t;
45:
46: /**
47: * Private data structure with signing context.
48: */
49: struct private_botan_rsa_public_key_t {
50:
51: /**
52: * Public interface for this signer
53: */
54: botan_rsa_public_key_t public;
55:
56: /**
57: * Botan public key
58: */
59: botan_pubkey_t key;
60:
61: /**
62: * Reference counter
63: */
64: refcount_t ref;
65: };
66:
67: /**
68: * Defined in botan_rsa_private_key.c
69: */
70: bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len);
71:
72: /**
73: * Verification of an EMSA PSS signature described in PKCS#1
74: */
75: static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this,
76: rsa_pss_params_t *params, chunk_t data,
77: chunk_t signature)
78: {
79: char hash_and_padding[BUF_LEN];
80:
81: if (!botan_emsa_pss_identifier(params, hash_and_padding,
82: sizeof(hash_and_padding)))
83: {
84: return FALSE;
85: }
86: return botan_verify_signature(this->key, hash_and_padding, data, signature);
87: }
88:
89: METHOD(public_key_t, get_type, key_type_t,
90: private_botan_rsa_public_key_t *this)
91: {
92: return KEY_RSA;
93: }
94:
95: METHOD(public_key_t, verify, bool,
96: private_botan_rsa_public_key_t *this, signature_scheme_t scheme,
97: void *params, chunk_t data, chunk_t signature)
98: {
99: switch (scheme)
100: {
101: case SIGN_RSA_EMSA_PKCS1_NULL:
102: return botan_verify_signature(this->key, "EMSA_PKCS1(Raw)", data,
103: signature);
104: case SIGN_RSA_EMSA_PKCS1_SHA1:
105: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-1)", data,
106: signature);
107: case SIGN_RSA_EMSA_PKCS1_SHA2_224:
108: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-224)",
109: data, signature);
110: case SIGN_RSA_EMSA_PKCS1_SHA2_256:
111: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-256)",
112: data, signature);
113: case SIGN_RSA_EMSA_PKCS1_SHA2_384:
114: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-384)",
115: data, signature);
116: case SIGN_RSA_EMSA_PKCS1_SHA2_512:
117: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-512)",
118: data, signature);
119: case SIGN_RSA_EMSA_PKCS1_SHA3_224:
120: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(224)",
121: data, signature);
122: case SIGN_RSA_EMSA_PKCS1_SHA3_256:
123: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(256))",
124: data, signature);
125: case SIGN_RSA_EMSA_PKCS1_SHA3_384:
126: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(384))",
127: data, signature);
128: case SIGN_RSA_EMSA_PKCS1_SHA3_512:
129: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(512))",
130: data, signature);
131: case SIGN_RSA_EMSA_PSS:
132: return verify_emsa_pss_signature(this, params, data, signature);
133: default:
134: DBG1(DBG_LIB, "signature scheme %N not supported via botan",
135: signature_scheme_names, scheme);
136: return FALSE;
137: }
138: }
139:
140: METHOD(public_key_t, encrypt, bool,
141: private_botan_rsa_public_key_t *this, encryption_scheme_t scheme,
142: chunk_t plain, chunk_t *crypto)
143: {
144: botan_pk_op_encrypt_t encrypt_op;
145: botan_rng_t rng;
146: const char* padding;
147:
148: switch (scheme)
149: {
150: case ENCRYPT_RSA_PKCS1:
151: padding = "PKCS1v15";
152: break;
153: case ENCRYPT_RSA_OAEP_SHA1:
154: padding = "OAEP(SHA-1)";
155: break;
156: case ENCRYPT_RSA_OAEP_SHA224:
157: padding = "OAEP(SHA-224)";
158: break;
159: case ENCRYPT_RSA_OAEP_SHA256:
160: padding = "OAEP(SHA-256)";
161: break;
162: case ENCRYPT_RSA_OAEP_SHA384:
163: padding = "OAEP(SHA-384)";
164: break;
165: case ENCRYPT_RSA_OAEP_SHA512:
166: padding = "OAEP(SHA-512)";
167: break;
168: default:
169: DBG1(DBG_LIB, "encryption scheme %N not supported via botan",
170: encryption_scheme_names, scheme);
171: return FALSE;
172: }
173:
1.1.1.2 ! misho 174: if (!botan_get_rng(&rng, RNG_STRONG))
1.1 misho 175: {
176: return FALSE;
177: }
178:
179: if (botan_pk_op_encrypt_create(&encrypt_op, this->key, padding, 0))
180: {
181: botan_rng_destroy(rng);
182: return FALSE;
183: }
184:
185: crypto->len = 0;
186: if (botan_pk_op_encrypt_output_length(encrypt_op, plain.len, &crypto->len))
187: {
188: botan_rng_destroy(rng);
189: botan_pk_op_encrypt_destroy(encrypt_op);
190: return FALSE;
191: }
192:
193: *crypto = chunk_alloc(crypto->len);
194: if (botan_pk_op_encrypt(encrypt_op, rng, crypto->ptr, &crypto->len,
195: plain.ptr, plain.len))
196: {
197: chunk_free(crypto);
198: botan_rng_destroy(rng);
199: botan_pk_op_encrypt_destroy(encrypt_op);
200: return FALSE;
201: }
202: botan_rng_destroy(rng);
203: botan_pk_op_encrypt_destroy(encrypt_op);
204: return TRUE;
205: }
206:
207: METHOD(public_key_t, get_keysize, int,
208: private_botan_rsa_public_key_t *this)
209: {
210: botan_mp_t n;
211: size_t bits = 0;
212:
213: if (botan_mp_init(&n))
214: {
215: return 0;
216: }
217:
218: if (botan_pubkey_get_field(n, this->key, "n") ||
219: botan_mp_num_bits(n, &bits))
220: {
221: botan_mp_destroy(n);
222: return 0;
223: }
224:
225: botan_mp_destroy(n);
226: return bits;
227: }
228:
229: METHOD(public_key_t, get_fingerprint, bool,
230: private_botan_rsa_public_key_t *this, cred_encoding_type_t type,
231: chunk_t *fp)
232: {
233: return botan_get_fingerprint(this->key, this, type, fp);
234: }
235:
236: METHOD(public_key_t, get_encoding, bool,
237: private_botan_rsa_public_key_t *this, cred_encoding_type_t type,
238: chunk_t *encoding)
239: {
240: return botan_get_encoding(this->key, type, encoding);
241: }
242:
243: METHOD(public_key_t, get_ref, public_key_t*,
244: private_botan_rsa_public_key_t *this)
245: {
246: ref_get(&this->ref);
247: return &this->public.key;
248: }
249:
250: METHOD(public_key_t, destroy, void,
251: private_botan_rsa_public_key_t *this)
252: {
253: if (ref_put(&this->ref))
254: {
255: lib->encoding->clear_cache(lib->encoding, this);
256: botan_pubkey_destroy(this->key);
257: free(this);
258: }
259: }
260:
261: /**
262: * Internal generic constructor
263: */
264: static private_botan_rsa_public_key_t *create_empty()
265: {
266: private_botan_rsa_public_key_t *this;
267:
268: INIT(this,
269: .public = {
270: .key = {
271: .get_type = _get_type,
272: .verify = _verify,
273: .encrypt = _encrypt,
274: .equals = public_key_equals,
275: .get_keysize = _get_keysize,
276: .get_fingerprint = _get_fingerprint,
277: .has_fingerprint = public_key_has_fingerprint,
278: .get_encoding = _get_encoding,
279: .get_ref = _get_ref,
280: .destroy = _destroy,
281: },
282: },
283: .ref = 1,
284: );
285:
286: return this;
287: }
288:
289: /*
290: * Described in header
291: */
292: botan_rsa_public_key_t *botan_rsa_public_key_adopt(botan_pubkey_t key)
293: {
294: private_botan_rsa_public_key_t *this;
295:
296: this = create_empty();
297: this->key = key;
298:
299: return &this->public;
300: }
301:
302: /*
303: * Described in header
304: */
305: botan_rsa_public_key_t *botan_rsa_public_key_load(key_type_t type,
306: va_list args)
307: {
308: private_botan_rsa_public_key_t *this = NULL;
309: chunk_t n, e;
310:
311: n = e = chunk_empty;
312: while (TRUE)
313: {
314: switch (va_arg(args, builder_part_t))
315: {
316: case BUILD_RSA_MODULUS:
317: n = va_arg(args, chunk_t);
318: continue;
319: case BUILD_RSA_PUB_EXP:
320: e = va_arg(args, chunk_t);
321: continue;
322: case BUILD_END:
323: break;
324: default:
325: return NULL;
326: }
327: break;
328: }
329:
330: if (n.ptr && e.ptr && type == KEY_RSA)
331: {
332: botan_mp_t mp_n, mp_e;
333:
334: if (!chunk_to_botan_mp(n, &mp_n))
335: {
336: return NULL;
337: }
338:
339: if (!chunk_to_botan_mp(e, &mp_e))
340: {
341: botan_mp_destroy(mp_n);
342: return NULL;
343: }
344:
345: this = create_empty();
346:
347: if (botan_pubkey_load_rsa(&this->key, mp_n, mp_e))
348: {
349: botan_mp_destroy(mp_n);
350: botan_mp_destroy(mp_e);
351: free(this);
352: return NULL;
353: }
354:
355: botan_mp_destroy(mp_n);
356: botan_mp_destroy(mp_e);
357: }
358:
359: return &this->public;
360: }
361:
362: #endif