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