PROV: Add a DER to RSA-PSS deserializer implementation
[openssl.git] / providers / implementations / serializers / deserialize_der2rsa.c
1 /*
2  * Copyright 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 <openssl/core_dispatch.h>
17 #include <openssl/core_names.h>
18 #include <openssl/crypto.h>
19 #include <openssl/err.h>
20 #include <openssl/params.h>
21 #include <openssl/x509.h>
22 #include "prov/bio.h"
23 #include "prov/implementations.h"
24 #include "prov/providercommonerr.h"
25 #include "serializer_local.h"
26
27 static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx;
28 static OSSL_FUNC_deserializer_freectx_fn der2rsa_freectx;
29 static OSSL_FUNC_deserializer_gettable_params_fn der2rsa_gettable_params;
30 static OSSL_FUNC_deserializer_get_params_fn der2rsa_get_params;
31 static OSSL_FUNC_deserializer_settable_ctx_params_fn der2rsa_settable_ctx_params;
32 static OSSL_FUNC_deserializer_set_ctx_params_fn der2rsa_set_ctx_params;
33 static OSSL_FUNC_deserializer_deserialize_fn der2rsa_deserialize;
34 static OSSL_FUNC_deserializer_export_object_fn der2rsa_export_object;
35
36 /*
37  * Context used for DER to RSA key deserialization.
38  */
39 struct der2rsa_ctx_st {
40     PROV_CTX *provctx;
41
42     int type;
43
44     struct pkcs8_encrypt_ctx_st sc;
45 };
46
47 static struct der2rsa_ctx_st *der2rsa_newctx_int(void *provctx)
48 {
49     struct der2rsa_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
50
51     if (ctx != NULL) {
52         ctx->provctx = provctx;
53         /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
54         ctx->sc.pbe_nid = -1;
55     }
56     return ctx;
57 }
58
59 static void *der2rsa_newctx(void *provctx)
60 {
61     struct der2rsa_ctx_st *ctx = der2rsa_newctx_int(provctx);
62
63     if (ctx != NULL)
64         ctx->type = EVP_PKEY_RSA;
65     return ctx;
66 }
67
68 static void *der2rsapss_newctx(void *provctx)
69 {
70     struct der2rsa_ctx_st *ctx = der2rsa_newctx_int(provctx);
71
72     if (ctx != NULL)
73         ctx->type = EVP_PKEY_RSA_PSS;
74     return ctx;
75 }
76
77 static void der2rsa_freectx(void *vctx)
78 {
79     struct der2rsa_ctx_st *ctx = vctx;
80
81     EVP_CIPHER_free(ctx->sc.cipher);
82     OPENSSL_clear_free(ctx->sc.cipher_pass, ctx->sc.cipher_pass_length);
83     OPENSSL_free(ctx);
84 }
85
86 static const OSSL_PARAM *der2rsa_gettable_params(void)
87 {
88     static const OSSL_PARAM gettables[] = {
89         { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
90         OSSL_PARAM_END,
91     };
92
93     return gettables;
94 }
95
96 static int der2rsa_get_params(OSSL_PARAM params[])
97 {
98     OSSL_PARAM *p;
99
100     p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE);
101     if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER"))
102         return 0;
103
104     return 1;
105 }
106
107
108 static const OSSL_PARAM *der2rsa_settable_ctx_params(void)
109 {
110     static const OSSL_PARAM settables[] = {
111         OSSL_PARAM_utf8_string(OSSL_DESERIALIZER_PARAM_CIPHER, NULL, 0),
112         OSSL_PARAM_utf8_string(OSSL_DESERIALIZER_PARAM_PROPERTIES, NULL, 0),
113         OSSL_PARAM_octet_string(OSSL_DESERIALIZER_PARAM_PASS, NULL, 0),
114         OSSL_PARAM_END,
115     };
116
117     return settables;
118 }
119
120 static int der2rsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])
121 {
122     struct der2rsa_ctx_st *ctx = vctx;
123     OPENSSL_CTX *libctx = PROV_CTX_get0_library_context(ctx->provctx);
124     const OSSL_PARAM *p;
125
126     if ((p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_CIPHER))
127         != NULL) {
128         const OSSL_PARAM *propsp =
129             OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_PROPERTIES);
130         const char *props = NULL;
131
132         if (p->data_type != OSSL_PARAM_UTF8_STRING)
133             return 0;
134         if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
135             return 0;
136         props = (propsp != NULL ? propsp->data : NULL);
137
138         EVP_CIPHER_free(ctx->sc.cipher);
139         ctx->sc.cipher = NULL;
140         ctx->sc.cipher_intent = p->data != NULL;
141         if (p->data != NULL
142             && ((ctx->sc.cipher = EVP_CIPHER_fetch(libctx, p->data, props))
143                 == NULL))
144             return 0;
145     }
146     if ((p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_PASS))
147         != NULL) {
148         OPENSSL_clear_free(ctx->sc.cipher_pass, ctx->sc.cipher_pass_length);
149         ctx->sc.cipher_pass = NULL;
150         if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
151                                          &ctx->sc.cipher_pass_length))
152             return 0;
153     }
154     return 1;
155 }
156
157 static int der2rsa_deserialize(void *vctx, OSSL_CORE_BIO *cin,
158                                OSSL_CALLBACK *data_cb, void *data_cbarg,
159                                OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
160 {
161     struct der2rsa_ctx_st *ctx = vctx;
162     void *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx);
163     RSA *rsa = NULL;
164     unsigned char *der = NULL;
165     const unsigned char *derp;
166     long der_len = 0;
167     unsigned char *new_der = NULL;
168     long new_der_len;
169     EVP_PKEY *pkey = NULL;
170     int ok = 0;
171
172     ctx->sc.cb = pw_cb;
173     ctx->sc.cbarg = pw_cbarg;
174
175     if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len))
176         return 0;
177
178     /*
179      * Opportunistic attempt to decrypt.  If it doesn't work, we try to
180      * decode our input unencrypted.
181      */
182     if (ctx->sc.cipher_intent
183         && ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len,
184                                  &ctx->sc)) {
185         OPENSSL_free(der);
186         der = new_der;
187         der_len = new_der_len;
188     }
189
190     derp = der;
191     if ((pkey = d2i_PrivateKey_ex(ctx->type, NULL, &derp, der_len,
192                                   libctx, NULL)) != NULL) {
193         /* Tear out the RSA pointer from the pkey */
194         rsa = EVP_PKEY_get1_RSA(pkey);
195         EVP_PKEY_free(pkey);
196     }
197
198     OPENSSL_free(der);
199
200     if (rsa != NULL) {
201         OSSL_PARAM params[3];
202         char *object_type = NULL;
203
204         switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
205         case RSA_FLAG_TYPE_RSA:
206             object_type = "RSA";
207             break;
208         case RSA_FLAG_TYPE_RSASSAPSS:
209             object_type = "RSA-PSS";
210             break;
211         default:
212             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_RSA_KEY,
213                            "Expected the RSA type to be %d or %d, but got %d",
214                            RSA_FLAG_TYPE_RSA, RSA_FLAG_TYPE_RSASSAPSS,
215                            RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK));
216             goto end;
217         }
218
219
220         params[0] =
221             OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE,
222                                              object_type, 0);
223         /* The address of the key becomes the octet string */
224         params[1] =
225             OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE,
226                                               &rsa, sizeof(rsa));
227         params[2] = OSSL_PARAM_construct_end();
228
229         ok = data_cb(params, data_cbarg);
230     }
231  end:
232     RSA_free(rsa);
233
234     return ok;
235 }
236
237 static int der2rsa_export_object_int(void *vctx,
238                                      const void *reference, size_t reference_sz,
239                                      OSSL_FUNC_keymgmt_export_fn *rsa_export,
240                                      OSSL_CALLBACK *export_cb,
241                                      void *export_cbarg)
242 {
243     void *keydata;
244
245     if (reference_sz == sizeof(keydata) && rsa_export != NULL) {
246         /* The contents of the reference is the address to our object */
247         keydata = *(RSA **)reference;
248
249         return rsa_export(keydata, OSSL_KEYMGMT_SELECT_ALL,
250                           export_cb, export_cbarg);
251     }
252     return 0;
253 }
254
255 static int der2rsa_export_object(void *vctx,
256                                  const void *reference, size_t reference_sz,
257                                  OSSL_CALLBACK *export_cb,
258                                  void *export_cbarg)
259 {
260     return der2rsa_export_object_int(vctx, reference, reference_sz,
261                                      ossl_prov_get_keymgmt_rsa_export(),
262                                      export_cb, export_cbarg);
263 }
264
265 static int der2rsapss_export_object(void *vctx,
266                                     const void *reference, size_t reference_sz,
267                                     OSSL_CALLBACK *export_cb,
268                                     void *export_cbarg)
269 {
270     return der2rsa_export_object_int(vctx, reference, reference_sz,
271                                      ossl_prov_get_keymgmt_rsapss_export(),
272                                      export_cb, export_cbarg);
273 }
274
275 const OSSL_DISPATCH der_to_rsa_deserializer_functions[] = {
276     { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))der2rsa_newctx },
277     { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))der2rsa_freectx },
278     { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS,
279       (void (*)(void))der2rsa_gettable_params },
280     { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
281       (void (*)(void))der2rsa_get_params },
282     { OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS,
283       (void (*)(void))der2rsa_settable_ctx_params },
284     { OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS,
285       (void (*)(void))der2rsa_set_ctx_params },
286     { OSSL_FUNC_DESERIALIZER_DESERIALIZE,
287       (void (*)(void))der2rsa_deserialize },
288     { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,
289       (void (*)(void))der2rsa_export_object },
290     { 0, NULL }
291 };
292
293 const OSSL_DISPATCH der_to_rsapss_deserializer_functions[] = {
294     { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))der2rsapss_newctx },
295     { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))der2rsa_freectx },
296     { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS,
297       (void (*)(void))der2rsa_gettable_params },
298     { OSSL_FUNC_DESERIALIZER_GET_PARAMS,
299       (void (*)(void))der2rsa_get_params },
300     { OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS,
301       (void (*)(void))der2rsa_settable_ctx_params },
302     { OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS,
303       (void (*)(void))der2rsa_set_ctx_params },
304     { OSSL_FUNC_DESERIALIZER_DESERIALIZE,
305       (void (*)(void))der2rsa_deserialize },
306     { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT,
307       (void (*)(void))der2rsapss_export_object },
308     { 0, NULL }
309 };