From 25dbe282917abc725bd9be9caf14aed2a3f5ba48 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Fri, 4 Oct 2019 11:50:12 -0500 Subject: [PATCH] hx509: SANs are critical if DN is empty --- lib/hx509/ca.c | 19 +++++++++++-------- lib/hx509/libhx509-exports.def | 1 + lib/hx509/name.c | 18 ++++++++++++++++-- lib/hx509/version-script.map | 1 + 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/hx509/ca.c b/lib/hx509/ca.c index 55fa458de..f81641eef 100644 --- a/lib/hx509/ca.c +++ b/lib/hx509/ca.c @@ -1087,6 +1087,12 @@ ca_sign(hx509_context context, tbsc = &c.tbsCertificate; + /* Default subject Name to empty */ + if (tbs->subject == NULL && + (ret = hx509_empty_name(context, &tbs->subject))) + return ret; + + /* Sanity checks */ if (tbs->flags.key == 0) { ret = EINVAL; hx509_set_error_string(context, 0, ret, "No public key set"); @@ -1097,13 +1103,9 @@ ca_sign(hx509_context context, * will be generated below. */ if (!tbs->flags.proxy) { - if (tbs->subject == NULL) { - hx509_set_error_string(context, 0, EINVAL, "No subject name set"); - return EINVAL; - } if (hx509_name_is_null_p(tbs->subject) && tbs->san.len == 0) { hx509_set_error_string(context, 0, EINVAL, - "NULL subject and no SubjectAltNames"); + "Empty subject and no SubjectAltNames"); return EINVAL; } } @@ -1291,9 +1293,10 @@ ca_sign(hx509_context context, } if (size != data.length) _hx509_abort("internal ASN.1 encoder error"); - ret = add_extension(context, tbsc, 0, - &asn1_oid_id_x509_ce_subjectAltName, - &data); + + /* The SAN extension is critical if the subject Name is empty */ + ret = add_extension(context, tbsc, hx509_name_is_null_p(tbs->subject), + &asn1_oid_id_x509_ce_subjectAltName, &data); free(data.data); if (ret) goto out; diff --git a/lib/hx509/libhx509-exports.def b/lib/hx509/libhx509-exports.def index 755ca7562..846435f32 100644 --- a/lib/hx509/libhx509-exports.def +++ b/lib/hx509/libhx509-exports.def @@ -144,6 +144,7 @@ EXPORTS hx509_crypto_set_padding hx509_crypto_set_params hx509_crypto_set_random_key + hx509_empty_name hx509_env_add hx509_env_add_binding hx509_env_find diff --git a/lib/hx509/name.c b/lib/hx509/name.c index 33df8a23b..2dccc6453 100644 --- a/lib/hx509/name.c +++ b/lib/hx509/name.c @@ -605,6 +605,19 @@ _hx509_name_modify(hx509_context context, return 0; } +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_empty_name(hx509_context context, hx509_name *name) +{ + if ((*name = calloc(1, sizeof(**name))) == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + (*name)->der_name.element = choice_Name_rdnSequence; + (*name)->der_name.u.rdnSequence.val = 0; + (*name)->der_name.u.rdnSequence.len = 0; + return 0; +} + /** * Parse a string into a hx509 name object. * @@ -972,7 +985,7 @@ _hx509_unparse_Name(const Name *aname, char **str) } /** - * Unparse the hx509 name in name into a string. + * Check if a name is empty. * * @param name the name to check if its empty/null. * @@ -984,7 +997,8 @@ _hx509_unparse_Name(const Name *aname, char **str) HX509_LIB_FUNCTION int HX509_LIB_CALL hx509_name_is_null_p(const hx509_name name) { - return name->der_name.u.rdnSequence.len == 0; + return name->der_name.element == choice_Name_rdnSequence && + name->der_name.u.rdnSequence.len == 0; } /** diff --git a/lib/hx509/version-script.map b/lib/hx509/version-script.map index 8e19abf0a..9abc06910 100644 --- a/lib/hx509/version-script.map +++ b/lib/hx509/version-script.map @@ -137,6 +137,7 @@ HEIMDAL_X509_1.2 { hx509_crypto_set_padding; hx509_crypto_set_params; hx509_crypto_set_random_key; + hx509_empty_name; hx509_env_add; hx509_env_add_binding; hx509_env_find;