155714Skris/* p12_kiss.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296341Sdelphij * 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 14296341Sdelphij * 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/* Simplified PKCS#12 routines */ 6555714Skris 66296341Sdelphijstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 67296341Sdelphij EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 6859191Skris 69296341Sdelphijstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 70296341Sdelphij int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 7159191Skris 72296341Sdelphijstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 73296341Sdelphij EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 7459191Skris 75296341Sdelphij/* 76296341Sdelphij * Parse and decrypt a PKCS#12 structure returning user key, user cert and 77296341Sdelphij * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it 78296341Sdelphij * should point to a valid STACK structure. pkey and cert can be passed 79296341Sdelphij * unitialised. 8055714Skris */ 8155714Skris 82160814Ssimonint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 83296341Sdelphij STACK_OF(X509) **ca) 8455714Skris{ 85296341Sdelphij STACK_OF(X509) *ocerts = NULL; 86296341Sdelphij X509 *x = NULL; 87296341Sdelphij /* Check for NULL PKCS12 structure */ 8855714Skris 89296341Sdelphij if (!p12) { 90296341Sdelphij PKCS12err(PKCS12_F_PKCS12_PARSE, 91296341Sdelphij PKCS12_R_INVALID_NULL_PKCS12_POINTER); 92296341Sdelphij return 0; 93296341Sdelphij } 9455714Skris 95296341Sdelphij if (pkey) 96296341Sdelphij *pkey = NULL; 97296341Sdelphij if (cert) 98296341Sdelphij *cert = NULL; 9955714Skris 100296341Sdelphij /* Check the mac */ 10155714Skris 102296341Sdelphij /* 103296341Sdelphij * If password is zero length or NULL then try verifying both cases to 104296341Sdelphij * determine which password is correct. The reason for this is that under 105296341Sdelphij * PKCS#12 password based encryption no password and a zero length 106296341Sdelphij * password are two different things... 107296341Sdelphij */ 10868651Skris 109296341Sdelphij if (!pass || !*pass) { 110296341Sdelphij if (PKCS12_verify_mac(p12, NULL, 0)) 111296341Sdelphij pass = NULL; 112296341Sdelphij else if (PKCS12_verify_mac(p12, "", 0)) 113296341Sdelphij pass = ""; 114296341Sdelphij else { 115296341Sdelphij PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); 116296341Sdelphij goto err; 117296341Sdelphij } 118296341Sdelphij } else if (!PKCS12_verify_mac(p12, pass, -1)) { 119296341Sdelphij PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); 120296341Sdelphij goto err; 121296341Sdelphij } 12255714Skris 123296341Sdelphij /* Allocate stack for other certificates */ 124296341Sdelphij ocerts = sk_X509_new_null(); 125238405Sjkim 126296341Sdelphij if (!ocerts) { 127296341Sdelphij PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); 128296341Sdelphij return 0; 129296341Sdelphij } 130238405Sjkim 131296341Sdelphij if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { 132296341Sdelphij PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); 133296341Sdelphij goto err; 134296341Sdelphij } 13555714Skris 136296341Sdelphij while ((x = sk_X509_pop(ocerts))) { 137296341Sdelphij if (pkey && *pkey && cert && !*cert) { 138296341Sdelphij ERR_set_mark(); 139296341Sdelphij if (X509_check_private_key(x, *pkey)) { 140296341Sdelphij *cert = x; 141296341Sdelphij x = NULL; 142296341Sdelphij } 143296341Sdelphij ERR_pop_to_mark(); 144296341Sdelphij } 145238405Sjkim 146296341Sdelphij if (ca && x) { 147296341Sdelphij if (!*ca) 148296341Sdelphij *ca = sk_X509_new_null(); 149296341Sdelphij if (!*ca) 150296341Sdelphij goto err; 151296341Sdelphij if (!sk_X509_push(*ca, x)) 152296341Sdelphij goto err; 153296341Sdelphij x = NULL; 154296341Sdelphij } 155296341Sdelphij if (x) 156296341Sdelphij X509_free(x); 157296341Sdelphij } 158238405Sjkim 159296341Sdelphij if (ocerts) 160296341Sdelphij sk_X509_pop_free(ocerts, X509_free); 161238405Sjkim 162296341Sdelphij return 1; 16355714Skris 16459191Skris err: 16555714Skris 166296341Sdelphij if (pkey && *pkey) 167296341Sdelphij EVP_PKEY_free(*pkey); 168296341Sdelphij if (cert && *cert) 169296341Sdelphij X509_free(*cert); 170296341Sdelphij if (x) 171296341Sdelphij X509_free(x); 172296341Sdelphij if (ocerts) 173296341Sdelphij sk_X509_pop_free(ocerts, X509_free); 174296341Sdelphij return 0; 17559191Skris 17655714Skris} 17755714Skris 17855714Skris/* Parse the outer PKCS#12 structure */ 17955714Skris 180160814Ssimonstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 181296341Sdelphij EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 18255714Skris{ 183296341Sdelphij STACK_OF(PKCS7) *asafes; 184296341Sdelphij STACK_OF(PKCS12_SAFEBAG) *bags; 185296341Sdelphij int i, bagnid; 186296341Sdelphij PKCS7 *p7; 18768651Skris 188296341Sdelphij if (!(asafes = PKCS12_unpack_authsafes(p12))) 189296341Sdelphij return 0; 190296341Sdelphij for (i = 0; i < sk_PKCS7_num(asafes); i++) { 191296341Sdelphij p7 = sk_PKCS7_value(asafes, i); 192296341Sdelphij bagnid = OBJ_obj2nid(p7->type); 193296341Sdelphij if (bagnid == NID_pkcs7_data) { 194296341Sdelphij bags = PKCS12_unpack_p7data(p7); 195296341Sdelphij } else if (bagnid == NID_pkcs7_encrypted) { 196296341Sdelphij bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 197296341Sdelphij } else 198296341Sdelphij continue; 199296341Sdelphij if (!bags) { 200296341Sdelphij sk_PKCS7_pop_free(asafes, PKCS7_free); 201296341Sdelphij return 0; 202296341Sdelphij } 203296341Sdelphij if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { 204296341Sdelphij sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 205296341Sdelphij sk_PKCS7_pop_free(asafes, PKCS7_free); 206296341Sdelphij return 0; 207296341Sdelphij } 208296341Sdelphij sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 209296341Sdelphij } 210296341Sdelphij sk_PKCS7_pop_free(asafes, PKCS7_free); 211296341Sdelphij return 1; 21255714Skris} 21355714Skris 214160814Ssimonstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 215296341Sdelphij int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 21655714Skris{ 217296341Sdelphij int i; 218296341Sdelphij for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 219296341Sdelphij if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), 220296341Sdelphij pass, passlen, pkey, ocerts)) 221296341Sdelphij return 0; 222296341Sdelphij } 223296341Sdelphij return 1; 22455714Skris} 22555714Skris 22659191Skrisstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 227296341Sdelphij EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 22855714Skris{ 229296341Sdelphij PKCS8_PRIV_KEY_INFO *p8; 230296341Sdelphij X509 *x509; 231296341Sdelphij ASN1_TYPE *attrib; 232296341Sdelphij ASN1_BMPSTRING *fname = NULL; 233296341Sdelphij ASN1_OCTET_STRING *lkid = NULL; 23455714Skris 235296341Sdelphij if ((attrib = PKCS12_get_attr(bag, NID_friendlyName))) 236296341Sdelphij fname = attrib->value.bmpstring; 23755714Skris 238296341Sdelphij if ((attrib = PKCS12_get_attr(bag, NID_localKeyID))) 239296341Sdelphij lkid = attrib->value.octet_string; 24055714Skris 241296341Sdelphij switch (M_PKCS12_bag_type(bag)) { 242296341Sdelphij case NID_keyBag: 243296341Sdelphij if (!pkey || *pkey) 244296341Sdelphij return 1; 245296341Sdelphij if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) 246296341Sdelphij return 0; 247296341Sdelphij break; 24855714Skris 249296341Sdelphij case NID_pkcs8ShroudedKeyBag: 250296341Sdelphij if (!pkey || *pkey) 251296341Sdelphij return 1; 252296341Sdelphij if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 253296341Sdelphij return 0; 254296341Sdelphij *pkey = EVP_PKCS82PKEY(p8); 255296341Sdelphij PKCS8_PRIV_KEY_INFO_free(p8); 256296341Sdelphij if (!(*pkey)) 257296341Sdelphij return 0; 258296341Sdelphij break; 25955714Skris 260296341Sdelphij case NID_certBag: 261296341Sdelphij if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 262296341Sdelphij return 1; 263296341Sdelphij if (!(x509 = PKCS12_certbag2x509(bag))) 264296341Sdelphij return 0; 265296341Sdelphij if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { 266296341Sdelphij X509_free(x509); 267296341Sdelphij return 0; 268296341Sdelphij } 269296341Sdelphij if (fname) { 270296341Sdelphij int len, r; 271296341Sdelphij unsigned char *data; 272296341Sdelphij len = ASN1_STRING_to_UTF8(&data, fname); 273296341Sdelphij if (len >= 0) { 274296341Sdelphij r = X509_alias_set1(x509, data, len); 275296341Sdelphij OPENSSL_free(data); 276296341Sdelphij if (!r) { 277296341Sdelphij X509_free(x509); 278296341Sdelphij return 0; 279296341Sdelphij } 280296341Sdelphij } 281296341Sdelphij } 28268651Skris 283296341Sdelphij if (!sk_X509_push(ocerts, x509)) { 284296341Sdelphij X509_free(x509); 285296341Sdelphij return 0; 286296341Sdelphij } 28768651Skris 288296341Sdelphij break; 28955714Skris 290296341Sdelphij case NID_safeContentsBag: 291296341Sdelphij return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts); 292296341Sdelphij break; 29355714Skris 294296341Sdelphij default: 295296341Sdelphij return 1; 296296341Sdelphij break; 297296341Sdelphij } 298296341Sdelphij return 1; 29955714Skris} 300