/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 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
* type
*/
+static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on)
+{
+ const unsigned char *p = *pp;
+ PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+ EVP_PKEY *ret;
+
+ if (p8 == NULL)
+ return NULL;
+
+ ret = EVP_PKCS82PKEY(p8);
+ if (ret == NULL)
+ *carry_on = 0;
+
+ PKCS8_PRIV_KEY_INFO_free(p8);
+
+ if (ret != NULL)
+ *pp = p;
+
+ return ret;
+}
+
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
long length)
{
STACK_OF(ASN1_TYPE) *inkey;
const unsigned char *p;
int keytype;
+ EVP_PKEY *ret = NULL;
+ int carry_on = 1;
+
+ ERR_set_mark();
+ ret = key_as_pkcs8(pp, length, &carry_on);
+ if (ret != NULL) {
+ ERR_clear_last_mark();
+ if (a != NULL)
+ *a = ret;
+ return ret;
+ }
+
+ if (carry_on == 0) {
+ ERR_clear_last_mark();
+ ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
+ ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ return NULL;
+ }
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
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
+ else
keytype = EVP_PKEY_RSA;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
- return d2i_PrivateKey(keytype, a, pp, length);
+
+ ret = d2i_PrivateKey(keytype, a, pp, length);
+ if (ret != NULL)
+ ERR_pop_to_mark();
+ else
+ ERR_clear_last_mark();
+
+ return ret;
}