]> git.ipfire.org Git - people/ms/strongswan.git/blob - src/libstrongswan/plugins/botan/botan_rsa_public_key.c
credentials: Added void *params to public_key encrypt() and private_key decrypt(...
[people/ms/strongswan.git] / src / libstrongswan / plugins / botan / botan_rsa_public_key.c
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 void *params, 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
174 if (!botan_get_rng(&rng, RNG_STRONG))
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