1*0Sstevel@tonic-gate /* evp_pkey.c */ 2*0Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3*0Sstevel@tonic-gate * project 1999. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate /* ==================================================================== 6*0Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7*0Sstevel@tonic-gate * 8*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 9*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 10*0Sstevel@tonic-gate * are met: 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 13*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 16*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 17*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 18*0Sstevel@tonic-gate * distribution. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 21*0Sstevel@tonic-gate * software must display the following acknowledgment: 22*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 23*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*0Sstevel@tonic-gate * endorse or promote products derived from this software without 27*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 28*0Sstevel@tonic-gate * licensing@OpenSSL.org. 29*0Sstevel@tonic-gate * 30*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 31*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 32*0Sstevel@tonic-gate * permission of the OpenSSL Project. 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 35*0Sstevel@tonic-gate * acknowledgment: 36*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 37*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 51*0Sstevel@tonic-gate * ==================================================================== 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 54*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 55*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 56*0Sstevel@tonic-gate * 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include <stdlib.h> 61*0Sstevel@tonic-gate #include "cryptlib.h" 62*0Sstevel@tonic-gate #include <openssl/x509.h> 63*0Sstevel@tonic-gate #include <openssl/rand.h> 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 66*0Sstevel@tonic-gate static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8inf, EVP_PKEY *pkey); 67*0Sstevel@tonic-gate #endif 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate /* Extract a private key from a PKCS8 structure */ 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8) 72*0Sstevel@tonic-gate { 73*0Sstevel@tonic-gate EVP_PKEY *pkey = NULL; 74*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 75*0Sstevel@tonic-gate RSA *rsa = NULL; 76*0Sstevel@tonic-gate #endif 77*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 78*0Sstevel@tonic-gate DSA *dsa = NULL; 79*0Sstevel@tonic-gate ASN1_INTEGER *privkey; 80*0Sstevel@tonic-gate ASN1_TYPE *t1, *t2, *param = NULL; 81*0Sstevel@tonic-gate STACK_OF(ASN1_TYPE) *ndsa = NULL; 82*0Sstevel@tonic-gate BN_CTX *ctx = NULL; 83*0Sstevel@tonic-gate int plen; 84*0Sstevel@tonic-gate #endif 85*0Sstevel@tonic-gate X509_ALGOR *a; 86*0Sstevel@tonic-gate unsigned char *p; 87*0Sstevel@tonic-gate const unsigned char *cp; 88*0Sstevel@tonic-gate int pkeylen; 89*0Sstevel@tonic-gate char obj_tmp[80]; 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate if(p8->pkey->type == V_ASN1_OCTET_STRING) { 92*0Sstevel@tonic-gate p8->broken = PKCS8_OK; 93*0Sstevel@tonic-gate p = p8->pkey->value.octet_string->data; 94*0Sstevel@tonic-gate pkeylen = p8->pkey->value.octet_string->length; 95*0Sstevel@tonic-gate } else { 96*0Sstevel@tonic-gate p8->broken = PKCS8_NO_OCTET; 97*0Sstevel@tonic-gate p = p8->pkey->value.sequence->data; 98*0Sstevel@tonic-gate pkeylen = p8->pkey->value.sequence->length; 99*0Sstevel@tonic-gate } 100*0Sstevel@tonic-gate if (!(pkey = EVP_PKEY_new())) { 101*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); 102*0Sstevel@tonic-gate return NULL; 103*0Sstevel@tonic-gate } 104*0Sstevel@tonic-gate a = p8->pkeyalg; 105*0Sstevel@tonic-gate switch (OBJ_obj2nid(a->algorithm)) 106*0Sstevel@tonic-gate { 107*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 108*0Sstevel@tonic-gate case NID_rsaEncryption: 109*0Sstevel@tonic-gate cp = p; 110*0Sstevel@tonic-gate if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) { 111*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 112*0Sstevel@tonic-gate return NULL; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate EVP_PKEY_assign_RSA (pkey, rsa); 115*0Sstevel@tonic-gate break; 116*0Sstevel@tonic-gate #endif 117*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 118*0Sstevel@tonic-gate case NID_dsa: 119*0Sstevel@tonic-gate /* PKCS#8 DSA is weird: you just get a private key integer 120*0Sstevel@tonic-gate * and parameters in the AlgorithmIdentifier the pubkey must 121*0Sstevel@tonic-gate * be recalculated. 122*0Sstevel@tonic-gate */ 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate /* Check for broken DSA PKCS#8, UGH! */ 125*0Sstevel@tonic-gate if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { 126*0Sstevel@tonic-gate if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, 127*0Sstevel@tonic-gate d2i_ASN1_TYPE, 128*0Sstevel@tonic-gate ASN1_TYPE_free))) { 129*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 130*0Sstevel@tonic-gate goto dsaerr; 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate if(sk_ASN1_TYPE_num(ndsa) != 2 ) { 133*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 134*0Sstevel@tonic-gate goto dsaerr; 135*0Sstevel@tonic-gate } 136*0Sstevel@tonic-gate /* Handle Two broken types: 137*0Sstevel@tonic-gate * SEQUENCE {parameters, priv_key} 138*0Sstevel@tonic-gate * SEQUENCE {pub_key, priv_key} 139*0Sstevel@tonic-gate */ 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate t1 = sk_ASN1_TYPE_value(ndsa, 0); 142*0Sstevel@tonic-gate t2 = sk_ASN1_TYPE_value(ndsa, 1); 143*0Sstevel@tonic-gate if(t1->type == V_ASN1_SEQUENCE) { 144*0Sstevel@tonic-gate p8->broken = PKCS8_EMBEDDED_PARAM; 145*0Sstevel@tonic-gate param = t1; 146*0Sstevel@tonic-gate } else if(a->parameter->type == V_ASN1_SEQUENCE) { 147*0Sstevel@tonic-gate p8->broken = PKCS8_NS_DB; 148*0Sstevel@tonic-gate param = a->parameter; 149*0Sstevel@tonic-gate } else { 150*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 151*0Sstevel@tonic-gate goto dsaerr; 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate if(t2->type != V_ASN1_INTEGER) { 155*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 156*0Sstevel@tonic-gate goto dsaerr; 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate privkey = t2->value.integer; 159*0Sstevel@tonic-gate } else { 160*0Sstevel@tonic-gate if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { 161*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 162*0Sstevel@tonic-gate goto dsaerr; 163*0Sstevel@tonic-gate } 164*0Sstevel@tonic-gate param = p8->pkeyalg->parameter; 165*0Sstevel@tonic-gate } 166*0Sstevel@tonic-gate if (!param || (param->type != V_ASN1_SEQUENCE)) { 167*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 168*0Sstevel@tonic-gate goto dsaerr; 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate cp = p = param->value.sequence->data; 171*0Sstevel@tonic-gate plen = param->value.sequence->length; 172*0Sstevel@tonic-gate if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) { 173*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); 174*0Sstevel@tonic-gate goto dsaerr; 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate /* We have parameters now set private key */ 177*0Sstevel@tonic-gate if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { 178*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); 179*0Sstevel@tonic-gate goto dsaerr; 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate /* Calculate public key (ouch!) */ 182*0Sstevel@tonic-gate if (!(dsa->pub_key = BN_new())) { 183*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); 184*0Sstevel@tonic-gate goto dsaerr; 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate if (!(ctx = BN_CTX_new())) { 187*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); 188*0Sstevel@tonic-gate goto dsaerr; 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate if (!BN_mod_exp(dsa->pub_key, dsa->g, 192*0Sstevel@tonic-gate dsa->priv_key, dsa->p, ctx)) { 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); 195*0Sstevel@tonic-gate goto dsaerr; 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate EVP_PKEY_assign_DSA(pkey, dsa); 199*0Sstevel@tonic-gate BN_CTX_free (ctx); 200*0Sstevel@tonic-gate if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 201*0Sstevel@tonic-gate else ASN1_INTEGER_free(privkey); 202*0Sstevel@tonic-gate break; 203*0Sstevel@tonic-gate dsaerr: 204*0Sstevel@tonic-gate BN_CTX_free (ctx); 205*0Sstevel@tonic-gate sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 206*0Sstevel@tonic-gate DSA_free(dsa); 207*0Sstevel@tonic-gate EVP_PKEY_free(pkey); 208*0Sstevel@tonic-gate return NULL; 209*0Sstevel@tonic-gate break; 210*0Sstevel@tonic-gate #endif 211*0Sstevel@tonic-gate default: 212*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); 213*0Sstevel@tonic-gate if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); 214*0Sstevel@tonic-gate else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); 215*0Sstevel@tonic-gate ERR_add_error_data(2, "TYPE=", obj_tmp); 216*0Sstevel@tonic-gate EVP_PKEY_free (pkey); 217*0Sstevel@tonic-gate return NULL; 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate return pkey; 220*0Sstevel@tonic-gate } 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) 223*0Sstevel@tonic-gate { 224*0Sstevel@tonic-gate return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK); 225*0Sstevel@tonic-gate } 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate /* Turn a private key into a PKCS8 structure */ 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) 230*0Sstevel@tonic-gate { 231*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *p8; 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { 234*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 235*0Sstevel@tonic-gate return NULL; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate p8->broken = broken; 238*0Sstevel@tonic-gate ASN1_INTEGER_set (p8->version, 0); 239*0Sstevel@tonic-gate if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) { 240*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 241*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free (p8); 242*0Sstevel@tonic-gate return NULL; 243*0Sstevel@tonic-gate } 244*0Sstevel@tonic-gate p8->pkey->type = V_ASN1_OCTET_STRING; 245*0Sstevel@tonic-gate switch (EVP_PKEY_type(pkey->type)) { 246*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 247*0Sstevel@tonic-gate case EVP_PKEY_RSA: 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE; 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption); 252*0Sstevel@tonic-gate p8->pkeyalg->parameter->type = V_ASN1_NULL; 253*0Sstevel@tonic-gate if (!ASN1_pack_string ((char *)pkey, i2d_PrivateKey, 254*0Sstevel@tonic-gate &p8->pkey->value.octet_string)) { 255*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 256*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free (p8); 257*0Sstevel@tonic-gate return NULL; 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate break; 260*0Sstevel@tonic-gate #endif 261*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 262*0Sstevel@tonic-gate case EVP_PKEY_DSA: 263*0Sstevel@tonic-gate if(!dsa_pkey2pkcs8(p8, pkey)) { 264*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free (p8); 265*0Sstevel@tonic-gate return NULL; 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate break; 269*0Sstevel@tonic-gate #endif 270*0Sstevel@tonic-gate default: 271*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); 272*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free (p8); 273*0Sstevel@tonic-gate return NULL; 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate RAND_add(p8->pkey->value.octet_string->data, 276*0Sstevel@tonic-gate p8->pkey->value.octet_string->length, 0); 277*0Sstevel@tonic-gate return p8; 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) 281*0Sstevel@tonic-gate { 282*0Sstevel@tonic-gate switch (broken) { 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate case PKCS8_OK: 285*0Sstevel@tonic-gate p8->broken = PKCS8_OK; 286*0Sstevel@tonic-gate return p8; 287*0Sstevel@tonic-gate break; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate case PKCS8_NO_OCTET: 290*0Sstevel@tonic-gate p8->broken = PKCS8_NO_OCTET; 291*0Sstevel@tonic-gate p8->pkey->type = V_ASN1_SEQUENCE; 292*0Sstevel@tonic-gate return p8; 293*0Sstevel@tonic-gate break; 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate default: 296*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); 297*0Sstevel@tonic-gate return NULL; 298*0Sstevel@tonic-gate break; 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate } 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 304*0Sstevel@tonic-gate static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) 305*0Sstevel@tonic-gate { 306*0Sstevel@tonic-gate ASN1_STRING *params; 307*0Sstevel@tonic-gate ASN1_INTEGER *prkey; 308*0Sstevel@tonic-gate ASN1_TYPE *ttmp; 309*0Sstevel@tonic-gate STACK_OF(ASN1_TYPE) *ndsa; 310*0Sstevel@tonic-gate unsigned char *p, *q; 311*0Sstevel@tonic-gate int len; 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa); 314*0Sstevel@tonic-gate len = i2d_DSAparams (pkey->pkey.dsa, NULL); 315*0Sstevel@tonic-gate if (!(p = OPENSSL_malloc(len))) { 316*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 317*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free (p8); 318*0Sstevel@tonic-gate return 0; 319*0Sstevel@tonic-gate } 320*0Sstevel@tonic-gate q = p; 321*0Sstevel@tonic-gate i2d_DSAparams (pkey->pkey.dsa, &q); 322*0Sstevel@tonic-gate params = ASN1_STRING_new(); 323*0Sstevel@tonic-gate ASN1_STRING_set(params, p, len); 324*0Sstevel@tonic-gate OPENSSL_free(p); 325*0Sstevel@tonic-gate /* Get private key into integer */ 326*0Sstevel@tonic-gate if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) { 327*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR); 328*0Sstevel@tonic-gate return 0; 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate switch(p8->broken) { 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate case PKCS8_OK: 334*0Sstevel@tonic-gate case PKCS8_NO_OCTET: 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate if (!ASN1_pack_string((char *)prkey, i2d_ASN1_INTEGER, 337*0Sstevel@tonic-gate &p8->pkey->value.octet_string)) { 338*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 339*0Sstevel@tonic-gate M_ASN1_INTEGER_free (prkey); 340*0Sstevel@tonic-gate return 0; 341*0Sstevel@tonic-gate } 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gate M_ASN1_INTEGER_free (prkey); 344*0Sstevel@tonic-gate p8->pkeyalg->parameter->value.sequence = params; 345*0Sstevel@tonic-gate p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate break; 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate case PKCS8_NS_DB: 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate p8->pkeyalg->parameter->value.sequence = params; 352*0Sstevel@tonic-gate p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; 353*0Sstevel@tonic-gate ndsa = sk_ASN1_TYPE_new_null(); 354*0Sstevel@tonic-gate ttmp = ASN1_TYPE_new(); 355*0Sstevel@tonic-gate if (!(ttmp->value.integer = BN_to_ASN1_INTEGER (pkey->pkey.dsa->pub_key, NULL))) { 356*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR); 357*0Sstevel@tonic-gate PKCS8_PRIV_KEY_INFO_free(p8); 358*0Sstevel@tonic-gate return 0; 359*0Sstevel@tonic-gate } 360*0Sstevel@tonic-gate ttmp->type = V_ASN1_INTEGER; 361*0Sstevel@tonic-gate sk_ASN1_TYPE_push(ndsa, ttmp); 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate ttmp = ASN1_TYPE_new(); 364*0Sstevel@tonic-gate ttmp->value.integer = prkey; 365*0Sstevel@tonic-gate ttmp->type = V_ASN1_INTEGER; 366*0Sstevel@tonic-gate sk_ASN1_TYPE_push(ndsa, ttmp); 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gate p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, 371*0Sstevel@tonic-gate &p8->pkey->value.octet_string->data, 372*0Sstevel@tonic-gate &p8->pkey->value.octet_string->length)) { 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 375*0Sstevel@tonic-gate sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 376*0Sstevel@tonic-gate M_ASN1_INTEGER_free(prkey); 377*0Sstevel@tonic-gate return 0; 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 380*0Sstevel@tonic-gate break; 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate case PKCS8_EMBEDDED_PARAM: 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gate p8->pkeyalg->parameter->type = V_ASN1_NULL; 385*0Sstevel@tonic-gate ndsa = sk_ASN1_TYPE_new_null(); 386*0Sstevel@tonic-gate ttmp = ASN1_TYPE_new(); 387*0Sstevel@tonic-gate ttmp->value.sequence = params; 388*0Sstevel@tonic-gate ttmp->type = V_ASN1_SEQUENCE; 389*0Sstevel@tonic-gate sk_ASN1_TYPE_push(ndsa, ttmp); 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate ttmp = ASN1_TYPE_new(); 392*0Sstevel@tonic-gate ttmp->value.integer = prkey; 393*0Sstevel@tonic-gate ttmp->type = V_ASN1_INTEGER; 394*0Sstevel@tonic-gate sk_ASN1_TYPE_push(ndsa, ttmp); 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gate if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, 399*0Sstevel@tonic-gate &p8->pkey->value.octet_string->data, 400*0Sstevel@tonic-gate &p8->pkey->value.octet_string->length)) { 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); 403*0Sstevel@tonic-gate sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 404*0Sstevel@tonic-gate M_ASN1_INTEGER_free (prkey); 405*0Sstevel@tonic-gate return 0; 406*0Sstevel@tonic-gate } 407*0Sstevel@tonic-gate sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); 408*0Sstevel@tonic-gate break; 409*0Sstevel@tonic-gate } 410*0Sstevel@tonic-gate return 1; 411*0Sstevel@tonic-gate } 412*0Sstevel@tonic-gate #endif 413