diff options
Diffstat (limited to 'providers/implementations/encode_decode/decode_pem2der.c')
-rw-r--r-- | providers/implementations/encode_decode/decode_pem2der.c | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c index bc937ffb9d27..abea679fe19a 100644 --- a/providers/implementations/encode_decode/decode_pem2der.c +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,7 +24,9 @@ #include <openssl/pem.h> #include <openssl/proverr.h> #include "internal/nelem.h" +#include "internal/sizes.h" #include "prov/bio.h" +#include "prov/decoders.h" #include "prov/implementations.h" #include "endecoder_local.h" @@ -52,6 +54,8 @@ static OSSL_FUNC_decoder_decode_fn pem2der_decode; */ struct pem2der_ctx_st { PROV_CTX *provctx; + char data_structure[OSSL_MAX_CODEC_STRUCT_SIZE]; + char propq[OSSL_MAX_PROPQUERY_SIZE]; }; static void *pem2der_newctx(void *provctx) @@ -70,6 +74,37 @@ static void pem2der_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *pem2der_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int pem2der_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct pem2der_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + str = ctx->propq; + if (p != NULL + && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_STRUCTURE); + str = ctx->data_structure; + if (p != NULL + && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->data_structure))) + return 0; + + return 1; +} + /* pem_password_cb compatible function */ struct pem2der_pass_data_st { OSSL_PASSPHRASE_CALLBACK *cb; @@ -88,10 +123,6 @@ static int pem2der_pass_helper(char *buf, int num, int w, void *data) return (int)plen; } -/* - * The selection parameter in pem2der_decode() is not used by this function - * because it's not relevant just to decode PEM to DER. - */ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *data_cb, void *data_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) @@ -109,8 +140,9 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, /* PKCS#8 and SubjectPublicKeyInfo */ { PEM_STRING_PKCS8, OSSL_OBJECT_PKEY, NULL, "EncryptedPrivateKeyInfo" }, { PEM_STRING_PKCS8INF, OSSL_OBJECT_PKEY, NULL, "PrivateKeyInfo" }, +#define PKCS8_LAST_IDX 1 { PEM_STRING_PUBLIC, OSSL_OBJECT_PKEY, NULL, "SubjectPublicKeyInfo" }, - +#define SPKI_LAST_IDX 2 /* Our set of type specific PEM types */ { PEM_STRING_DHPARAMS, OSSL_OBJECT_PKEY, "DH", "type-specific" }, { PEM_STRING_DHXPARAMS, OSSL_OBJECT_PKEY, "X9.42 DH", "type-specific" }, @@ -119,6 +151,7 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, { PEM_STRING_DSAPARAMS, OSSL_OBJECT_PKEY, "DSA", "type-specific" }, { PEM_STRING_ECPRIVATEKEY, OSSL_OBJECT_PKEY, "EC", "type-specific" }, { PEM_STRING_ECPARAMETERS, OSSL_OBJECT_PKEY, "EC", "type-specific" }, + { PEM_STRING_SM2PARAMETERS, OSSL_OBJECT_PKEY, "SM2", "type-specific" }, { PEM_STRING_RSA, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, { PEM_STRING_RSA_PUBLIC, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, @@ -182,6 +215,31 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, char *data_type = (char *)pem_name_map[i].data_type; char *data_structure = (char *)pem_name_map[i].data_structure; + /* + * Since this may perform decryption, we need to check the selection to + * avoid password prompts for objects of no interest. + */ + if (i <= PKCS8_LAST_IDX + && ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) + || OPENSSL_strcasecmp(ctx->data_structure, "EncryptedPrivateKeyInfo") == 0 + || OPENSSL_strcasecmp(ctx->data_structure, "PrivateKeyInfo") == 0)) { + ok = ossl_epki2pki_der_decode(der, der_len, selection, data_cb, + data_cbarg, pw_cb, pw_cbarg, + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); + goto end; + } + + if (i <= SPKI_LAST_IDX + && ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) + || OPENSSL_strcasecmp(ctx->data_structure, "SubjectPublicKeyInfo") == 0)) { + ok = ossl_spki2typespki_der_decode(der, der_len, selection, data_cb, + data_cbarg, pw_cb, pw_cbarg, + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); + goto end; + } + objtype = pem_name_map[i].object_type; if (data_type != NULL) *p++ = @@ -215,5 +273,9 @@ const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[] = { { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))pem2der_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))pem2der_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))pem2der_decode }, - { 0, NULL } + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, + (void (*)(void))pem2der_settable_ctx_params }, + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, + (void (*)(void))pem2der_set_ctx_params }, + OSSL_DISPATCH_END }; |