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