[3261] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

krb5-libs/1006: ETYPE-INFO handling bug

daemon@ATHENA.MIT.EDU (Nicolas Williams)
Thu Oct 18 15:02:57 2001

Resent-From: gnats@rt-11.mit.edu (GNATS Management)
Resent-To: krb5-unassigned@rt-11.mit.edu
Resent-Reply-To: krb5-bugs@MIT.EDU, Nicolas.Williams@ubsw.com
Message-Id: <200110181855.OAA20160@sm0d1989cmp.stm.swissbank.com>
Date: Thu, 18 Oct 2001 14:55:24 -0400 (EDT)
From: Nicolas Williams <Nicolas.Williams@ubsw.com>
Reply-To: Nicolas.Williams@ubsw.com
To: krb5-bugs@mit.edu


>Number:         1006
>Category:       krb5-libs
>Synopsis:       MIT krb5 clients (all versions) don't check ALL ETYPE-INFO entries, only the first one
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    krb5-unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Thu Oct 18 14:57:00 EDT 2001
>Last-Modified:
>Originator:     Nicolas Williams
>Organization:
UBS Warburg / Perot Systems Corp.
--
>Release:        krb5-1.2.2
>Environment:
Solaris 2.6 and 8, MIT krb5 v1.2.2 KDCs
>Description:

Older releases of MIT krb5 don't cope well with newer KDCs that support
new enctypes, even when the principals involved have keys in the       
enctypes supported by the older clients.                               

Here's what I've found:

 - decode_krb5_etype_info() produces an array of krb5_etype_info_entry
   (this is good)                                                     
   
 - krb5_do_preauth() [v1.1.x, v1.2.x] does not try (*pa_types[j].fct)()
   for each krb5_etype_info_entry, only the first one -- if            
   (*pa_types[j].fct)() returns KRB5_PROG_ETYPE_NOSUPP then            
   krb5_do_preauth() should try the next krb5_etype_info_entry         
   
 - krb5_obtain_padata() [pre-v1.1.x] does not try (*key_proc)() each
   krb5_etype_info_entry, only the first one -- if (*key_proc)() returns
   KRB5_PROG_ETYPE_NOSUPP then krb5_obtain_padata() should try the next 
   krb5_etype_info_entry                                                
   
 - the KDC COULD (SHOULD!) sort the ETYPE_INFO sequence such that the
   enctype requested by the client in the KDC REQ is put first in the
   sequence, but doesn't, instead, the ETYPE_INFO sequence is generated
   in the order returned by krb5_dbe_search_enctype(), which is the    
   order in which the keys for the given principal were created by       
   kadmin.                                                             

>How-To-Repeat:

Using a 1.1.x or 1.2.x KDC and a pre-DES3 client:

 - setup a principal with des and des keys
 - set the requires_preauth flag for that principal
 - attempt to kinit with the older client

>Fix:

Here's a patch for the KDC which sorts the ETYPE_INFO sequence as
discussed above. The clients should be patched to fix the problem
in perpetuity.

--- orig/kdc/kdc_preauth.c Wed, 14 Mar 2001 14:20:32 -0500
+++ current/kdc/kdc_preauth.c Thu, 11 Oct 2001 14:17:42 -0400
@@ -501,6 +501,74 @@
     return retval;
 }
 
+static void
+sort_etype_info(context, request, etype_info)
+    krb5_context        context;
+    krb5_kdc_req *      request;
+    krb5_etype_info_entry **etype_info;
+{
+    krb5_etype_info_entry *tmp;
+    int i, j, e;
+    krb5_boolean similar;
+
+    if (etype_info == NULL)
+	return;
+
+    /* First, move up etype_info_entries whose enctype exactly matches a
+     * requested enctype.
+     */
+    e = 0;
+    for ( i = 0 ; i < request->nktypes && etype_info[e] != NULL ; i++ )
+    {
+	if (request->ktype[i] == etype_info[e]->etype)
+	{
+	    e++;
+	    continue;
+	}
+	for ( j = e+1 ; etype_info[j] ; j++ )
+	    if (request->ktype[i] == etype_info[j]->etype)
+		break;
+	if (etype_info[j] == NULL)
+	    continue;
+
+	tmp = etype_info[j];
+	etype_info[j] = etype_info[e];
+	etype_info[e] = tmp;
+	e++;
+    }
+
+    /* Then move up etype_info_entries whose enctype is similar to a
+     * requested enctype.
+     */
+    e=0;
+    for ( i = 0 ; i < request->nktypes && etype_info[e] != NULL ; i++ )
+    {
+	if (krb5_c_enctype_compare(context, request->ktype[i], etype_info[e]->etype, &similar) != 0)
+	    continue;
+
+	if (similar)
+	{
+	    e++;
+	    continue;
+	}
+	for ( j = e+1 ; etype_info[j] ; j++ )
+	{
+	    if (krb5_c_enctype_compare(context, request->ktype[i], etype_info[j]->etype, &similar) != 0)
+		continue;
+
+	    if (similar)
+		break;
+	}
+	if (etype_info[j] == NULL)
+	    continue;
+
+	tmp = etype_info[j];
+	etype_info[j] = etype_info[e];
+	etype_info[e] = tmp;
+	e++;
+    }
+}
+
 /*
  * This function returns the etype information for a particular
  * client, to be passed back in the preauth list in the KRB_ERROR
@@ -571,6 +639,7 @@
 		break;
 	}
     }
+    sort_etype_info(context, request, entry);
     retval = encode_krb5_etype_info((const krb5_etype_info_entry **) entry,
 				    &scratch);
     if (retval)



Visit our website at http://www.ubswarburg.com

This message contains confidential information and is intended only 
for the individual named.  If you are not the named addressee you 
should not disseminate, distribute or copy this e-mail.  Please 
notify the sender immediately by e-mail if you have received this 
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free 
as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete, or contain viruses.  The sender therefore 
does not accept liability for any errors or omissions in the contents 
of this message which arise as a result of e-mail transmission.  If 
verification is required please request a hard-copy version.  This 
message is provided for informational purposes and should not be 
construed as a solicitation or offer to buy or sell any securities or 
related financial instruments.

>Audit-Trail:
>Unformatted:

home help back first fref pref prev next nref lref last post