Add new APIs to get PKCS12 secretBag OID and value

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/10063)
This commit is contained in:
Jon Spillett 2019-09-19 15:39:13 +10:00 committed by Pauli
parent 15c9aa3aef
commit c5ec6dcf0b
19 changed files with 1738 additions and 9 deletions

View File

@ -789,6 +789,16 @@ int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag,
X509_free(x509);
break;
case NID_secretBag:
if (options & INFO)
BIO_printf(bio_err, "Secret bag\n");
print_attribs(out, attrs, "Bag Attributes");
BIO_printf(bio_err, "Bag Type: ");
i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_bag_type(bag));
BIO_printf(bio_err, "\nBag Value: ");
print_attribute(out, PKCS12_SAFEBAG_get0_bag_obj(bag));
return 1;
case NID_safeContentsBag:
if (options & INFO)
BIO_printf(bio_err, "Safe Contents bag\n");
@ -954,6 +964,10 @@ void print_attribute(BIO *out, const ASN1_TYPE *av)
OPENSSL_free(value);
break;
case V_ASN1_UTF8STRING:
BIO_printf(out, "%s\n", av->value.utf8string->data);
break;
case V_ASN1_OCTET_STRING:
hex_prin(out, av->value.octet_string->data,
av->value.octet_string->length);

View File

@ -1058,6 +1058,7 @@ PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF:112:PKCS12_SAFEBAG_create0_p8inf
PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8:113:PKCS12_SAFEBAG_create0_pkcs8
PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT:133:\
PKCS12_SAFEBAG_create_pkcs8_encrypt
PKCS12_F_PKCS12_SAFEBAG_CREATE_SECRET:134:
PKCS12_F_PKCS12_SETUP_MAC:122:PKCS12_setup_mac
PKCS12_F_PKCS12_SET_MAC:123:PKCS12_set_mac
PKCS12_F_PKCS12_UNPACK_AUTHSAFES:130:PKCS12_unpack_authsafes
@ -2760,6 +2761,7 @@ PKCS12_R_ENCRYPT_ERROR:103:encrypt error
PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE:120:error setting encrypted data type
PKCS12_R_INVALID_NULL_ARGUMENT:104:invalid null argument
PKCS12_R_INVALID_NULL_PKCS12_POINTER:105:invalid null pkcs12 pointer
PKCS12_R_INVALID_TYPE:112:invalid type
PKCS12_R_IV_GEN_ERROR:106:iv gen error
PKCS12_R_KEY_GEN_ERROR:107:key gen error
PKCS12_R_MAC_ABSENT:108:mac absent

View File

@ -18,7 +18,7 @@ int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
int namelen)
{
if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
V_ASN1_OCTET_STRING, name, namelen))
V_ASN1_OCTET_STRING, name, namelen) != NULL)
return 1;
else
return 0;
@ -39,7 +39,7 @@ int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
int namelen)
{
if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
MBSTRING_ASC, (unsigned char *)name, namelen))
MBSTRING_ASC, (unsigned char *)name, namelen) != NULL)
return 1;
else
return 0;
@ -49,7 +49,7 @@ int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name,
int namelen)
{
if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
MBSTRING_UTF8, (unsigned char *)name, namelen))
MBSTRING_UTF8, (unsigned char *)name, namelen) != NULL)
return 1;
else
return 0;
@ -59,7 +59,7 @@ int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
const unsigned char *name, int namelen)
{
if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
MBSTRING_BMP, name, namelen))
MBSTRING_BMP, name, namelen) != NULL)
return 1;
else
return 0;
@ -68,7 +68,25 @@ int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen)
{
if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
MBSTRING_ASC, (unsigned char *)name, namelen))
MBSTRING_ASC, (unsigned char *)name, namelen) != NULL)
return 1;
else
return 0;
}
int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type,
const unsigned char *bytes, int len)
{
if (X509at_add1_attr_by_NID(&bag->attrib, nid, type, bytes, len) != NULL)
return 1;
else
return 0;
}
int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type,
const unsigned char *bytes, int len)
{
if (X509at_add1_attr_by_txt(&bag->attrib, attrname, type, bytes, len) != NULL)
return 1;
else
return 0;

View File

@ -207,6 +207,24 @@ PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
}
PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
int nid_type, const unsigned char *value, int len)
{
PKCS12_SAFEBAG *bag = NULL;
/* Add secret, storing the value as an octet string */
if ((bag = PKCS12_SAFEBAG_create_secret(nid_type, V_ASN1_OCTET_STRING, value, len)) == NULL)
goto err;
if (!pkcs12_add_bag(pbags, bag))
goto err;
return bag;
err:
PKCS12_SAFEBAG_free(bag);
return NULL;
}
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int nid_safe, int iter, const char *pass)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -71,6 +71,16 @@ int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
return OBJ_obj2nid(bag->value.bag->type);
}
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag)
{
return bag->value.bag->type;
}
const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag)
{
return bag->value.bag->value.other;
}
X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
{
if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
@ -103,6 +113,60 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
NID_x509Crl, NID_crlBag);
}
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len)
{
PKCS12_BAGS *bag;
PKCS12_SAFEBAG *safebag;
if ((bag = PKCS12_BAGS_new()) == NULL) {
PKCS12err(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
bag->type = OBJ_nid2obj(type);
switch(vtype) {
case V_ASN1_OCTET_STRING:
{
ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new();
if (strtmp == NULL) {
PKCS12err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
/* Pack data into an octet string */
if (!ASN1_OCTET_STRING_set(strtmp, value, len)) {
ASN1_OCTET_STRING_free(strtmp);
PKCS12err(0, PKCS12_R_ENCODE_ERROR);
goto err;
}
bag->value.other = ASN1_TYPE_new();
if (bag->value.other == NULL) {
ASN1_OCTET_STRING_free(strtmp);
PKCS12err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
ASN1_TYPE_set(bag->value.other, vtype, strtmp);
}
break;
default:
PKCS12err(0, PKCS12_R_INVALID_TYPE);
goto err;
}
if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
PKCS12err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
safebag->value.bag = bag;
safebag->type = OBJ_nid2obj(NID_secretBag);
return safebag;
err:
PKCS12_BAGS_free(bag);
return NULL;
}
/* Turn PKCS8 object into a keybag */
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@ -27,6 +27,7 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = {
"invalid null argument"},
{ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_NULL_PKCS12_POINTER),
"invalid null pkcs12 pointer"},
{ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_TYPE), "invalid type"},
{ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_IV_GEN_ERROR), "iv gen error"},
{ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_KEY_GEN_ERROR), "key gen error"},
{ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_ABSENT), "mac absent"},

View File

@ -0,0 +1,80 @@
=pod
=head1 NAME
PKCS12_SAFEBAG_create_cert, PKCS12_SAFEBAG_create_crl,
PKCS12_SAFEBAG_create_secret, PKCS12_SAFEBAG_create0_p8inf,
PKCS12_SAFEBAG_create0_pkcs8, PKCS12_SAFEBAG_create_pkcs8_encrypt - Create
PKCS#12 safeBag objects
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype,
const unsigned char* value,
int len);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
const char *pass,
int passlen,
unsigned char *salt,
int saltlen, int iter,
PKCS8_PRIV_KEY_INFO *p8inf);
=head1 DESCRIPTION
PKCS12_SAFEBAG_create_cert() creates a new B<PKCS12_SAFEBAG> of type B<NID_certBag>
containing the supplied certificate.
PKCS12_SAFEBAG_create_crl() creates a new B<PKCS12_SAFEBAG> of type B<NID_crlBag>
containing the supplied crl.
PKCS12_SAFEBAG_create_secret() creates a new B<PKCS12_SAFEBAG> of type
corresponding to a PKCS#12 I<secretBag>. The I<secretBag> contents are tagged as
I<type> with an ASN1 value of type I<vtype> constructed using the bytes in
I<value> of length I<len>.
PKCS12_SAFEBAG_create0_p8inf() creates a new B<PKCS12_SAFEBAG> of type B<NID_keyBag>
containing the supplied PKCS8 structure.
PKCS12_SAFEBAG_create0_pkcs8() creates a new B<PKCS12_SAFEBAG> of type
B<NID_pkcs8ShroudedKeyBag> containing the supplied PKCS8 structure.
PKCS12_SAFEBAG_create_pkcs8_encrypt() creates a new B<PKCS12_SAFEBAG> of type
B<NID_pkcs8ShroudedKeyBag> by encrypting the supplied PKCS8 I<p8inf>.
If I<pbe_nid> is 0, a default encryption algorithm is used. I<pass> is the
passphrase and I<iter> is the iteration count. If I<iter> is zero then a default
value of 2048 is used. If I<salt> is NULL then a salt is generated randomly.
=head1 NOTES
PKCS12_SAFEBAG_create_pkcs8_encrypt() makes assumptions regarding the encoding of the given pass
phrase.
See L<passphrase-encoding(7)> for more information.
PKCS12_SAFEBAG_create_secret() was added in OpenSSL 3.0.
=head1 RETURN VALUES
All of these functions return a valid B<PKCS12_SAFEBAG> structure or NULL if an error occurred.
=head1 SEE ALSO
L<PKCS12_create(3)>,
L<PKCS12_add_safe(3)>,
L<PKCS12_add_safes(3)>
=head1 COPYRIGHT
Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,74 @@
=pod
=head1 NAME
PKCS12_SAFEBAG_get0_attr, PKCS12_SAFEBAG_get0_type,
PKCS12_SAFEBAG_get_nid, PKCS12_SAFEBAG_get_bag_nid,
PKCS12_SAFEBAG_get0_bag_obj, PKCS12_SAFEBAG_get0_bag_type,
PKCS12_SAFEBAG_get1_cert, PKCS12_SAFEBAG_get1_crl,
PKCS12_SAFEBAG_get0_safes, PKCS12_SAFEBAG_get0_p8inf,
PKCS12_SAFEBAG_get0_pkcs8 - Get objects from a PKCS#12 safeBag
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
int attr_nid);
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag);
int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag);
int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag);
const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag);
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag);
X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag);
X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag);
const STACK_OF(PKCS12_SAFEBAG) *PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag);
const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag);
const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag);
=head1 DESCRIPTION
PKCS12_SAFEBAG_get0_attr() gets the attribute value corresponding to the B<attr_nid>.
PKCS12_SAFEBAG_get0_type() gets the B<safeBag> type as an OID, whereas
PKCS12_SAFEBAG_get_nid() gets the B<safeBag> type as an NID, which could be
B<NID_certBag>, B<NID_crlBag>, B<NID_keyBag>, B<NID_secretBag>, B<NID_safeContentsBag>
or B<NID_pkcs8ShroudedKeyBag>.
PKCS12_SAFEBAG_get_bag_nid() gets the type of the object contained within the
B<PKCS12_SAFEBAG>. This corresponds to the bag type for most bags, but can be
arbitrary for B<secretBag>s. PKCS12_SAFEBAG_get0_bag_type() gets this type as an OID.
PKCS12_SAFEBAG_get0_bag_obj() retrieves the object contained within the safeBag.
PKCS12_SAFEBAG_get1_cert() and PKCS12_SAFEBAG_get1_crl() return new B<X509> or
B<X509_CRL> objects from the item in the safeBag.
PKCS12_SAFEBAG_get0_p8inf() and PKCS12_SAFEBAG_get0_pkcs8() return the PKCS8 object
from a PKCS8shroudedKeyBag or a keyBag.
PKCS12_SAFEBAG_get0_safes() retrieves the set of B<safeBags> contained within a
safeContentsBag.
=head1 RETURN VALUES
PKCS12_SAFEBAG_get_nid() and PKCS12_SAFEBAG_get_bag_nid() return the NID of the safeBag
or bag object, or -1 if there is no corresponding NID.
Other functions return a valid object of the specified type or NULL if an error occurred.
=head1 SEE ALSO
L<PKCS12_create(3)>,
L<PKCS12_add_safe(3)>,
L<PKCS12_add_safes(3)>
=head1 COPYRIGHT
Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,52 @@
=pod
=head1 NAME
PKCS12_add1_attr_by_NID, PKCS12_add1_attr_by_txt - Add an attribute to a PKCS#12
safeBag structure
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type,
const unsigned char *bytes, int len);
int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type,
const unsigned char *bytes, int len);
=head1 DESCRIPTION
These functions add a PKCS#12 Attribute to the Attribute Set of the B<bag>.
PKCS12_add1_attr_by_NID() adds an attribute of type B<nid> with a value of ASN1
type B<type> constructed using B<len> bytes from B<bytes>.
PKCS12_add1_attr_by_txt() adds an attribute of type B<attrname> with a value of
ASN1 type B<type> constructed using B<len> bytes from B<bytes>.
=head1 NOTES
These functions do not check whether an existing attribute of the same type is
present. There can be multiple attributes with the same type assigned to a
safeBag.
Both functions were added in OpenSSL 3.0.
=head1 RETURN VALUES
A return value of 1 indicates success, 0 indicates failure.
=head1 SEE ALSO
L<PKCS12_create(3)>
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,66 @@
=pod
=head1 NAME
PKCS12_add_cert, PKCS12_add_key,
PKCS12_add_secret - Add an object to a set of PKCS#12 safeBags
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int key_nid, const char *pass);
PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
int nid_type, const unsigned char *value, int len);
=head1 DESCRIPTION
These functions create a new B<PKCS12_SAFEBAG> and add it to the set of safeBags
in I<pbags>.
PKCS12_add_cert() creates a PKCS#12 certBag containing the supplied
certificate and adds this to the set of PKCS#12 safeBags.
PKCS12_add_key() creates a PKCS#12 keyBag (unencrypted) or a pkcs8shroudedKeyBag
(encrypted) containing the supplied B<EVP_PKEY> and adds this to the set of PKCS#12
safeBags. If I<key_nid> is not -1 then the key is encrypted with the supplied
algorithm, using I<pass> as the passphrase and I<iter> as the iteration count. If
I<iter> is zero then a default value for iteration count of 2048 is used.
PKCS12_add_secret() creates a PKCS#12 secretBag with an OID corresponding to
the supplied B<nid_type> containing the supplied value as an ASN1 octet string.
This is then added to the set of PKCS#12 safeBags.
=head1 NOTES
If a certificate contains an B<alias> or a B<keyid> then this will be
used for the corresponding B<friendlyName> or B<localKeyID> in the
PKCS12 structure.
PKCS12_add_key() makes assumptions regarding the encoding of the given pass
phrase.
See L<passphrase-encoding(7)> for more information.
PKCS12_add_secret() was added in OpenSSL 3.0.
=head1 RETURN VALUES
A valid B<PKCS12_SAFEBAG> structure or NULL if an error occurred.
=head1 SEE ALSO
L<PKCS12_create(3)>
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -0,0 +1,64 @@
=pod
=head1 NAME
PKCS12_add_safe, PKCS12_add_safes - Create and add objects to a PKCS#12 structure
=head1 SYNOPSIS
#include <openssl/pkcs12.h>
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int safe_nid, int iter, const char *pass);
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
=head1 DESCRIPTION
PKCS12_add_safe() creates a new PKCS7 contentInfo containing the supplied
B<PKCS12_SAFEBAG>s and adds this to a set of PKCS7 contentInfos. Its type
depends on the value of B<safe_nid>:
=over 4
=item * If I<safe_nid> is -1, a plain PKCS7 I<data> contentInfo is created.
=item * If I<safe_nid> is a valid PBE algorithm NID, a PKCS7 B<encryptedData>
contentInfo is created. The algorithm uses I<pass> as the passphrase and I<iter>
as the iteration count. If I<iter> is zero then a default value for iteration
count of 2048 is used.
=item * If I<safe_nid> is 0, a PKCS7 B<encryptedData> contentInfo is created using
a default encryption algorithm, currently B<NID_pbe_WithSHA1And3_Key_TripleDES_CBC>.
=back
PKCS12_add_safes() creates a B<PKCS12> structure containing the supplied set of
PKCS7 contentInfos. The I<safes> are enclosed first within a PKCS7 contentInfo
of type I<p7_nid>. Currently the only supported type is B<NID_pkcs7_data>.
=head1 NOTES
PKCS12_add_safe() makes assumptions regarding the encoding of the given pass
phrase.
See L<passphrase-encoding(7)> for more information.
=head1 RETURN VALUES
PKCS12_add_safe() returns a value of 1 indicating success or 0 for failure.
PKCS12_add_safes() returns a valid B<PKCS12> structure or NULL if an error occurred.
=head1 SEE ALSO
L<PKCS12_create(3)>
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -93,6 +93,8 @@ const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag);
int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag);
int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag);
const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag);
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag);
X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag);
X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag);
@ -103,6 +105,7 @@ const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8);
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
@ -144,6 +147,10 @@ int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
int namelen);
int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
const unsigned char *name, int namelen);
int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type,
const unsigned char *bytes, int len);
int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type,
const unsigned char *bytes, int len);
int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs,
int attr_nid);
@ -209,6 +216,8 @@ PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
EVP_PKEY *key, int key_usage, int iter,
int key_nid, const char *pass);
PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
int nid_type, const unsigned char *value, int len);
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
int safe_nid, int iter, const char *pass);
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);

View File

@ -47,6 +47,7 @@ int ERR_load_PKCS12_strings(void);
# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF 0
# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8 0
# define PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT 0
# define PKCS12_F_PKCS12_SAFEBAG_CREATE_SECRET 0
# define PKCS12_F_PKCS12_SETUP_MAC 0
# define PKCS12_F_PKCS12_SET_MAC 0
# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 0
@ -67,6 +68,7 @@ int ERR_load_PKCS12_strings(void);
# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120
# define PKCS12_R_INVALID_NULL_ARGUMENT 104
# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105
# define PKCS12_R_INVALID_TYPE 112
# define PKCS12_R_IV_GEN_ERROR 106
# define PKCS12_R_KEY_GEN_ERROR 107
# define PKCS12_R_MAC_ABSENT 108

View File

@ -30,7 +30,7 @@ IF[{- !$disabled{tests} -}]
PROGRAMS{noinst}= \
confdump \
versions \
aborttest test_test \
aborttest test_test pkcs12_format_test \
sanitytest rsa_complex exdatatest bntest \
ectest ecstresstest gmdifftest pbelutest \
destest mdc2test \
@ -234,6 +234,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[memleaktest]=../include ../apps/include
DEPEND[memleaktest]=../libcrypto libtestutil.a
SOURCE[pkcs12_format_test]=pkcs12_format_test.c pkcs12_helper.c
INCLUDE[pkcs12_format_test]=../include ../apps/include
DEPEND[pkcs12_format_test]=../libcrypto libtestutil.a
SOURCE[stack_test]=stack_test.c
INCLUDE[stack_test]=../include ../apps/include
DEPEND[stack_test]=../libcrypto libtestutil.a
@ -276,6 +280,7 @@ IF[{- !$disabled{tests} -}]
INCLUDE[ssl_test_ctx.o]=../include
INCLUDE[handshake_helper.o]=.. ../include
INCLUDE[pkcs12_helper.o]=.. ../include
INCLUDE[ssltestlib.o]=.. ../include
INCLUDE[cmp_testlib.o]=.. ../include ../apps/include

444
test/pkcs12_format_test.c Normal file
View File

@ -0,0 +1,444 @@
/*
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "internal/nelem.h"
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
#include "testutil.h"
#include "pkcs12_helper.h"
/* --------------------------------------------------------------------------
* PKCS12 component test data
*/
static const unsigned char CERT1[] =
{
0x30, 0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x56, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
0x8b, 0x4b, 0x5e, 0x6c, 0x03, 0x28, 0x4e, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x19, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0c, 0x0e, 0x50, 0x31, 0x32, 0x54, 0x65, 0x73, 0x74, 0x2d, 0x52, 0x6f, 0x6f, 0x74,
0x2d, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x39, 0x33, 0x30, 0x30, 0x30, 0x34, 0x36,
0x35, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x39, 0x32, 0x37, 0x30, 0x30, 0x34, 0x36, 0x35,
0x36, 0x5a, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x50,
0x31, 0x32, 0x54, 0x65, 0x73, 0x74, 0x2d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x31, 0x30,
0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xbc, 0xdc, 0x6f, 0x8c,
0x7a, 0x2a, 0x4b, 0xea, 0x66, 0x66, 0x04, 0xa9, 0x05, 0x92, 0x53, 0xd7, 0x13, 0x3c, 0x49, 0xe1,
0xc8, 0xbb, 0xdf, 0x3d, 0xcb, 0x88, 0x31, 0x07, 0x20, 0x59, 0x93, 0x24, 0x7f, 0x7d, 0xc6, 0x84,
0x81, 0x16, 0x64, 0x4a, 0x52, 0xa6, 0x30, 0x44, 0xdc, 0x1a, 0x30, 0xde, 0xae, 0x29, 0x18, 0xcf,
0xc7, 0xf3, 0xcf, 0x0c, 0xb7, 0x8e, 0x2b, 0x1e, 0x21, 0x01, 0x0b, 0xfb, 0xe5, 0xe6, 0xcf, 0x2b,
0x84, 0xe1, 0x33, 0xf8, 0xba, 0x02, 0xfc, 0x30, 0xfa, 0xc4, 0x33, 0xc7, 0x37, 0xc6, 0x7f, 0x72,
0x31, 0x92, 0x1d, 0x8f, 0xa0, 0xfb, 0xe5, 0x4a, 0x08, 0x31, 0x78, 0x80, 0x9c, 0x23, 0xb4, 0xe9,
0x19, 0x56, 0x04, 0xfa, 0x0d, 0x07, 0x04, 0xb7, 0x43, 0xac, 0x4c, 0x49, 0x7c, 0xc2, 0xa1, 0x44,
0xc1, 0x48, 0x7d, 0x28, 0xe5, 0x23, 0x66, 0x07, 0x22, 0xd5, 0xf0, 0xf1, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x3b, 0x30, 0x39, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
0x80, 0x14, 0xdb, 0xbb, 0xb8, 0x92, 0x4e, 0x24, 0x0b, 0x1b, 0xbb, 0x78, 0x33, 0xf9, 0x01, 0x02,
0x23, 0x0d, 0x96, 0x18, 0x30, 0x47, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x04, 0xf0, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81,
0x00, 0x1c, 0x13, 0xdc, 0x02, 0xf1, 0x44, 0x36, 0x65, 0xa9, 0xbe, 0x30, 0x1c, 0x66, 0x14, 0x20,
0x86, 0x5a, 0xa8, 0x69, 0x25, 0xf8, 0x1a, 0xb6, 0x9e, 0x5e, 0xe9, 0x89, 0xb8, 0x67, 0x70, 0x19,
0x87, 0x60, 0xeb, 0x4b, 0x11, 0x71, 0x85, 0xf8, 0xe9, 0xa7, 0x3e, 0x20, 0x42, 0xec, 0x43, 0x25,
0x01, 0x03, 0xe5, 0x4d, 0x83, 0x22, 0xf5, 0x8e, 0x3a, 0x1a, 0x1b, 0xd4, 0x1c, 0xda, 0x6b, 0x9d,
0x10, 0x1b, 0xee, 0x67, 0x4e, 0x1f, 0x69, 0xab, 0xbc, 0xaa, 0x62, 0x8e, 0x9e, 0xc6, 0xee, 0xd6,
0x09, 0xc0, 0xca, 0xe0, 0xaa, 0x9f, 0x07, 0xb2, 0xc2, 0xbb, 0x31, 0x96, 0xa2, 0x04, 0x62, 0xd3,
0x13, 0x32, 0x29, 0x67, 0x6e, 0xad, 0x2e, 0x0b, 0xea, 0x04, 0x7c, 0x8c, 0x5a, 0x5d, 0xac, 0x14,
0xaa, 0x61, 0x7f, 0x28, 0x6c, 0x2d, 0x64, 0x2d, 0xc3, 0xaf, 0x77, 0x52, 0x90, 0xb4, 0x37, 0xc0,
0x30,
};
static const unsigned char CERT2[] =
{
0x30, 0x82, 0x01, 0xed, 0x30, 0x82, 0x01, 0x56, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
0x8b, 0x4b, 0x5e, 0x6c, 0x03, 0x28, 0x4e, 0xe7, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x19, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0c, 0x0e, 0x50, 0x31, 0x32, 0x54, 0x65, 0x73, 0x74, 0x2d, 0x52, 0x6f, 0x6f, 0x74,
0x2d, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x39, 0x33, 0x30, 0x30, 0x30, 0x34, 0x36,
0x35, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x39, 0x32, 0x37, 0x30, 0x30, 0x34, 0x36, 0x35,
0x36, 0x5a, 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x50,
0x31, 0x32, 0x54, 0x65, 0x73, 0x74, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x31, 0x30,
0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa8, 0x6e, 0x40, 0x86,
0x9f, 0x98, 0x59, 0xfb, 0x57, 0xbf, 0xc1, 0x55, 0x12, 0x38, 0xeb, 0xb3, 0x46, 0x34, 0xc9, 0x35,
0x4d, 0xfd, 0x03, 0xe9, 0x3a, 0x88, 0x9e, 0x97, 0x8f, 0xf4, 0xec, 0x36, 0x7b, 0x3f, 0xba, 0xb8,
0xa5, 0x96, 0x30, 0x03, 0xc5, 0xc6, 0xd9, 0xa8, 0x4e, 0xbc, 0x23, 0x51, 0xa1, 0x96, 0xd2, 0x03,
0x98, 0x73, 0xb6, 0x17, 0x9c, 0x77, 0xd4, 0x95, 0x1e, 0x1b, 0xb3, 0x1b, 0xc8, 0x71, 0xd1, 0x2e,
0x31, 0xc7, 0x6a, 0x75, 0x57, 0x08, 0x7f, 0xba, 0x70, 0x76, 0xf7, 0x67, 0xf4, 0x4e, 0xbe, 0xfc,
0x70, 0x61, 0x41, 0x07, 0x2b, 0x7c, 0x3c, 0x3b, 0xb3, 0xbc, 0xd5, 0xa8, 0xbd, 0x28, 0xd8, 0x49,
0xd3, 0xe1, 0x78, 0xc8, 0xc1, 0x42, 0x5e, 0x18, 0x36, 0xa8, 0x41, 0xf7, 0xc8, 0xaa, 0x35, 0xfe,
0x2d, 0xd1, 0xb4, 0xcc, 0x00, 0x67, 0xae, 0x79, 0xd3, 0x28, 0xd5, 0x5b, 0x02, 0x03, 0x01, 0x00,
0x01, 0xa3, 0x3b, 0x30, 0x39, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
0x80, 0x14, 0xdb, 0xbb, 0xb8, 0x92, 0x4e, 0x24, 0x0b, 0x1b, 0xbb, 0x78, 0x33, 0xf9, 0x01, 0x02,
0x23, 0x0d, 0x96, 0x18, 0x30, 0x47, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30,
0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x04, 0xf0, 0x30, 0x0d,
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x81, 0x81,
0x00, 0x3b, 0xa6, 0x73, 0xbe, 0xe0, 0x28, 0xed, 0x1f, 0x29, 0x78, 0x4c, 0xc0, 0x1f, 0xe9, 0x85,
0xc6, 0x8f, 0xe3, 0x87, 0x7c, 0xd9, 0xe7, 0x0a, 0x37, 0xe8, 0xaa, 0xb5, 0xd2, 0x7f, 0xf8, 0x90,
0x20, 0x80, 0x35, 0xa7, 0x79, 0x2b, 0x04, 0xa7, 0xbf, 0xe6, 0x7b, 0x58, 0xcb, 0xec, 0x0e, 0x58,
0xef, 0x2a, 0x70, 0x8a, 0x56, 0x8a, 0xcf, 0x6b, 0x7a, 0x74, 0x0c, 0xf4, 0x15, 0x37, 0x93, 0xcd,
0xe6, 0xb2, 0xa1, 0x83, 0x09, 0xdb, 0x9e, 0x4f, 0xff, 0x6a, 0x17, 0x4f, 0x33, 0xc9, 0xcc, 0x90,
0x2a, 0x67, 0xff, 0x16, 0x78, 0xa8, 0x2c, 0x10, 0xe0, 0x52, 0x8c, 0xe6, 0xe9, 0x90, 0x8d, 0xe0,
0x62, 0x04, 0x9a, 0x0f, 0x44, 0x01, 0x82, 0x14, 0x92, 0x44, 0x25, 0x69, 0x22, 0xb7, 0xb8, 0xc5,
0x94, 0x4c, 0x4b, 0x1c, 0x9b, 0x92, 0x60, 0x66, 0x90, 0x4e, 0xb9, 0xa8, 0x4c, 0x89, 0xbb, 0x0f,
0x0b,
};
static const unsigned char KEY1[] =
{
0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xbc, 0xdc, 0x6f, 0x8c, 0x7a,
0x2a, 0x4b, 0xea, 0x66, 0x66, 0x04, 0xa9, 0x05, 0x92, 0x53, 0xd7, 0x13, 0x3c, 0x49, 0xe1, 0xc8,
0xbb, 0xdf, 0x3d, 0xcb, 0x88, 0x31, 0x07, 0x20, 0x59, 0x93, 0x24, 0x7f, 0x7d, 0xc6, 0x84, 0x81,
0x16, 0x64, 0x4a, 0x52, 0xa6, 0x30, 0x44, 0xdc, 0x1a, 0x30, 0xde, 0xae, 0x29, 0x18, 0xcf, 0xc7,
0xf3, 0xcf, 0x0c, 0xb7, 0x8e, 0x2b, 0x1e, 0x21, 0x01, 0x0b, 0xfb, 0xe5, 0xe6, 0xcf, 0x2b, 0x84,
0xe1, 0x33, 0xf8, 0xba, 0x02, 0xfc, 0x30, 0xfa, 0xc4, 0x33, 0xc7, 0x37, 0xc6, 0x7f, 0x72, 0x31,
0x92, 0x1d, 0x8f, 0xa0, 0xfb, 0xe5, 0x4a, 0x08, 0x31, 0x78, 0x80, 0x9c, 0x23, 0xb4, 0xe9, 0x19,
0x56, 0x04, 0xfa, 0x0d, 0x07, 0x04, 0xb7, 0x43, 0xac, 0x4c, 0x49, 0x7c, 0xc2, 0xa1, 0x44, 0xc1,
0x48, 0x7d, 0x28, 0xe5, 0x23, 0x66, 0x07, 0x22, 0xd5, 0xf0, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x81, 0x81, 0x00, 0xa5, 0x6d, 0xf9, 0x8f, 0xf5, 0x5a, 0xa3, 0x50, 0xd9, 0x0d, 0x37, 0xbb,
0xce, 0x13, 0x94, 0xb8, 0xea, 0x32, 0x7f, 0x0c, 0xf5, 0x46, 0x0b, 0x90, 0x17, 0x7e, 0x5e, 0x63,
0xbd, 0xa4, 0x78, 0xcd, 0x19, 0x97, 0xd4, 0x92, 0x30, 0x78, 0xaa, 0xb4, 0xa7, 0x9c, 0xc6, 0xdf,
0x2a, 0x65, 0x0e, 0xb5, 0x9f, 0x9c, 0x84, 0x0d, 0x4d, 0x3a, 0x74, 0xfc, 0xd0, 0xb4, 0x09, 0x74,
0xc4, 0xb8, 0x24, 0x03, 0xa8, 0xf0, 0xf8, 0x0d, 0x5c, 0x8e, 0xdf, 0x4b, 0xe1, 0x0a, 0x8f, 0x4f,
0xd5, 0xc7, 0x9b, 0x54, 0x55, 0x8f, 0x00, 0x5c, 0xea, 0x4c, 0x73, 0xf9, 0x1b, 0xbf, 0xb8, 0x93,
0x33, 0x20, 0xce, 0x45, 0xd9, 0x03, 0x02, 0xb2, 0x36, 0xc5, 0x0a, 0x30, 0x50, 0x78, 0x80, 0x66,
0x00, 0x22, 0x38, 0x86, 0xcf, 0x63, 0x4a, 0x5c, 0xbf, 0x2b, 0xd9, 0x6e, 0xe6, 0xf0, 0x39, 0xad,
0x12, 0x25, 0x41, 0xb9, 0x02, 0x41, 0x00, 0xf3, 0x7c, 0x07, 0x99, 0x64, 0x3a, 0x28, 0x8c, 0x8d,
0x05, 0xfe, 0x32, 0xb5, 0x4c, 0x8c, 0x6d, 0xde, 0x3d, 0x16, 0x08, 0xa0, 0x01, 0x61, 0x4f, 0x8e,
0xa0, 0xf7, 0x26, 0x26, 0xb5, 0x8e, 0xc0, 0x7a, 0xce, 0x86, 0x34, 0xde, 0xb8, 0xef, 0x86, 0x01,
0xbe, 0x24, 0xaa, 0x9b, 0x36, 0x93, 0x72, 0x9b, 0xf9, 0xc6, 0xcb, 0x76, 0x84, 0x67, 0x06, 0x06,
0x30, 0x50, 0xdf, 0x42, 0x17, 0xe0, 0xa7, 0x02, 0x41, 0x00, 0xc6, 0x91, 0xa0, 0x41, 0x34, 0x11,
0x67, 0x4b, 0x08, 0x0f, 0xda, 0xa7, 0x99, 0xec, 0x58, 0x11, 0xa5, 0x82, 0xdb, 0x50, 0xfe, 0x77,
0xe2, 0xd1, 0x53, 0x9c, 0x7d, 0xe8, 0xbf, 0xe7, 0x7c, 0xa9, 0x01, 0xb1, 0x87, 0xc3, 0x52, 0x79,
0x9e, 0x2c, 0xa7, 0x6f, 0x02, 0x37, 0x32, 0xef, 0x24, 0x31, 0x21, 0x0b, 0x86, 0x05, 0x32, 0x4a,
0x2e, 0x0b, 0x65, 0x05, 0xd3, 0xd6, 0x30, 0xb2, 0xfc, 0xa7, 0x02, 0x41, 0x00, 0xc2, 0xed, 0x31,
0xdc, 0x40, 0x9c, 0x3a, 0xe8, 0x42, 0xe2, 0x60, 0x5e, 0x52, 0x3c, 0xc5, 0x54, 0x14, 0x0e, 0x8d,
0x7c, 0x3c, 0x34, 0xbe, 0xa6, 0x05, 0x86, 0xa2, 0x36, 0x5d, 0xd9, 0x0e, 0x3e, 0xd4, 0x52, 0x50,
0xa9, 0x35, 0x01, 0x93, 0x68, 0x92, 0x2e, 0x9a, 0x86, 0x27, 0x1a, 0xab, 0x32, 0x9e, 0xe2, 0x79,
0x9f, 0x5b, 0xf3, 0xa5, 0xd2, 0xf1, 0xd3, 0x6e, 0x7b, 0x3e, 0x1b, 0x85, 0x93, 0x02, 0x40, 0x68,
0xb8, 0xb6, 0x7e, 0x8c, 0xba, 0x3c, 0xf2, 0x8a, 0x2e, 0xea, 0x4f, 0x07, 0xd3, 0x68, 0x62, 0xee,
0x1a, 0x04, 0x16, 0x44, 0x0d, 0xef, 0xf6, 0x1b, 0x95, 0x65, 0xa5, 0xd1, 0x47, 0x81, 0x2c, 0x14,
0xb3, 0x8e, 0xf9, 0x08, 0xcf, 0x11, 0x07, 0x55, 0xca, 0x2a, 0xad, 0xf7, 0xd3, 0xbd, 0x0f, 0x97,
0xf0, 0xde, 0xde, 0x70, 0xb6, 0x44, 0x70, 0x47, 0xf7, 0xf9, 0xcf, 0x75, 0x61, 0x7f, 0xf3, 0x02,
0x40, 0x38, 0x4a, 0x67, 0xaf, 0xae, 0xb6, 0xb2, 0x6a, 0x00, 0x25, 0x5a, 0xa4, 0x65, 0x20, 0xb1,
0x13, 0xbd, 0x83, 0xff, 0xb4, 0xbc, 0xf4, 0xdd, 0xa1, 0xbb, 0x1c, 0x96, 0x37, 0x35, 0xf4, 0xbf,
0xed, 0x4c, 0xed, 0x92, 0xe8, 0xac, 0xc9, 0xc1, 0xa5, 0xa3, 0x23, 0x66, 0x40, 0x8a, 0xa1, 0xe6,
0xe3, 0x95, 0xfe, 0xc4, 0x53, 0xf5, 0x7d, 0x6e, 0xca, 0x45, 0x42, 0xe4, 0xc2, 0x9f, 0xe5, 0x1e,
0xb5,
};
static const unsigned char KEY2[] =
{
0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xa8, 0x6e, 0x40, 0x86, 0x9f,
0x98, 0x59, 0xfb, 0x57, 0xbf, 0xc1, 0x55, 0x12, 0x38, 0xeb, 0xb3, 0x46, 0x34, 0xc9, 0x35, 0x4d,
0xfd, 0x03, 0xe9, 0x3a, 0x88, 0x9e, 0x97, 0x8f, 0xf4, 0xec, 0x36, 0x7b, 0x3f, 0xba, 0xb8, 0xa5,
0x96, 0x30, 0x03, 0xc5, 0xc6, 0xd9, 0xa8, 0x4e, 0xbc, 0x23, 0x51, 0xa1, 0x96, 0xd2, 0x03, 0x98,
0x73, 0xb6, 0x17, 0x9c, 0x77, 0xd4, 0x95, 0x1e, 0x1b, 0xb3, 0x1b, 0xc8, 0x71, 0xd1, 0x2e, 0x31,
0xc7, 0x6a, 0x75, 0x57, 0x08, 0x7f, 0xba, 0x70, 0x76, 0xf7, 0x67, 0xf4, 0x4e, 0xbe, 0xfc, 0x70,
0x61, 0x41, 0x07, 0x2b, 0x7c, 0x3c, 0x3b, 0xb3, 0xbc, 0xd5, 0xa8, 0xbd, 0x28, 0xd8, 0x49, 0xd3,
0xe1, 0x78, 0xc8, 0xc1, 0x42, 0x5e, 0x18, 0x36, 0xa8, 0x41, 0xf7, 0xc8, 0xaa, 0x35, 0xfe, 0x2d,
0xd1, 0xb4, 0xcc, 0x00, 0x67, 0xae, 0x79, 0xd3, 0x28, 0xd5, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x81, 0x81, 0x00, 0xa6, 0x00, 0x83, 0xf8, 0x2b, 0x33, 0xac, 0xfb, 0xdb, 0xf0, 0x52, 0x4b,
0xd6, 0x39, 0xe3, 0x94, 0x3d, 0x8d, 0xa9, 0x01, 0xb0, 0x6b, 0xbe, 0x7f, 0x10, 0x01, 0xb6, 0xcd,
0x0a, 0x45, 0x0a, 0xca, 0x67, 0x8e, 0xd8, 0x29, 0x44, 0x8a, 0x51, 0xa8, 0x66, 0x35, 0x26, 0x30,
0x8b, 0xe9, 0x41, 0xa6, 0x22, 0xec, 0xd2, 0xf0, 0x58, 0x41, 0x33, 0x26, 0xf2, 0x3f, 0xe8, 0x75,
0x4f, 0xc7, 0x5d, 0x2e, 0x5a, 0xa8, 0x7a, 0xd2, 0xbf, 0x59, 0xa0, 0x86, 0x79, 0x0b, 0x92, 0x6c,
0x95, 0x5d, 0x87, 0x63, 0x5c, 0xd6, 0x1a, 0xc0, 0xf6, 0x7a, 0x15, 0x8d, 0xc7, 0x3c, 0xb6, 0x9e,
0xa6, 0x58, 0x46, 0x9b, 0xbf, 0x3e, 0x28, 0x8c, 0xdf, 0x1a, 0x87, 0xaa, 0x7e, 0xf5, 0xf2, 0xcb,
0x5e, 0x84, 0x2d, 0xf6, 0x82, 0x7e, 0x89, 0x4e, 0xf5, 0xe6, 0x3c, 0x92, 0x80, 0x1e, 0x98, 0x1c,
0x6a, 0x7b, 0x57, 0x01, 0x02, 0x41, 0x00, 0xdd, 0x60, 0x95, 0xd7, 0xa1, 0x9d, 0x0c, 0xa1, 0x84,
0xc5, 0x39, 0xca, 0x67, 0x4c, 0x1c, 0x06, 0x71, 0x5b, 0x5c, 0x2d, 0x8d, 0xce, 0xcd, 0xe2, 0x79,
0xc8, 0x33, 0xbe, 0x50, 0x37, 0x60, 0x9f, 0x3b, 0xb9, 0x59, 0x55, 0x22, 0x1f, 0xa5, 0x4b, 0x1d,
0xca, 0x38, 0xa0, 0xab, 0x87, 0x9c, 0x86, 0x0e, 0xdb, 0x1c, 0x4f, 0x4f, 0x07, 0xed, 0x18, 0x3f,
0x05, 0x3c, 0xec, 0x78, 0x11, 0xf6, 0x99, 0x02, 0x41, 0x00, 0xc2, 0xc5, 0xcf, 0xbe, 0x95, 0x91,
0xeb, 0xcf, 0x47, 0xf3, 0x33, 0x32, 0xc7, 0x7e, 0x93, 0x56, 0xf7, 0xd8, 0xf9, 0xd4, 0xb6, 0xd6,
0x20, 0xac, 0xba, 0x8a, 0x20, 0x19, 0x14, 0xab, 0xc5, 0x5d, 0xb2, 0x08, 0xcc, 0x77, 0x7c, 0x65,
0xa8, 0xdb, 0x66, 0x97, 0x36, 0x44, 0x2c, 0x63, 0xc0, 0x6a, 0x7e, 0xb0, 0x0b, 0x5c, 0x90, 0x12,
0x50, 0xb4, 0x36, 0x60, 0xc3, 0x1f, 0x22, 0x0c, 0xc8, 0x13, 0x02, 0x40, 0x33, 0xc8, 0x7e, 0x04,
0x7c, 0x97, 0x61, 0xf6, 0xfe, 0x39, 0xac, 0x34, 0xfe, 0x48, 0xbd, 0x5d, 0x7c, 0x72, 0xa4, 0x73,
0x3b, 0x72, 0x9e, 0x92, 0x55, 0x6e, 0x51, 0x3c, 0x39, 0x43, 0x5a, 0xe4, 0xa4, 0x71, 0xcc, 0xc5,
0xaf, 0x3f, 0xbb, 0xc8, 0x80, 0x65, 0x67, 0x2d, 0x9e, 0x32, 0x10, 0x99, 0x03, 0x2c, 0x99, 0xc8,
0xab, 0x71, 0xed, 0x31, 0xf8, 0xbb, 0xde, 0xee, 0x69, 0x7f, 0xba, 0x31, 0x02, 0x40, 0x7e, 0xbc,
0x60, 0x55, 0x4e, 0xd5, 0xc8, 0x6e, 0xf4, 0x0e, 0x57, 0xbe, 0x2e, 0xf9, 0x39, 0xbe, 0x59, 0x3f,
0xa2, 0x30, 0xbb, 0x57, 0xd1, 0xa3, 0x13, 0x2e, 0x55, 0x7c, 0x7c, 0x6a, 0xd8, 0xde, 0x02, 0xbe,
0x9e, 0xed, 0x10, 0xd0, 0xc5, 0x73, 0x1d, 0xea, 0x3e, 0xb1, 0x55, 0x81, 0x02, 0xef, 0x48, 0xc8,
0x1c, 0x5c, 0x7a, 0x92, 0xb0, 0x58, 0xd3, 0x19, 0x5b, 0x5d, 0xa2, 0xb6, 0x56, 0x69, 0x02, 0x40,
0x1e, 0x00, 0x6a, 0x9f, 0xba, 0xee, 0x46, 0x5a, 0xc5, 0xb5, 0x9f, 0x91, 0x33, 0xdd, 0xc9, 0x96,
0x75, 0xb7, 0x87, 0xcf, 0x18, 0x1c, 0xb7, 0xb9, 0x3f, 0x04, 0x10, 0xb8, 0x75, 0xa9, 0xb8, 0xa0,
0x31, 0x35, 0x03, 0x30, 0x89, 0xc8, 0x37, 0x68, 0x20, 0x30, 0x99, 0x39, 0x96, 0xd6, 0x2b, 0x3d,
0x5e, 0x45, 0x84, 0xf7, 0xd2, 0x61, 0x50, 0xc9, 0x50, 0xba, 0x8d, 0x08, 0xaa, 0xd0, 0x08, 0x1e,
};
static const PKCS12_ATTR ATTRS1[] = {
{ "friendlyName", "george" },
{ "localKeyID", "1234567890" },
{ "1.2.3.4.5", "MyCustomAttribute" },
{ NULL, NULL }
};
static const PKCS12_ATTR ATTRS2[] = {
{ "friendlyName", "janet" },
{ "localKeyID", "987654321" },
{ "1.2.3.5.8.13", "AnotherCustomAttribute" },
{ NULL, NULL }
};
static const PKCS12_ENC enc_default = {
NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
"Password1",
1000
};
static const PKCS12_ENC mac_default = {
NID_sha1,
"Password1",
1000
};
/* --------------------------------------------------------------------------
* Local functions
*/
static int get_custom_oid(void)
{
static int sec_nid = -1;
if (sec_nid != -1)
return sec_nid;
if (!TEST_true(OBJ_create("1.3.5.7.9", "CustomSecretOID", "My custom secret OID")))
return -1;
return sec_nid = OBJ_txt2nid("CustomSecretOID");
}
/* --------------------------------------------------------------------------
* PKCS12 format tests
*/
static int test_single_cert_no_attrs(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1cert.p12");
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_certbag(pb, CERT1, sizeof(CERT1), NULL);
end_contentinfo(pb);
end_pkcs12(pb);
/* Read/decode */
start_check_pkcs12(pb);
start_check_contentinfo(pb);
check_certbag(pb, CERT1, sizeof(CERT1), NULL);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_single_key_with_attrs(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1key.p12");
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
end_contentinfo(pb);
end_pkcs12(pb);
/* Read/decode */
start_check_pkcs12(pb);
start_check_contentinfo(pb);
check_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_cert_key_with_attrs_and_mac(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1cert1key.p12");
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_certbag(pb, CERT1, sizeof(CERT1), ATTRS1);
add_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
end_contentinfo(pb);
end_pkcs12_with_mac(pb, &mac_default);
/* Read/decode */
start_check_pkcs12_with_mac(pb, &mac_default);
start_check_contentinfo(pb);
check_certbag(pb, CERT1, sizeof(CERT1), ATTRS1);
check_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_cert_key_encrypted_content(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1cert1key_enc.p12");
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_certbag(pb, CERT1, sizeof(CERT1), ATTRS1);
add_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
end_contentinfo_encrypted(pb, &enc_default);
end_pkcs12_with_mac(pb, &mac_default);
/* Read/decode */
start_check_pkcs12_with_mac(pb, &mac_default);
start_check_contentinfo_encrypted(pb, &enc_default);
check_certbag(pb, CERT1, sizeof(CERT1), ATTRS1);
check_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_single_secret_encrypted_content(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("1secret.p12");
int custom_nid = get_custom_oid();
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_secretbag(pb, custom_nid, "VerySecretMessage", ATTRS1);
end_contentinfo_encrypted(pb, &enc_default);
end_pkcs12_with_mac(pb, &mac_default);
/* Read/decode */
start_check_pkcs12_with_mac(pb, &mac_default);
start_check_contentinfo_encrypted(pb, &enc_default);
check_secretbag(pb, custom_nid, "VerySecretMessage", ATTRS1);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
static int test_multiple_contents(void)
{
PKCS12_BUILDER *pb = new_pkcs12_builder("multi_contents.p12");
int custom_nid = get_custom_oid();
/* Generate/encode */
start_pkcs12(pb);
start_contentinfo(pb);
add_certbag(pb, CERT1, sizeof(CERT1), ATTRS1);
add_certbag(pb, CERT2, sizeof(CERT2), ATTRS2);
add_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
add_keybag(pb, KEY2, sizeof(KEY2), ATTRS2, &enc_default);
end_contentinfo(pb);
start_contentinfo(pb);
add_secretbag(pb, custom_nid, "VeryVerySecretMessage", ATTRS1);
end_contentinfo_encrypted(pb, &enc_default);
end_pkcs12_with_mac(pb, &mac_default);
/* Read/decode */
start_check_pkcs12_with_mac(pb, &mac_default);
start_check_contentinfo(pb);
check_certbag(pb, CERT1, sizeof(CERT1), ATTRS1);
check_certbag(pb, CERT2, sizeof(CERT2), ATTRS2);
check_keybag(pb, KEY1, sizeof(KEY1), ATTRS1, &enc_default);
check_keybag(pb, KEY2, sizeof(KEY2), ATTRS2, &enc_default);
end_check_contentinfo(pb);
start_check_contentinfo_encrypted(pb, &enc_default);
check_secretbag(pb, custom_nid, "VeryVerySecretMessage", ATTRS1);
end_check_contentinfo(pb);
end_check_pkcs12(pb);
return end_pkcs12_builder(pb);
}
int setup_tests(void)
{
ADD_TEST(test_single_cert_no_attrs);
ADD_TEST(test_single_key_with_attrs);
ADD_TEST(test_cert_key_with_attrs_and_mac);
ADD_TEST(test_cert_key_encrypted_content);
ADD_TEST(test_single_secret_encrypted_content);
ADD_TEST(test_multiple_contents);
return 1;
}

708
test/pkcs12_helper.c Normal file
View File

@ -0,0 +1,708 @@
/*
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "internal/nelem.h"
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
#include "testutil.h"
#include "pkcs12_helper.h"
DEFINE_STACK_OF(PKCS7)
DEFINE_STACK_OF(PKCS12_SAFEBAG)
DEFINE_STACK_OF(X509_ATTRIBUTE)
/* Set this to > 0 write test data to file */
int write_files = 0;
/* -------------------------------------------------------------------------
* Local function declarations
*/
static X509 *load_cert(const unsigned char *bytes, int len);
static EVP_PKEY *load_pkey(const unsigned char *bytes, int len);
static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs);
static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac);
static int write_p12(PKCS12 *p12, const char *outfile);
static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac);
static PKCS12 *read_p12(const char *infile, const PKCS12_ENC *mac);
static int check_p12_mac(PKCS12 *p12, const PKCS12_ENC *mac);
static int check_asn1_string(const ASN1_TYPE *av, const char *txt);
static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs);
/* --------------------------------------------------------------------------
* Test data load functions
*/
static X509 *load_cert(const unsigned char *bytes, int len)
{
X509 *cert = NULL;
cert = d2i_X509(NULL, &bytes, len);
if (!TEST_ptr(cert))
goto err;
err:
return cert;
}
static EVP_PKEY *load_pkey(const unsigned char *bytes, int len)
{
EVP_PKEY *pkey = NULL;
pkey = d2i_AutoPrivateKey(NULL, &bytes, len);
if (!TEST_ptr(pkey))
goto err;
err:
return pkey;
}
/* -------------------------------------------------------------------------
* PKCS12 builder
*/
PKCS12_BUILDER *new_pkcs12_builder(const char *filename)
{
PKCS12_BUILDER *pb = OPENSSL_malloc(sizeof(PKCS12_BUILDER));
if (!TEST_ptr(pb))
return NULL;
pb->filename = filename;
pb->success = 1;
return pb;
}
int end_pkcs12_builder(PKCS12_BUILDER *pb)
{
int result = pb->success;
OPENSSL_free(pb);
return result;
}
void start_pkcs12(PKCS12_BUILDER *pb)
{
pb->safes = NULL;
}
void end_pkcs12(PKCS12_BUILDER *pb)
{
if (!pb->success)
return;
generate_p12(pb, NULL);
}
void end_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
if (!pb->success)
return;
generate_p12(pb, mac);
}
/* Generate the PKCS12 encoding and write to memory bio */
static void generate_p12(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
PKCS12 *p12;
if (!pb->success)
return;
pb->p12bio = BIO_new(BIO_s_mem());
if (!TEST_ptr(pb->p12bio)) {
pb->success = 0;
return;
}
p12 = PKCS12_add_safes(pb->safes, 0);
if (!TEST_ptr(p12)) {
pb->success = 0;
goto err;
}
sk_PKCS7_pop_free(pb->safes, PKCS7_free);
if (mac != NULL) {
if (!TEST_true(PKCS12_set_mac(p12, mac->pass, strlen(mac->pass),
NULL, 0, mac->iter, EVP_get_digestbynid(mac->nid)))) {
pb->success = 0;
goto err;
}
}
i2d_PKCS12_bio(pb->p12bio, p12);
/* Can write to file here for debug */
if (write_files)
write_p12(p12, pb->filename);
err:
PKCS12_free(p12);
}
static int write_p12(PKCS12 *p12, const char *outfile)
{
int ret = 0;
BIO *out = BIO_new_file(outfile, "w");
if (out == NULL)
goto err;
if (!TEST_int_eq(i2d_PKCS12_bio(out, p12), 1))
goto err;
ret = 1;
err:
BIO_free(out);
return ret;
}
static PKCS12 *from_bio_p12(BIO *bio, const PKCS12_ENC *mac)
{
PKCS12 *p12 = NULL;
p12 = d2i_PKCS12_bio(bio, NULL);
BIO_free(bio);
if (!TEST_ptr(p12))
goto err;
if (mac == NULL) {
if (!TEST_false(PKCS12_mac_present(p12)))
goto err;
} else {
if (!check_p12_mac(p12, mac))
goto err;
}
return p12;
err:
PKCS12_free(p12);
return NULL;
}
/* For use with existing files */
static PKCS12 *read_p12(const char *infile, const PKCS12_ENC *mac)
{
PKCS12 *p12 = NULL;
BIO *in = BIO_new_file(infile, "r");
if (in == NULL)
goto err;
p12 = d2i_PKCS12_bio(in, NULL);
BIO_free(in);
if (!TEST_ptr(p12))
goto err;
if (mac == NULL) {
if (!TEST_false(PKCS12_mac_present(p12)))
goto err;
} else {
if (!check_p12_mac(p12, mac))
goto err;
}
return p12;
err:
PKCS12_free(p12);
return NULL;
}
static int check_p12_mac(PKCS12 *p12, const PKCS12_ENC *mac)
{
return TEST_true(PKCS12_mac_present(p12))
&& TEST_true(PKCS12_verify_mac(p12, mac->pass, strlen(mac->pass)));
}
/* -------------------------------------------------------------------------
* PKCS7 content info builder
*/
void start_contentinfo(PKCS12_BUILDER *pb)
{
pb->bags = NULL;
}
void end_contentinfo(PKCS12_BUILDER *pb)
{
if (pb->success) {
if (pb->bags && !TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, -1, 0, NULL))) {
pb->success = 0;
return;
}
}
sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
pb->bags = NULL;
}
void end_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
{
if (pb->success) {
if (pb->bags
&& !TEST_true(PKCS12_add_safe(&pb->safes, pb->bags, enc->nid, enc->iter, enc->pass))) {
pb->success = 0;
return;
}
}
sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
pb->bags = NULL;
}
static STACK_OF(PKCS12_SAFEBAG) *decode_contentinfo(STACK_OF(PKCS7) *safes, int idx, const PKCS12_ENC *enc)
{
STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
PKCS7 *p7 = sk_PKCS7_value(safes, idx);
int bagnid = OBJ_obj2nid(p7->type);
if (enc) {
if (!TEST_int_eq(bagnid, NID_pkcs7_encrypted))
goto err;
/* TODO: Check algorithm (iterations?) against what we originally set */
bags = PKCS12_unpack_p7encdata(p7, enc->pass, strlen(enc->pass));
} else {
if (!TEST_int_eq(bagnid, NID_pkcs7_data))
goto err;
bags = PKCS12_unpack_p7data(p7);
}
if (!TEST_ptr(bags))
goto err;
return bags;
err:
return NULL;
}
/* -------------------------------------------------------------------------
* PKCS12 safeBag/attribute builder
*/
static int add_attributes(PKCS12_SAFEBAG *bag, const PKCS12_ATTR *attrs)
{
int ret = 0;
int attr_nid;
const PKCS12_ATTR *p_attr = attrs;
if (attrs == NULL)
return 1;
while (p_attr->oid != NULL) {
TEST_info("Adding attribute %s = %s", p_attr->oid, p_attr->value);
attr_nid = OBJ_txt2nid(p_attr->oid);
if (attr_nid == NID_friendlyName) {
if (!TEST_true(PKCS12_add_friendlyname(bag, p_attr->value, -1)))
goto err;
} else if (attr_nid == NID_localKeyID) {
if (!TEST_true(PKCS12_add_localkeyid(bag, (unsigned char *)p_attr->value,
strlen(p_attr->value))))
goto err;
} else {
/* Custom attribute values limited to ASCII in these tests */
if (!TEST_true(PKCS12_add1_attr_by_txt(bag, p_attr->oid, MBSTRING_ASC,
(unsigned char *)p_attr->value,
strlen(p_attr->value))))
goto err;
}
p_attr++;
}
ret = 1;
err:
return ret;
}
void add_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs)
{
PKCS12_SAFEBAG *bag = NULL;
X509 *cert = NULL;
char *name;
if (!pb->success)
return;
cert = load_cert(bytes, len);
if (!TEST_ptr(cert)) {
pb->success = 0;
return;
}
name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
TEST_info("Adding certificate <%s>", name);
OPENSSL_free(name);
bag = PKCS12_add_cert(&pb->bags, cert);
if (!TEST_ptr(bag)) {
pb->success = 0;
goto err;
}
if (!TEST_true(add_attributes(bag, attrs))) {
pb->success = 0;
goto err;
}
err:
X509_free(cert);
}
void add_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs, const PKCS12_ENC *enc)
{
PKCS12_SAFEBAG *bag = NULL;
EVP_PKEY *pkey = NULL;
if (!pb->success)
return;
TEST_info("Adding key");
pkey = load_pkey(bytes, len);
if (!TEST_ptr(pkey)) {
pb->success = 0;
return;
}
bag = PKCS12_add_key(&pb->bags, pkey, 0 /*keytype*/, enc->iter, enc->nid, enc->pass);
if (!TEST_ptr(bag)) {
pb->success = 0;
goto err;
}
if (!add_attributes(bag, attrs))
pb->success = 0;
err:
EVP_PKEY_free(pkey);
}
void add_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret,
const PKCS12_ATTR *attrs)
{
PKCS12_SAFEBAG *bag = NULL;
if (!pb->success)
return;
TEST_info("Adding secret <%s>", secret);
bag = PKCS12_add_secret(&pb->bags, secret_nid, (const unsigned char *)secret, strlen(secret));
if (!TEST_ptr(bag)) {
pb->success = 0;
return;
}
if (!add_attributes(bag, attrs))
pb->success = 0;
}
/* -------------------------------------------------------------------------
* PKCS12 structure checking
*/
static int check_asn1_string(const ASN1_TYPE *av, const char *txt)
{
int ret = 0;
char *value = NULL;
if (!TEST_ptr(av))
goto err;
switch (av->type) {
case V_ASN1_BMPSTRING:
value = OPENSSL_uni2asc(av->value.bmpstring->data,
av->value.bmpstring->length);
if (!TEST_str_eq(txt, (char *)value))
goto err;
break;
case V_ASN1_UTF8STRING:
if (!TEST_str_eq(txt, (char *)av->value.utf8string->data))
goto err;
break;
case V_ASN1_OCTET_STRING:
if (!TEST_str_eq(txt, (char *)av->value.octet_string->data))
goto err;
break;
default:
/* Tests do not support other attribute types currently */
goto err;
}
ret = 1;
err:
OPENSSL_free(value);
return ret;
}
static int check_attrs(const STACK_OF(X509_ATTRIBUTE) *bag_attrs, const PKCS12_ATTR *attrs)
{
int ret = 0;
X509_ATTRIBUTE *attr;
ASN1_TYPE *av;
int i, j;
char attr_txt[100];
for (i = 0; i < sk_X509_ATTRIBUTE_num(bag_attrs); i++) {
const PKCS12_ATTR *p_attr = attrs;
ASN1_OBJECT *attr_obj;
attr = sk_X509_ATTRIBUTE_value(bag_attrs, i);
attr_obj = X509_ATTRIBUTE_get0_object(attr);
OBJ_obj2txt(attr_txt, 100, attr_obj, 0);
while(p_attr->oid != NULL) {
/* Find a matching attribute type */
if (strcmp(p_attr->oid, attr_txt) == 0) {
/* TODO: Handle multi-value attributes */
if (!TEST_int_eq(X509_ATTRIBUTE_count(attr), 1))
goto err;
for (j = 0; j < X509_ATTRIBUTE_count(attr); j++)
{
av = X509_ATTRIBUTE_get0_type(attr, j);
if (!TEST_true(check_asn1_string(av, p_attr->value)))
goto err;
}
break;
}
p_attr++;
}
}
ret = 1;
err:
return ret;
}
void check_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs)
{
X509 *x509 = NULL;
X509 *ref_x509 = NULL;
const PKCS12_SAFEBAG *bag;
if (!pb->success)
return;
bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
if (!TEST_ptr(bag)) {
pb->success = 0;
return;
}
if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)
|| !TEST_int_eq(PKCS12_SAFEBAG_get_nid(bag), NID_certBag)
|| !TEST_int_eq(PKCS12_SAFEBAG_get_bag_nid(bag), NID_x509Certificate)) {
pb->success = 0;
return;
}
x509 = PKCS12_SAFEBAG_get1_cert(bag);
if (!TEST_ptr(x509)) {
pb->success = 0;
goto err;
}
ref_x509 = load_cert(bytes, len);
if (!TEST_false(X509_cmp(x509, ref_x509)))
pb->success = 0;
err:
X509_free(x509);
X509_free(ref_x509);
}
void check_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs, const PKCS12_ENC *enc)
{
EVP_PKEY *pkey = NULL;
EVP_PKEY *ref_pkey = NULL;
PKCS8_PRIV_KEY_INFO *p8;
const PKCS8_PRIV_KEY_INFO *p8c;
const PKCS12_SAFEBAG *bag;
if (!pb->success)
return;
bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
if (!TEST_ptr(bag)) {
pb->success = 0;
return;
}
if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)) {
pb->success = 0;
return;
}
switch (PKCS12_SAFEBAG_get_nid(bag)) {
case NID_keyBag:
p8c = PKCS12_SAFEBAG_get0_p8inf(bag);
if (!TEST_ptr(pkey = EVP_PKCS82PKEY(p8c))) {
pb->success = 0;
goto err;
}
/* TODO: handle key attributes */
/* PKCS8_pkey_get0_attrs(p8c); */
break;
case NID_pkcs8ShroudedKeyBag:
if (!TEST_ptr(p8 = PKCS12_decrypt_skey(bag, enc->pass, strlen(enc->pass)))) {
pb->success = 0;
goto err;
}
if (!TEST_ptr(pkey = EVP_PKCS82PKEY(p8))) {
PKCS8_PRIV_KEY_INFO_free(p8);
pb->success = 0;
goto err;
}
/* TODO: handle key attributes */
/* PKCS8_pkey_get0_attrs(p8); */
PKCS8_PRIV_KEY_INFO_free(p8);
break;
default:
pb->success = 0;
goto err;
}
/* PKEY compare returns 1 for match */
ref_pkey = load_pkey(bytes, len);
if (!TEST_true(EVP_PKEY_eq(pkey, ref_pkey)))
pb->success = 0;
err:
EVP_PKEY_free(pkey);
EVP_PKEY_free(ref_pkey);
}
void check_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret, const PKCS12_ATTR *attrs)
{
const PKCS12_SAFEBAG *bag;
if (!pb->success)
return;
bag = sk_PKCS12_SAFEBAG_value(pb->bags, pb->bag_idx++);
if (!TEST_ptr(bag)) {
pb->success = 0;
return;
}
if (!check_attrs(PKCS12_SAFEBAG_get0_attrs(bag), attrs)
|| !TEST_int_eq(PKCS12_SAFEBAG_get_nid(bag), NID_secretBag)
|| !TEST_int_eq(PKCS12_SAFEBAG_get_bag_nid(bag), secret_nid)
|| !TEST_true(check_asn1_string(PKCS12_SAFEBAG_get0_bag_obj(bag), secret)))
pb->success = 0;
}
void start_check_pkcs12(PKCS12_BUILDER *pb)
{
PKCS12 *p12 = from_bio_p12(pb->p12bio, NULL);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
}
pb->safes = PKCS12_unpack_authsafes(p12);
if (!TEST_ptr(pb->safes))
pb->success = 0;
pb->safe_idx = 0;
PKCS12_free(p12);
}
void start_check_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
PKCS12 *p12 = from_bio_p12(pb->p12bio, mac);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
}
pb->safes = PKCS12_unpack_authsafes(p12);
if (!TEST_ptr(pb->safes))
pb->success = 0;
pb->safe_idx = 0;
PKCS12_free(p12);
}
void start_check_pkcs12_file(PKCS12_BUILDER *pb)
{
PKCS12 *p12 = read_p12(pb->filename, NULL);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
}
pb->safes = PKCS12_unpack_authsafes(p12);
if (!TEST_ptr(pb->safes))
pb->success = 0;
pb->safe_idx = 0;
PKCS12_free(p12);
}
void start_check_pkcs12_file_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac)
{
PKCS12 *p12 = read_p12(pb->filename, mac);
if (!TEST_ptr(p12)) {
pb->success = 0;
return;
}
pb->safes = PKCS12_unpack_authsafes(p12);
if (!TEST_ptr(pb->safes))
pb->success = 0;
pb->safe_idx = 0;
PKCS12_free(p12);
}
void end_check_pkcs12(PKCS12_BUILDER *pb)
{
sk_PKCS7_pop_free(pb->safes, PKCS7_free);
}
void start_check_contentinfo(PKCS12_BUILDER *pb)
{
pb->bag_idx = 0;
pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, NULL);
if (!TEST_ptr(pb->bags)) {
pb->success = 0;
return;
}
TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb->bags));
}
void start_check_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc)
{
pb->bag_idx = 0;
pb->bags = decode_contentinfo(pb->safes, pb->safe_idx++, enc);
if (!TEST_ptr(pb->bags)) {
pb->success = 0;
return;
}
TEST_info("Decoding %d bags", sk_PKCS12_SAFEBAG_num(pb->bags));
}
void end_check_contentinfo(PKCS12_BUILDER *pb)
{
if (!TEST_int_eq(sk_PKCS12_SAFEBAG_num(pb->bags), pb->bag_idx))
pb->success = 0;
sk_PKCS12_SAFEBAG_pop_free(pb->bags, PKCS12_SAFEBAG_free);
pb->bags = NULL;
}

99
test/pkcs12_helper.h Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "internal/nelem.h"
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
#include "testutil.h"
/* Set this to > 0 write test data to file */
extern int write_files;
/* -------------------------------------------------------------------------
* PKCS#12 Test structures
*/
/* Holds a set of Attributes */
typedef struct pkcs12_attr {
char *oid;
char *value;
} PKCS12_ATTR;
/* Holds encryption parameters */
typedef struct pkcs12_enc {
int nid;
char *pass;
int iter;
} PKCS12_ENC;
/* Set of variables required for constructing the PKCS#12 structure */
typedef struct pkcs12_builder {
const char *filename;
int success;
BIO *p12bio;
STACK_OF(PKCS7) *safes;
int safe_idx;
STACK_OF(PKCS12_SAFEBAG) *bags;
int bag_idx;
} PKCS12_BUILDER;
/* -------------------------------------------------------------------------
* PKCS#12 Test function declarations
*/
/* Allocate and initialise a PKCS#12 builder object */
PKCS12_BUILDER *new_pkcs12_builder(const char *filename);
/* Finalise and free the PKCS#12 builder object, returning the success/fail flag */
int end_pkcs12_builder(PKCS12_BUILDER *pb);
/* Encode/build functions */
void start_pkcs12(PKCS12_BUILDER *pb);
void end_pkcs12(PKCS12_BUILDER *pb);
void end_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac);
void start_contentinfo(PKCS12_BUILDER *pb);
void end_contentinfo(PKCS12_BUILDER *pb);
void end_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc);
void add_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs);
void add_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs, const PKCS12_ENC *enc);
void add_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret,
const PKCS12_ATTR *attrs);
/* Decode/check functions */
void start_check_pkcs12(PKCS12_BUILDER *pb);
void start_check_pkcs12_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac);
void start_check_pkcs12_file(PKCS12_BUILDER *pb);
void start_check_pkcs12_file_with_mac(PKCS12_BUILDER *pb, const PKCS12_ENC *mac);
void end_check_pkcs12(PKCS12_BUILDER *pb);
void start_check_contentinfo(PKCS12_BUILDER *pb);
void start_check_contentinfo_encrypted(PKCS12_BUILDER *pb, const PKCS12_ENC *enc);
void end_check_contentinfo(PKCS12_BUILDER *pb);
void check_certbag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs);
void check_keybag(PKCS12_BUILDER *pb, const unsigned char *bytes, int len,
const PKCS12_ATTR *attrs, const PKCS12_ENC *enc);
void check_secretbag(PKCS12_BUILDER *pb, int secret_nid, const char *secret,
const PKCS12_ATTR *attrs);

View File

@ -57,7 +57,10 @@ if (eval { require Win32::API; 1; }) {
}
$ENV{OPENSSL_WIN32_UTF8}=1;
plan tests => 1;
plan tests => 2;
# Test different PKCS#12 formats
ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats");
# just see that we can read shibboleth.pfx protected with $pass
ok(run(app(["openssl", "pkcs12", "-noout",

View File

@ -5197,3 +5197,9 @@ OSSL_DESERIALIZER_CTX_set_cleanup ? 3_0_0 EXIST::FUNCTION:
OSSL_DESERIALIZER_CTX_get_construct ? 3_0_0 EXIST::FUNCTION:
OSSL_DESERIALIZER_CTX_get_construct_data ? 3_0_0 EXIST::FUNCTION:
OSSL_DESERIALIZER_CTX_get_cleanup ? 3_0_0 EXIST::FUNCTION:
PKCS12_SAFEBAG_get0_bag_obj ? 3_0_0 EXIST::FUNCTION:
PKCS12_SAFEBAG_get0_bag_type ? 3_0_0 EXIST::FUNCTION:
PKCS12_SAFEBAG_create_secret ? 3_0_0 EXIST::FUNCTION:
PKCS12_add1_attr_by_NID ? 3_0_0 EXIST::FUNCTION:
PKCS12_add1_attr_by_txt ? 3_0_0 EXIST::FUNCTION:
PKCS12_add_secret ? 3_0_0 EXIST::FUNCTION: