1/* 2 * Copyright 2020-2025 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{- 10use OpenSSL::paramnames qw(produce_param_decoder); 11-} 12 13#include <openssl/core.h> 14#include <openssl/core_dispatch.h> 15#include <openssl/core_names.h> 16#include <openssl/core_object.h> 17#include <openssl/asn1.h> 18#include <openssl/err.h> 19#include <openssl/objects.h> 20#include <openssl/pkcs12.h> 21#include <openssl/x509.h> 22#include <openssl/proverr.h> 23#include "internal/cryptlib.h" 24#include "internal/asn1.h" 25#include "internal/sizes.h" 26#include "prov/bio.h" 27#include "prov/decoders.h" 28#include "prov/implementations.h" 29#include "prov/endecoder_local.h" 30 31static OSSL_FUNC_decoder_newctx_fn epki2pki_newctx; 32static OSSL_FUNC_decoder_freectx_fn epki2pki_freectx; 33static OSSL_FUNC_decoder_decode_fn epki2pki_decode; 34static OSSL_FUNC_decoder_settable_ctx_params_fn epki2pki_settable_ctx_params; 35static OSSL_FUNC_decoder_set_ctx_params_fn epki2pki_set_ctx_params; 36 37/* 38 * Context used for EncryptedPrivateKeyInfo to PrivateKeyInfo decoding. 39 */ 40struct epki2pki_ctx_st { 41 PROV_CTX *provctx; 42 char propq[OSSL_MAX_PROPQUERY_SIZE]; 43}; 44 45static void *epki2pki_newctx(void *provctx) 46{ 47 struct epki2pki_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); 48 49 if (ctx != NULL) 50 ctx->provctx = provctx; 51 return ctx; 52} 53 54static void epki2pki_freectx(void *vctx) 55{ 56 struct epki2pki_ctx_st *ctx = vctx; 57 58 OPENSSL_free(ctx); 59} 60 61{- produce_param_decoder('epki2pki_set_ctx_params', 62 (['DECODER_PARAM_PROPERTIES', 'propq', 'utf8_string'], 63 )); -} 64 65static const OSSL_PARAM *epki2pki_settable_ctx_params(ossl_unused void *provctx) 66{ 67 return epki2pki_set_ctx_params_list; 68} 69 70static int epki2pki_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 71{ 72 struct epki2pki_ctx_st *ctx = vctx; 73 struct epki2pki_set_ctx_params_st p; 74 char *str; 75 76 if (ctx == NULL || !epki2pki_set_ctx_params_decoder(params, &p)) 77 return 0; 78 79 str = ctx->propq; 80 if (p.propq != NULL 81 && !OSSL_PARAM_get_utf8_string(p.propq, &str, sizeof(ctx->propq))) 82 return 0; 83 84 return 1; 85} 86 87/* 88 * The selection parameter in epki2pki_decode() is not used by this function 89 * because it's not relevant just to decode EncryptedPrivateKeyInfo to 90 * PrivateKeyInfo. 91 */ 92static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, 93 OSSL_CALLBACK *data_cb, void *data_cbarg, 94 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) 95{ 96 struct epki2pki_ctx_st *ctx = vctx; 97 BUF_MEM *mem = NULL; 98 unsigned char *der = NULL; 99 long der_len = 0; 100 BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin); 101 int ok = 0; 102 103 if (in == NULL) 104 return 0; 105 106 ok = (asn1_d2i_read_bio(in, &mem) >= 0); 107 BIO_free(in); 108 109 /* We return "empty handed". This is not an error. */ 110 if (!ok) 111 return 1; 112 113 der = (unsigned char *)mem->data; 114 der_len = (long)mem->length; 115 OPENSSL_free(mem); 116 117 ok = ossl_epki2pki_der_decode(der, der_len, selection, data_cb, data_cbarg, 118 pw_cb, pw_cbarg, PROV_LIBCTX_OF(ctx->provctx), 119 ctx->propq); 120 OPENSSL_free(der); 121 return ok; 122} 123 124int ossl_epki2pki_der_decode(unsigned char *der, long der_len, int selection, 125 OSSL_CALLBACK *data_cb, void *data_cbarg, 126 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg, 127 OSSL_LIB_CTX *libctx, const char *propq) 128{ 129 const unsigned char *pder = der; 130 unsigned char *new_der = NULL; 131 X509_SIG *p8 = NULL; 132 PKCS8_PRIV_KEY_INFO *p8inf = NULL; 133 const X509_ALGOR *alg = NULL; 134 int ok = 1; /* Assume good */ 135 136 ERR_set_mark(); 137 if ((p8 = d2i_X509_SIG(NULL, &pder, der_len)) != NULL) { 138 char pbuf[1024]; 139 size_t plen = 0; 140 141 ERR_clear_last_mark(); 142 143 if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) { 144 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE); 145 ok = 0; 146 } else { 147 const ASN1_OCTET_STRING *oct; 148 int new_der_len = 0; 149 150 X509_SIG_get0(p8, &alg, &oct); 151 if (!PKCS12_pbe_crypt_ex(alg, pbuf, (int)plen, 152 oct->data, oct->length, 153 &new_der, &new_der_len, 0, 154 libctx, propq)) { 155 ok = 0; 156 } else { 157 der = new_der; 158 der_len = new_der_len; 159 } 160 alg = NULL; 161 } 162 X509_SIG_free(p8); 163 } else { 164 ERR_pop_to_mark(); 165 } 166 167 ERR_set_mark(); 168 pder = der; 169 p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &pder, der_len); 170 ERR_pop_to_mark(); 171 172 if (p8inf != NULL && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)) { 173 /* 174 * We have something and recognised it as PrivateKeyInfo, so let's 175 * pass all the applicable data to the callback. 176 */ 177 char keytype[OSSL_MAX_NAME_SIZE]; 178 OSSL_PARAM params[6], *p = params; 179 int objtype = OSSL_OBJECT_PKEY; 180 181 OBJ_obj2txt(keytype, sizeof(keytype), alg->algorithm, 0); 182 183 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, 184 keytype, 0); 185 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_INPUT_TYPE, 186 "DER", 0); 187 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, 188 "PrivateKeyInfo", 0); 189 *p++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, 190 der, der_len); 191 *p++ = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype); 192 *p = OSSL_PARAM_construct_end(); 193 194 ok = data_cb(params, data_cbarg); 195 } 196 PKCS8_PRIV_KEY_INFO_free(p8inf); 197 OPENSSL_free(new_der); 198 return ok; 199} 200 201const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions[] = { 202 { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))epki2pki_newctx }, 203 { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))epki2pki_freectx }, 204 { OSSL_FUNC_DECODER_DECODE, (void (*)(void))epki2pki_decode }, 205 { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, 206 (void (*)(void))epki2pki_settable_ctx_params }, 207 { OSSL_FUNC_DECODER_SET_CTX_PARAMS, 208 (void (*)(void))epki2pki_set_ctx_params }, 209 OSSL_DISPATCH_END 210}; 211