source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_kiss.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 6.8 KB
Line 
1/*
2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include "internal/cryptlib.h"
12#include <openssl/pkcs12.h>
13
14/* Simplified PKCS#12 routines */
15
16static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
17 EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
18
19static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
20 int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
21
22static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
23 EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
24
25/*
26 * Parse and decrypt a PKCS#12 structure returning user key, user cert and
27 * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
28 * should point to a valid STACK structure. pkey and cert can be passed
29 * uninitialised.
30 */
31
32int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
33 STACK_OF(X509) **ca)
34{
35 STACK_OF(X509) *ocerts = NULL;
36 X509 *x = NULL;
37 /* Check for NULL PKCS12 structure */
38
39 if (!p12) {
40 PKCS12err(PKCS12_F_PKCS12_PARSE,
41 PKCS12_R_INVALID_NULL_PKCS12_POINTER);
42 return 0;
43 }
44
45 if (pkey)
46 *pkey = NULL;
47 if (cert)
48 *cert = NULL;
49
50 /* Check the mac */
51
52 /*
53 * If password is zero length or NULL then try verifying both cases to
54 * determine which password is correct. The reason for this is that under
55 * PKCS#12 password based encryption no password and a zero length
56 * password are two different things...
57 */
58
59 if (!pass || !*pass) {
60 if (PKCS12_verify_mac(p12, NULL, 0))
61 pass = NULL;
62 else if (PKCS12_verify_mac(p12, "", 0))
63 pass = "";
64 else {
65 PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
66 goto err;
67 }
68 } else if (!PKCS12_verify_mac(p12, pass, -1)) {
69 PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
70 goto err;
71 }
72
73 /* Allocate stack for other certificates */
74 ocerts = sk_X509_new_null();
75
76 if (!ocerts) {
77 PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
78 return 0;
79 }
80
81 if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
82 PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
83 goto err;
84 }
85
86 while ((x = sk_X509_pop(ocerts))) {
87 if (pkey && *pkey && cert && !*cert) {
88 ERR_set_mark();
89 if (X509_check_private_key(x, *pkey)) {
90 *cert = x;
91 x = NULL;
92 }
93 ERR_pop_to_mark();
94 }
95
96 if (ca && x) {
97 if (!*ca)
98 *ca = sk_X509_new_null();
99 if (!*ca)
100 goto err;
101 if (!sk_X509_push(*ca, x))
102 goto err;
103 x = NULL;
104 }
105 X509_free(x);
106 }
107
108 sk_X509_pop_free(ocerts, X509_free);
109
110 return 1;
111
112 err:
113
114 if (pkey)
115 EVP_PKEY_free(*pkey);
116 if (cert)
117 X509_free(*cert);
118 X509_free(x);
119 sk_X509_pop_free(ocerts, X509_free);
120 return 0;
121
122}
123
124/* Parse the outer PKCS#12 structure */
125
126static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
127 EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
128{
129 STACK_OF(PKCS7) *asafes;
130 STACK_OF(PKCS12_SAFEBAG) *bags;
131 int i, bagnid;
132 PKCS7 *p7;
133
134 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
135 return 0;
136 for (i = 0; i < sk_PKCS7_num(asafes); i++) {
137 p7 = sk_PKCS7_value(asafes, i);
138 bagnid = OBJ_obj2nid(p7->type);
139 if (bagnid == NID_pkcs7_data) {
140 bags = PKCS12_unpack_p7data(p7);
141 } else if (bagnid == NID_pkcs7_encrypted) {
142 bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
143 } else
144 continue;
145 if (!bags) {
146 sk_PKCS7_pop_free(asafes, PKCS7_free);
147 return 0;
148 }
149 if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
150 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
151 sk_PKCS7_pop_free(asafes, PKCS7_free);
152 return 0;
153 }
154 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
155 }
156 sk_PKCS7_pop_free(asafes, PKCS7_free);
157 return 1;
158}
159
160static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
161 int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
162{
163 int i;
164 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
165 if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
166 pass, passlen, pkey, ocerts))
167 return 0;
168 }
169 return 1;
170}
171
172static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
173 EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
174{
175 PKCS8_PRIV_KEY_INFO *p8;
176 X509 *x509;
177 const ASN1_TYPE *attrib;
178 ASN1_BMPSTRING *fname = NULL;
179 ASN1_OCTET_STRING *lkid = NULL;
180
181 if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)))
182 fname = attrib->value.bmpstring;
183
184 if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)))
185 lkid = attrib->value.octet_string;
186
187 switch (PKCS12_SAFEBAG_get_nid(bag)) {
188 case NID_keyBag:
189 if (!pkey || *pkey)
190 return 1;
191 *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag));
192 if (*pkey == NULL)
193 return 0;
194 break;
195
196 case NID_pkcs8ShroudedKeyBag:
197 if (!pkey || *pkey)
198 return 1;
199 if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
200 return 0;
201 *pkey = EVP_PKCS82PKEY(p8);
202 PKCS8_PRIV_KEY_INFO_free(p8);
203 if (!(*pkey))
204 return 0;
205 break;
206
207 case NID_certBag:
208 if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
209 return 1;
210 if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
211 return 0;
212 if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
213 X509_free(x509);
214 return 0;
215 }
216 if (fname) {
217 int len, r;
218 unsigned char *data;
219 len = ASN1_STRING_to_UTF8(&data, fname);
220 if (len >= 0) {
221 r = X509_alias_set1(x509, data, len);
222 OPENSSL_free(data);
223 if (!r) {
224 X509_free(x509);
225 return 0;
226 }
227 }
228 }
229
230 if (!sk_X509_push(ocerts, x509)) {
231 X509_free(x509);
232 return 0;
233 }
234
235 break;
236
237 case NID_safeContentsBag:
238 return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey,
239 ocerts);
240
241 default:
242 return 1;
243 }
244 return 1;
245}
Note: See TracBrowser for help on using the repository browser.