Imported Upstream version 1.1.1l
[platform/upstream/openssl1.1.git] / crypto / asn1 / d2i_pr.c
1 /*
2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/bn.h>
13 #include <openssl/evp.h>
14 #include <openssl/objects.h>
15 #include <openssl/engine.h>
16 #include <openssl/x509.h>
17 #include <openssl/asn1.h>
18 #include "crypto/asn1.h"
19 #include "crypto/evp.h"
20
21 EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
22                          long length)
23 {
24     EVP_PKEY *ret;
25     const unsigned char *p = *pp;
26
27     if ((a == NULL) || (*a == NULL)) {
28         if ((ret = EVP_PKEY_new()) == NULL) {
29             ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
30             return NULL;
31         }
32     } else {
33         ret = *a;
34 #ifndef OPENSSL_NO_ENGINE
35         ENGINE_finish(ret->engine);
36         ret->engine = NULL;
37 #endif
38     }
39
40     if (!EVP_PKEY_set_type(ret, type)) {
41         ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
42         goto err;
43     }
44
45     if (!ret->ameth->old_priv_decode ||
46         !ret->ameth->old_priv_decode(ret, &p, length)) {
47         if (ret->ameth->priv_decode) {
48             EVP_PKEY *tmp;
49             PKCS8_PRIV_KEY_INFO *p8 = NULL;
50             p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
51             if (!p8)
52                 goto err;
53             tmp = EVP_PKCS82PKEY(p8);
54             PKCS8_PRIV_KEY_INFO_free(p8);
55             if (tmp == NULL)
56                 goto err;
57             EVP_PKEY_free(ret);
58             ret = tmp;
59             if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret))
60                 goto err;
61         } else {
62             ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
63             goto err;
64         }
65     }
66     *pp = p;
67     if (a != NULL)
68         (*a) = ret;
69     return ret;
70  err:
71     if (a == NULL || *a != ret)
72         EVP_PKEY_free(ret);
73     return NULL;
74 }
75
76 /*
77  * This works like d2i_PrivateKey() except it automatically works out the
78  * type
79  */
80
81 static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on)
82 {
83     const unsigned char *p = *pp;
84     PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
85     EVP_PKEY *ret;
86
87     if (p8 == NULL)
88         return NULL;
89
90     ret = EVP_PKCS82PKEY(p8);
91     if (ret == NULL)
92         *carry_on = 0;
93
94     PKCS8_PRIV_KEY_INFO_free(p8);
95
96     if (ret != NULL)
97         *pp = p;
98
99     return ret;
100 }
101
102 EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
103                              long length)
104 {
105     STACK_OF(ASN1_TYPE) *inkey;
106     const unsigned char *p;
107     int keytype;
108     EVP_PKEY *ret = NULL;
109     int carry_on = 1;
110
111     ERR_set_mark();
112     ret = key_as_pkcs8(pp, length, &carry_on);
113     if (ret != NULL) {
114         ERR_clear_last_mark();
115         if (a != NULL)
116             *a = ret;
117         return ret;
118     }
119
120     if (carry_on == 0) {
121         ERR_clear_last_mark();
122         ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
123                 ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
124         return NULL;
125     }
126     p = *pp;
127
128     /*
129      * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
130      * analyzing it we can determine the passed structure: this assumes the
131      * input is surrounded by an ASN1 SEQUENCE.
132      */
133     inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
134     p = *pp;
135     /*
136      * Since we only need to discern "traditional format" RSA and DSA keys we
137      * can just count the elements.
138      */
139     if (sk_ASN1_TYPE_num(inkey) == 6)
140         keytype = EVP_PKEY_DSA;
141     else if (sk_ASN1_TYPE_num(inkey) == 4)
142         keytype = EVP_PKEY_EC;
143     else
144         keytype = EVP_PKEY_RSA;
145     sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
146
147     ret = d2i_PrivateKey(keytype, a, pp, length);
148     if (ret != NULL)
149         ERR_pop_to_mark();
150     else
151         ERR_clear_last_mark();
152
153     return ret;
154 }