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