155714Skris/* p12_kiss.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/* Simplified PKCS#12 routines */ 6555714Skris 66280304Sjkimstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 67280304Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 6859191Skris 69280304Sjkimstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 70280304Sjkim int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 7159191Skris 72280304Sjkimstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 73280304Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 7459191Skris 75280304Sjkim/* 76280304Sjkim * Parse and decrypt a PKCS#12 structure returning user key, user cert and 77280304Sjkim * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it 78280304Sjkim * should point to a valid STACK structure. pkey and cert can be passed 79280304Sjkim * unitialised. 8055714Skris */ 8155714Skris 82160814Ssimonint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 83280304Sjkim STACK_OF(X509) **ca) 8455714Skris{ 85280304Sjkim STACK_OF(X509) *ocerts = NULL; 86280304Sjkim X509 *x = NULL; 87280304Sjkim /* Check for NULL PKCS12 structure */ 8855714Skris 89280304Sjkim if (!p12) { 90280304Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, 91280304Sjkim PKCS12_R_INVALID_NULL_PKCS12_POINTER); 92280304Sjkim return 0; 93280304Sjkim } 9455714Skris 95280304Sjkim if (pkey) 96280304Sjkim *pkey = NULL; 97280304Sjkim if (cert) 98280304Sjkim *cert = NULL; 9955714Skris 100280304Sjkim /* Check the mac */ 10155714Skris 102280304Sjkim /* 103280304Sjkim * If password is zero length or NULL then try verifying both cases to 104280304Sjkim * determine which password is correct. The reason for this is that under 105280304Sjkim * PKCS#12 password based encryption no password and a zero length 106280304Sjkim * password are two different things... 107280304Sjkim */ 10868651Skris 109280304Sjkim if (!pass || !*pass) { 110280304Sjkim if (PKCS12_verify_mac(p12, NULL, 0)) 111280304Sjkim pass = NULL; 112280304Sjkim else if (PKCS12_verify_mac(p12, "", 0)) 113280304Sjkim pass = ""; 114280304Sjkim else { 115280304Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); 116280304Sjkim goto err; 117280304Sjkim } 118280304Sjkim } else if (!PKCS12_verify_mac(p12, pass, -1)) { 119280304Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); 120280304Sjkim goto err; 121280304Sjkim } 12255714Skris 123280304Sjkim /* Allocate stack for other certificates */ 124280304Sjkim ocerts = sk_X509_new_null(); 125238405Sjkim 126280304Sjkim if (!ocerts) { 127280304Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); 128280304Sjkim return 0; 129280304Sjkim } 130238405Sjkim 131280304Sjkim if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { 132280304Sjkim PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); 133280304Sjkim goto err; 134280304Sjkim } 13555714Skris 136280304Sjkim while ((x = sk_X509_pop(ocerts))) { 137280304Sjkim if (pkey && *pkey && cert && !*cert) { 138285330Sjkim ERR_set_mark(); 139280304Sjkim if (X509_check_private_key(x, *pkey)) { 140280304Sjkim *cert = x; 141280304Sjkim x = NULL; 142280304Sjkim } 143285330Sjkim ERR_pop_to_mark(); 144280304Sjkim } 145238405Sjkim 146280304Sjkim if (ca && x) { 147280304Sjkim if (!*ca) 148280304Sjkim *ca = sk_X509_new_null(); 149280304Sjkim if (!*ca) 150280304Sjkim goto err; 151280304Sjkim if (!sk_X509_push(*ca, x)) 152280304Sjkim goto err; 153280304Sjkim x = NULL; 154280304Sjkim } 155280304Sjkim if (x) 156280304Sjkim X509_free(x); 157280304Sjkim } 158238405Sjkim 159280304Sjkim if (ocerts) 160280304Sjkim sk_X509_pop_free(ocerts, X509_free); 161238405Sjkim 162280304Sjkim return 1; 16355714Skris 16459191Skris err: 16555714Skris 166280304Sjkim if (pkey && *pkey) 167280304Sjkim EVP_PKEY_free(*pkey); 168280304Sjkim if (cert && *cert) 169280304Sjkim X509_free(*cert); 170280304Sjkim if (x) 171280304Sjkim X509_free(x); 172280304Sjkim if (ocerts) 173280304Sjkim sk_X509_pop_free(ocerts, X509_free); 174280304Sjkim return 0; 17559191Skris 17655714Skris} 17755714Skris 17855714Skris/* Parse the outer PKCS#12 structure */ 17955714Skris 180160814Ssimonstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 181280304Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 18255714Skris{ 183280304Sjkim STACK_OF(PKCS7) *asafes; 184280304Sjkim STACK_OF(PKCS12_SAFEBAG) *bags; 185280304Sjkim int i, bagnid; 186280304Sjkim PKCS7 *p7; 18768651Skris 188280304Sjkim if (!(asafes = PKCS12_unpack_authsafes(p12))) 189280304Sjkim return 0; 190280304Sjkim for (i = 0; i < sk_PKCS7_num(asafes); i++) { 191280304Sjkim p7 = sk_PKCS7_value(asafes, i); 192280304Sjkim bagnid = OBJ_obj2nid(p7->type); 193280304Sjkim if (bagnid == NID_pkcs7_data) { 194280304Sjkim bags = PKCS12_unpack_p7data(p7); 195280304Sjkim } else if (bagnid == NID_pkcs7_encrypted) { 196280304Sjkim bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 197280304Sjkim } else 198280304Sjkim continue; 199280304Sjkim if (!bags) { 200280304Sjkim sk_PKCS7_pop_free(asafes, PKCS7_free); 201280304Sjkim return 0; 202280304Sjkim } 203280304Sjkim if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { 204280304Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 205280304Sjkim sk_PKCS7_pop_free(asafes, PKCS7_free); 206280304Sjkim return 0; 207280304Sjkim } 208280304Sjkim sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 209280304Sjkim } 210280304Sjkim sk_PKCS7_pop_free(asafes, PKCS7_free); 211280304Sjkim return 1; 21255714Skris} 21355714Skris 214160814Ssimonstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 215280304Sjkim int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 21655714Skris{ 217280304Sjkim int i; 218280304Sjkim for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 219280304Sjkim if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), 220280304Sjkim pass, passlen, pkey, ocerts)) 221280304Sjkim return 0; 222280304Sjkim } 223280304Sjkim return 1; 22455714Skris} 22555714Skris 22659191Skrisstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 227280304Sjkim EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 22855714Skris{ 229280304Sjkim PKCS8_PRIV_KEY_INFO *p8; 230280304Sjkim X509 *x509; 231280304Sjkim ASN1_TYPE *attrib; 232280304Sjkim ASN1_BMPSTRING *fname = NULL; 233280304Sjkim ASN1_OCTET_STRING *lkid = NULL; 23455714Skris 235280304Sjkim if ((attrib = PKCS12_get_attr(bag, NID_friendlyName))) 236280304Sjkim fname = attrib->value.bmpstring; 23755714Skris 238280304Sjkim if ((attrib = PKCS12_get_attr(bag, NID_localKeyID))) 239280304Sjkim lkid = attrib->value.octet_string; 24055714Skris 241280304Sjkim switch (M_PKCS12_bag_type(bag)) { 242280304Sjkim case NID_keyBag: 243280304Sjkim if (!pkey || *pkey) 244280304Sjkim return 1; 245280304Sjkim if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) 246280304Sjkim return 0; 247280304Sjkim break; 24855714Skris 249280304Sjkim case NID_pkcs8ShroudedKeyBag: 250280304Sjkim if (!pkey || *pkey) 251280304Sjkim return 1; 252280304Sjkim if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 253280304Sjkim return 0; 254280304Sjkim *pkey = EVP_PKCS82PKEY(p8); 255280304Sjkim PKCS8_PRIV_KEY_INFO_free(p8); 256280304Sjkim if (!(*pkey)) 257280304Sjkim return 0; 258280304Sjkim break; 25955714Skris 260280304Sjkim case NID_certBag: 261280304Sjkim if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) 262280304Sjkim return 1; 263280304Sjkim if (!(x509 = PKCS12_certbag2x509(bag))) 264280304Sjkim return 0; 265280304Sjkim if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { 266280304Sjkim X509_free(x509); 267280304Sjkim return 0; 268280304Sjkim } 269280304Sjkim if (fname) { 270280304Sjkim int len, r; 271280304Sjkim unsigned char *data; 272280304Sjkim len = ASN1_STRING_to_UTF8(&data, fname); 273280304Sjkim if (len >= 0) { 274280304Sjkim r = X509_alias_set1(x509, data, len); 275280304Sjkim OPENSSL_free(data); 276280304Sjkim if (!r) { 277280304Sjkim X509_free(x509); 278280304Sjkim return 0; 279280304Sjkim } 280280304Sjkim } 281280304Sjkim } 28268651Skris 283280304Sjkim if (!sk_X509_push(ocerts, x509)) { 284280304Sjkim X509_free(x509); 285280304Sjkim return 0; 286280304Sjkim } 28768651Skris 288280304Sjkim break; 28955714Skris 290280304Sjkim case NID_safeContentsBag: 291280304Sjkim return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts); 292280304Sjkim break; 29355714Skris 294280304Sjkim default: 295280304Sjkim return 1; 296280304Sjkim break; 297280304Sjkim } 298280304Sjkim return 1; 29955714Skris} 300