54c63347fd10424eda99aecd63175b81dbb3f589
[openssl.git] / providers / implementations / serializers / deserialize_common.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 #include <openssl/core_names.h>
11 #include <openssl/bio.h>
12 #include <openssl/err.h>
13 #include <openssl/buffer.h>
14 #include <openssl/pem.h>         /* For public PEM and PVK functions */
15 #include <openssl/pkcs12.h>
16 #include "internal/pem.h"        /* For internal PVK and "blob" functions */
17 #include "internal/cryptlib.h"
18 #include "crypto/asn1.h"
19 #include "prov/bio.h"               /* ossl_prov_bio_printf() */
20 #include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
21 #include "serializer_local.h"
22
23 int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
24                        unsigned char **data, long *len)
25 {
26     BUF_MEM *mem = NULL;
27     BIO *in = bio_new_from_core_bio(provctx, cin);
28     int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
29
30     if (ok) {
31         *data = (unsigned char *)mem->data;
32         *len = (long)mem->length;
33         OPENSSL_free(mem);
34     }
35     BIO_free(in);
36     return ok;
37 }
38
39 int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
40                        char **pem_name, char **pem_header,
41                        unsigned char **data, long *len)
42 {
43     BIO *in = bio_new_from_core_bio(provctx, cin);
44     int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0);
45
46     BIO_free(in);
47     return ok;
48 }
49
50 #ifndef OPENSSL_NO_DSA
51 EVP_PKEY *ossl_prov_read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
52                                 int *ispub)
53 {
54     BIO *in = bio_new_from_core_bio(provctx, cin);
55     EVP_PKEY *pkey = ossl_b2i_bio(in, ispub);
56
57     BIO_free(in);
58     return pkey;
59 }
60
61 struct pwdata_st {
62     OSSL_PASSPHRASE_CALLBACK *pw_cb;
63     void *pw_cbarg;
64 };
65
66 pem_password_cb pw_pem_password_to_ossl_passhrase;
67 int pw_pem_password_to_ossl_passhrase(char *buf, int size, int rwflag,
68                                       void *userdata)
69 {
70     struct pwdata_st *data = userdata;
71     size_t pw_len = 0;
72     static char prompt_info[] = "pass phrase";
73     OSSL_PARAM params[] = {
74         OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, prompt_info,
75                                sizeof(prompt_info) - 1),
76         OSSL_PARAM_END
77     };
78     int ok = data->pw_cb(buf, (size_t)size, &pw_len, params, data->pw_cbarg);
79
80     if (ok)
81         return (int)pw_len;
82     else
83         return -1;
84 }
85
86 # ifndef OPENSSL_NO_RC4
87 EVP_PKEY *ossl_prov_read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
88                              OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
89 {
90     BIO *in = bio_new_from_core_bio(provctx, cin);
91     EVP_PKEY *pkey = NULL;
92     struct pwdata_st pwdata;
93
94     pwdata.pw_cb = pw_cb;
95     pwdata.pw_cbarg = pw_cbarg;
96     pkey = b2i_PVK_bio(in, pw_pem_password_to_ossl_passhrase, &pwdata);
97
98     BIO_free(in);
99     return pkey;
100 }
101 # endif
102 #endif
103
104 int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
105                           unsigned char *input_der, long input_der_len,
106                           OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
107 {
108     const unsigned char *derp;
109     X509_SIG *p8 = NULL;
110     int ok = 0;
111
112     if (!ossl_assert(new_der != NULL && *new_der == NULL)
113         || !ossl_assert(new_der_len != NULL))
114         return 0;
115
116     derp = input_der;
117     if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
118         char pbuf[PEM_BUFSIZE];
119         size_t plen = 0;
120
121         if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
122             ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
123         } else {
124             const X509_ALGOR *alg = NULL;
125             const ASN1_OCTET_STRING *oct = NULL;
126             int len = 0;
127
128             X509_SIG_get0(p8, &alg, &oct);
129             if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
130                                  new_der, &len, 0) != NULL)
131                 ok = 1;
132             *new_der_len = len;
133         }
134     }
135     X509_SIG_free(p8);
136     return ok;
137 }