155714Skris/* p12_crt.c */ 2280297Sjkim/* 3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4160814Ssimon * project. 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 14280297Sjkim * 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 "cryptlib.h" 6255714Skris#include <openssl/pkcs12.h> 6355714Skris 64280297Sjkimstatic int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, 65280297Sjkim PKCS12_SAFEBAG *bag); 66160814Ssimon 67194206Ssimonstatic int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) 68280297Sjkim{ 69280297Sjkim int idx; 70280297Sjkim X509_ATTRIBUTE *attr; 71280297Sjkim idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); 72280297Sjkim if (idx < 0) 73280297Sjkim return 1; 74280297Sjkim attr = EVP_PKEY_get_attr(pkey, idx); 75280297Sjkim if (!X509at_add1_attr(&bag->attrib, attr)) 76280297Sjkim return 0; 77280297Sjkim return 1; 78280297Sjkim} 79194206Ssimon 8055714SkrisPKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, 81280297Sjkim STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, 82280297Sjkim int mac_iter, int keytype) 8355714Skris{ 84280297Sjkim PKCS12 *p12 = NULL; 85280297Sjkim STACK_OF(PKCS7) *safes = NULL; 86280297Sjkim STACK_OF(PKCS12_SAFEBAG) *bags = NULL; 87280297Sjkim PKCS12_SAFEBAG *bag = NULL; 88280297Sjkim int i; 89280297Sjkim unsigned char keyid[EVP_MAX_MD_SIZE]; 90280297Sjkim unsigned int keyidlen = 0; 9155714Skris 92280297Sjkim /* Set defaults */ 93280297Sjkim if (!nid_cert) { 94261037Sjkim#ifdef OPENSSL_FIPS 95280297Sjkim if (FIPS_mode()) 96280297Sjkim nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 97280297Sjkim else 98261037Sjkim#endif 99267256Sjkim#ifdef OPENSSL_NO_RC2 100280297Sjkim nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 101267256Sjkim#else 102280297Sjkim nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; 103267256Sjkim#endif 104280297Sjkim } 105280297Sjkim if (!nid_key) 106280297Sjkim nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 107280297Sjkim if (!iter) 108280297Sjkim iter = PKCS12_DEFAULT_ITER; 109280297Sjkim if (!mac_iter) 110280297Sjkim mac_iter = 1; 11155714Skris 112280297Sjkim if (!pkey && !cert && !ca) { 113280297Sjkim PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT); 114280297Sjkim return NULL; 115280297Sjkim } 11655714Skris 117280297Sjkim if (pkey && cert) { 118280297Sjkim if (!X509_check_private_key(cert, pkey)) 119280297Sjkim return NULL; 120280297Sjkim X509_digest(cert, EVP_sha1(), keyid, &keyidlen); 121280297Sjkim } 12268651Skris 123280297Sjkim if (cert) { 124280297Sjkim bag = PKCS12_add_cert(&bags, cert); 125280297Sjkim if (name && !PKCS12_add_friendlyname(bag, name, -1)) 126280297Sjkim goto err; 127280297Sjkim if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) 128280297Sjkim goto err; 129280297Sjkim } 13055714Skris 131280297Sjkim /* Add all other certificates */ 132280297Sjkim for (i = 0; i < sk_X509_num(ca); i++) { 133280297Sjkim if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) 134280297Sjkim goto err; 135280297Sjkim } 136160814Ssimon 137280297Sjkim if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass)) 138280297Sjkim goto err; 139160814Ssimon 140280297Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 141280297Sjkim bags = NULL; 142160814Ssimon 143280297Sjkim if (pkey) { 144280297Sjkim bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); 145160814Ssimon 146280297Sjkim if (!bag) 147280297Sjkim goto err; 148160814Ssimon 149280297Sjkim if (!copy_bag_attr(bag, pkey, NID_ms_csp_name)) 150280297Sjkim goto err; 151280297Sjkim if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) 152280297Sjkim goto err; 153160814Ssimon 154280297Sjkim if (name && !PKCS12_add_friendlyname(bag, name, -1)) 155280297Sjkim goto err; 156280297Sjkim if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) 157280297Sjkim goto err; 158280297Sjkim } 159160814Ssimon 160280297Sjkim if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) 161280297Sjkim goto err; 162160814Ssimon 163280297Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 164280297Sjkim bags = NULL; 165160814Ssimon 166280297Sjkim p12 = PKCS12_add_safes(safes, 0); 167160814Ssimon 168280297Sjkim if (!p12) 169280297Sjkim goto err; 170194206Ssimon 171280297Sjkim sk_PKCS7_pop_free(safes, PKCS7_free); 172160814Ssimon 173280297Sjkim safes = NULL; 174160814Ssimon 175280297Sjkim if ((mac_iter != -1) && 176280297Sjkim !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL)) 177280297Sjkim goto err; 178160814Ssimon 179280297Sjkim return p12; 180160814Ssimon 181280297Sjkim err: 182160814Ssimon 183280297Sjkim if (p12) 184280297Sjkim PKCS12_free(p12); 185280297Sjkim if (safes) 186280297Sjkim sk_PKCS7_pop_free(safes, PKCS7_free); 187280297Sjkim if (bags) 188280297Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 189280297Sjkim return NULL; 190160814Ssimon 191160814Ssimon} 192160814Ssimon 193160814SsimonPKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) 194280297Sjkim{ 195280297Sjkim PKCS12_SAFEBAG *bag = NULL; 196280297Sjkim char *name; 197280297Sjkim int namelen = -1; 198280297Sjkim unsigned char *keyid; 199280297Sjkim int keyidlen = -1; 200160814Ssimon 201280297Sjkim /* Add user certificate */ 202280297Sjkim if (!(bag = PKCS12_x5092certbag(cert))) 203280297Sjkim goto err; 20455714Skris 205280297Sjkim /* 206280297Sjkim * Use friendlyName and localKeyID in certificate. (if present) 207280297Sjkim */ 208160814Ssimon 209280297Sjkim name = (char *)X509_alias_get0(cert, &namelen); 210160814Ssimon 211280297Sjkim if (name && !PKCS12_add_friendlyname(bag, name, namelen)) 212280297Sjkim goto err; 213160814Ssimon 214280297Sjkim keyid = X509_keyid_get0(cert, &keyidlen); 215160814Ssimon 216280297Sjkim if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) 217280297Sjkim goto err; 218160814Ssimon 219280297Sjkim if (!pkcs12_add_bag(pbags, bag)) 220280297Sjkim goto err; 221160814Ssimon 222280297Sjkim return bag; 223160814Ssimon 224280297Sjkim err: 225160814Ssimon 226280297Sjkim if (bag) 227280297Sjkim PKCS12_SAFEBAG_free(bag); 228160814Ssimon 229280297Sjkim return NULL; 230160814Ssimon 231280297Sjkim} 232160814Ssimon 233280297SjkimPKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, 234280297Sjkim EVP_PKEY *key, int key_usage, int iter, 235280297Sjkim int nid_key, char *pass) 236280297Sjkim{ 237160814Ssimon 238280297Sjkim PKCS12_SAFEBAG *bag = NULL; 239280297Sjkim PKCS8_PRIV_KEY_INFO *p8 = NULL; 240160814Ssimon 241280297Sjkim /* Make a PKCS#8 structure */ 242280297Sjkim if (!(p8 = EVP_PKEY2PKCS8(key))) 243280297Sjkim goto err; 244280297Sjkim if (key_usage && !PKCS8_add_keyusage(p8, key_usage)) 245280297Sjkim goto err; 246280297Sjkim if (nid_key != -1) { 247280297Sjkim bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8); 248280297Sjkim PKCS8_PRIV_KEY_INFO_free(p8); 249280297Sjkim } else 250280297Sjkim bag = PKCS12_MAKE_KEYBAG(p8); 251160814Ssimon 252280297Sjkim if (!bag) 253280297Sjkim goto err; 254160814Ssimon 255280297Sjkim if (!pkcs12_add_bag(pbags, bag)) 256280297Sjkim goto err; 257160814Ssimon 258280297Sjkim return bag; 259160814Ssimon 260280297Sjkim err: 261160814Ssimon 262280297Sjkim if (bag) 263280297Sjkim PKCS12_SAFEBAG_free(bag); 264160814Ssimon 265280297Sjkim return NULL; 266160814Ssimon 267280297Sjkim} 26855714Skris 269160814Ssimonint PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, 270280297Sjkim int nid_safe, int iter, char *pass) 271280297Sjkim{ 272280297Sjkim PKCS7 *p7 = NULL; 273280297Sjkim int free_safes = 0; 274160814Ssimon 275280297Sjkim if (!*psafes) { 276280297Sjkim *psafes = sk_PKCS7_new_null(); 277280297Sjkim if (!*psafes) 278280297Sjkim return 0; 279280297Sjkim free_safes = 1; 280280297Sjkim } else 281280297Sjkim free_safes = 0; 282160814Ssimon 283280297Sjkim if (nid_safe == 0) 284267256Sjkim#ifdef OPENSSL_NO_RC2 285280297Sjkim nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; 286267256Sjkim#else 287280297Sjkim nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC; 288267256Sjkim#endif 289160814Ssimon 290280297Sjkim if (nid_safe == -1) 291280297Sjkim p7 = PKCS12_pack_p7data(bags); 292280297Sjkim else 293280297Sjkim p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags); 294280297Sjkim if (!p7) 295280297Sjkim goto err; 29655714Skris 297280297Sjkim if (!sk_PKCS7_push(*psafes, p7)) 298280297Sjkim goto err; 29955714Skris 300280297Sjkim return 1; 301160814Ssimon 302280297Sjkim err: 303280297Sjkim if (free_safes) { 304280297Sjkim sk_PKCS7_free(*psafes); 305280297Sjkim *psafes = NULL; 306280297Sjkim } 307160814Ssimon 308280297Sjkim if (p7) 309280297Sjkim PKCS7_free(p7); 310160814Ssimon 311280297Sjkim return 0; 312160814Ssimon 313280297Sjkim} 31455714Skris 315280297Sjkimstatic int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, 316280297Sjkim PKCS12_SAFEBAG *bag) 317280297Sjkim{ 318280297Sjkim int free_bags; 319280297Sjkim if (!pbags) 320280297Sjkim return 1; 321280297Sjkim if (!*pbags) { 322280297Sjkim *pbags = sk_PKCS12_SAFEBAG_new_null(); 323280297Sjkim if (!*pbags) 324280297Sjkim return 0; 325280297Sjkim free_bags = 1; 326280297Sjkim } else 327280297Sjkim free_bags = 0; 328160814Ssimon 329280297Sjkim if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) { 330280297Sjkim if (free_bags) { 331280297Sjkim sk_PKCS12_SAFEBAG_free(*pbags); 332280297Sjkim *pbags = NULL; 333280297Sjkim } 334280297Sjkim return 0; 335280297Sjkim } 336160814Ssimon 337280297Sjkim return 1; 338160814Ssimon 339280297Sjkim} 34055714Skris 341160814SsimonPKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) 342280297Sjkim{ 343280297Sjkim PKCS12 *p12; 344280297Sjkim if (nid_p7 <= 0) 345280297Sjkim nid_p7 = NID_pkcs7_data; 346280297Sjkim p12 = PKCS12_init(nid_p7); 34755714Skris 348280297Sjkim if (!p12) 349280297Sjkim return NULL; 35055714Skris 351280297Sjkim if (!PKCS12_pack_authsafes(p12, safes)) { 352280297Sjkim PKCS12_free(p12); 353280297Sjkim return NULL; 354280297Sjkim } 35555714Skris 356280297Sjkim return p12; 35755714Skris 358280297Sjkim} 359