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