1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* We need to use some engine deprecated APIs */ 11e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci#include <stdio.h> 14e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 15e1051a39Sopenharmony_ci#include <openssl/bn.h> 16e1051a39Sopenharmony_ci#include <openssl/evp.h> 17e1051a39Sopenharmony_ci#include <openssl/objects.h> 18e1051a39Sopenharmony_ci#include <openssl/decoder.h> 19e1051a39Sopenharmony_ci#include <openssl/engine.h> 20e1051a39Sopenharmony_ci#include <openssl/x509.h> 21e1051a39Sopenharmony_ci#include <openssl/asn1.h> 22e1051a39Sopenharmony_ci#include "crypto/asn1.h" 23e1051a39Sopenharmony_ci#include "crypto/evp.h" 24e1051a39Sopenharmony_ci#include "internal/asn1.h" 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_cistatic EVP_PKEY * 27e1051a39Sopenharmony_cid2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp, 28e1051a39Sopenharmony_ci long length, OSSL_LIB_CTX *libctx, const char *propq) 29e1051a39Sopenharmony_ci{ 30e1051a39Sopenharmony_ci OSSL_DECODER_CTX *dctx = NULL; 31e1051a39Sopenharmony_ci size_t len = length; 32e1051a39Sopenharmony_ci EVP_PKEY *pkey = NULL, *bak_a = NULL; 33e1051a39Sopenharmony_ci EVP_PKEY **ppkey = &pkey; 34e1051a39Sopenharmony_ci const char *key_name = NULL; 35e1051a39Sopenharmony_ci const char *input_structures[] = { "type-specific", "PrivateKeyInfo", NULL }; 36e1051a39Sopenharmony_ci int i, ret; 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci if (keytype != EVP_PKEY_NONE) { 39e1051a39Sopenharmony_ci key_name = evp_pkey_type2name(keytype); 40e1051a39Sopenharmony_ci if (key_name == NULL) 41e1051a39Sopenharmony_ci return NULL; 42e1051a39Sopenharmony_ci } 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci for (i = 0; i < (int)OSSL_NELEM(input_structures); ++i) { 45e1051a39Sopenharmony_ci const unsigned char *p = *pp; 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci if (a != NULL && (bak_a = *a) != NULL) 48e1051a39Sopenharmony_ci ppkey = a; 49e1051a39Sopenharmony_ci dctx = OSSL_DECODER_CTX_new_for_pkey(ppkey, "DER", 50e1051a39Sopenharmony_ci input_structures[i], key_name, 51e1051a39Sopenharmony_ci EVP_PKEY_KEYPAIR, libctx, propq); 52e1051a39Sopenharmony_ci if (a != NULL) 53e1051a39Sopenharmony_ci *a = bak_a; 54e1051a39Sopenharmony_ci if (dctx == NULL) 55e1051a39Sopenharmony_ci continue; 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ci ret = OSSL_DECODER_from_data(dctx, pp, &len); 58e1051a39Sopenharmony_ci OSSL_DECODER_CTX_free(dctx); 59e1051a39Sopenharmony_ci if (ret) { 60e1051a39Sopenharmony_ci if (*ppkey != NULL 61e1051a39Sopenharmony_ci && evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) { 62e1051a39Sopenharmony_ci if (a != NULL) 63e1051a39Sopenharmony_ci *a = *ppkey; 64e1051a39Sopenharmony_ci return *ppkey; 65e1051a39Sopenharmony_ci } 66e1051a39Sopenharmony_ci *pp = p; 67e1051a39Sopenharmony_ci goto err; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci } 70e1051a39Sopenharmony_ci /* Fall through to error if all decodes failed */ 71e1051a39Sopenharmony_cierr: 72e1051a39Sopenharmony_ci if (ppkey != a) 73e1051a39Sopenharmony_ci EVP_PKEY_free(*ppkey); 74e1051a39Sopenharmony_ci return NULL; 75e1051a39Sopenharmony_ci} 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_ciEVP_PKEY * 78e1051a39Sopenharmony_ciossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp, 79e1051a39Sopenharmony_ci long length, OSSL_LIB_CTX *libctx, const char *propq) 80e1051a39Sopenharmony_ci{ 81e1051a39Sopenharmony_ci EVP_PKEY *ret; 82e1051a39Sopenharmony_ci const unsigned char *p = *pp; 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_ci if (a == NULL || *a == NULL) { 85e1051a39Sopenharmony_ci if ((ret = EVP_PKEY_new()) == NULL) { 86e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); 87e1051a39Sopenharmony_ci return NULL; 88e1051a39Sopenharmony_ci } 89e1051a39Sopenharmony_ci } else { 90e1051a39Sopenharmony_ci ret = *a; 91e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 92e1051a39Sopenharmony_ci ENGINE_finish(ret->engine); 93e1051a39Sopenharmony_ci ret->engine = NULL; 94e1051a39Sopenharmony_ci#endif 95e1051a39Sopenharmony_ci } 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci if (!EVP_PKEY_set_type(ret, keytype)) { 98e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); 99e1051a39Sopenharmony_ci goto err; 100e1051a39Sopenharmony_ci } 101e1051a39Sopenharmony_ci 102e1051a39Sopenharmony_ci ERR_set_mark(); 103e1051a39Sopenharmony_ci if (!ret->ameth->old_priv_decode || 104e1051a39Sopenharmony_ci !ret->ameth->old_priv_decode(ret, &p, length)) { 105e1051a39Sopenharmony_ci if (ret->ameth->priv_decode != NULL 106e1051a39Sopenharmony_ci || ret->ameth->priv_decode_ex != NULL) { 107e1051a39Sopenharmony_ci EVP_PKEY *tmp; 108e1051a39Sopenharmony_ci PKCS8_PRIV_KEY_INFO *p8 = NULL; 109e1051a39Sopenharmony_ci p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); 110e1051a39Sopenharmony_ci if (p8 == NULL) { 111e1051a39Sopenharmony_ci ERR_clear_last_mark(); 112e1051a39Sopenharmony_ci goto err; 113e1051a39Sopenharmony_ci } 114e1051a39Sopenharmony_ci tmp = evp_pkcs82pkey_legacy(p8, libctx, propq); 115e1051a39Sopenharmony_ci PKCS8_PRIV_KEY_INFO_free(p8); 116e1051a39Sopenharmony_ci if (tmp == NULL) { 117e1051a39Sopenharmony_ci ERR_clear_last_mark(); 118e1051a39Sopenharmony_ci goto err; 119e1051a39Sopenharmony_ci } 120e1051a39Sopenharmony_ci EVP_PKEY_free(ret); 121e1051a39Sopenharmony_ci ret = tmp; 122e1051a39Sopenharmony_ci ERR_pop_to_mark(); 123e1051a39Sopenharmony_ci if (EVP_PKEY_type(keytype) != EVP_PKEY_get_base_id(ret)) 124e1051a39Sopenharmony_ci goto err; 125e1051a39Sopenharmony_ci } else { 126e1051a39Sopenharmony_ci ERR_clear_last_mark(); 127e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); 128e1051a39Sopenharmony_ci goto err; 129e1051a39Sopenharmony_ci } 130e1051a39Sopenharmony_ci } else { 131e1051a39Sopenharmony_ci ERR_clear_last_mark(); 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci *pp = p; 134e1051a39Sopenharmony_ci if (a != NULL) 135e1051a39Sopenharmony_ci *a = ret; 136e1051a39Sopenharmony_ci return ret; 137e1051a39Sopenharmony_ci err: 138e1051a39Sopenharmony_ci if (a == NULL || *a != ret) 139e1051a39Sopenharmony_ci EVP_PKEY_free(ret); 140e1051a39Sopenharmony_ci return NULL; 141e1051a39Sopenharmony_ci} 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_ciEVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp, 144e1051a39Sopenharmony_ci long length, OSSL_LIB_CTX *libctx, 145e1051a39Sopenharmony_ci const char *propq) 146e1051a39Sopenharmony_ci{ 147e1051a39Sopenharmony_ci EVP_PKEY *ret; 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci ret = d2i_PrivateKey_decoder(keytype, a, pp, length, libctx, propq); 150e1051a39Sopenharmony_ci /* try the legacy path if the decoder failed */ 151e1051a39Sopenharmony_ci if (ret == NULL) 152e1051a39Sopenharmony_ci ret = ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq); 153e1051a39Sopenharmony_ci return ret; 154e1051a39Sopenharmony_ci} 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ciEVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, 157e1051a39Sopenharmony_ci long length) 158e1051a39Sopenharmony_ci{ 159e1051a39Sopenharmony_ci return d2i_PrivateKey_ex(type, a, pp, length, NULL, NULL); 160e1051a39Sopenharmony_ci} 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_cistatic EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a, 163e1051a39Sopenharmony_ci const unsigned char **pp, 164e1051a39Sopenharmony_ci long length, 165e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, 166e1051a39Sopenharmony_ci const char *propq) 167e1051a39Sopenharmony_ci{ 168e1051a39Sopenharmony_ci STACK_OF(ASN1_TYPE) *inkey; 169e1051a39Sopenharmony_ci const unsigned char *p; 170e1051a39Sopenharmony_ci int keytype; 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci p = *pp; 173e1051a39Sopenharmony_ci /* 174e1051a39Sopenharmony_ci * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by 175e1051a39Sopenharmony_ci * analyzing it we can determine the passed structure: this assumes the 176e1051a39Sopenharmony_ci * input is surrounded by an ASN1 SEQUENCE. 177e1051a39Sopenharmony_ci */ 178e1051a39Sopenharmony_ci inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); 179e1051a39Sopenharmony_ci p = *pp; 180e1051a39Sopenharmony_ci /* 181e1051a39Sopenharmony_ci * Since we only need to discern "traditional format" RSA and DSA keys we 182e1051a39Sopenharmony_ci * can just count the elements. 183e1051a39Sopenharmony_ci */ 184e1051a39Sopenharmony_ci if (sk_ASN1_TYPE_num(inkey) == 6) { 185e1051a39Sopenharmony_ci keytype = EVP_PKEY_DSA; 186e1051a39Sopenharmony_ci } else if (sk_ASN1_TYPE_num(inkey) == 4) { 187e1051a39Sopenharmony_ci keytype = EVP_PKEY_EC; 188e1051a39Sopenharmony_ci } else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not 189e1051a39Sopenharmony_ci * traditional format */ 190e1051a39Sopenharmony_ci PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); 191e1051a39Sopenharmony_ci EVP_PKEY *ret; 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); 194e1051a39Sopenharmony_ci if (p8 == NULL) { 195e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 196e1051a39Sopenharmony_ci return NULL; 197e1051a39Sopenharmony_ci } 198e1051a39Sopenharmony_ci ret = evp_pkcs82pkey_legacy(p8, libctx, propq); 199e1051a39Sopenharmony_ci PKCS8_PRIV_KEY_INFO_free(p8); 200e1051a39Sopenharmony_ci if (ret == NULL) 201e1051a39Sopenharmony_ci return NULL; 202e1051a39Sopenharmony_ci *pp = p; 203e1051a39Sopenharmony_ci if (a != NULL) { 204e1051a39Sopenharmony_ci *a = ret; 205e1051a39Sopenharmony_ci } 206e1051a39Sopenharmony_ci return ret; 207e1051a39Sopenharmony_ci } else { 208e1051a39Sopenharmony_ci keytype = EVP_PKEY_RSA; 209e1051a39Sopenharmony_ci } 210e1051a39Sopenharmony_ci sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); 211e1051a39Sopenharmony_ci return ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq); 212e1051a39Sopenharmony_ci} 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci/* 215e1051a39Sopenharmony_ci * This works like d2i_PrivateKey() except it passes the keytype as 216e1051a39Sopenharmony_ci * EVP_PKEY_NONE, which then figures out the type during decoding. 217e1051a39Sopenharmony_ci */ 218e1051a39Sopenharmony_ciEVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp, 219e1051a39Sopenharmony_ci long length, OSSL_LIB_CTX *libctx, 220e1051a39Sopenharmony_ci const char *propq) 221e1051a39Sopenharmony_ci{ 222e1051a39Sopenharmony_ci EVP_PKEY *ret; 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci ret = d2i_PrivateKey_decoder(EVP_PKEY_NONE, a, pp, length, libctx, propq); 225e1051a39Sopenharmony_ci /* try the legacy path if the decoder failed */ 226e1051a39Sopenharmony_ci if (ret == NULL) 227e1051a39Sopenharmony_ci ret = d2i_AutoPrivateKey_legacy(a, pp, length, libctx, propq); 228e1051a39Sopenharmony_ci return ret; 229e1051a39Sopenharmony_ci} 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ciEVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, 232e1051a39Sopenharmony_ci long length) 233e1051a39Sopenharmony_ci{ 234e1051a39Sopenharmony_ci return d2i_AutoPrivateKey_ex(a, pp, length, NULL, NULL); 235e1051a39Sopenharmony_ci} 236