155714Skris/* evp_pkey.c */
2296465Sdelphij/*
3296465Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4296465Sdelphij * 1999.
555714Skris */
655714Skris/* ====================================================================
7160814Ssimon * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
855714Skris *
955714Skris * Redistribution and use in source and binary forms, with or without
1055714Skris * modification, are permitted provided that the following conditions
1155714Skris * are met:
1255714Skris *
1355714Skris * 1. Redistributions of source code must retain the above copyright
14296465Sdelphij *    notice, this list of conditions and the following disclaimer.
1555714Skris *
1655714Skris * 2. Redistributions in binary form must reproduce the above copyright
1755714Skris *    notice, this list of conditions and the following disclaimer in
1855714Skris *    the documentation and/or other materials provided with the
1955714Skris *    distribution.
2055714Skris *
2155714Skris * 3. All advertising materials mentioning features or use of this
2255714Skris *    software must display the following acknowledgment:
2355714Skris *    "This product includes software developed by the OpenSSL Project
2455714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2555714Skris *
2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2755714Skris *    endorse or promote products derived from this software without
2855714Skris *    prior written permission. For written permission, please contact
2955714Skris *    licensing@OpenSSL.org.
3055714Skris *
3155714Skris * 5. Products derived from this software may not be called "OpenSSL"
3255714Skris *    nor may "OpenSSL" appear in their names without prior written
3355714Skris *    permission of the OpenSSL Project.
3455714Skris *
3555714Skris * 6. Redistributions of any form whatsoever must retain the following
3655714Skris *    acknowledgment:
3755714Skris *    "This product includes software developed by the OpenSSL Project
3855714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3955714Skris *
4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4355714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
5255714Skris * ====================================================================
5355714Skris *
5455714Skris * This product includes cryptographic software written by Eric Young
5555714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5655714Skris * Hudson (tjh@cryptsoft.com).
5755714Skris *
5855714Skris */
5955714Skris
6055714Skris#include <stdio.h>
6155714Skris#include <stdlib.h>
6255714Skris#include "cryptlib.h"
6355714Skris#include <openssl/x509.h>
6455714Skris#include <openssl/rand.h>
65160814Ssimon#ifndef OPENSSL_NO_RSA
66296465Sdelphij# include <openssl/rsa.h>
67160814Ssimon#endif
68160814Ssimon#ifndef OPENSSL_NO_DSA
69296465Sdelphij# include <openssl/dsa.h>
70160814Ssimon#endif
71160814Ssimon#include <openssl/bn.h>
7255714Skris
73109998Smarkm#ifndef OPENSSL_NO_DSA
7459191Skrisstatic int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
75109998Smarkm#endif
76160814Ssimon#ifndef OPENSSL_NO_EC
77160814Ssimonstatic int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey);
78160814Ssimon#endif
7959191Skris
8055714Skris/* Extract a private key from a PKCS8 structure */
8155714Skris
82160814SsimonEVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
8355714Skris{
84296465Sdelphij    EVP_PKEY *pkey = NULL;
85109998Smarkm#ifndef OPENSSL_NO_RSA
86296465Sdelphij    RSA *rsa = NULL;
8755714Skris#endif
88109998Smarkm#ifndef OPENSSL_NO_DSA
89296465Sdelphij    DSA *dsa = NULL;
90296465Sdelphij    ASN1_TYPE *t1, *t2;
91296465Sdelphij    ASN1_INTEGER *privkey;
92296465Sdelphij    STACK_OF(ASN1_TYPE) *ndsa = NULL;
93160814Ssimon#endif
94160814Ssimon#ifndef OPENSSL_NO_EC
95296465Sdelphij    EC_KEY *eckey = NULL;
96296465Sdelphij    const unsigned char *p_tmp;
97160814Ssimon#endif
98160814Ssimon#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
99296465Sdelphij    ASN1_TYPE *param = NULL;
100296465Sdelphij    BN_CTX *ctx = NULL;
101296465Sdelphij    int plen;
10255714Skris#endif
103296465Sdelphij    X509_ALGOR *a;
104296465Sdelphij    const unsigned char *p;
105296465Sdelphij    const unsigned char *cp;
106296465Sdelphij    int pkeylen;
107296465Sdelphij    int nid;
108296465Sdelphij    char obj_tmp[80];
10955714Skris
110296465Sdelphij    if (p8->pkey->type == V_ASN1_OCTET_STRING) {
111296465Sdelphij        p8->broken = PKCS8_OK;
112296465Sdelphij        p = p8->pkey->value.octet_string->data;
113296465Sdelphij        pkeylen = p8->pkey->value.octet_string->length;
114296465Sdelphij    } else {
115296465Sdelphij        p8->broken = PKCS8_NO_OCTET;
116296465Sdelphij        p = p8->pkey->value.sequence->data;
117296465Sdelphij        pkeylen = p8->pkey->value.sequence->length;
118296465Sdelphij    }
119296465Sdelphij    if (!(pkey = EVP_PKEY_new())) {
120296465Sdelphij        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
121296465Sdelphij        return NULL;
122296465Sdelphij    }
123296465Sdelphij    a = p8->pkeyalg;
124296465Sdelphij    nid = OBJ_obj2nid(a->algorithm);
125296465Sdelphij    switch (nid) {
126109998Smarkm#ifndef OPENSSL_NO_RSA
127296465Sdelphij    case NID_rsaEncryption:
128296465Sdelphij        cp = p;
129296465Sdelphij        if (!(rsa = d2i_RSAPrivateKey(NULL, &cp, pkeylen))) {
130296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
131296465Sdelphij            return NULL;
132296465Sdelphij        }
133296465Sdelphij        EVP_PKEY_assign_RSA(pkey, rsa);
134296465Sdelphij        break;
13555714Skris#endif
136109998Smarkm#ifndef OPENSSL_NO_DSA
137296465Sdelphij    case NID_dsa:
138296465Sdelphij        /*
139296465Sdelphij         * PKCS#8 DSA is weird: you just get a private key integer and
140296465Sdelphij         * parameters in the AlgorithmIdentifier the pubkey must be
141296465Sdelphij         * recalculated.
142296465Sdelphij         */
14359191Skris
144296465Sdelphij        /* Check for broken DSA PKCS#8, UGH! */
145296465Sdelphij        if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
146296465Sdelphij            if (!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen,
147296465Sdelphij                                                   d2i_ASN1_TYPE,
148296465Sdelphij                                                   ASN1_TYPE_free))) {
149296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
150296465Sdelphij                goto dsaerr;
151296465Sdelphij            }
152296465Sdelphij            if (sk_ASN1_TYPE_num(ndsa) != 2) {
153296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
154296465Sdelphij                goto dsaerr;
155296465Sdelphij            }
156296465Sdelphij            /*
157296465Sdelphij             * Handle Two broken types: SEQUENCE {parameters, priv_key}
158296465Sdelphij             * SEQUENCE {pub_key, priv_key}
159296465Sdelphij             */
16059191Skris
161296465Sdelphij            t1 = sk_ASN1_TYPE_value(ndsa, 0);
162296465Sdelphij            t2 = sk_ASN1_TYPE_value(ndsa, 1);
163296465Sdelphij            if (t1->type == V_ASN1_SEQUENCE) {
164296465Sdelphij                p8->broken = PKCS8_EMBEDDED_PARAM;
165296465Sdelphij                param = t1;
166296465Sdelphij            } else if (a->parameter->type == V_ASN1_SEQUENCE) {
167296465Sdelphij                p8->broken = PKCS8_NS_DB;
168296465Sdelphij                param = a->parameter;
169296465Sdelphij            } else {
170296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
171296465Sdelphij                goto dsaerr;
172296465Sdelphij            }
17355714Skris
174296465Sdelphij            if (t2->type != V_ASN1_INTEGER) {
175296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
176296465Sdelphij                goto dsaerr;
177296465Sdelphij            }
178296465Sdelphij            privkey = t2->value.integer;
179296465Sdelphij        } else {
180296465Sdelphij            if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pkeylen))) {
181296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
182296465Sdelphij                goto dsaerr;
183296465Sdelphij            }
184296465Sdelphij            param = p8->pkeyalg->parameter;
185296465Sdelphij        }
186296465Sdelphij        if (!param || (param->type != V_ASN1_SEQUENCE)) {
187296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
188296465Sdelphij            goto dsaerr;
189296465Sdelphij        }
190296465Sdelphij        cp = p = param->value.sequence->data;
191296465Sdelphij        plen = param->value.sequence->length;
192296465Sdelphij        if (!(dsa = d2i_DSAparams(NULL, &cp, plen))) {
193296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
194296465Sdelphij            goto dsaerr;
195296465Sdelphij        }
196296465Sdelphij        /* We have parameters now set private key */
197296465Sdelphij        if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
198296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_BN_DECODE_ERROR);
199296465Sdelphij            goto dsaerr;
200296465Sdelphij        }
201296465Sdelphij        /* Calculate public key (ouch!) */
202296465Sdelphij        if (!(dsa->pub_key = BN_new())) {
203296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
204296465Sdelphij            goto dsaerr;
205296465Sdelphij        }
206296465Sdelphij        if (!(ctx = BN_CTX_new())) {
207296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
208296465Sdelphij            goto dsaerr;
209296465Sdelphij        }
210296465Sdelphij
211296465Sdelphij        if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
212296465Sdelphij
213296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_BN_PUBKEY_ERROR);
214296465Sdelphij            goto dsaerr;
215296465Sdelphij        }
216296465Sdelphij
217296465Sdelphij        EVP_PKEY_assign_DSA(pkey, dsa);
218296465Sdelphij        BN_CTX_free(ctx);
219296465Sdelphij        if (ndsa)
220296465Sdelphij            sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
221296465Sdelphij        else
222296465Sdelphij            ASN1_INTEGER_free(privkey);
223296465Sdelphij        break;
224296465Sdelphij dsaerr:
225296465Sdelphij        BN_CTX_free(ctx);
226296465Sdelphij        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
227296465Sdelphij        DSA_free(dsa);
228296465Sdelphij        EVP_PKEY_free(pkey);
229296465Sdelphij        return NULL;
230296465Sdelphij        break;
23155714Skris#endif
232160814Ssimon#ifndef OPENSSL_NO_EC
233296465Sdelphij    case NID_X9_62_id_ecPublicKey:
234296465Sdelphij        p_tmp = p;
235296465Sdelphij        /* extract the ec parameters */
236296465Sdelphij        param = p8->pkeyalg->parameter;
237160814Ssimon
238296465Sdelphij        if (!param || ((param->type != V_ASN1_SEQUENCE) &&
239296465Sdelphij                       (param->type != V_ASN1_OBJECT))) {
240296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
241296465Sdelphij            goto ecerr;
242296465Sdelphij        }
243160814Ssimon
244296465Sdelphij        if (param->type == V_ASN1_SEQUENCE) {
245296465Sdelphij            cp = p = param->value.sequence->data;
246296465Sdelphij            plen = param->value.sequence->length;
247160814Ssimon
248296465Sdelphij            if (!(eckey = d2i_ECParameters(NULL, &cp, plen))) {
249296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
250296465Sdelphij                goto ecerr;
251296465Sdelphij            }
252296465Sdelphij        } else {
253296465Sdelphij            EC_GROUP *group;
254296465Sdelphij            cp = p = param->value.object->data;
255296465Sdelphij            plen = param->value.object->length;
256160814Ssimon
257296465Sdelphij            /*
258296465Sdelphij             * type == V_ASN1_OBJECT => the parameters are given by an asn1
259296465Sdelphij             * OID
260296465Sdelphij             */
261296465Sdelphij            if ((eckey = EC_KEY_new()) == NULL) {
262296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
263296465Sdelphij                goto ecerr;
264296465Sdelphij            }
265296465Sdelphij            group =
266296465Sdelphij                EC_GROUP_new_by_curve_name(OBJ_obj2nid
267296465Sdelphij                                           (a->parameter->value.object));
268296465Sdelphij            if (group == NULL)
269296465Sdelphij                goto ecerr;
270296465Sdelphij            EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
271296465Sdelphij            if (EC_KEY_set_group(eckey, group) == 0)
272296465Sdelphij                goto ecerr;
273296465Sdelphij            EC_GROUP_free(group);
274296465Sdelphij        }
275160814Ssimon
276296465Sdelphij        /* We have parameters now set private key */
277296465Sdelphij        if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen)) {
278296465Sdelphij            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
279296465Sdelphij            goto ecerr;
280296465Sdelphij        }
281160814Ssimon
282296465Sdelphij        /* calculate public key (if necessary) */
283296465Sdelphij        if (EC_KEY_get0_public_key(eckey) == NULL) {
284296465Sdelphij            const BIGNUM *priv_key;
285296465Sdelphij            const EC_GROUP *group;
286296465Sdelphij            EC_POINT *pub_key;
287296465Sdelphij            /*
288296465Sdelphij             * the public key was not included in the SEC1 private key =>
289296465Sdelphij             * calculate the public key
290296465Sdelphij             */
291296465Sdelphij            group = EC_KEY_get0_group(eckey);
292296465Sdelphij            pub_key = EC_POINT_new(group);
293296465Sdelphij            if (pub_key == NULL) {
294296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
295296465Sdelphij                goto ecerr;
296296465Sdelphij            }
297296465Sdelphij            if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
298296465Sdelphij                EC_POINT_free(pub_key);
299296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
300296465Sdelphij                goto ecerr;
301296465Sdelphij            }
302296465Sdelphij            priv_key = EC_KEY_get0_private_key(eckey);
303296465Sdelphij            if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) {
304296465Sdelphij                EC_POINT_free(pub_key);
305296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
306296465Sdelphij                goto ecerr;
307296465Sdelphij            }
308296465Sdelphij            if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
309296465Sdelphij                EC_POINT_free(pub_key);
310296465Sdelphij                EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
311296465Sdelphij                goto ecerr;
312296465Sdelphij            }
313296465Sdelphij            EC_POINT_free(pub_key);
314296465Sdelphij        }
315160814Ssimon
316296465Sdelphij        EVP_PKEY_assign_EC_KEY(pkey, eckey);
317296465Sdelphij        if (ctx)
318296465Sdelphij            BN_CTX_free(ctx);
319296465Sdelphij        break;
320296465Sdelphij ecerr:
321296465Sdelphij        if (ctx)
322296465Sdelphij            BN_CTX_free(ctx);
323296465Sdelphij        if (eckey)
324296465Sdelphij            EC_KEY_free(eckey);
325296465Sdelphij        if (pkey)
326296465Sdelphij            EVP_PKEY_free(pkey);
327296465Sdelphij        return NULL;
328160814Ssimon#endif
329296465Sdelphij    default:
330296465Sdelphij        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
331296465Sdelphij        if (!a->algorithm)
332296465Sdelphij            BUF_strlcpy(obj_tmp, "NULL", sizeof obj_tmp);
333296465Sdelphij        else
334296465Sdelphij            i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
335296465Sdelphij        ERR_add_error_data(2, "TYPE=", obj_tmp);
336296465Sdelphij        EVP_PKEY_free(pkey);
337296465Sdelphij        return NULL;
338296465Sdelphij    }
339296465Sdelphij    return pkey;
34055714Skris}
34155714Skris
34259191SkrisPKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
34359191Skris{
344296465Sdelphij    return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
34559191Skris}
34659191Skris
34755714Skris/* Turn a private key into a PKCS8 structure */
34855714Skris
34959191SkrisPKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
35055714Skris{
351296465Sdelphij    PKCS8_PRIV_KEY_INFO *p8;
35259191Skris
353296465Sdelphij    if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
354296465Sdelphij        EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
355296465Sdelphij        return NULL;
356296465Sdelphij    }
357296465Sdelphij    p8->broken = broken;
358296465Sdelphij    if (!ASN1_INTEGER_set(p8->version, 0)) {
359296465Sdelphij        EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
360296465Sdelphij        PKCS8_PRIV_KEY_INFO_free(p8);
361296465Sdelphij        return NULL;
362296465Sdelphij    }
363296465Sdelphij    if (!(p8->pkeyalg->parameter = ASN1_TYPE_new())) {
364296465Sdelphij        EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
365296465Sdelphij        PKCS8_PRIV_KEY_INFO_free(p8);
366296465Sdelphij        return NULL;
367296465Sdelphij    }
368296465Sdelphij    p8->pkey->type = V_ASN1_OCTET_STRING;
369296465Sdelphij    switch (EVP_PKEY_type(pkey->type)) {
370109998Smarkm#ifndef OPENSSL_NO_RSA
371296465Sdelphij    case EVP_PKEY_RSA:
37255714Skris
373296465Sdelphij        if (p8->broken == PKCS8_NO_OCTET)
374296465Sdelphij            p8->pkey->type = V_ASN1_SEQUENCE;
37559191Skris
376296465Sdelphij        p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
377296465Sdelphij        p8->pkeyalg->parameter->type = V_ASN1_NULL;
378296465Sdelphij        if (!ASN1_pack_string_of(EVP_PKEY, pkey, i2d_PrivateKey,
379296465Sdelphij                                 &p8->pkey->value.octet_string)) {
380296465Sdelphij            EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
381296465Sdelphij            PKCS8_PRIV_KEY_INFO_free(p8);
382296465Sdelphij            return NULL;
383296465Sdelphij        }
384296465Sdelphij        break;
38555714Skris#endif
386109998Smarkm#ifndef OPENSSL_NO_DSA
387296465Sdelphij    case EVP_PKEY_DSA:
388296465Sdelphij        if (!dsa_pkey2pkcs8(p8, pkey)) {
389296465Sdelphij            PKCS8_PRIV_KEY_INFO_free(p8);
390296465Sdelphij            return NULL;
391296465Sdelphij        }
39259191Skris
393296465Sdelphij        break;
39455714Skris#endif
395160814Ssimon#ifndef OPENSSL_NO_EC
396296465Sdelphij    case EVP_PKEY_EC:
397296465Sdelphij        if (!eckey_pkey2pkcs8(p8, pkey)) {
398296465Sdelphij            PKCS8_PRIV_KEY_INFO_free(p8);
399296465Sdelphij            return (NULL);
400296465Sdelphij        }
401296465Sdelphij        break;
402160814Ssimon#endif
403296465Sdelphij    default:
404296465Sdelphij        EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
405296465Sdelphij               EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
406296465Sdelphij        PKCS8_PRIV_KEY_INFO_free(p8);
407296465Sdelphij        return NULL;
408296465Sdelphij    }
409296465Sdelphij    RAND_add(p8->pkey->value.octet_string->data,
410296465Sdelphij             p8->pkey->value.octet_string->length, 0.0);
411296465Sdelphij    return p8;
41255714Skris}
41355714Skris
41455714SkrisPKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
41555714Skris{
416296465Sdelphij    switch (broken) {
41755714Skris
418296465Sdelphij    case PKCS8_OK:
419296465Sdelphij        p8->broken = PKCS8_OK;
420296465Sdelphij        return p8;
421296465Sdelphij        break;
42255714Skris
423296465Sdelphij    case PKCS8_NO_OCTET:
424296465Sdelphij        p8->broken = PKCS8_NO_OCTET;
425296465Sdelphij        p8->pkey->type = V_ASN1_SEQUENCE;
426296465Sdelphij        return p8;
427296465Sdelphij        break;
42855714Skris
429296465Sdelphij    default:
430296465Sdelphij        EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
431296465Sdelphij        return NULL;
432296465Sdelphij    }
43355714Skris}
43455714Skris
435109998Smarkm#ifndef OPENSSL_NO_DSA
43659191Skrisstatic int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
43759191Skris{
438296465Sdelphij    ASN1_STRING *params = NULL;
439296465Sdelphij    ASN1_INTEGER *prkey = NULL;
440296465Sdelphij    ASN1_TYPE *ttmp = NULL;
441296465Sdelphij    STACK_OF(ASN1_TYPE) *ndsa = NULL;
442296465Sdelphij    unsigned char *p = NULL, *q;
443296465Sdelphij    int len;
44468651Skris
445296465Sdelphij    p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
446296465Sdelphij    len = i2d_DSAparams(pkey->pkey.dsa, NULL);
447296465Sdelphij    if (!(p = OPENSSL_malloc(len))) {
448296465Sdelphij        EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
449296465Sdelphij        goto err;
450296465Sdelphij    }
451296465Sdelphij    q = p;
452296465Sdelphij    i2d_DSAparams(pkey->pkey.dsa, &q);
453296465Sdelphij    if (!(params = ASN1_STRING_new())) {
454296465Sdelphij        EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
455296465Sdelphij        goto err;
456296465Sdelphij    }
457296465Sdelphij    if (!ASN1_STRING_set(params, p, len)) {
458296465Sdelphij        EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
459296465Sdelphij        goto err;
460296465Sdelphij    }
461296465Sdelphij    OPENSSL_free(p);
462296465Sdelphij    p = NULL;
463296465Sdelphij    /* Get private key into integer */
464296465Sdelphij    if (!(prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL))) {
465296465Sdelphij        EVPerr(EVP_F_DSA_PKEY2PKCS8, EVP_R_ENCODE_ERROR);
466296465Sdelphij        goto err;
467296465Sdelphij    }
46855714Skris
469296465Sdelphij    switch (p8->broken) {
47059191Skris
471296465Sdelphij    case PKCS8_OK:
472296465Sdelphij    case PKCS8_NO_OCTET:
47359191Skris
474296465Sdelphij        if (!ASN1_pack_string_of(ASN1_INTEGER, prkey, i2d_ASN1_INTEGER,
475296465Sdelphij                                 &p8->pkey->value.octet_string)) {
476296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
477296465Sdelphij            goto err;
478296465Sdelphij        }
47959191Skris
480296465Sdelphij        M_ASN1_INTEGER_free(prkey);
481296465Sdelphij        prkey = NULL;
482296465Sdelphij        p8->pkeyalg->parameter->value.sequence = params;
483296465Sdelphij        params = NULL;
484296465Sdelphij        p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
48559191Skris
486296465Sdelphij        break;
48759191Skris
488296465Sdelphij    case PKCS8_NS_DB:
48959191Skris
490296465Sdelphij        p8->pkeyalg->parameter->value.sequence = params;
491296465Sdelphij        params = NULL;
492296465Sdelphij        p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
493296465Sdelphij        if (!(ndsa = sk_ASN1_TYPE_new_null())) {
494296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
495296465Sdelphij            goto err;
496296465Sdelphij        }
497296465Sdelphij        if (!(ttmp = ASN1_TYPE_new())) {
498296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
499296465Sdelphij            goto err;
500296465Sdelphij        }
501296465Sdelphij        if (!(ttmp->value.integer =
502296465Sdelphij              BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
503296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, EVP_R_ENCODE_ERROR);
504296465Sdelphij            goto err;
505296465Sdelphij        }
506296465Sdelphij        ttmp->type = V_ASN1_INTEGER;
507296465Sdelphij        if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
508296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
509296465Sdelphij            goto err;
510296465Sdelphij        }
51159191Skris
512296465Sdelphij        if (!(ttmp = ASN1_TYPE_new())) {
513296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
514296465Sdelphij            goto err;
515296465Sdelphij        }
516296465Sdelphij        ttmp->value.integer = prkey;
517296465Sdelphij        prkey = NULL;
518296465Sdelphij        ttmp->type = V_ASN1_INTEGER;
519296465Sdelphij        if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
520296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
521296465Sdelphij            goto err;
522296465Sdelphij        }
523296465Sdelphij        ttmp = NULL;
52459191Skris
525296465Sdelphij        if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
526296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
527296465Sdelphij            goto err;
528296465Sdelphij        }
52959191Skris
530296465Sdelphij        if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
531296465Sdelphij                                     &p8->pkey->value.octet_string->data,
532296465Sdelphij                                     &p8->pkey->value.octet_string->length)) {
53359191Skris
534296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
535296465Sdelphij            goto err;
536296465Sdelphij        }
537296465Sdelphij        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
538296465Sdelphij        break;
53959191Skris
540296465Sdelphij    case PKCS8_EMBEDDED_PARAM:
54159191Skris
542296465Sdelphij        p8->pkeyalg->parameter->type = V_ASN1_NULL;
543296465Sdelphij        if (!(ndsa = sk_ASN1_TYPE_new_null())) {
544296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
545296465Sdelphij            goto err;
546296465Sdelphij        }
547296465Sdelphij        if (!(ttmp = ASN1_TYPE_new())) {
548296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
549296465Sdelphij            goto err;
550296465Sdelphij        }
551296465Sdelphij        ttmp->value.sequence = params;
552296465Sdelphij        params = NULL;
553296465Sdelphij        ttmp->type = V_ASN1_SEQUENCE;
554296465Sdelphij        if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
555296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
556296465Sdelphij            goto err;
557296465Sdelphij        }
55859191Skris
559296465Sdelphij        if (!(ttmp = ASN1_TYPE_new())) {
560296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
561296465Sdelphij            goto err;
562296465Sdelphij        }
563296465Sdelphij        ttmp->value.integer = prkey;
564296465Sdelphij        prkey = NULL;
565296465Sdelphij        ttmp->type = V_ASN1_INTEGER;
566296465Sdelphij        if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
567296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
568296465Sdelphij            goto err;
569296465Sdelphij        }
570296465Sdelphij        ttmp = NULL;
57159191Skris
572296465Sdelphij        if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
573296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
574296465Sdelphij            goto err;
575296465Sdelphij        }
57659191Skris
577296465Sdelphij        if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
578296465Sdelphij                                     &p8->pkey->value.octet_string->data,
579296465Sdelphij                                     &p8->pkey->value.octet_string->length)) {
58059191Skris
581296465Sdelphij            EVPerr(EVP_F_DSA_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
582296465Sdelphij            goto err;
583296465Sdelphij        }
584296465Sdelphij        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
585296465Sdelphij        break;
586296465Sdelphij    }
587296465Sdelphij    return 1;
588296465Sdelphij err:
589296465Sdelphij    if (p != NULL)
590296465Sdelphij        OPENSSL_free(p);
591296465Sdelphij    if (params != NULL)
592296465Sdelphij        ASN1_STRING_free(params);
593296465Sdelphij    if (prkey != NULL)
594296465Sdelphij        M_ASN1_INTEGER_free(prkey);
595296465Sdelphij    if (ttmp != NULL)
596296465Sdelphij        ASN1_TYPE_free(ttmp);
597296465Sdelphij    if (ndsa != NULL)
598296465Sdelphij        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
599296465Sdelphij    return 0;
60059191Skris}
60159191Skris#endif
602160814Ssimon
603160814Ssimon#ifndef OPENSSL_NO_EC
604160814Ssimonstatic int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
605160814Ssimon{
606296465Sdelphij    EC_KEY *ec_key;
607296465Sdelphij    const EC_GROUP *group;
608296465Sdelphij    unsigned char *p, *pp;
609296465Sdelphij    int nid, i, ret = 0;
610296465Sdelphij    unsigned int tmp_flags, old_flags;
611160814Ssimon
612296465Sdelphij    ec_key = pkey->pkey.ec;
613296465Sdelphij    if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
614296465Sdelphij        EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
615296465Sdelphij        return 0;
616296465Sdelphij    }
617160814Ssimon
618296465Sdelphij    /* set the ec parameters OID */
619296465Sdelphij    if (p8->pkeyalg->algorithm)
620296465Sdelphij        ASN1_OBJECT_free(p8->pkeyalg->algorithm);
621160814Ssimon
622296465Sdelphij    p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey);
623160814Ssimon
624296465Sdelphij    /* set the ec parameters */
625160814Ssimon
626296465Sdelphij    if (p8->pkeyalg->parameter) {
627296465Sdelphij        ASN1_TYPE_free(p8->pkeyalg->parameter);
628296465Sdelphij        p8->pkeyalg->parameter = NULL;
629296465Sdelphij    }
630160814Ssimon
631296465Sdelphij    if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL) {
632296465Sdelphij        EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
633296465Sdelphij        return 0;
634296465Sdelphij    }
635160814Ssimon
636296465Sdelphij    if (EC_GROUP_get_asn1_flag(group)
637296465Sdelphij        && (nid = EC_GROUP_get_curve_name(group))) {
638296465Sdelphij        /* we have a 'named curve' => just set the OID */
639296465Sdelphij        p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
640296465Sdelphij        p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid);
641296465Sdelphij    } else {                    /* explicit parameters */
642160814Ssimon
643296465Sdelphij        if ((i = i2d_ECParameters(ec_key, NULL)) == 0) {
644296465Sdelphij            EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
645296465Sdelphij            return 0;
646296465Sdelphij        }
647296465Sdelphij        if ((p = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
648296465Sdelphij            EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
649296465Sdelphij            return 0;
650296465Sdelphij        }
651296465Sdelphij        pp = p;
652296465Sdelphij        if (!i2d_ECParameters(ec_key, &pp)) {
653296465Sdelphij            EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
654296465Sdelphij            OPENSSL_free(p);
655296465Sdelphij            return 0;
656296465Sdelphij        }
657296465Sdelphij        p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
658296465Sdelphij        if ((p8->pkeyalg->parameter->value.sequence
659296465Sdelphij             = ASN1_STRING_new()) == NULL) {
660296465Sdelphij            EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB);
661296465Sdelphij            OPENSSL_free(p);
662296465Sdelphij            return 0;
663296465Sdelphij        }
664296465Sdelphij        ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i);
665296465Sdelphij        OPENSSL_free(p);
666296465Sdelphij    }
667160814Ssimon
668296465Sdelphij    /* set the private key */
669160814Ssimon
670296465Sdelphij    /*
671296465Sdelphij     * do not include the parameters in the SEC1 private key see PKCS#11
672296465Sdelphij     * 12.11
673296465Sdelphij     */
674296465Sdelphij    old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
675296465Sdelphij    tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
676296465Sdelphij    EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
677296465Sdelphij    i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
678296465Sdelphij    if (!i) {
679296465Sdelphij        EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
680296465Sdelphij        EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
681296465Sdelphij        return 0;
682296465Sdelphij    }
683296465Sdelphij    p = (unsigned char *)OPENSSL_malloc(i);
684296465Sdelphij    if (!p) {
685296465Sdelphij        EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
686296465Sdelphij        EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
687296465Sdelphij        return 0;
688296465Sdelphij    }
689296465Sdelphij    pp = p;
690296465Sdelphij    if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp)) {
691296465Sdelphij        EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
692296465Sdelphij        EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
693296465Sdelphij        OPENSSL_free(p);
694296465Sdelphij        return 0;
695296465Sdelphij    }
696296465Sdelphij    /* restore old encoding flags */
697296465Sdelphij    EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
698160814Ssimon
699296465Sdelphij    switch (p8->broken) {
700296465Sdelphij
701296465Sdelphij    case PKCS8_OK:
702296465Sdelphij        p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();
703296465Sdelphij        if (!p8->pkey->value.octet_string ||
704296465Sdelphij            !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string,
705296465Sdelphij                                     (const void *)p, i)) {
706296465Sdelphij            EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
707296465Sdelphij        } else
708296465Sdelphij            ret = 1;
709296465Sdelphij        break;
710296465Sdelphij    case PKCS8_NO_OCTET:       /* RSA specific */
711296465Sdelphij    case PKCS8_NS_DB:          /* DSA specific */
712296465Sdelphij    case PKCS8_EMBEDDED_PARAM: /* DSA specific */
713296465Sdelphij    default:
714296465Sdelphij        EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_ENCODE_ERROR);
715296465Sdelphij    }
716296465Sdelphij    OPENSSL_cleanse(p, (size_t)i);
717296465Sdelphij    OPENSSL_free(p);
718296465Sdelphij    return ret;
719160814Ssimon}
720160814Ssimon#endif
721160814Ssimon
722160814Ssimon/* EVP_PKEY attribute functions */
723160814Ssimon
724160814Ssimonint EVP_PKEY_get_attr_count(const EVP_PKEY *key)
725160814Ssimon{
726296465Sdelphij    return X509at_get_attr_count(key->attributes);
727160814Ssimon}
728160814Ssimon
729296465Sdelphijint EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
730160814Ssimon{
731296465Sdelphij    return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
732160814Ssimon}
733160814Ssimon
734160814Ssimonint EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
735296465Sdelphij                             int lastpos)
736160814Ssimon{
737296465Sdelphij    return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
738160814Ssimon}
739160814Ssimon
740160814SsimonX509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
741160814Ssimon{
742296465Sdelphij    return X509at_get_attr(key->attributes, loc);
743160814Ssimon}
744160814Ssimon
745160814SsimonX509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
746160814Ssimon{
747296465Sdelphij    return X509at_delete_attr(key->attributes, loc);
748160814Ssimon}
749160814Ssimon
750160814Ssimonint EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
751160814Ssimon{
752296465Sdelphij    if (X509at_add1_attr(&key->attributes, attr))
753296465Sdelphij        return 1;
754296465Sdelphij    return 0;
755160814Ssimon}
756160814Ssimon
757160814Ssimonint EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
758296465Sdelphij                              const ASN1_OBJECT *obj, int type,
759296465Sdelphij                              const unsigned char *bytes, int len)
760160814Ssimon{
761296465Sdelphij    if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
762296465Sdelphij        return 1;
763296465Sdelphij    return 0;
764160814Ssimon}
765160814Ssimon
766160814Ssimonint EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
767296465Sdelphij                              int nid, int type,
768296465Sdelphij                              const unsigned char *bytes, int len)
769160814Ssimon{
770296465Sdelphij    if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
771296465Sdelphij        return 1;
772296465Sdelphij    return 0;
773160814Ssimon}
774160814Ssimon
775160814Ssimonint EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
776296465Sdelphij                              const char *attrname, int type,
777296465Sdelphij                              const unsigned char *bytes, int len)
778160814Ssimon{
779296465Sdelphij    if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len))
780296465Sdelphij        return 1;
781296465Sdelphij    return 0;
782160814Ssimon}
783