1/* 2 * Copyright 2020-2023 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/* 14 * low level APIs are deprecated for public use, but still ok for 15 * internal use. 16 */ 17#include "internal/deprecated.h" 18 19#include <string.h> 20 21#include <openssl/core_dispatch.h> 22#include <openssl/core_names.h> 23#include <openssl/core_object.h> 24#include <openssl/crypto.h> 25#include <openssl/params.h> 26#include <openssl/err.h> 27#include <openssl/proverr.h> 28#include <openssl/pem.h> /* For public PVK functions */ 29#include <openssl/x509.h> 30#include "internal/cryptlib.h" 31#include "internal/passphrase.h" 32#include "internal/sizes.h" 33#include "crypto/pem.h" /* For internal PVK and "blob" headers */ 34#include "crypto/rsa.h" 35#include "prov/bio.h" 36#include "prov/implementations.h" 37#include "prov/endecoder_local.h" 38 39struct pvk2key_ctx_st; /* Forward declaration */ 40typedef int check_key_fn(void *, struct pvk2key_ctx_st *ctx); 41typedef void adjust_key_fn(void *, struct pvk2key_ctx_st *ctx); 42typedef void *b2i_PVK_of_bio_pw_fn(BIO *in, pem_password_cb *cb, void *u, 43 OSSL_LIB_CTX *libctx, const char *propq); 44typedef void free_key_fn(void *); 45struct keytype_desc_st { 46 int type; /* EVP key type */ 47 const char *name; /* Keytype */ 48 const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ 49 50 b2i_PVK_of_bio_pw_fn *read_private_key; 51 adjust_key_fn *adjust_key; 52 free_key_fn *free_key; 53}; 54 55static OSSL_FUNC_decoder_freectx_fn pvk2key_freectx; 56static OSSL_FUNC_decoder_decode_fn pvk2key_decode; 57static OSSL_FUNC_decoder_export_object_fn pvk2key_export_object; 58static OSSL_FUNC_decoder_settable_ctx_params_fn pvk2key_settable_ctx_params; 59static OSSL_FUNC_decoder_set_ctx_params_fn pvk2key_set_ctx_params; 60 61/* 62 * Context used for DER to key decoding. 63 */ 64struct pvk2key_ctx_st { 65 PROV_CTX *provctx; 66 char propq[OSSL_MAX_PROPQUERY_SIZE]; 67 const struct keytype_desc_st *desc; 68 /* The selection that is passed to der2key_decode() */ 69 int selection; 70}; 71 72static struct pvk2key_ctx_st * 73pvk2key_newctx(void *provctx, const struct keytype_desc_st *desc) 74{ 75 struct pvk2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); 76 77 if (ctx != NULL) { 78 ctx->provctx = provctx; 79 ctx->desc = desc; 80 } 81 return ctx; 82} 83 84static void pvk2key_freectx(void *vctx) 85{ 86 struct pvk2key_ctx_st *ctx = vctx; 87 88 OPENSSL_free(ctx); 89} 90 91{- produce_param_decoder('pvk2key_set_ctx_params', 92 (['DECODER_PARAM_PROPERTIES', 'propq', 'utf8_string'], 93 )); -} 94 95static const OSSL_PARAM *pvk2key_settable_ctx_params(ossl_unused void *provctx) 96{ 97 return pvk2key_set_ctx_params_list; 98} 99 100static int pvk2key_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 101{ 102 struct pvk2key_ctx_st *ctx = vctx; 103 struct pvk2key_set_ctx_params_st p; 104 char *str; 105 106 if (ctx == NULL || !pvk2key_set_ctx_params_decoder(params, &p)) 107 return 0; 108 109 str = ctx->propq; 110 if (p.propq != NULL 111 && !OSSL_PARAM_get_utf8_string(p.propq, &str, sizeof(ctx->propq))) 112 return 0; 113 114 return 1; 115} 116 117static int pvk2key_does_selection(void *provctx, int selection) 118{ 119 if (selection == 0) 120 return 1; 121 122 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 123 return 1; 124 125 return 0; 126} 127 128static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, 129 OSSL_CALLBACK *data_cb, void *data_cbarg, 130 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) 131{ 132 struct pvk2key_ctx_st *ctx = vctx; 133 BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin); 134 void *key = NULL; 135 int ok = 0; 136 137 if (in == NULL) 138 return 0; 139 140 ctx->selection = selection; 141 142 if ((selection == 0 143 || (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 144 && ctx->desc->read_private_key != NULL) { 145 struct ossl_passphrase_data_st pwdata; 146 int err, lib, reason; 147 148 memset(&pwdata, 0, sizeof(pwdata)); 149 if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg)) 150 goto end; 151 152 key = ctx->desc->read_private_key(in, ossl_pw_pvk_password, &pwdata, 153 PROV_LIBCTX_OF(ctx->provctx), 154 ctx->propq); 155 156 /* 157 * Because the PVK API doesn't have a separate decrypt call, we need 158 * to check the error queue for certain well known errors that are 159 * considered fatal and which we pass through, while the rest gets 160 * thrown away. 161 */ 162 err = ERR_peek_last_error(); 163 lib = ERR_GET_LIB(err); 164 reason = ERR_GET_REASON(err); 165 if (lib == ERR_LIB_PEM 166 && (reason == PEM_R_BAD_PASSWORD_READ 167 || reason == PEM_R_BAD_DECRYPT)) { 168 ERR_clear_last_mark(); 169 goto end; 170 } 171 172 if (selection != 0 && key == NULL) 173 goto next; 174 } 175 176 if (key != NULL && ctx->desc->adjust_key != NULL) 177 ctx->desc->adjust_key(key, ctx); 178 179 next: 180 /* 181 * Indicated that we successfully decoded something, or not at all. 182 * Ending up "empty handed" is not an error. 183 */ 184 ok = 1; 185 186 /* 187 * We free resources here so it's not held up during the callback, because 188 * we know the process is recursive and the allocated chunks of memory 189 * add up. 190 */ 191 BIO_free(in); 192 in = NULL; 193 194 if (key != NULL) { 195 OSSL_PARAM params[4]; 196 int object_type = OSSL_OBJECT_PKEY; 197 198 params[0] = 199 OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); 200 params[1] = 201 OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, 202 (char *)ctx->desc->name, 0); 203 /* The address of the key becomes the octet string */ 204 params[2] = 205 OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, 206 &key, sizeof(key)); 207 params[3] = OSSL_PARAM_construct_end(); 208 209 ok = data_cb(params, data_cbarg); 210 } 211 212 end: 213 BIO_free(in); 214 ctx->desc->free_key(key); 215 216 return ok; 217} 218 219static int pvk2key_export_object(void *vctx, 220 const void *reference, size_t reference_sz, 221 OSSL_CALLBACK *export_cb, void *export_cbarg) 222{ 223 struct pvk2key_ctx_st *ctx = vctx; 224 OSSL_FUNC_keymgmt_export_fn *export = 225 ossl_prov_get_keymgmt_export(ctx->desc->fns); 226 void *keydata; 227 228 if (reference_sz == sizeof(keydata) && export != NULL) { 229 int selection = ctx->selection; 230 231 if (selection == 0) 232 selection = OSSL_KEYMGMT_SELECT_ALL; 233 /* The contents of the reference is the address to our object */ 234 keydata = *(void **)reference; 235 236 return export(keydata, selection, export_cb, export_cbarg); 237 } 238 return 0; 239} 240 241/* ---------------------------------------------------------------------- */ 242 243#define dsa_private_key_bio (b2i_PVK_of_bio_pw_fn *)b2i_DSA_PVK_bio_ex 244#define dsa_adjust NULL 245#define dsa_free (void (*)(void *))DSA_free 246 247/* ---------------------------------------------------------------------- */ 248 249#define rsa_private_key_bio (b2i_PVK_of_bio_pw_fn *)b2i_RSA_PVK_bio_ex 250 251static void rsa_adjust(void *key, struct pvk2key_ctx_st *ctx) 252{ 253 ossl_rsa_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); 254} 255 256#define rsa_free (void (*)(void *))RSA_free 257 258/* ---------------------------------------------------------------------- */ 259 260#define IMPLEMENT_MS(KEYTYPE, keytype) \ 261 static const struct keytype_desc_st \ 262 pvk2##keytype##_desc = { \ 263 EVP_PKEY_##KEYTYPE, #KEYTYPE, \ 264 ossl_##keytype##_keymgmt_functions, \ 265 keytype##_private_key_bio, \ 266 keytype##_adjust, \ 267 keytype##_free \ 268 }; \ 269 static OSSL_FUNC_decoder_newctx_fn pvk2##keytype##_newctx; \ 270 static void *pvk2##keytype##_newctx(void *provctx) \ 271 { \ 272 return pvk2key_newctx(provctx, &pvk2##keytype##_desc); \ 273 } \ 274 const OSSL_DISPATCH \ 275 ossl_##pvk_to_##keytype##_decoder_functions[] = { \ 276 { OSSL_FUNC_DECODER_NEWCTX, \ 277 (void (*)(void))pvk2##keytype##_newctx }, \ 278 { OSSL_FUNC_DECODER_FREECTX, \ 279 (void (*)(void))pvk2key_freectx }, \ 280 { OSSL_FUNC_DECODER_DOES_SELECTION, \ 281 (void (*)(void))pvk2key_does_selection }, \ 282 { OSSL_FUNC_DECODER_DECODE, \ 283 (void (*)(void))pvk2key_decode }, \ 284 { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ 285 (void (*)(void))pvk2key_export_object }, \ 286 { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, \ 287 (void (*)(void))pvk2key_settable_ctx_params }, \ 288 { OSSL_FUNC_DECODER_SET_CTX_PARAMS, \ 289 (void (*)(void))pvk2key_set_ctx_params }, \ 290 OSSL_DISPATCH_END \ 291 } 292 293#ifndef OPENSSL_NO_DSA 294IMPLEMENT_MS(DSA, dsa); 295#endif 296IMPLEMENT_MS(RSA, rsa); 297