authentication indicators and S4U2Self

Alexander Bokovoy abokovoy at redhat.com
Wed May 6 14:20:19 EDT 2020


Hi,

Together with Isaac we were looking into cross-realm S4U2Self
implementation in FreeIPA and I noticed that MIT Kerberos does not allow
to issue S4U2Self service ticket to a service protected with
an authentication indicator. The corresponding check in
process_tgs_req() does not retrieve authentication indicators from the
ticket if s4u_x509_user is set:

https://github.com/krb5/krb5/blob/master/src/kdc/do_tgs_req.c#L395-L410

     /* Extract auth indicators from the subject ticket, except for S4U2Self
      * requests (where the client didn't authenticate). */
     if (s4u_x509_user == NULL) {
         errcode = get_auth_indicators(kdc_context, subject_tkt, local_tgt,
                                       &local_tgt_key, &auth_indicators);
         if (errcode) {
             status = "GET_AUTH_INDICATORS";
             goto cleanup;
         }
     }

     errcode = check_indicators(kdc_context, server, auth_indicators);
     if (errcode) {
         status = "HIGHER_AUTHENTICATION_REQUIRED";
         goto cleanup;
     }

This means it is not possible to implement a protocol transition by a
service that otherwise has an authentication indicator assigned. 

This is how it looks for FreeIPA 4.8.6 in Fedora 32:

1. Create a service and fetch keytab for it

[root at client ~]# kinit admin
Password for admin at IPA.TEST:
[root at client ~]# ipa service-add protected/`hostname`
--------------------------------------------------
Added service "protected/client.ipa.test at IPA.TEST"
--------------------------------------------------
   Principal name: protected/client.ipa.test at IPA.TEST
   Principal alias: protected/client.ipa.test at IPA.TEST
   Managed by: client.ipa.test
[root at client ~]# ipa-getkeytab -p protected/`hostname` -k protected.keytab
Keytab successfully retrieved and stored in: protected.keytab

2. kinit as the service using the keytab:

[root at client ~]# kinit -kt ./protected.keytab protected/`hostname`
[root at client ~]# klist
Ticket cache: KCM:0:89242
Default principal: protected/client.ipa.test at IPA.TEST

Valid starting     Expires            Service principal
05/06/20 17:46:01  05/07/20 17:46:01  krbtgt/IPA.TEST at IPA.TEST

3. Perform S4U2Self request:

[root at client ~]# kvno -U admin protected/`hostname`
protected/client.ipa.test at IPA.TEST: kvno = 1
[root at client ~]# kdestroy -A

4. Now associate authentication indicator with the service, requiring
that whoever talks to it would need to have 'pkinit' indicator in the
ticket:

[root at client ~]# kinit admin
Password for admin at IPA.TEST:
[root at client ~]# ipa service-mod protected/`hostname` --auth-ind=pkinit
-----------------------------------------------------
Modified service "protected/client.ipa.test at IPA.TEST"
-----------------------------------------------------
   Principal name: protected/client.ipa.test at IPA.TEST
   Principal alias: protected/client.ipa.test at IPA.TEST
   Authentication Indicators: pkinit
   Managed by: client.ipa.test
[root at client ~]# kdestroy -A

5. Attempt to perform S4U2Self as the service:

[root at client ~]# kinit -kt ./protected.keytab protected/`hostname`
[root at client ~]# KRB5_TRACE=/dev/stderr kvno -U admin protected/`hostname`
[36135] 1588787255.699025: Getting credentials admin at IPA.TEST -> protected/client.ipa.test at IPA.TEST using ccache KCM:0
[36135] 1588787255.699026: Retrieving admin at IPA.TEST -> protected/client.ipa.test at IPA.TEST from KCM:0 with result: -1765328243/Matching credential not found
[36135] 1588787255.699027: Getting initial credentials for admin at IPA.TEST
[36135] 1588787255.699029: Sending unauthenticated request
[36135] 1588787255.699030: Sending request (169 bytes) to IPA.TEST
[36135] 1588787255.699031: Initiating TCP connection to stream 10.0.106.145:88
[36135] 1588787255.699032: Sending TCP request to stream 10.0.106.145:88
[36135] 1588787255.699033: Received answer (493 bytes) from stream 10.0.106.145:88
[36135] 1588787255.699034: Terminating TCP connection to stream 10.0.106.145:88
[36135] 1588787255.699035: Response was from master KDC
[36135] 1588787255.699036: Received error from KDC: -1765328359/Additional pre-authentication required
[36135] 1588787255.699037: Identified realm of client principal as IPA.TEST
[36135] 1588787255.699038: Getting credentials admin at IPA.TEST -> protected/client.ipa.test at IPA.TEST using ccache KCM:0
[36135] 1588787255.699039: Retrieving admin at IPA.TEST -> protected/client.ipa.test at IPA.TEST from KCM:0 with result: -1765328243/Matching credential not found
[36135] 1588787255.699040: Getting credentials protected/client.ipa.test at IPA.TEST -> krbtgt/IPA.TEST at IPA.TEST using ccache KCM:0
[36135] 1588787255.699041: Retrieving protected/client.ipa.test at IPA.TEST -> krbtgt/IPA.TEST at IPA.TEST from KCM:0 with result: 0/Success
[36135] 1588787255.699042: Get cred via TGT krbtgt/IPA.TEST at IPA.TEST after requesting protected/client.ipa.test at IPA.TEST (canonicalize on)
[36135] 1588787255.699043: Generated subkey for TGS request: aes256-cts/2286
[36135] 1588787255.699044: etypes requested in TGS request: aes256-cts, aes256-sha2, camellia256-cts, aes128-cts, aes128-sha2, camellia128-cts
[36135] 1588787255.699046: Encoding request body and padata into FAST request
[36135] 1588787255.699047: Sending request (1443 bytes) to IPA.TEST
[36135] 1588787255.699048: Initiating TCP connection to stream 10.0.106.145:88
[36135] 1588787255.699049: Sending TCP request to stream 10.0.106.145:88
[36135] 1588787255.699050: Received answer (493 bytes) from stream 10.0.106.145:88
[36135] 1588787255.699051: Terminating TCP connection to stream 10.0.106.145:88
[36135] 1588787255.699052: Response was from master KDC
[36135] 1588787255.699053: Decoding FAST response
[36135] 1588787255.699054: Decoding FAST response
[36135] 1588787255.699055: Got cred; -1765328372/KDC policy rejects request
kvno: KDC policy rejects request while getting credentials for protected/client.ipa.test at IPA.TEST

On the KDC side:

May 06 17:47:47 replica1.ipa.test krb5kdc[29944](info): AS_REQ (6 etypes {aes256-cts-hmac-sha1-96(18), aes256-cts-hmac-sha384-192(20), camellia256-cts-cmac(26), aes128-cts-hmac-sha1-96(17), 
aes128-cts-hmac-sha256-128(19), camellia128-cts-cmac(25)}) 10.0.106.219: NEEDED_PREAUTH: admin at IPA.TEST for krbtgt/IPA.TEST at IPA.TEST, Additional pre-authentication required
May 06 17:47:47 replica1.ipa.test krb5kdc[29944](info): closing down fd 11
May 06 17:47:47 replica1.ipa.test krb5kdc[29944](info): TGS_REQ (6 etypes {aes256-cts-hmac-sha1-96(18), aes256-cts-hmac-sha384-192(20), camellia256-cts-cmac(26), aes128-cts-hmac-sha1-96(17),
  aes128-cts-hmac-sha256-128(19), camellia128-cts-cmac(25)}) 10.0.106.219: HIGHER_AUTHENTICATION_REQUIRED: authtime 1588787254, etypes {rep=UNSUPPORTED:(0)} protected/client.ipa.test at IPA.TEST
  for protected/client.ipa.test at IPA.TEST, Required auth indicators not present in ticket: pkinit
May 06 17:47:47 replica1.ipa.test krb5kdc[29944](info): ... PROTOCOL-TRANSITION s4u-client=<unknown>
May 06 17:47:47 replica1.ipa.test krb5kdc[29944](info): closing down fd 11

This means that if the service is doing protocol transition, it has to
perform authentication indicators checks on its own for all use cases
and not just for a protocol transition.

Perhaps for S4U2Self case a KDC could add an implicit authentication
indicator 'impersonation' to the list of indicators associated with
s4u_x509_user before doing the check? 

Since this would be a regular authentication indicator, setting it in
the service configuration on KDC side then would have allowed
impersonation in S42Self case explicitly by allowing 'impersonation'
indicator:

   ipa service-mod protected/`hostname` --auth-ind={pkinit,impersonation}

E.g. the service is only accessible with pkinit authentication indicator
in possession _or_ via protocol transition.


-- 
/ Alexander Bokovoy
Sr. Principal Software Engineer
Security / Identity Management Engineering
Red Hat Limited, Finland




More information about the krbdev mailing list