1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* p12_kiss.c */ 2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 1999. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * licensing@OpenSSL.org. 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h> 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h" 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/pkcs12.h> 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Simplified PKCS#12 routines */ 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int parse_pk12( PKCS12 *p12, const char *pass, int passlen, 66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, 72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom EVP_PKEY **pkey, STACK_OF(X509) *ocerts); 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Parse and decrypt a PKCS#12 structure returning user key, user cert 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * or it should point to a valid STACK structure. pkey and cert can be 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * passed unitialised. 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(X509) **ca) 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom STACK_OF(X509) *ocerts = NULL; 84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509 *x = NULL; 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Check for NULL PKCS12 structure */ 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!p12) 88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(pkey) 94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *pkey = NULL; 95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(cert) 96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *cert = NULL; 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* Check the mac */ 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* If password is zero length or NULL then try verifying both cases 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to determine which password is correct. The reason for this is that 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * under PKCS#12 password based encryption no password and a zero length 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * password are two different things... 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(!pass || !*pass) { 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL; 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else if(PKCS12_verify_mac(p12, "", 0)) pass = ""; 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else { 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else if (!PKCS12_verify_mac(p12, pass, -1)) { 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom /* Allocate stack for other certificates */ 119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ocerts = sk_X509_new_null(); 120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!ocerts) 122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); 124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while ((x = sk_X509_pop(ocerts))) 134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (pkey && *pkey && cert && !*cert) 136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (X509_check_private_key(x, *pkey)) 138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *cert = x; 140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom x = NULL; 141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ca && x) 145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!*ca) 147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *ca = sk_X509_new_null(); 148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!*ca) 149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!sk_X509_push(*ca, x)) 151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom goto err; 152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom x = NULL; 153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (x) 155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509_free(x); 156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ocerts) 159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_pop_free(ocerts, X509_free); 160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (pkey && *pkey) 166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom EVP_PKEY_free(*pkey); 167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (cert && *cert) 168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509_free(*cert); 169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (x) 17021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom X509_free(x); 171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ocerts) 172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom sk_X509_pop_free(ocerts, X509_free); 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Parse the outer PKCS#12 structure */ 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen, 180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(PKCS7) *asafes; 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project STACK_OF(PKCS12_SAFEBAG) *bags; 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i, bagnid; 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS7 *p7; 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; 188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_PKCS7_num (asafes); i++) { 189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project p7 = sk_PKCS7_value (asafes, i); 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bagnid = OBJ_obj2nid (p7->type); 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bagnid == NID_pkcs7_data) { 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bags = PKCS12_unpack_p7data(p7); 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else if (bagnid == NID_pkcs7_encrypted) { 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bags = PKCS12_unpack_p7encdata(p7, pass, passlen); 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else continue; 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!bags) { 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_PKCS7_pop_free(asafes, PKCS7_free); 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_PKCS7_pop_free(asafes, PKCS7_free); 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project sk_PKCS7_pop_free(asafes, PKCS7_free); 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, 213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), 218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom pass, passlen, pkey, ocerts)) 219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom EVP_PKEY **pkey, STACK_OF(X509) *ocerts) 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS8_PRIV_KEY_INFO *p8; 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509 *x509; 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_TYPE *attrib; 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ASN1_BMPSTRING *fname = NULL; 231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ASN1_OCTET_STRING *lkid = NULL; 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((attrib = PKCS12_get_attr (bag, NID_friendlyName))) 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project fname = attrib->value.bmpstring; 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) 237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom lkid = attrib->value.octet_string; 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (M_PKCS12_bag_type(bag)) 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case NID_keyBag: 242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!pkey || *pkey) 243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) 245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case NID_pkcs8ShroudedKeyBag: 249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!pkey || *pkey) 250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *pkey = EVP_PKCS82PKEY(p8); 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PKCS8_PRIV_KEY_INFO_free(p8); 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!(*pkey)) return 0; 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case NID_certBag: 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 1; 261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!(x509 = PKCS12_certbag2x509(bag))) 262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509_free(x509); 266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(fname) { 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int len, r; 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned char *data; 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project len = ASN1_STRING_to_UTF8(&data, fname); 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if(len > 0) { 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project r = X509_alias_set1(x509, data, len); 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project OPENSSL_free(data); 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!r) 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project X509_free(x509); 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if(!sk_X509_push(ocerts, x509)) 284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom { 285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom X509_free(x509); 286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return 0; 287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case NID_safeContentsBag: 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return parse_bags(bag->value.safes, pass, passlen, 293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom pkey, ocerts); 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 303