xref: /third_party/openssl/crypto/asn1/d2i_pr.c (revision e1051a39)
1/*
2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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/* We need to use some engine deprecated APIs */
11#define OPENSSL_SUPPRESS_DEPRECATED
12
13#include <stdio.h>
14#include "internal/cryptlib.h"
15#include <openssl/bn.h>
16#include <openssl/evp.h>
17#include <openssl/objects.h>
18#include <openssl/decoder.h>
19#include <openssl/engine.h>
20#include <openssl/x509.h>
21#include <openssl/asn1.h>
22#include "crypto/asn1.h"
23#include "crypto/evp.h"
24#include "internal/asn1.h"
25
26static EVP_PKEY *
27d2i_PrivateKey_decoder(int keytype, EVP_PKEY **a, const unsigned char **pp,
28                       long length, OSSL_LIB_CTX *libctx, const char *propq)
29{
30    OSSL_DECODER_CTX *dctx = NULL;
31    size_t len = length;
32    EVP_PKEY *pkey = NULL, *bak_a = NULL;
33    EVP_PKEY **ppkey = &pkey;
34    const char *key_name = NULL;
35    const char *input_structures[] = { "type-specific", "PrivateKeyInfo", NULL };
36    int i, ret;
37
38    if (keytype != EVP_PKEY_NONE) {
39        key_name = evp_pkey_type2name(keytype);
40        if (key_name == NULL)
41            return NULL;
42    }
43
44    for (i = 0;  i < (int)OSSL_NELEM(input_structures); ++i) {
45        const unsigned char *p = *pp;
46
47        if (a != NULL && (bak_a = *a) != NULL)
48            ppkey = a;
49        dctx = OSSL_DECODER_CTX_new_for_pkey(ppkey, "DER",
50                                             input_structures[i], key_name,
51                                             EVP_PKEY_KEYPAIR, libctx, propq);
52        if (a != NULL)
53            *a = bak_a;
54        if (dctx == NULL)
55            continue;
56
57        ret = OSSL_DECODER_from_data(dctx, pp, &len);
58        OSSL_DECODER_CTX_free(dctx);
59        if (ret) {
60            if (*ppkey != NULL
61                && evp_keymgmt_util_has(*ppkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) {
62                if (a != NULL)
63                    *a = *ppkey;
64                return *ppkey;
65            }
66            *pp = p;
67            goto err;
68        }
69    }
70    /* Fall through to error if all decodes failed */
71err:
72    if (ppkey != a)
73        EVP_PKEY_free(*ppkey);
74    return NULL;
75}
76
77EVP_PKEY *
78ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp,
79                           long length, OSSL_LIB_CTX *libctx, const char *propq)
80{
81    EVP_PKEY *ret;
82    const unsigned char *p = *pp;
83
84    if (a == NULL || *a == NULL) {
85        if ((ret = EVP_PKEY_new()) == NULL) {
86            ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB);
87            return NULL;
88        }
89    } else {
90        ret = *a;
91#ifndef OPENSSL_NO_ENGINE
92        ENGINE_finish(ret->engine);
93        ret->engine = NULL;
94#endif
95    }
96
97    if (!EVP_PKEY_set_type(ret, keytype)) {
98        ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
99        goto err;
100    }
101
102    ERR_set_mark();
103    if (!ret->ameth->old_priv_decode ||
104        !ret->ameth->old_priv_decode(ret, &p, length)) {
105        if (ret->ameth->priv_decode != NULL
106                || ret->ameth->priv_decode_ex != NULL) {
107            EVP_PKEY *tmp;
108            PKCS8_PRIV_KEY_INFO *p8 = NULL;
109            p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
110            if (p8 == NULL) {
111                ERR_clear_last_mark();
112                goto err;
113            }
114            tmp = evp_pkcs82pkey_legacy(p8, libctx, propq);
115            PKCS8_PRIV_KEY_INFO_free(p8);
116            if (tmp == NULL) {
117                ERR_clear_last_mark();
118                goto err;
119            }
120            EVP_PKEY_free(ret);
121            ret = tmp;
122            ERR_pop_to_mark();
123            if (EVP_PKEY_type(keytype) != EVP_PKEY_get_base_id(ret))
124                goto err;
125        } else {
126            ERR_clear_last_mark();
127            ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
128            goto err;
129        }
130    } else {
131      ERR_clear_last_mark();
132    }
133    *pp = p;
134    if (a != NULL)
135        *a = ret;
136    return ret;
137 err:
138    if (a == NULL || *a != ret)
139        EVP_PKEY_free(ret);
140    return NULL;
141}
142
143EVP_PKEY *d2i_PrivateKey_ex(int keytype, EVP_PKEY **a, const unsigned char **pp,
144                            long length, OSSL_LIB_CTX *libctx,
145                            const char *propq)
146{
147    EVP_PKEY *ret;
148
149    ret = d2i_PrivateKey_decoder(keytype, a, pp, length, libctx, propq);
150    /* try the legacy path if the decoder failed */
151    if (ret == NULL)
152        ret = ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq);
153    return ret;
154}
155
156EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
157                         long length)
158{
159    return d2i_PrivateKey_ex(type, a, pp, length, NULL, NULL);
160}
161
162static EVP_PKEY *d2i_AutoPrivateKey_legacy(EVP_PKEY **a,
163                                           const unsigned char **pp,
164                                           long length,
165                                           OSSL_LIB_CTX *libctx,
166                                           const char *propq)
167{
168    STACK_OF(ASN1_TYPE) *inkey;
169    const unsigned char *p;
170    int keytype;
171
172    p = *pp;
173    /*
174     * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
175     * analyzing it we can determine the passed structure: this assumes the
176     * input is surrounded by an ASN1 SEQUENCE.
177     */
178    inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
179    p = *pp;
180    /*
181     * Since we only need to discern "traditional format" RSA and DSA keys we
182     * can just count the elements.
183     */
184    if (sk_ASN1_TYPE_num(inkey) == 6) {
185        keytype = EVP_PKEY_DSA;
186    } else if (sk_ASN1_TYPE_num(inkey) == 4) {
187        keytype = EVP_PKEY_EC;
188    } else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
189                                              * traditional format */
190        PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
191        EVP_PKEY *ret;
192
193        sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
194        if (p8 == NULL) {
195            ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
196            return NULL;
197        }
198        ret = evp_pkcs82pkey_legacy(p8, libctx, propq);
199        PKCS8_PRIV_KEY_INFO_free(p8);
200        if (ret == NULL)
201            return NULL;
202        *pp = p;
203        if (a != NULL) {
204            *a = ret;
205        }
206        return ret;
207    } else {
208        keytype = EVP_PKEY_RSA;
209    }
210    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
211    return ossl_d2i_PrivateKey_legacy(keytype, a, pp, length, libctx, propq);
212}
213
214/*
215 * This works like d2i_PrivateKey() except it passes the keytype as
216 * EVP_PKEY_NONE, which then figures out the type during decoding.
217 */
218EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp,
219                                long length, OSSL_LIB_CTX *libctx,
220                                const char *propq)
221{
222    EVP_PKEY *ret;
223
224    ret = d2i_PrivateKey_decoder(EVP_PKEY_NONE, a, pp, length, libctx, propq);
225    /* try the legacy path if the decoder failed */
226    if (ret == NULL)
227        ret = d2i_AutoPrivateKey_legacy(a, pp, length, libctx, propq);
228    return ret;
229}
230
231EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
232                             long length)
233{
234    return d2i_AutoPrivateKey_ex(a, pp, length, NULL, NULL);
235}
236