[krbdev.mit.edu #8777] S4U2Self with X.509 certificate bugs

Greg Hudson via RT rt-comment at KRBDEV-PROD-APP-1.mit.edu
Mon Jan 28 13:06:27 EST 2019


Microsoft's S4U2Self extension allows a service to obtain a ticket to 
itself from an arbitrary user.  The user can be identified by regular 
krb5 principal, by enterprise principal, or by X.509 certificate.  In 
the latter two cases, AS requests are used to identify the client's 
realm.  After the realm is identified, a TGS-REQ with S4U2Self pa-
data is used to obtain the ticket.  (In the cross-realm case, 
multiple TGS-REQs are required.)

Commit 0e39f8a3ad915eeb0131fb4a87b0fef304101cfd added the client code 
for S4U2Self to the MIT krb5 tree.  It contained support for using an 
X.509 certificate to identify the user, but that functionality was 
not reachable by any public path.  Isaac Boukris has identified and 
corrected the following issues with the client code for using X.509 
certificates:

* During realm identification, the code attempted to present the 
X.509 certificate using an optimistic preauth list and special 
handling in preauth2.c.  Changes to the preauth framework caused this 
attempt to fail (because it did not produce authenticating padata 
from a clpreauth module) and fall back to sending an AS request 
without the cert.

* When performing realm identification with a cert, the existing code 
uses a client principal with NT-ENTERPRISE type and no data 
components.  Windows clients provide a principal of type NT-X500-
PRINCIPAL and the certificate subject as a single data component.  
Doing that would require partially decoding the certificate.  
Experimentally, using a single empty data component actually works 
better with Windows KDCs than including the certificate subject (it 
works with cross-realm), so we should do that instead.

* If an enterprise principal and cert are both presented to the API, 
to be consistent with Windows clients we should do realm 
identification with just the enterprise principal, and then prsent 
the cert in the TGS request.  The current code presents (well, tries 
to present) the certificate during realm identification in this case.

* In krb5_get_self_cred_from_kdc(), if no client principal is 
provided, the code to build s4u_user.user_id.user did not terminate 
the krb5_build_principal_ext() variable argument list and could 
therefore crash.

* In the same function, the PA-FOR_USER padata input is supplied to 
krb5_get_cred_via_tkt_ext() via an in_padata list, while the PA-FOR-
X509-USER padata is constructed via a callback because so that the 
TGS subkey can be used to build it.  When the TGS reply is received, 
krb5int_process_tgs_reply() looks for PA-FOR_USER or PA-FOR-X509-USER 
padata in the in_padata list to decide whether to use S4U2Self logic 
to validate the client.  Because the PA-FOR-X509-USER padata is not 
supplied via the in_padata list, the code will never find that type.  
In the usual case, we will find the PA-FOR_USER type and do the right 
thing, but in the cert-only case there is no PA-FOR_USER padata 
value, so the S4U2Self logic is not applied.



More information about the krb5-bugs mailing list