PROV: Add a DER to RSA-PSS deserializer implementation
[openssl.git] / providers / implementations / serializers / serializer_rsa.c
1 /*
2  * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
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
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
16 #include "internal/packet.h"
17 #include "crypto/rsa.h"           /* rsa_get0_all_params() */
18 #include "prov/bio.h"             /* ossl_prov_bio_printf() */
19 #include "prov/der_rsa.h"         /* DER_w_RSASSA_PSS_params() */
20 #include "prov/implementations.h" /* rsa_keymgmt_functions */
21 #include "serializer_local.h"
22
23 DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
24
25 OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void)
26 {
27     return ossl_prov_get_keymgmt_new(rsa_keymgmt_functions);
28 }
29
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
35 OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void)
36 {
37     return ossl_prov_get_keymgmt_free(rsa_keymgmt_functions);
38 }
39
40 OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void)
41 {
42     return ossl_prov_get_keymgmt_import(rsa_keymgmt_functions);
43 }
44
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
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
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();
63     RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa);
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) {
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)
76             goto err;
77         modulus_label = "modulus:";
78         exponent_label = "publicExponent:";
79     } else {
80         if (BIO_printf(out, "Public-Key: (%d bit)\n", BN_num_bits(rsa_n)) <= 0)
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++) {
110             if (BIO_printf(out, "prime%d:", i + 1) <= 0)
111                 goto err;
112             if (!ossl_prov_print_labeled_bignum(out, NULL,
113                                                 sk_BIGNUM_const_value(factors,
114                                                                       i)))
115                 goto err;
116             if (BIO_printf(out, "exponent%d:", i + 1) <= 0)
117                 goto err;
118             if (!ossl_prov_print_labeled_bignum(out, NULL,
119                                                 sk_BIGNUM_const_value(exps, i)))
120                 goto err;
121             if (BIO_printf(out, "coefficient%d:", i + 1) <= 0)
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     }
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)) {
133             if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0)
134                 goto err;
135         }
136         break;
137     case RSA_FLAG_TYPE_RSASSAPSS:
138         if (rsa_pss_params_30_is_unrestricted(pss_params)) {
139             if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0)
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
149             if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0)
150                 goto err;
151             if (BIO_printf(out, "  Hash Algorithm: %s%s\n",
152                            rsa_oaeppss_nid2name(hashalg_nid),
153                            (hashalg_nid == NID_sha1
154                            ? " (default)" : "")) <= 0)
155                 goto err;
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)
162                 goto err;
163             if (BIO_printf(out, "  Minimum Salt Length: %d%s\n",
164                            saltlen,
165                            (saltlen == 20 ? " (default)" : "")) <= 0)
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              */
174             if (BIO_printf(out, "  Trailer Field: 0x%x%s\n",
175                            trailerfield,
176                            (trailerfield == 1 ? " (default)" : ""))
177                 <= 0)
178                 goto err;
179         }
180         break;
181     }
182
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 }
190
191 /*
192  * Helper functions to prepare RSA-PSS params for serialization.  We would
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;
212             return 1;
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)
234                     || !WPACKET_finish(&pkt)
235                     || !WPACKET_get_total_written(&pkt, &str_sz))
236                     goto err;
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 }