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