]>
Commit | Line | Data |
---|---|---|
37d398c1 RL |
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 | * 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/params.h> | |
20 | #include <openssl/x509.h> | |
21 | #include "internal/pem.h" /* For PVK and "blob" PEM headers */ | |
22 | #include "prov/bio.h" | |
23 | #include "prov/implementations.h" | |
ece9304c | 24 | #include "encoder_local.h" |
37d398c1 | 25 | |
ece9304c RL |
26 | static OSSL_FUNC_decoder_freectx_fn ms2key_freectx; |
27 | static OSSL_FUNC_decoder_gettable_params_fn ms2key_gettable_params; | |
28 | static OSSL_FUNC_decoder_get_params_fn msblob2key_get_params; | |
37d398c1 | 29 | #ifndef OPENSSL_NO_RC4 |
ece9304c | 30 | static OSSL_FUNC_decoder_get_params_fn pvk2key_get_params; |
37d398c1 | 31 | #endif |
ece9304c | 32 | static OSSL_FUNC_decoder_decode_fn msblob2key_decode; |
37d398c1 | 33 | #ifndef OPENSSL_NO_RC4 |
ece9304c | 34 | static OSSL_FUNC_decoder_decode_fn pvk2key_decode; |
37d398c1 | 35 | #endif |
ece9304c | 36 | static OSSL_FUNC_decoder_export_object_fn ms2key_export_object; |
37d398c1 RL |
37 | |
38 | typedef void *(extract_key_fn)(EVP_PKEY *); | |
39 | typedef void (free_key_fn)(void *); | |
40 | struct keytype_desc_st { | |
41 | int type; /* EVP key type */ | |
42 | const char *name; /* Keytype */ | |
43 | const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ | |
44 | ||
45 | /* | |
46 | * These must be the correct EVP_PKEY_get1_{TYPE}() and {TYPE}_free() | |
47 | * function for the key. | |
48 | */ | |
49 | extract_key_fn *extract_key; | |
50 | free_key_fn *free_key; | |
51 | }; | |
52 | ||
53 | /* | |
ece9304c | 54 | * Context used for DER to key decoding. |
37d398c1 RL |
55 | */ |
56 | struct ms2key_ctx_st { | |
57 | PROV_CTX *provctx; | |
58 | const struct keytype_desc_st *desc; | |
59 | }; | |
60 | ||
61 | static struct ms2key_ctx_st * | |
62 | ms2key_newctx(void *provctx, const struct keytype_desc_st *desc) | |
63 | { | |
64 | struct ms2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); | |
65 | ||
66 | if (ctx != NULL) { | |
67 | ctx->provctx = provctx; | |
68 | ctx->desc = desc; | |
69 | } | |
70 | return ctx; | |
71 | } | |
72 | ||
73 | static void ms2key_freectx(void *vctx) | |
74 | { | |
75 | struct ms2key_ctx_st *ctx = vctx; | |
76 | ||
77 | OPENSSL_free(ctx); | |
78 | } | |
79 | ||
4df0d37f | 80 | static const OSSL_PARAM *ms2key_gettable_params(ossl_unused void *provctx) |
37d398c1 RL |
81 | { |
82 | static const OSSL_PARAM gettables[] = { | |
ece9304c | 83 | { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, |
37d398c1 RL |
84 | OSSL_PARAM_END, |
85 | }; | |
86 | ||
87 | return gettables; | |
88 | } | |
89 | ||
90 | static int msblob2key_get_params(OSSL_PARAM params[]) | |
91 | { | |
92 | OSSL_PARAM *p; | |
93 | ||
ece9304c | 94 | p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); |
37d398c1 RL |
95 | if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "MSBLOB")) |
96 | return 0; | |
97 | ||
98 | return 1; | |
99 | } | |
100 | ||
101 | #ifndef OPENSSL_NO_RC4 | |
102 | static int pvk2key_get_params(OSSL_PARAM params[]) | |
103 | { | |
104 | OSSL_PARAM *p; | |
105 | ||
ece9304c | 106 | p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); |
37d398c1 RL |
107 | if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "PVK")) |
108 | return 0; | |
109 | ||
110 | return 1; | |
111 | } | |
112 | #endif | |
113 | ||
114 | static int ms2key_post(struct ms2key_ctx_st *ctx, EVP_PKEY *pkey, | |
115 | OSSL_CALLBACK *data_cb, void *data_cbarg) | |
116 | { | |
117 | void *key = NULL; | |
118 | int ok = 0; | |
119 | ||
120 | if (pkey != NULL) { | |
121 | /* | |
122 | * Tear out the low-level key pointer from the pkey, | |
123 | * but only if it matches the expected key type. | |
124 | * | |
125 | * TODO(3.0): The check should be done with EVP_PKEY_is_a(), but | |
126 | * as long as we still have #legacy internal keys, it's safer to | |
127 | * use the type numbers in side the provider. | |
128 | */ | |
129 | if (EVP_PKEY_id(pkey) == ctx->desc->type) | |
130 | key = ctx->desc->extract_key(pkey); | |
131 | } | |
132 | ||
133 | if (key != NULL) { | |
134 | OSSL_PARAM params[3]; | |
135 | ||
136 | params[0] = | |
ece9304c | 137 | OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_DATA_TYPE, |
37d398c1 RL |
138 | (char *)ctx->desc->name, 0); |
139 | /* The address of the key becomes the octet string */ | |
140 | params[1] = | |
ece9304c | 141 | OSSL_PARAM_construct_octet_string(OSSL_DECODER_PARAM_REFERENCE, |
37d398c1 RL |
142 | &key, sizeof(key)); |
143 | params[2] = OSSL_PARAM_construct_end(); | |
144 | ||
145 | ok = data_cb(params, data_cbarg); | |
146 | } | |
147 | ctx->desc->free_key(key); | |
148 | ||
149 | return ok; | |
150 | } | |
151 | ||
ece9304c RL |
152 | static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin, |
153 | OSSL_CALLBACK *data_cb, void *data_cbarg, | |
154 | OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) | |
37d398c1 RL |
155 | { |
156 | struct ms2key_ctx_st *ctx = vctx; | |
157 | int ispub = -1; | |
158 | EVP_PKEY *pkey = ossl_prov_read_msblob(ctx->provctx, cin, &ispub); | |
159 | int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg); | |
160 | ||
161 | EVP_PKEY_free(pkey); | |
162 | return ok; | |
163 | } | |
164 | ||
165 | #ifndef OPENSSL_NO_RC4 | |
ece9304c RL |
166 | static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin, |
167 | OSSL_CALLBACK *data_cb, void *data_cbarg, | |
168 | OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) | |
37d398c1 RL |
169 | { |
170 | struct ms2key_ctx_st *ctx = vctx; | |
171 | EVP_PKEY *pkey = ossl_prov_read_pvk(ctx->provctx, cin, pw_cb, pw_cbarg); | |
172 | int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg); | |
173 | ||
174 | EVP_PKEY_free(pkey); | |
175 | return ok; | |
176 | } | |
177 | #endif | |
178 | ||
179 | static int ms2key_export_object(void *vctx, | |
ece9304c RL |
180 | const void *reference, size_t reference_sz, |
181 | OSSL_CALLBACK *export_cb, void *export_cbarg) | |
37d398c1 RL |
182 | { |
183 | struct ms2key_ctx_st *ctx = vctx; | |
184 | OSSL_FUNC_keymgmt_export_fn *export = | |
185 | ossl_prov_get_keymgmt_export(ctx->desc->fns); | |
186 | void *keydata; | |
187 | ||
188 | if (reference_sz == sizeof(keydata) && export != NULL) { | |
189 | /* The contents of the reference is the address to our object */ | |
190 | keydata = *(void **)reference; | |
191 | ||
192 | return export(keydata, OSSL_KEYMGMT_SELECT_ALL, | |
193 | export_cb, export_cbarg); | |
194 | } | |
195 | return 0; | |
196 | } | |
197 | ||
198 | #define IMPLEMENT_TYPE(KEYTYPEstr, KEYTYPE, keytype, extract, free) \ | |
199 | static const struct keytype_desc_st keytype##_desc; \ | |
ece9304c | 200 | static OSSL_FUNC_decoder_newctx_fn ms2##keytype##_newctx; \ |
37d398c1 RL |
201 | static void *ms2##keytype##_newctx(void *provctx) \ |
202 | { \ | |
203 | return ms2key_newctx(provctx, &keytype##_desc); \ | |
204 | } \ | |
205 | static const struct keytype_desc_st keytype##_desc = \ | |
206 | { EVP_PKEY_##KEYTYPE, KEYTYPEstr, keytype##_keymgmt_functions, \ | |
207 | (extract_key_fn *)extract, \ | |
208 | (free_key_fn *)free } | |
209 | ||
210 | #define IMPLEMENT_MS(mstype, keytype) \ | |
211 | const OSSL_DISPATCH \ | |
ece9304c RL |
212 | mstype##_to_##keytype##_decoder_functions[] = { \ |
213 | { OSSL_FUNC_DECODER_NEWCTX, \ | |
37d398c1 | 214 | (void (*)(void))ms2##keytype##_newctx }, \ |
ece9304c | 215 | { OSSL_FUNC_DECODER_FREECTX, \ |
37d398c1 | 216 | (void (*)(void))ms2key_freectx }, \ |
ece9304c | 217 | { OSSL_FUNC_DECODER_GETTABLE_PARAMS, \ |
37d398c1 | 218 | (void (*)(void))ms2key_gettable_params }, \ |
ece9304c | 219 | { OSSL_FUNC_DECODER_GET_PARAMS, \ |
37d398c1 | 220 | (void (*)(void))mstype##2key_get_params }, \ |
ece9304c RL |
221 | { OSSL_FUNC_DECODER_DECODE, \ |
222 | (void (*)(void))mstype##2key_decode }, \ | |
223 | { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ | |
37d398c1 RL |
224 | (void (*)(void))ms2key_export_object }, \ |
225 | { 0, NULL } \ | |
226 | } | |
227 | ||
228 | #ifndef OPENSSL_NO_DSA | |
229 | IMPLEMENT_TYPE("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free); | |
230 | IMPLEMENT_MS(msblob, dsa); | |
231 | # ifndef OPENSSL_NO_RC4 | |
232 | IMPLEMENT_MS(pvk, dsa); | |
233 | # endif | |
234 | #endif | |
235 | IMPLEMENT_TYPE("RSA", RSA, rsa, EVP_PKEY_get1_RSA, RSA_free); | |
236 | IMPLEMENT_MS(msblob, rsa); | |
237 | #ifndef OPENSSL_NO_RC4 | |
238 | IMPLEMENT_MS(pvk, rsa); | |
239 | #endif |