2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/core_numbers.h>
11 #include <openssl/core_names.h>
12 #include <openssl/bn.h>
13 #include <openssl/rsa.h>
14 #include <openssl/params.h>
15 #include <openssl/types.h>
16 #include "internal/param_build.h"
17 #include "prov/implementations.h"
18 #include "prov/providercommon.h"
19 #include "crypto/rsa.h"
21 static OSSL_OP_keymgmt_importkey_fn rsa_importkey
;
22 static OSSL_OP_keymgmt_exportkey_fn rsa_exportkey
;
24 DEFINE_STACK_OF(BIGNUM
)
25 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const
, BIGNUM
)
27 static int collect_numbers(STACK_OF(BIGNUM
) *numbers
,
28 const OSSL_PARAM params
[], const char *key
)
30 const OSSL_PARAM
*p
= NULL
;
35 for (p
= params
; (p
= OSSL_PARAM_locate_const(p
, key
)) != NULL
; p
++) {
38 if (!OSSL_PARAM_get_BN(p
, &tmp
))
40 sk_BIGNUM_push(numbers
, tmp
);
46 static int params_to_key(RSA
*rsa
, const OSSL_PARAM params
[])
48 const OSSL_PARAM
*param_n
, *param_e
, *param_d
;
49 BIGNUM
*n
= NULL
, *e
= NULL
, *d
= NULL
;
50 STACK_OF(BIGNUM
) *factors
= NULL
, *exps
= NULL
, *coeffs
= NULL
;
56 param_n
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_N
);
57 param_e
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_E
);
58 param_d
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_RSA_D
);
60 if ((param_n
!= NULL
&& !OSSL_PARAM_get_BN(param_n
, &n
))
61 || (param_e
!= NULL
&& !OSSL_PARAM_get_BN(param_e
, &e
))
62 || (param_d
!= NULL
&& !OSSL_PARAM_get_BN(param_d
, &d
)))
65 is_private
= (d
!= NULL
);
67 if (!RSA_set0_key(rsa
, n
, e
, d
))
72 if (!collect_numbers(factors
= sk_BIGNUM_new_null(), params
,
73 OSSL_PKEY_PARAM_RSA_FACTOR
)
74 || !collect_numbers(exps
= sk_BIGNUM_new_null(), params
,
75 OSSL_PKEY_PARAM_RSA_EXPONENT
)
76 || !collect_numbers(coeffs
= sk_BIGNUM_new_null(), params
,
77 OSSL_PKEY_PARAM_RSA_COEFFICIENT
))
80 /* It's ok if this private key just has n, e and d */
81 if (sk_BIGNUM_num(factors
) != 0
82 && !rsa_set0_all_params(rsa
, factors
, exps
, coeffs
))
86 sk_BIGNUM_free(factors
);
88 sk_BIGNUM_free(coeffs
);
95 sk_BIGNUM_pop_free(factors
, BN_free
);
96 sk_BIGNUM_pop_free(exps
, BN_free
);
97 sk_BIGNUM_pop_free(coeffs
, BN_free
);
101 static int export_numbers(OSSL_PARAM_BLD
*tmpl
, const char *key
,
102 STACK_OF(BIGNUM_const
) *numbers
)
109 nnum
= sk_BIGNUM_const_num(numbers
);
111 for (i
= 0; i
< nnum
; i
++) {
112 if (!ossl_param_bld_push_BN(tmpl
, key
,
113 sk_BIGNUM_const_value(numbers
, i
)))
120 static int key_to_params(RSA
*rsa
, OSSL_PARAM_BLD
*tmpl
)
123 const BIGNUM
*rsa_d
= NULL
, *rsa_n
= NULL
, *rsa_e
= NULL
;
124 STACK_OF(BIGNUM_const
) *factors
= sk_BIGNUM_const_new_null();
125 STACK_OF(BIGNUM_const
) *exps
= sk_BIGNUM_const_new_null();
126 STACK_OF(BIGNUM_const
) *coeffs
= sk_BIGNUM_const_new_null();
128 if (rsa
== NULL
|| factors
== NULL
|| exps
== NULL
|| coeffs
== NULL
)
131 RSA_get0_key(rsa
, &rsa_n
, &rsa_e
, &rsa_d
);
132 rsa_get0_all_params(rsa
, factors
, exps
, coeffs
);
135 && !ossl_param_bld_push_BN(tmpl
, OSSL_PKEY_PARAM_RSA_N
, rsa_n
))
138 && !ossl_param_bld_push_BN(tmpl
, OSSL_PKEY_PARAM_RSA_E
, rsa_e
))
141 && !ossl_param_bld_push_BN(tmpl
, OSSL_PKEY_PARAM_RSA_D
, rsa_d
))
144 if (!export_numbers(tmpl
, OSSL_PKEY_PARAM_RSA_FACTOR
, factors
)
145 || !export_numbers(tmpl
, OSSL_PKEY_PARAM_RSA_EXPONENT
, exps
)
146 || !export_numbers(tmpl
, OSSL_PKEY_PARAM_RSA_COEFFICIENT
, coeffs
))
151 sk_BIGNUM_const_free(factors
);
152 sk_BIGNUM_const_free(exps
);
153 sk_BIGNUM_const_free(coeffs
);
157 static void *rsa_importkey(void *provctx
, const OSSL_PARAM params
[])
161 if ((rsa
= RSA_new()) == NULL
162 || !params_to_key(rsa
, params
)) {
169 static int rsa_exportkey(void *key
, OSSL_CALLBACK
*param_callback
, void *cbarg
)
173 OSSL_PARAM
*params
= NULL
;
176 ossl_param_bld_init(&tmpl
);
178 || !key_to_params(rsa
, &tmpl
)
179 || (params
= ossl_param_bld_to_param(&tmpl
)) == NULL
)
181 ret
= param_callback(params
, cbarg
);
182 ossl_param_bld_free(params
);
187 * This provider can export everything in an RSA key, so we use the exact
188 * same type description for export as for import. Other providers might
189 * choose to import full keys, but only export the public parts, and will
190 * therefore have the importkey_types and importkey_types functions return
193 static const OSSL_PARAM rsa_key_types
[] = {
194 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N
, NULL
, 0),
195 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E
, NULL
, 0),
196 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D
, NULL
, 0),
197 /* We tolerate up to 10 factors... */
198 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
199 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
200 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
201 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
202 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
203 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
204 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
205 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
206 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
207 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR
, NULL
, 0),
208 /* ..., up to 10 CRT exponents... */
209 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
210 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
211 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
212 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
213 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
214 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
215 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
216 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
217 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
218 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT
, NULL
, 0),
219 /* ..., and up to 9 CRT coefficients */
220 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
221 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
222 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
223 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
224 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
225 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
226 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
227 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
228 OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT
, NULL
, 0),
231 * We lied about the amount of factors, exponents and coefficients, the
232 * export and import functions can really deal with an infinite amount
233 * of these numbers. However, RSA keys with too many primes are futile,
234 * so we at least pretend to have some limits.
237 static const OSSL_PARAM
*rsa_exportkey_types(void)
239 return rsa_key_types
;
242 static const OSSL_PARAM
*rsa_importkey_types(void)
244 return rsa_key_types
;
247 const OSSL_DISPATCH rsa_keymgmt_functions
[] = {
248 { OSSL_FUNC_KEYMGMT_IMPORTKEY
, (void (*)(void))rsa_importkey
},
249 { OSSL_FUNC_KEYMGMT_IMPORTKEY_TYPES
, (void (*)(void))rsa_importkey_types
},
250 { OSSL_FUNC_KEYMGMT_EXPORTKEY
, (void (*)(void))rsa_exportkey
},
251 { OSSL_FUNC_KEYMGMT_EXPORTKEY_TYPES
, (void (*)(void))rsa_exportkey_types
},
252 { OSSL_FUNC_KEYMGMT_FREEKEY
, (void (*)(void))RSA_free
},