]>
git.ipfire.org Git - thirdparty/openssl.git/blob - test/helpers/pkcs12.c
2 * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
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
14 #include "internal/nelem.h"
16 #include <openssl/pkcs12.h>
17 #include <openssl/x509.h>
18 #include <openssl/x509v3.h>
19 #include <openssl/pem.h>
21 #include "../testutil.h"
22 #include "pkcs12.h" /* from the same directory */
24 /* Set this to > 0 write test data to file */
25 static int write_files
= 0;
27 static int legacy
= 0;
29 static OSSL_LIB_CTX
*test_ctx
= NULL
;
30 static const char *test_propq
= NULL
;
32 /* -------------------------------------------------------------------------
33 * Local function declarations
36 static int add_attributes(PKCS12_SAFEBAG
*bag
, const PKCS12_ATTR
*attrs
);
38 static void generate_p12(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*mac
);
39 static int write_p12(PKCS12
*p12
, const char *outfile
);
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
);
48 /* --------------------------------------------------------------------------
52 void PKCS12_helper_set_write_files(int enable
)
57 void PKCS12_helper_set_legacy(int enable
)
62 void PKCS12_helper_set_libctx(OSSL_LIB_CTX
*libctx
)
67 void PKCS12_helper_set_propq(const char *propq
)
73 /* --------------------------------------------------------------------------
74 * Test data load functions
77 static X509
*load_cert_asn1(const unsigned char *bytes
, int len
)
81 cert
= d2i_X509(NULL
, &bytes
, len
);
88 static EVP_PKEY
*load_pkey_asn1(const unsigned char *bytes
, int len
)
90 EVP_PKEY
*pkey
= NULL
;
92 pkey
= d2i_AutoPrivateKey(NULL
, &bytes
, len
);
99 /* -------------------------------------------------------------------------
103 PKCS12_BUILDER
*new_pkcs12_builder(const char *filename
)
105 PKCS12_BUILDER
*pb
= OPENSSL_malloc(sizeof(PKCS12_BUILDER
));
109 pb
->filename
= filename
;
114 int end_pkcs12_builder(PKCS12_BUILDER
*pb
)
116 int result
= pb
->success
;
123 void start_pkcs12(PKCS12_BUILDER
*pb
)
129 void end_pkcs12(PKCS12_BUILDER
*pb
)
133 generate_p12(pb
, NULL
);
137 void end_pkcs12_with_mac(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*mac
)
141 generate_p12(pb
, mac
);
145 /* Generate the PKCS12 encoding and write to memory bio */
146 static void generate_p12(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*mac
)
154 pb
->p12bio
= BIO_new(BIO_s_mem());
155 if (!TEST_ptr(pb
->p12bio
)) {
160 p12
= PKCS12_add_safes(pb
->safes
, 0);
162 p12
= PKCS12_add_safes_ex(pb
->safes
, 0, test_ctx
, test_propq
);
163 if (!TEST_ptr(p12
)) {
167 sk_PKCS7_pop_free(pb
->safes
, PKCS7_free
);
171 md
= (EVP_MD
*)EVP_get_digestbynid(mac
->nid
);
173 md
= EVP_MD_fetch(test_ctx
, OBJ_nid2sn(mac
->nid
), test_propq
);
175 if (!TEST_true(PKCS12_set_mac(p12
, mac
->pass
, strlen(mac
->pass
),
176 NULL
, 0, mac
->iter
, md
))) {
181 i2d_PKCS12_bio(pb
->p12bio
, p12
);
183 /* Can write to file here for debug */
185 write_p12(p12
, pb
->filename
);
187 if (!legacy
&& md
!= NULL
)
193 static int write_p12(PKCS12
*p12
, const char *outfile
)
196 BIO
*out
= BIO_new_file(outfile
, "w");
201 if (!TEST_int_eq(i2d_PKCS12_bio(out
, p12
), 1))
209 static PKCS12
*from_bio_p12(BIO
*bio
, const PKCS12_ENC
*mac
)
213 /* Supply a p12 with library context/propq to the d2i decoder*/
215 p12
= PKCS12_init_ex(NID_pkcs7_data
, test_ctx
, test_propq
);
219 p12
= d2i_PKCS12_bio(bio
, &p12
);
224 if (!TEST_false(PKCS12_mac_present(p12
)))
227 if (!check_p12_mac(p12
, mac
))
237 /* For use with existing files */
238 static PKCS12
*read_p12(const char *infile
, const PKCS12_ENC
*mac
)
241 BIO
*in
= BIO_new_file(infile
, "r");
245 p12
= d2i_PKCS12_bio(in
, NULL
);
250 if (!TEST_false(PKCS12_mac_present(p12
)))
253 if (!check_p12_mac(p12
, mac
))
262 static int check_p12_mac(PKCS12
*p12
, const PKCS12_ENC
*mac
)
264 return TEST_true(PKCS12_mac_present(p12
))
265 && TEST_true(PKCS12_verify_mac(p12
, mac
->pass
, strlen(mac
->pass
)));
269 /* -------------------------------------------------------------------------
270 * PKCS7 content info builder
273 void start_contentinfo(PKCS12_BUILDER
*pb
)
279 void end_contentinfo(PKCS12_BUILDER
*pb
)
281 if (pb
->success
&& pb
->bags
!= NULL
) {
282 if (!TEST_true(PKCS12_add_safe(&pb
->safes
, pb
->bags
, -1, 0, NULL
)))
285 sk_PKCS12_SAFEBAG_pop_free(pb
->bags
, PKCS12_SAFEBAG_free
);
290 void end_contentinfo_encrypted(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*enc
)
292 if (pb
->success
&& pb
->bags
!= NULL
) {
294 if (!TEST_true(PKCS12_add_safe(&pb
->safes
, pb
->bags
, enc
->nid
,
295 enc
->iter
, enc
->pass
)))
298 if (!TEST_true(PKCS12_add_safe_ex(&pb
->safes
, pb
->bags
, enc
->nid
,
299 enc
->iter
, enc
->pass
, test_ctx
,
304 sk_PKCS12_SAFEBAG_pop_free(pb
->bags
, PKCS12_SAFEBAG_free
);
309 static STACK_OF(PKCS12_SAFEBAG
) *decode_contentinfo(STACK_OF(PKCS7
) *safes
, int idx
, const PKCS12_ENC
*enc
)
311 STACK_OF(PKCS12_SAFEBAG
) *bags
= NULL
;
313 PKCS7
*p7
= sk_PKCS7_value(safes
, idx
);
318 bagnid
= OBJ_obj2nid(p7
->type
);
320 if (!TEST_int_eq(bagnid
, NID_pkcs7_encrypted
))
322 bags
= PKCS12_unpack_p7encdata(p7
, enc
->pass
, strlen(enc
->pass
));
324 if (!TEST_int_eq(bagnid
, NID_pkcs7_data
))
326 bags
= PKCS12_unpack_p7data(p7
);
337 /* -------------------------------------------------------------------------
338 * PKCS12 safeBag/attribute builder
341 static int add_attributes(PKCS12_SAFEBAG
*bag
, const PKCS12_ATTR
*attrs
)
345 const PKCS12_ATTR
*p_attr
= attrs
;
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
);
354 if (attr_nid
== NID_friendlyName
) {
355 if (!TEST_true(PKCS12_add_friendlyname(bag
, p_attr
->value
, -1)))
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
))))
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
))))
375 void add_certbag(PKCS12_BUILDER
*pb
, const unsigned char *bytes
, int len
,
376 const PKCS12_ATTR
*attrs
)
378 PKCS12_SAFEBAG
*bag
= NULL
;
385 cert
= load_cert_asn1(bytes
, len
);
386 if (!TEST_ptr(cert
)) {
391 name
= X509_NAME_oneline(X509_get_subject_name(cert
), NULL
, 0);
392 TEST_info("Adding certificate <%s>", name
);
395 bag
= PKCS12_add_cert(&pb
->bags
, cert
);
396 if (!TEST_ptr(bag
)) {
401 if (!TEST_true(add_attributes(bag
, attrs
))) {
409 void add_keybag(PKCS12_BUILDER
*pb
, const unsigned char *bytes
, int len
,
410 const PKCS12_ATTR
*attrs
, const PKCS12_ENC
*enc
)
412 PKCS12_SAFEBAG
*bag
= NULL
;
413 EVP_PKEY
*pkey
= NULL
;
418 TEST_info("Adding key");
420 pkey
= load_pkey_asn1(bytes
, len
);
421 if (!TEST_ptr(pkey
)) {
427 bag
= PKCS12_add_key(&pb
->bags
, pkey
, 0 /*keytype*/, enc
->iter
, enc
->nid
, enc
->pass
);
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
)) {
435 if (!add_attributes(bag
, attrs
))
441 void add_secretbag(PKCS12_BUILDER
*pb
, int secret_nid
, const char *secret
,
442 const PKCS12_ATTR
*attrs
)
444 PKCS12_SAFEBAG
*bag
= NULL
;
449 TEST_info("Adding secret <%s>", secret
);
451 bag
= PKCS12_add_secret(&pb
->bags
, secret_nid
, (const unsigned char *)secret
, strlen(secret
));
452 if (!TEST_ptr(bag
)) {
456 if (!add_attributes(bag
, attrs
))
461 /* -------------------------------------------------------------------------
462 * PKCS12 structure checking
465 static int check_asn1_string(const ASN1_TYPE
*av
, const char *txt
)
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
))
481 case V_ASN1_UTF8STRING
:
482 if (!TEST_mem_eq(txt
, strlen(txt
), (char *)av
->value
.utf8string
->data
,
483 av
->value
.utf8string
->length
))
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
))
495 /* Tests do not support other attribute types currently */
504 static int check_attrs(const STACK_OF(X509_ATTRIBUTE
) *bag_attrs
, const PKCS12_ATTR
*attrs
)
507 X509_ATTRIBUTE
*attr
;
512 for (i
= 0; i
< sk_X509_ATTRIBUTE_num(bag_attrs
); i
++) {
513 const PKCS12_ATTR
*p_attr
= attrs
;
514 ASN1_OBJECT
*attr_obj
;
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);
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))
526 for (j
= 0; j
< X509_ATTRIBUTE_count(attr
); j
++)
528 av
= X509_ATTRIBUTE_get0_type(attr
, j
);
529 if (!TEST_true(check_asn1_string(av
, p_attr
->value
)))
542 void check_certbag(PKCS12_BUILDER
*pb
, const unsigned char *bytes
, int len
,
543 const PKCS12_ATTR
*attrs
)
546 X509
*ref_x509
= NULL
;
547 const PKCS12_SAFEBAG
*bag
;
552 bag
= sk_PKCS12_SAFEBAG_value(pb
->bags
, pb
->bag_idx
++);
553 if (!TEST_ptr(bag
)) {
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
)) {
563 x509
= PKCS12_SAFEBAG_get1_cert(bag
);
564 if (!TEST_ptr(x509
)) {
568 ref_x509
= load_cert_asn1(bytes
, len
);
569 if (!TEST_false(X509_cmp(x509
, ref_x509
)))
576 void check_keybag(PKCS12_BUILDER
*pb
, const unsigned char *bytes
, int len
,
577 const PKCS12_ATTR
*attrs
, const PKCS12_ENC
*enc
)
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
;
588 bag
= sk_PKCS12_SAFEBAG_value(pb
->bags
, pb
->bag_idx
++);
589 if (!TEST_ptr(bag
)) {
594 if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag
), attrs
)) {
599 switch (PKCS12_SAFEBAG_get_nid(bag
)) {
601 p8c
= PKCS12_SAFEBAG_get0_p8inf(bag
);
602 if (!TEST_ptr(pkey
= EVP_PKCS82PKEY(p8c
))) {
608 case NID_pkcs8ShroudedKeyBag
:
610 p8
= PKCS12_decrypt_skey(bag
, enc
->pass
, strlen(enc
->pass
));
612 p8
= PKCS12_decrypt_skey_ex(bag
, enc
->pass
, strlen(enc
->pass
), test_ctx
, test_propq
);
617 if (!TEST_ptr(pkey
= EVP_PKCS82PKEY(p8
))) {
618 PKCS8_PRIV_KEY_INFO_free(p8
);
622 PKCS8_PRIV_KEY_INFO_free(p8
);
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
)))
636 EVP_PKEY_free(ref_pkey
);
639 void check_secretbag(PKCS12_BUILDER
*pb
, int secret_nid
, const char *secret
, const PKCS12_ATTR
*attrs
)
641 const PKCS12_SAFEBAG
*bag
;
646 bag
= sk_PKCS12_SAFEBAG_value(pb
->bags
, pb
->bag_idx
++);
647 if (!TEST_ptr(bag
)) {
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
)))
660 void start_check_pkcs12(PKCS12_BUILDER
*pb
)
667 p12
= from_bio_p12(pb
->p12bio
, NULL
);
668 if (!TEST_ptr(p12
)) {
672 pb
->safes
= PKCS12_unpack_authsafes(p12
);
673 if (!TEST_ptr(pb
->safes
))
680 void start_check_pkcs12_with_mac(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*mac
)
687 p12
= from_bio_p12(pb
->p12bio
, mac
);
688 if (!TEST_ptr(p12
)) {
692 pb
->safes
= PKCS12_unpack_authsafes(p12
);
693 if (!TEST_ptr(pb
->safes
))
700 void start_check_pkcs12_file(PKCS12_BUILDER
*pb
)
707 p12
= read_p12(pb
->filename
, NULL
);
708 if (!TEST_ptr(p12
)) {
712 pb
->safes
= PKCS12_unpack_authsafes(p12
);
713 if (!TEST_ptr(pb
->safes
))
720 void start_check_pkcs12_file_with_mac(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*mac
)
727 p12
= read_p12(pb
->filename
, mac
);
728 if (!TEST_ptr(p12
)) {
732 pb
->safes
= PKCS12_unpack_authsafes(p12
);
733 if (!TEST_ptr(pb
->safes
))
740 void end_check_pkcs12(PKCS12_BUILDER
*pb
)
745 sk_PKCS7_pop_free(pb
->safes
, PKCS7_free
);
749 void start_check_contentinfo(PKCS12_BUILDER
*pb
)
755 pb
->bags
= decode_contentinfo(pb
->safes
, pb
->safe_idx
++, NULL
);
756 if (!TEST_ptr(pb
->bags
)) {
760 TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb
->bags
));
763 void start_check_contentinfo_encrypted(PKCS12_BUILDER
*pb
, const PKCS12_ENC
*enc
)
769 pb
->bags
= decode_contentinfo(pb
->safes
, pb
->safe_idx
++, enc
);
770 if (!TEST_ptr(pb
->bags
)) {
774 TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb
->bags
));
778 void end_check_contentinfo(PKCS12_BUILDER
*pb
)
783 if (!TEST_int_eq(sk_PKCS12_SAFEBAG_num(pb
->bags
), pb
->bag_idx
))
785 sk_PKCS12_SAFEBAG_pop_free(pb
->bags
, PKCS12_SAFEBAG_free
);