Subject: | Regression in rule-based matching of PKINIT client certs with UPN SANs |
Standard PKINIT client certificates use Subject Alternative Name
(SAN) values of type id-pkinit-san containing an ASN.1 DER
representation of the principal name and realm. Client certificates
issued for use with Windows KDCs may instead contain SAN values of
type id-ms-san-sc-logon-upn containing a UTF-8 string giving the
UserPrincipalName (UPN) of the client account object.
Ticket 8528 improved matching of UPN SAN certificates against the
client principal. As part of that improvement, UPN SANs values are
correctly parsed as enterprise principal names (one data component
usually containing an "@" character, no realm). Unfortunately this
change breaks matching of UPN SANs against pkinit_cert_match rules.
The matching code concatenates PKINIT SAN and UPN SAN principals
together without remembering which is which, and unparses each
principal normally (yielding a string like "a\@b@DEFAULT.REALM" for
an enterprise principal name) before matching them against the
regular expression in the rule. If the rule is written naturally as
"<SAN>^a@b$", it will not match.
The best fix is to record the original UPN SAN string in the matching
data and match that against the rule regexp. An acceptable fix would
be to unparse UPN SANs with the KRB5_PRINCIPAL_UNPARSE_NO_REALM flag,
which would usually yield the original UPN string.
(SAN) values of type id-pkinit-san containing an ASN.1 DER
representation of the principal name and realm. Client certificates
issued for use with Windows KDCs may instead contain SAN values of
type id-ms-san-sc-logon-upn containing a UTF-8 string giving the
UserPrincipalName (UPN) of the client account object.
Ticket 8528 improved matching of UPN SAN certificates against the
client principal. As part of that improvement, UPN SANs values are
correctly parsed as enterprise principal names (one data component
usually containing an "@" character, no realm). Unfortunately this
change breaks matching of UPN SANs against pkinit_cert_match rules.
The matching code concatenates PKINIT SAN and UPN SAN principals
together without remembering which is which, and unparses each
principal normally (yielding a string like "a\@b@DEFAULT.REALM" for
an enterprise principal name) before matching them against the
regular expression in the rule. If the rule is written naturally as
"<SAN>^a@b$", it will not match.
The best fix is to record the original UPN SAN string in the matching
data and match that against the rule regexp. An acceptable fix would
be to unparse UPN SANs with the KRB5_PRINCIPAL_UNPARSE_NO_REALM flag,
which would usually yield the original UPN string.