2 * Copyright (C) 2018 Tobias Brunner
3 * Copyright (C) 2018 Andreas Steffen
5 * Copyright (C) 2018 René Korthaus
6 * Rohde & Schwarz Cybersecurity GmbH
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include "botan_rsa_public_key.h"
29 #include <botan/build.h>
33 #include "botan_util.h"
36 #include <asn1/asn1.h>
37 #include <asn1/asn1_parser.h>
39 #include <utils/debug.h>
41 #include <botan/ffi.h>
43 typedef struct private_botan_rsa_public_key_t private_botan_rsa_public_key_t
;
46 * Private data structure with signing context.
48 struct private_botan_rsa_public_key_t
{
51 * Public interface for this signer
53 botan_rsa_public_key_t
public;
67 * Defined in botan_rsa_private_key.c
69 bool botan_emsa_pss_identifier(rsa_pss_params_t
*params
, char *id
, size_t len
);
72 * Verification of an EMSA PSS signature described in PKCS#1
74 static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t
*this,
75 rsa_pss_params_t
*params
, chunk_t data
,
78 char hash_and_padding
[BUF_LEN
];
80 if (!botan_emsa_pss_identifier(params
, hash_and_padding
,
81 sizeof(hash_and_padding
)))
85 return botan_verify_signature(this->key
, hash_and_padding
, data
, signature
);
88 METHOD(public_key_t
, get_type
, key_type_t
,
89 private_botan_rsa_public_key_t
*this)
94 METHOD(public_key_t
, verify
, bool,
95 private_botan_rsa_public_key_t
*this, signature_scheme_t scheme
,
96 void *params
, chunk_t data
, chunk_t signature
)
100 case SIGN_RSA_EMSA_PKCS1_NULL
:
101 return botan_verify_signature(this->key
, "EMSA_PKCS1(Raw)", data
,
103 case SIGN_RSA_EMSA_PKCS1_SHA1
:
104 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-1)", data
,
106 case SIGN_RSA_EMSA_PKCS1_SHA2_224
:
107 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-224)",
109 case SIGN_RSA_EMSA_PKCS1_SHA2_256
:
110 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-256)",
112 case SIGN_RSA_EMSA_PKCS1_SHA2_384
:
113 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-384)",
115 case SIGN_RSA_EMSA_PKCS1_SHA2_512
:
116 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-512)",
118 case SIGN_RSA_EMSA_PKCS1_SHA3_224
:
119 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(224)",
121 case SIGN_RSA_EMSA_PKCS1_SHA3_256
:
122 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(256))",
124 case SIGN_RSA_EMSA_PKCS1_SHA3_384
:
125 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(384))",
127 case SIGN_RSA_EMSA_PKCS1_SHA3_512
:
128 return botan_verify_signature(this->key
, "EMSA_PKCS1(SHA-3(512))",
130 case SIGN_RSA_EMSA_PSS
:
131 return verify_emsa_pss_signature(this, params
, data
, signature
);
133 DBG1(DBG_LIB
, "signature scheme %N not supported via botan",
134 signature_scheme_names
, scheme
);
139 METHOD(public_key_t
, encrypt
, bool,
140 private_botan_rsa_public_key_t
*this, encryption_scheme_t scheme
,
141 void *params
, chunk_t plain
, chunk_t
*crypto
)
143 botan_pk_op_encrypt_t encrypt_op
;
145 chunk_t label
= chunk_empty
;
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 (scheme
!= ENCRYPT_RSA_PKCS1
&& params
!= NULL
)
176 label
= *(chunk_t
*)params
;
179 DBG1(DBG_LIB
, "RSA OAEP encryption with a label not supported");
184 if (!botan_get_rng(&rng
, RNG_STRONG
))
189 if (botan_pk_op_encrypt_create(&encrypt_op
, this->key
, padding
, 0))
191 botan_rng_destroy(rng
);
196 if (botan_pk_op_encrypt_output_length(encrypt_op
, plain
.len
, &crypto
->len
))
198 botan_rng_destroy(rng
);
199 botan_pk_op_encrypt_destroy(encrypt_op
);
203 *crypto
= chunk_alloc(crypto
->len
);
204 if (botan_pk_op_encrypt(encrypt_op
, rng
, crypto
->ptr
, &crypto
->len
,
205 plain
.ptr
, plain
.len
))
208 botan_rng_destroy(rng
);
209 botan_pk_op_encrypt_destroy(encrypt_op
);
212 botan_rng_destroy(rng
);
213 botan_pk_op_encrypt_destroy(encrypt_op
);
217 METHOD(public_key_t
, get_keysize
, int,
218 private_botan_rsa_public_key_t
*this)
223 if (botan_mp_init(&n
))
228 if (botan_pubkey_get_field(n
, this->key
, "n") ||
229 botan_mp_num_bits(n
, &bits
))
239 METHOD(public_key_t
, get_fingerprint
, bool,
240 private_botan_rsa_public_key_t
*this, cred_encoding_type_t type
,
243 return botan_get_fingerprint(this->key
, this, type
, fp
);
246 METHOD(public_key_t
, get_encoding
, bool,
247 private_botan_rsa_public_key_t
*this, cred_encoding_type_t type
,
250 return botan_get_encoding(this->key
, type
, encoding
);
253 METHOD(public_key_t
, get_ref
, public_key_t
*,
254 private_botan_rsa_public_key_t
*this)
257 return &this->public.key
;
260 METHOD(public_key_t
, destroy
, void,
261 private_botan_rsa_public_key_t
*this)
263 if (ref_put(&this->ref
))
265 lib
->encoding
->clear_cache(lib
->encoding
, this);
266 botan_pubkey_destroy(this->key
);
272 * Internal generic constructor
274 static private_botan_rsa_public_key_t
*create_empty()
276 private_botan_rsa_public_key_t
*this;
281 .get_type
= _get_type
,
284 .equals
= public_key_equals
,
285 .get_keysize
= _get_keysize
,
286 .get_fingerprint
= _get_fingerprint
,
287 .has_fingerprint
= public_key_has_fingerprint
,
288 .get_encoding
= _get_encoding
,
300 * Described in header
302 botan_rsa_public_key_t
*botan_rsa_public_key_adopt(botan_pubkey_t key
)
304 private_botan_rsa_public_key_t
*this;
306 this = create_empty();
309 return &this->public;
313 * Described in header
315 botan_rsa_public_key_t
*botan_rsa_public_key_load(key_type_t type
,
318 private_botan_rsa_public_key_t
*this = NULL
;
324 switch (va_arg(args
, builder_part_t
))
326 case BUILD_RSA_MODULUS
:
327 n
= va_arg(args
, chunk_t
);
329 case BUILD_RSA_PUB_EXP
:
330 e
= va_arg(args
, chunk_t
);
340 if (n
.ptr
&& e
.ptr
&& type
== KEY_RSA
)
342 botan_mp_t mp_n
, mp_e
;
344 if (!chunk_to_botan_mp(n
, &mp_n
))
349 if (!chunk_to_botan_mp(e
, &mp_e
))
351 botan_mp_destroy(mp_n
);
355 this = create_empty();
357 if (botan_pubkey_load_rsa(&this->key
, mp_n
, mp_e
))
359 botan_mp_destroy(mp_n
);
360 botan_mp_destroy(mp_e
);
365 botan_mp_destroy(mp_n
);
366 botan_mp_destroy(mp_e
);
369 return &this->public;