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; ikeylength) + 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