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