From 37ab2a5308836327fcc0e14699602f5180d835b5 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Fri, 15 Jan 2021 13:13:55 -0600 Subject: [PATCH] hx509: Add DNSSRV and TCG SAN types and DN attrs This adds hx509 API and hxtool(1) support for PermanentIdentifier, HardwareModuleName, and DNSSRV SAN types, as well as for serialNumber, TPMManufacturer, TPMModel, and TPMVersion DN attributes. --- lib/hx509/ca.c | 324 ++++++++++++++++++++++++++++++++- lib/hx509/hx509.h | 5 + lib/hx509/hx_locl.h | 3 + lib/hx509/hxtool-commands.in | 15 ++ lib/hx509/hxtool.c | 22 +++ lib/hx509/libhx509-exports.def | 6 + lib/hx509/name.c | 83 ++++++++- lib/hx509/req.c | 111 ++++++++++- lib/hx509/test_ca.in | 28 +++ lib/hx509/version-script.map | 6 + 10 files changed, 594 insertions(+), 9 deletions(-) diff --git a/lib/hx509/ca.c b/lib/hx509/ca.c index 8cb4ccc0c..e2353f54c 100644 --- a/lib/hx509/ca.c +++ b/lib/hx509/ca.c @@ -926,6 +926,73 @@ out: return ret; } +static int +add_ia5string_san(hx509_context context, + hx509_ca_tbs tbs, + const heim_oid *oid, + const char *string) +{ + SRVName ustring; + heim_octet_string os; + size_t size; + int ret; + + ustring.data = (void *)(uintptr_t)string; + ustring.length = strlen(string); + + os.length = 0; + os.data = NULL; + + ASN1_MALLOC_ENCODE(SRVName, os.data, os.length, &ustring, &size, ret); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + return ret; + } + if (size != os.length) + _hx509_abort("internal ASN.1 encoder error"); + + ret = hx509_ca_tbs_add_san_otherName(context, tbs, oid, &os); + free(os.data); + return ret; +} + +/** + * Add DNSSRV Subject Alternative Name to the to-be-signed certificate object. + * + * @param context A hx509 context. + * @param tbs object to be signed. + * @param dnssrv An ASCII string of the for _Service.Name. + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_ca + */ + +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_ca_tbs_add_san_dnssrv(hx509_context context, + hx509_ca_tbs tbs, + const char *dnssrv) +{ + size_t i, len; + + /* Minimal DNSSRV input validation */ + if (dnssrv == 0 || dnssrv[0] != '_') { + hx509_set_error_string(context, 0, EINVAL, "Invalid DNSSRV name"); + return EINVAL; + } + for (i = 1, len = strlen(dnssrv); i < len; i++) { + if (dnssrv[i] == '.' && dnssrv[i + 1] != '\0') + break; + } + if (i == len) { + hx509_set_error_string(context, 0, EINVAL, "Invalid DNSSRV name"); + return EINVAL; + } + + return add_ia5string_san(context, tbs, + &asn1_oid_id_pkix_on_dnsSRV, dnssrv); +} + /** * Add Kerberos Subject Alternative Name to the to-be-signed * certificate object. The principal string is a UTF8 string. @@ -965,7 +1032,7 @@ add_utf8_san(hx509_context context, const heim_oid *oid, const char *string) { - const PKIXXmppAddr ustring = (const PKIXXmppAddr)(intptr_t)string; + const PKIXXmppAddr ustring = (const PKIXXmppAddr)(uintptr_t)string; heim_octet_string os; size_t size; int ret; @@ -976,17 +1043,13 @@ add_utf8_san(hx509_context context, ASN1_MALLOC_ENCODE(PKIXXmppAddr, os.data, os.length, &ustring, &size, ret); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); - goto out; + return ret; } if (size != os.length) _hx509_abort("internal ASN.1 encoder error"); - ret = hx509_ca_tbs_add_san_otherName(context, - tbs, - oid, - &os); + ret = hx509_ca_tbs_add_san_otherName(context, tbs, oid, &os); free(os.data); -out: return ret; } @@ -1092,6 +1155,253 @@ hx509_ca_tbs_add_san_rfc822name(hx509_context context, return add_GeneralNames(&tbs->san, &gn); } +/* + * PermanentIdentifier is one SAN for naming devices with TPMs after their + * endorsement keys or EK certificates. See TPM 2.0 Keys for Device Identity + * and Attestation, Version 1.00, Revision 2, 9/17/2020 (DRAFT). + * + * The text on the form of permanent identifiers for TPM endorsement keys sans + * certificates is clearly problematic, saying: "When the TPM does not have an + * EK certificate, the identifierValue is a digest of a concatenation of the + * UTF8 string “EkPubkey” (terminating NULL not included) with the binary EK + * public key", but since arbitrary binary is not necessarily valid UTF-8... + * and since NULs embedded in UTF-8 might be OK in some contexts but really + * isn't in C (and Heimdal's ASN.1 compiler does not allow NULs in the + * middle of strings)... That just cannot be correct. Since elsewhere the TCG + * specs use the hex encoding of the SHA-256 digest of the DER encoding of + * public keys, that's what we should support in Heimdal, and maybe send in a + * comment. + * + * Also, even where one should use hex encoding of the SHA-256 digest of the + * DER encoding of public keys, how should the public keys be represented? + * Presumably as SPKIs, with all the required parameters and no more. + */ + +/** + * Add a Subject Alternative Name of PermanentIdentifier type to a to-be-signed + * certificate object. The permanent identifier form for TPM endorsement key + * certificates is the hex encoding of the SHA-256 digest of the DER encoding + * of the certificate. The permanent identifier form for TPM endorsement keys + * are of the form "EkPubkey", where the form of is + * not well specified at this point. It is the caller's responsibility to + * format the identifierValue. + * + * @param context A hx509 context. + * @param tbs object to be signed. + * @param str permanent identifier name in the form "[]:[]". + * @param assigner The OID of an assigner. + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_ca + */ + +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_ca_tbs_add_san_permanentIdentifier_string(hx509_context context, + hx509_ca_tbs tbs, + const char *str) +{ + const heim_oid *found = NULL; + heim_oid oid; + const char *oidstr, *id; + char *freeme, *p; + int ret; + + if ((freeme = strdup(str)) == NULL) + return hx509_enomem(context); + + oidstr = freeme; + p = strchr(freeme, ':'); + if (!p) { + hx509_set_error_string(context, 0, EINVAL, + "Invalid PermanentIdentifier string (should be \"[]:[]\")", + oidstr); + free(freeme); + return EINVAL; + } + if (p) { + *(p++) = '\0'; + id = p; + } + if (oidstr[0] != '\0') { + ret = der_find_heim_oid_by_name(oidstr, &found); + if (ret) { + ret = der_parse_heim_oid(oidstr, " .", &oid); + if (ret == 0) + found = &oid; + } + } + ret = hx509_ca_tbs_add_san_permanentIdentifier(context, tbs, id, found); + if (found == &oid) + der_free_oid(&oid); + free(freeme); + return ret; +} + +/** + * Add a Subject Alternative Name of PermanentIdentifier type to a to-be-signed + * certificate object. The permanent identifier form for TPM endorsement key + * certificates is the hex encoding of the SHA-256 digest of the DER encoding + * of the certificate. The permanent identifier form for TPM endorsement keys + * are of the form "EkPubkey", where the form of is + * not well specified at this point. It is the caller's responsibility to + * format the identifierValue. + * + * @param context A hx509 context. + * @param tbs object to be signed. + * @param identifierValue The permanent identifier name. + * @param assigner The OID of an assigner. + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_ca + */ + +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_ca_tbs_add_san_permanentIdentifier(hx509_context context, + hx509_ca_tbs tbs, + const char *identifierValue, + const heim_oid *assigner) +{ + PermanentIdentifier pi; + heim_utf8_string s = (void *)(uintptr_t)identifierValue; + heim_octet_string os; + size_t size; + int ret; + + pi.identifierValue = &s; + pi.assigner = (heim_oid*)(uintptr_t)assigner; + os.length = 0; + os.data = NULL; + + ASN1_MALLOC_ENCODE(PermanentIdentifier, os.data, os.length, &pi, &size, + ret); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + return ret; + } + if (size != os.length) + _hx509_abort("internal ASN.1 encoder error"); + + ret = hx509_ca_tbs_add_san_otherName(context, tbs, + &asn1_oid_id_on_permanentIdentifier, + &os); + free(os.data); + return ret; +} + +/** + * Add a Subject Alternative Name of HardwareModuleName type to a to-be-signed + * certificate object. + * + * @param context A hx509 context. + * @param tbs object to be signed. + * @param str a string of the form ":". + * @param hwserial The serial number. + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_ca + */ + +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_ca_tbs_add_san_hardwareModuleName_string(hx509_context context, + hx509_ca_tbs tbs, + const char *str) +{ + const heim_oid *found = NULL; + heim_oid oid; + const char *oidstr, *sno; + char *freeme, *p; + int ret; + + if ((freeme = strdup(str)) == NULL) + return hx509_enomem(context); + + oidstr = freeme; + p = strchr(freeme, ':'); + if (!p) { + hx509_set_error_string(context, 0, EINVAL, + "Invalid HardwareModuleName string (should be \":\")", + oidstr); + free(freeme); + return EINVAL; + } + if (p) { + *(p++) = '\0'; + sno = p; + } + if (oidstr[0] == '\0') { + found = &asn1_oid_tcg_tpm20; + } else { + ret = der_find_heim_oid_by_name(oidstr, &found); + if (ret) { + ret = der_parse_heim_oid(oidstr, " .", &oid); + if (ret == 0) + found = &oid; + } + } + if (!found) { + hx509_set_error_string(context, 0, EINVAL, + "Could not resolve or parse OID \"%s\"", + oidstr); + free(freeme); + return EINVAL; + } + ret = hx509_ca_tbs_add_san_hardwareModuleName(context, tbs, found, sno); + if (found == &oid) + der_free_oid(&oid); + free(freeme); + return ret; +} + +/** + * Add a Subject Alternative Name of HardwareModuleName type to a to-be-signed + * certificate object. + * + * @param context A hx509 context. + * @param tbs object to be signed. + * @param hwtype The hardwar module type (e.g., `&asn1_oid_tcg_tpm20'). + * @param hwserial The serial number. + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_ca + */ + +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_ca_tbs_add_san_hardwareModuleName(hx509_context context, + hx509_ca_tbs tbs, + const heim_oid *hwtype, + const char *hwserial) +{ + HardwareModuleName hm; + heim_octet_string os; + size_t size; + int ret; + + hm.hwType = *hwtype; + hm.hwSerialNum.data = (void *)(uintptr_t)hwserial; + hm.hwSerialNum.length = strlen(hwserial); + os.length = 0; + os.data = NULL; + + ASN1_MALLOC_ENCODE(HardwareModuleName, os.data, os.length, &hm, &size, + ret); + if (ret) { + hx509_set_error_string(context, 0, ret, "Out of memory"); + return ret; + } + if (size != os.length) + _hx509_abort("internal ASN.1 encoder error"); + + ret = hx509_ca_tbs_add_san_otherName(context, tbs, + &asn1_oid_id_on_hardwareModuleName, + &os); + free(os.data); + return ret; +} + /** * Add a Subject Alternative Name of the given type to the * to-be-signed certificate object. diff --git a/lib/hx509/hx509.h b/lib/hx509/hx509.h index 778a02ba4..325182a2d 100644 --- a/lib/hx509/hx509.h +++ b/lib/hx509/hx509.h @@ -37,6 +37,8 @@ #define HEIMDAL_HX509_H 1 #include +#include +#include #include #include #include @@ -82,6 +84,9 @@ typedef enum { HX509_SAN_TYPE_XMPP = 32, HX509_SAN_TYPE_PKINIT = 33, HX509_SAN_TYPE_MS_UPN = 34, + HX509_SAN_TYPE_DNSSRV = 35, /* SRVName [RFC4985] */ + HX509_SAN_TYPE_PERMANENT_ID = 36, /* PermanentIdentifier [RFC4043] */ + HX509_SAN_TYPE_HW_MODULE = 37, /* HardwareModuleName [RFC4108] */ } hx509_san_type; enum { diff --git a/lib/hx509/hx_locl.h b/lib/hx509/hx_locl.h index 5d5c3bf3d..b8848919d 100644 --- a/lib/hx509/hx_locl.h +++ b/lib/hx509/hx_locl.h @@ -59,6 +59,8 @@ #include #include +#include +#include #include #include #include @@ -67,6 +69,7 @@ #include #include #include +#include #include diff --git a/lib/hx509/hxtool-commands.in b/lib/hx509/hxtool-commands.in index 9ea633dc8..a6f750395 100644 --- a/lib/hx509/hxtool-commands.in +++ b/lib/hx509/hxtool-commands.in @@ -741,6 +741,11 @@ command = { type = "strings" help = "DNS names this certificate is allowed to serve" } + option = { + long = "dnssrv" + type = "strings" + help = "DNS SRV names this certificate is allowed to serve" + } option = { long = "email" type = "strings" @@ -761,6 +766,16 @@ command = { type = "string" help = "XMPP jabber id (for SAN)" } + option = { + long = "permanent-id" + type = "string" + help = "PermanentIdentifier ([oid]:[serial])" + } + option = { + long = "hardware-module-name" + type = "string" + help = "HardwareModuleName (oid:serial)" + } option = { long = "policy" type = "strings" diff --git a/lib/hx509/hxtool.c b/lib/hx509/hxtool.c index 9e6ed8466..3c24c445a 100644 --- a/lib/hx509/hxtool.c +++ b/lib/hx509/hxtool.c @@ -1844,6 +1844,14 @@ eval_types(hx509_context contextp, hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_hostname"); } + for (i = 0; i < opt->dnssrv_strings.num_strings; i++) { + const char *dnssrv = opt->dnssrv_strings.strings[i]; + + ret = hx509_ca_tbs_add_san_dnssrv(contextp, tbs, dnssrv); + if (ret) + hx509_err(contextp, 1, ret, "hx509_ca_tbs_add_san_dnssrv"); + } + for (i = 0; i < opt->email_strings.num_strings; i++) { const char *email = opt->email_strings.strings[i]; @@ -2115,6 +2123,20 @@ hxtool_ca(struct certificate_sign_options *opt, int argc, char **argv) eval_types(context, tbs, opt); + if (opt->permanent_id_string) { + ret = hx509_ca_tbs_add_san_permanentIdentifier_string(context, tbs, + opt->permanent_id_string); + if (ret) + hx509_err(context, 1, ret, "hx509_ca_tbs_add_san_permanentIdentifier"); + } + + if (opt->hardware_module_name_string) { + ret = hx509_ca_tbs_add_san_hardwareModuleName_string(context, tbs, + opt->hardware_module_name_string); + if (ret) + hx509_err(context, 1, ret, "hx509_ca_tbs_add_san_hardwareModuleName_string"); + } + for (i = 0; ret == 0 && i < opt->policy_strings.num_strings; i++) { char *oidstr, *uri, *dt; diff --git a/lib/hx509/libhx509-exports.def b/lib/hx509/libhx509-exports.def index 56eaccc48..725adf95c 100644 --- a/lib/hx509/libhx509-exports.def +++ b/lib/hx509/libhx509-exports.def @@ -23,6 +23,7 @@ EXPORTS _hx509_private_key_ref hx509_request_add_GeneralName hx509_request_add_dns_name + hx509_request_add_dns_srv hx509_request_add_eku hx509_request_add_email hx509_request_add_ms_upn_name @@ -68,10 +69,15 @@ EXPORTS hx509_ca_tbs_add_pol hx509_ca_tbs_add_pol_mapping hx509_ca_tbs_add_san + hx509_ca_tbs_add_san_dnssrv + hx509_ca_tbs_add_san_hardwareModuleName + hx509_ca_tbs_add_san_hardwareModuleName_string hx509_ca_tbs_add_san_hostname hx509_ca_tbs_add_san_jid hx509_ca_tbs_add_san_ms_upn hx509_ca_tbs_add_san_otherName + hx509_ca_tbs_add_san_permanentIdentifier + hx509_ca_tbs_add_san_permanentIdentifier_string hx509_ca_tbs_add_san_pkinit hx509_ca_tbs_add_san_rfc822name hx509_ca_tbs_free diff --git a/lib/hx509/name.c b/lib/hx509/name.c index ec7737693..855d7bdae 100644 --- a/lib/hx509/name.c +++ b/lib/hx509/name.c @@ -85,7 +85,12 @@ static const struct { { "STREET", &asn1_oid_id_at_streetAddress, 0, 0 }, /* ENOTSUP */ { "UID", &asn1_oid_id_Userid, 0, ub_numeric_user_id_length }, { "emailAddress", &asn1_oid_id_pkcs9_emailAddress, 0, ub_emailaddress_length }, - { "serialNumber", &asn1_oid_id_at_serialNumber, 0, ub_serial_number } + /* This is for DevID certificates and maybe others */ + { "serialNumber", &asn1_oid_id_at_serialNumber, 0, ub_serial_number }, + /* These are for TPM 2.0 Endorsement Key Certificates (EKCerts) */ + { "TPMManufacturer", &asn1_oid_tcg_at_tpmManufacturer, 0, ub_emailaddress_length }, + { "TPMModel", &asn1_oid_tcg_at_tpmModel, 0, ub_emailaddress_length }, + { "TPMVersion", &asn1_oid_tcg_at_tpmVersion, 0, ub_emailaddress_length }, }; static char * @@ -1004,6 +1009,73 @@ hx509_name_is_null_p(const hx509_name name) name->der_name.u.rdnSequence.len == 0; } +int +_hx509_unparse_PermanentIdentifier(hx509_context context, + struct rk_strpool **strpool, + heim_any *value) +{ + PermanentIdentifier pi; + size_t len; + const char *pid = ""; + char *s = NULL; + int ret; + + ret = decode_PermanentIdentifier(value->data, value->length, &pi, &len); + if (ret == 0 && pi.assigner && + der_print_heim_oid(pi.assigner, '.', &s) != 0) + ret = hx509_enomem(context); + if (pi.identifierValue && *pi.identifierValue) + pid = *pi.identifierValue; + if (ret == 0 && + (*strpool = rk_strpoolprintf(*strpool, "%s:%s", s ? s : "", pid)) == NULL) + ret = hx509_enomem(context); + free_PermanentIdentifier(&pi); + free(s); + if (ret) { + rk_strpoolfree(*strpool); + *strpool = rk_strpoolprintf(NULL, + "data, value->length, &hm, &len); + if (ret == 0 && hm.hwSerialNum.length > 256) + hm.hwSerialNum.length = 256; + if (ret == 0) + ret = der_print_heim_oid(&hm.hwType, '.', &s); + if (ret == 0) { + *strpool = rk_strpoolprintf(*strpool, "%s:%.*s%s", s, + (int)hm.hwSerialNum.length, + (char *)hm.hwSerialNum.data, + value->length == len ? "" : ", "); + if (*strpool == NULL) + ret = hx509_enomem(context); + } + free_HardwareModuleName(&hm); + free(s); + if (ret) { + rk_strpoolfree(*strpool); + *strpool = rk_strpoolprintf(NULL, + "san, &name); } +/** + * Add a dnsSRV (_service.hostname) subject alternative name to a CSR. + * + * @param context An hx509 context. + * @param req The hx509_request object. + * @param dnssrv The DNS SRV name. + * + * @return An hx509 error code, see hx509_get_error_string(). + * + * @ingroup hx509_request + */ +HX509_LIB_FUNCTION int HX509_LIB_CALL +hx509_request_add_dns_srv(hx509_context context, + hx509_request req, + const char *dnssrv) +{ + GeneralName gn; + SRVName n; + size_t size; + int ret; + + memset(&n, 0, sizeof(n)); + memset(&gn, 0, sizeof(gn)); + gn.element = choice_GeneralName_otherName; + gn.u.otherName.type_id.length = 0; + gn.u.otherName.type_id.components = 0; + gn.u.otherName.value.data = NULL; + gn.u.otherName.value.length = 0; + n.length = strlen(dnssrv); + n.data = (void *)(uintptr_t)dnssrv; + ASN1_MALLOC_ENCODE(SRVName, + gn.u.otherName.value.data, + gn.u.otherName.value.length, &n, &size, ret); + if (ret == 0) + ret = der_copy_oid(&asn1_oid_id_pkix_on_dnsSRV, &gn.u.otherName.type_id); + if (ret == 0) + ret = add_GeneralNames(&req->san, &gn); + free_GeneralName(&gn); + return ret; +} + /** * Add an rfc822Name (e-mail address) subject alternative name to a CSR. * @@ -1196,9 +1237,12 @@ san_map_type(GeneralName *san) const heim_oid *oid; hx509_san_type type; } map[] = { + { &asn1_oid_id_pkix_on_dnsSRV, HX509_SAN_TYPE_DNSSRV }, { &asn1_oid_id_pkinit_san, HX509_SAN_TYPE_PKINIT }, { &asn1_oid_id_pkix_on_xmppAddr, HX509_SAN_TYPE_XMPP }, - { &asn1_oid_id_pkinit_ms_san, HX509_SAN_TYPE_MS_UPN } + { &asn1_oid_id_pkinit_ms_san, HX509_SAN_TYPE_MS_UPN }, + { &asn1_oid_id_on_permanentIdentifier, HX509_SAN_TYPE_PERMANENT_ID }, + { &asn1_oid_id_on_hardwareModuleName, HX509_SAN_TYPE_HW_MODULE }, }; size_t i; @@ -1248,6 +1292,71 @@ hx509_request_get_san(hx509_request req, *out = strndup(san->u.dNSName.data, san->u.dNSName.length); break; + case HX509_SAN_TYPE_DNSSRV: { + SRVName name; + size_t size; + int ret; + + ret = decode_SRVName(san->u.otherName.value.data, + san->u.otherName.value.length, &name, &size); + if (ret) + return ret; + *out = strndup(name.data, name.length); + break; + } + case HX509_SAN_TYPE_PERMANENT_ID: { + PermanentIdentifier pi; + size_t size; + char *s = NULL; + int ret; + + ret = decode_PermanentIdentifier(san->u.otherName.value.data, + san->u.otherName.value.length, + &pi, &size); + if (ret == 0 && pi.assigner) { + ret = der_print_heim_oid(pi.assigner, '.', &s); + if (ret == 0 && + (pool = rk_strpoolprintf(NULL, "%s", s)) == NULL) + ret = ENOMEM; + } else if (ret == 0) { + pool = rk_strpoolprintf(NULL, "-"); + } + if (ret == 0 && + (pool = rk_strpoolprintf(pool, "%s%s", + *pi.identifierValue ? " " : "", + *pi.identifierValue ? *pi.identifierValue : "")) == NULL) + ret = ENOMEM; + if (ret == 0 && (*out = rk_strpoolcollect(pool)) == NULL) + ret = ENOMEM; + free_PermanentIdentifier(&pi); + free(s); + return ret; + } + case HX509_SAN_TYPE_HW_MODULE: { + HardwareModuleName hn; + size_t size; + char *s = NULL; + int ret; + + ret = decode_HardwareModuleName(san->u.otherName.value.data, + san->u.otherName.value.length, + &hn, &size); + if (ret == 0 && hn.hwSerialNum.length > 256) + hn.hwSerialNum.length = 256; + if (ret == 0) + ret = der_print_heim_oid(&hn.hwType, '.', &s); + if (ret == 0) + pool = rk_strpoolprintf(NULL, "%s", s); + if (ret == 0 && pool) + pool = rk_strpoolprintf(pool, " %.*s", + (int)hn.hwSerialNum.length, + (char *)hn.hwSerialNum.data); + if (ret == 0 && + (pool == NULL || (*out = rk_strpoolcollect(pool)) == NULL)) + ret = ENOMEM; + free_HardwareModuleName(&hn); + return ret; + } case HX509_SAN_TYPE_DN: { Name name; diff --git a/lib/hx509/test_ca.in b/lib/hx509/test_ca.in index 0264116bb..cf739a1f9 100644 --- a/lib/hx509/test_ca.in +++ b/lib/hx509/test_ca.in @@ -89,6 +89,8 @@ ${hxtool} verify \ crl:FILE:crl.crl \ anchor:FILE:$srcdir/data/ca.crt > /dev/null && exit 1 +# XXX Check that the certs issued below have the requested content + echo "issue crl (with cert)" ${hxtool} crl-sign \ --crl-file=crl.crl \ @@ -108,7 +110,14 @@ ${hxtool} issue-certificate \ --subject="cn=foo" \ --lifetime="10years 1 month" \ --req="PKCS10:pkcs10-request.der" \ + --permanent-id=1.2.3.4.5.6.6:SomeVendor:A0B1C2D3 \ + --hardware-module-name=tcg-tpm20:SomeVendor:Z0Y1X2W3 \ + --policy="1.2.3.4.5.6:data:foo this is a warning" \ + --policy="id-x509-ce-certificatePolicies-anyPolicy" \ + --policy-mapping="1.2.3.4.5.6:1.2.3.4.5.6" \ + --policy-mapping="1.2.3.4.5.6:1.2.3.4.5.7" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue certificate (with https ekus)" ${hxtool} issue-certificate \ @@ -118,6 +127,7 @@ ${hxtool} issue-certificate \ --type="https-client" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue certificate (pkinit KDC)" ${hxtool} issue-certificate \ @@ -127,6 +137,7 @@ ${hxtool} issue-certificate \ --pk-init-principal="krbtgt/TEST.H5L.SE@TEST.H5L.SE" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue certificate (pkinit client)" ${hxtool} issue-certificate \ @@ -136,6 +147,7 @@ ${hxtool} issue-certificate \ --pk-init-principal="lha@TEST.H5L.SE" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue certificate (hostnames)" ${hxtool} issue-certificate \ @@ -146,6 +158,7 @@ ${hxtool} issue-certificate \ --hostname="ftp.test.h5l.se" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "verify certificate hostname (ok)" ${hxtool} verify --missing-revoke \ @@ -172,6 +185,7 @@ ${hxtool} issue-certificate \ --type="https-server" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "verify certificate hostname (ok)" ${hxtool} verify --missing-revoke \ @@ -193,6 +207,7 @@ ${hxtool} issue-certificate \ --email="test@test.h5l.se" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue certificate (email, null subject DN)" ${hxtool} issue-certificate \ @@ -201,6 +216,7 @@ ${hxtool} issue-certificate \ --email="lha@test.h5l.se" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-null.pem" || exit 1 +${hxtool} print --content FILE:cert-null.pem || exit 1 echo "issue certificate (jabber)" ${hxtool} issue-certificate \ @@ -209,6 +225,7 @@ ${hxtool} issue-certificate \ --jid="lha@test.h5l.se" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue self-signed cert" ${hxtool} issue-certificate \ @@ -216,6 +233,7 @@ ${hxtool} issue-certificate \ --ca-private-key=FILE:$srcdir/data/key.der \ --subject="cn=test" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue ca cert" ${hxtool} issue-certificate \ @@ -224,6 +242,7 @@ ${hxtool} issue-certificate \ --subject="cn=ca-cert" \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-ca.der" || exit 1 +${hxtool} print --content FILE:cert-ca.der || exit 1 echo "issue self-signed ca cert" ${hxtool} issue-certificate \ @@ -232,6 +251,7 @@ ${hxtool} issue-certificate \ --ca-private-key=FILE:$srcdir/data/key.der \ --subject="cn=ca-root" \ --certificate="FILE:cert-ca.der" || exit 1 +${hxtool} print --content FILE:cert-ca.der || exit 1 echo "issue proxy certificate" ${hxtool} issue-certificate \ @@ -239,6 +259,7 @@ ${hxtool} issue-certificate \ --issue-proxy \ --req="PKCS10:pkcs10-request.der" \ --certificate="FILE:cert-proxy.der" || exit 1 +${hxtool} print --content FILE:cert-proxy.der || exit 1 echo "verify proxy cert" ${hxtool} verify --missing-revoke \ @@ -256,6 +277,7 @@ ${hxtool} issue-certificate \ --path-length=-1 \ --subject="cn=ca2-cert" \ --certificate="FILE:cert-ca.pem" || exit 1 +${hxtool} print --content FILE:cert-ca.pem || exit 1 echo "issue sub-ca cert (generate rsa key)" ${hxtool} issue-certificate \ @@ -265,6 +287,7 @@ ${hxtool} issue-certificate \ --generate-key=rsa \ --subject="cn=sub-ca2-cert" \ --certificate="FILE:cert-sub-ca.pem" || exit 1 +${hxtool} print --content FILE:cert-sub-ca.pem || exit 1 echo "issue ee cert (generate rsa key)" ${hxtool} issue-certificate \ @@ -272,6 +295,7 @@ ${hxtool} issue-certificate \ --generate-key=rsa \ --subject="cn=cert-ee2" \ --certificate="FILE:cert-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-ee.pem || exit 1 echo "issue sub-ca ee cert (generate rsa key)" ${hxtool} issue-certificate \ @@ -279,6 +303,7 @@ ${hxtool} issue-certificate \ --generate-key=rsa \ --subject="cn=cert-sub-ee2" \ --certificate="FILE:cert-sub-ee.pem" || exit 1 +${hxtool} print --content FILE:cert-sub-ee.pem || exit 1 echo "verify certificate (ee)" ${hxtool} verify --missing-revoke \ @@ -313,6 +338,7 @@ ${hxtool} issue-certificate \ --ca-private-key=FILE:cert-ca.pem \ --subject="cn=ca2-cert" \ --certificate="FILE:cert-ca.pem" || exit 1 +${hxtool} print --content FILE:cert-ca.pem || exit 1 echo "verify certificate generated by previous ca" ${hxtool} verify --missing-revoke \ @@ -329,6 +355,7 @@ ${hxtool} issue-certificate \ --path-length=-1 \ --ca-private-key=FILE:cert-ca.pem \ --certificate="FILE:cert-ca.pem" || exit 1 +${hxtool} print --content FILE:cert-ca.pem || exit 1 echo "verify certificate generated by previous ca" ${hxtool} verify --missing-revoke \ @@ -343,6 +370,7 @@ ${hxtool} issue-certificate \ --template-certificate="FILE:cert-sub-ca.pem" \ --template-fields="serialNumber,notBefore,subject,SPKI" \ --certificate="FILE:cert-sub-ca2.pem" || exit 1 +${hxtool} print --content FILE:cert-sub-ca2.pem || exit 1 echo "verify certificate (sub-ee) with extended chain" ${hxtool} verify --missing-revoke \ diff --git a/lib/hx509/version-script.map b/lib/hx509/version-script.map index 5b8903b39..0cb2be8cd 100644 --- a/lib/hx509/version-script.map +++ b/lib/hx509/version-script.map @@ -27,6 +27,7 @@ HEIMDAL_X509_1.2 { _hx509_private_key_ref; hx509_request_add_GeneralName; hx509_request_add_dns_name; + hx509_request_add_dns_srv; hx509_request_add_eku; hx509_request_add_email; hx509_request_add_ms_upn_name; @@ -52,10 +53,15 @@ HEIMDAL_X509_1.2 { hx509_ca_tbs_add_pol; hx509_ca_tbs_add_pol_mapping; hx509_ca_tbs_add_san; + hx509_ca_tbs_add_san_dnssrv; + hx509_ca_tbs_add_san_hardwareModuleName; + hx509_ca_tbs_add_san_hardwareModuleName_string; hx509_ca_tbs_add_san_hostname; hx509_ca_tbs_add_san_jid; hx509_ca_tbs_add_san_ms_upn; hx509_ca_tbs_add_san_otherName; + hx509_ca_tbs_add_san_permanentIdentifier; + hx509_ca_tbs_add_san_permanentIdentifier_string; hx509_ca_tbs_add_san_pkinit; hx509_ca_tbs_add_san_rfc822name; hx509_ca_tbs_free;