1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/pkcs12/p12_add.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,224 @@
1.4 +/* p12_add.c */
1.5 +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
1.6 + * project 1999.
1.7 + */
1.8 +/* ====================================================================
1.9 + * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
1.10 + *
1.11 + * Redistribution and use in source and binary forms, with or without
1.12 + * modification, are permitted provided that the following conditions
1.13 + * are met:
1.14 + *
1.15 + * 1. Redistributions of source code must retain the above copyright
1.16 + * notice, this list of conditions and the following disclaimer.
1.17 + *
1.18 + * 2. Redistributions in binary form must reproduce the above copyright
1.19 + * notice, this list of conditions and the following disclaimer in
1.20 + * the documentation and/or other materials provided with the
1.21 + * distribution.
1.22 + *
1.23 + * 3. All advertising materials mentioning features or use of this
1.24 + * software must display the following acknowledgment:
1.25 + * "This product includes software developed by the OpenSSL Project
1.26 + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
1.27 + *
1.28 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.29 + * endorse or promote products derived from this software without
1.30 + * prior written permission. For written permission, please contact
1.31 + * licensing@OpenSSL.org.
1.32 + *
1.33 + * 5. Products derived from this software may not be called "OpenSSL"
1.34 + * nor may "OpenSSL" appear in their names without prior written
1.35 + * permission of the OpenSSL Project.
1.36 + *
1.37 + * 6. Redistributions of any form whatsoever must retain the following
1.38 + * acknowledgment:
1.39 + * "This product includes software developed by the OpenSSL Project
1.40 + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
1.41 + *
1.42 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.43 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.44 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.45 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.46 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.47 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.48 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.49 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.50 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.51 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.52 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.53 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.54 + * ====================================================================
1.55 + *
1.56 + * This product includes cryptographic software written by Eric Young
1.57 + * (eay@cryptsoft.com). This product includes software written by Tim
1.58 + * Hudson (tjh@cryptsoft.com).
1.59 + *
1.60 + */
1.61 +
1.62 +#include <stdio.h>
1.63 +#include "cryptlib.h"
1.64 +#include <openssl/pkcs12.h>
1.65 +
1.66 +/* Pack an object into an OCTET STRING and turn into a safebag */
1.67 +
1.68 +EXPORT_C PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
1.69 + int nid2)
1.70 +{
1.71 + PKCS12_BAGS *bag;
1.72 + PKCS12_SAFEBAG *safebag;
1.73 + if (!(bag = PKCS12_BAGS_new())) {
1.74 + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
1.75 + return NULL;
1.76 + }
1.77 + bag->type = OBJ_nid2obj(nid1);
1.78 + if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
1.79 + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
1.80 + return NULL;
1.81 + }
1.82 + if (!(safebag = PKCS12_SAFEBAG_new())) {
1.83 + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
1.84 + return NULL;
1.85 + }
1.86 + safebag->value.bag = bag;
1.87 + safebag->type = OBJ_nid2obj(nid2);
1.88 + return safebag;
1.89 +}
1.90 +
1.91 +/* Turn PKCS8 object into a keybag */
1.92 +
1.93 +EXPORT_C PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
1.94 +{
1.95 + PKCS12_SAFEBAG *bag;
1.96 + if (!(bag = PKCS12_SAFEBAG_new())) {
1.97 + PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG,ERR_R_MALLOC_FAILURE);
1.98 + return NULL;
1.99 + }
1.100 + bag->type = OBJ_nid2obj(NID_keyBag);
1.101 + bag->value.keybag = p8;
1.102 + return bag;
1.103 +}
1.104 +
1.105 +/* Turn PKCS8 object into a shrouded keybag */
1.106 +
1.107 +EXPORT_C PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
1.108 + int passlen, unsigned char *salt, int saltlen, int iter,
1.109 + PKCS8_PRIV_KEY_INFO *p8)
1.110 +{
1.111 + PKCS12_SAFEBAG *bag;
1.112 +
1.113 + /* Set up the safe bag */
1.114 + if (!(bag = PKCS12_SAFEBAG_new())) {
1.115 + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
1.116 + return NULL;
1.117 + }
1.118 +
1.119 + bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
1.120 + if (!(bag->value.shkeybag =
1.121 + PKCS8_encrypt(pbe_nid, NULL, pass, passlen, salt, saltlen, iter,
1.122 + p8))) {
1.123 + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
1.124 + return NULL;
1.125 + }
1.126 +
1.127 + return bag;
1.128 +}
1.129 +
1.130 +/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
1.131 +EXPORT_C PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
1.132 +{
1.133 + PKCS7 *p7;
1.134 + if (!(p7 = PKCS7_new())) {
1.135 + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
1.136 + return NULL;
1.137 + }
1.138 + p7->type = OBJ_nid2obj(NID_pkcs7_data);
1.139 + if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
1.140 + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
1.141 + return NULL;
1.142 + }
1.143 +
1.144 + if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
1.145 + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
1.146 + return NULL;
1.147 + }
1.148 + return p7;
1.149 +}
1.150 +
1.151 +/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
1.152 +EXPORT_C STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
1.153 +{
1.154 + if(!PKCS7_type_is_data(p7))
1.155 + {
1.156 + PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,PKCS12_R_CONTENT_TYPE_NOT_DATA);
1.157 + return NULL;
1.158 + }
1.159 + return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
1.160 +}
1.161 +
1.162 +/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
1.163 +
1.164 +EXPORT_C PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
1.165 + unsigned char *salt, int saltlen, int iter,
1.166 + STACK_OF(PKCS12_SAFEBAG) *bags)
1.167 +{
1.168 + PKCS7 *p7;
1.169 + X509_ALGOR *pbe;
1.170 + if (!(p7 = PKCS7_new())) {
1.171 + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
1.172 + return NULL;
1.173 + }
1.174 + if(!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
1.175 + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
1.176 + PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
1.177 + return NULL;
1.178 + }
1.179 + if (!(pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen))) {
1.180 + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
1.181 + return NULL;
1.182 + }
1.183 + X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
1.184 + p7->d.encrypted->enc_data->algorithm = pbe;
1.185 + M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
1.186 + if (!(p7->d.encrypted->enc_data->enc_data =
1.187 + PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen,
1.188 + bags, 1))) {
1.189 + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
1.190 + return NULL;
1.191 + }
1.192 +
1.193 + return p7;
1.194 +}
1.195 +
1.196 +EXPORT_C STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen)
1.197 +{
1.198 + if(!PKCS7_type_is_encrypted(p7)) return NULL;
1.199 + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
1.200 + ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
1.201 + pass, passlen,
1.202 + p7->d.encrypted->enc_data->enc_data, 1);
1.203 +}
1.204 +
1.205 +EXPORT_C PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
1.206 + int passlen)
1.207 +{
1.208 + return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
1.209 +}
1.210 +
1.211 +EXPORT_C int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
1.212 +{
1.213 + if(ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
1.214 + &p12->authsafes->d.data))
1.215 + return 1;
1.216 + return 0;
1.217 +}
1.218 +
1.219 +EXPORT_C STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
1.220 +{
1.221 + if (!PKCS7_type_is_data(p12->authsafes))
1.222 + {
1.223 + PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,PKCS12_R_CONTENT_TYPE_NOT_DATA);
1.224 + return NULL;
1.225 + }
1.226 + return ASN1_item_unpack(p12->authsafes->d.data, ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
1.227 +}