From aa4d426b4d3527d7e166df1a05058c9a4a0f6683 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 30 Apr 2021 00:33:56 +0200 Subject: initial/final commit --- openssl-1.1.0h/crypto/asn1/d2i_pr.c | 125 ++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 openssl-1.1.0h/crypto/asn1/d2i_pr.c (limited to 'openssl-1.1.0h/crypto/asn1/d2i_pr.c') diff --git a/openssl-1.1.0h/crypto/asn1/d2i_pr.c b/openssl-1.1.0h/crypto/asn1/d2i_pr.c new file mode 100644 index 0000000..e311b90 --- /dev/null +++ b/openssl-1.1.0h/crypto/asn1/d2i_pr.c @@ -0,0 +1,125 @@ +/* + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "internal/asn1_int.h" +#include "internal/evp_int.h" + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + EVP_PKEY *ret; + const unsigned char *p = *pp; + + if ((a == NULL) || (*a == NULL)) { + if ((ret = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); + return (NULL); + } + } else { + ret = *a; +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(ret->engine); + ret->engine = NULL; +#endif + } + + if (!EVP_PKEY_set_type(ret, type)) { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + + if (!ret->ameth->old_priv_decode || + !ret->ameth->old_priv_decode(ret, &p, length)) { + if (ret->ameth->priv_decode) { + EVP_PKEY *tmp; + PKCS8_PRIV_KEY_INFO *p8 = NULL; + p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + if (!p8) + goto err; + tmp = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (tmp == NULL) + goto err; + EVP_PKEY_free(ret); + ret = tmp; + } else { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + } + *pp = p; + if (a != NULL) + (*a) = ret; + return (ret); + err: + if (a == NULL || *a != ret) + EVP_PKEY_free(ret); + return (NULL); +} + +/* + * This works like d2i_PrivateKey() except it automatically works out the + * type + */ + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length) +{ + STACK_OF(ASN1_TYPE) *inkey; + const unsigned char *p; + int keytype; + p = *pp; + /* + * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by + * analyzing it we can determine the passed structure: this assumes the + * input is surrounded by an ASN1 SEQUENCE. + */ + inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); + p = *pp; + /* + * Since we only need to discern "traditional format" RSA and DSA keys we + * can just count the elements. + */ + if (sk_ASN1_TYPE_num(inkey) == 6) + keytype = EVP_PKEY_DSA; + else if (sk_ASN1_TYPE_num(inkey) == 4) + keytype = EVP_PKEY_EC; + else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not + * traditional format */ + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + EVP_PKEY *ret; + + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + if (!p8) { + ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, + ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } + ret = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (ret == NULL) + return NULL; + *pp = p; + if (a) { + *a = ret; + } + return ret; + } else + keytype = EVP_PKEY_RSA; + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + return d2i_PrivateKey(keytype, a, pp, length); +} -- cgit v1.2.3