]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/implementations/encode_decode/encoder_rsa.c
Rename OSSL_SERIALIZER / OSSL_DESERIALIZER to OSSL_ENCODE / OSSL_DECODE
[thirdparty/openssl.git] / providers / implementations / encode_decode / encoder_rsa.c
CommitLineData
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
23DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
24
363b1e5d 25OSSL_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
30OSSL_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 35OSSL_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 40OSSL_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
45OSSL_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
50OSSL_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
55int 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
197int 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
266int 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}