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