mirror of
https://github.com/AntelopeIO/boringssl.git
synced 2026-07-21 14:43:53 +00:00
Use X509 certificate alias as friendlyName in PKCS12
Bug: 481 Change-Id: I5c1dd6e39874cd1e88cb6fd0b3a6c6c6fac0db85 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51665 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com>
This commit is contained in:
committed by
Boringssl LUCI CQ
parent
c9a7dd6879
commit
225e8d39b5
@@ -1,3 +1,4 @@
|
||||
PKCS8,133,AMBIGUOUS_FRIENDLY_NAME
|
||||
PKCS8,129,BAD_ITERATION_COUNT
|
||||
PKCS8,100,BAD_PKCS12_DATA
|
||||
PKCS8,101,BAD_PKCS12_VERSION
|
||||
|
||||
@@ -599,3 +599,45 @@ TEST(PKCS12Test, Order) {
|
||||
ASSERT_TRUE(PKCS12CreateVector(&p12, key1.get(), {cert2.get(), cert3.get()}));
|
||||
ExpectPKCS12Parse(p12, key1.get(), nullptr, {cert2.get(), cert3.get()});
|
||||
}
|
||||
|
||||
TEST(PKCS12Test, CreateWithAlias) {
|
||||
bssl::UniquePtr<EVP_PKEY> key = MakeTestKey();
|
||||
ASSERT_TRUE(key);
|
||||
bssl::UniquePtr<X509> cert1 = MakeTestCert(key.get());
|
||||
ASSERT_TRUE(cert1);
|
||||
bssl::UniquePtr<X509> cert2 = MakeTestCert(key.get());
|
||||
ASSERT_TRUE(cert2);
|
||||
|
||||
std::string alias = "I'm an alias";
|
||||
int res = X509_alias_set1(
|
||||
cert1.get(), reinterpret_cast<const unsigned char *>(alias.data()),
|
||||
alias.size());
|
||||
ASSERT_EQ(res, 1);
|
||||
|
||||
std::vector<X509 *> certs = {cert1.get(), cert2.get()};
|
||||
std::vector<uint8_t> der;
|
||||
ASSERT_TRUE(PKCS12CreateVector(&der, key.get(), certs));
|
||||
|
||||
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(der.data(), der.size()));
|
||||
ASSERT_TRUE(bio);
|
||||
bssl::UniquePtr<PKCS12> p12(d2i_PKCS12_bio(bio.get(), nullptr));
|
||||
ASSERT_TRUE(p12);
|
||||
|
||||
EVP_PKEY *parsed_key = nullptr;
|
||||
X509 *parsed_cert = nullptr;
|
||||
STACK_OF(X509) *ca_certs = nullptr;
|
||||
ASSERT_TRUE(
|
||||
PKCS12_parse(p12.get(), kPassword, &parsed_key, &parsed_cert, &ca_certs));
|
||||
|
||||
bssl::UniquePtr<EVP_PKEY> delete_key(parsed_key);
|
||||
bssl::UniquePtr<X509> delete_cert(parsed_cert);
|
||||
bssl::UniquePtr<STACK_OF(X509)> delete_ca_certs(ca_certs);
|
||||
ASSERT_EQ(sk_X509_num(ca_certs), 1UL);
|
||||
|
||||
int alias_len = 0;
|
||||
const unsigned char *parsed_alias =
|
||||
X509_alias_get0(sk_X509_value(ca_certs, 0), &alias_len);
|
||||
ASSERT_TRUE(parsed_alias);
|
||||
ASSERT_EQ(alias, std::string(reinterpret_cast<const char *>(parsed_alias),
|
||||
static_cast<size_t>(alias_len)));
|
||||
}
|
||||
|
||||
@@ -993,8 +993,8 @@ int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
|
||||
|
||||
// add_bag_attributes adds the bagAttributes field of a SafeBag structure,
|
||||
// containing the specified friendlyName and localKeyId attributes.
|
||||
static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id,
|
||||
size_t key_id_len) {
|
||||
static int add_bag_attributes(CBB *bag, const char *name, size_t name_len,
|
||||
const uint8_t *key_id, size_t key_id_len) {
|
||||
if (name == NULL && key_id_len == 0) {
|
||||
return 1; // Omit the OPTIONAL SET.
|
||||
}
|
||||
@@ -1003,7 +1003,7 @@ static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id,
|
||||
if (!CBB_add_asn1(bag, &attrs, CBS_ASN1_SET)) {
|
||||
return 0;
|
||||
}
|
||||
if (name != NULL) {
|
||||
if (name_len != 0) {
|
||||
// See https://tools.ietf.org/html/rfc2985, section 5.5.1.
|
||||
if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) ||
|
||||
!CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) ||
|
||||
@@ -1014,7 +1014,7 @@ static int add_bag_attributes(CBB *bag, const char *name, const uint8_t *key_id,
|
||||
}
|
||||
// Convert the friendly name to a BMPString.
|
||||
CBS name_cbs;
|
||||
CBS_init(&name_cbs, (const uint8_t *)name, strlen(name));
|
||||
CBS_init(&name_cbs, (const uint8_t *)name, name_len);
|
||||
while (CBS_len(&name_cbs) != 0) {
|
||||
uint32_t c;
|
||||
if (!cbs_get_utf8(&name_cbs, &c) ||
|
||||
@@ -1059,10 +1059,24 @@ static int add_cert_bag(CBB *cbb, X509 *cert, const char *name,
|
||||
}
|
||||
uint8_t *buf;
|
||||
int len = i2d_X509(cert, NULL);
|
||||
|
||||
int int_name_len = 0;
|
||||
const char *cert_name = (const char *)X509_alias_get0(cert, &int_name_len);
|
||||
size_t name_len = int_name_len;
|
||||
if (name) {
|
||||
if (name_len != 0) {
|
||||
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_AMBIGUOUS_FRIENDLY_NAME);
|
||||
return 0;
|
||||
}
|
||||
name_len = strlen(name);
|
||||
} else {
|
||||
name = cert_name;
|
||||
}
|
||||
|
||||
if (len < 0 ||
|
||||
!CBB_add_space(&cert_value, &buf, (size_t)len) ||
|
||||
i2d_X509(cert, &buf) < 0 ||
|
||||
!add_bag_attributes(&bag, name, key_id, key_id_len) ||
|
||||
!add_bag_attributes(&bag, name, name_len, key_id, key_id_len) ||
|
||||
!CBB_flush(cbb)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1323,7 +1337,11 @@ PKCS12 *PKCS12_create(const char *password, const char *name,
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (!add_bag_attributes(&bag, name, key_id, key_id_len) ||
|
||||
size_t name_len = 0;
|
||||
if (name) {
|
||||
name_len = strlen(name);
|
||||
}
|
||||
if (!add_bag_attributes(&bag, name, name_len, key_id, key_id_len) ||
|
||||
!CBB_flush(&content_infos)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ OPENSSL_EXPORT EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs,
|
||||
// and decrypts it using |password|, sets |*out_key| to the included private
|
||||
// key and appends the included certificates to |out_certs|. It returns one on
|
||||
// success and zero on error. The caller takes ownership of the outputs.
|
||||
// Any friendlyName attributes (RFC 2985) in the PKCS#12 structure will be
|
||||
// returned on the |X509| objects as aliases. See also |X509_alias_get0|.
|
||||
OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key,
|
||||
STACK_OF(X509) *out_certs,
|
||||
CBS *in, const char *password);
|
||||
@@ -219,6 +221,11 @@ OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password,
|
||||
// implemented for compatibility with external packages. Note the output still
|
||||
// requires a password for the MAC. Unencrypted keys in PKCS#12 are also not
|
||||
// widely supported and may not open in other implementations.
|
||||
//
|
||||
// If |cert| or |chain| have associated aliases (see |X509_alias_set1|), they
|
||||
// will be included in the output as friendlyName attributes (RFC 2985). It is
|
||||
// an error to specify both an alias on |cert| and a non-NULL |name|
|
||||
// parameter.
|
||||
OPENSSL_EXPORT PKCS12 *PKCS12_create(const char *password, const char *name,
|
||||
const EVP_PKEY *pkey, X509 *cert,
|
||||
const STACK_OF(X509) *chain, int key_nid,
|
||||
@@ -278,5 +285,6 @@ BSSL_NAMESPACE_END
|
||||
#define PKCS8_R_UNSUPPORTED_PRF 130
|
||||
#define PKCS8_R_INVALID_CHARACTERS 131
|
||||
#define PKCS8_R_UNSUPPORTED_OPTIONS 132
|
||||
#define PKCS8_R_AMBIGUOUS_FRIENDLY_NAME 133
|
||||
|
||||
#endif // OPENSSL_HEADER_PKCS8_H
|
||||
|
||||
Reference in New Issue
Block a user