]>
Commit | Line | Data |
---|---|---|
677add38 | 1 | /* |
33388b44 | 2 | * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. |
677add38 RL |
3 | * |
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 | |
8 | */ | |
9 | ||
c5f87134 P |
10 | /* |
11 | * RSA low level APIs are deprecated for public use, but still ok for | |
12 | * internal use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
ea297dca | 16 | #include "internal/packet.h" |
677add38 RL |
17 | #include "crypto/rsa.h" /* rsa_get0_all_params() */ |
18 | #include "prov/bio.h" /* ossl_prov_bio_printf() */ | |
ea297dca | 19 | #include "prov/der_rsa.h" /* DER_w_RSASSA_PSS_params() */ |
677add38 | 20 | #include "prov/implementations.h" /* rsa_keymgmt_functions */ |
ece9304c | 21 | #include "encoder_local.h" |
677add38 RL |
22 | |
23 | DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) | |
24 | ||
363b1e5d | 25 | OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void) |
677add38 | 26 | { |
32b0645c RL |
27 | return ossl_prov_get_keymgmt_new(rsa_keymgmt_functions); |
28 | } | |
29 | ||
a4e55ccc RL |
30 | OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void) |
31 | { | |
32 | return ossl_prov_get_keymgmt_new(rsapss_keymgmt_functions); | |
33 | } | |
34 | ||
363b1e5d | 35 | OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void) |
32b0645c RL |
36 | { |
37 | return ossl_prov_get_keymgmt_free(rsa_keymgmt_functions); | |
38 | } | |
39 | ||
363b1e5d | 40 | OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void) |
32b0645c RL |
41 | { |
42 | return ossl_prov_get_keymgmt_import(rsa_keymgmt_functions); | |
677add38 RL |
43 | } |
44 | ||
1017b8e4 RL |
45 | OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void) |
46 | { | |
47 | return ossl_prov_get_keymgmt_export(rsa_keymgmt_functions); | |
48 | } | |
49 | ||
a4e55ccc RL |
50 | OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void) |
51 | { | |
52 | return ossl_prov_get_keymgmt_export(rsapss_keymgmt_functions); | |
53 | } | |
54 | ||
677add38 RL |
55 | int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv) |
56 | { | |
57 | const char *modulus_label; | |
58 | const char *exponent_label; | |
59 | const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; | |
60 | STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null(); | |
61 | STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null(); | |
62 | STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null(); | |
ea297dca | 63 | RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa); |
677add38 RL |
64 | int ret = 0; |
65 | ||
66 | if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL) | |
67 | goto err; | |
68 | ||
69 | RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); | |
70 | rsa_get0_all_params(rsa, factors, exps, coeffs); | |
71 | ||
72 | if (priv && rsa_d != NULL) { | |
d40b42ab MC |
73 | if (BIO_printf(out, "Private-Key: (%d bit, %d primes)\n", |
74 | BN_num_bits(rsa_n), | |
75 | sk_BIGNUM_const_num(factors)) <= 0) | |
677add38 RL |
76 | goto err; |
77 | modulus_label = "modulus:"; | |
78 | exponent_label = "publicExponent:"; | |
79 | } else { | |
d40b42ab | 80 | if (BIO_printf(out, "Public-Key: (%d bit)\n", BN_num_bits(rsa_n)) <= 0) |
677add38 RL |
81 | goto err; |
82 | modulus_label = "Modulus:"; | |
83 | exponent_label = "Exponent:"; | |
84 | } | |
85 | if (!ossl_prov_print_labeled_bignum(out, modulus_label, rsa_n)) | |
86 | goto err; | |
87 | if (!ossl_prov_print_labeled_bignum(out, exponent_label, rsa_e)) | |
88 | goto err; | |
89 | if (priv) { | |
90 | int i; | |
91 | ||
92 | if (!ossl_prov_print_labeled_bignum(out, "privateExponent:", rsa_d)) | |
93 | goto err; | |
94 | if (!ossl_prov_print_labeled_bignum(out, "prime1:", | |
95 | sk_BIGNUM_const_value(factors, 0))) | |
96 | goto err; | |
97 | if (!ossl_prov_print_labeled_bignum(out, "prime2:", | |
98 | sk_BIGNUM_const_value(factors, 1))) | |
99 | goto err; | |
100 | if (!ossl_prov_print_labeled_bignum(out, "exponent1:", | |
101 | sk_BIGNUM_const_value(exps, 0))) | |
102 | goto err; | |
103 | if (!ossl_prov_print_labeled_bignum(out, "exponent2:", | |
104 | sk_BIGNUM_const_value(exps, 1))) | |
105 | goto err; | |
106 | if (!ossl_prov_print_labeled_bignum(out, "coefficient:", | |
107 | sk_BIGNUM_const_value(coeffs, 0))) | |
108 | goto err; | |
109 | for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { | |
d40b42ab | 110 | if (BIO_printf(out, "prime%d:", i + 1) <= 0) |
677add38 RL |
111 | goto err; |
112 | if (!ossl_prov_print_labeled_bignum(out, NULL, | |
113 | sk_BIGNUM_const_value(factors, | |
114 | i))) | |
115 | goto err; | |
d40b42ab | 116 | if (BIO_printf(out, "exponent%d:", i + 1) <= 0) |
677add38 RL |
117 | goto err; |
118 | if (!ossl_prov_print_labeled_bignum(out, NULL, | |
119 | sk_BIGNUM_const_value(exps, i))) | |
120 | goto err; | |
d40b42ab | 121 | if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) |
677add38 RL |
122 | goto err; |
123 | if (!ossl_prov_print_labeled_bignum(out, NULL, | |
124 | sk_BIGNUM_const_value(coeffs, | |
125 | i - 1))) | |
126 | goto err; | |
127 | } | |
128 | } | |
ea297dca RL |
129 | |
130 | switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { | |
131 | case RSA_FLAG_TYPE_RSA: | |
132 | if (!rsa_pss_params_30_is_unrestricted(pss_params)) { | |
d40b42ab | 133 | if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0) |
ea297dca RL |
134 | goto err; |
135 | } | |
136 | break; | |
137 | case RSA_FLAG_TYPE_RSASSAPSS: | |
138 | if (rsa_pss_params_30_is_unrestricted(pss_params)) { | |
d40b42ab | 139 | if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0) |
ea297dca RL |
140 | goto err; |
141 | } else { | |
142 | int hashalg_nid = rsa_pss_params_30_hashalg(pss_params); | |
143 | int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params); | |
144 | int maskgenhashalg_nid = | |
145 | rsa_pss_params_30_maskgenhashalg(pss_params); | |
146 | int saltlen = rsa_pss_params_30_saltlen(pss_params); | |
147 | int trailerfield = rsa_pss_params_30_trailerfield(pss_params); | |
148 | ||
d40b42ab | 149 | if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0) |
ea297dca | 150 | goto err; |
d40b42ab MC |
151 | if (BIO_printf(out, " Hash Algorithm: %s%s\n", |
152 | rsa_oaeppss_nid2name(hashalg_nid), | |
153 | (hashalg_nid == NID_sha1 | |
154 | ? " (default)" : "")) <= 0) | |
ea297dca | 155 | goto err; |
d40b42ab MC |
156 | if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n", |
157 | rsa_mgf_nid2name(maskgenalg_nid), | |
158 | rsa_oaeppss_nid2name(maskgenhashalg_nid), | |
159 | (maskgenalg_nid == NID_mgf1 | |
160 | && maskgenhashalg_nid == NID_sha1 | |
161 | ? " (default)" : "")) <= 0) | |
ea297dca | 162 | goto err; |
d40b42ab MC |
163 | if (BIO_printf(out, " Minimum Salt Length: %d%s\n", |
164 | saltlen, | |
165 | (saltlen == 20 ? " (default)" : "")) <= 0) | |
ea297dca RL |
166 | goto err; |
167 | /* | |
168 | * TODO(3.0) Should we show the ASN.1 trailerField value, or | |
169 | * the actual trailerfield byte (i.e. 0xBC for 1)? | |
170 | * crypto/rsa/rsa_ameth.c isn't very clear on that, as it | |
171 | * does display 0xBC when the default applies, but the ASN.1 | |
172 | * trailerField value otherwise... | |
173 | */ | |
d40b42ab MC |
174 | if (BIO_printf(out, " Trailer Field: 0x%x%s\n", |
175 | trailerfield, | |
176 | (trailerfield == 1 ? " (default)" : "")) | |
ea297dca RL |
177 | <= 0) |
178 | goto err; | |
179 | } | |
180 | break; | |
181 | } | |
182 | ||
677add38 RL |
183 | ret = 1; |
184 | err: | |
185 | sk_BIGNUM_const_free(factors); | |
186 | sk_BIGNUM_const_free(exps); | |
187 | sk_BIGNUM_const_free(coeffs); | |
188 | return ret; | |
189 | } | |
ea297dca RL |
190 | |
191 | /* | |
ece9304c | 192 | * Helper functions to prepare RSA-PSS params for encoding. We would |
ea297dca RL |
193 | * have simply written the whole AlgorithmIdentifier, but existing libcrypto |
194 | * functionality doesn't allow that. | |
195 | */ | |
196 | ||
197 | int ossl_prov_prepare_rsa_params(const void *rsa, int nid, | |
198 | void **pstr, int *pstrtype) | |
199 | { | |
200 | const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa); | |
201 | ||
202 | *pstr = NULL; | |
203 | ||
204 | switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { | |
205 | case RSA_FLAG_TYPE_RSA: | |
206 | /* If plain RSA, the parameters shall be NULL */ | |
207 | *pstrtype = V_ASN1_NULL; | |
208 | return 1; | |
209 | case RSA_FLAG_TYPE_RSASSAPSS: | |
210 | if (rsa_pss_params_30_is_unrestricted(pss)) { | |
211 | *pstrtype = V_ASN1_UNDEF; | |
456b3b97 | 212 | return 1; |
ea297dca RL |
213 | } else { |
214 | ASN1_STRING *astr = NULL; | |
215 | WPACKET pkt; | |
216 | unsigned char *str = NULL; | |
217 | size_t str_sz = 0; | |
218 | int i; | |
219 | ||
220 | for (i = 0; i < 2; i++) { | |
221 | switch (i) { | |
222 | case 0: | |
223 | if (!WPACKET_init_null_der(&pkt)) | |
224 | goto err; | |
225 | break; | |
226 | case 1: | |
227 | if ((str = OPENSSL_malloc(str_sz)) == NULL | |
228 | || !WPACKET_init_der(&pkt, str, str_sz)) { | |
229 | goto err; | |
230 | } | |
231 | break; | |
232 | } | |
233 | if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss) | |
e5cb3453 P |
234 | || !WPACKET_finish(&pkt) |
235 | || !WPACKET_get_total_written(&pkt, &str_sz)) | |
ea297dca | 236 | goto err; |
ea297dca RL |
237 | WPACKET_cleanup(&pkt); |
238 | ||
239 | /* | |
240 | * If no PSS parameters are going to be written, there's no | |
241 | * point going for another iteration. | |
242 | * This saves us from getting |str| allocated just to have it | |
243 | * immediately de-allocated. | |
244 | */ | |
245 | if (str_sz == 0) | |
246 | break; | |
247 | } | |
248 | ||
249 | if ((astr = ASN1_STRING_new()) == NULL) | |
250 | goto err; | |
251 | *pstrtype = V_ASN1_SEQUENCE; | |
252 | ASN1_STRING_set0(astr, str, (int)str_sz); | |
253 | *pstr = astr; | |
254 | ||
255 | return 1; | |
256 | err: | |
257 | OPENSSL_free(str); | |
258 | return 0; | |
259 | } | |
260 | } | |
261 | ||
262 | /* Currently unsupported RSA key type */ | |
263 | return 0; | |
264 | } | |
265 | ||
266 | int ossl_prov_rsa_type_to_evp(const RSA *rsa) | |
267 | { | |
268 | switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { | |
269 | case RSA_FLAG_TYPE_RSA: | |
270 | return EVP_PKEY_RSA; | |
271 | case RSA_FLAG_TYPE_RSASSAPSS: | |
272 | return EVP_PKEY_RSA_PSS; | |
273 | } | |
274 | ||
275 | /* Currently unsupported RSA key type */ | |
276 | return EVP_PKEY_NONE; | |
277 | } |