Projects/GSS-API preauth

From K5Wiki
Jump to: navigation, search
This is an early stage project for MIT Kerberos. It is being fleshed out by its proponents. Feel free to help flesh out the details of this project. After the project is ready, it will be presented for review and approval.


The purpose of this Project is to implement the functionality described in draft-perez-krb-wg-gss-preauth-01, where GSS-API is used to carry out a pre-authentication process between the client and the KDC. That is, this would alow making use of any GSS-API mechanism (with some restrictions) to allow the client to authenticate with the KDC and to obtain a valid TGT.

The main motivation behind this pre-authentication functionality is to allow the use of the GSS-EAP mechanism (draft-ietf-abfab-gss-eap) to allow federated users accessing to resources protected by Kerberos making use of the AAA infrastructure. Nevertheless, this pre-authentication mechanism does not preclude any other GSS-API mechanism to be used, as long as it provides the required security services (see below).


In order to implement the required functionality, the current KDC implementation needs to be modified to support multi-round trip pre-authentication mechanism. This can be easily achieved by just modifying a couple of lines in the base code (version 1.10.2):

File: kdc/kdc_preauth.c
@@ -1019,6 +1019,7 @@
         /* pkinit alg-agility */
+    case KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED: /* Multi-round trip preauthentication */
         (*oldrespond)(oldarg, code);

File: lib/krb5/error_tables/krb5_err.et
@@ -132,7 +132,7 @@
 error_code KRB5PLACEHOLD_88,	"KRB5 error code 88"
 error_code KRB5PLACEHOLD_89,	"KRB5 error code 89"
 error_code KRB5PLACEHOLD_90,	"KRB5 error code 90"
-error_code KRB5PLACEHOLD_91,	"KRB5 error code 91"
+error_code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,	"More preauthentication data required"
 error_code KRB5PLACEHOLD_92,	"KRB5 error code 92"
 error_code KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION, "An unsupported critical FAST option was requested"
 error_code KRB5PLACEHOLD_94,	"KRB5 error code 94"

File: include/k5-int.h
@@ -376,6 +376,9 @@
 #define KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE       86 /* The KDC did not respond
                                                       to the IAKERB proxy */
+#define KDC_ERR_MORE_PREAUTH_DATA_REQUIRED      91 /* More pre-authentication 
+                                                      data is required */ 
  * This structure is returned in the e-data field of the KRB-ERROR
  * message when the error calling for an alternative form of


In order to assure statelessness, and due how MIT Kerberos and MIT GSS-API are designed, the second approach described in draft-perez-krb-wg-gss-preauth-01 should be followed. That is, if the GSS mechanism requires more than one round-trip to be completed, the partially established security context is exported from the GSS-API and included into the pre-authentication element (PA-GSS).

The resulting PA-GSS would be something similar to this (ASN1 provided by Nico):

     sec-ctx-token [0] OCTET STRING,
     state [1] EncryptedData OPTIONAL -- containing PA-GSS-STATE

     timestamp [0] KerberosTime,
     exported-sec-ctx-token [1] OCTET STRING,

state would be absent on first AS_REQ and last AS_REP messages. It would be encrypted with the first krbtgt key, using a key usage in the 512-1023 range.

Reply key generation

Reply key is derived using the gss_pseudo_random call, obtaining enough material to completely replace the previously existing key.

--Aperez 17:19, 9 August 2012 (UTC) gss_get_mic cannot be used for generating keying material. Thanks to Nico Williams for ponting this out.

GSS-API credentials

The cname provided by the client in the kinit call is directly used to acquire the initial GSS credentials. However, some special considerations are required at this point:

  1. Some GSS-API mechanism allow a federated authentication (e.g. GSS-EAP). This means that the cname introduced by the client is not present into the KDC database. In this situations, draft-perez-abfab-eap-gss-preauth-01 defines the use of WELLKNOWN:FEDERATED as the cname value. This way, the KDC knows that the client name will be provided by the GSS-preauth plugin at the end of the authentication. To implement this:
    1. In the KDC side we propose to just insert the principal WELLKNOW:FEDERATED with a random password (as the actual reply key will be derived from the gss_pseudo_random function), in a similar way as done with the WELLKNOWN:ANONYMOUS.
    2. In the client side, a new pre-auth option (e.g. -X gss_federated) is used to indicate that client is in a federated environment, and that the provided cname MUST be replaced with WELLKNOWN:FEDERATED, while the actual cname is still used to acquire the credentials.
  2. If the client wanted to use the default credentials for the GSS mechanism, he could use another pre-auth option (e.g. -X gss_default) to indicated that NULL MUST be used as client name to acquire the initial credentials. Note that in this case, the provided cname will be still being used as the cname in the AS_REQ message.

For instance, to execute a federated GSS-EAP authentication with default credentials (for example, to launch the moonshot's identity selector), both options should be indicated.

If -X gss_federated is not used, the returned textual representation of the GSS name MUST be identical to the cname provided in AS_REQ, excluding the realm part.

Allowed GSS-API mechanisms

Due to the previous restrictions, GSS-preauth can only work with those GSS-mechanism that:

  1. Require only one round-trip to be compled, or support the exporting of partially established security contexts if more than one round-trip are required.
  2. Implement gss_pseudo_random.
  3. Are not able to trigger an additional AS_REQ exchange (as it may lead the pre-authentication process to get into an infinite loop).
  4. Provide the following GSS services (in order to provide a secure authentication):
    4. GSS_C_TRANS_FLAG (only on the KDC)

Ticket timestamps

Default ticket expiration and renewal times are updated if time_rec is not GSS_C_INDEFINITE. In particular

  • enc_tkt_reply->times.endtime = enc_tkt_reply->times.authtime + time_rec
  • enc_tkt_reply->times.renew_till = enc_tkt_reply->times.endtime;