[krbdev.mit.edu #6058] kadm5_setkey_principal does not validate keyblocks.

Roland C. Dowdeswell via RT rt-comment at krbdev.mit.edu
Mon Aug 4 14:22:54 EDT 2008


Looks like kadm5_setkey_principal() and krb5_kt_add_entry() do not
validate the length of the keys that are in the krb5_keyblocks
passed in.

This will allow you to set invalid keys in either the Kerberos DB
or in keytabs.  From a quick code perusal, it seemed that if you
set a key in the DB of aes256-cts but with a key length of 16 then
the KDC will simply use aes128-cts.  This seems a little wrong.

The attached patch defines krb5_c_valid_keyblock() which returns
false if:

	1.  the magic number is incorrect,

	2.  the encryption type can't be found, or

	3.  the key length does not correspond to the encryption
	    type.

This is by no means a complete solution, as in a more perfect world,
one would want to define some extra error codes and return something
a little more precise than a boolean value.

But it does at least prevent programming mistakes from inserting
inappropriate keys into the DB.

It should also be called from a lot more locations rather than just
these two.

Index: lib/crypto/Makefile.in
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/lib/crypto/Makefile.in,v
retrieving revision 1.1.1.2
diff -u -b -U10 -r1.1.1.2 Makefile.in
--- lib/crypto/Makefile.in	26 Sep 2006 20:29:54 -0000	1.1.1.2
+++ lib/crypto/Makefile.in	1 Aug 2008 17:15:53 -0000
@@ -55,20 +55,21 @@
 	nfold.o			\
 	old_api_glue.o		\
 	pbkdf2.o		\
 	prng.o			\
 	state.o \
 	string_to_cksumtype.o	\
 	string_to_enctype.o	\
 	string_to_key.o		\
 	valid_cksumtype.o	\
 	valid_enctype.o		\
+	valid_keyblock.o	\
 	verify_checksum.o
 
 OBJS=\
 	$(OUTPRE)block_size.$(OBJEXT)		\
 	$(OUTPRE)checksum_length.$(OBJEXT)	\
 	$(OUTPRE)cksumtype_to_string.$(OBJEXT)	\
 	$(OUTPRE)cksumtypes.$(OBJEXT)		\
 	$(OUTPRE)coll_proof_cksum.$(OBJEXT)	\
 	$(OUTPRE)combine_keys.$(OBJEXT)	\
 	$(OUTPRE)crypto_libinit.$(OBJEXT)	\
@@ -88,20 +89,21 @@
 	$(OUTPRE)nfold.$(OBJEXT)		\
 	$(OUTPRE)old_api_glue.$(OBJEXT)		\
 	$(OUTPRE)pbkdf2.$(OBJEXT)		\
 	$(OUTPRE)prng.$(OBJEXT)			\
 	$(OUTPRE)state.$(OBJEXT) \
 	$(OUTPRE)string_to_cksumtype.$(OBJEXT)	\
 	$(OUTPRE)string_to_enctype.$(OBJEXT)	\
 	$(OUTPRE)string_to_key.$(OBJEXT)	\
 	$(OUTPRE)valid_cksumtype.$(OBJEXT)	\
 	$(OUTPRE)valid_enctype.$(OBJEXT)	\
+	$(OUTPRE)valid_keyblock.$(OBJEXT)	\
 	$(OUTPRE)verify_checksum.$(OBJEXT)
 
 SRCS=\
 	$(srcdir)/block_size.c		\
 	$(srcdir)/checksum_length.c	\
 	$(srcdir)/cksumtype_to_string.c	\
 	$(srcdir)/cksumtypes.c		\
 	$(srcdir)/coll_proof_cksum.c	\
 	$(srcdir)/combine_keys.c	\
 	$(srcdir)/crypto_libinit.c	\
@@ -120,21 +122,21 @@
 	$(srcdir)/mandatory_sumtype.c	\
 	$(srcdir)/nfold.c		\
 	$(srcdir)/old_api_glue.c	\
 	$(srcdir)/pbkdf2.c	\
 	$(srcdir)/prng.c		\
 	$(srcdir)/state.c \
 	$(srcdir)/string_to_cksumtype.c	\
 	$(srcdir)/string_to_enctype.c	\
 	$(srcdir)/string_to_key.c	\
 	$(srcdir)/valid_cksumtype.c	\
-	$(srcdir)/valid_enctype.c	\
+	$(srcdir)/valid_keyblock.c	\
 	$(srcdir)/verify_checksum.c
 
 
 LIBBASE=k5crypto
 LIBMAJOR=3
 LIBMINOR=0
 LIBINITFUNC=cryptoint_initialize_library
 LIBFINIFUNC=cryptoint_cleanup_library
 RELDIR=crypto
 
@@ -538,20 +540,26 @@
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
   $(SRCTOP)/include/krb5/kdb.h etypes.h
 valid_cksumtype.so valid_cksumtype.po $(OUTPRE)valid_cksumtype.$(OBJEXT): valid_cksumtype.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
   $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
   $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
   cksumtypes.h
 valid_enctype.so valid_enctype.po $(OUTPRE)valid_enctype.$(OBJEXT): valid_enctype.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
+  $(SRCTOP)/include/krb5/kdb.h etypes.h
+valid_keyblock.so valid_keyblock.po $(OUTPRE)valid_keyblock.$(OBJEXT): valid_keyblock.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
   $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
   $(SRCTOP)/include/krb5/kdb.h etypes.h
 verify_checksum.so verify_checksum.po $(OUTPRE)verify_checksum.$(OBJEXT): verify_checksum.c \
   $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \
   $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \
Index: lib/crypto/libk5crypto.exports
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/lib/crypto/libk5crypto.exports,v
retrieving revision 1.1.1.1
diff -u -b -U10 -r1.1.1.1 libk5crypto.exports
--- lib/crypto/libk5crypto.exports	28 Mar 2005 21:43:21 -0000	1.1.1.1
+++ lib/crypto/libk5crypto.exports	1 Aug 2008 17:17:05 -0000
@@ -26,20 +26,21 @@
 krb5_c_make_checksum
 krb5_c_make_random_key
 krb5_c_random_add_entropy
 krb5_c_random_make_octets
 krb5_c_random_os_entropy
 krb5_c_random_seed
 krb5_c_string_to_key
 krb5_c_string_to_key_with_params
 krb5_c_valid_cksumtype
 krb5_c_valid_enctype
+krb5_c_valid_keyblock
 krb5_c_verify_checksum
 krb5_calculate_checksum
 krb5_checksum_size
 krb5_cksumtype_to_string
 krb5_cksumtypes_length
 krb5_cksumtypes_list
 krb5_decrypt
 krb5_decrypt_data
 krb5_derive_key
 krb5_derive_random
Index: lib/crypto/valid_keyblock.c
===================================================================
RCS file: lib/crypto/valid_keyblock.c
diff -N lib/crypto/valid_keyblock.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/crypto/valid_keyblock.c	1 Aug 2008 17:16:39 -0000
@@ -0,0 +1,28 @@
+
+#include "k5-int.h"
+#include "etypes.h"
+
+krb5_boolean KRB5_CALLCONV
+krb5_c_valid_keyblock(krb5_keyblock k)
+{
+    int i;
+    const struct krb5_enc_provider *enc;
+
+    if (k.magic != KV5M_KEYBLOCK)
+	return(0);
+
+    for (i=0; i<krb5_enctypes_length; i++) {
+	if (krb5_enctypes_list[i].etype == k.enctype)
+	    break;
+    }
+
+    if (i == krb5_enctypes_length)
+	return(0);
+
+    enc = krb5_enctypes_list[i].enc;
+
+    if (k.length != enc->keylength)
+	return(0);
+
+    return(1);
+}
Index: lib/kadm5/srv/svr_principal.c
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/lib/kadm5/srv/svr_principal.c,v
retrieving revision 1.4
diff -u -b -U10 -r1.4 svr_principal.c
--- lib/kadm5/srv/svr_principal.c	26 Sep 2006 20:50:37 -0000	1.4
+++ lib/kadm5/srv/svr_principal.c	1 Aug 2008 17:35:51 -0000
@@ -1687,20 +1687,23 @@
     CHECK_HANDLE(server_handle);
 
     if (principal == NULL || keyblocks == NULL)
 	return EINVAL;
     if (hist_princ && /* this will be NULL when initializing the databse */
 	((krb5_principal_compare(handle->context,
 				 principal, hist_princ)) == TRUE))
 	return KADM5_PROTECT_PRINCIPAL;
 
     for (i = 0; i < n_keys; i++) {
+	if (!krb5_c_valid_keyblock(keyblocks[i]))
+	    return EINVAL;
+
 	for (j = i+1; j < n_keys; j++) {
 	    if ((ret = krb5_c_enctype_compare(handle->context,
 					      keyblocks[i].enctype,
 					      keyblocks[j].enctype,
 					      &similar)))
 		return(ret);
 	    if (similar) {
 		if (n_ks_tuple) {
 		    if (ks_tuple[i].ks_salttype == ks_tuple[j].ks_salttype)
 			return KADM5_SETKEY_DUP_ENCTYPES;
Index: lib/krb5/keytab/ktadd.c
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/lib/krb5/keytab/ktadd.c,v
retrieving revision 1.1.1.1
diff -u -b -U10 -r1.1.1.1 ktadd.c
--- lib/krb5/keytab/ktadd.c	28 Mar 2005 21:43:35 -0000	1.1.1.1
+++ lib/krb5/keytab/ktadd.c	1 Aug 2008 17:43:07 -0000
@@ -25,15 +25,18 @@
  * 
  *
  * krb5_kt_add_entry()
  */
 
 #include "k5-int.h"
 
 krb5_error_code KRB5_CALLCONV
 krb5_kt_add_entry (krb5_context context, krb5_keytab id, krb5_keytab_entry *entry)
 {
+    if (!krb5_c_valid_keyblock(entry->key))
+	return EINVAL;	/* XXXrcd: bad error code, choose another one. */
+
     if (id->ops->add)
 	return (*id->ops->add)(context, id, entry);
     else
 	return KRB5_KT_NOWRITE;
 }
Index: include/krb5.hin
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/include/krb5.hin,v
retrieving revision 1.1.1.2
diff -u -b -U10 -r1.1.1.2 krb5.hin
--- include/krb5.hin	26 Sep 2006 20:29:10 -0000	1.1.1.2
+++ include/krb5.hin	1 Aug 2008 17:19:04 -0000
@@ -542,20 +542,22 @@
 #define KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV		24
 
 /* Defined in hardware preauth draft */
 
 #define KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM	25
 #define KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID	26
 #define KRB5_KEYUSAGE_PA_SAM_RESPONSE		27
 
 krb5_boolean KRB5_CALLCONV krb5_c_valid_enctype
 	(krb5_enctype ktype);
+krb5_boolean KRB5_CALLCONV krb5_c_valid_keyblock
+	(krb5_keyblock key);
 krb5_boolean KRB5_CALLCONV krb5_c_valid_cksumtype
 	(krb5_cksumtype ctype);
 krb5_boolean KRB5_CALLCONV krb5_c_is_coll_proof_cksum
 	(krb5_cksumtype ctype);
 krb5_boolean KRB5_CALLCONV krb5_c_is_keyed_cksum
 	(krb5_cksumtype ctype);
 
 #if KRB5_PRIVATE
 /* Use the above four instead.  */
 krb5_boolean KRB5_CALLCONV valid_enctype




More information about the krb5-bugs mailing list