155714Skris/* p12_add.c */ 2280304Sjkim/* 3280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280304Sjkim * 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 14280304Sjkim * 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 66280304SjkimPKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, 67280304Sjkim int nid1, int nid2) 6855714Skris{ 69280304Sjkim PKCS12_BAGS *bag; 70280304Sjkim PKCS12_SAFEBAG *safebag; 71280304Sjkim if (!(bag = PKCS12_BAGS_new())) { 72280304Sjkim PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); 73280304Sjkim return NULL; 74280304Sjkim } 75280304Sjkim bag->type = OBJ_nid2obj(nid1); 76280304Sjkim if (!ASN1_item_pack(obj, it, &bag->value.octet)) { 77280304Sjkim PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); 78291721Sjkim goto err; 79280304Sjkim } 80280304Sjkim if (!(safebag = PKCS12_SAFEBAG_new())) { 81280304Sjkim PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); 82291721Sjkim goto err; 83280304Sjkim } 84280304Sjkim safebag->value.bag = bag; 85280304Sjkim safebag->type = OBJ_nid2obj(nid2); 86280304Sjkim return safebag; 87291721Sjkim 88291721Sjkim err: 89291721Sjkim PKCS12_BAGS_free(bag); 90291721Sjkim return NULL; 9155714Skris} 9255714Skris 9355714Skris/* Turn PKCS8 object into a keybag */ 9455714Skris 95109998SmarkmPKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) 9655714Skris{ 97280304Sjkim PKCS12_SAFEBAG *bag; 98280304Sjkim if (!(bag = PKCS12_SAFEBAG_new())) { 99280304Sjkim PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE); 100280304Sjkim return NULL; 101280304Sjkim } 102280304Sjkim bag->type = OBJ_nid2obj(NID_keyBag); 103280304Sjkim bag->value.keybag = p8; 104280304Sjkim return bag; 10555714Skris} 10655714Skris 10755714Skris/* Turn PKCS8 object into a shrouded keybag */ 10855714Skris 109109998SmarkmPKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, 110280304Sjkim int passlen, unsigned char *salt, 111280304Sjkim int saltlen, int iter, 112280304Sjkim PKCS8_PRIV_KEY_INFO *p8) 11355714Skris{ 114280304Sjkim PKCS12_SAFEBAG *bag; 115280304Sjkim const EVP_CIPHER *pbe_ciph; 11655714Skris 117280304Sjkim /* Set up the safe bag */ 118280304Sjkim if (!(bag = PKCS12_SAFEBAG_new())) { 119280304Sjkim PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); 120280304Sjkim return NULL; 121280304Sjkim } 12255714Skris 123280304Sjkim bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); 124238405Sjkim 125280304Sjkim pbe_ciph = EVP_get_cipherbynid(pbe_nid); 126238405Sjkim 127280304Sjkim if (pbe_ciph) 128280304Sjkim pbe_nid = -1; 129238405Sjkim 130280304Sjkim if (!(bag->value.shkeybag = 131280304Sjkim PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, 132280304Sjkim p8))) { 133280304Sjkim PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); 134291721Sjkim PKCS12_SAFEBAG_free(bag); 135280304Sjkim return NULL; 136280304Sjkim } 13755714Skris 138280304Sjkim 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{ 144280304Sjkim PKCS7 *p7; 145280304Sjkim if (!(p7 = PKCS7_new())) { 146280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); 147280304Sjkim return NULL; 148280304Sjkim } 149280304Sjkim p7->type = OBJ_nid2obj(NID_pkcs7_data); 150280304Sjkim if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) { 151280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); 152291721Sjkim goto err; 153280304Sjkim } 154280304Sjkim 155280304Sjkim if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) { 156280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); 157291721Sjkim goto err; 158280304Sjkim } 159280304Sjkim return p7; 160291721Sjkim 161291721Sjkim err: 162291721Sjkim PKCS7_free(p7); 163291721Sjkim return NULL; 16455714Skris} 16555714Skris 166109998Smarkm/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ 167109998SmarkmSTACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) 168109998Smarkm{ 169280304Sjkim if (!PKCS7_type_is_data(p7)) { 170280304Sjkim PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, 171280304Sjkim PKCS12_R_CONTENT_TYPE_NOT_DATA); 172280304Sjkim return NULL; 173280304Sjkim } 174280304Sjkim 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, 180280304Sjkim unsigned char *salt, int saltlen, int iter, 181280304Sjkim STACK_OF(PKCS12_SAFEBAG) *bags) 18255714Skris{ 183280304Sjkim PKCS7 *p7; 184280304Sjkim X509_ALGOR *pbe; 185280304Sjkim const EVP_CIPHER *pbe_ciph; 186280304Sjkim if (!(p7 = PKCS7_new())) { 187280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); 188280304Sjkim return NULL; 189280304Sjkim } 190280304Sjkim if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { 191280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, 192280304Sjkim PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); 193291721Sjkim goto err; 194280304Sjkim } 195238405Sjkim 196280304Sjkim pbe_ciph = EVP_get_cipherbynid(pbe_nid); 197238405Sjkim 198280304Sjkim if (pbe_ciph) 199280304Sjkim pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); 200280304Sjkim else 201280304Sjkim pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); 202238405Sjkim 203280304Sjkim if (!pbe) { 204280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); 205291721Sjkim goto err; 206280304Sjkim } 207280304Sjkim X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); 208280304Sjkim p7->d.encrypted->enc_data->algorithm = pbe; 209280304Sjkim M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); 210280304Sjkim if (!(p7->d.encrypted->enc_data->enc_data = 211280304Sjkim PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, 212280304Sjkim passlen, bags, 1))) { 213280304Sjkim PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); 214291721Sjkim goto err; 215280304Sjkim } 21655714Skris 217280304Sjkim return p7; 218291721Sjkim 219291721Sjkim err: 220291721Sjkim PKCS7_free(p7); 221291721Sjkim return NULL; 22255714Skris} 22355714Skris 224280304SjkimSTACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, 225280304Sjkim int passlen) 22655714Skris{ 227280304Sjkim if (!PKCS7_type_is_encrypted(p7)) 228280304Sjkim return NULL; 229280304Sjkim return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, 230280304Sjkim ASN1_ITEM_rptr(PKCS12_SAFEBAGS), 231280304Sjkim pass, passlen, 232280304Sjkim p7->d.encrypted->enc_data->enc_data, 1); 233109998Smarkm} 23455714Skris 235280304SjkimPKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, 236280304Sjkim const char *pass, int passlen) 237109998Smarkm{ 238280304Sjkim return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); 239109998Smarkm} 24055714Skris 241280304Sjkimint PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) 242109998Smarkm{ 243280304Sjkim if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES), 244280304Sjkim &p12->authsafes->d.data)) 245280304Sjkim return 1; 246280304Sjkim return 0; 247109998Smarkm} 24855714Skris 249109998SmarkmSTACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12) 250109998Smarkm{ 251280304Sjkim if (!PKCS7_type_is_data(p12->authsafes)) { 252280304Sjkim PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, 253280304Sjkim PKCS12_R_CONTENT_TYPE_NOT_DATA); 254280304Sjkim return NULL; 255280304Sjkim } 256280304Sjkim return ASN1_item_unpack(p12->authsafes->d.data, 257280304Sjkim ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); 25855714Skris} 259