hx509: Add Heimdal cert ext for ticket max_life
This adds support for using a Heimdal-specific PKIX extension to derive a maximum Kerberos ticket lifetime from a client's PKINIT certificate: - a `--pkinit-max-life` to the `hxtool ca` command - `hx509_ca_tbs_set_pkinit_max_life()` - `hx509_cert_get_pkinit_max_life()` - `HX509_CA_TEMPLATE_PKINIT_MAX_LIFE` There are two extensions. One is an EKU, which if present means that the maximum ticket lifetime should be derived from the notAfter minus notBefore. The other is a certificate extension whose value is a maximum ticket lifetime in seconds. The latter is preferred.
This commit is contained in:
@@ -1633,6 +1633,63 @@ hx509_cert_get_notAfter(hx509_cert p)
|
||||
return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notAfter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a maximum Kerberos credential lifetime from a Heimdal certificate
|
||||
* extension.
|
||||
*
|
||||
* @param context hx509 context.
|
||||
* @param cert Certificate.
|
||||
* @param bound If larger than zero, return no more than this.
|
||||
*
|
||||
* @return maximum ticket lifetime.
|
||||
*/
|
||||
HX509_LIB_FUNCTION time_t HX509_LIB_CALL
|
||||
hx509_cert_get_pkinit_max_life(hx509_context context,
|
||||
hx509_cert cert,
|
||||
time_t bound)
|
||||
{
|
||||
HeimPkinitPrincMaxLifeSecs r = 0;
|
||||
size_t sz, i;
|
||||
time_t b, e;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < cert->data->tbsCertificate.extensions->len; i++) {
|
||||
Extension *ext = &cert->data->tbsCertificate.extensions->val[i];
|
||||
|
||||
if (ext->_ioschoice_extnValue.element !=
|
||||
choice_Extension_iosnumunknown &&
|
||||
ext->_ioschoice_extnValue.element !=
|
||||
choice_Extension_iosnum_id_heim_ce_pkinit_princ_max_life)
|
||||
continue;
|
||||
if (ext->_ioschoice_extnValue.element == choice_Extension_iosnumunknown &&
|
||||
der_heim_oid_cmp(&asn1_oid_id_heim_ce_pkinit_princ_max_life, &ext->extnID))
|
||||
continue;
|
||||
if (ext->_ioschoice_extnValue.u.ext_HeimPkinitPrincMaxLife) {
|
||||
r = *ext->_ioschoice_extnValue.u.ext_HeimPkinitPrincMaxLife;
|
||||
} else {
|
||||
ret = decode_HeimPkinitPrincMaxLifeSecs(ext->extnValue.data,
|
||||
ext->extnValue.length,
|
||||
&r, &sz);
|
||||
/* No need to free_HeimPkinitPrincMaxLifeSecs(); it's an int */
|
||||
if (ret || r < 1)
|
||||
return 0;
|
||||
}
|
||||
if (bound > 0 && r > bound)
|
||||
return bound;
|
||||
return r;
|
||||
}
|
||||
if (hx509_cert_check_eku(context, cert,
|
||||
&asn1_oid_id_heim_eku_pkinit_certlife_is_max_life, 0))
|
||||
return 0;
|
||||
b = hx509_cert_get_notBefore(cert);
|
||||
e = hx509_cert_get_notAfter(cert);
|
||||
if (e > b)
|
||||
r = e - b;
|
||||
if (bound > 0 && r > bound)
|
||||
return bound;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SubjectPublicKeyInfo structure from the hx509 certificate.
|
||||
*
|
||||
|
Reference in New Issue
Block a user