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.
This commit is contained in:
Nicolas Williams
2021-01-15 13:13:55 -06:00
parent dbb0463ca8
commit 37ab2a5308
10 changed files with 594 additions and 9 deletions

View File

@@ -379,6 +379,47 @@ hx509_request_add_dns_name(hx509_context context,
return add_GeneralNames(&req->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;