2 * Copyright (C) 2018 Tobias Brunner
3 * Copyright (C) 2018 Andreas Steffen
4 * HSR Hochschule fuer Technik Rapperswil
6 * Copyright (C) 2018 René Korthaus
7 * Rohde & Schwarz Cybersecurity GmbH
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:
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
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
28 #include "botan_rsa_public_key.h"
30 #include <botan/build.h>
34 #include "botan_util.h"
37 #include <asn1/asn1.h>
38 #include <asn1/asn1_parser.h>
40 #include <utils/debug.h>
42 #include <botan/ffi.h>
44 typedef struct private_botan_rsa_public_key_t private_botan_rsa_public_key_t
;
47 * Private data structure with signing context.
49 struct private_botan_rsa_public_key_t
{
52 * Public interface for this signer
54 botan_rsa_public_key_t
public;
68 * Defined in botan_rsa_private_key.c
70 bool botan_emsa_pss_identifier(rsa_pss_params_t
*params
, char *id
, size_t len
);
73 * Verification of an EMSA PSS signature described in PKCS#1
75 static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t
*this,
76 rsa_pss_params_t
*params
, chunk_t data
,
79 char hash_and_padding
[BUF_LEN
];
81 if (!botan_emsa_pss_identifier(params
, hash_and_padding
,
82 sizeof(hash_and_padding
)))
86 return botan_verify_signature(this->key
, hash_and_padding
, data
, signature
);
89 METHOD(public_key_t
, get_type
, key_type_t
,
90 private_botan_rsa_public_key_t
*this)
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
)
101 case SIGN_RSA_EMSA_PKCS1_NULL
:
102 return botan_verify_signature(this->key
, "EMSA_PKCS1(Raw)", data
,
104 case SIGN_RSA_EMSA_PKCS1_SHA1
:
105 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-1)", data
,
107 case SIGN_RSA_EMSA_PKCS1_SHA2_224
:
108 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-224)",
110 case SIGN_RSA_EMSA_PKCS1_SHA2_256
:
111 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-256)",
113 case SIGN_RSA_EMSA_PKCS1_SHA2_384
:
114 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-384)",
116 case SIGN_RSA_EMSA_PKCS1_SHA2_512
:
117 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-512)",
119 case SIGN_RSA_EMSA_PKCS1_SHA3_224
:
120 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(224)",
122 case SIGN_RSA_EMSA_PKCS1_SHA3_256
:
123 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(256))",
125 case SIGN_RSA_EMSA_PKCS1_SHA3_384
:
126 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(384))",
128 case SIGN_RSA_EMSA_PKCS1_SHA3_512
:
129 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(512))",
131 case SIGN_RSA_EMSA_PSS
:
132 return verify_emsa_pss_signature(this, params
, data
, signature
);
134 DBG1(DBG_LIB
, "signature scheme %N not supported via botan",
135 signature_scheme_names
, scheme
);
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
)
144 botan_pk_op_encrypt_t encrypt_op
;
150 case ENCRYPT_RSA_PKCS1
:
151 padding
= "PKCS1v15";
153 case ENCRYPT_RSA_OAEP_SHA1
:
154 padding
= "OAEP(SHA-1)";
156 case ENCRYPT_RSA_OAEP_SHA224
:
157 padding
= "OAEP(SHA-224)";
159 case ENCRYPT_RSA_OAEP_SHA256
:
160 padding
= "OAEP(SHA-256)";
162 case ENCRYPT_RSA_OAEP_SHA384
:
163 padding
= "OAEP(SHA-384)";
165 case ENCRYPT_RSA_OAEP_SHA512
:
166 padding
= "OAEP(SHA-512)";
169 DBG1(DBG_LIB
, "encryption scheme %N not supported via botan",
170 encryption_scheme_names
, scheme
);
174 if (!botan_get_rng(&rng
, RNG_STRONG
))
179 if (botan_pk_op_encrypt_create(&encrypt_op
, this->key
, padding
, 0))
181 botan_rng_destroy(rng
);
186 if (botan_pk_op_encrypt_output_length(encrypt_op
, plain
.len
, &crypto
->len
))
188 botan_rng_destroy(rng
);
189 botan_pk_op_encrypt_destroy(encrypt_op
);
193 *crypto
= chunk_alloc(crypto
->len
);
194 if (botan_pk_op_encrypt(encrypt_op
, rng
, crypto
->ptr
, &crypto
->len
,
195 plain
.ptr
, plain
.len
))
198 botan_rng_destroy(rng
);
199 botan_pk_op_encrypt_destroy(encrypt_op
);
202 botan_rng_destroy(rng
);
203 botan_pk_op_encrypt_destroy(encrypt_op
);
207 METHOD(public_key_t
, get_keysize
, int,
208 private_botan_rsa_public_key_t
*this)
213 if (botan_mp_init(&n
))
218 if (botan_pubkey_get_field(n
, this->key
, "n") ||
219 botan_mp_num_bits(n
, &bits
))
229 METHOD(public_key_t
, get_fingerprint
, bool,
230 private_botan_rsa_public_key_t
*this, cred_encoding_type_t type
,
233 return botan_get_fingerprint(this->key
, this, type
, fp
);
236 METHOD(public_key_t
, get_encoding
, bool,
237 private_botan_rsa_public_key_t
*this, cred_encoding_type_t type
,
240 return botan_get_encoding(this->key
, type
, encoding
);
243 METHOD(public_key_t
, get_ref
, public_key_t
*,
244 private_botan_rsa_public_key_t
*this)
247 return &this->public.key
;
250 METHOD(public_key_t
, destroy
, void,
251 private_botan_rsa_public_key_t
*this)
253 if (ref_put(&this->ref
))
255 lib
->encoding
->clear_cache(lib
->encoding
, this);
256 botan_pubkey_destroy(this->key
);
262 * Internal generic constructor
264 static private_botan_rsa_public_key_t
*create_empty()
266 private_botan_rsa_public_key_t
*this;
271 .get_type
= _get_type
,
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
,
290 * Described in header
292 botan_rsa_public_key_t
*botan_rsa_public_key_adopt(botan_pubkey_t key
)
294 private_botan_rsa_public_key_t
*this;
296 this = create_empty();
299 return &this->public;
303 * Described in header
305 botan_rsa_public_key_t
*botan_rsa_public_key_load(key_type_t type
,
308 private_botan_rsa_public_key_t
*this = NULL
;
314 switch (va_arg(args
, builder_part_t
))
316 case BUILD_RSA_MODULUS
:
317 n
= va_arg(args
, chunk_t
);
319 case BUILD_RSA_PUB_EXP
:
320 e
= va_arg(args
, chunk_t
);
330 if (n
.ptr
&& e
.ptr
&& type
== KEY_RSA
)
332 botan_mp_t mp_n
, mp_e
;
334 if (!chunk_to_botan_mp(n
, &mp_n
))
339 if (!chunk_to_botan_mp(e
, &mp_e
))
341 botan_mp_destroy(mp_n
);
345 this = create_empty();
347 if (botan_pubkey_load_rsa(&this->key
, mp_n
, mp_e
))
349 botan_mp_destroy(mp_n
);
350 botan_mp_destroy(mp_e
);
355 botan_mp_destroy(mp_n
);
356 botan_mp_destroy(mp_e
);
359 return &this->public;