155714Skris/* p12_add.c */ 2280297Sjkim/* 3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280297Sjkim * 1999. 555714Skris */ 655714Skris/* ==================================================================== 755714Skris * Copyright (c) 1999 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 6455714Skris/* Pack an object into an OCTET STRING and turn into a safebag */ 6555714Skris 66280297SjkimPKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, 67280297Sjkim int nid1, int nid2) 6855714Skris{ 69280297Sjkim PKCS12_BAGS *bag; 70280297Sjkim PKCS12_SAFEBAG *safebag; 71280297Sjkim if (!(bag = PKCS12_BAGS_new())) { 72280297Sjkim PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); 73280297Sjkim return NULL; 74280297Sjkim } 75280297Sjkim bag->type = OBJ_nid2obj(nid1); 76280297Sjkim if (!ASN1_item_pack(obj, it, &bag->value.octet)) { 77280297Sjkim PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); 78291719Sjkim goto err; 79280297Sjkim } 80280297Sjkim if (!(safebag = PKCS12_SAFEBAG_new())) { 81280297Sjkim PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); 82291719Sjkim goto err; 83280297Sjkim } 84280297Sjkim safebag->value.bag = bag; 85280297Sjkim safebag->type = OBJ_nid2obj(nid2); 86280297Sjkim return safebag; 87291719Sjkim 88291719Sjkim err: 89291719Sjkim PKCS12_BAGS_free(bag); 90291719Sjkim return NULL; 9155714Skris} 9255714Skris 9355714Skris/* Turn PKCS8 object into a keybag */ 9455714Skris 95109998SmarkmPKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) 9655714Skris{ 97280297Sjkim PKCS12_SAFEBAG *bag; 98280297Sjkim if (!(bag = PKCS12_SAFEBAG_new())) { 99280297Sjkim PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE); 100280297Sjkim return NULL; 101280297Sjkim } 102280297Sjkim bag->type = OBJ_nid2obj(NID_keyBag); 103280297Sjkim bag->value.keybag = p8; 104280297Sjkim return bag; 10555714Skris} 10655714Skris 10755714Skris/* Turn PKCS8 object into a shrouded keybag */ 10855714Skris 109109998SmarkmPKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, 110280297Sjkim int passlen, unsigned char *salt, 111280297Sjkim int saltlen, int iter, 112280297Sjkim PKCS8_PRIV_KEY_INFO *p8) 11355714Skris{ 114280297Sjkim PKCS12_SAFEBAG *bag; 115280297Sjkim const EVP_CIPHER *pbe_ciph; 11655714Skris 117280297Sjkim /* Set up the safe bag */ 118280297Sjkim if (!(bag = PKCS12_SAFEBAG_new())) { 119280297Sjkim PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); 120280297Sjkim return NULL; 121280297Sjkim } 12255714Skris 123280297Sjkim bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); 124238405Sjkim 125280297Sjkim pbe_ciph = EVP_get_cipherbynid(pbe_nid); 126238405Sjkim 127280297Sjkim if (pbe_ciph) 128280297Sjkim pbe_nid = -1; 129238405Sjkim 130280297Sjkim if (!(bag->value.shkeybag = 131280297Sjkim PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, 132280297Sjkim p8))) { 133280297Sjkim PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); 134291719Sjkim PKCS12_SAFEBAG_free(bag); 135280297Sjkim return NULL; 136280297Sjkim } 13755714Skris 138280297Sjkim return bag; 13955714Skris} 14055714Skris 14155714Skris/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ 142109998SmarkmPKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) 14355714Skris{ 144280297Sjkim PKCS7 *p7; 145280297Sjkim if (!(p7 = PKCS7_new())) { 146280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); 147280297Sjkim return NULL; 148280297Sjkim } 149280297Sjkim p7->type = OBJ_nid2obj(NID_pkcs7_data); 150280297Sjkim if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) { 151280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); 152291719Sjkim goto err; 153280297Sjkim } 154280297Sjkim 155280297Sjkim if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) { 156280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); 157291719Sjkim goto err; 158280297Sjkim } 159280297Sjkim return p7; 160291719Sjkim 161291719Sjkim err: 162291719Sjkim PKCS7_free(p7); 163291719Sjkim return NULL; 16455714Skris} 16555714Skris 166109998Smarkm/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ 167109998SmarkmSTACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) 168109998Smarkm{ 169280297Sjkim if (!PKCS7_type_is_data(p7)) { 170280297Sjkim PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, 171280297Sjkim PKCS12_R_CONTENT_TYPE_NOT_DATA); 172280297Sjkim return NULL; 173280297Sjkim } 174280297Sjkim return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); 175109998Smarkm} 176109998Smarkm 17755714Skris/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ 17855714Skris 179109998SmarkmPKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, 180280297Sjkim unsigned char *salt, int saltlen, int iter, 181280297Sjkim STACK_OF(PKCS12_SAFEBAG) *bags) 18255714Skris{ 183280297Sjkim PKCS7 *p7; 184280297Sjkim X509_ALGOR *pbe; 185280297Sjkim const EVP_CIPHER *pbe_ciph; 186280297Sjkim if (!(p7 = PKCS7_new())) { 187280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); 188280297Sjkim return NULL; 189280297Sjkim } 190280297Sjkim if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { 191280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, 192280297Sjkim PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); 193291719Sjkim goto err; 194280297Sjkim } 195238405Sjkim 196280297Sjkim pbe_ciph = EVP_get_cipherbynid(pbe_nid); 197238405Sjkim 198280297Sjkim if (pbe_ciph) 199280297Sjkim pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); 200280297Sjkim else 201280297Sjkim pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); 202238405Sjkim 203280297Sjkim if (!pbe) { 204280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); 205291719Sjkim goto err; 206280297Sjkim } 207280297Sjkim X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); 208280297Sjkim p7->d.encrypted->enc_data->algorithm = pbe; 209280297Sjkim M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); 210280297Sjkim if (!(p7->d.encrypted->enc_data->enc_data = 211280297Sjkim PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, 212280297Sjkim passlen, bags, 1))) { 213280297Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); 214291719Sjkim goto err; 215280297Sjkim } 21655714Skris 217280297Sjkim return p7; 218291719Sjkim 219291719Sjkim err: 220291719Sjkim PKCS7_free(p7); 221291719Sjkim return NULL; 22255714Skris} 22355714Skris 224280297SjkimSTACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, 225280297Sjkim int passlen) 22655714Skris{ 227280297Sjkim if (!PKCS7_type_is_encrypted(p7)) 228280297Sjkim return NULL; 229280297Sjkim return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, 230280297Sjkim ASN1_ITEM_rptr(PKCS12_SAFEBAGS), 231280297Sjkim pass, passlen, 232280297Sjkim p7->d.encrypted->enc_data->enc_data, 1); 233109998Smarkm} 23455714Skris 235280297SjkimPKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, 236280297Sjkim const char *pass, int passlen) 237109998Smarkm{ 238280297Sjkim return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); 239109998Smarkm} 24055714Skris 241280297Sjkimint PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) 242109998Smarkm{ 243280297Sjkim if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES), 244280297Sjkim &p12->authsafes->d.data)) 245280297Sjkim return 1; 246280297Sjkim return 0; 247109998Smarkm} 24855714Skris 249109998SmarkmSTACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12) 250109998Smarkm{ 251280297Sjkim if (!PKCS7_type_is_data(p12->authsafes)) { 252280297Sjkim PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, 253280297Sjkim PKCS12_R_CONTENT_TYPE_NOT_DATA); 254280297Sjkim return NULL; 255280297Sjkim } 256280297Sjkim return ASN1_item_unpack(p12->authsafes->d.data, 257280297Sjkim ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); 25855714Skris} 259