1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* p12_kiss.c */ 2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * project 1999. 4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ==================================================================== 6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without 9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions 10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met: 11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright 13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer. 14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * notice, this list of conditions and the following disclaimer in 17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the documentation and/or other materials provided with the 18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * distribution. 19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this 21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * software must display the following acknowledgment: 22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * endorse or promote products derived from this software without 27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * prior written permission. For written permission, please contact 28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * licensing@OpenSSL.org. 29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL" 31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * nor may "OpenSSL" appear in their names without prior written 32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * permission of the OpenSSL Project. 33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following 35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * acknowledgment: 36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * "This product includes software developed by the OpenSSL Project 37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE. 51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ==================================================================== 52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young 54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com). This product includes software written by Tim 55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com). 56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h> 60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h" 61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/pkcs12.h> 62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Simplified PKCS#12 routines */ 64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int parse_pk12( PKCS12 *p12, const char *pass, int passlen, 66480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 69480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, 72480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Parse and decrypt a PKCS#12 structure returning user key, user cert 75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, 76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * or it should point to a valid STACK structure. pkey and cert can be 77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * passed unitialised. 78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(X509) **ca) 82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ 83480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org STACK_OF(X509) *ocerts = NULL; 84480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509 *x = NULL; 85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Check for NULL PKCS12 structure */ 86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 87480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(!p12) 88480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 93480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(pkey) 94480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *pkey = NULL; 95480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(cert) 96480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *cert = NULL; 97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* Check the mac */ 99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org /* If password is zero length or NULL then try verifying both cases 101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * to determine which password is correct. The reason for this is that 102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * under PKCS#12 password based encryption no password and a zero length 103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * password are two different things... 104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */ 105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(!pass || !*pass) { 107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL; 108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else if(PKCS12_verify_mac(p12, "", 0)) pass = ""; 109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org else { 110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); 111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } else if (!PKCS12_verify_mac(p12, pass, -1)) { 114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); 115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org /* Allocate stack for other certificates */ 119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ocerts = sk_X509_new_null(); 120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!ocerts) 122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); 124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) 128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); 130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org goto err; 131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org while ((x = sk_X509_pop(ocerts))) 134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pkey && *pkey && cert && !*cert) 136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 137480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (X509_check_private_key(x, *pkey)) 138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *cert = x; 140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org x = NULL; 141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 142480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 143480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ca && x) 145480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 146480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!*ca) 147480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *ca = sk_X509_new_null(); 148480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!*ca) 149480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!sk_X509_push(*ca, x)) 151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org goto err; 152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org x = NULL; 153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (x) 155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_free(x); 156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ocerts) 159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org sk_X509_pop_free(ocerts, X509_free); 160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org 161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org err: 164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (pkey && *pkey) 166480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY_free(*pkey); 167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (cert && *cert) 168480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_free(*cert); 169480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (x) 1702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org X509_free(x); 171480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (ocerts) 172480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org sk_X509_pop_free(ocerts, X509_free); 173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} 176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Parse the outer PKCS#12 structure */ 178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ 182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(PKCS7) *asafes; 183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org STACK_OF(PKCS12_SAFEBAG) *bags; 184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i, bagnid; 185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS7 *p7; 186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; 188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 0; i < sk_PKCS7_num (asafes); i++) { 189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org p7 = sk_PKCS7_value (asafes, i); 190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bagnid = OBJ_obj2nid (p7->type); 191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (bagnid == NID_pkcs7_data) { 192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bags = PKCS12_unpack_p7data(p7); 193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } else if (bagnid == NID_pkcs7_encrypted) { 194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } else continue; 196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!bags) { 197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_PKCS7_pop_free(asafes, PKCS7_free); 198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { 201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_PKCS7_pop_free(asafes, PKCS7_free); 203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org sk_PKCS7_pop_free(asafes, PKCS7_free); 208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} 210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 213480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ 215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int i; 216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), 218480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org pass, passlen, pkey, ocerts)) 219480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} 223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 225480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ 227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS8_PRIV_KEY_INFO *p8; 228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509 *x509; 229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_TYPE *attrib; 230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org ASN1_BMPSTRING *fname = NULL; 231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org ASN1_OCTET_STRING *lkid = NULL; 232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if ((attrib = PKCS12_get_attr (bag, NID_friendlyName))) 234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org fname = attrib->value.bmpstring; 235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) 237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org lkid = attrib->value.octet_string; 238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org switch (M_PKCS12_bag_type(bag)) 240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_keyBag: 242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!pkey || *pkey) 243480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 244480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) 245480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_pkcs8ShroudedKeyBag: 249480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!pkey || *pkey) 250480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *pkey = EVP_PKCS82PKEY(p8); 254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org PKCS8_PRIV_KEY_INFO_free(p8); 255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!(*pkey)) return 0; 256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_certBag: 259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 1; 261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if (!(x509 = PKCS12_certbag2x509(bag))) 262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) 264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 265480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_free(x509); 266480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(fname) { 269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org int len, r; 270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org unsigned char *data; 271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org len = ASN1_STRING_to_UTF8(&data, fname); 272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if(len > 0) { 273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org r = X509_alias_set1(x509, data, len); 274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org OPENSSL_free(data); 275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org if (!r) 276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org { 277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org X509_free(x509); 278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 0; 279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 283480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org if(!sk_X509_push(ocerts, x509)) 284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org { 285480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org X509_free(x509); 286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org return 0; 287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org } 288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org case NID_safeContentsBag: 292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return parse_bags(bag->value.safes, pass, passlen, 293480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org pkey, ocerts); 294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org default: 297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org break; 299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org } 300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org return 1; 301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} 302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 303