1e71b7053SJung-uk Kim /* 2*9a3ae0cdSJung-uk Kim * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 374664626SKris Kennaway * 4e71b7053SJung-uk Kim * Licensed under the OpenSSL license (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 1074664626SKris Kennaway #include <stdio.h> 11e71b7053SJung-uk Kim #include "internal/cryptlib.h" 1274664626SKris Kennaway #include <openssl/bn.h> 1374664626SKris Kennaway #include <openssl/evp.h> 1474664626SKris Kennaway #include <openssl/objects.h> 151f13597dSJung-uk Kim #include <openssl/engine.h> 161f13597dSJung-uk Kim #include <openssl/x509.h> 1774664626SKris Kennaway #include <openssl/asn1.h> 1817f01e99SJung-uk Kim #include "crypto/asn1.h" 1917f01e99SJung-uk Kim #include "crypto/evp.h" 2074664626SKris Kennaway 213b4e3dcbSSimon L. B. Nielsen EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, 2274664626SKris Kennaway long length) 2374664626SKris Kennaway { 2474664626SKris Kennaway EVP_PKEY *ret; 2580815a77SJung-uk Kim const unsigned char *p = *pp; 2674664626SKris Kennaway 276f9291ceSJung-uk Kim if ((a == NULL) || (*a == NULL)) { 286f9291ceSJung-uk Kim if ((ret = EVP_PKEY_new()) == NULL) { 2974664626SKris Kennaway ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); 30e71b7053SJung-uk Kim return NULL; 3174664626SKris Kennaway } 326f9291ceSJung-uk Kim } else { 331f13597dSJung-uk Kim ret = *a; 341f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE 351f13597dSJung-uk Kim ENGINE_finish(ret->engine); 361f13597dSJung-uk Kim ret->engine = NULL; 371f13597dSJung-uk Kim #endif 381f13597dSJung-uk Kim } 3974664626SKris Kennaway 406f9291ceSJung-uk Kim if (!EVP_PKEY_set_type(ret, type)) { 4174664626SKris Kennaway ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); 4274664626SKris Kennaway goto err; 431f13597dSJung-uk Kim } 441f13597dSJung-uk Kim 451f13597dSJung-uk Kim if (!ret->ameth->old_priv_decode || 4680815a77SJung-uk Kim !ret->ameth->old_priv_decode(ret, &p, length)) { 476f9291ceSJung-uk Kim if (ret->ameth->priv_decode) { 48aeb5019cSJung-uk Kim EVP_PKEY *tmp; 491f13597dSJung-uk Kim PKCS8_PRIV_KEY_INFO *p8 = NULL; 5080815a77SJung-uk Kim p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); 516f9291ceSJung-uk Kim if (!p8) 526f9291ceSJung-uk Kim goto err; 53aeb5019cSJung-uk Kim tmp = EVP_PKCS82PKEY(p8); 541f13597dSJung-uk Kim PKCS8_PRIV_KEY_INFO_free(p8); 55aeb5019cSJung-uk Kim if (tmp == NULL) 5680815a77SJung-uk Kim goto err; 57aeb5019cSJung-uk Kim EVP_PKEY_free(ret); 58aeb5019cSJung-uk Kim ret = tmp; 5958f35182SJung-uk Kim if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret)) 6058f35182SJung-uk Kim goto err; 616f9291ceSJung-uk Kim } else { 621f13597dSJung-uk Kim ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); 631f13597dSJung-uk Kim goto err; 641f13597dSJung-uk Kim } 6574664626SKris Kennaway } 6680815a77SJung-uk Kim *pp = p; 676f9291ceSJung-uk Kim if (a != NULL) 686f9291ceSJung-uk Kim (*a) = ret; 69e71b7053SJung-uk Kim return ret; 7074664626SKris Kennaway err: 71e71b7053SJung-uk Kim if (a == NULL || *a != ret) 726f9291ceSJung-uk Kim EVP_PKEY_free(ret); 73e71b7053SJung-uk Kim return NULL; 7474664626SKris Kennaway } 7574664626SKris Kennaway 766f9291ceSJung-uk Kim /* 776f9291ceSJung-uk Kim * This works like d2i_PrivateKey() except it automatically works out the 786f9291ceSJung-uk Kim * type 796f9291ceSJung-uk Kim */ 80f579bf8eSKris Kennaway 81*9a3ae0cdSJung-uk Kim static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on) 82*9a3ae0cdSJung-uk Kim { 83*9a3ae0cdSJung-uk Kim const unsigned char *p = *pp; 84*9a3ae0cdSJung-uk Kim PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); 85*9a3ae0cdSJung-uk Kim EVP_PKEY *ret; 86*9a3ae0cdSJung-uk Kim 87*9a3ae0cdSJung-uk Kim if (p8 == NULL) 88*9a3ae0cdSJung-uk Kim return NULL; 89*9a3ae0cdSJung-uk Kim 90*9a3ae0cdSJung-uk Kim ret = EVP_PKCS82PKEY(p8); 91*9a3ae0cdSJung-uk Kim if (ret == NULL) 92*9a3ae0cdSJung-uk Kim *carry_on = 0; 93*9a3ae0cdSJung-uk Kim 94*9a3ae0cdSJung-uk Kim PKCS8_PRIV_KEY_INFO_free(p8); 95*9a3ae0cdSJung-uk Kim 96*9a3ae0cdSJung-uk Kim if (ret != NULL) 97*9a3ae0cdSJung-uk Kim *pp = p; 98*9a3ae0cdSJung-uk Kim 99*9a3ae0cdSJung-uk Kim return ret; 100*9a3ae0cdSJung-uk Kim } 101*9a3ae0cdSJung-uk Kim 1023b4e3dcbSSimon L. B. Nielsen EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, 103f579bf8eSKris Kennaway long length) 104f579bf8eSKris Kennaway { 105f579bf8eSKris Kennaway STACK_OF(ASN1_TYPE) *inkey; 1063b4e3dcbSSimon L. B. Nielsen const unsigned char *p; 107f579bf8eSKris Kennaway int keytype; 108*9a3ae0cdSJung-uk Kim EVP_PKEY *ret = NULL; 109*9a3ae0cdSJung-uk Kim int carry_on = 1; 110*9a3ae0cdSJung-uk Kim 111*9a3ae0cdSJung-uk Kim ERR_set_mark(); 112*9a3ae0cdSJung-uk Kim ret = key_as_pkcs8(pp, length, &carry_on); 113*9a3ae0cdSJung-uk Kim if (ret != NULL) { 114*9a3ae0cdSJung-uk Kim ERR_clear_last_mark(); 115*9a3ae0cdSJung-uk Kim if (a != NULL) 116*9a3ae0cdSJung-uk Kim *a = ret; 117*9a3ae0cdSJung-uk Kim return ret; 118*9a3ae0cdSJung-uk Kim } 119*9a3ae0cdSJung-uk Kim 120*9a3ae0cdSJung-uk Kim if (carry_on == 0) { 121*9a3ae0cdSJung-uk Kim ERR_clear_last_mark(); 122*9a3ae0cdSJung-uk Kim ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, 123*9a3ae0cdSJung-uk Kim ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 124*9a3ae0cdSJung-uk Kim return NULL; 125*9a3ae0cdSJung-uk Kim } 126f579bf8eSKris Kennaway p = *pp; 127*9a3ae0cdSJung-uk Kim 1286f9291ceSJung-uk Kim /* 1296f9291ceSJung-uk Kim * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by 1306f9291ceSJung-uk Kim * analyzing it we can determine the passed structure: this assumes the 1316f9291ceSJung-uk Kim * input is surrounded by an ASN1 SEQUENCE. 132f579bf8eSKris Kennaway */ 1331f13597dSJung-uk Kim inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); 13480815a77SJung-uk Kim p = *pp; 1356f9291ceSJung-uk Kim /* 1366f9291ceSJung-uk Kim * Since we only need to discern "traditional format" RSA and DSA keys we 1376f9291ceSJung-uk Kim * can just count the elements. 138f579bf8eSKris Kennaway */ 1393b4e3dcbSSimon L. B. Nielsen if (sk_ASN1_TYPE_num(inkey) == 6) 1403b4e3dcbSSimon L. B. Nielsen keytype = EVP_PKEY_DSA; 1413b4e3dcbSSimon L. B. Nielsen else if (sk_ASN1_TYPE_num(inkey) == 4) 1423b4e3dcbSSimon L. B. Nielsen keytype = EVP_PKEY_EC; 143*9a3ae0cdSJung-uk Kim else 1446f9291ceSJung-uk Kim keytype = EVP_PKEY_RSA; 145f579bf8eSKris Kennaway sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); 146*9a3ae0cdSJung-uk Kim 147*9a3ae0cdSJung-uk Kim ret = d2i_PrivateKey(keytype, a, pp, length); 148*9a3ae0cdSJung-uk Kim if (ret != NULL) 149*9a3ae0cdSJung-uk Kim ERR_pop_to_mark(); 150*9a3ae0cdSJung-uk Kim else 151*9a3ae0cdSJung-uk Kim ERR_clear_last_mark(); 152*9a3ae0cdSJung-uk Kim 153*9a3ae0cdSJung-uk Kim return ret; 154f579bf8eSKris Kennaway } 155