1e71b7053SJung-uk Kim /* 29a3ae0cdSJung-uk Kim * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy 6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at 7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html 874664626SKris Kennaway */ 974664626SKris Kennaway 10*b077aed3SPierre Pronchery /* We need to use some engine deprecated APIs */ 11*b077aed3SPierre Pronchery #define OPENSSL_SUPPRESS_DEPRECATED 12*b077aed3SPierre Pronchery 1374664626SKris Kennaway #include <stdio.h> 14e71b7053SJung-uk Kim #include "internal/cryptlib.h" 1574664626SKris Kennaway #include <openssl/bn.h> 1674664626SKris Kennaway #include <openssl/evp.h> 1774664626SKris Kennaway #include <openssl/objects.h> 18*b077aed3SPierre Pronchery #include <openssl/decoder.h> 191f13597dSJung-uk Kim #include <openssl/engine.h> 201f13597dSJung-uk Kim #include <openssl/x509.h> 2174664626SKris Kennaway #include <openssl/asn1.h> 2217f01e99SJung-uk Kim #include "crypto/asn1.h" 2317f01e99SJung-uk Kim #include "crypto/evp.h" 24*b077aed3SPierre Pronchery #include "internal/asn1.h" 2574664626SKris Kennaway 26*b077aed3SPierre Pronchery static EVP_PKEY * 27*b077aed3SPierre Pronchery d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp, 28*b077aed3SPierre Pronchery long length, OSSL_LIB_CTX *libctx, const char *propq) 29*b077aed3SPierre Pronchery { 30*b077aed3SPierre Pronchery OSSL_DECODER_CTX *dctx = NULL; 31*b077aed3SPierre Pronchery size_t len = length; 32*b077aed3SPierre Pronchery EVP_PKEY *pkey = NULL, *bak_a = NULL; 33*b077aed3SPierre Pronchery EVP_PKEY **ppkey = &pkey; 34*b077aed3SPierre Pronchery const char *key_name = NULL; 35*b077aed3SPierre Pronchery const char *input_structures[] = { "type-specific", "PrivateKeyInfo", NULL }; 36*b077aed3SPierre Pronchery int i, ret; 37*b077aed3SPierre Pronchery 38*b077aed3SPierre Pronchery if (keytype != EVP_PKEY_NONE) { 39*b077aed3SPierre Pronchery key_name = evp_pkey_type2name(keytype); 40*b077aed3SPierre Pronchery if (key_name == NULL) 41*b077aed3SPierre Pronchery return NULL; 42*b077aed3SPierre Pronchery } 43*b077aed3SPierre Pronchery 44*b077aed3SPierre Pronchery for (i = 0; i < (int)OSSL_NELEM(input_structures); ++i) { 45*b077aed3SPierre Pronchery const unsigned char *p = *pp; 46*b077aed3SPierre Pronchery 47*b077aed3SPierre Pronchery if (a != NULL && (bak_a = *a) != NULL) 48*b077aed3SPierre Pronchery ppkey = a; 49*b077aed3SPierre Pronchery dctx = OSSL_DECODER_CTX_new_for_pkey(ppkey, "DER", 50*b077aed3SPierre Pronchery input_structures[i], key_name, 51*b077aed3SPierre Pronchery EVP_PKEY_KEYPAIR, libctx, propq); 52*b077aed3SPierre Pronchery if (a != NULL) 53*b077aed3SPierre Pronchery *a = bak_a; 54*b077aed3SPierre Pronchery if (dctx == NULL) 55*b077aed3SPierre Pronchery continue; 56*b077aed3SPierre Pronchery 57*b077aed3SPierre Pronchery ret = OSSL_DECODER_from_data(dctx, pp, &len); 58*b077aed3SPierre Pronchery OSSL_DECODER_CTX_free(dctx); 59*b077aed3SPierre Pronchery if (ret) { 60*b077aed3SPierre Pronchery if (*ppkey != NULL 61*b077aed3SPierre Pronchery && evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) { 62*b077aed3SPierre Pronchery if (a != NULL) 63*b077aed3SPierre Pronchery *a = *ppkey; 64*b077aed3SPierre Pronchery return *ppkey; 65*b077aed3SPierre Pronchery } 66*b077aed3SPierre Pronchery *pp = p; 67*b077aed3SPierre Pronchery goto err; 68*b077aed3SPierre Pronchery } 69*b077aed3SPierre Pronchery } 70*b077aed3SPierre Pronchery /* Fall through to error if all decodes failed */ 71*b077aed3SPierre Pronchery err: 72*b077aed3SPierre Pronchery if (ppkey != a) 73*b077aed3SPierre Pronchery EVP_PKEY_free(*ppkey); 74*b077aed3SPierre Pronchery return NULL; 75*b077aed3SPierre Pronchery } 76*b077aed3SPierre Pronchery 77*b077aed3SPierre Pronchery EVP_PKEY * 78*b077aed3SPierre Pronchery ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp, 79*b077aed3SPierre Pronchery long length, OSSL_LIB_CTX *libctx, const char *propq) 8074664626SKris Kennaway { 8174664626SKris Kennaway EVP_PKEY *ret; 8280815a77SJung-uk Kim const unsigned char *p = *pp; 8374664626SKris Kennaway 84*b077aed3SPierre Pronchery if (a == NULL || *a == NULL) { 856f9291ceSJung-uk Kim if ((ret = EVP_PKEY_new()) == NULL) { 86*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); 87e71b7053SJung-uk Kim return NULL; 8874664626SKris Kennaway } 896f9291ceSJung-uk Kim } else { 901f13597dSJung-uk Kim ret = *a; 911f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE 921f13597dSJung-uk Kim ENGINE_finish(ret->engine); 931f13597dSJung-uk Kim ret->engine = NULL; 941f13597dSJung-uk Kim #endif 951f13597dSJung-uk Kim } 9674664626SKris Kennaway 97*b077aed3SPierre Pronchery if (!EVP_PKEY_set_type(ret, keytype)) { 98*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); 9974664626SKris Kennaway goto err; 1001f13597dSJung-uk Kim } 1011f13597dSJung-uk Kim 102*b077aed3SPierre Pronchery ERR_set_mark(); 1031f13597dSJung-uk Kim if (!ret->ameth->old_priv_decode || 10480815a77SJung-uk Kim !ret->ameth->old_priv_decode(ret, &p, length)) { 105*b077aed3SPierre Pronchery if (ret->ameth->priv_decode != NULL 106*b077aed3SPierre Pronchery || ret->ameth->priv_decode_ex != NULL) { 107aeb5019cSJung-uk Kim EVP_PKEY *tmp; 1081f13597dSJung-uk Kim PKCS8_PRIV_KEY_INFO *p8 = NULL; 10980815a77SJung-uk Kim p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); 110*b077aed3SPierre Pronchery if (p8 == NULL) { 111*b077aed3SPierre Pronchery ERR_clear_last_mark(); 1121f13597dSJung-uk Kim goto err; 1131f13597dSJung-uk Kim } 114*b077aed3SPierre Pronchery tmp = evp_pkcs82pkey_legacy(p8, libctx, propq); 115*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO_free(p8); 116*b077aed3SPierre Pronchery if (tmp == NULL) { 117*b077aed3SPierre Pronchery ERR_clear_last_mark(); 118*b077aed3SPierre Pronchery goto err; 119*b077aed3SPierre Pronchery } 120*b077aed3SPierre Pronchery EVP_PKEY_free(ret); 121*b077aed3SPierre Pronchery ret = tmp; 122*b077aed3SPierre Pronchery ERR_pop_to_mark(); 123*b077aed3SPierre Pronchery if (EVP_PKEY_type(keytype) != EVP_PKEY_get_base_id(ret)) 124*b077aed3SPierre Pronchery goto err; 125*b077aed3SPierre Pronchery } else { 126*b077aed3SPierre Pronchery ERR_clear_last_mark(); 127*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); 128*b077aed3SPierre Pronchery goto err; 129*b077aed3SPierre Pronchery } 130*b077aed3SPierre Pronchery } else { 131*b077aed3SPierre Pronchery ERR_clear_last_mark(); 13274664626SKris Kennaway } 13380815a77SJung-uk Kim *pp = p; 1346f9291ceSJung-uk Kim if (a != NULL) 135*b077aed3SPierre Pronchery *a = ret; 136e71b7053SJung-uk Kim return ret; 13774664626SKris Kennaway err: 138e71b7053SJung-uk Kim if (a == NULL || *a != ret) 1396f9291ceSJung-uk Kim EVP_PKEY_free(ret); 140e71b7053SJung-uk Kim return NULL; 14174664626SKris Kennaway } 14274664626SKris Kennaway 143*b077aed3SPierre Pronchery EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp, 144*b077aed3SPierre Pronchery long length, OSSL_LIB_CTX *libctx, 145*b077aed3SPierre Pronchery const char *propq) 1469a3ae0cdSJung-uk Kim { 1479a3ae0cdSJung-uk Kim EVP_PKEY *ret; 1489a3ae0cdSJung-uk Kim 149*b077aed3SPierre Pronchery ret = d2i_PrivateKey_decoder(keytype, a, pp, length, libctx, propq); 150*b077aed3SPierre Pronchery /* try the legacy path if the decoder failed */ 1519a3ae0cdSJung-uk Kim if (ret == NULL) 152*b077aed3SPierre Pronchery ret = ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq); 1539a3ae0cdSJung-uk Kim return ret; 1549a3ae0cdSJung-uk Kim } 1559a3ae0cdSJung-uk Kim 156*b077aed3SPierre Pronchery EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, 157f579bf8eSKris Kennaway long length) 158f579bf8eSKris Kennaway { 159*b077aed3SPierre Pronchery return d2i_PrivateKey_ex(type, a, pp, length, NULL, NULL); 160*b077aed3SPierre Pronchery } 161*b077aed3SPierre Pronchery 162*b077aed3SPierre Pronchery static EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a, 163*b077aed3SPierre Pronchery const unsigned char **pp, 164*b077aed3SPierre Pronchery long length, 165*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx, 166*b077aed3SPierre Pronchery const char *propq) 167*b077aed3SPierre Pronchery { 168f579bf8eSKris Kennaway STACK_OF(ASN1_TYPE) *inkey; 1693b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 170f579bf8eSKris Kennaway int keytype; 1719a3ae0cdSJung-uk Kim 172f579bf8eSKris Kennaway p = *pp; 1736f9291ceSJung-uk Kim /* 1746f9291ceSJung-uk Kim * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by 1756f9291ceSJung-uk Kim * analyzing it we can determine the passed structure: this assumes the 1766f9291ceSJung-uk Kim * input is surrounded by an ASN1 SEQUENCE. 177f579bf8eSKris Kennaway */ 1781f13597dSJung-uk Kim inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); 17980815a77SJung-uk Kim p = *pp; 1806f9291ceSJung-uk Kim /* 1816f9291ceSJung-uk Kim * Since we only need to discern "traditional format" RSA and DSA keys we 1826f9291ceSJung-uk Kim * can just count the elements. 183f579bf8eSKris Kennaway */ 184*b077aed3SPierre Pronchery if (sk_ASN1_TYPE_num(inkey) == 6) { 1853b4e3dcbSSimon L. B. Nielsen keytype = EVP_PKEY_DSA; 186*b077aed3SPierre Pronchery } else if (sk_ASN1_TYPE_num(inkey) == 4) { 1873b4e3dcbSSimon L. B. Nielsen keytype = EVP_PKEY_EC; 188*b077aed3SPierre Pronchery } else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not 189*b077aed3SPierre Pronchery * traditional format */ 190*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); 191*b077aed3SPierre Pronchery EVP_PKEY *ret; 192*b077aed3SPierre Pronchery 193f579bf8eSKris Kennaway sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); 194*b077aed3SPierre Pronchery if (p8 == NULL) { 195*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 196*b077aed3SPierre Pronchery return NULL; 197*b077aed3SPierre Pronchery } 198*b077aed3SPierre Pronchery ret = evp_pkcs82pkey_legacy(p8, libctx, propq); 199*b077aed3SPierre Pronchery PKCS8_PRIV_KEY_INFO_free(p8); 200*b077aed3SPierre Pronchery if (ret == NULL) 201*b077aed3SPierre Pronchery return NULL; 202*b077aed3SPierre Pronchery *pp = p; 203*b077aed3SPierre Pronchery if (a != NULL) { 204*b077aed3SPierre Pronchery *a = ret; 205*b077aed3SPierre Pronchery } 2069a3ae0cdSJung-uk Kim return ret; 207*b077aed3SPierre Pronchery } else { 208*b077aed3SPierre Pronchery keytype = EVP_PKEY_RSA; 209*b077aed3SPierre Pronchery } 210*b077aed3SPierre Pronchery sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); 211*b077aed3SPierre Pronchery return ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq); 212*b077aed3SPierre Pronchery } 213*b077aed3SPierre Pronchery 214*b077aed3SPierre Pronchery /* 215*b077aed3SPierre Pronchery * This works like d2i_PrivateKey() except it passes the keytype as 216*b077aed3SPierre Pronchery * EVP_PKEY_NONE, which then figures out the type during decoding. 217*b077aed3SPierre Pronchery */ 218*b077aed3SPierre Pronchery EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp, 219*b077aed3SPierre Pronchery long length, OSSL_LIB_CTX *libctx, 220*b077aed3SPierre Pronchery const char *propq) 221*b077aed3SPierre Pronchery { 222*b077aed3SPierre Pronchery EVP_PKEY *ret; 223*b077aed3SPierre Pronchery 224*b077aed3SPierre Pronchery ret = d2i_PrivateKey_decoder(EVP_PKEY_NONE, a, pp, length, libctx, propq); 225*b077aed3SPierre Pronchery /* try the legacy path if the decoder failed */ 226*b077aed3SPierre Pronchery if (ret == NULL) 227*b077aed3SPierre Pronchery ret = d2i_AutoPrivateKey_legacy(a, pp, length, libctx, propq); 228*b077aed3SPierre Pronchery return ret; 229*b077aed3SPierre Pronchery } 230*b077aed3SPierre Pronchery 231*b077aed3SPierre Pronchery EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, 232*b077aed3SPierre Pronchery long length) 233*b077aed3SPierre Pronchery { 234*b077aed3SPierre Pronchery return d2i_AutoPrivateKey_ex(a, pp, length, NULL, NULL); 235f579bf8eSKris Kennaway } 236