2 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/core_names.h>
11 #include <openssl/core_object.h>
12 #include <openssl/provider.h>
13 #include <openssl/evp.h>
14 #include <openssl/ui.h>
15 #include <openssl/decoder.h>
16 #include <openssl/safestack.h>
17 #include <openssl/trace.h>
18 #include "crypto/evp.h"
19 #include "crypto/decoder.h"
20 #include "encoder_local.h"
21 #include "e_os.h" /* strcasecmp on Windows */
23 int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX
*ctx
,
24 const unsigned char *kstr
,
27 return ossl_pw_set_passphrase(&ctx
->pwdata
, kstr
, klen
);
30 int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX
*ctx
,
31 const UI_METHOD
*ui_method
,
34 return ossl_pw_set_ui_method(&ctx
->pwdata
, ui_method
, ui_data
);
37 int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX
*ctx
,
38 pem_password_cb
*cb
, void *cbarg
)
40 return ossl_pw_set_pem_password_cb(&ctx
->pwdata
, cb
, cbarg
);
43 int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX
*ctx
,
44 OSSL_PASSPHRASE_CALLBACK
*cb
,
47 return ossl_pw_set_ossl_passphrase_cb(&ctx
->pwdata
, cb
, cbarg
);
51 * Support for OSSL_DECODER_CTX_new_for_pkey:
52 * The construct data, and collecting keymgmt information for it
55 DEFINE_STACK_OF(EVP_KEYMGMT
)
57 struct decoder_pkey_data_st
{
61 char *object_type
; /* recorded object data type, may be NULL */
62 void **object
; /* Where the result should end up */
65 static int decoder_construct_pkey(OSSL_DECODER_INSTANCE
*decoder_inst
,
66 const OSSL_PARAM
*params
,
69 struct decoder_pkey_data_st
*data
= construct_data
;
70 OSSL_DECODER
*decoder
= OSSL_DECODER_INSTANCE_get_decoder(decoder_inst
);
71 void *decoderctx
= OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst
);
72 EVP_KEYMGMT
*keymgmt
= NULL
;
74 * |object_ref| points to a provider reference to an object, its exact
75 * contents entirely opaque to us, but may be passed to any provider
76 * function that expects this (such as OSSL_FUNC_keymgmt_load().
78 * This pointer is considered volatile, i.e. whatever it points at
79 * is assumed to be freed as soon as this function returns.
81 void *object_ref
= NULL
;
82 size_t object_ref_sz
= 0;
85 p
= OSSL_PARAM_locate_const(params
, OSSL_OBJECT_PARAM_DATA_TYPE
);
87 char *object_type
= NULL
;
89 if (!OSSL_PARAM_get_utf8_string(p
, &object_type
, 0))
91 OPENSSL_free(data
->object_type
);
92 data
->object_type
= object_type
;
96 * For stuff that should end up in an EVP_PKEY, we only accept an object
97 * reference for the moment. This enforces that the key data itself
98 * remains with the provider.
100 p
= OSSL_PARAM_locate_const(params
, OSSL_OBJECT_PARAM_REFERENCE
);
101 if (p
== NULL
|| p
->data_type
!= OSSL_PARAM_OCTET_STRING
)
103 object_ref
= p
->data
;
104 object_ref_sz
= p
->data_size
;
106 keymgmt
= EVP_KEYMGMT_fetch(data
->libctx
, data
->object_type
, data
->propq
);
108 if (keymgmt
!= NULL
) {
109 EVP_PKEY
*pkey
= NULL
;
110 void *keydata
= NULL
;
111 const OSSL_PROVIDER
*keymgmt_prov
= EVP_KEYMGMT_get0_provider(keymgmt
);
112 const OSSL_PROVIDER
*decoder_prov
= OSSL_DECODER_get0_provider(decoder
);
115 * If the EVP_KEYMGMT and the OSSL_DECODER are from the
116 * same provider, we assume that the KEYMGMT has a key loading
117 * function that can handle the provider reference we hold.
119 * Otherwise, we export from the decoder and import the
120 * result in the keymgmt.
122 if (keymgmt_prov
== decoder_prov
) {
123 keydata
= evp_keymgmt_load(keymgmt
, object_ref
, object_ref_sz
);
125 struct evp_keymgmt_util_try_import_data_st import_data
;
127 import_data
.keymgmt
= keymgmt
;
128 import_data
.keydata
= NULL
;
129 import_data
.selection
= OSSL_KEYMGMT_SELECT_ALL
;
132 * No need to check for errors here, the value of
133 * |import_data.keydata| is as much an indicator.
135 (void)decoder
->export_object(decoderctx
,
136 object_ref
, object_ref_sz
,
137 &evp_keymgmt_util_try_import
,
139 keydata
= import_data
.keydata
;
140 import_data
.keydata
= NULL
;
144 && (pkey
= evp_keymgmt_util_make_pkey(keymgmt
, keydata
)) == NULL
)
145 evp_keymgmt_freedata(keymgmt
, keydata
);
147 *data
->object
= pkey
;
150 * evp_keymgmt_util_make_pkey() increments the reference count when
151 * assigning the EVP_PKEY, so we can free the keymgmt here.
153 EVP_KEYMGMT_free(keymgmt
);
156 * We successfully looked through, |*ctx->object| determines if we
157 * actually found something.
159 return (*data
->object
!= NULL
);
162 static void decoder_clean_pkey_construct_arg(void *construct_data
)
164 struct decoder_pkey_data_st
*data
= construct_data
;
167 OPENSSL_free(data
->propq
);
168 OPENSSL_free(data
->object_type
);
173 static void collect_name(const char *name
, void *arg
)
175 STACK_OF(OPENSSL_CSTRING
) *names
= arg
;
177 sk_OPENSSL_CSTRING_push(names
, name
);
180 static void collect_keymgmt(EVP_KEYMGMT
*keymgmt
, void *arg
)
182 STACK_OF(EVP_KEYMGMT
) *keymgmts
= arg
;
184 if (!EVP_KEYMGMT_up_ref(keymgmt
) /* ref++ */)
186 if (sk_EVP_KEYMGMT_push(keymgmts
, keymgmt
) <= 0) {
187 EVP_KEYMGMT_free(keymgmt
); /* ref-- */
193 * The input structure check is only done on the initial decoder
196 static int decoder_check_input_structure(OSSL_DECODER_CTX
*ctx
,
197 OSSL_DECODER_INSTANCE
*di
)
199 int di_is_was_set
= 0;
201 OSSL_DECODER_INSTANCE_get_input_structure(di
, &di_is_was_set
);
204 * If caller didn't give an input structure name, the decoder is accepted
205 * unconditionally with regards to the input structure.
207 if (ctx
->input_structure
== NULL
)
210 * If the caller did give an input structure name, the decoder must have
211 * a matching input structure to be accepted.
213 if (di_is
!= NULL
&& strcasecmp(ctx
->input_structure
, di_is
) == 0)
218 struct collect_decoder_data_st
{
219 STACK_OF(OPENSSL_CSTRING
) *names
;
220 OSSL_DECODER_CTX
*ctx
;
222 unsigned int error_occurred
:1;
225 static void collect_decoder(OSSL_DECODER
*decoder
, void *arg
)
227 struct collect_decoder_data_st
*data
= arg
;
229 const OSSL_PROVIDER
*prov
= OSSL_DECODER_get0_provider(decoder
);
230 void *provctx
= OSSL_PROVIDER_get0_provider_ctx(prov
);
232 if (data
->error_occurred
)
235 if (data
->names
== NULL
) {
236 data
->error_occurred
= 1;
241 * Either the caller didn't give a selection, or if they did,
242 * the decoder must tell us if it supports that selection to
243 * be accepted. If the decoder doesn't have |does_selection|,
244 * it's seen as taking anything.
246 if (decoder
->does_selection
!= NULL
247 && !decoder
->does_selection(provctx
, data
->ctx
->selection
))
250 end_i
= sk_OPENSSL_CSTRING_num(data
->names
);
251 for (i
= 0; i
< end_i
; i
++) {
252 const char *name
= sk_OPENSSL_CSTRING_value(data
->names
, i
);
254 if (OSSL_DECODER_is_a(decoder
, name
)) {
255 void *decoderctx
= NULL
;
256 OSSL_DECODER_INSTANCE
*di
= NULL
;
258 if ((decoderctx
= decoder
->newctx(provctx
)) == NULL
) {
259 data
->error_occurred
= 1;
262 if ((di
= ossl_decoder_instance_new(decoder
, decoderctx
)) == NULL
) {
263 decoder
->freectx(decoderctx
);
264 data
->error_occurred
= 1;
268 OSSL_TRACE_BEGIN(DECODER
) {
270 "(ctx %p) Checking out decoder %p:\n"
272 (void *)data
->ctx
, (void *)decoder
,
273 OSSL_DECODER_get0_name(decoder
),
274 OSSL_DECODER_get0_properties(decoder
));
275 } OSSL_TRACE_END(DECODER
);
277 if (!decoder_check_input_structure(data
->ctx
, di
)) {
278 OSSL_TRACE_BEGIN(DECODER
) {
280 " REJECTED: not the desired input structure\n");
281 } OSSL_TRACE_END(DECODER
);
282 ossl_decoder_instance_free(di
);
283 /* Not a fatal error. Just return */
286 if (!ossl_decoder_ctx_add_decoder_inst(data
->ctx
, di
)) {
287 ossl_decoder_instance_free(di
);
288 data
->error_occurred
= 1;
297 /* Decoder not suitable - but not a fatal error */
298 data
->error_occurred
= 0;
301 int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX
*ctx
,
302 EVP_PKEY
**pkey
, const char *keytype
,
303 OSSL_LIB_CTX
*libctx
,
304 const char *propquery
)
306 struct decoder_pkey_data_st
*process_data
= NULL
;
307 STACK_OF(EVP_KEYMGMT
) *keymgmts
= NULL
;
308 STACK_OF(OPENSSL_CSTRING
) *names
= NULL
;
313 && (strcmp(keytype
, "id-ecPublicKey") == 0
314 || strcmp(keytype
, "1.2.840.10045.2.1") == 0))
317 if ((process_data
= OPENSSL_zalloc(sizeof(*process_data
))) == NULL
318 || (propquery
!= NULL
319 && (process_data
->propq
= OPENSSL_strdup(propquery
)) == NULL
)
320 || (keymgmts
= sk_EVP_KEYMGMT_new_null()) == NULL
321 || (names
= sk_OPENSSL_CSTRING_new_null()) == NULL
) {
322 ERR_raise(ERR_LIB_OSSL_DECODER
, ERR_R_MALLOC_FAILURE
);
326 process_data
->object
= (void **)pkey
;
327 process_data
->libctx
= libctx
;
329 /* First, find all keymgmts to form goals */
330 EVP_KEYMGMT_do_all_provided(libctx
, collect_keymgmt
, keymgmts
);
332 /* Then, we collect all the keymgmt names */
333 while (sk_EVP_KEYMGMT_num(keymgmts
) > 0) {
334 EVP_KEYMGMT
*keymgmt
= sk_EVP_KEYMGMT_shift(keymgmts
);
337 * If the key type is given by the caller, we only use the matching
338 * KEYMGMTs, otherwise we use them all.
339 * We have to special case SM2 here because of its abuse of the EC OID.
340 * The EC OID can be used to identify an EC key or an SM2 key - so if
341 * we have seen that OID we try both key types
344 || EVP_KEYMGMT_is_a(keymgmt
, keytype
)
345 || (isecoid
&& EVP_KEYMGMT_is_a(keymgmt
, "SM2"))) {
346 if (!EVP_KEYMGMT_names_do_all(keymgmt
, collect_name
, names
)) {
347 ERR_raise(ERR_LIB_OSSL_DECODER
, ERR_R_INTERNAL_ERROR
);
352 EVP_KEYMGMT_free(keymgmt
);
354 sk_EVP_KEYMGMT_free(keymgmts
);
358 * Finally, find all decoders that have any keymgmt of the collected
362 struct collect_decoder_data_st collect_decoder_data
= { NULL
, };
364 collect_decoder_data
.names
= names
;
365 collect_decoder_data
.ctx
= ctx
;
366 OSSL_DECODER_do_all_provided(libctx
,
367 collect_decoder
, &collect_decoder_data
);
368 sk_OPENSSL_CSTRING_free(names
);
371 if (collect_decoder_data
.error_occurred
)
375 if (OSSL_DECODER_CTX_get_num_decoders(ctx
) != 0) {
376 if (!OSSL_DECODER_CTX_set_construct(ctx
, decoder_construct_pkey
)
377 || !OSSL_DECODER_CTX_set_construct_data(ctx
, process_data
)
378 || !OSSL_DECODER_CTX_set_cleanup(ctx
,
379 decoder_clean_pkey_construct_arg
))
382 process_data
= NULL
; /* Avoid it being freed */
387 decoder_clean_pkey_construct_arg(process_data
);
388 sk_EVP_KEYMGMT_pop_free(keymgmts
, EVP_KEYMGMT_free
);
389 sk_OPENSSL_CSTRING_free(names
);
395 OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY
**pkey
,
396 const char *input_type
,
397 const char *input_structure
,
398 const char *keytype
, int selection
,
399 OSSL_LIB_CTX
*libctx
, const char *propquery
)
401 OSSL_DECODER_CTX
*ctx
= NULL
;
403 if ((ctx
= OSSL_DECODER_CTX_new()) == NULL
) {
404 ERR_raise(ERR_LIB_OSSL_DECODER
, ERR_R_MALLOC_FAILURE
);
408 OSSL_TRACE_BEGIN(DECODER
) {
410 "(ctx %p) Looking for %s decoders with selection %d\n",
411 (void *)ctx
, keytype
, selection
);
412 BIO_printf(trc_out
, " input type: %s, input structure: %s\n",
413 input_type
, input_structure
);
414 } OSSL_TRACE_END(DECODER
);
416 if (OSSL_DECODER_CTX_set_input_type(ctx
, input_type
)
417 && OSSL_DECODER_CTX_set_input_structure(ctx
, input_structure
)
418 && OSSL_DECODER_CTX_set_selection(ctx
, selection
)
419 && ossl_decoder_ctx_setup_for_pkey(ctx
, pkey
, keytype
,
421 && OSSL_DECODER_CTX_add_extra(ctx
, libctx
, propquery
)) {
422 OSSL_TRACE_BEGIN(DECODER
) {
423 BIO_printf(trc_out
, "(ctx %p) Got %d decoders\n",
424 (void *)ctx
, OSSL_DECODER_CTX_get_num_decoders(ctx
));
425 } OSSL_TRACE_END(DECODER
);
429 OSSL_DECODER_CTX_free(ctx
);