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