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