1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* pkcs12.c */
2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1999-2006 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 <openssl/opensslconf.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdlib.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "apps.h"
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/crypto.h>
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/pem.h>
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/pkcs12.h>
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define PROG pkcs12_main
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EVP_CIPHER *enc;
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define NOKEYS		0x1
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define NOCERTS 	0x2
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define INFO		0x4
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CLCERTS		0x8
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define CACERTS		0x10
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain);
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, int options, char *pempass);
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, char *pass,
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			  int passlen, int options, char *pempass);
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass);
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name);
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid hex_prin(BIO *out, unsigned char *buf, int len);
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint alg_print(BIO *x, X509_ALGOR *alg);
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint cert_load(BIO *in, STACK_OF(X509) *sk);
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int set_pbe(BIO *err, int *ppbe, const char *str);
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint MAIN(int, char **);
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint MAIN(int argc, char **argv)
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ENGINE *e = NULL;
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *infile=NULL, *outfile=NULL, *keyname = NULL;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *certfile=NULL;
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BIO *in=NULL, *out = NULL;
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char **args;
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *name = NULL;
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *csp_name = NULL;
104e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu    int add_lmk = 0;
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    PKCS12 *p12 = NULL;
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char pass[50], macpass[50];
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int export_cert = 0;
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int options = 0;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int chain = 0;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int badarg = 0;
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int iter = PKCS12_DEFAULT_ITER;
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int maciter = PKCS12_DEFAULT_ITER;
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int twopass = 0;
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int keytype = 0;
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int ret = 1;
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int macver = 1;
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int noprompt = 0;
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    STACK_OF(OPENSSL_STRING) *canames = NULL;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *cpass = NULL, *mpass = NULL;
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *passargin = NULL, *passargout = NULL, *passarg = NULL;
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *passin = NULL, *passout = NULL;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *inrand = NULL;
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    char *macalg = NULL;
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *CApath = NULL, *CAfile = NULL;
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char *engine=NULL;
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    apps_startup();
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    enc = EVP_des_ede3_cbc();
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!load_config(bio_err, NULL))
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    args = argv + 1;
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    while (*args) {
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (*args[0] == '-') {
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!strcmp (*args, "-nokeys")) options |= NOKEYS;
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-keyex")) keytype = KEY_EX;
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG;
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-nocerts")) options |= NOCERTS;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-clcerts")) options |= CLCERTS;
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-cacerts")) options |= CACERTS;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS);
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-info")) options |= INFO;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-chain")) chain = 1;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-twopass")) twopass = 1;
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-nomacver")) macver = 0;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-descert"))
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    			cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-export")) export_cert = 1;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-des")) enc=EVP_des_cbc();
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc();
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_IDEA
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc();
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_SEED
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args, "-seed")) enc=EVP_seed_cbc();
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_AES
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc();
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc();
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc();
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_CAMELLIA
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args,"-camellia128")) enc=EVP_camellia_128_cbc();
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args,"-camellia192")) enc=EVP_camellia_192_cbc();
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp(*args,"-camellia256")) enc=EVP_camellia_256_cbc();
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-noiter")) iter = 1;
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-maciter"))
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					 maciter = PKCS12_DEFAULT_ITER;
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-nomaciter"))
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					 maciter = 1;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-nomac"))
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					 maciter = -1;
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else if (!strcmp (*args, "-macalg"))
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		    if (args[1]) {
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			args++;
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			macalg = *args;
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		    } else badarg = 1;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-nodes")) enc=NULL;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if (!strcmp (*args, "-certpbe")) {
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!set_pbe(bio_err, &cert_pbe, *++args))
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				badarg = 1;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-keypbe")) {
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!set_pbe(bio_err, &key_pbe, *++args))
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				badarg = 1;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-rand")) {
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			inrand = *args;
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-inkey")) {
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			keyname = *args;
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-certfile")) {
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			certfile = *args;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-name")) {
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			name = *args;
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
215e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		} else if (!strcmp (*args, "-LMK"))
216e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			add_lmk = 1;
217e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		else if (!strcmp (*args, "-CSP")) {
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			csp_name = *args;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-caname")) {
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!canames) canames = sk_OPENSSL_STRING_new_null();
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			sk_OPENSSL_STRING_push(canames, *args);
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-in")) {
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			infile = *args;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-out")) {
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			outfile = *args;
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*args,"-passin")) {
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			passargin = *args;
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*args,"-passout")) {
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			passargout = *args;
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp (*args, "-password")) {
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			passarg = *args;
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    	noprompt = 1;
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*args,"-CApath")) {
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CApath = *args;
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*args,"-CAfile")) {
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			CAfile = *args;
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*args,"-engine")) {
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    if (args[1]) {
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			args++;
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			engine = *args;
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    } else badarg = 1;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else badarg = 1;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else badarg = 1;
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	args++;
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (badarg) {
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "Usage: pkcs12 [options]\n");
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "where options are\n");
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-export       output PKCS12 file\n");
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-chain        add certificate chain\n");
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-inkey file   private key if not infile\n");
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-certfile f   add all certs in f\n");
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-CApath arg   - PEM format directory of CA's\n");
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-CAfile arg   - PEM format file of CA's\n");
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-name \"name\"  use name as friendly name\n");
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-caname \"nm\"  use nm as CA friendly name (can be used more than once).\n");
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-in  infile   input filename\n");
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-out outfile  output filename\n");
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-noout        don't output anything, just verify.\n");
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-nomacver     don't verify MAC.\n");
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-nocerts      don't output certificates.\n");
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-clcerts      only output client certificates.\n");
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-cacerts      only output CA certificates.\n");
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-nokeys       don't output private keys.\n");
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-info         give info about PKCS#12 structure.\n");
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-des          encrypt private keys with DES\n");
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-des3         encrypt private keys with triple DES (default)\n");
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_IDEA
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-idea         encrypt private keys with idea\n");
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_SEED
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-seed         encrypt private keys with seed\n");
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_AES
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "              encrypt PEM output with cbc aes\n");
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_CAMELLIA
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "              encrypt PEM output with cbc camellia\n");
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-nodes        don't encrypt private keys\n");
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-noiter       don't use encryption iteration\n");
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf (bio_err, "-nomaciter    don't use MAC iteration\n");
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-maciter      use MAC iteration\n");
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf (bio_err, "-nomac        don't generate MAC\n");
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-twopass      separate MAC, encryption passwords\n");
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-descert      encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf (bio_err, "-macalg alg   digest algorithm used in MAC (default SHA1)\n");
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-keyex        set MS key exchange type\n");
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-keysig       set MS key signature type\n");
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-password p   set import/export password source\n");
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-passin p     input file pass phrase source\n");
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-passout p    output file pass phrase source\n");
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-engine e     use engine e, possibly a hardware device.\n");
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err,  "              the random number generator\n");
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf(bio_err,  "-CSP name     Microsoft CSP name\n");
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_printf(bio_err,  "-LMK          Add local machine keyset attribute to private key\n");
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	goto end;
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    e = setup_engine(bio_err, engine, 0);
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(passarg) {
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(export_cert) passargout = passarg;
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else passargin = passarg;
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "Error getting passwords\n");
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(!cpass) {
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	if(export_cert) cpass = passout;
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	else cpass = passin;
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(cpass) {
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mpass = cpass;
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	noprompt = 1;
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    } else {
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cpass = pass;
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mpass = macpass;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(export_cert || inrand) {
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (inrand != NULL)
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			app_RAND_load_files(inrand));
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ERR_load_crypto_strings();
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_push_info("read files");
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE);
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    else in = BIO_new_file(infile, "rb");
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!in) {
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    BIO_printf(bio_err, "Error opening input file %s\n",
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						infile ? infile : "<stdin>");
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    perror (infile);
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    goto end;
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project   }
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_pop_info();
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_push_info("write files");
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!outfile) {
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	out = BIO_new_fp(stdout, BIO_NOCLOSE);
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef OPENSSL_SYS_VMS
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    out = BIO_push(tmpbio, out);
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    } else out = BIO_new_file(outfile, "wb");
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!out) {
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "Error opening output file %s\n",
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						outfile ? outfile : "<stdout>");
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	perror (outfile);
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (twopass) {
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_push_info("read MAC password");
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:", export_cert))
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	    BIO_printf (bio_err, "Can't read Password\n");
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	    goto end;
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project       	}
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_pop_info();
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (export_cert) {
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY *key = NULL;
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509 *ucert = NULL, *x = NULL;
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(X509) *certs=NULL;
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EVP_MD *macmd = NULL;
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *catmp = NULL;
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err, "Nothing to do!\n");
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto export_end;
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (options & NOCERTS)
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		chain = 0;
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("process -export_cert");
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("reading private key");
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!(options & NOKEYS))
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		key = load_key(bio_err, keyname ? keyname : infile,
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				FORMAT_PEM, 1, passin, e, "private key");
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!key)
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto export_end;
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("reading certs from input");
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Load in all certs in input file */
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!(options & NOCERTS))
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project							"certificates");
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!certs)
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto export_end;
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (key)
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Look for matching private key */
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			for(i = 0; i < sk_X509_num(certs); i++)
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				x = sk_X509_value(certs, i);
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if(X509_check_private_key(x, key))
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					ucert = x;
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					/* Zero keyid and alias */
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					X509_keyid_set1(ucert, NULL, 0);
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					X509_alias_set1(ucert, NULL, 0);
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					/* Remove from list */
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					(void)sk_X509_delete(certs, i);
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					break;
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (!ucert)
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_printf(bio_err, "No certificate matches private key\n");
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto export_end;
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("reading certs from input 2");
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Add any more certificates asked for */
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(certfile)
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		STACK_OF(X509) *morecerts=NULL;
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					    NULL, e,
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					    "certificates from certfile")))
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto export_end;
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		while(sk_X509_num(morecerts) > 0)
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sk_X509_push(certs, sk_X509_shift(morecerts));
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_X509_free(morecerts);
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 		}
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("reading certs from certfile");
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("building chain");
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If chaining get chain from user cert */
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (chain) {
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        	int vret;
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		STACK_OF(X509) *chain2;
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509_STORE *store = X509_STORE_new();
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!store)
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_printf (bio_err, "Memory allocation error\n");
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto export_end;
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!X509_STORE_load_locations(store, CAfile, CApath))
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_STORE_set_default_paths (store);
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		vret = get_cert_chain (ucert, store, &chain2);
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509_STORE_free(store);
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!vret) {
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    /* Exclude verified certificate */
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    for (i = 1; i < sk_X509_num (chain2) ; i++)
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sk_X509_push(certs, sk_X509_value (chain2, i));
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    /* Free first certificate */
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    X509_free(sk_X509_value(chain2, 0));
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    sk_X509_free(chain2);
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else {
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (vret >= 0)
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_printf (bio_err, "Error %s getting chain.\n",
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					X509_verify_cert_error_string(vret));
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_print_errors(bio_err);
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto export_end;
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    	}
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Add any CA names */
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
552221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++)
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
554221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (csp_name && key)
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				MBSTRING_ASC, (unsigned char *)csp_name, -1);
561e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
562e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (add_lmk && key)
563e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("reading password");
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!noprompt &&
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    	BIO_printf (bio_err, "Can't read Password\n");
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    	goto export_end;
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        	}
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("creating PKCS#12 structure");
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p12 = PKCS12_create(cpass, name, key, ucert, certs,
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				key_pbe, cert_pbe, iter, -1, keytype);
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!p12)
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    	ERR_print_errors (bio_err);
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto export_end;
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
592221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (macalg)
593221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
594221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		macmd = EVP_get_digestbyname(macalg);
595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!macmd)
596221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
597221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			BIO_printf(bio_err, "Unknown digest algorithm %s\n",
598221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						macalg);
599221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
600221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
601221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (maciter != -1)
603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("writing pkcs12");
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i2d_PKCS12_bio(out, p12);
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 0;
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    export_end:
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("process -export_cert: freeing");
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (key) EVP_PKEY_free(key);
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (certs) sk_X509_pop_free(certs, X509_free);
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ucert) X509_free(ucert);
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!(p12 = d2i_PKCS12_bio (in, NULL))) {
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_print_errors(bio_err);
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_push_info("read import password");
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", 0)) {
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "Can't read Password\n");
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_pop_info();
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass);
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
650ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom    if ((options & INFO) && p12->mac) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1);
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(macver) {
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_push_info("verify MAC");
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If we enter empty password try no password first */
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* If mac and crypto pass the same set it to NULL too */
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!twopass) cpass = NULL;
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else if (!PKCS12_verify_mac(p12, mpass, -1)) {
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    BIO_printf (bio_err, "Mac verify error: invalid password?\n");
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    ERR_print_errors (bio_err);
662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    goto end;
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "MAC verified OK\n");
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_pop_info();
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_push_info("output keys and certificates");
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) {
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "Error outputting keys and certificates\n");
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_print_errors (bio_err);
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	goto end;
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_pop_info();
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ret = 0;
682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project end:
683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (p12) PKCS12_free(p12);
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(export_cert || inrand) app_RAND_write_file(NULL, bio_err);
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    CRYPTO_remove_all_info();
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BIO_free(in);
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BIO_free_all(out);
690221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (canames) sk_OPENSSL_STRING_free(canames);
691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(passin) OPENSSL_free(passin);
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if(passout) OPENSSL_free(passout);
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    apps_shutdown();
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    OPENSSL_EXIT(ret);
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass,
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     int passlen, int options, char *pempass)
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(PKCS7) *asafes = NULL;
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(PKCS12_SAFEBAG) *bags;
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, bagnid;
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 0;
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	PKCS7 *p7;
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0;
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p7 = sk_PKCS7_value (asafes, i);
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bagnid = OBJ_obj2nid (p7->type);
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (bagnid == NID_pkcs7_data) {
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			bags = PKCS12_unpack_p7data(p7);
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n");
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (bagnid == NID_pkcs7_encrypted) {
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (options & INFO) {
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_printf(bio_err, "PKCS7 Encrypted data: ");
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				alg_print(bio_err,
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					p7->d.encrypted->enc_data->algorithm);
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else continue;
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!bags) goto err;
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    	if (!dump_certs_pkeys_bags (out, bags, pass, passlen,
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						 options, pempass)) {
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_PKCS12_SAFEBAG_pop_free (bags, PKCS12_SAFEBAG_free);
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bags = NULL;
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 1;
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	err:
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (asafes)
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_PKCS7_pop_free (asafes, PKCS7_free);
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dump_certs_pkeys_bags (BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags,
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			   char *pass, int passlen, int options, char *pempass)
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < sk_PKCS12_SAFEBAG_num (bags); i++) {
744656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!dump_certs_pkeys_bag (out,
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					   sk_PKCS12_SAFEBAG_value (bags, i),
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					   pass, passlen,
747656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					   options, pempass))
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    return 0;
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
750656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
753656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass,
754656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     int passlen, int options, char *pempass)
755656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
756656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY *pkey;
757656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	PKCS8_PRIV_KEY_INFO *p8;
758656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509 *x509;
759656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
760656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (M_PKCS12_bag_type(bag))
761656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
762656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_keyBag:
763656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & INFO) BIO_printf (bio_err, "Key bag\n");
764656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & NOKEYS) return 1;
765656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		print_attribs (out, bag->attrib, "Bag Attributes");
766656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		p8 = bag->value.keybag;
767656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(pkey = EVP_PKCS82PKEY (p8))) return 0;
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		print_attribs (out, p8->attributes, "Key Attributes");
769656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
770656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_PKEY_free(pkey);
771656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	break;
772656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_pkcs8ShroudedKeyBag:
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & INFO) {
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_printf (bio_err, "Shrouded Keybag: ");
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			alg_print (bio_err, bag->value.shkeybag->algor);
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & NOKEYS) return 1;
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		print_attribs (out, bag->attrib, "Bag Attributes");
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 0;
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(pkey = EVP_PKCS82PKEY (p8))) {
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			PKCS8_PRIV_KEY_INFO_free(p8);
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		print_attribs (out, p8->attributes, "Key Attributes");
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		PKCS8_PRIV_KEY_INFO_free(p8);
788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		PEM_write_bio_PrivateKey (out, pkey, enc, NULL, 0, NULL, pempass);
789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_PKEY_free(pkey);
790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	break;
791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_certBag:
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & INFO) BIO_printf (bio_err, "Certificate bag\n");
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & NOCERTS) return 1;
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                if (PKCS12_get_attr(bag, NID_localKeyID)) {
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (options & CACERTS) return 1;
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (options & CLCERTS) return 1;
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		print_attribs (out, bag->attrib, "Bag Attributes");
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project								 return 1;
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dump_cert_text (out, x509);
803656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		PEM_write_bio_X509 (out, x509);
804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		X509_free(x509);
805656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	break;
806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_safeContentsBag:
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (options & INFO) BIO_printf (bio_err, "Safe Contents bag\n");
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		print_attribs (out, bag->attrib, "Bag Attributes");
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return dump_certs_pkeys_bags (out, bag->value.safes, pass,
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project							    passlen, options, pempass);
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf (bio_err, "Warning unsupported bag type: ");
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i2a_ASN1_OBJECT (bio_err, bag->type);
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf (bio_err, "\n");
817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	break;
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
820656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Given a single certificate return a verified chain or NULL if error */
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Hope this is OK .... */
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint get_cert_chain (X509 *cert, X509_STORE *store, STACK_OF(X509) **chain)
828656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
829656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_STORE_CTX store_ctx;
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	STACK_OF(X509) *chn;
831656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i = 0;
832656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
833656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* FIXME: Should really check the return status of X509_STORE_CTX_init
834656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * for an error, but how that fits into the return value of this
835656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * function is less obvious. */
836656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_STORE_CTX_init(&store_ctx, store, cert, NULL);
837656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (X509_verify_cert(&store_ctx) <= 0) {
838656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		i = X509_STORE_CTX_get_error (&store_ctx);
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (i == 0)
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* avoid returning 0 if X509_verify_cert() did not
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * set an appropriate error value in the context */
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i = -1;
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		chn = NULL;
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
845656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		chn = X509_STORE_CTX_get1_chain(&store_ctx);
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_STORE_CTX_cleanup(&store_ctx);
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*chain = chn;
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return i;
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint alg_print (BIO *x, X509_ALGOR *alg)
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	PBEPARAM *pbe;
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const unsigned char *p;
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p = alg->parameter->value.sequence->data;
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!pbe)
861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "%s, Iteration %ld\n",
863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)),
864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1_INTEGER_get(pbe->iter));
865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	PBEPARAM_free (pbe);
866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Load all certificates from a given file */
870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint cert_load(BIO *in, STACK_OF(X509) *sk)
872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509 *cert;
875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 0;
876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
877656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_push_info("cert_load(): reading one cert");
878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_pop_info();
882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
883656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
884656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_X509_push(sk, cert);
885656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
886656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		CRYPTO_push_info("cert_load(): reading one cert");
887656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
888656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
889656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef CRYPTO_MDEBUG
890656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	CRYPTO_pop_info();
891656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
892656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret) ERR_clear_error();
893656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
894656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
895656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
896656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Generalised attribute print: handle PKCS#8 and bag attributes */
897656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint print_attribs (BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst,const char *name)
899656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
900656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509_ATTRIBUTE *attr;
901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_TYPE *av;
902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *value;
903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, attr_nid;
904656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!attrlst) {
905656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(out, "%s: <No Attributes>\n", name);
906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
907656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
908656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!sk_X509_ATTRIBUTE_num(attrlst)) {
909656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(out, "%s: <Empty Attributes>\n", name);
910656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
911656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(out, "%s\n", name);
913656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for(i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		attr = sk_X509_ATTRIBUTE_value(attrlst, i);
915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		attr_nid = OBJ_obj2nid(attr->object);
916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(out, "    ");
917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(attr_nid == NID_undef) {
918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i2a_ASN1_OBJECT (out, attr->object);
919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_printf(out, ": ");
920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
922656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(sk_ASN1_TYPE_num(attr->value.set)) {
923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			av = sk_ASN1_TYPE_value(attr->value.set, 0);
924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			switch(av->type) {
925656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				case V_ASN1_BMPSTRING:
926221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        			value = OPENSSL_uni2asc(av->value.bmpstring->data,
927656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                	       av->value.bmpstring->length);
928656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_printf(out, "%s\n", value);
929656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				OPENSSL_free(value);
930656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
931656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
932656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				case V_ASN1_OCTET_STRING:
933656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				hex_prin(out, av->value.octet_string->data,
934656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					av->value.octet_string->length);
935656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_printf(out, "\n");
936656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
937656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
938656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				case V_ASN1_BIT_STRING:
939656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				hex_prin(out, av->value.bit_string->data,
940656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					av->value.bit_string->length);
941656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				BIO_printf(out, "\n");
942656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
943656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
944656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				default:
945656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					BIO_printf(out, "<Unsupported tag %d>\n", av->type);
946656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				break;
947656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
948656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else BIO_printf(out, "<No Values>\n");
949656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
950656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
951656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
952656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
953656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid hex_prin(BIO *out, unsigned char *buf, int len)
954656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
955656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
956656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < len; i++) BIO_printf (out, "%02X ", buf[i]);
957656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
958656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
959221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int set_pbe(BIO *err, int *ppbe, const char *str)
960221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
961221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!str)
962221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
963221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!strcmp(str, "NONE"))
964221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
965221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*ppbe = -1;
966221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
967221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
968221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	*ppbe=OBJ_txt2nid(str);
969221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (*ppbe == NID_undef)
970221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
971221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
972221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
973221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
974221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
975221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
976221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
977656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
978