[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