155714Skris/* p12_kiss.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/* Simplified PKCS#12 routines */ 6555714Skris 66280297Sjkimstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 67280297Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 6859191Skris 69280297Sjkimstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 70280297Sjkim int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 7159191Skris 72280297Sjkimstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 73280297Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 7459191Skris 75280297Sjkim/* 76280297Sjkim * Parse and decrypt a PKCS#12 structure returning user key, user cert and 77280297Sjkim * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it 78280297Sjkim * should point to a valid STACK structure. pkey and cert can be passed 79280297Sjkim * unitialised. 8055714Skris */ 8155714Skris 82160814Ssimonint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 83280297Sjkim STACK_OF(X509) **ca) 8455714Skris{ 85280297Sjkim STACK_OF(X509) *ocerts = NULL; 86280297Sjkim X509 *x = NULL; 87325337Sjkim 88325337Sjkim if (pkey) 89325337Sjkim *pkey = NULL; 90325337Sjkim if (cert) 91325337Sjkim *cert = NULL; 92325337Sjkim 93280297Sjkim /* Check for NULL PKCS12 structure */ 9455714Skris 95280297Sjkim if (!p12) { 96280297Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, 97280297Sjkim PKCS12_R_INVALID_NULL_PKCS12_POINTER); 98280297Sjkim return 0; 99280297Sjkim } 10055714Skris 101280297Sjkim /* Check the mac */ 10255714Skris 103280297Sjkim /* 104280297Sjkim * If password is zero length or NULL then try verifying both cases to 105280297Sjkim * determine which password is correct. The reason for this is that under 106280297Sjkim * PKCS#12 password based encryption no password and a zero length 107280297Sjkim * password are two different things... 108280297Sjkim */ 10968651Skris 110280297Sjkim if (!pass || !*pass) { 111280297Sjkim if (PKCS12_verify_mac(p12, NULL, 0)) 112280297Sjkim pass = NULL; 113280297Sjkim else if (PKCS12_verify_mac(p12, "", 0)) 114280297Sjkim pass = ""; 115280297Sjkim else { 116280297Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); 117280297Sjkim goto err; 118280297Sjkim } 119280297Sjkim } else if (!PKCS12_verify_mac(p12, pass, -1)) { 120280297Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); 121280297Sjkim goto err; 122280297Sjkim } 12355714Skris 124280297Sjkim /* Allocate stack for other certificates */ 125280297Sjkim ocerts = sk_X509_new_null(); 126238405Sjkim 127280297Sjkim if (!ocerts) { 128280297Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); 129325337Sjkim goto err; 130280297Sjkim } 131238405Sjkim 132280297Sjkim if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { 133280297Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); 134280297Sjkim goto err; 135280297Sjkim } 13655714Skris 137280297Sjkim while ((x = sk_X509_pop(ocerts))) { 138280297Sjkim if (pkey && *pkey && cert && !*cert) { 139285329Sjkim ERR_set_mark(); 140280297Sjkim if (X509_check_private_key(x, *pkey)) { 141280297Sjkim *cert = x; 142280297Sjkim x = NULL; 143280297Sjkim } 144285329Sjkim ERR_pop_to_mark(); 145280297Sjkim } 146238405Sjkim 147280297Sjkim if (ca && x) { 148280297Sjkim if (!*ca) 149280297Sjkim *ca = sk_X509_new_null(); 150280297Sjkim if (!*ca) 151280297Sjkim goto err; 152280297Sjkim if (!sk_X509_push(*ca, x)) 153280297Sjkim goto err; 154280297Sjkim x = NULL; 155280297Sjkim } 156280297Sjkim if (x) 157280297Sjkim X509_free(x); 158280297Sjkim } 159238405Sjkim 160280297Sjkim if (ocerts) 161280297Sjkim sk_X509_pop_free(ocerts, X509_free); 162238405Sjkim 163280297Sjkim return 1; 16455714Skris 16559191Skris err: 16655714Skris 167325337Sjkim if (pkey) { 168280297Sjkim EVP_PKEY_free(*pkey); 169325337Sjkim *pkey = NULL; 170325337Sjkim } 171325337Sjkim if (cert) { 172280297Sjkim X509_free(*cert); 173325337Sjkim *cert = NULL; 174325337Sjkim } 175280297Sjkim if (x) 176280297Sjkim X509_free(x); 177280297Sjkim if (ocerts) 178280297Sjkim sk_X509_pop_free(ocerts, X509_free); 179280297Sjkim return 0; 18059191Skris 18155714Skris} 18255714Skris 18355714Skris/* Parse the outer PKCS#12 structure */ 18455714Skris 185160814Ssimonstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 186280297Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 18755714Skris{ 188280297Sjkim STACK_OF(PKCS7) *asafes; 189280297Sjkim STACK_OF(PKCS12_SAFEBAG) *bags; 190280297Sjkim int i, bagnid; 191280297Sjkim PKCS7 *p7; 19268651Skris 193280297Sjkim if (!(asafes = PKCS12_unpack_authsafes(p12))) 194280297Sjkim return 0; 195280297Sjkim for (i = 0; i < sk_PKCS7_num(asafes); i++) { 196280297Sjkim p7 = sk_PKCS7_value(asafes, i); 197280297Sjkim bagnid = OBJ_obj2nid(p7->type); 198280297Sjkim if (bagnid == NID_pkcs7_data) { 199280297Sjkim bags = PKCS12_unpack_p7data(p7); 200280297Sjkim } else if (bagnid == NID_pkcs7_encrypted) { 201280297Sjkim bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 202280297Sjkim } else 203280297Sjkim continue; 204280297Sjkim if (!bags) { 205280297Sjkim sk_PKCS7_pop_free(asafes, PKCS7_free); 206280297Sjkim return 0; 207280297Sjkim } 208280297Sjkim if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { 209280297Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 210280297Sjkim sk_PKCS7_pop_free(asafes, PKCS7_free); 211280297Sjkim return 0; 212280297Sjkim } 213280297Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 214280297Sjkim } 215280297Sjkim sk_PKCS7_pop_free(asafes, PKCS7_free); 216280297Sjkim return 1; 21755714Skris} 21855714Skris 219160814Ssimonstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 220280297Sjkim int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 22155714Skris{ 222280297Sjkim int i; 223280297Sjkim for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 224280297Sjkim if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), 225280297Sjkim pass, passlen, pkey, ocerts)) 226280297Sjkim return 0; 227280297Sjkim } 228280297Sjkim return 1; 22955714Skris} 23055714Skris 23159191Skrisstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 232280297Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 23355714Skris{ 234280297Sjkim PKCS8_PRIV_KEY_INFO *p8; 235280297Sjkim X509 *x509; 236280297Sjkim ASN1_TYPE *attrib; 237280297Sjkim ASN1_BMPSTRING *fname = NULL; 238280297Sjkim ASN1_OCTET_STRING *lkid = NULL; 23955714Skris 240280297Sjkim if ((attrib = PKCS12_get_attr(bag, NID_friendlyName))) 241280297Sjkim fname = attrib->value.bmpstring; 24255714Skris 243280297Sjkim if ((attrib = PKCS12_get_attr(bag, NID_localKeyID))) 244280297Sjkim lkid = attrib->value.octet_string; 24555714Skris 246280297Sjkim switch (M_PKCS12_bag_type(bag)) { 247280297Sjkim case NID_keyBag: 248280297Sjkim if (!pkey || *pkey) 249280297Sjkim return 1; 250280297Sjkim if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) 251280297Sjkim return 0; 252280297Sjkim break; 25355714Skris 254280297Sjkim case NID_pkcs8ShroudedKeyBag: 255280297Sjkim if (!pkey || *pkey) 256280297Sjkim return 1; 257280297Sjkim if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 258280297Sjkim return 0; 259280297Sjkim *pkey = EVP_PKCS82PKEY(p8); 260280297Sjkim PKCS8_PRIV_KEY_INFO_free(p8); 261280297Sjkim if (!(*pkey)) 262280297Sjkim return 0; 263280297Sjkim break; 26455714Skris 265280297Sjkim case NID_certBag: 266280297Sjkim if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 267280297Sjkim return 1; 268280297Sjkim if (!(x509 = PKCS12_certbag2x509(bag))) 269280297Sjkim return 0; 270280297Sjkim if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { 271280297Sjkim X509_free(x509); 272280297Sjkim return 0; 273280297Sjkim } 274280297Sjkim if (fname) { 275280297Sjkim int len, r; 276280297Sjkim unsigned char *data; 277280297Sjkim len = ASN1_STRING_to_UTF8(&data, fname); 278280297Sjkim if (len >= 0) { 279280297Sjkim r = X509_alias_set1(x509, data, len); 280280297Sjkim OPENSSL_free(data); 281280297Sjkim if (!r) { 282280297Sjkim X509_free(x509); 283280297Sjkim return 0; 284280297Sjkim } 285280297Sjkim } 286280297Sjkim } 28768651Skris 288280297Sjkim if (!sk_X509_push(ocerts, x509)) { 289280297Sjkim X509_free(x509); 290280297Sjkim return 0; 291280297Sjkim } 29268651Skris 293280297Sjkim break; 29455714Skris 295280297Sjkim case NID_safeContentsBag: 296280297Sjkim return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts); 297280297Sjkim break; 29855714Skris 299280297Sjkim default: 300280297Sjkim return 1; 301280297Sjkim break; 302280297Sjkim } 303280297Sjkim return 1; 30455714Skris} 305