1 | /*
|
---|
2 | * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (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 <string.h>
|
---|
12 | #include <stdlib.h>
|
---|
13 |
|
---|
14 | #include "internal/nelem.h"
|
---|
15 |
|
---|
16 | #include <openssl/pkcs12.h>
|
---|
17 | #include <openssl/x509.h>
|
---|
18 | #include <openssl/x509v3.h>
|
---|
19 | #include <openssl/pem.h>
|
---|
20 |
|
---|
21 | #include "../testutil.h"
|
---|
22 | #include "pkcs12.h" /* from the same directory */
|
---|
23 |
|
---|
24 | /* Set this to > 0 write test data to file */
|
---|
25 | static int write_files = 0;
|
---|
26 |
|
---|
27 | static int legacy = 0;
|
---|
28 |
|
---|
29 | static OSSL_LIB_CTX *test_ctx = NULL;
|
---|
30 | static const char *test_propq = NULL;
|
---|
31 |
|
---|
32 | /* -------------------------------------------------------------------------
|
---|
33 | * Local function declarations
|
---|
34 | */
|
---|
35 |
|
---|
36 | static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs);
|
---|
37 |
|
---|
38 | static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac);
|
---|
39 | static int write_p12(PKCS12 *p12, const char *outfile);
|
---|
40 |
|
---|
41 | static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac);
|
---|
42 | static PKCS12 *read_p12(const char *infile, const PKCS12_ENC *mac);
|
---|
43 | static int check_p12_mac(PKCS12 *p12, const PKCS12_ENC *mac);
|
---|
44 | static int check_asn1_string(const ASN1_TYPE *av, const char *txt);
|
---|
45 | static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs);
|
---|
46 |
|
---|
47 |
|
---|
48 | /* --------------------------------------------------------------------------
|
---|
49 | * Global settings
|
---|
50 | */
|
---|
51 |
|
---|
52 | void PKCS12_helper_set_write_files(int enable)
|
---|
53 | {
|
---|
54 | write_files = enable;
|
---|
55 | }
|
---|
56 |
|
---|
57 | void PKCS12_helper_set_legacy(int enable)
|
---|
58 | {
|
---|
59 | legacy = enable;
|
---|
60 | }
|
---|
61 |
|
---|
62 | void PKCS12_helper_set_libctx(OSSL_LIB_CTX *libctx)
|
---|
63 | {
|
---|
64 | test_ctx = libctx;
|
---|
65 | }
|
---|
66 |
|
---|
67 | void PKCS12_helper_set_propq(const char *propq)
|
---|
68 | {
|
---|
69 | test_propq = propq;
|
---|
70 | }
|
---|
71 |
|
---|
72 |
|
---|
73 | /* --------------------------------------------------------------------------
|
---|
74 | * Test data load functions
|
---|
75 | */
|
---|
76 |
|
---|
77 | static X509 *load_cert_asn1(const unsigned char *bytes, int len)
|
---|
78 | {
|
---|
79 | X509 *cert = NULL;
|
---|
80 |
|
---|
81 | cert = d2i_X509(NULL, &bytes, len);
|
---|
82 | if (!TEST_ptr(cert))
|
---|
83 | goto err;
|
---|
84 | err:
|
---|
85 | return cert;
|
---|
86 | }
|
---|
87 |
|
---|
88 | static EVP_PKEY *load_pkey_asn1(const unsigned char *bytes, int len)
|
---|
89 | {
|
---|
90 | EVP_PKEY *pkey = NULL;
|
---|
91 |
|
---|
92 | pkey = d2i_AutoPrivateKey(NULL, &bytes, len);
|
---|
93 | if (!TEST_ptr(pkey))
|
---|
94 | goto err;
|
---|
95 | err:
|
---|
96 | return pkey;
|
---|
97 | }
|
---|
98 |
|
---|
99 | /* -------------------------------------------------------------------------
|
---|
100 | * PKCS12 builder
|
---|
101 | */
|
---|
102 |
|
---|
103 | PKCS12_BUILDER *new_pkcs12_builder(const char *filename)
|
---|
104 | {
|
---|
105 | PKCS12_BUILDER *pb = OPENSSL_malloc(sizeof(PKCS12_BUILDER));
|
---|
106 | if (!TEST_ptr(pb))
|
---|
107 | return NULL;
|
---|
108 |
|
---|
109 | pb->filename = filename;
|
---|
110 | pb->success = 1;
|
---|
111 | return pb;
|
---|
112 | }
|
---|
113 |
|
---|
114 | int end_pkcs12_builder(PKCS12_BUILDER *pb)
|
---|
115 | {
|
---|
116 | int result = pb->success;
|
---|
117 |
|
---|
118 | OPENSSL_free(pb);
|
---|
119 | return result;
|
---|
120 | }
|
---|
121 |
|
---|
122 |
|
---|
123 | void start_pkcs12(PKCS12_BUILDER *pb)
|
---|
124 | {
|
---|
125 | pb->safes = NULL;
|
---|
126 | }
|
---|
127 |
|
---|
128 |
|
---|
129 | void end_pkcs12(PKCS12_BUILDER *pb)
|
---|
130 | {
|
---|
131 | if (!pb->success)
|
---|
132 | return;
|
---|
133 | generate_p12(pb, NULL);
|
---|
134 | }
|
---|
135 |
|
---|
136 |
|
---|
137 | void end_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
|
---|
138 | {
|
---|
139 | if (!pb->success)
|
---|
140 | return;
|
---|
141 | generate_p12(pb, mac);
|
---|
142 | }
|
---|
143 |
|
---|
144 |
|
---|
145 | /* Generate the PKCS12 encoding and write to memory bio */
|
---|
146 | static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
|
---|
147 | {
|
---|
148 | PKCS12 *p12;
|
---|
149 | EVP_MD *md = NULL;
|
---|
150 |
|
---|
151 | if (!pb->success)
|
---|
152 | return;
|
---|
153 |
|
---|
154 | pb->p12bio = BIO_new(BIO_s_mem());
|
---|
155 | if (!TEST_ptr(pb->p12bio)) {
|
---|
156 | pb->success = 0;
|
---|
157 | return;
|
---|
158 | }
|
---|
159 | if (legacy)
|
---|
160 | p12 = PKCS12_add_safes(pb->safes, 0);
|
---|
161 | else
|
---|
162 | p12 = PKCS12_add_safes_ex(pb->safes, 0, test_ctx, test_propq);
|
---|
163 | if (!TEST_ptr(p12)) {
|
---|
164 | pb->success = 0;
|
---|
165 | goto err;
|
---|
166 | }
|
---|
167 | sk_PKCS7_pop_free(pb->safes, PKCS7_free);
|
---|
168 |
|
---|
169 | if (mac != NULL) {
|
---|
170 | if (legacy)
|
---|
171 | md = (EVP_MD *)EVP_get_digestbynid(mac->nid);
|
---|
172 | else
|
---|
173 | md = EVP_MD_fetch(test_ctx, OBJ_nid2sn(mac->nid), test_propq);
|
---|
174 |
|
---|
175 | if (!TEST_true(PKCS12_set_mac(p12, mac->pass, strlen(mac->pass),
|
---|
176 | NULL, 0, mac->iter, md))) {
|
---|
177 | pb->success = 0;
|
---|
178 | goto err;
|
---|
179 | }
|
---|
180 | }
|
---|
181 | i2d_PKCS12_bio(pb->p12bio, p12);
|
---|
182 |
|
---|
183 | /* Can write to file here for debug */
|
---|
184 | if (write_files)
|
---|
185 | write_p12(p12, pb->filename);
|
---|
186 | err:
|
---|
187 | if (!legacy && md != NULL)
|
---|
188 | EVP_MD_free(md);
|
---|
189 | PKCS12_free(p12);
|
---|
190 | }
|
---|
191 |
|
---|
192 |
|
---|
193 | static int write_p12(PKCS12 *p12, const char *outfile)
|
---|
194 | {
|
---|
195 | int ret = 0;
|
---|
196 | BIO *out = BIO_new_file(outfile, "w");
|
---|
197 |
|
---|
198 | if (out == NULL)
|
---|
199 | goto err;
|
---|
200 |
|
---|
201 | if (!TEST_int_eq(i2d_PKCS12_bio(out, p12), 1))
|
---|
202 | goto err;
|
---|
203 | ret = 1;
|
---|
204 | err:
|
---|
205 | BIO_free(out);
|
---|
206 | return ret;
|
---|
207 | }
|
---|
208 |
|
---|
209 | static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac)
|
---|
210 | {
|
---|
211 | PKCS12 *p12 = NULL;
|
---|
212 |
|
---|
213 | /* Supply a p12 with library context/propq to the d2i decoder*/
|
---|
214 | if (!legacy) {
|
---|
215 | p12 = PKCS12_init_ex(NID_pkcs7_data, test_ctx, test_propq);
|
---|
216 | if (!TEST_ptr(p12))
|
---|
217 | goto err;
|
---|
218 | }
|
---|
219 | p12 = d2i_PKCS12_bio(bio, &p12);
|
---|
220 | BIO_free(bio);
|
---|
221 | if (!TEST_ptr(p12))
|
---|
222 | goto err;
|
---|
223 | if (mac == NULL) {
|
---|
224 | if (!TEST_false(PKCS12_mac_present(p12)))
|
---|
225 | goto err;
|
---|
226 | } else {
|
---|
227 | if (!check_p12_mac(p12, mac))
|
---|
228 | goto err;
|
---|
229 | }
|
---|
230 | return p12;
|
---|
231 | err:
|
---|
232 | PKCS12_free(p12);
|
---|
233 | return NULL;
|
---|
234 | }
|
---|
235 |
|
---|
236 |
|
---|
237 | /* For use with existing files */
|
---|
238 | static PKCS12 *read_p12(const char *infile, const PKCS12_ENC *mac)
|
---|
239 | {
|
---|
240 | PKCS12 *p12 = NULL;
|
---|
241 | BIO *in = BIO_new_file(infile, "r");
|
---|
242 |
|
---|
243 | if (in == NULL)
|
---|
244 | goto err;
|
---|
245 | p12 = d2i_PKCS12_bio(in, NULL);
|
---|
246 | BIO_free(in);
|
---|
247 | if (!TEST_ptr(p12))
|
---|
248 | goto err;
|
---|
249 | if (mac == NULL) {
|
---|
250 | if (!TEST_false(PKCS12_mac_present(p12)))
|
---|
251 | goto err;
|
---|
252 | } else {
|
---|
253 | if (!check_p12_mac(p12, mac))
|
---|
254 | goto err;
|
---|
255 | }
|
---|
256 | return p12;
|
---|
257 | err:
|
---|
258 | PKCS12_free(p12);
|
---|
259 | return NULL;
|
---|
260 | }
|
---|
261 |
|
---|
262 | static int check_p12_mac(PKCS12 *p12, const PKCS12_ENC *mac)
|
---|
263 | {
|
---|
264 | return TEST_true(PKCS12_mac_present(p12))
|
---|
265 | && TEST_true(PKCS12_verify_mac(p12, mac->pass, strlen(mac->pass)));
|
---|
266 | }
|
---|
267 |
|
---|
268 |
|
---|
269 | /* -------------------------------------------------------------------------
|
---|
270 | * PKCS7 content info builder
|
---|
271 | */
|
---|
272 |
|
---|
273 | void start_contentinfo(PKCS12_BUILDER *pb)
|
---|
274 | {
|
---|
275 | pb->bags = NULL;
|
---|
276 | }
|
---|
277 |
|
---|
278 |
|
---|
279 | void end_contentinfo(PKCS12_BUILDER *pb)
|
---|
280 | {
|
---|
281 | if (pb->success && pb->bags != NULL) {
|
---|
282 | if (!TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, -1, 0, NULL)))
|
---|
283 | pb->success = 0;
|
---|
284 | }
|
---|
285 | sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
|
---|
286 | pb->bags = NULL;
|
---|
287 | }
|
---|
288 |
|
---|
289 |
|
---|
290 | void end_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
|
---|
291 | {
|
---|
292 | if (pb->success && pb->bags != NULL) {
|
---|
293 | if (legacy) {
|
---|
294 | if (!TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, enc->nid,
|
---|
295 | enc->iter, enc->pass)))
|
---|
296 | pb->success = 0;
|
---|
297 | } else {
|
---|
298 | if (!TEST_true(PKCS12_add_safe_ex(&pb->safes, pb->bags, enc->nid,
|
---|
299 | enc->iter, enc->pass, test_ctx,
|
---|
300 | test_propq)))
|
---|
301 | pb->success = 0;
|
---|
302 | }
|
---|
303 | }
|
---|
304 | sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
|
---|
305 | pb->bags = NULL;
|
---|
306 | }
|
---|
307 |
|
---|
308 |
|
---|
309 | static STACK_OF(PKCS12_SAFEBAG) *decode_contentinfo(STACK_OF(PKCS7) *safes, int idx, const PKCS12_ENC *enc)
|
---|
310 | {
|
---|
311 | STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
|
---|
312 | int bagnid;
|
---|
313 | PKCS7 *p7 = sk_PKCS7_value(safes, idx);
|
---|
314 |
|
---|
315 | if (!TEST_ptr(p7))
|
---|
316 | goto err;
|
---|
317 |
|
---|
318 | bagnid = OBJ_obj2nid(p7->type);
|
---|
319 | if (enc) {
|
---|
320 | if (!TEST_int_eq(bagnid, NID_pkcs7_encrypted))
|
---|
321 | goto err;
|
---|
322 | bags = PKCS12_unpack_p7encdata(p7, enc->pass, strlen(enc->pass));
|
---|
323 | } else {
|
---|
324 | if (!TEST_int_eq(bagnid, NID_pkcs7_data))
|
---|
325 | goto err;
|
---|
326 | bags = PKCS12_unpack_p7data(p7);
|
---|
327 | }
|
---|
328 | if (!TEST_ptr(bags))
|
---|
329 | goto err;
|
---|
330 |
|
---|
331 | return bags;
|
---|
332 | err:
|
---|
333 | return NULL;
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | /* -------------------------------------------------------------------------
|
---|
338 | * PKCS12 safeBag/attribute builder
|
---|
339 | */
|
---|
340 |
|
---|
341 | static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs)
|
---|
342 | {
|
---|
343 | int ret = 0;
|
---|
344 | int attr_nid;
|
---|
345 | const PKCS12_ATTR *p_attr = attrs;
|
---|
346 |
|
---|
347 | if (attrs == NULL)
|
---|
348 | return 1;
|
---|
349 |
|
---|
350 | while (p_attr->oid != NULL) {
|
---|
351 | TEST_info("Adding attribute %s = %s", p_attr->oid, p_attr->value);
|
---|
352 | attr_nid = OBJ_txt2nid(p_attr->oid);
|
---|
353 |
|
---|
354 | if (attr_nid == NID_friendlyName) {
|
---|
355 | if (!TEST_true(PKCS12_add_friendlyname(bag, p_attr->value, -1)))
|
---|
356 | goto err;
|
---|
357 | } else if (attr_nid == NID_localKeyID) {
|
---|
358 | if (!TEST_true(PKCS12_add_localkeyid(bag, (unsigned char *)p_attr->value,
|
---|
359 | strlen(p_attr->value))))
|
---|
360 | goto err;
|
---|
361 | } else {
|
---|
362 | /* Custom attribute values limited to ASCII in these tests */
|
---|
363 | if (!TEST_true(PKCS12_add1_attr_by_txt(bag, p_attr->oid, MBSTRING_ASC,
|
---|
364 | (unsigned char *)p_attr->value,
|
---|
365 | strlen(p_attr->value))))
|
---|
366 | goto err;
|
---|
367 | }
|
---|
368 | p_attr++;
|
---|
369 | }
|
---|
370 | ret = 1;
|
---|
371 | err:
|
---|
372 | return ret;
|
---|
373 | }
|
---|
374 |
|
---|
375 | void add_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
|
---|
376 | const PKCS12_ATTR *attrs)
|
---|
377 | {
|
---|
378 | PKCS12_SAFEBAG *bag = NULL;
|
---|
379 | X509 *cert = NULL;
|
---|
380 | char *name;
|
---|
381 |
|
---|
382 | if (!pb->success)
|
---|
383 | return;
|
---|
384 |
|
---|
385 | cert = load_cert_asn1(bytes, len);
|
---|
386 | if (!TEST_ptr(cert)) {
|
---|
387 | pb->success = 0;
|
---|
388 | return;
|
---|
389 | }
|
---|
390 |
|
---|
391 | name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
---|
392 | TEST_info("Adding certificate <%s>", name);
|
---|
393 | OPENSSL_free(name);
|
---|
394 |
|
---|
395 | bag = PKCS12_add_cert(&pb->bags, cert);
|
---|
396 | if (!TEST_ptr(bag)) {
|
---|
397 | pb->success = 0;
|
---|
398 | goto err;
|
---|
399 | }
|
---|
400 |
|
---|
401 | if (!TEST_true(add_attributes(bag, attrs))) {
|
---|
402 | pb->success = 0;
|
---|
403 | goto err;
|
---|
404 | }
|
---|
405 | err:
|
---|
406 | X509_free(cert);
|
---|
407 | }
|
---|
408 |
|
---|
409 | void add_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
|
---|
410 | const PKCS12_ATTR *attrs, const PKCS12_ENC *enc)
|
---|
411 | {
|
---|
412 | PKCS12_SAFEBAG *bag = NULL;
|
---|
413 | EVP_PKEY *pkey = NULL;
|
---|
414 |
|
---|
415 | if (!pb->success)
|
---|
416 | return;
|
---|
417 |
|
---|
418 | TEST_info("Adding key");
|
---|
419 |
|
---|
420 | pkey = load_pkey_asn1(bytes, len);
|
---|
421 | if (!TEST_ptr(pkey)) {
|
---|
422 | pb->success = 0;
|
---|
423 | return;
|
---|
424 | }
|
---|
425 |
|
---|
426 | if (legacy)
|
---|
427 | bag = PKCS12_add_key(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass);
|
---|
428 | else
|
---|
429 | bag = PKCS12_add_key_ex(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass,
|
---|
430 | test_ctx, test_propq);
|
---|
431 | if (!TEST_ptr(bag)) {
|
---|
432 | pb->success = 0;
|
---|
433 | goto err;
|
---|
434 | }
|
---|
435 | if (!add_attributes(bag, attrs))
|
---|
436 | pb->success = 0;
|
---|
437 | err:
|
---|
438 | EVP_PKEY_free(pkey);
|
---|
439 | }
|
---|
440 |
|
---|
441 | void add_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret,
|
---|
442 | const PKCS12_ATTR *attrs)
|
---|
443 | {
|
---|
444 | PKCS12_SAFEBAG *bag = NULL;
|
---|
445 |
|
---|
446 | if (!pb->success)
|
---|
447 | return;
|
---|
448 |
|
---|
449 | TEST_info("Adding secret <%s>", secret);
|
---|
450 |
|
---|
451 | bag = PKCS12_add_secret(&pb->bags, secret_nid, (const unsigned char *)secret, strlen(secret));
|
---|
452 | if (!TEST_ptr(bag)) {
|
---|
453 | pb->success = 0;
|
---|
454 | return;
|
---|
455 | }
|
---|
456 | if (!add_attributes(bag, attrs))
|
---|
457 | pb->success = 0;
|
---|
458 | }
|
---|
459 |
|
---|
460 |
|
---|
461 | /* -------------------------------------------------------------------------
|
---|
462 | * PKCS12 structure checking
|
---|
463 | */
|
---|
464 |
|
---|
465 | static int check_asn1_string(const ASN1_TYPE *av, const char *txt)
|
---|
466 | {
|
---|
467 | int ret = 0;
|
---|
468 | char *value = NULL;
|
---|
469 |
|
---|
470 | if (!TEST_ptr(av))
|
---|
471 | goto err;
|
---|
472 |
|
---|
473 | switch (av->type) {
|
---|
474 | case V_ASN1_BMPSTRING:
|
---|
475 | value = OPENSSL_uni2asc(av->value.bmpstring->data,
|
---|
476 | av->value.bmpstring->length);
|
---|
477 | if (!TEST_str_eq(txt, (char *)value))
|
---|
478 | goto err;
|
---|
479 | break;
|
---|
480 |
|
---|
481 | case V_ASN1_UTF8STRING:
|
---|
482 | if (!TEST_mem_eq(txt, strlen(txt), (char *)av->value.utf8string->data,
|
---|
483 | av->value.utf8string->length))
|
---|
484 | goto err;
|
---|
485 | break;
|
---|
486 |
|
---|
487 | case V_ASN1_OCTET_STRING:
|
---|
488 | if (!TEST_mem_eq(txt, strlen(txt),
|
---|
489 | (char *)av->value.octet_string->data,
|
---|
490 | av->value.octet_string->length))
|
---|
491 | goto err;
|
---|
492 | break;
|
---|
493 |
|
---|
494 | default:
|
---|
495 | /* Tests do not support other attribute types currently */
|
---|
496 | goto err;
|
---|
497 | }
|
---|
498 | ret = 1;
|
---|
499 | err:
|
---|
500 | OPENSSL_free(value);
|
---|
501 | return ret;
|
---|
502 | }
|
---|
503 |
|
---|
504 | static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs)
|
---|
505 | {
|
---|
506 | int ret = 0;
|
---|
507 | X509_ATTRIBUTE *attr;
|
---|
508 | ASN1_TYPE *av;
|
---|
509 | int i, j;
|
---|
510 | char attr_txt[100];
|
---|
511 |
|
---|
512 | for (i = 0; i < sk_X509_ATTRIBUTE_num(bag_attrs); i++) {
|
---|
513 | const PKCS12_ATTR *p_attr = attrs;
|
---|
514 | ASN1_OBJECT *attr_obj;
|
---|
515 |
|
---|
516 | attr = sk_X509_ATTRIBUTE_value(bag_attrs, i);
|
---|
517 | attr_obj = X509_ATTRIBUTE_get0_object(attr);
|
---|
518 | OBJ_obj2txt(attr_txt, 100, attr_obj, 0);
|
---|
519 |
|
---|
520 | while(p_attr->oid != NULL) {
|
---|
521 | /* Find a matching attribute type */
|
---|
522 | if (strcmp(p_attr->oid, attr_txt) == 0) {
|
---|
523 | if (!TEST_int_eq(X509_ATTRIBUTE_count(attr), 1))
|
---|
524 | goto err;
|
---|
525 |
|
---|
526 | for (j = 0; j < X509_ATTRIBUTE_count(attr); j++)
|
---|
527 | {
|
---|
528 | av = X509_ATTRIBUTE_get0_type(attr, j);
|
---|
529 | if (!TEST_true(check_asn1_string(av, p_attr->value)))
|
---|
530 | goto err;
|
---|
531 | }
|
---|
532 | break;
|
---|
533 | }
|
---|
534 | p_attr++;
|
---|
535 | }
|
---|
536 | }
|
---|
537 | ret = 1;
|
---|
538 | err:
|
---|
539 | return ret;
|
---|
540 | }
|
---|
541 |
|
---|
542 | void check_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
|
---|
543 | const PKCS12_ATTR *attrs)
|
---|
544 | {
|
---|
545 | X509 *x509 = NULL;
|
---|
546 | X509 *ref_x509 = NULL;
|
---|
547 | const PKCS12_SAFEBAG *bag;
|
---|
548 |
|
---|
549 | if (!pb->success)
|
---|
550 | return;
|
---|
551 |
|
---|
552 | bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
|
---|
553 | if (!TEST_ptr(bag)) {
|
---|
554 | pb->success = 0;
|
---|
555 | return;
|
---|
556 | }
|
---|
557 | if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)
|
---|
558 | || !TEST_int_eq(PKCS12_SAFEBAG_get_nid(bag), NID_certBag)
|
---|
559 | || !TEST_int_eq(PKCS12_SAFEBAG_get_bag_nid(bag), NID_x509Certificate)) {
|
---|
560 | pb->success = 0;
|
---|
561 | return;
|
---|
562 | }
|
---|
563 | x509 = PKCS12_SAFEBAG_get1_cert(bag);
|
---|
564 | if (!TEST_ptr(x509)) {
|
---|
565 | pb->success = 0;
|
---|
566 | goto err;
|
---|
567 | }
|
---|
568 | ref_x509 = load_cert_asn1(bytes, len);
|
---|
569 | if (!TEST_false(X509_cmp(x509, ref_x509)))
|
---|
570 | pb->success = 0;
|
---|
571 | err:
|
---|
572 | X509_free(x509);
|
---|
573 | X509_free(ref_x509);
|
---|
574 | }
|
---|
575 |
|
---|
576 | void check_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
|
---|
577 | const PKCS12_ATTR *attrs, const PKCS12_ENC *enc)
|
---|
578 | {
|
---|
579 | EVP_PKEY *pkey = NULL;
|
---|
580 | EVP_PKEY *ref_pkey = NULL;
|
---|
581 | PKCS8_PRIV_KEY_INFO *p8;
|
---|
582 | const PKCS8_PRIV_KEY_INFO *p8c;
|
---|
583 | const PKCS12_SAFEBAG *bag;
|
---|
584 |
|
---|
585 | if (!pb->success)
|
---|
586 | return;
|
---|
587 |
|
---|
588 | bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
|
---|
589 | if (!TEST_ptr(bag)) {
|
---|
590 | pb->success = 0;
|
---|
591 | return;
|
---|
592 | }
|
---|
593 |
|
---|
594 | if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)) {
|
---|
595 | pb->success = 0;
|
---|
596 | return;
|
---|
597 | }
|
---|
598 |
|
---|
599 | switch (PKCS12_SAFEBAG_get_nid(bag)) {
|
---|
600 | case NID_keyBag:
|
---|
601 | p8c = PKCS12_SAFEBAG_get0_p8inf(bag);
|
---|
602 | if (!TEST_ptr(pkey = EVP_PKCS82PKEY(p8c))) {
|
---|
603 | pb->success = 0;
|
---|
604 | goto err;
|
---|
605 | }
|
---|
606 | break;
|
---|
607 |
|
---|
608 | case NID_pkcs8ShroudedKeyBag:
|
---|
609 | if (legacy)
|
---|
610 | p8 = PKCS12_decrypt_skey(bag, enc->pass, strlen(enc->pass));
|
---|
611 | else
|
---|
612 | p8 = PKCS12_decrypt_skey_ex(bag, enc->pass, strlen(enc->pass), test_ctx, test_propq);
|
---|
613 | if (!TEST_ptr(p8)) {
|
---|
614 | pb->success = 0;
|
---|
615 | goto err;
|
---|
616 | }
|
---|
617 | if (!TEST_ptr(pkey = EVP_PKCS82PKEY(p8))) {
|
---|
618 | PKCS8_PRIV_KEY_INFO_free(p8);
|
---|
619 | pb->success = 0;
|
---|
620 | goto err;
|
---|
621 | }
|
---|
622 | PKCS8_PRIV_KEY_INFO_free(p8);
|
---|
623 | break;
|
---|
624 |
|
---|
625 | default:
|
---|
626 | pb->success = 0;
|
---|
627 | goto err;
|
---|
628 | }
|
---|
629 |
|
---|
630 | /* PKEY compare returns 1 for match */
|
---|
631 | ref_pkey = load_pkey_asn1(bytes, len);
|
---|
632 | if (!TEST_true(EVP_PKEY_eq(pkey, ref_pkey)))
|
---|
633 | pb->success = 0;
|
---|
634 | err:
|
---|
635 | EVP_PKEY_free(pkey);
|
---|
636 | EVP_PKEY_free(ref_pkey);
|
---|
637 | }
|
---|
638 |
|
---|
639 | void check_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret, const PKCS12_ATTR *attrs)
|
---|
640 | {
|
---|
641 | const PKCS12_SAFEBAG *bag;
|
---|
642 |
|
---|
643 | if (!pb->success)
|
---|
644 | return;
|
---|
645 |
|
---|
646 | bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
|
---|
647 | if (!TEST_ptr(bag)) {
|
---|
648 | pb->success = 0;
|
---|
649 | return;
|
---|
650 | }
|
---|
651 |
|
---|
652 | if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)
|
---|
653 | || !TEST_int_eq(PKCS12_SAFEBAG_get_nid(bag), NID_secretBag)
|
---|
654 | || !TEST_int_eq(PKCS12_SAFEBAG_get_bag_nid(bag), secret_nid)
|
---|
655 | || !TEST_true(check_asn1_string(PKCS12_SAFEBAG_get0_bag_obj(bag), secret)))
|
---|
656 | pb->success = 0;
|
---|
657 | }
|
---|
658 |
|
---|
659 |
|
---|
660 | void start_check_pkcs12(PKCS12_BUILDER *pb)
|
---|
661 | {
|
---|
662 | PKCS12 *p12;
|
---|
663 |
|
---|
664 | if (!pb->success)
|
---|
665 | return;
|
---|
666 |
|
---|
667 | p12 = from_bio_p12(pb->p12bio, NULL);
|
---|
668 | if (!TEST_ptr(p12)) {
|
---|
669 | pb->success = 0;
|
---|
670 | return;
|
---|
671 | }
|
---|
672 | pb->safes = PKCS12_unpack_authsafes(p12);
|
---|
673 | if (!TEST_ptr(pb->safes))
|
---|
674 | pb->success = 0;
|
---|
675 |
|
---|
676 | pb->safe_idx = 0;
|
---|
677 | PKCS12_free(p12);
|
---|
678 | }
|
---|
679 |
|
---|
680 | void start_check_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
|
---|
681 | {
|
---|
682 | PKCS12 *p12;
|
---|
683 |
|
---|
684 | if (!pb->success)
|
---|
685 | return;
|
---|
686 |
|
---|
687 | p12 = from_bio_p12(pb->p12bio, mac);
|
---|
688 | if (!TEST_ptr(p12)) {
|
---|
689 | pb->success = 0;
|
---|
690 | return;
|
---|
691 | }
|
---|
692 | pb->safes = PKCS12_unpack_authsafes(p12);
|
---|
693 | if (!TEST_ptr(pb->safes))
|
---|
694 | pb->success = 0;
|
---|
695 |
|
---|
696 | pb->safe_idx = 0;
|
---|
697 | PKCS12_free(p12);
|
---|
698 | }
|
---|
699 |
|
---|
700 | void start_check_pkcs12_file(PKCS12_BUILDER *pb)
|
---|
701 | {
|
---|
702 | PKCS12 *p12;
|
---|
703 |
|
---|
704 | if (!pb->success)
|
---|
705 | return;
|
---|
706 |
|
---|
707 | p12 = read_p12(pb->filename, NULL);
|
---|
708 | if (!TEST_ptr(p12)) {
|
---|
709 | pb->success = 0;
|
---|
710 | return;
|
---|
711 | }
|
---|
712 | pb->safes = PKCS12_unpack_authsafes(p12);
|
---|
713 | if (!TEST_ptr(pb->safes))
|
---|
714 | pb->success = 0;
|
---|
715 |
|
---|
716 | pb->safe_idx = 0;
|
---|
717 | PKCS12_free(p12);
|
---|
718 | }
|
---|
719 |
|
---|
720 | void start_check_pkcs12_file_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
|
---|
721 | {
|
---|
722 | PKCS12 *p12;
|
---|
723 |
|
---|
724 | if (!pb->success)
|
---|
725 | return;
|
---|
726 |
|
---|
727 | p12 = read_p12(pb->filename, mac);
|
---|
728 | if (!TEST_ptr(p12)) {
|
---|
729 | pb->success = 0;
|
---|
730 | return;
|
---|
731 | }
|
---|
732 | pb->safes = PKCS12_unpack_authsafes(p12);
|
---|
733 | if (!TEST_ptr(pb->safes))
|
---|
734 | pb->success = 0;
|
---|
735 |
|
---|
736 | pb->safe_idx = 0;
|
---|
737 | PKCS12_free(p12);
|
---|
738 | }
|
---|
739 |
|
---|
740 | void end_check_pkcs12(PKCS12_BUILDER *pb)
|
---|
741 | {
|
---|
742 | if (!pb->success)
|
---|
743 | return;
|
---|
744 |
|
---|
745 | sk_PKCS7_pop_free(pb->safes, PKCS7_free);
|
---|
746 | }
|
---|
747 |
|
---|
748 |
|
---|
749 | void start_check_contentinfo(PKCS12_BUILDER *pb)
|
---|
750 | {
|
---|
751 | if (!pb->success)
|
---|
752 | return;
|
---|
753 |
|
---|
754 | pb->bag_idx = 0;
|
---|
755 | pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, NULL);
|
---|
756 | if (!TEST_ptr(pb->bags)) {
|
---|
757 | pb->success = 0;
|
---|
758 | return;
|
---|
759 | }
|
---|
760 | TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb->bags));
|
---|
761 | }
|
---|
762 |
|
---|
763 | void start_check_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
|
---|
764 | {
|
---|
765 | if (!pb->success)
|
---|
766 | return;
|
---|
767 |
|
---|
768 | pb->bag_idx = 0;
|
---|
769 | pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, enc);
|
---|
770 | if (!TEST_ptr(pb->bags)) {
|
---|
771 | pb->success = 0;
|
---|
772 | return;
|
---|
773 | }
|
---|
774 | TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb->bags));
|
---|
775 | }
|
---|
776 |
|
---|
777 |
|
---|
778 | void end_check_contentinfo(PKCS12_BUILDER *pb)
|
---|
779 | {
|
---|
780 | if (!pb->success)
|
---|
781 | return;
|
---|
782 |
|
---|
783 | if (!TEST_int_eq(sk_PKCS12_SAFEBAG_num(pb->bags), pb->bag_idx))
|
---|
784 | pb->success = 0;
|
---|
785 | sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
|
---|
786 | pb->bags = NULL;
|
---|
787 | }
|
---|
788 |
|
---|
789 |
|
---|