diff options
author | Marc Horowitz <marc@mit.edu> | 1998-10-30 02:56:35 +0000 |
---|---|---|
committer | Marc Horowitz <marc@mit.edu> | 1998-10-30 02:56:35 +0000 |
commit | 1440ab035ba04550ddbbfbff1ee9b5571e3d95db (patch) | |
tree | 9d5e8d2e151a930e044c7d0f7c64053d244577a0 /src/lib | |
parent | 61ddbf948ba6ee70c1bc049268c3dfa73bc9983e (diff) | |
download | krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.tar.gz krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.tar.xz krb5-1440ab035ba04550ddbbfbff1ee9b5571e3d95db.zip |
pull up 3des implementation from the marc-3des branch
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11001 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
214 files changed, 7933 insertions, 9745 deletions
diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index dd0e7b5611..566afc88f3 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,3 +1,34 @@ +Tue Sep 22 21:19:01 1998 Tom Yu <tlyu@mit.edu> + + * prng.c (krb5_c_random_make_octets): Fix to nfold into 15 bytes, + not one byte. + +Mon Sep 21 15:23:19 1998 Tom Yu <tlyu@mit.edu> + + * prng.c (krb5_c_random_seed): Fix memory leak. + +Mon Sep 14 23:21:17 1998 Tom Yu <tlyu@mit.edu> + + * old/decrypt.c (krb5_old_decrypt): Fix memory leak. + +Tue Sep 1 19:33:38 1998 Tom Yu <tlyu@mit.edu> + + * etypes.c: Add ETYPE_LOCAL_DES3_HMAC_SHA1 to deal with marc's + des3 code. ETYPE_DES3_HMAC_SHA1 remains the same for now. + +Mon Aug 17 23:40:11 1998 Tom Yu <tlyu@mit.edu> + + * keyhash_provider/k5_md4des.c (k5_md4des_verify): Add + compatibility for krb5-beta5 checksums. + + * keyhash_provider/k5_md5des.c (k5_md5des_verify): Add + compatibility for krb5-beta5 checksums. Fix typos similar to + those corrected in k5_md4des.c. + +Sun Jul 19 12:00:00 1998 Marc Horowitz <marc@mit.edu> + + * *.c: replace the crypto layer. + Wed Apr 15 18:02:44 1998 Tom Yu <tlyu@mit.edu> * Makefile.in (LIB): Rename to k5crypto. diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index 468818cb80..48d035a78b 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -1,7 +1,10 @@ thisconfigdir=. BUILDTOP=$(REL)$(U)$(S)$(U) -LOCAL_SUBDIRS=des crc32 md4 md5 sha os -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/crc32 -I$(srcdir)/des -I$(srcdir)/md4 -I$(srcdir)/md5 -I$(srcdir)/sha +LOCAL_SUBDIRS=crc32 des dk enc_provider hash_provider keyhash_provider \ + md4 md5 old raw sha1 +CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/enc_provider \ + -I$(srcdir)/hash_provider -I$(srcdir)/keyhash_provider \ + -I$(srcdir)/old -I$(srcdir)/raw -I$(srcdir)/dk ##DOSBUILDTOP = ..\.. ##DOSLIBNAME=crypto.lib @@ -9,37 +12,102 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/crc32 -I$(srcdir)/des -I$(srcdir)/md4 -I$ ##DOSOBJFILELIST=@crypto.lst @des.lst @md4.lst @md5.lst @sha.lst @crc32.lst @os.lst ##DOSOBJFILEDEP =crypto.lst des.lst md4.lst md5.lst sha.lst crc32.lst os.lst -MAC_SUBDIRS = des sha md4 md5 crc32 os - -OBJS= cryptoconf.$(OBJEXT) \ - encrypt_data.$(OBJEXT) \ - krb5_glue.$(OBJEXT) \ - decrypt_data.$(OBJEXT) \ - des_crc.$(OBJEXT) \ - des_md5.$(OBJEXT) \ - des3_sha.$(OBJEXT) \ - des3_raw.$(OBJEXT) \ - raw_des.$(OBJEXT) - -SRCS= $(srcdir)/cryptoconf.c \ - $(srcdir)/encrypt_data.c \ - $(srcdir)/krb5_glue.c \ - $(srcdir)/decrypt_data.c \ - $(srcdir)/des_crc.c \ - $(srcdir)/des_md5.c \ - $(srcdir)/des3_sha.c \ - $(srcdir)/des3_raw.c \ - $(srcdir)/raw_des.c +MAC_SUBDIRS = crc32 des dk enc_provider hash_provider keyhash_provider \ + md4 md5 old raw sha1 + +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +STLIBOBJS=\ + block_size.o \ + checksum_length.o \ + cksumtype_to_string.o \ + cksumtypes.o \ + coll_proof_cksum.o \ + decrypt.o \ + encrypt.o \ + encrypt_length.o \ + enctype_compare.o \ + enctype_to_string.o \ + etypes.o \ + hmac.o \ + keyed_cksum.o \ + keyed_checksum_types.o \ + make_checksum.o \ + make_random_key.o \ + nfold.o \ + old_api_glue.o \ + prng.o \ + string_to_cksumtype.o \ + string_to_enctype.o \ + string_to_key.o \ + valid_cksumtype.o \ + valid_enctype.o \ + verify_checksum.o + +OBJS=\ + block_size.$(OBJEXT) \ + checksum_length.$(OBJEXT) \ + cksumtype_to_string.$(OBJEXT) \ + cksumtypes.$(OBJEXT) \ + coll_proof_cksum.$(OBJEXT) \ + decrypt.$(OBJEXT) \ + encrypt.$(OBJEXT) \ + encrypt_length.$(OBJEXT) \ + enctype_compare.$(OBJEXT) \ + enctype_to_string.$(OBJEXT) \ + etypes.$(OBJEXT) \ + hmac.$(OBJEXT) \ + keyed_cksum.$(OBJEXT) \ + keyed_checksum_types.$(OBJEXT) \ + make_checksum.$(OBJEXT) \ + make_random_key.$(OBJEXT) \ + nfold.$(OBJEXT) \ + old_api_glue.$(OBJEXT) \ + prng.$(OBJEXT) \ + string_to_cksumtype.$(OBJEXT) \ + string_to_enctype.$(OBJEXT) \ + string_to_key.$(OBJEXT) \ + valid_cksumtype.$(OBJEXT) \ + valid_enctype.$(OBJEXT) \ + verify_checksum.$(OBJEXT) + +SRCS=\ + $(subdir)/block_size.c \ + $(subdir)/checksum_length.c \ + $(subdir)/cksumtype_to_string.c \ + $(subdir)/cksumtypes.c \ + $(subdir)/coll_proof_cksum.c \ + $(subdir)/decrypt.c \ + $(subdir)/encrypt.c \ + $(subdir)/encrypt_length.c \ + $(subdir)/enctype_compare.c \ + $(subdir)/enctype_to_string.c \ + $(subdir)/etypes.c \ + $(subdir)/hmac.c \ + $(subdir)/keyed_cksum.c \ + $(subdir)/keyed_checksum_types.c\ + $(subdir)/make_checksum.c \ + $(subdir)/make_random_key.c \ + $(subdir)/nfold.c \ + $(subdir)/old_api_glue.c \ + $(subdir)/prng.c \ + $(subdir)/string_to_cksumtype.c \ + $(subdir)/string_to_enctype.c \ + $(subdir)/string_to_key.c \ + $(subdir)/valid_cksumtype.c \ + $(subdir)/valid_enctype.c \ + $(subdir)/verify_checksum.c + LIB=k5crypto LIBMAJOR=2 -LIBMINOR=0 +LIBMINOR=1 RELDIR=crypto -STLIBOBJS=cryptoconf.o encrypt_data.o decrypt_data.o \ - des_crc.o des_md5.o des3_sha.o des3_raw.o raw_des.o krb5_glue.o -STOBJLISTS=des/OBJS.ST md4/OBJS.ST md5/OBJS.ST sha/OBJS.ST crc32/OBJS.ST \ - os/OBJS.ST OBJS.ST +STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ + hash_provider/OBJS.ST keyhash_provider/OBJS.ST md4/OBJS.ST \ + md5/OBJS.ST old/OBJS.ST raw/OBJS.ST sha1/OBJS.ST OBJS.ST # No dependencies. Record places to find this shared object if the target # link editor and loader support it. @@ -58,7 +126,14 @@ libcrypto.lib: clean-unix:: clean-liblinks clean-libs clean-libobjs -check-unix:: +check-unix:: t_nfold + $(RUN_SETUP) ./t_nfold + +t_nfold$(EXEEXT): t_nfold.$(OBJEXT) nfold.$(OBJEXT) + $(CC_LINK) -o $@ t_nfold.$(OBJEXT) nfold.$(OBJEXT) + +clean:: + $(RM) t_nfold.o t_nfold all-windows:: cd crc32 @@ -67,61 +142,101 @@ all-windows:: cd ..\des @echo Making in crypto\des -$(MAKE) -$(MFLAGS) + cd ..\dk + @echo Making in crypto\dk + -$(MAKE) -$(MFLAGS) + cd ..\enc_provider + @echo Making in crypto\enc_provider + -$(MAKE) -$(MFLAGS) + cd ..\hash_provider + @echo Making in crypto\hash_provider + -$(MAKE) -$(MFLAGS) + cd ..\keyhash_provider + @echo Making in crypto\keyhash_provider + -$(MAKE) -$(MFLAGS) cd ..\md4 @echo Making in crypto\md4 -$(MAKE) -$(MFLAGS) - cd ..\os - @echo Making in crypto\os - -$(MAKE) -$(MFLAGS) cd ..\md5 @echo Making in crypto\md5 -$(MAKE) -$(MFLAGS) - cd ..\sha - @echo Making in crypto\sha + cd ..\old + @echo Making in crypto\old + -$(MAKE) -$(MFLAGS) + cd ..\raw + @echo Making in crypto\raw + -$(MAKE) -$(MFLAGS) + cd ..\sha1 + @echo Making in crypto\sha1 -$(MAKE) -$(MFLAGS) - cd .. clean-windows:: cd crc32 - @echo Making clean in crypto\crc32 + @echo Making in clean crypto\crc32 -$(MAKE) -$(MFLAGS) clean cd ..\des @echo Making clean in crypto\des -$(MAKE) -$(MFLAGS) clean + cd ..\dk + @echo Making clean in crypto\dk + -$(MAKE) -$(MFLAGS) clean + cd ..\enc_provider + @echo Making clean in crypto\enc_provider + -$(MAKE) -$(MFLAGS) clean + cd ..\hash_provider + @echo Making clean in crypto\hash_provider + -$(MAKE) -$(MFLAGS) clean + cd ..\keyhash_provider + @echo Making clean in crypto\keyhash_provider + -$(MAKE) -$(MFLAGS) clean cd ..\md4 @echo Making clean in crypto\md4 -$(MAKE) -$(MFLAGS) clean cd ..\md5 @echo Making clean in crypto\md5 -$(MAKE) -$(MFLAGS) clean - cd ..\sha - @echo Making clean in crypto\sha + cd ..\old + @echo Making clean in crypto\old -$(MAKE) -$(MFLAGS) clean - cd ..\os - @echo Making clean in crypto\os + cd ..\raw + @echo Making clean in crypto\raw + -$(MAKE) -$(MFLAGS) clean + cd ..\sha1 + @echo Making clean in crypto\sha1 -$(MAKE) -$(MFLAGS) clean - cd .. - @echo Making clean locally check-windows:: cd crc32 - @echo Making check in crypto\crc32 + @echo Making in check crypto\crc32 -$(MAKE) -$(MFLAGS) check cd ..\des @echo Making check in crypto\des -$(MAKE) -$(MFLAGS) check + cd ..\dk + @echo Making check in crypto\dk + -$(MAKE) -$(MFLAGS) check + cd ..\enc_provider + @echo Making check in crypto\enc_provider + -$(MAKE) -$(MFLAGS) check + cd ..\hash_provider + @echo Making check in crypto\hash_provider + -$(MAKE) -$(MFLAGS) check + cd ..\keyhash_provider + @echo Making check in crypto\keyhash_provider + -$(MAKE) -$(MFLAGS) check cd ..\md4 @echo Making check in crypto\md4 -$(MAKE) -$(MFLAGS) check cd ..\md5 @echo Making check in crypto\md5 -$(MAKE) -$(MFLAGS) check - cd ..\sha - @echo Making check in crypto\sha + cd ..\old + @echo Making check in crypto\old -$(MAKE) -$(MFLAGS) check - cd ..\os - @echo Making check in crypto\os + cd ..\raw + @echo Making check in crypto\raw + -$(MAKE) -$(MFLAGS) check + cd ..\sha1 + @echo Making check in crypto\sha1 -$(MAKE) -$(MFLAGS) check - cd .. - diff --git a/src/lib/crypto/block_size.c b/src/lib/crypto/block_size.c new file mode 100644 index 0000000000..de5c3ac89c --- /dev/null +++ b/src/lib/crypto/block_size.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_block_size(context, enctype, blocksize) + krb5_context context; + krb5_enctype enctype; + size_t *blocksize; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + (*(krb5_enctypes_list[i].enc->block_size))(blocksize); + + return(0); +} diff --git a/src/lib/crypto/checksum_length.c b/src/lib/crypto/checksum_length.c new file mode 100644 index 0000000000..38773cae01 --- /dev/null +++ b/src/lib/crypto/checksum_length.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_error_code +krb5_c_checksum_length(context, cksumtype, length) + krb5_context context; + krb5_cksumtype cksumtype; + size_t *length; +{ + int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + if (krb5_cksumtypes_list[i].keyhash) + (*(krb5_cksumtypes_list[i].keyhash->hash_size))(length); + else + (*(krb5_cksumtypes_list[i].hash->hash_size))(length); + + return(0); +} + diff --git a/src/lib/crypto/cksumtype_to_string.c b/src/lib/crypto/cksumtype_to_string.c new file mode 100644 index 0000000000..21cc5905f6 --- /dev/null +++ b/src/lib/crypto/cksumtype_to_string.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_cksumtype_to_string(cksumtype, buffer, buflen) + krb5_cksumtype cksumtype; + char FAR * buffer; + size_t buflen; +{ + int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) { + if ((strlen(krb5_cksumtypes_list[i].out_string)+1) > buflen) + return(ENOMEM); + + strcpy(buffer, krb5_cksumtypes_list[i].out_string); + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/cksumtypes.c b/src/lib/crypto/cksumtypes.c new file mode 100644 index 0000000000..8107d3b8f7 --- /dev/null +++ b/src/lib/crypto/cksumtypes.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "hash_provider.h" +#include "keyhash_provider.h" +#include "cksumtypes.h" + +struct krb5_cksumtypes krb5_cksumtypes_list[] = { + { CKSUMTYPE_CRC32, KRB5_CKSUMFLAG_NOT_COLL_PROOF, + "crc32", "CRC-32", + 0, NULL, + &krb5_hash_crc32 }, + + { CKSUMTYPE_RSA_MD4, 0, + "md4", "RSA-MD4", + 0, NULL, + &krb5_hash_md4 }, + { CKSUMTYPE_RSA_MD4_DES, 0, + "md4-des", "RSA-MD4 with DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5_keyhash_md4des, + NULL }, + + { CKSUMTYPE_DESCBC, 0, + "des-cbc", "DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5_keyhash_descbc, + NULL }, + + { CKSUMTYPE_RSA_MD5, 0, + "md5", "RSA-MD5", + 0, NULL, + &krb5_hash_md5 }, + { CKSUMTYPE_RSA_MD5_DES, 0, + "md5-des", "RSA-MD5 with DES cbc mode", + ENCTYPE_DES_CBC_CRC, &krb5_keyhash_md5des, + NULL }, + + { CKSUMTYPE_NIST_SHA, 0, + "sha", "NIST-SHA", + 0, NULL, + &krb5_hash_sha1 }, + + { CKSUMTYPE_HMAC_SHA1, KRB5_CKSUMFLAG_DERIVE, + "hmac-sha1", "HMAC-SHA1", + 0, NULL, + &krb5_hash_sha1 }, +}; + +int krb5_cksumtypes_length = +sizeof(krb5_cksumtypes_list)/sizeof(struct krb5_cksumtypes); + diff --git a/src/lib/crypto/cksumtypes.h b/src/lib/crypto/cksumtypes.h new file mode 100644 index 0000000000..900a7c8914 --- /dev/null +++ b/src/lib/crypto/cksumtypes.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +extern struct krb5_cksumtypes krb5_cksumtypes_list[]; +extern int krb5_cksumtypes_length; + diff --git a/src/lib/crypto/coll_proof_cksum.c b/src/lib/crypto/coll_proof_cksum.c new file mode 100644 index 0000000000..07925c641a --- /dev/null +++ b/src/lib/crypto/coll_proof_cksum.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_boolean is_coll_proof_cksum(ctype) + krb5_cksumtype ctype; +{ + int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == ctype) + return((krb5_cksumtypes_list[i].flags & + KRB5_CKSUMFLAG_NOT_COLL_PROOF)?0:1); + } + + /* ick, but it's better than coredumping, which is what the + old code would have done */ + return(0); +} diff --git a/src/lib/crypto/configure.in b/src/lib/crypto/configure.in index 19688e35e6..2fb1faffbf 100644 --- a/src/lib/crypto/configure.in +++ b/src/lib/crypto/configure.in @@ -4,136 +4,22 @@ AC_PROG_ARCHIVE AC_PROG_ARCHIVE_ADD AC_PROG_RANLIB AC_PROG_INSTALL -dnl -dnl Determine which cryptosystems we are enabling -dnl -AC_ARG_ENABLE([des-cbc-md5], -[ --enable-des-cbc-md5 enable DES_CBC_MD5 (DEFAULT). - --disable-des-cbc-md5 disable DES_CBC_MD5.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling DES_CBC_MD5) - AC_DEFINE(PROVIDE_DES_CBC_MD5) -else - AC_MSG_RESULT(Disabling DES_CBC_MD5) -fi -dnl AC_ARG_ENABLE([des3-cbc-sha], -dnl [ --enable-des3-cbc-sha enable DES3_CBC_SHA (DEFAULT). -dnl --disable-des3-cbc-sha disable DES3_CBC_SHA.], -dnl , -dnl enableval=yes)dnl -dnl if test "$enableval" = yes; then -dnl AC_MSG_RESULT(Enabling DES3_CBC_SHA) -dnl AC_DEFINE(PROVIDE_DES3_CBC_SHA) -dnl else -dnl AC_MSG_RESULT(Disabling DES3_CBC_SHA) -dnl fi -AC_ARG_WITH([des-cbc-crc], -[ --enable-des-cbc-crc enable DES_CBC_CRC (DEFAULT). - --disable-des-cbc-crc disable DES_CBC_CRC.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling DES_CBC_CRC) - AC_DEFINE(PROVIDE_DES_CBC_CRC) -else - AC_MSG_RESULT(Disabling DES_CBC_CRC) -fi -AC_ARG_WITH([des-cbc-raw], -[ --enable-des-cbc-raw enable DES_CBC_RAW (DEFAULT). - --disable-des-cbc-raw disable DES_CBC_RAW.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling DES_CBC_RAW) - AC_DEFINE(PROVIDE_DES_CBC_RAW) -else - AC_MSG_RESULT(Disabling DES_CBC_RAW) -fi -dnl AC_ARG_WITH([des3-cbc-raw], -dnl [ --enable-des3-cbc-raw enable DES3_CBC_RAW (DEFAULT). -dnl --disable-des3-cbc-raw disable DES3_CBC_RAW.], -dnl , -dnl enableval=yes)dnl -dnl if test "$enableval" = yes; then -dnl AC_MSG_RESULT(Enabling DES3_CBC_RAW) -dnl AC_DEFINE(PROVIDE_DES3_CBC_RAW) -dnl else -dnl AC_MSG_RESULT(Disabling DES3_CBC_RAW) -dnl fi -AC_ARG_WITH([des-cbc-cksum], -[ --enable-des-cbc-cksum enable DES_CBC_CKSUM (DEFAULT). - --disable-des-cbc-cksum disable DES_CBC_CKSUM.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling DES_CBC_CKSUM) - AC_DEFINE(PROVIDE_DES_CBC_CKSUM) -else - AC_MSG_RESULT(Disabling DES_CBC_CKSUM) -fi -AC_ARG_WITH([crc32], -[ --enable-crc32 enable CRC32 (DEFAULT). - --disable-crc32 disable CRC32.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling CRC32) - AC_DEFINE(PROVIDE_CRC32) -else - AC_MSG_RESULT(Disabling CRC32) -fi -AC_ARG_WITH([rsa-md4], -[ --enable-rsa-md4 enable RSA_MD4 (DEFAULT). - --disable-rsa-md4 disable RSA_MD4.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling RSA_MD4) - AC_DEFINE(PROVIDE_RSA_MD4) -else - AC_MSG_RESULT(Disabling RSA_MD4) -fi -AC_ARG_WITH([rsa-md5], -[ --enable-rsa-md5 enable RSA_MD5 (DEFAULT). - --disable-rsa-md5 disable RSA_MD5.], -, -enableval=yes)dnl -if test "$enableval" = yes; then - AC_MSG_RESULT(Enabling RSA_MD5) - AC_DEFINE(PROVIDE_RSA_MD5) -else - AC_MSG_RESULT(Disabling RSA_MD5) -fi -dnl AC_ARG_WITH([nist-sha], -dnl [ --enable-nist-sha enable NIST_SHA (DEFAULT). -dnl --disable-nist-sha disable NIST_SHA.], -dnl , -dnl enableval=yes)dnl -dnl if test "$enableval" = yes; then -dnl AC_MSG_RESULT(Enabling NIST_SHA) -dnl AC_DEFINE(PROVIDE_NIST_SHA) -dnl else -dnl AC_MSG_RESULT(Disabling NIST_SHA) -dnl fi - -AC_REPLACE_FUNCS(memmove) -AC_HAVE_FUNCS(srand48 srand srandom getpid) -AC_CHECK_HEADERS(sys/types.h) -AC_PROG_LN_S -KRB5_SOCKADDR_SA_LEN KRB5_RUN_FLAGS +KRB5_BUILD_PROGRAM KRB5_BUILD_LIBOBJS KRB5_BUILD_LIBRARY -KRB5_BUILD_PROGRAM K5_GEN_MAKEFILE(., lib libobj) K5_GEN_MAKEFILE(crc32, libobj) K5_GEN_MAKEFILE(des, libobj) +K5_GEN_MAKEFILE(dk, libobj) +K5_GEN_MAKEFILE(enc_provider, libobj) +K5_GEN_MAKEFILE(hash_provider, libobj) +K5_GEN_MAKEFILE(keyhash_provider, libobj) K5_GEN_MAKEFILE(md4, libobj) K5_GEN_MAKEFILE(md5, libobj) -K5_GEN_MAKEFILE(os, libobj) -K5_GEN_MAKEFILE(sha, libobj) +K5_GEN_MAKEFILE(old, libobj) +K5_GEN_MAKEFILE(raw, libobj) +K5_GEN_MAKEFILE(sha1, libobj) K5_AC_OUTPUT diff --git a/src/lib/crypto/crc32/ChangeLog b/src/lib/crypto/crc32/ChangeLog index 1ee004262c..5f6e617cb9 100644 --- a/src/lib/crypto/crc32/ChangeLog +++ b/src/lib/crypto/crc32/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz <marc@mit.edu> + + * *.c: replace the crypto layer. + Wed Feb 18 16:05:45 1998 Tom Yu <tlyu@mit.edu> * Makefile.in: Remove trailing slash from thisconfigdir. Fix up diff --git a/src/lib/crypto/crc32/Makefile.in b/src/lib/crypto/crc32/Makefile.in index b1ad86bdd8..97ab64cf04 100644 --- a/src/lib/crypto/crc32/Makefile.in +++ b/src/lib/crypto/crc32/Makefile.in @@ -7,25 +7,23 @@ CFLAGS = $(CCOPTS) $(DEFS) ##DOS##OBJFILE=..\crc32.lst ##WIN16##LIBNAME=..\crypto.lib -STLIBOBJS=crc.o -OBJS= crc.$(OBJEXT) -SRCS= $(srcdir)/crc.c +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) -##DOS##LIBOBJS = $(OBJS) +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -all-unix:: all-libobjs +STLIBOBJS= crc32.o + +OBJS= crc32.$(OBJEXT) -crctest: crctest.$(OBJEXT) $(OBJS) - $(RM) crctest - $(CC) -o crctest crctest.$(OBJEXT) $(CFLAGS) $(LDFLAGS) $(OBJS) +SRCS= $(srcdir)/crc32.c -crctest.exe: - $(CC) -o crctest.exe $(CFLAGS2) $(SRCS) +##DOS##LIBOBJS = $(OBJS) + +all-unix:: all-libobjs -check:: crctest$(EXEEXT) - $(C)crctest$(EXEEXT) < $(srcdir)$(S)crc-test +includes:: depend -clean:: - $(RM) crctest$(EXEEXT) crctest.$(OBJEXT) +depend:: $(SRCS) clean-unix:: clean-libobjs diff --git a/src/lib/crypto/crc32/crc-32.h b/src/lib/crypto/crc32/crc-32.h index 28d0dc4519..1b05b9ac6a 100644 --- a/src/lib/crypto/crc32/crc-32.h +++ b/src/lib/crypto/crc32/crc-32.h @@ -24,11 +24,41 @@ * Definitions for the CRC-32 checksum */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #ifndef KRB5_CRC32__ #define KRB5_CRC32__ -#define CRC32_CKSUM_LENGTH (4*sizeof(krb5_octet)) +#define CRC32_CKSUM_LENGTH 4 + +void +mit_crc32 PROTOTYPE((krb5_const krb5_pointer in, krb5_const size_t in_length, + unsigned long *c)); extern krb5_checksum_entry crc32_cksumtable_entry; diff --git a/src/lib/crypto/crc32/crc32.c b/src/lib/crypto/crc32/crc32.c new file mode 100644 index 0000000000..654981fc9f --- /dev/null +++ b/src/lib/crypto/crc32/crc32.c @@ -0,0 +1,166 @@ +/* + * lib/crypto/crc32/crc.c + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * CRC-32/AUTODIN-II routines + */ + +#include "k5-int.h" +#include "crc-32.h" + +/* This table and block of comments are taken from code labeled: */ +/* + * Copyright (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + */ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +static u_long const crc_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + +void +mit_crc32(in, in_length, cksum) + krb5_const krb5_pointer in; + krb5_const size_t in_length; + unsigned long *cksum; +{ + register u_char *data; + register u_long c = 0; + register int idx; + size_t i; + + data = (u_char *)in; + for (i = 0; i < in_length; i++) { + idx = (int) (data[i] ^ c); + idx &= 0xff; + c >>= 8; + c ^= crc_table[idx]; + } + + *cksum = c; +} diff --git a/src/lib/crypto/cryptoconf.c b/src/lib/crypto/cryptoconf.c deleted file mode 100644 index 62be745812..0000000000 --- a/src/lib/crypto/cryptoconf.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * lib/crypto/cryptoconf.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * Cryptosystem configurations - */ - -#include "k5-int.h" - -#if defined(PROVIDE_DES_CBC_CRC) || defined(PROVIDE_CRC32) -#include "crc-32.h" -#define CRC32_CKENTRY &crc32_cksumtable_entry -#else -#define CRC32_CKENTRY 0 -#endif - -#ifdef PROVIDE_RSA_MD4 -#include "rsa-md4.h" -#define MD4_CKENTRY &rsa_md4_cksumtable_entry -#define MD4_DES_CKENTRY &rsa_md4_des_cksumtable_entry -#else -#define MD4_CKENTRY 0 -#define MD4_DES_CKENTRY 0 -#endif - -#ifdef PROVIDE_RSA_MD5 -#include "rsa-md5.h" -#define MD5_CKENTRY &rsa_md5_cksumtable_entry -#define MD5_DES_CKENTRY &rsa_md5_des_cksumtable_entry -#else -#define MD5_CKENTRY 0 -#define MD5_DES_CKENTRY 0 -#endif - -#ifdef PROVIDE_NIST_SHA -#include "shs.h" -/* #define SHA_CKENTRY &nist_sha_cksumtable_entry */ -/* #define HMAC_SHA_CKENTRY &hmac_sha_cksumtable_entry */ -#define SHA_CKENTRY 0 -#define HMAC_SHA_CKENTRY 0 -#else -#define SHA_CKENTRY 0 -#define HMAC_SHA_CKENTRY 0 -#endif - -#ifdef PROVIDE_SNEFRU -#define XEROX_CKENTRY &snefru_cksumtable_entry -#else -#define XEROX_CKENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_CKSUM -#include "des_int.h" -#define _DES_DONE__ -#define DES_CBC_CKENTRY &krb5_des_cbc_cksumtable_entry -#else -#define DES_CBC_CKENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_CRC -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -#define DES_CBC_CRC_CSENTRY &krb5_des_crc_cst_entry -#else -#define DES_CBC_CRC_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_MD5 -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -#define DES_CBC_MD5_CSENTRY &krb5_des_md5_cst_entry -#else -#define DES_CBC_MD5_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES_CBC_RAW -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -#define DES_CBC_RAW_CSENTRY &krb5_raw_des_cst_entry -#else -#define DES_CBC_RAW_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES3_CBC_SHA -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -/* Don't try to enable triple DES unless you know what you are doing; */ -/* the current implementation of triple DES is NOT the final and */ -/* correct implementation.!!! */ -/* #define DES3_CBC_SHA_CSENTRY &krb5_des3_sha_cst_entry */ -#define DES3_CBC_SHA_CSENTRY 0 -#else -#define DES3_CBC_SHA_CSENTRY 0 -#endif - -#ifdef PROVIDE_DES3_CBC_RAW -#ifndef _DES_DONE__ -#include "des_int.h" -#define _DES_DONE__ -#endif -/* #define DES3_CBC_RAW_CSENTRY &krb5_des3_raw_cst_entry */ -#define DES3_CBC_RAW_CSENTRY 0 -#else -#define DES3_CBC_RAW_CSENTRY 0 -#endif - - -/* WARNING: - make sure the order of entries in these tables matches the #defines in - "krb5/encryption.h" - */ - -krb5_cs_table_entry * NEAR krb5_enctype_array[] = { - 0, /* ENCTYPE_NULL */ - DES_CBC_CRC_CSENTRY, /* ENCTYPE_DES_CBC_CRC */ - 0, /* ENCTYPE_DES_CBC_MD4 */ - DES_CBC_MD5_CSENTRY, /* ENCTYPE_DES_CBC_MD5 */ - DES_CBC_RAW_CSENTRY, /* ENCTYPE_DES_CBC_RAW */ - DES3_CBC_SHA_CSENTRY, /* ENCTYPE_DES3_CBC_SHA */ - DES3_CBC_RAW_CSENTRY /* ENCTYPE_DES3_CBC_RAW */ -}; - -krb5_enctype krb5_max_enctype = sizeof(krb5_enctype_array)/sizeof(krb5_enctype_array[0]) - 1; - -krb5_checksum_entry * NEAR krb5_cksumarray[] = { - 0, - CRC32_CKENTRY, /* 1 - CKSUMTYPE_CRC32 */ - MD4_CKENTRY, /* 2 - CKSUMTYPE_RSA_MD4 */ - MD4_DES_CKENTRY, /* 3 - CKSUMTYPE_RSA_MD4_DES */ - DES_CBC_CKENTRY, /* 4 - CKSUMTYPE_DESCBC */ - 0, /* 5 - des-mac-k */ - 0, /* 6 - rsa-md4-des-k */ - MD5_CKENTRY, /* 7 - CKSUMTYPE_RSA_MD5 */ - MD5_DES_CKENTRY, /* 8 - CKSUMTYPE_RSA_MD5_DES */ - SHA_CKENTRY, /* 9 - CKSUMTYPE_NIST_SHA */ - HMAC_SHA_CKENTRY /* 10 - CKSUMTYPE_NIST_SHA_DES3 */ -}; - -krb5_cksumtype krb5_max_cksum = sizeof(krb5_cksumarray)/sizeof(krb5_cksumarray[0]); - -#undef _DES_DONE__ diff --git a/src/lib/crypto/decrypt.c b/src/lib/crypto/decrypt.c new file mode 100644 index 0000000000..0d66ec0c0e --- /dev/null +++ b/src/lib/crypto/decrypt.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_decrypt(context, key, usage, ivec, input, output) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_enc_data *input; + krb5_data *output; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + if ((input->enctype != ENCTYPE_UNKNOWN) && + (krb5_enctypes_list[i].etype != input->enctype)) + return(KRB5_BAD_ENCTYPE); + + return((*(krb5_enctypes_list[i].decrypt)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, usage, ivec, &input->ciphertext, output)); +} diff --git a/src/lib/crypto/decrypt_data.c b/src/lib/crypto/decrypt_data.c deleted file mode 100644 index ae886d0c9d..0000000000 --- a/src/lib/crypto/decrypt_data.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -#include "k5-int.h" - -/* - * This routine takes a key and a krb5_enc_data structure as input, and - * outputs the decrypted data in a krb5_data structure. Note that - * the krb5_data structure is not allocated. - */ -krb5_error_code -krb5_decrypt_data(context, key, ivec, enc_data, data) - krb5_context context; - krb5_keyblock * key; - krb5_pointer ivec; - krb5_enc_data * enc_data; - krb5_data * data; -{ - krb5_error_code retval; - krb5_encrypt_block eblock; - - krb5_use_enctype(context, &eblock, key->enctype); - data->length = enc_data->ciphertext.length; - if (!(data->data = malloc(data->length))) - return ENOMEM; - - if ((retval = krb5_process_key(context, &eblock, key)) != 0) - goto cleanup; - - if ((retval = krb5_decrypt(context, - (krb5_pointer) enc_data->ciphertext.data, - (krb5_pointer) data->data, - enc_data->ciphertext.length, &eblock, ivec))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - (void) krb5_finish_key(context, &eblock); - - return 0; - -cleanup: - if (data->data) { - free(data->data); - data->data = 0; - } - return retval; -} diff --git a/src/lib/crypto/des/.rconf b/src/lib/crypto/des/.rconf deleted file mode 100644 index b886964867..0000000000 --- a/src/lib/crypto/des/.rconf +++ /dev/null @@ -1,8 +0,0 @@ -ignore fp.c -ignore ip.c -ignore key_perm.h -ignore odd.h -ignore p.c -ignore p_table.h -ignore s_table.h -ignore doc diff --git a/src/lib/crypto/des/ChangeLog b/src/lib/crypto/des/ChangeLog index e236a9cb96..70c431aa5c 100644 --- a/src/lib/crypto/des/ChangeLog +++ b/src/lib/crypto/des/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz <marc@mit.edu> + + * *.c: replace the crypto layer. + Wed Feb 18 16:06:23 1998 Tom Yu <tlyu@mit.edu> * Makefile.in: Remove trailing slash from thisconfigdir. Fix up diff --git a/src/lib/crypto/des/FUNCTIONS b/src/lib/crypto/des/FUNCTIONS deleted file mode 100644 index 7ed082e32d..0000000000 --- a/src/lib/crypto/des/FUNCTIONS +++ /dev/null @@ -1,26 +0,0 @@ -File Function Where? - -weak_key.c mit_des_is_weak_key crypto -string2key.c mit_des_string_to_key ? -random_key.c mit_des_random_key ? -process_ky.c mit_des_process_key ? -new_rn_key.c mit_des_new_random_key ? - mit_des_init_random_number_generator ? - mit_des_set_random_generator_seed ? - mit_des_set_sequence_number ? - mit_des_generate_random_block ? -krb_glue.c mit_des_encrypt_func ? - mit_des_decrypt_func ? -key_sched.c mit_des_key_sched crypto -key_parity.c mit_des_fixup_key_parity crypto - mit_des_check_key_parity crypto -init_rkey.c mit_des_init_random_key crypto -finish_key.c mit_des_finish_key crypto -fin_rndkey.c mit_des_finish_random_key crypto -enc_dec.c mit_des_cbc_encrypt crypto -des.c mit_des_ecb_encrypt crypto -cs_entry.c (var) mit_des_cryptosystem_entry krb5 - (var) krb5_des_cst_entry krb5 - (var) mit_des_cbc_cksumtable_entry krb5 -cksum.c mit_des_cbc_cksum crypto -cbc_cksum.c mit_des_cbc_checksum crypto diff --git a/src/lib/crypto/des/Makefile.in b/src/lib/crypto/des/Makefile.in index 3f9311b96e..fdef9e869a 100644 --- a/src/lib/crypto/des/Makefile.in +++ b/src/lib/crypto/des/Makefile.in @@ -13,77 +13,41 @@ PROG_RPATH=$(KRB5_LIBDIR) RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf STLIBOBJS=\ - afsstring2key.o \ - cbc_cksum.o \ - finish_key.o \ - fin_rndkey.o \ - init_rkey.o \ - process_ky.o \ - random_key.o \ - string2key.o \ - key_sched.o \ - weak_key.o \ + afsstring2key.o \ + d3_cbc.o \ + d3_kysched.o \ f_cbc.o \ - f_cksum.o \ - f_sched.o \ - f_ecb.o \ + f_cksum.o \ f_parity.o \ + f_sched.o \ f_tables.o \ - d3_cbc.o \ - d3_ecb.o \ - d3_kysched.o \ - d3_procky.o \ - d3_str2ky.o \ - u_nfold.o \ - u_rn_key.o - -OBJS= afsstring2key.$(OBJEXT) \ - cbc_cksum.$(OBJEXT) \ - finish_key.$(OBJEXT) \ - fin_rndkey.$(OBJEXT) \ - init_rkey.$(OBJEXT) \ - process_ky.$(OBJEXT) \ - random_key.$(OBJEXT) \ - string2key.$(OBJEXT) \ - key_sched.$(OBJEXT) \ - weak_key.$(OBJEXT) \ + key_sched.o \ + string2key.o \ + weak_key.o + +OBJS= afsstring2key.$(OBJEXT) \ + d3_cbc.$(OBJEXT) \ + d3_kysched.$(OBJEXT) \ f_cbc.$(OBJEXT) \ - f_cksum.$(OBJEXT) \ - f_sched.$(OBJEXT) \ - f_ecb.$(OBJEXT) \ + f_cksum.$(OBJEXT) \ f_parity.$(OBJEXT) \ + f_sched.$(OBJEXT) \ f_tables.$(OBJEXT) \ - d3_cbc.$(OBJEXT) \ - d3_ecb.$(OBJEXT) \ - d3_kysched.$(OBJEXT) \ - d3_procky.$(OBJEXT) \ - d3_str2ky.$(OBJEXT) \ - u_nfold.$(OBJEXT) \ - u_rn_key.$(OBJEXT) - -SRCS= $(srcdir)/afsstring2key.c \ - $(srcdir)/cbc_cksum.c \ - $(srcdir)/finish_key.c \ - $(srcdir)/fin_rndkey.c \ - $(srcdir)/init_rkey.c \ - $(srcdir)/process_ky.c \ - $(srcdir)/random_key.c \ - $(srcdir)/string2key.c \ + key_sched.$(OBJEXT) \ + string2key.$(OBJEXT) \ + weak_key.$(OBJEXT) + +SRCS= $(srcdir)/afsstring2key.c \ + $(srcdir)/d3_cbc.c \ + $(srcdir)/d3_kysched.c \ + $(srcdir)/f_cbc.c \ + $(srcdir)/f_cksum.c \ + $(srcdir)/f_parity.c \ + $(srcdir)/f_sched.c \ + $(srcdir)/f_tables.c \ $(srcdir)/key_sched.c \ $(srcdir)/weak_key.c \ - $(srcdir)/f_cbc.c \ - $(srcdir)/f_cksum.c \ - $(srcdir)/f_sched.c \ - $(srcdir)/f_ecb.c \ - $(srcdir)/f_parity.c \ - $(srcdir)/f_tables.c \ - $(srcdir)/d3_cbc.c \ - $(srcdir)/d3_ecb.c \ - $(srcdir)/d3_kysched.c \ - $(srcdir)/d3_procky.c \ - $(srcdir)/d3_str2ky.c \ - $(srcdir)/u_nfold.c \ - $(srcdir)/u_rn_key.c + $(srcdir)/string2key.c ##DOS##LIBOBJS = $(OBJS) @@ -93,22 +57,18 @@ includes:: depend depend:: $(SRCS) -# FIXME, this is left from the previous DES implementation. -clean:: - $(RM) fp.c ip.c key_perm.h odd.h p.c p_table.h s_table.h - -verify$(EXEEXT): t_verify.$(OBJEXT) $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o $@ t_verify.$(OBJEXT) process_ky.o key_sched.o \ - ../cryptoconf.o ../des_crc.o $(KRB5_BASE_LIBS) +TOBJS = key_sched.$(OBJEXT) f_sched.$(OBJEXT) f_cbc.$(OBJEXT) \ + f_tables.$(OBJEXT) f_cksum.$(OBJEXT) -destest$(EXEEXT): destest.$(OBJEXT) $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o $@ destest.$(OBJEXT) process_ky.o key_sched.o \ - ../cryptoconf.o ../des_crc.o $(KRB5_BASE_LIBS) +verify$(EXEEXT): t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \ + $(COM_ERR_DEPLIB) + $(CC_LINK) -o $@ t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \ + -lcom_err -t_random$(EXEEXT): t_random.$(OBJEXT) $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o $@ t_random.$(OBJEXT) $(KRB5_BASE_LIBS) +destest$(EXEEXT): destest.$(OBJEXT) $(TOBJS) + $(CC_LINK) -o $@ destest.$(OBJEXT) $(TOBJS) -check-unix:: destest verify +check-unix:: verify destest $(RUN_SETUP) ./verify -z $(RUN_SETUP) ./verify -m $(RUN_SETUP) ./verify @@ -118,6 +78,6 @@ check-windows:: clean:: $(RM) destest$(EXEEXT) verify$(EXEEXT) destest.$(OBJEXT) \ - t_verify.$(OBJEXT) t_random.$(OBJEXT) t_random$(EXEEXT) + t_verify.$(OBJEXT) clean-unix:: clean-libobjs diff --git a/src/lib/crypto/des/afsstring2key.c b/src/lib/crypto/des/afsstring2key.c index 36c42c4823..7eac0807c2 100644 --- a/src/lib/crypto/des/afsstring2key.c +++ b/src/lib/crypto/des/afsstring2key.c @@ -6,6 +6,32 @@ * constructed by Mark Eichin, Cygnus Support, 1995. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include "des_int.h" #include <ctype.h> @@ -13,8 +39,7 @@ static char *afs_crypt PROTOTYPE((char*,char*)); krb5_error_code -mit_afs_string_to_key (eblock, keyblock, data, salt) - const krb5_encrypt_block FAR * eblock; +mit_afs_string_to_key (keyblock, data, salt) krb5_keyblock FAR * keyblock; const krb5_data FAR * data; const krb5_data FAR * salt; @@ -29,7 +54,7 @@ mit_afs_string_to_key (eblock, keyblock, data, salt) register krb5_octet *key = keyblock->contents; if (data->length <= 8) { - char password[9]; /* trailing null for crypt() */ + char password[9]; /* trailing nul for crypt() */ strncpy(password, realm, 8); for (i=0; i<8; i++) if (isupper(password[i])) @@ -39,6 +64,7 @@ mit_afs_string_to_key (eblock, keyblock, data, salt) for (i=0; i<8; i++) if (password[i] == '\0') password[i] = 'X'; + password[8] = '\0'; strncpy(key, (char *) afs_crypt(password, "#~") + 2, 8); for (i=0; i<8; i++) key[i] <<= 1; diff --git a/src/lib/crypto/des/cbc_cksum.c b/src/lib/crypto/des/cbc_cksum.c deleted file mode 100644 index 29a38a0a59..0000000000 --- a/src/lib/crypto/des/cbc_cksum.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * lib/crypto/des/cbc_cksum.c - * - * Copyright 1985, 1986, 1987, 1988, 1990 by the Massachusetts Institute - * of Technology. - * All Rights Reserved. - * - * Under U.S. law, this software may not be exported outside the US - * without license from the U.S. Commerce department. - * - * These routines form the library interface to the DES facilities. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - produces cbc cheksum of sequence "in" of the length "in_length" - with the help of key "key" of size "key_size" (which should be 8); - fills out krb5_checksum structure. - - caller is responsible for allocating & freeing "contents" element in - krb5_checksum structure. - - returns: errors -*/ - -static krb5_error_code mit_des_cbc_checksum - PROTOTYPE((krb5_const krb5_pointer, - krb5_const size_t, - krb5_const krb5_pointer, - krb5_const size_t, - krb5_checksum FAR * )); - -static krb5_error_code mit_des_cbc_verf_cksum - PROTOTYPE ((krb5_const krb5_checksum FAR *, - krb5_const krb5_pointer, - krb5_const size_t, - krb5_const krb5_pointer, - krb5_const size_t )); - -static krb5_error_code -mit_des_cbc_checksum(in, in_length, key, key_size, cksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer key; - krb5_const size_t key_size; - krb5_checksum FAR * cksum; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - - if (cksum->length < sizeof(mit_des_cblock)) - return KRB5_BAD_MSIZE; - if (key_size != sizeof(mit_des_cblock)) - return KRB5_BAD_KEYSIZE; - - if (!(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule)))) - return ENOMEM; - -#define cleanup() { memset((char *)schedule, 0, sizeof(mit_des_key_schedule));\ - free( (char *) schedule); } - - switch (mit_des_key_sched ((krb5_octet *)key, schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - - default: - ; - } - - cksum->checksum_type = CKSUMTYPE_DESCBC; - cksum->length = sizeof(mit_des_cblock); - mit_des_cbc_cksum(in, cksum->contents, in_length, schedule, key); - - cleanup(); - - return 0; -} - -static krb5_error_code -mit_des_cbc_verf_cksum(cksum, in, in_length, key, key_size) - krb5_const krb5_checksum FAR * cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer key; - krb5_const size_t key_size; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - mit_des_cblock contents; - krb5_error_code retval; - - if (key_size != sizeof(mit_des_cblock)) - return KRB5_BAD_KEYSIZE; - - if (!(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule)))) - return ENOMEM; - -#define cleanup() { memset((char *)schedule, 0, sizeof(mit_des_key_schedule));\ - free( (char *) schedule); } - - switch (mit_des_key_sched ((krb5_octet *)key, schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - - default: - ; - } - - mit_des_cbc_cksum(in, contents, in_length, schedule, key); - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_DESCBC) { - if (cksum->length == sizeof(mit_des_cblock)) { - if (memcmp((char *) cksum->contents, - (char *) contents, - sizeof(mit_des_cblock))) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - cleanup(); - - return retval; -} - -krb5_checksum_entry krb5_des_cbc_cksumtable_entry = { - 0, - mit_des_cbc_checksum, - mit_des_cbc_verf_cksum, - sizeof(mit_des_cblock), - 1, /* is collision proof */ - 1, /* is keyed */ -}; diff --git a/src/lib/crypto/des/d3_ecb.c b/src/lib/crypto/des/d3_ecb.c deleted file mode 100644 index 306f97dd60..0000000000 --- a/src/lib/crypto/des/d3_ecb.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "des_int.h" -#include "f_tables.h" - -/* - * Triple-DES ECB encryption mode. - */ - -int -mit_des3_ecb_encrypt(in, out, sched1, sched2, sched3, encrypt) - const mit_des_cblock FAR *in; - mit_des_cblock FAR *out; - mit_des_key_schedule sched1, sched2, sched3; - int encrypt; -{ - if (encrypt) { - mit_des_ecb_encrypt(in, out, sched1, encrypt); - mit_des_ecb_encrypt(out, out, sched2, !encrypt); - mit_des_ecb_encrypt(out, out, sched3, encrypt); - } else { - mit_des_ecb_encrypt(in, out, sched3, encrypt); - mit_des_ecb_encrypt(out, out, sched2, !encrypt); - mit_des_ecb_encrypt(out, out, sched1, encrypt); - } - return 0; -} diff --git a/src/lib/crypto/des/d3_procky.c b/src/lib/crypto/des/d3_procky.c deleted file mode 100644 index 9c969a823b..0000000000 --- a/src/lib/crypto/des/d3_procky.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code -mit_des3_process_key (eblock, keyblock) - krb5_encrypt_block * eblock; - const krb5_keyblock * keyblock; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - - if ((keyblock->enctype != ENCTYPE_DES3_CBC_SHA) && - (keyblock->enctype != ENCTYPE_DES3_CBC_RAW)) - return KRB5_PROG_ETYPE_NOSUPP; - - if (keyblock->length != sizeof (mit_des3_cblock)) - return KRB5_BAD_KEYSIZE; - - if ( !(schedule = (struct mit_des_ks_struct *) malloc(3*sizeof(mit_des_key_schedule))) ) - return ENOMEM; -#define cleanup() { free( (char *) schedule); } - - switch (mit_des3_key_sched (*(mit_des3_cblock *)keyblock->contents, - *(mit_des3_key_schedule *)schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - } - - eblock->key = (krb5_keyblock *) keyblock; - eblock->priv = (krb5_pointer) schedule; - eblock->priv_size = (krb5_int32) 3*sizeof(mit_des_key_schedule); - - return 0; -} diff --git a/src/lib/crypto/des/d3_str2ky.c b/src/lib/crypto/des/d3_str2ky.c deleted file mode 100644 index ed9f5183d2..0000000000 --- a/src/lib/crypto/des/d3_str2ky.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - * Triple-DES string-to-key algorithm - * - * 168-fold the input string (appended with any salt), and treat the resulting - * 168 bits as three DES keys sans parity. Process each set of 56 bits into - * a usable DES key with odd parity, and twice encrypt the set of three usable - * DES keys using Triple-DES CBC mode. The result is then treated as three - * DES keys, and should be corrected for parity. Any DES key that is weak or - * semi-weak is to be corrected by eXclusive-ORing with 00000000000000F0. - */ - -static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -krb5_error_code -mit_des3_string_to_key (eblock, keyblock, data, salt) -const krb5_encrypt_block FAR * eblock; -krb5_keyblock FAR * keyblock; -const krb5_data FAR * data; -const krb5_data FAR * salt; -{ - char *copystr; - mit_des_cblock *key; - unsigned int j; - - int length; - mit_des3_key_schedule ks; - krb5_enctype enctype = eblock->crypto_entry->proto_enctype; - - if ((enctype == ENCTYPE_DES3_CBC_SHA) || - (enctype == ENCTYPE_DES3_CBC_RAW)) - keyblock->length = sizeof(mit_des3_cblock); - else - return (KRB5_PROG_ETYPE_NOSUPP); - - if ( !(keyblock->contents = (krb5_octet *)malloc(keyblock->length)) ) - return(ENOMEM); - - keyblock->magic = KV5M_KEYBLOCK; - keyblock->enctype = enctype; - key = (mit_des_cblock *)keyblock->contents; - - if (salt) - length = data->length + salt->length; - else - length = data->length; - - if (length < keyblock->length) - length = keyblock->length; - - copystr = malloc((size_t) length); - if (!copystr) { - free(keyblock->contents); - keyblock->contents = 0; - return ENOMEM; - } - - memset(copystr, 0, length); - memcpy(copystr, (char *) data->data, data->length); - if (salt) - memcpy(copystr + data->length, (char *)salt->data, salt->length); - - /* n-fold into des3 key sans parity */ - if (mit_des_n_fold(copystr, length, keyblock->contents, - keyblock->length * 7 / 8)) - return EINVAL; - - /* Add space for parity (low bit) */ - for (j = keyblock->length; j--; ) { - register int k; - - k = (8-(j%8)) & 7; - keyblock->contents[j] = - ((keyblock->contents[j*7/8] << k) & 0xfe) + - ((k>1) ? keyblock->contents[j*7/8 +1] >> (8-k) : 0); - } - - /* fix key parity */ - for (j = 0; j < keyblock->length/sizeof(mit_des_cblock); j++) { - mit_des_fixup_key_parity(key[j]); - if (mit_des_is_weak_key(key[j])) - ((krb5_octet *)(key[j]))[7] ^= 0xf0; - } - - /* Now, CBC encrypt with itself */ - (void) mit_des3_key_sched(*((mit_des3_cblock *)key), ks); - (void) mit_des3_cbc_encrypt(key, key, keyblock->length, - ((mit_des_key_schedule *)ks)[0], - ((mit_des_key_schedule *)ks)[1], - ((mit_des_key_schedule *)ks)[2], - zero_ivec, TRUE); - (void) mit_des3_cbc_encrypt(key, key, keyblock->length, - ((mit_des_key_schedule *)ks)[0], - ((mit_des_key_schedule *)ks)[1], - ((mit_des_key_schedule *)ks)[2], - key[2], TRUE); - - /* erase key_sked */ - memset((char *)ks, 0, sizeof(ks)); - - /* clean & free the input string */ - memset(copystr, 0, (size_t) length); - krb5_xfree(copystr); - - /* now fix up key parity again */ - for (j = 0; j < keyblock->length/sizeof(mit_des_cblock); j++) { - mit_des_fixup_key_parity(key[j]); - if (mit_des_is_weak_key(key[j])) - ((krb5_octet *)(key[j]))[7] ^= 0xf0; - } - - return 0; -} diff --git a/src/lib/crypto/des/des.h b/src/lib/crypto/des/des.h deleted file mode 100644 index bd0a30b370..0000000000 --- a/src/lib/crypto/des/des.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * include/des.h - * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * - * For copying and distribution information, please see the file - * <mit-copyright.h>. - * - * Include file for the Data Encryption Standard library. - */ - -/* only do the whole thing once */ -#ifndef DES_DEFS -#define DES_DEFS - -#include "k5-int.h" - -#ifndef DES_INT32 -#ifdef SIZEOF_INT -#if SIZEOF_INT >= 4 -#define DES_INT32 int -#else -#define DES_INT32 long -#endif -#else /* !defined(SIZEOF_INT) */ -#include <limits.h> -#if (UINT_MAX >= 0xffffffff) -#define DES_INT32 int -#else -#define DES_INT32 long -#endif -#endif /* !defined(SIZEOF_INT) */ -#endif /* !defined(DES_INT32) */ - -#ifndef DES_UINT32 -#define DES_UINT32 unsigned DES_INT32 -#endif - -#ifndef NCOMPAT -#define C_Block des_cblock -#define Key_schedule des_key_schedule -#define ENCRYPT DES_ENCRYPT -#define DECRYPT DES_DECRYPT -#define KEY_SZ DES_KEY_SZ -#define string_to_key des_string_to_key -#define read_pw_string des_read_pw_string -#define random_key des_random_key -#define pcbc_encrypt des_pcbc_encrypt -#define key_sched des_key_sched -#define cbc_encrypt des_cbc_encrypt -#define cbc_cksum des_cbc_cksum -#define C_Block_print des_cblock_print -#define quad_cksum des_quad_cksum -typedef struct des_ks_struct bit_64; -#endif - -#define des_cblock_print(x) des_cblock_print_file(x, stdout) - -#endif /* DES_DEFS */ diff --git a/src/lib/crypto/des/des_int.h b/src/lib/crypto/des/des_int.h index df8e9ca1ed..0f81908615 100644 --- a/src/lib/crypto/des/des_int.h +++ b/src/lib/crypto/des/des_int.h @@ -24,6 +24,32 @@ * Private include file for the Data Encryption Standard library. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + /* only do the whole thing once */ #ifndef DES_INTERNAL_DEFS #define DES_INTERNAL_DEFS @@ -112,8 +138,7 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE) /* afsstring2key.c */ extern krb5_error_code mit_afs_string_to_key - PROTOTYPE((const krb5_encrypt_block FAR *eblock, - krb5_keyblock FAR *keyblock, + PROTOTYPE((krb5_keyblock FAR *keyblock, const krb5_data FAR *data, const krb5_data FAR *salt)); diff --git a/src/lib/crypto/des/destest.c b/src/lib/crypto/des/destest.c index 1e077a4239..bf442e8698 100644 --- a/src/lib/crypto/des/destest.c +++ b/src/lib/crypto/des/destest.c @@ -25,20 +25,43 @@ */ -#include "k5-int.h" +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "des_int.h" #include "com_err.h" -extern int errno; -extern mit_des_ecb_encrypt(); - #include <stdio.h> - void convert PROTOTYPE((char *, unsigned char [])); void des_cblock_print_file PROTOTYPE((mit_des_cblock, FILE *)); +char zeroblock[8] = {0,0,0,0,0,0,0,0}; + void main(argc, argv) int argc; @@ -46,38 +69,23 @@ char *argv[]; { char block1[17], block2[17], block3[17]; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_context context; mit_des_cblock key, input, output, output2; - krb5_error_code retval; + mit_des_key_schedule sched; int num = 0; + int retval; int error = 0; - /* This is a crock and we know it... We win because - none of these tests rely on a valid context pointer */ - context = 0; - - /* do some initialisation */ - initialize_krb5_error_table(); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC); - keyblock.magic = KV5M_KEYBLOCK; - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof (mit_des_cblock); - keyblock.contents = (krb5_octet *)key; while (scanf("%16s %16s %16s", block1, block2, block3) == 3) { convert(block1, key); convert(block2, input); convert(block3, output); - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des test", retval, "can't process key"); - exit(-1); + if (retval = mit_des_key_sched(key, sched)) { + fprintf(stderr, "des test: can't process key"); + exit(1); } - mit_des_ecb_encrypt(&input, &output2, - (struct mit_des_ks_struct *)eblock.priv,1); + mit_des_cbc_encrypt(&input, &output2, 8, sched, zeroblock, 1); if (memcmp((char *)output2, (char *)output, 8)) { fprintf(stderr, @@ -91,8 +99,7 @@ char *argv[]; /* * Now try decrypting.... */ - mit_des_ecb_encrypt(&output, &output2, - (struct mit_des_ks_struct *)eblock.priv,0); + mit_des_cbc_encrypt(&output, &output2, 8, sched, zeroblock, 0); if (memcmp((char *)output2, (char *)input, 8)) { fprintf(stderr, @@ -103,10 +110,6 @@ char *argv[]; error++; } - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key"); - exit(-1); - } num++; } @@ -157,7 +160,6 @@ unsigned char cblock[]; * Fake out the DES library, for the purposes of testing. */ -#include "des.h" #include "des_int.h" int diff --git a/src/lib/crypto/des/f_README b/src/lib/crypto/des/f_README deleted file mode 100644 index 0d381e3739..0000000000 --- a/src/lib/crypto/des/f_README +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -Sorry about the poor quality of installation instructions. Included -here are replacements for the DES portions of Eric Young's kerberos -DES library replacement. To use this you will need his distribution. -Untar the latter and: - -(1) Copy all .c and .h files into the distribution directory. This will - overwrite some files and add others. - -(2) Apply the patch included here to set_key.c in the distribution directory. - -(3) Edit the Imakefile (or the Makefile) to include the following files - on the SRCS= line: - - des_tables.c ecb_buffer.c make_sched.c - - Add the following files to the OBJS= line: - - des_tables.o ecb_buffer.o make_sched.o - - Add the following file to the CODE= line: - - des_tables.h - -Recompile and you're done. - -The salient differences between this DES and Eric Young's are as follows: - -(1) There are no dependencies on byte ordering, the ability to do - unaligned loads and stores, or any other machine dependencies - that I know of. There are no #ifdef's. The code could probably - be made faster by adding such things, but not enough to be worth - it. - -(2) Combined S and P tables are used for the inner loop of the cipher - routine and the E expansion is computed on the fly, like Eric - Young's code, but the computation is reordered from the standard - to save instructions. - -(3) The initial and final permutations are table driven, and take - about the same amount of work as a single round of the inner - loop (i.e. only about 12% of the work done for an ecb encryption - is spent in the IP and FP code). - -(4) Since NTP (for which this DES was originally implemented) uses - lots of keys to encrypt small things, the key permutation code - has been well worked over and is quite speedy (the amount of - work required to permute a key is on the order of that required - to do a single ECB encryption, more or less). - -(5) Since the code required to do an ECB encryption using the tables - is actually fairly compact, even with lots of inlining, it was - implemented as a macro and is expanded in situ where needed. - -On the one machine I ran a comparison on this code ran 80% faster than -Eric's, compiled into a slightly smaller space, and did pass destest. -I suspect this stuff is also faster, and not a lot larger, than the -library MIT doesn't export with kerberos. You mileage may vary. - -The silly copyright was a (probably ineffective) afterthought. If it -really inconveniences you give me a call. diff --git a/src/lib/crypto/des/f_ecb.c b/src/lib/crypto/des/f_ecb.c deleted file mode 100644 index a1d1dcb0c7..0000000000 --- a/src/lib/crypto/des/f_ecb.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -/* - * des_ecb_encrypt.c - do an encryption in ECB mode - */ -#include "des_int.h" -#include "f_tables.h" - -/* - * des_ecb_encrypt - {en,de}crypt a block in ECB mode - */ -int -mit_des_ecb_encrypt(in, out, schedule, encrypt) - const mit_des_cblock *in; - mit_des_cblock *out; - mit_des_key_schedule schedule; - int encrypt; -{ - register unsigned DES_INT32 left, right; - register unsigned DES_INT32 temp; - register int i; - - { - /* - * Need a temporary for copying the data in - */ - register unsigned char *datap; - - /* - * Copy the input block into the registers - */ - datap = (unsigned char *)in; - GET_HALF_BLOCK(left, datap); - GET_HALF_BLOCK(right, datap); - } - - /* - * Do the initial permutation. - */ - DES_INITIAL_PERM(left, right, temp); - - /* - * Now the rounds. Use different code depending on whether it - * is an encryption or a decryption (gross, should keep both - * sets of keys in the key schedule instead). - */ - if (encrypt) { - register unsigned DES_INT32 *kp; - - kp = (unsigned DES_INT32 *)schedule; - for (i = 0; i < 8; i++) { - DES_SP_ENCRYPT_ROUND(left, right, temp, kp); - DES_SP_ENCRYPT_ROUND(right, left, temp, kp); - } - } else { - register unsigned DES_INT32 *kp; - - /* - * Point kp past end of schedule - */ - kp = ((unsigned DES_INT32 *)schedule) + (2 * 16);; - for (i = 0; i < 8; i++) { - DES_SP_DECRYPT_ROUND(left, right, temp, kp); - DES_SP_DECRYPT_ROUND(right, left, temp, kp); - } - } - - /* - * Do the final permutation - */ - DES_FINAL_PERM(left, right, temp); - - /* - * Finally, copy the result out a byte at a time - */ - { - register unsigned char *datap; - - datap = (unsigned char *)out; - PUT_HALF_BLOCK(left, datap); - PUT_HALF_BLOCK(right, datap); - } - - /* - * return nothing - */ - return (0); -} diff --git a/src/lib/crypto/des/f_pcbc.c b/src/lib/crypto/des/f_pcbc.c deleted file mode 100644 index cb445446b9..0000000000 --- a/src/lib/crypto/des/f_pcbc.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 1990 Dennis Ferguson. All rights reserved. - * - * Commercial use is permitted only if products which are derived from - * or include this software are made available for purchase and/or use - * in Canada. Otherwise, redistribution and use in source and binary - * forms are permitted. - */ - -/* - * des_pcbc_encrypt.c - encrypt a string of characters in error propagation mode - */ -#include "des_int.h" -#include "f_tables.h" - -/* - * des_pcbc_encrypt - {en,de}crypt a stream in PCBC mode - */ -int -mit_des_pcbc_encrypt(in, out, length, schedule, ivec, encrypt) - mit_des_cblock *in; - mit_des_cblock *out; - long length; - mit_des_key_schedule schedule; - mit_des_cblock ivec; - int encrypt; -{ - register unsigned DES_INT32 left, right; - register unsigned DES_INT32 temp; - register unsigned DES_INT32 *kp; - register unsigned char *ip, *op; - - /* - * Copy the key pointer, just once - */ - kp = (unsigned DES_INT32 *)schedule; - - /* - * Deal with encryption and decryption separately. - */ - if (encrypt) { - register unsigned DES_INT32 plainl; - register unsigned DES_INT32 plainr; - - /* - * Initialize left and right with the contents of the initial - * vector. - */ - ip = (unsigned char *)ivec; - GET_HALF_BLOCK(left, ip); - GET_HALF_BLOCK(right, ip); - - /* - * Suitably initialized, now work the length down 8 bytes - * at a time. - */ - ip = (unsigned char *)in; - op = (unsigned char *)out; - while (length > 0) { - /* - * Get block of input. If the length is - * greater than 8 this is straight - * forward. Otherwise we have to fart around. - */ - if (length > 8) { - GET_HALF_BLOCK(plainl, ip); - GET_HALF_BLOCK(plainr, ip); - left ^= plainl; - right ^= plainr; - length -= 8; - } else { - /* - * Oh, shoot. We need to pad the - * end with zeroes. Work backwards - * to do this. We know this is the - * last block, though, so we don't have - * to save the plain text. - */ - ip += (int) length; - switch(length) { - case 8: - right ^= *(--ip) & FF_UINT32; - case 7: - right ^= (*(--ip) & FF_UINT32) << 8; - case 6: - right ^= (*(--ip) & FF_UINT32) << 16; - case 5: - right ^= (*(--ip) & FF_UINT32) << 24; - case 4: - left ^= *(--ip) & FF_UINT32; - case 3: - left ^= (*(--ip) & FF_UINT32) << 8; - case 2: - left ^= (*(--ip) & FF_UINT32) << 16; - case 1: - left ^= (*(--ip) & FF_UINT32) << 24; - break; - } - length = 0; - } - - /* - * Encrypt what we have - */ - DES_DO_ENCRYPT(left, right, temp, kp); - - /* - * Copy the results out - */ - PUT_HALF_BLOCK(left, op); - PUT_HALF_BLOCK(right, op); - - /* - * Xor with the old plain text - */ - left ^= plainl; - right ^= plainr; - } - } else { - /* - * Decrypting is harder than encrypting because of - * the necessity of remembering a lot more things. - * Should think about this a little more... - */ - unsigned DES_INT32 ocipherl, ocipherr; - unsigned DES_INT32 cipherl, cipherr; - - if (length <= 0) - return 0; - - /* - * Prime the old cipher with ivec. - */ - ip = (unsigned char *)ivec; - GET_HALF_BLOCK(ocipherl, ip); - GET_HALF_BLOCK(ocipherr, ip); - - /* - * Now do this in earnest until we run out of length. - */ - ip = (unsigned char *)in; - op = (unsigned char *)out; - for (;;) { /* check done inside loop */ - /* - * Read a block from the input into left and - * right. Save this cipher block for later. - */ - GET_HALF_BLOCK(left, ip); - GET_HALF_BLOCK(right, ip); - cipherl = left; - cipherr = right; - - /* - * Decrypt this. - */ - DES_DO_DECRYPT(left, right, temp, kp); - - /* - * Xor with the old cipher to get plain - * text. Output 8 or less bytes of this. - */ - left ^= ocipherl; - right ^= ocipherr; - if (length > 8) { - length -= 8; - PUT_HALF_BLOCK(left, op); - PUT_HALF_BLOCK(right, op); - /* - * Save current cipher block here - */ - ocipherl = cipherl ^ left; - ocipherr = cipherr ^ right; - } else { - /* - * Trouble here. Start at end of output, - * work backwards. - */ - op += (int) length; - switch(length) { - case 8: - *(--op) = (unsigned char) (right & 0xff); - case 7: - *(--op) = (unsigned char) ((right >> 8) & 0xff); - case 6: - *(--op) = (unsigned char) ((right >> 16) & 0xff); - case 5: - *(--op) = (unsigned char) ((right >> 24) & 0xff); - case 4: - *(--op) = (unsigned char) (left & 0xff); - case 3: - *(--op) = (unsigned char) ((left >> 8) & 0xff); - case 2: - *(--op) = (unsigned char) ((left >> 16) & 0xff); - case 1: - *(--op) = (unsigned char) ((left >> 24) & 0xff); - break; - } - break; /* we're done */ - } - } - } - - /* - * Done, return nothing. - */ - return 0; -} diff --git a/src/lib/crypto/des/fin_rndkey.c b/src/lib/crypto/des/fin_rndkey.c deleted file mode 100644 index 7b8a2c385c..0000000000 --- a/src/lib/crypto/des/fin_rndkey.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * lib/crypto/des/fin_rndkey.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * Copyright 1996 by Lehman Brothers, Inc. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. or Lehman Brothers not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. M.I.T. and Lehman Brothers - * make no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied - * warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - free any resources held by "seed" and assigned by init_random_key() - */ - -krb5_error_code mit_des_finish_random_key (eblock, p_state) - const krb5_encrypt_block * eblock; - krb5_pointer * p_state; -{ - mit_des_random_state * state = *p_state; - - if (! state) return 0; - - if (state->sequence.data) { - memset((char *)state->sequence.data, 0, state->sequence.length); - krb5_xfree(state->sequence.data); - } - - mit_des_finish_key(&state->eblock); - - krb5_xfree(state); - *p_state = 0; - return 0; -} diff --git a/src/lib/crypto/des/finish_key.c b/src/lib/crypto/des/finish_key.c deleted file mode 100644 index e7e9e13ae3..0000000000 --- a/src/lib/crypto/des/finish_key.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * lib/crypto/des/finish_key.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - does any necessary clean-up on the eblock (such as releasing - resources held by eblock->priv). - - returns: errors - */ - -krb5_error_code -mit_des_finish_key (eblock) - krb5_encrypt_block FAR * eblock; -{ - if (eblock->priv) { - memset((char *)eblock->priv, 0, (size_t) eblock->priv_size); - free(eblock->priv); - } - eblock->priv = 0; - eblock->priv_size = 0; - /* free/clear other stuff here? */ - return 0; -} diff --git a/src/lib/crypto/des/init_rkey.c b/src/lib/crypto/des/init_rkey.c deleted file mode 100644 index 5096647ec6..0000000000 --- a/src/lib/crypto/des/init_rkey.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * lib/crypto/des/init_rkey.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - initialize the random key generator using the encryption key, - "seedblock", and allocating private sequence information, filling - in "seed" with the address of such information. - "seed" is later passed to the random_key() function to provide - sequence information. - */ - -#ifndef min -#define min(a,b) (((a) > (b)) ? (b) : (a)) -#endif - -krb5_error_code -mit_des_init_random_key (eblock, seedblock, state) - const krb5_encrypt_block * eblock; - const krb5_keyblock * seedblock; - krb5_pointer * state; -{ - mit_des_random_state * p_state = 0; - krb5_keyblock *new_key; - krb5_enctype enctype = eblock->crypto_entry->proto_enctype; - krb5_error_code kret = 0; - krb5_address **addrs = 0; - krb5_data seed; - krb5_int32 now; - krb5_int32 unow; - unsigned char *cp; - - switch (enctype) - { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - enctype = ENCTYPE_DES_CBC_RAW; - break; - - case ENCTYPE_DES3_CBC_SHA: - case ENCTYPE_DES3_CBC_RAW: - enctype = ENCTYPE_DES3_CBC_RAW; - break; - - default: - return KRB5_BAD_ENCTYPE; - } - - p_state = (mit_des_random_state *) malloc(sizeof(mit_des_random_state)); - *state = (krb5_pointer) p_state; - - if (! p_state) { - kret = ENOMEM; - goto cleanup; - } - - memset(p_state, 0, sizeof(*p_state)); - p_state->eblock.crypto_entry = krb5_enctype_array[enctype]->system; - p_state->sequence.length = p_state->eblock.crypto_entry->keysize; - p_state->sequence.data = (krb5_pointer) malloc(p_state->sequence.length); - - if (! p_state->sequence.data) { - kret = ENOMEM; - goto cleanup; - } - - /* - * Generate a temporary value that is based on the - * input seed and the hostid (sequence number) - * such that it gives no useful information about the input. - * - * Then use the temporary value as the new seed and the current - * time as a sequence number to give us a stream that was not - * previously used. - * - * This result will be the seed for the random number stream - * (the sequence number will start at zero). - */ - - /* seed = input */ - seed.data = seedblock->contents; - seed.length = seedblock->length; - kret = mit_des_set_random_generator_seed(&seed, p_state); - if (kret) goto cleanup; - - /* sequence = hostid */ - if (!krb5_crypto_os_localaddr(&addrs) && addrs && *addrs) { - memcpy((char *)p_state->sequence.data, (char *)addrs[0]->contents, - min(p_state->sequence.length, addrs[0]->length)); - /* XXX may not do all of the sequence number. */ - } - if (addrs) { - /* can't use krb5_free_addresses due to circular dependencies in - libraries */ - register krb5_address **addr2; - for (addr2 = addrs; *addr2; addr2++) { - krb5_xfree((*addr2)->contents); - krb5_xfree(*addr2); - } - krb5_xfree(addrs); - } - - /* tmp.seed = random(input,hostid) */ - kret = mit_des_random_key(NULL, p_state, &new_key); - if (kret) goto cleanup; - seed.data = new_key->contents; - seed.length = new_key->length; - kret = mit_des_set_random_generator_seed(&seed, p_state); - (void) memset(new_key->contents, 0, new_key->length); - krb5_xfree(new_key->contents); - krb5_xfree(new_key); - if (kret) goto cleanup; - - /* sequence = time */ - (void) krb5_crypto_us_timeofday(&now, &unow); - cp = p_state->sequence.data; - *cp++ = (now >> 24) & 0xff; - *cp++ = (now >> 16) & 0xff; - *cp++ = (now >> 8) & 0xff; - *cp++ = now & 0xff; - *cp++ = (unow >> 24) & 0xff; - *cp++ = (unow >> 16) & 0xff; - *cp++ = (unow >> 8) & 0xff; - *cp++ = unow &0xff; - - /* seed = random(tmp.seed, time) */ - kret = mit_des_random_key(NULL, p_state, &new_key); - if (kret) goto cleanup; - seed.data = new_key->contents; - seed.length = new_key->length; - kret = mit_des_set_random_generator_seed(&seed, p_state); - (void) memset(new_key->contents, 0, new_key->length); - krb5_xfree(new_key->contents); - krb5_xfree(new_key); - if (kret) goto cleanup; - - return 0; - -cleanup: - if (kret) - mit_des_finish_random_key(eblock, state); - return kret; -} diff --git a/src/lib/crypto/des/process_ky.c b/src/lib/crypto/des/process_ky.c deleted file mode 100644 index 64cef57ad6..0000000000 --- a/src/lib/crypto/des/process_ky.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * lib/crypto/des/process_ky.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -/* - does any necessary key preprocessing (such as computing key - schedules for DES). - eblock->crypto_entry must be set by the caller; the other elements - of eblock are to be assigned by this function. - [in particular, eblock->key must be set by this function if the key - is needed in raw form by the encryption routine] - - The caller may not move or reallocate "keyblock" before calling - finish_key on "eblock" - - returns: errors - */ - -krb5_error_code -mit_des_process_key (eblock, keyblock) - krb5_encrypt_block * eblock; - const krb5_keyblock * keyblock; -{ - struct mit_des_ks_struct *schedule; /* pointer to key schedules */ - - if (keyblock->length != sizeof (mit_des_cblock)) - return KRB5_BAD_KEYSIZE; - - if ( !(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule))) ) - return ENOMEM; -#define cleanup() { free( (char *) schedule); } - - switch (mit_des_key_sched (keyblock->contents, schedule)) { - case -1: - cleanup(); - return KRB5DES_BAD_KEYPAR; - - case -2: - cleanup(); - return KRB5DES_WEAK_KEY; - - default: - eblock->key = (krb5_keyblock *) keyblock; - eblock->priv = (krb5_pointer) schedule; - eblock->priv_size = (krb5_int32) sizeof(mit_des_key_schedule); - return 0; - } -} diff --git a/src/lib/crypto/des/random_key.c b/src/lib/crypto/des/random_key.c deleted file mode 100644 index 1dc4600b4f..0000000000 --- a/src/lib/crypto/des/random_key.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * lib/crypto/des/random_key.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * Copyright 1996 by Lehman Brothers, Inc. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. or Lehman Brothers not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. M.I.T. and Lehman Brothers - * make no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied - * warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -static void mit_des_generate_random_key - PROTOTYPE((mit_des_random_state * state, krb5_keyblock * randkey)); - - -/* - generate a random encryption key, allocating storage for it and - filling in the keyblock address in *keyblock - */ - -krb5_error_code -mit_des_random_key (eblock, state, keyblock) - const krb5_encrypt_block * eblock; - krb5_pointer state; - krb5_keyblock ** keyblock; -{ - krb5_keyblock *randkey; - int keysize = ((mit_des_random_state *)state)->eblock.crypto_entry->keysize; - - if (eblock == NULL) - /* We are being called from the random number initialization routine */ - eblock = &((mit_des_random_state *)state)->eblock; - - if (!(randkey = (krb5_keyblock *)malloc(sizeof(*randkey)))) - return ENOMEM; - if (!(randkey->contents = (krb5_octet *)malloc(keysize))) { - krb5_xfree(randkey); - return ENOMEM; - } - randkey->magic = KV5M_KEYBLOCK; - randkey->length = keysize; - randkey->enctype = eblock->crypto_entry->proto_enctype; - - do { - mit_des_generate_random_key(state, randkey); - mit_des_fixup_keyblock_parity(randkey); - } while (mit_des_is_weak_keyblock(randkey)); - - *keyblock = randkey; - return 0; -} - -static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -static void -mit_des_generate_random_key(state, randkey) - mit_des_random_state * state; - krb5_keyblock * randkey; -{ - krb5_encrypt_block *eblock = &state->eblock; - int i; - - (* state->eblock.crypto_entry->encrypt_func) - (state->sequence.data /*in*/, randkey->contents /*out*/, - state->sequence.length, eblock, zero_ivec); - if (state->sequence.length > sizeof(mit_des_cblock)) - (* state->eblock.crypto_entry->encrypt_func) - (randkey->contents /*in*/, randkey->contents /*out*/, - randkey->length, eblock, - randkey->contents + randkey->length - sizeof(mit_des_cblock)); - - /* Increment the sequence number, with wraparound (LSB) */ - for (i = 0; i < state->sequence.length; i++) { - state->sequence.data[i] = (state->sequence.data[i] + 1) & 0xff; - if (state->sequence.data[i]) - break; - } -} diff --git a/src/lib/crypto/des/string2key.c b/src/lib/crypto/des/string2key.c index 8a2b1415b7..79b7c9cbd8 100644 --- a/src/lib/crypto/des/string2key.c +++ b/src/lib/crypto/des/string2key.c @@ -21,6 +21,32 @@ * or implied warranty. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include "des_int.h" @@ -41,8 +67,7 @@ */ krb5_error_code -mit_des_string_to_key (eblock, keyblock, data, salt) -const krb5_encrypt_block FAR * eblock; +mit_des_string_to_key_int (keyblock, data, salt) krb5_keyblock FAR * keyblock; const krb5_data FAR * data; const krb5_data FAR * salt; @@ -59,28 +84,19 @@ const krb5_data FAR * salt; register char *p_char; char k_char[64]; mit_des_key_schedule key_sked; - krb5_enctype enctype = eblock->crypto_entry->proto_enctype; #ifndef min #define min(A, B) ((A) < (B) ? (A): (B)) #endif - if ((enctype != ENCTYPE_DES_CBC_CRC) && (enctype != ENCTYPE_DES_CBC_MD4) && - (enctype != ENCTYPE_DES_CBC_MD5) && (enctype != ENCTYPE_DES_CBC_RAW)) - return (KRB5_PROG_ETYPE_NOSUPP); - - if ( !(keyblock->contents = (krb5_octet *)malloc(sizeof(mit_des_cblock))) ) - return(ENOMEM); - keyblock->magic = KV5M_KEYBLOCK; keyblock->length = sizeof(mit_des_cblock); - keyblock->enctype = eblock->crypto_entry->proto_enctype; key = keyblock->contents; if (salt) { if (salt->length == -1) { /* cheat and do AFS string2key instead */ - return mit_afs_string_to_key (eblock, keyblock, data, salt); + return mit_afs_string_to_key (keyblock, data, salt); } else length = data->length + salt->length; } diff --git a/src/lib/crypto/des/t_random.c b/src/lib/crypto/des/t_random.c deleted file mode 100644 index bc013bdab7..0000000000 --- a/src/lib/crypto/des/t_random.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * lib/crypto/des/t_random.c - * - * Copyright 1996 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * Test a DES implementation against known inputs & outputs - */ - -#include "k5-int.h" -#include "des_int.h" -#include <stdio.h> -#include "com_err.h" - -extern krb5_cryptosystem_entry mit_des_cryptosystem_entry; - -char *progname; -int nflag = 2; -int vflag; -int mflag; -int zflag; -int pid; -int mit_des_debug; - -krb5_data kdata; - -unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f }; -unsigned char zerokey[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - -void print_key(key) - krb5_keyblock *key; -{ - int i; - - printf("key type: %d, length = %d, contents =", key->enctype, - key->length); - for (i=0; i < key->length; i++) { - printf(" %02x", key->contents[i]); - } - printf("\n"); -} - -/* - * Can also add : - * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?) - */ - -void -main(argc,argv) - int argc; - char *argv[]; -{ - /* Local Declarations */ - krb5_context context; - krb5_encrypt_block eblock; - krb5_keyblock keyblock, *randkey; - void *random_seed = 0; - -#ifdef WINDOWS - /* Set screen window buffer to infinite size -- MS default is tiny. */ - _wsetscreenbuf (fileno (stdout), _WINBUFINF); -#endif - - /* do some initialisation */ - krb5_init_context(&context); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC); - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); - - keyblock.contents = key2; - - printf("init_random: "); - print_key(&keyblock); - krb5_init_random_key(context, &eblock, &keyblock, &random_seed); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_finish_random_key(context, &eblock, &random_seed); - - keyblock.contents = zerokey; - - printf("\n\ninit_random: "); - print_key(&keyblock); - - krb5_init_random_key(context, &eblock, &keyblock, &random_seed); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_random_key(context, &eblock, random_seed, &randkey); - print_key(randkey); - krb5_free_keyblock(context, randkey); - krb5_finish_random_key(context, &eblock, &random_seed); - - krb5_free_context(context); -} - diff --git a/src/lib/crypto/des/t_verify.c b/src/lib/crypto/des/t_verify.c index 82a73e21fb..e8a7dc0eed 100644 --- a/src/lib/crypto/des/t_verify.c +++ b/src/lib/crypto/des/t_verify.c @@ -28,13 +28,37 @@ * -1 ==> error */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include "des_int.h" #include <stdio.h> #include "com_err.h" -extern krb5_cryptosystem_entry mit_des_cryptosystem_entry; - char *progname; int nflag = 2; int vflag; @@ -43,10 +67,6 @@ int zflag; int pid; int mit_des_debug; -krb5_encrypt_block eblock; -krb5_keyblock keyblock; -krb5_data kdata; - unsigned char cipher_text[64]; unsigned char clear_text[64] = "Now is the time for all " ; unsigned char clear_text2[64] = "7654321 Now is the time for "; @@ -56,23 +76,6 @@ unsigned char zero_text[8] = {0x0,0,0,0,0,0,0,0}; unsigned char msb_text[8] = {0x0,0,0,0, 0,0,0,0x40}; /* to ANSI MSB */ unsigned char *input; -unsigned char *nfold_in[] = { - "basch", - "eichin", - "sommerfeld", - "MASSACHVSETTS INSTITVTE OF TECHNOLOGY" }; - -unsigned char nfold_192[4][24] = { - { 0x1a, 0xab, 0x6b, 0x42, 0x96, 0x4b, 0x98, 0xb2, 0x1f, 0x8c, 0xde, 0x2d, - 0x24, 0x48, 0xba, 0x34, 0x55, 0xd7, 0x86, 0x2c, 0x97, 0x31, 0x64, 0x3f }, - { 0x65, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x4b, 0x73, 0x2b, 0x4b, 0x1b, 0x43, - 0xda, 0x1a, 0x5b, 0x99, 0x5a, 0x58, 0xd2, 0xc6, 0xd0, 0xd2, 0xdc, 0xca }, - { 0x2f, 0x7a, 0x98, 0x55, 0x7c, 0x6e, 0xe4, 0xab, 0xad, 0xf4, 0xe7, 0x11, - 0x92, 0xdd, 0x44, 0x2b, 0xd4, 0xff, 0x53, 0x25, 0xa5, 0xde, 0xf7, 0x5c }, - { 0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, 0x32, 0x82, 0xb3, 0x08, - 0xa5, 0x08, 0x41, 0x22, 0x9a, 0xd7, 0x98, 0xfa, 0xb9, 0x54, 0x0c, 0x1b } -}; - /* 0x0123456789abcdef */ unsigned char default_key[8] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef @@ -86,7 +89,6 @@ unsigned char default_ivec[8] = { unsigned char *ivec; unsigned char zero_key[8] = {1,1,1,1,1,1,1,1}; /* just parity bits */ int i,j; -krb5_error_code retval; unsigned char cipher1[8] = { 0x25,0xdd,0xac,0x3e,0x96,0x17,0x64,0x67 @@ -117,14 +119,15 @@ unsigned char mresult[8] = { * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?) */ -void +mit_des_key_schedule sched; + +int main(argc,argv) int argc; char *argv[]; { /* Local Declarations */ - krb5_context context; - int in_length; + int in_length, retval; void do_encrypt(); void do_decrypt(); @@ -164,23 +167,13 @@ main(argc,argv) } /* do some initialisation */ - initialize_krb5_error_table(); - krb5_init_context(&context); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC); - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); /* use known input and key */ /* ECB zero text zero key */ if (zflag) { input = zero_text; - keyblock.contents = (krb5_octet *)zero_key; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process zero key"); - exit(-1); - } + mit_des_key_sched(zero_key, sched); printf("plaintext = key = 0, cipher = 0x8ca64de9c1b123a7\n"); do_encrypt(input,cipher_text); printf("\tcipher = (low to high bytes)\n\t\t"); @@ -188,26 +181,17 @@ main(argc,argv) printf("%02x ",cipher_text[j]); printf("\n"); do_decrypt(output,cipher_text); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish zero key"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)zresult, 8) ) { printf("verify: error in zero key test\n"); exit(-1); } - krb5_free_context(context); exit(0); } if (mflag) { input = msb_text; - keyblock.contents = (krb5_octet *)key3; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process key3"); - exit(-1); - } + mit_des_key_sched(key3, sched); printf("plaintext = 0x00 00 00 00 00 00 00 40, "); printf("key = 0x80 01 01 01 01 01 01 01\n"); printf(" cipher = 0xa380e02a6be54696\n"); @@ -218,26 +202,17 @@ main(argc,argv) } printf("\n"); do_decrypt(output,cipher_text); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key3"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)mresult, 8) ) { printf("verify: error in msb test\n"); exit(-1); } - krb5_free_context(context); exit(0); } /* ECB mode Davies and Price */ { input = zero_text; - keyblock.contents = (krb5_octet *)key2; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process key2"); - exit(-1); - } + mit_des_key_sched(key2, sched); printf("Examples per FIPS publication 81, keys ivs and cipher\n"); printf("in hex. These are the correct answers, see below for\n"); printf("the actual answers.\n\n"); @@ -253,10 +228,6 @@ main(argc,argv) printf("%02x ",cipher_text[j]); printf("\n\n"); do_decrypt(output,cipher_text); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key2"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)cipher1, 8) ) { printf("verify: error in ECB encryption\n"); exit(-1); @@ -267,11 +238,7 @@ main(argc,argv) /* ECB mode */ { - keyblock.contents = (krb5_octet *)default_key; - if (retval = krb5_process_key(context, &eblock,&keyblock)) { - com_err("des verify", retval, "can't process key2"); - exit(-1); - } + mit_des_key_sched(default_key, sched); input = clear_text; ivec = default_ivec; printf("EXAMPLE ECB\tkey = 0123456789abcdef\n"); @@ -306,14 +273,14 @@ main(argc,argv) if (retval = mit_des_cbc_encrypt((mit_des_cblock *) input, (mit_des_cblock *) cipher_text, (size_t) in_length, - (struct mit_des_ks_struct *)eblock.priv, + sched, ivec, MIT_DES_ENCRYPT)) { com_err("des verify", retval, "can't encrypt"); exit(-1); } printf("\tciphertext = (low to high bytes)\n"); - for (i = 0; i <= 7; i++) { + for (i = 0; i <= 2; i++) { printf("\t\t"); for (j = 0; j <= 7; j++) { printf("%02x ",cipher_text[i*8+j]); @@ -323,7 +290,7 @@ main(argc,argv) if (retval = mit_des_cbc_encrypt((mit_des_cblock *) cipher_text, (mit_des_cblock *) clear_text, (size_t) in_length, - eblock.priv, + sched, ivec, MIT_DES_DECRYPT)) { com_err("des verify", retval, "can't decrypt"); @@ -345,16 +312,12 @@ main(argc,argv) printf("or some part thereof\n"); input = clear_text2; mit_des_cbc_cksum(input,cipher_text,(long) strlen((char *)input), - eblock.priv,ivec); + sched,ivec); printf("ACTUAL CBC checksum\n"); printf("\t\tencrypted cksum = (low to high bytes)\n\t\t"); for (j = 0; j<=7; j++) printf("%02x ",cipher_text[j]); printf("\n\n"); - if (retval = krb5_finish_key(context, &eblock)) { - com_err("des verify", retval, "can't finish key2"); - exit(-1); - } if ( memcmp((char *)cipher_text, (char *)checksum, 8) ) { printf("verify: error in CBC cheksum\n"); exit(-1); @@ -362,25 +325,6 @@ main(argc,argv) else printf("verify: CBC checksum is correct\n\n"); - printf("N-fold\n"); - for (i=0; i<sizeof(nfold_in)/sizeof(char *); i++) { - kdata.data = nfold_in[i]; - kdata.length = strlen(kdata.data); - printf("\tInput:\t\"%.*s\"\n", kdata.length, kdata.data); - printf("\t192-Fold:\t"); - mit_des_n_fold(kdata.data, kdata.length, cipher_text, 24); - for (j=0; j<24; j++) - printf("%s%02x", (j&3) ? "" : " ", cipher_text[j]); - printf("\n"); - if (memcmp(cipher_text, nfold_192[i], 24)) { - printf("verify: error in n-fold\n"); - exit(-1); - }; - } - printf("verify: N-fold is correct\n\n"); - - krb5_free_context(context); - exit(0); } @@ -412,9 +356,11 @@ do_encrypt(in,out) char *out; { for (i =1; i<=nflag; i++) { - mit_des_ecb_encrypt((mit_des_cblock *)in, + mit_des_cbc_encrypt((mit_des_cblock *)in, (mit_des_cblock *)out, - (struct mit_des_ks_struct *)eblock.priv, + 8, + sched, + zero_text, MIT_DES_ENCRYPT); if (mit_des_debug) { printf("\nclear %s\n",in); @@ -434,9 +380,11 @@ do_decrypt(in,out) /* try to invert it */ { for (i =1; i<=nflag; i++) { - mit_des_ecb_encrypt((mit_des_cblock *)out, + mit_des_cbc_encrypt((mit_des_cblock *)out, (mit_des_cblock *)in, - (struct mit_des_ks_struct *)eblock.priv, + 8, + sched, + zero_text, MIT_DES_DECRYPT); if (mit_des_debug) { printf("clear %s\n",in); @@ -453,8 +401,6 @@ do_decrypt(in,out) * Fake out the DES library, for the purposes of testing. */ -#include "des.h" - int mit_des_is_weak_key(key) mit_des_cblock key; diff --git a/src/lib/crypto/des/u_nfold.c b/src/lib/crypto/des/u_nfold.c deleted file mode 100644 index 6da58cbef3..0000000000 --- a/src/lib/crypto/des/u_nfold.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 1995 by Richard P. Basch. All Rights Reserved. - * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * - * N-folding algorithm - * Described in "A Better Key Schedule for DES-like Ciphers" - * by Uri Blumenthal and Steven M. Bellovin - * based on the work done by Lars Knudsen. - * - * To n-fold a number X, replicate the input value X to a length that is - * the least common multiple of n and the length of X. Before each - * repetition, the input value is rotated to the right by 13 bit positions. - * The successive n-bit chunks are added together using 1's complement - * addition (addition with end-around carry) to yield a n-bit result. - * - * The algorithm here assumes that the input and output are padded to - * octet boundaries (8-bit multiple). - */ - -#include "k5-int.h" - -#define ROTATE_VALUE 13 - -krb5_error_code -mit_des_n_fold(inbuf, inlen, outbuf, outlen) - krb5_octet *inbuf; - size_t inlen; - krb5_octet *outbuf; - size_t outlen; -{ - register int bytes; - register krb5_octet *tempbuf; - - if (inbuf == (krb5_octet *)NULL) - return EINVAL; - if (outbuf == (krb5_octet *)NULL) - return EINVAL; - - tempbuf = (krb5_octet *)malloc(inlen); - if (tempbuf == (krb5_octet *)NULL) - return ENOMEM; - - memset(outbuf, 0, outlen); - bytes = 0; - -#ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#endif - - do { - unsigned int j, k; - - /* Rotate input */ - k = ((bytes/inlen) * ROTATE_VALUE) % (inlen*8); - for (j = (k+7)/8; j < inlen + (k+7)/8; j++) - tempbuf[j % inlen] = - ((inbuf[((8*j-k)/8)%inlen] << ((8-(k&7))&7)) + - ((k&7) ? (inbuf[((8*j-k)/8 +1)%inlen] >> (k&7)) : 0)) - & 0xff; - - for (k=0, j=inlen; j--; ) { - k += outbuf[(bytes+j) % outlen] + tempbuf[j]; - outbuf[(bytes+j) % outlen] = k & 0xff; - k >>= 8; - } - j = bytes % outlen; - while (k) { - if (j == 0) - j = outlen; - j--; - k += outbuf[j]; - outbuf[j] = k & 0xff; - k >>= 8; - } - bytes += inlen; - } while (bytes % outlen); - - free(tempbuf); - - return 0; -} diff --git a/src/lib/crypto/des/u_rn_key.c b/src/lib/crypto/des/u_rn_key.c deleted file mode 100644 index 44d3c73839..0000000000 --- a/src/lib/crypto/des/u_rn_key.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 1996 by Richard P. Basch. All Rights Reserved. - * Copyright 1996 by Lehman Brothers, Inc. All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used - * in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. Richard P. Basch, - * Lehman Brothers and M.I.T. make no representations about the suitability - * of this software for any purpose. It is provided "as is" without - * express or implied warranty. - * - * - * Based on the version written by Mark Lillibridge, MIT Project Athena. - * - * Under U.S. law, this software may not be exported outside the US - * without license from the U.S. Commerce department. - */ - -#include "k5-int.h" -#include "des_int.h" - -int -mit_des_is_weak_keyblock(keyblock) - krb5_keyblock * keyblock; -{ - int i; - - for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++) - if (mit_des_is_weak_key(*((mit_des_cblock *)keyblock->contents + i))) - return 1; - return 0; -} - -void -mit_des_fixup_keyblock_parity(keyblock) - krb5_keyblock * keyblock; -{ - int i; - - for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++) - mit_des_fixup_key_parity(*((mit_des_cblock *)keyblock->contents + i)); -} - -/* - * mit_des_set_random_generator_seed: this routine is used to select a random - * number stream. The stream that results is - * totally determined by the passed in key. - * (I.e., calling this routine again with the - * same key allows repeating a sequence of - * random numbers) - */ -krb5_error_code -mit_des_set_random_generator_seed(seed, p_state) - const krb5_data * seed; - krb5_pointer p_state; -{ - krb5_error_code kret; - register int i; - mit_des_cblock *new_key; - mit_des_random_state *state = p_state; - - if (state->eblock.key) { - if (state->eblock.key->contents) { - memset(state->eblock.key->contents, 0, state->eblock.key->length); - krb5_xfree(state->eblock.key->contents); - } - } - - state->eblock.key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)); - if (! state->eblock.key) - return ENOMEM; - - state->eblock.key->enctype = state->eblock.crypto_entry->proto_enctype; - state->eblock.key->length = state->eblock.crypto_entry->keysize; - state->eblock.key->contents = (krb5_octet *)malloc(state->eblock.key->length); - if (! state->eblock.key->contents) { - krb5_xfree(state->eblock.key); - state->eblock.key = 0; - return ENOMEM; - } - - kret = mit_des_n_fold(seed->data, seed->length, - state->eblock.key->contents, state->eblock.key->length); - if (kret) return kret; - - mit_des_fixup_keyblock_parity(state->eblock.key); - - for (i = 0; i < state->eblock.key->length/sizeof(mit_des_cblock); i++) { - new_key = (mit_des_cblock *)state->eblock.key->contents + i; - if (mit_des_is_weak_key(*new_key)) { - (*new_key)[0] ^= 0xF0; - mit_des_fixup_key_parity(*new_key); - } - } - - /* destroy any old key schedule */ - mit_des_finish_key(&state->eblock); - - /* compute the key schedule */ - (* state->eblock.crypto_entry->process_key) - (&state->eblock, state->eblock.key); - - /* now we can destroy the key... */ - memset(state->eblock.key->contents, 0, state->eblock.key->length); - krb5_xfree(state->eblock.key->contents); - krb5_xfree(state->eblock.key); - state->eblock.key = (krb5_keyblock *) 0; - - /* "seek" to the start of the stream: */ - memset(state->sequence.data, 0, state->sequence.length); - - return 0; -} - -krb5_error_code -mit_des_set_random_sequence_number(sequence, p_state) - const krb5_data *sequence; - krb5_pointer p_state; -{ - mit_des_random_state *state = p_state; - int length = state->eblock.crypto_entry->keysize; - - if (length > sequence->length) - length = sequence->length; - - memcpy(state->sequence.data, sequence->data, length); - - return 0; -} diff --git a/src/lib/crypto/des3_raw.c b/src/lib/crypto/des3_raw.c deleted file mode 100644 index 62e3d724dc..0000000000 --- a/src/lib/crypto/des3_raw.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * lib/crypto/des3_raw.c - * - * Copyright 1996 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code mit_des3_raw_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_des3_raw_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static krb5_cryptosystem_entry mit_des3_raw_cryptosystem_entry = { - 0, - mit_des3_raw_encrypt_func, - mit_des3_raw_decrypt_func, - mit_des3_process_key, - mit_des_finish_key, - mit_des3_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - 0, - sizeof(mit_des3_cblock), - ENCTYPE_DES3_CBC_RAW - }; - -krb5_cs_table_entry krb5_des3_raw_cst_entry = { - 0, - &mit_des3_raw_cryptosystem_entry, - 0 - }; - -krb5_error_code -mit_des3_raw_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - return (mit_des3_cbc_encrypt((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *)key->priv, - ((struct mit_des_ks_struct *)key->priv) + 1, - ((struct mit_des_ks_struct *)key->priv) + 2, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_DECRYPT)); -} - -krb5_error_code -mit_des3_raw_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - int sumsize; - - /* round up to des block size */ - - sumsize = krb5_roundup(size, sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - memcpy((char *)out, (char *)in, size); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des3_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *)key->priv, - ((struct mit_des_ks_struct *)key->priv) + 1, - ((struct mit_des_ks_struct *)key->priv) + 2, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_ENCRYPT)); -} diff --git a/src/lib/crypto/des3_sha.c b/src/lib/crypto/des3_sha.c deleted file mode 100644 index 9b060e5899..0000000000 --- a/src/lib/crypto/des3_sha.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * lib/crypto/des3-sha.c - * - * Copyright 1996 by Lehman Brothers, Inc. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of Lehman Brothers or M.I.T. not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. Lehman Brothers and - * M.I.T. make no representations about the suitability of this - * software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "shs.h" -#include "des_int.h" - - -#define DES3_SHA_CONFOUNDER_SIZE sizeof(mit_des_cblock) - -static krb5_error_code -mit_des3_sha_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static krb5_error_code -mit_des3_sha_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static mit_des_cblock zero_ivec = { 0 }; - -static krb5_cryptosystem_entry mit_des3_sha_cryptosystem_entry = { - 0, - mit_des3_sha_encrypt_func, - mit_des3_sha_decrypt_func, - mit_des3_process_key, - mit_des_finish_key, - mit_des3_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - NIST_SHA_CKSUM_LENGTH + DES3_SHA_CONFOUNDER_SIZE, - sizeof(mit_des3_cblock), - ENCTYPE_DES3_CBC_SHA - }; - -krb5_cs_table_entry krb5_des3_sha_cst_entry = { - 0, - &mit_des3_sha_cryptosystem_entry, - 0 - }; - - -static krb5_error_code -mit_des3_sha_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents[NIST_SHA_CKSUM_LENGTH]; - int sumsize; - krb5_error_code retval; - - /* caller passes data size, and saves room for the padding. */ - /* format of ciphertext, per RFC is: - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - our confounder is 8 bytes - our checksum is NIST_SHA_CKSUM_LENGTH - */ - sumsize = krb5_roundup(size + mit_des3_sha_cryptosystem_entry.pad_minimum, - mit_des3_sha_cryptosystem_entry.block_length); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - - /* put in the confounder */ - if ((retval = krb5_random_confounder(DES3_SHA_CONFOUNDER_SIZE, out))) - return retval; - - memcpy((char *)out + mit_des3_sha_cryptosystem_entry.pad_minimum, - (char *)in, size); - - cksum.length = sizeof(contents); - cksum.contents = contents; - - /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_SHA,...) - but avoids use of the cryptosystem config table which can not be - referenced here if this object is to be included in a shared library. */ - retval = nist_sha_cksumtable_entry.sum_func((krb5_pointer) out, sumsize, - 0, 0, &cksum); - if (retval) - return retval; - - memcpy((char *)out + DES3_SHA_CONFOUNDER_SIZE, - (char *)contents, NIST_SHA_CKSUM_LENGTH); - - /* We depend here on the ability of this DES-3 implementation to - encrypt plaintext to ciphertext in-place. */ - retval = mit_des3_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *) key->priv, - ((struct mit_des_ks_struct *) key->priv) + 1, - ((struct mit_des_ks_struct *) key->priv) + 2, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_ENCRYPT); - return retval; -} - -static krb5_error_code -mit_des3_sha_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents_prd[NIST_SHA_CKSUM_LENGTH]; - krb5_octet contents_get[NIST_SHA_CKSUM_LENGTH]; - char *p; - krb5_error_code retval; - - if ( size < krb5_roundup(mit_des3_sha_cryptosystem_entry.pad_minimum, - mit_des3_sha_cryptosystem_entry.block_length)) - return KRB5_BAD_MSIZE; - - retval = mit_des3_cbc_encrypt((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *) key->priv, - ((struct mit_des_ks_struct *) key->priv) + 1, - ((struct mit_des_ks_struct *) key->priv) + 2, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_DECRYPT); - if (retval) - return retval; - - cksum.length = sizeof(contents_prd); - cksum.contents = contents_prd; - p = (char *)out + DES3_SHA_CONFOUNDER_SIZE; - memcpy((char *)contents_get, p, NIST_SHA_CKSUM_LENGTH); - memset(p, 0, NIST_SHA_CKSUM_LENGTH); - - retval = nist_sha_cksumtable_entry.sum_func(out, size, 0, 0, &cksum); - if (retval) - return retval; - - if (memcmp((char *)contents_get, - (char *)contents_prd, - NIST_SHA_CKSUM_LENGTH)) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - - memmove((char *)out, (char *)out + - mit_des3_sha_cryptosystem_entry.pad_minimum, - size - mit_des3_sha_cryptosystem_entry.pad_minimum); - return 0; -} diff --git a/src/lib/crypto/des_crc.c b/src/lib/crypto/des_crc.c deleted file mode 100644 index 6317f61d7a..0000000000 --- a/src/lib/crypto/des_crc.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * lib/crypto/des-crc.32 - * - * Copyright 1994 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "crc-32.h" -#include "des_int.h" - -krb5_error_code mit_des_crc_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_des_crc_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - - -static krb5_cryptosystem_entry mit_des_crc_cryptosystem_entry = { - 0, - mit_des_crc_encrypt_func, - mit_des_crc_decrypt_func, - mit_des_process_key, - mit_des_finish_key, - mit_des_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - CRC32_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock), - ENCTYPE_DES_CBC_CRC - }; - -krb5_cs_table_entry krb5_des_crc_cst_entry = { - 0, - &mit_des_crc_cryptosystem_entry, - 0 - }; - - -krb5_error_code -mit_des_crc_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents[CRC32_CKSUM_LENGTH]; - int sumsize; - krb5_error_code retval; - -/* if ( size < sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; */ - - /* caller passes data size, and saves room for the padding. */ - /* format of ciphertext, per RFC is: - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - our confounder is 8 bytes (one cblock); - our checksum is CRC32_CKSUM_LENGTH - */ - sumsize = krb5_roundup(size+CRC32_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - - /* put in the confounder */ - if ((retval = krb5_random_confounder(sizeof(mit_des_cblock), out))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock)+CRC32_CKSUM_LENGTH, (char *)in, - size); - - cksum.length = sizeof(contents); - cksum.contents = contents; - - /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_CRC32,...) - but avoids use of the cryptosystem config table which can not be - referenced here if this object is to be included in a shared library. */ - if ((retval = crc32_cksumtable_entry.sum_func((krb5_pointer) out, - sumsize, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock), (char *)contents, - CRC32_CKSUM_LENGTH); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_ENCRYPT)); - -} - -krb5_error_code -mit_des_crc_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents_prd[CRC32_CKSUM_LENGTH]; - krb5_octet contents_get[CRC32_CKSUM_LENGTH]; - char *p; - krb5_error_code retval; - - if ( size < 2*sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; - - retval = mit_des_cbc_encrypt((const mit_des_cblock FAR *) in, - out, - size, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_DECRYPT); - if (retval) - return retval; - - cksum.length = sizeof(contents_prd); - cksum.contents = contents_prd; - p = (char *)out + sizeof(mit_des_cblock); - memcpy((char *)contents_get, p, CRC32_CKSUM_LENGTH); - memset(p, 0, CRC32_CKSUM_LENGTH); - - if ((retval = crc32_cksumtable_entry.sum_func(out, size, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - if (memcmp((char *)contents_get, (char *)contents_prd, CRC32_CKSUM_LENGTH) ) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - memmove((char *)out, (char *)out + - sizeof(mit_des_cblock) + CRC32_CKSUM_LENGTH, - size - sizeof(mit_des_cblock) - CRC32_CKSUM_LENGTH); - return 0; -} diff --git a/src/lib/crypto/des_md5.c b/src/lib/crypto/des_md5.c deleted file mode 100644 index 6794f568f6..0000000000 --- a/src/lib/crypto/des_md5.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * lib/crypto/des-md5.32 - * - * Copyright 1994 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "rsa-md5.h" -#include "des_int.h" - -krb5_error_code mit_des_md5_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_des_md5_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static mit_des_cblock zero_ivec = { 0 }; - -static krb5_cryptosystem_entry mit_des_md5_cryptosystem_entry = { - 0, - mit_des_md5_encrypt_func, - mit_des_md5_decrypt_func, - mit_des_process_key, - mit_des_finish_key, - mit_des_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - RSA_MD5_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock), - ENCTYPE_DES_CBC_MD5 - }; - -krb5_cs_table_entry krb5_des_md5_cst_entry = { - 0, - &mit_des_md5_cryptosystem_entry, - 0 - }; - - -krb5_error_code -mit_des_md5_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents[RSA_MD5_CKSUM_LENGTH]; - int sumsize; - krb5_error_code retval; - -/* if ( size < sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; */ - - /* caller passes data size, and saves room for the padding. */ - /* format of ciphertext, per RFC is: - +-----------+----------+-------------+-----+ - |confounder | check | msg-seq | pad | - +-----------+----------+-------------+-----+ - - our confounder is 8 bytes (one cblock); - our checksum is RSA_MD5_CKSUM_LENGTH - */ - sumsize = krb5_roundup(size+RSA_MD5_CKSUM_LENGTH+sizeof(mit_des_cblock), - sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - - /* put in the confounder */ - if ((retval = krb5_random_confounder(sizeof(mit_des_cblock), out))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock)+RSA_MD5_CKSUM_LENGTH, (char *)in, - size); - - cksum.length = sizeof(contents); - cksum.contents = contents; - - /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_MD5,...) - but avoids use of the cryptosystem config table which can not be - referenced here if this object is to be included in a shared library. */ - if ((retval = rsa_md5_cksumtable_entry.sum_func((krb5_pointer) out, - sumsize, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - memcpy((char *)out+sizeof(mit_des_cblock), (char *)contents, - RSA_MD5_CKSUM_LENGTH); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des_cbc_encrypt(out, - out, - sumsize, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_ENCRYPT)); - -} - -krb5_error_code -mit_des_md5_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - krb5_checksum cksum; - krb5_octet contents_prd[RSA_MD5_CKSUM_LENGTH]; - krb5_octet contents_get[RSA_MD5_CKSUM_LENGTH]; - char *p; - krb5_error_code retval; - - if ( size < 2*sizeof(mit_des_cblock) ) - return KRB5_BAD_MSIZE; - - retval = mit_des_cbc_encrypt((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *) key->priv, - ivec ? ivec : (krb5_pointer)zero_ivec, - MIT_DES_DECRYPT); - if (retval) - return retval; - - cksum.length = sizeof(contents_prd); - cksum.contents = contents_prd; - p = (char *)out + sizeof(mit_des_cblock); - memcpy((char *)contents_get, p, RSA_MD5_CKSUM_LENGTH); - memset(p, 0, RSA_MD5_CKSUM_LENGTH); - - if ((retval = rsa_md5_cksumtable_entry.sum_func(out, size, - (krb5_pointer)key->key->contents, - sizeof(mit_des_cblock), - &cksum))) - return retval; - - if (memcmp((char *)contents_get, (char *)contents_prd, RSA_MD5_CKSUM_LENGTH) ) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - memmove((char *)out, (char *)out + - sizeof(mit_des_cblock) + RSA_MD5_CKSUM_LENGTH, - size - sizeof(mit_des_cblock) - RSA_MD5_CKSUM_LENGTH); - return 0; -} diff --git a/src/lib/crypto/encrypt.c b/src/lib/crypto/encrypt.c new file mode 100644 index 0000000000..76b8c84031 --- /dev/null +++ b/src/lib/crypto/encrypt.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_encrypt(context, key, usage, ivec, input, output) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *ivec; + krb5_const krb5_data *input; + krb5_enc_data *output; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == key->enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + output->magic = KV5M_ENC_DATA; + output->kvno = 0; + output->enctype = key->enctype; + + return((*(krb5_enctypes_list[i].encrypt)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + key, usage, ivec, input, &output->ciphertext)); +} diff --git a/src/lib/crypto/encrypt_data.c b/src/lib/crypto/encrypt_data.c deleted file mode 100644 index b2f039f339..0000000000 --- a/src/lib/crypto/encrypt_data.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -#include "k5-int.h" - -/* - * This routine takes a key and a krb5_data structure as input, and - * outputs the encrypted data in a krb5_enc_data structure. Note that - * the krb5_enc_data structure is not allocated, and the kvno field is - * not filled in. - */ -krb5_error_code -krb5_encrypt_data(context, key, ivec, data, enc_data) - krb5_context context; - krb5_keyblock * key; - krb5_pointer ivec; - krb5_data * data; - krb5_enc_data * enc_data; -{ - krb5_error_code retval; - krb5_encrypt_block eblock; - - krb5_use_enctype(context, &eblock, key->enctype); - - enc_data->magic = KV5M_ENC_DATA; - enc_data->kvno = 0; - enc_data->enctype = key->enctype; - enc_data->ciphertext.length = krb5_encrypt_size(data->length, - eblock.crypto_entry); - enc_data->ciphertext.data = malloc(enc_data->ciphertext.length); - if (enc_data->ciphertext.data == 0) - return ENOMEM; - - if ((retval = krb5_process_key(context, &eblock, key)) != 0) - goto cleanup; - - if ((retval = krb5_encrypt(context, (krb5_pointer) data->data, - (krb5_pointer) enc_data->ciphertext.data, - data->length, &eblock, ivec))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - (void) krb5_finish_key(context, &eblock); - - return 0; - -cleanup: - free(enc_data->ciphertext.data); - return retval; -} - diff --git a/src/lib/crypto/encrypt_length.c b/src/lib/crypto/encrypt_length.c new file mode 100644 index 0000000000..005b2211da --- /dev/null +++ b/src/lib/crypto/encrypt_length.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_encrypt_length(context, enctype, inputlen, length) + krb5_context context; + krb5_enctype enctype; + size_t inputlen; + size_t *length; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + (*(krb5_enctypes_list[i].encrypt_len)) + (krb5_enctypes_list[i].enc, krb5_enctypes_list[i].hash, + inputlen, length); + + return(0); +} diff --git a/src/lib/crypto/enctype_compare.c b/src/lib/crypto/enctype_compare.c new file mode 100644 index 0000000000..8972589685 --- /dev/null +++ b/src/lib/crypto/enctype_compare.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +krb5_error_code +krb5_c_enctype_compare(context, e1, e2, similar) + krb5_context context; + krb5_enctype e1; + krb5_enctype e2; + krb5_boolean *similar; +{ + int i, j; + + for (i=0; i<krb5_enctypes_length; i++) + if (krb5_enctypes_list[i].etype == e1) + break; + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + for (j=0; j<krb5_enctypes_length; j++) + if (krb5_enctypes_list[j].etype == e2) + break; + + if (j == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + *similar = + ((krb5_enctypes_list[i].enc == krb5_enctypes_list[j].enc) && + (krb5_enctypes_list[i].str2key == krb5_enctypes_list[j].str2key)); + + return(0); +} diff --git a/src/lib/crypto/enctype_to_string.c b/src/lib/crypto/enctype_to_string.c new file mode 100644 index 0000000000..2c25a52510 --- /dev/null +++ b/src/lib/crypto/enctype_to_string.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_enctype_to_string(enctype, buffer, buflen) + krb5_enctype enctype; + char FAR * buffer; + size_t buflen; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) { + if ((strlen(krb5_enctypes_list[i].out_string)+1) > buflen) + return(ENOMEM); + + strcpy(buffer, krb5_enctypes_list[i].out_string); + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/etypes.c b/src/lib/crypto/etypes.c new file mode 100644 index 0000000000..cebb5bda5a --- /dev/null +++ b/src/lib/crypto/etypes.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "enc_provider.h" +#include "hash_provider.h" +#include "etypes.h" +#include "old.h" +#include "raw.h" +#include "dk.h" + +/* these will be linear searched. if they ever get big, a binary + search or hash table would be better, which means these would need + to be sorted. An array would be more efficient, but that assumes + that the keytypes are all near each other. I'd rather not make + that assumption. */ + +struct krb5_keytypes krb5_enctypes_list[] = { + { ENCTYPE_DES_CBC_CRC, + "des-cbc-crc", "DES cbc mode with CRC-32", + &krb5_enc_des, &krb5_hash_crc32, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5_des_string_to_key }, + { ENCTYPE_DES_CBC_MD4, + "des-cbc-md4", "DES cbc mode with RSA-MD4", + &krb5_enc_des, &krb5_hash_md4, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5_des_string_to_key }, + { ENCTYPE_DES_CBC_MD5, + "des-cbc-md5", "DES cbc mode with RSA-MD5", + &krb5_enc_des, &krb5_hash_md5, + krb5_old_encrypt_length, krb5_old_encrypt, krb5_old_decrypt, + krb5_des_string_to_key }, + + { ENCTYPE_DES_CBC_RAW, + "des-cbc-raw", "DES cbc mode raw", + &krb5_enc_des, NULL, + krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, + krb5_des_string_to_key }, + { ENCTYPE_DES3_CBC_RAW, + "des3-cbc-raw", "Triple DES cbc mode raw", + &krb5_enc_des3, NULL, + krb5_raw_encrypt_length, krb5_raw_encrypt, krb5_raw_decrypt, + krb5_dk_string_to_key }, + + { ENCTYPE_DES3_HMAC_SHA1, + "des3-hmac-sha1", "Triple DES with HMAC/sha1", + &krb5_enc_des3, &krb5_hash_sha1, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5_dk_string_to_key }, + { ENCTYPE_DES_HMAC_SHA1, + "des-hmac-sha1", "DES with HMAC/sha1", + &krb5_enc_des, &krb5_hash_sha1, + krb5_dk_encrypt_length, krb5_dk_encrypt, krb5_dk_decrypt, + krb5_dk_string_to_key }, +}; + +int krb5_enctypes_length = +sizeof(krb5_enctypes_list)/sizeof(struct krb5_keytypes); diff --git a/src/lib/crypto/etypes.h b/src/lib/crypto/etypes.h new file mode 100644 index 0000000000..53d8b655af --- /dev/null +++ b/src/lib/crypto/etypes.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +extern struct krb5_keytypes krb5_enctypes_list[]; +extern int krb5_enctypes_length; diff --git a/src/lib/crypto/hmac.c b/src/lib/crypto/hmac.c new file mode 100644 index 0000000000..7cf11a6c70 --- /dev/null +++ b/src/lib/crypto/hmac.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +/* + * the HMAC transform looks like: + * + * H(K XOR opad, H(K XOR ipad, text)) + * + * where H is a cryptographic hash + * K is an n byte key + * ipad is the byte 0x36 repeated blocksize times + * opad is the byte 0x5c repeated blocksize times + * and text is the data being protected + */ + +krb5_error_code +krb5_hmac(hash, key, icount, input, output) + krb5_const struct krb5_hash_provider *hash; + krb5_const krb5_keyblock *key; + unsigned int icount; + krb5_const krb5_data *input; + krb5_data *output; +{ + size_t hashsize, blocksize; + unsigned char *xorkey, *ihash; + int i; + krb5_data *hashin, hashout; + krb5_error_code ret; + + (*(hash->hash_size))(&hashsize); + (*(hash->block_size))(&blocksize); + + if (key->length > blocksize) + return(KRB5_CRYPTO_INTERNAL); + if (output->length < hashsize) + return(KRB5_BAD_MSIZE); + /* if this isn't > 0, then there won't be enough space in this + array to compute the outer hash */ + if (icount == 0) + return(KRB5_CRYPTO_INTERNAL); + + /* allocate space for the xor key, hash input vector, and inner hash */ + + if ((xorkey = (unsigned char *) malloc(blocksize)) == NULL) + return(ENOMEM); + if ((ihash = (unsigned char *) malloc(hashsize)) == NULL) { + free(xorkey); + return(ENOMEM); + } + if ((hashin = (krb5_data *)malloc(sizeof(krb5_data)*(icount+1))) == NULL) { + free(ihash); + free(xorkey); + return(ENOMEM); + } + + /* create the inner padded key */ + + memset(xorkey, 0x36, blocksize); + + for (i=0; i<key->length; i++) + xorkey[i] ^= key->contents[i]; + + /* compute the inner hash */ + + for (i=0; i<icount; i++) { + hashin[0].length = blocksize; + hashin[0].data = xorkey; + hashin[i+1] = input[i]; + } + + hashout.length = hashsize; + hashout.data = ihash; + + if (ret = ((*(hash->hash))(icount+1, hashin, &hashout))) + goto cleanup; + + /* create the outer padded key */ + + memset(xorkey, 0x5c, blocksize); + + for (i=0; i<key->length; i++) + xorkey[i] ^= key->contents[i]; + + /* compute the outer hash */ + + hashin[0].length = blocksize; + hashin[0].data = xorkey; + hashin[1] = hashout; + + output->length = hashsize; + + if (ret = ((*(hash->hash))(2, hashin, output))) + memset(output->data, 0, output->length); + + /* ret is set correctly by the prior call */ + +cleanup: + memset(xorkey, 0, blocksize); + memset(ihash, 0, hashsize); + + free(hashin); + free(ihash); + free(xorkey); + + return(ret); +} diff --git a/src/lib/crypto/keyed_checksum_types.c b/src/lib/crypto/keyed_checksum_types.c new file mode 100644 index 0000000000..cf0b736f2f --- /dev/null +++ b/src/lib/crypto/keyed_checksum_types.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" +#include "cksumtypes.h" + +static int etype_match(e1, e2) + krb5_enctype e1, e2; +{ + int i1, i2; + + for (i1=0; i1<krb5_enctypes_length; i1++) + if (krb5_enctypes_list[i1].etype == e1) + break; + + for (i2=0; i2<krb5_enctypes_length; i2++) + if (krb5_enctypes_list[i2].etype == e2) + break; + + return((i1 < krb5_enctypes_length) && + (i2 < krb5_enctypes_length) && + (krb5_enctypes_list[i1].enc == krb5_enctypes_list[i2].enc)); +} + +krb5_error_code +krb5_c_keyed_checksum_types(context, enctype, count, cksumtypes) + krb5_context context; + krb5_enctype enctype; + unsigned int *count; + krb5_cksumtype **cksumtypes; +{ + unsigned int i, c; + + c = 0; + for (i=0; i<krb5_cksumtypes_length; i++) { + if ((krb5_cksumtypes_list[i].keyhash && + etype_match(krb5_cksumtypes_list[i].keyed_etype, enctype)) || + (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE)) { + c++; + } + } + + *count = c; + + if ((*cksumtypes = (krb5_cksumtype *) malloc(c*sizeof(krb5_cksumtype))) + == NULL) + return(ENOMEM); + + c = 0; + for (i=0; i<krb5_cksumtypes_length; i++) { + if ((krb5_cksumtypes_list[i].keyhash && + etype_match(krb5_cksumtypes_list[i].keyed_etype, enctype)) || + (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE)) { + (*cksumtypes)[c] = krb5_cksumtypes_list[i].ctype; + c++; + } + } + + return(0); +} + +void +krb5_free_cksumtypes(context, val) + krb5_context context; + krb5_cksumtype FAR * val; +{ + if (val) + krb5_xfree(val); + return; +} + diff --git a/src/lib/crypto/keyed_cksum.c b/src/lib/crypto/keyed_cksum.c new file mode 100644 index 0000000000..0ff6d3e38c --- /dev/null +++ b/src/lib/crypto/keyed_cksum.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_boolean is_keyed_cksum(ctype) + krb5_cksumtype ctype; +{ + int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == ctype) { + if (krb5_cksumtypes_list[i].keyhash || + (krb5_cksumtypes_list[i].flags & + KRB5_CKSUMFLAG_DERIVE)) + return(1); + else + return(0); + } + } + + /* ick, but it's better than coredumping, which is what the + old code would have done */ + return(-1); +} diff --git a/src/lib/crypto/krb5_glue.c b/src/lib/crypto/krb5_glue.c deleted file mode 100644 index 3b26aed18c..0000000000 --- a/src/lib/crypto/krb5_glue.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * lib/krb5/krb/crypto_glue.c - * - * Copyright 1996 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * Exported routines: - * krb5_use_enctype() - * krb5_checksum_size() - * krb5_encrypt_size() - * krb5_calculate_checksum() - * krb5_verify_checksum() - * krb5_encrypt() - * krb5_decrypt() - * krb5_process_key() - * krb5_finish_key() - * krb5_string_to_key() - * krb5_init_random_key() - * krb5_finish_random_key() - * krb5_random_key() - * krb5_eblock_enctype() - * - * Internal library routines: - * is_coll_proof_cksum() - * is_keyed_cksum() - * valid_cksumtype() - * valid_enctype() - */ - -#include "k5-int.h" - - -KRB5_DLLIMP size_t KRB5_CALLCONV -krb5_encrypt_size(length, crypto) - krb5_const size_t length; - krb5_const krb5_cryptosystem_entry FAR * crypto; -{ - return krb5_roundup(length + crypto->pad_minimum, crypto->block_length); -} - -krb5_boolean KRB5_CALLCONV -valid_enctype(ktype) - krb5_const krb5_enctype ktype; -{ - return ((ktype<=krb5_max_enctype) && (ktype>0) && krb5_enctype_array[ktype]); -} - -krb5_boolean KRB5_CALLCONV -valid_cksumtype(cktype) - krb5_const krb5_cksumtype cktype; -{ - return ((cktype<=krb5_max_cksum) && (cktype>0) && krb5_cksumarray[cktype]); -} - -krb5_boolean KRB5_CALLCONV -is_coll_proof_cksum(cktype) - krb5_const krb5_cksumtype cktype; -{ - return(krb5_cksumarray[cktype]->is_collision_proof); -} - -krb5_boolean KRB5_CALLCONV -is_keyed_cksum(cktype) - krb5_const krb5_cksumtype cktype; -{ - return (krb5_cksumarray[cktype]->uses_key); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_use_enctype(context, eblock, enctype) - krb5_context context; - krb5_encrypt_block FAR * eblock; - krb5_const krb5_enctype enctype; -{ - eblock->crypto_entry = krb5_enctype_array[(enctype)]->system; - return 0; -} - -KRB5_DLLIMP size_t KRB5_CALLCONV -krb5_checksum_size(context, cktype) - krb5_context context; - krb5_const krb5_cksumtype cktype; -{ - return krb5_cksumarray[cktype]->checksum_length; -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_calculate_checksum(context, cktype, in, in_length, seed, seed_length, outcksum) - krb5_context context; - krb5_const krb5_cksumtype cktype; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - return krb5_x(((*krb5_cksumarray[cktype]->sum_func)), - (in, in_length, seed, seed_length, outcksum)); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_verify_checksum(context, cktype, cksum, in, in_length, seed, seed_length) - krb5_context context; - krb5_const krb5_cksumtype cktype; - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - return krb5_x((*krb5_cksumarray[cktype]->sum_verf_func), - (cksum, in, in_length, seed, seed_length)); -} - -KRB5_DLLIMP krb5_enctype KRB5_CALLCONV -krb5_eblock_enctype(context, eblock) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; -{ - return eblock->crypto_entry->proto_enctype; -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_encrypt(context, inptr, outptr, size, eblock, ivec) - krb5_context context; - krb5_const krb5_pointer inptr; - krb5_pointer outptr; - krb5_const size_t size; - krb5_encrypt_block FAR * eblock; - krb5_pointer ivec; -{ - return krb5_x(eblock->crypto_entry->encrypt_func, - (inptr, outptr, size, eblock, ivec)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_decrypt(context, inptr, outptr, size, eblock, ivec) - krb5_context context; - krb5_const krb5_pointer inptr; - krb5_pointer outptr; - krb5_const size_t size; - krb5_encrypt_block FAR * eblock; - krb5_pointer ivec; -{ - return krb5_x(eblock->crypto_entry->decrypt_func, - (inptr, outptr, size, eblock, ivec)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_process_key(context, eblock, key) - krb5_context context; - krb5_encrypt_block FAR * eblock; - krb5_const krb5_keyblock FAR * key; -{ - return krb5_x(eblock->crypto_entry->process_key, - (eblock, key)); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_finish_key(context, eblock) - krb5_context context; - krb5_encrypt_block FAR * eblock; -{ - return krb5_x(eblock->crypto_entry->finish_key,(eblock)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_string_to_key(context, eblock, keyblock, data, princ) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_keyblock FAR * keyblock; - krb5_const krb5_data FAR * data; - krb5_const krb5_data FAR * princ; -{ - return krb5_x(eblock->crypto_entry->string_to_key, - (eblock, keyblock, data, princ)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_init_random_key(context, eblock, keyblock, ptr) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_const krb5_keyblock FAR * keyblock; - krb5_pointer FAR * ptr; -{ - return krb5_x(eblock->crypto_entry->init_random_key, - (eblock, keyblock, ptr)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_finish_random_key(context, eblock, ptr) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_pointer FAR * ptr; -{ - return krb5_x(eblock->crypto_entry->finish_random_key, - (eblock, ptr)); -} - - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_random_key(context, eblock, ptr, keyblock) - krb5_context context; - krb5_const krb5_encrypt_block FAR * eblock; - krb5_pointer ptr; - krb5_keyblock FAR * FAR * keyblock; -{ - return krb5_x(eblock->crypto_entry->random_key, - (eblock, ptr, keyblock)); -} - - diff --git a/src/lib/crypto/make_checksum.c b/src/lib/crypto/make_checksum.c new file mode 100644 index 0000000000..b2faef191f --- /dev/null +++ b/src/lib/crypto/make_checksum.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" +#include "etypes.h" + +krb5_error_code +krb5_c_make_checksum(context, cksumtype, key, usage, input, cksum) + krb5_context context; + krb5_cksumtype cksumtype; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *input; + krb5_checksum *cksum; +{ + int i, e1, e2; + krb5_data data; + krb5_error_code ret; + size_t cksumlen; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksumtype) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + if (krb5_cksumtypes_list[i].keyhash) + (*(krb5_cksumtypes_list[i].keyhash->hash_size))(&cksumlen); + else + (*(krb5_cksumtypes_list[i].hash->hash_size))(&cksumlen); + + cksum->length = cksumlen; + + if ((cksum->contents = (krb5_octet *) malloc(cksum->length)) == NULL) + return(ENOMEM); + + data.length = cksum->length; + data.data = cksum->contents; + + if (krb5_cksumtypes_list[i].keyhash) { + /* check if key is compatible */ + + if (krb5_cksumtypes_list[i].keyed_etype) { + for (e1=0; e1<krb5_enctypes_length; e1++) + if (krb5_enctypes_list[e1].etype == + krb5_cksumtypes_list[i].keyed_etype) + break; + + for (e2=0; e2<krb5_enctypes_length; e2++) + if (krb5_enctypes_list[e2].etype == key->enctype) + break; + + if ((e1 == krb5_enctypes_length) || + (e2 == krb5_enctypes_length) || + (krb5_enctypes_list[e1].enc != krb5_enctypes_list[e2].enc)) { + ret = KRB5_BAD_ENCTYPE; + goto cleanup; + } + } + + ret = (*(krb5_cksumtypes_list[i].keyhash->hash))(key, 0, input, &data); + } else if (krb5_cksumtypes_list[i].flags & KRB5_CKSUMFLAG_DERIVE) { + /* any key is ok */ + + ret = krb5_dk_make_checksum(krb5_cksumtypes_list[i].hash, + key, usage, input, &data); + } else { + /* no key is used */ + + ret = (*(krb5_cksumtypes_list[i].hash->hash))(1, input, &data); + } + + if (!ret) { + cksum->magic = KV5M_CHECKSUM; + cksum->checksum_type = cksumtype; + } + +cleanup: + if (ret) { + memset(cksum->contents, 0, cksum->length); + free(cksum->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/make_random_key.c b/src/lib/crypto/make_random_key.c new file mode 100644 index 0000000000..391f56dfc2 --- /dev/null +++ b/src/lib/crypto/make_random_key.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_make_random_key(context, enctype, random_key) + krb5_context context; + krb5_enctype enctype; + krb5_keyblock *random_key; +{ + int i; + krb5_error_code ret; + struct krb5_enc_provider *enc; + size_t keybytes, keylength; + krb5_data random; + unsigned char *bytes; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + (*(enc->keysize))(&keybytes, &keylength); + + if ((bytes = (unsigned char *) malloc(keybytes)) == NULL) + return(ENOMEM); + if ((random_key->contents = (krb5_octet *) malloc(keylength)) == NULL) { + free(bytes); + return(ENOMEM); + } + + random.data = bytes; + random.length = keybytes; + + if (ret = krb5_c_random_make_octets(context, &random)) + goto cleanup; + + random_key->magic = KV5M_KEYBLOCK; + random_key->enctype = enctype; + random_key->length = keylength; + + ret = ((*(enc->make_key))(&random, random_key)); + +cleanup: + memset(bytes, 0, keybytes); + free(bytes); + + if (ret) { + memset(random_key->contents, 0, keylength); + free(random_key->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/md4/.rconf b/src/lib/crypto/md4/.rconf deleted file mode 100644 index de30fd8c9c..0000000000 --- a/src/lib/crypto/md4/.rconf +++ /dev/null @@ -1,2 +0,0 @@ -ignore RFC1186.TXT -ignore RFC1186B.TXT diff --git a/src/lib/crypto/md4/ChangeLog b/src/lib/crypto/md4/ChangeLog index 3ca8c08728..7714d4a43f 100644 --- a/src/lib/crypto/md4/ChangeLog +++ b/src/lib/crypto/md4/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz <marc@mit.edu> + + * *.c: replace the crypto layer. + Tue Mar 3 08:39:47 1998 Ezra Peisach <epeisach@kangaroo.mit.edu> * Makefile.in (t_cksum): Do not depend on libkrb5.a, use diff --git a/src/lib/crypto/md4/Makefile.in b/src/lib/crypto/md4/Makefile.in index 739b34b84c..be6baebb01 100644 --- a/src/lib/crypto/md4/Makefile.in +++ b/src/lib/crypto/md4/Makefile.in @@ -1,7 +1,6 @@ thisconfigdir=./.. BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -# -I$(srcdir) is needed to pull in $(srcdir)/rsa-md4.h for ./t_mddriver.c. -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des -I"$(srcdir)" +CFLAGS = $(CCOPTS) $(DEFS) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=md4 @@ -11,16 +10,22 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des -I"$(srcdir)" PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) -RUN_SETUP=@KRB5_RUN_ENV@ +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -STLIBOBJS=md4.o md4glue.o md4crypto.o -OBJS= md4.$(OBJEXT) md4glue.$(OBJEXT) md4crypto.$(OBJEXT) -SRCS= $(srcdir)/md4.c $(srcdir)/md4glue.c $(srcdir)/md4crypto.c +STLIBOBJS= md4.o + +OBJS= md4.$(OBJEXT) + +SRCS= $(srcdir)/md4.c ##DOS##LIBOBJS = $(OBJS) all-unix:: all-libobjs +includes:: depend + +depend:: $(SRCS) + t_mddriver.c: $(srcdir)/../md5/t_mddriver.c $(CP) $(srcdir)/../md5/t_mddriver.c t_mddriver.c @@ -35,24 +40,13 @@ t_mddriver.exe: $(CC) -DMD=4 $(CFLAGS2) -o t_mddriver t_mddriver.c md4.c $(RM) md4.obj -t_cksum.c: $(srcdir)/../md5/t_cksum.c - $(CP) $(srcdir)/../md5/t_cksum.c t_cksum.c - -t_cksum.o: t_cksum.c - $(CC) -DMD=4 $(CFLAGS) -c t_cksum.c - -t_cksum: t_cksum.o $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o t_cksum t_cksum.o $(KRB5_BASE_LIBS) - -check-unix:: t_mddriver t_cksum +check-unix:: t_mddriver $(RUN_SETUP) $(C)t_mddriver -x - $(RUN_SETUP) $(C)t_cksum "this is a test" check-windows:: t_mddriver$(EXEEXT) $(C)t_mddriver$(EXEEXT) -x clean:: $(RM) t_mddriver$(EXEEXT) t_mddriver.$(OBJEXT) t_mddriver.c - $(RM) t_cksum$(EXEEXT) t_cksum.$(OBJEXT) t_cksum.c clean-unix:: clean-libobjs diff --git a/src/lib/crypto/md4/md4crypto.c b/src/lib/crypto/md4/md4crypto.c deleted file mode 100644 index eac9647f2d..0000000000 --- a/src/lib/crypto/md4/md4crypto.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * lib/crypto/md4/md4crypto.c - * - * Copyright 1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * Kerberos glue for MD4 sample implementation. - */ - -#include "k5-int.h" -#include "rsa-md4.h" -#include "des_int.h" /* we cheat a bit and call it directly... */ - -/* - * In Kerberos V5 Beta 5 and previous releases the RSA-MD4-DES implementation - * did not follow RFC1510. The folowing definitions control the compatibility - * with these releases. - * - * If MD4_K5BETA_COMPAT is defined, then compatability mode is enabled. That - * means that both checksum functions are compiled and available for use and - * the additional interface md4_crypto_compat_ctl() is defined. - * - * If MD4_K5BETA_COMPAT_DEF is defined and compatability mode is enabled, then - * the compatible behaviour becomes the default. - * - */ -#define MD4_K5BETA_COMPAT -#define MD4_K5BETA_COMPAT_DEF - - -/* Windows needs to these prototypes for the assignment below */ - -#ifdef MD4_K5BETA_COMPAT -krb5_error_code -krb5_md4_crypto_compat_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum *outcksum)); -#endif - -krb5_error_code -krb5_md4_crypto_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum *outcksum)); - -krb5_error_code -krb5_md4_crypto_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -static mit_des_cblock zero_ivec = { 0 }; - -static void -krb5_md4_calculate_cksum(md4ctx, confound, confound_length, in, in_length) - krb5_MD4_CTX *md4ctx; - krb5_pointer confound; - size_t confound_length; - krb5_pointer in; - size_t in_length; -{ - krb5_MD4Init(md4ctx); - if (confound && confound_length) - krb5_MD4Update(md4ctx, confound, confound_length); - krb5_MD4Update(md4ctx, in, in_length); - krb5_MD4Final(md4ctx); -} - -#ifdef MD4_K5BETA_COMPAT -/* - * Generate the RSA-MD4-DES checksum in a manner which is compatible with - * K5 Beta implementations. Sigh... - */ -krb5_error_code -krb5_md4_crypto_compat_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[OLD_RSA_MD4_DES_CKSUM_LENGTH]; - krb5_octet *input = (krb5_octet *)in; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - krb5_MD4_CTX working; - - if (outcksum->length < OLD_RSA_MD4_DES_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - krb5_MD4Init(&working); - krb5_MD4Update(&working, input, in_length); - krb5_MD4Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD4_DES; - outcksum->length = OLD_RSA_MD4_DES_CKSUM_LENGTH; - - memcpy((char *)outtmp, (char *)&working.digest[0], 16); - - memset((char *)&working, 0, sizeof(working)); - - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *)seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD4; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0], - (mit_des_cblock *)outcksum->contents, - OLD_RSA_MD4_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} -#endif /* MD4_K5BETA_COMPAT */ - -/* - * Generate the RSA-MD4-DES checksum correctly. - */ -krb5_error_code -krb5_md4_crypto_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[NEW_RSA_MD4_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - - krb5_MD4_CTX working; - - /* Generate the confounder in place */ - if ((retval = krb5_random_confounder(RSA_MD4_DES_CONFOUND_LENGTH, outtmp))) - return(retval); - - /* Calculate the checksum */ - krb5_md4_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD4_DES_CONFOUND_LENGTH, - in, - in_length); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD4_DES; - outcksum->length = NEW_RSA_MD4_DES_CKSUM_LENGTH; - - /* Now blast in the digest */ - memcpy((char *) &outtmp[RSA_MD4_DES_CONFOUND_LENGTH], - (char *) &working.digest[0], - RSA_MD4_CKSUM_LENGTH); - - /* Clean up droppings */ - memset((char *)&working, 0, sizeof(working)); - - /* Set up the temporary copy of the key (see RFC 1510 section 6.4.3) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++) - tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0; - - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *) tmpkey; - keyblock.enctype = ENCTYPE_DES_CBC_MD4; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0], - (mit_des_cblock *)outcksum->contents, - NEW_RSA_MD4_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - zero_ivec, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} - -krb5_error_code -krb5_md4_crypto_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet outtmp[NEW_RSA_MD4_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - - krb5_MD4_CTX working; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD4_DES) { -#ifdef MD4_K5BETA_COMPAT - /* - * We have a backwards compatibility problem here. Kerberos - * version 5 Beta 5 and previous releases did not correctly - * generate RSA-MD4-DES checksums. The way that we can - * differentiate is by the length of the provided checksum. - * If it's only OLD_RSA_MD4_DES_CKSUM_LENGTH, then it's the - * old style, otherwise it's the correct implementation. - */ - if (cksum->length == OLD_RSA_MD4_DES_CKSUM_LENGTH) { - /* - * If we're verifying the Old Style (tm) checksum, then we can just - * recalculate the checksum and encrypt it and see if it's the - * same. - */ - - /* Recalculate the checksum with no confounder */ - krb5_md4_calculate_cksum(&working, - (krb5_pointer) NULL, - (size_t) 0, - in, - in_length); - - /* Use the key "as-is" */ - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *) seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD4; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt the checksum */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&working.digest[0], - (mit_des_cblock *)&outtmp[0], - RSA_MD4_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Compare the encrypted checksums */ - if (memcmp((char *) &outtmp[0], - (char *) cksum->contents, - OLD_RSA_MD4_DES_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else -#endif /* MD4_K5BETA_COMPAT */ - if (cksum->length == (NEW_RSA_MD4_DES_CKSUM_LENGTH)) { - /* - * If we're verifying the correct implementation, then we have - * to do a little more work because we must decrypt the checksum - * because it contains the confounder in it. So, figure out - * what our key variant is and then do it! - */ - - /* Set up the variant of the key (see RFC 1510 section 6.4.3) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++) - tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0; - - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *) tmpkey; - keyblock.enctype = ENCTYPE_DES_CBC_MD4; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now decrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)cksum->contents, - (mit_des_cblock *)&outtmp[0], - NEW_RSA_MD4_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - zero_ivec, - MIT_DES_DECRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Now that we have the decrypted checksum, try to regenerate it */ - krb5_md4_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD4_DES_CONFOUND_LENGTH, - in, - in_length); - - /* Compare the checksums */ - if (memcmp((char *) &outtmp[RSA_MD4_DES_CONFOUND_LENGTH], - (char *) &working.digest[0], - RSA_MD4_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - - /* Clean up droppings */ - memset((char *)&working, 0, sizeof(working)); - return(retval); -} - -krb5_checksum_entry rsa_md4_des_cksumtable_entry = -#if defined(MD4_K5BETA_COMPAT) && defined(MD4_K5BETA_COMPAT_DEF) -{ - 0, - krb5_md4_crypto_compat_sum_func, - krb5_md4_crypto_verify_func, - OLD_RSA_MD4_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#else /* MD4_K5BETA_COMPAT && MD4_K5BETA_COMPAT_DEF */ -{ - 0, - krb5_md4_crypto_sum_func, - krb5_md4_crypto_verify_func, - NEW_RSA_MD4_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#endif /* MD4_K5BETA_COMPAT && MD4_K5BETA_COMPAT_DEF */ - -#ifdef MD4_K5BETA_COMPAT -/* - * Turn on/off compatible checksum generation. - */ -void -krb5_md4_crypto_compat_ctl(scompat) - krb5_boolean scompat; -{ - if (scompat) { - rsa_md4_des_cksumtable_entry.sum_func = krb5_md4_crypto_compat_sum_func; - rsa_md4_des_cksumtable_entry.checksum_length = - OLD_RSA_MD4_DES_CKSUM_LENGTH; - } - else { - rsa_md4_des_cksumtable_entry.sum_func = krb5_md4_crypto_sum_func; - rsa_md4_des_cksumtable_entry.checksum_length = - NEW_RSA_MD4_DES_CKSUM_LENGTH; - } -} -#endif /* MD4_K5BETA_COMPAT */ diff --git a/src/lib/crypto/md4/md4driver.c b/src/lib/crypto/md4/md4driver.c deleted file mode 100644 index 425ef2954a..0000000000 --- a/src/lib/crypto/md4/md4driver.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * lib/crypto/md4/md4driver.c - */ - -/* - ********************************************************************** - ** md4driver.c -- sample routines to test ** - ** RSA Data Security, Inc. MD4 message digest algorithm. ** - ** Created: 2/16/90 RLR ** - ** Updated: 1/91 SRD ** - ********************************************************************** - */ - -/* - ********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - ********************************************************************** - */ - -#include "k5-int.h" -#include "rsa-md4.h" - -/* Prints message digest buffer in mdContext as 32 hexadecimal digits. - Order is from low-order byte to high-order byte of digest. - Each byte is printed with high-order hexadecimal digit first. - */ -static void MDPrint (mdContext) -krb5_MD4_CTX *mdContext; -{ - int i; - - for (i = 0; i < 16; i++) - printf ("%02x", mdContext->digest[i]); -} - -/* size of test block */ -#define TEST_BLOCK_SIZE 1000 - -/* number of blocks to process */ -#define TEST_BLOCKS 2000 - -/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */ -static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS; - -/* A time trial routine, to measure the speed of MD4. - Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE - characters. - */ -static void MDTimeTrial () -{ - krb5_MD4_CTX mdContext; - time_t endTime, startTime; - unsigned char data[TEST_BLOCK_SIZE]; - unsigned int i; - - /* initialize test data */ - for (i = 0; i < TEST_BLOCK_SIZE; i++) - data[i] = (unsigned char)(i & 0xFF); - - /* start timer */ - printf ("MD4 time trial. Processing %ld characters...\n", TEST_BYTES); - time (&startTime); - - /* digest data in TEST_BLOCK_SIZE byte blocks */ - krb5_MD4Init (&mdContext); - for (i = TEST_BLOCKS; i > 0; i--) - krb5_MD4Update (&mdContext, data, TEST_BLOCK_SIZE); - krb5_MD4Final (&mdContext); - /* stop timer, get time difference */ - time (&endTime); - MDPrint (&mdContext); - printf (" is digest of test input.\n"); - printf - ("Seconds to process test input: %ld\n", (long)(endTime-startTime)); - printf - ("Characters processed per second: %ld\n", - TEST_BYTES/(endTime-startTime)); -} - -/* Computes the message digest for string inString. - Prints out message digest, a space, the string (in quotes) and a - carriage return. - */ -static void MDString (inString) -char *inString; -{ - krb5_MD4_CTX mdContext; - unsigned int len = strlen (inString); - - krb5_MD4Init (&mdContext); - krb5_MD4Update (&mdContext, inString, len); - krb5_MD4Final (&mdContext); - MDPrint (&mdContext); - printf (" \"%s\"\n\n", inString); -} - -/* Computes the message digest for a specified file. - Prints out message digest, a space, the file name, and a carriage - return. - */ -static void MDFile (filename) -char *filename; -{ -#ifdef __STDC__ - FILE *inFile = fopen (filename, "rb"); -#else - FILE *inFile = fopen (filename, "r"); -#endif - krb5_MD4_CTX mdContext; - int bytes; - unsigned char data[1024]; - - if (inFile == NULL) { - printf ("%s can't be opened.\n", filename); - return; - } - - krb5_MD4Init (&mdContext); - while ((bytes = fread (data, 1, 1024, inFile)) != 0) - krb5_MD4Update (&mdContext, data, bytes); - krb5_MD4Final (&mdContext); - MDPrint (&mdContext); - printf (" %s\n", filename); - fclose (inFile); -} - - -/* Writes the message digest of the data from stdin onto stdout, - followed by a carriage return. - */ -static void MDFilter () -{ - krb5_MD4_CTX mdContext; - int bytes; - unsigned char data[16]; - - krb5_MD4Init (&mdContext); - while ((bytes = fread (data, 1, 16, stdin)) != 0) - krb5_MD4Update (&mdContext, data, bytes); - krb5_MD4Final (&mdContext); - MDPrint (&mdContext); - printf ("\n"); -} - -/* Runs a standard suite of test data. - */ -static void MDTestSuite () -{ - printf ("MD4 test suite results:\n\n"); - MDString (""); - MDString ("a"); - MDString ("abc"); - MDString ("message digest"); - MDString ("abcdefghijklmnopqrstuvwxyz"); - MDString - ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); - MDString - ("1234567890123456789012345678901234567890\ -1234567890123456789012345678901234567890"); - /* Contents of file foo are "abc" */ - MDFile ("foo"); -} - -void main (argc, argv) -int argc; -char *argv[]; -{ - int i; - - /* For each command line argument in turn: - ** filename -- prints message digest and name of file - ** -sstring -- prints message digest and contents of string - ** -t -- prints time trial statistics for 1M characters - ** -x -- execute a standard suite of test data - ** (no args) -- writes messages digest of stdin onto stdout - */ - if (argc == 1) - MDFilter (); - else - for (i = 1; i < argc; i++) - if (argv[i][0] == '-' && argv[i][1] == 's') - MDString (argv[i] + 2); - else if (strcmp (argv[i], "-t") == 0) - MDTimeTrial (); - else if (strcmp (argv[i], "-x") == 0) - MDTestSuite (); - else MDFile (argv[i]); -} - -/* - ********************************************************************** - ** End of md4driver.c ** - ******************************* (cut) ******************************** - */ diff --git a/src/lib/crypto/md4/md4glue.c b/src/lib/crypto/md4/md4glue.c deleted file mode 100644 index f7e566e9b2..0000000000 --- a/src/lib/crypto/md4/md4glue.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * lib/crypto/md4/md4glue.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * Kerberos glue for MD4 sample implementation. - */ - -#include "k5-int.h" -#include "rsa-md4.h" - -/* Windows needs to these prototypes for the assignment below */ - -krb5_error_code -krb5_md4_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_md4_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -krb5_error_code -krb5_md4_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD4_CTX working; - - if (outcksum->length < RSA_MD4_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - krb5_MD4Init(&working); - krb5_MD4Update(&working, input, in_length); - krb5_MD4Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD4; - outcksum->length = RSA_MD4_CKSUM_LENGTH; - - memcpy((char *)outcksum->contents, (char *)&working.digest[0], - RSA_MD4_CKSUM_LENGTH); - - memset((char *)&working, 0, sizeof(working)); - return 0; -} - -krb5_error_code -krb5_md4_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD4_CTX working; - krb5_error_code retval; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD4) { - if (cksum->length == RSA_MD4_CKSUM_LENGTH) { - krb5_MD4Init(&working); - krb5_MD4Update(&working, input, in_length); - krb5_MD4Final(&working); - - if (memcmp((char *) cksum->contents, - (char *) &working.digest[0], - RSA_MD4_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - memset((char *)&working, 0, sizeof(working)); - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - return retval; -} - -krb5_checksum_entry rsa_md4_cksumtable_entry = { - 0, - krb5_md4_sum_func, - krb5_md4_verify_func, - RSA_MD4_CKSUM_LENGTH, - 1, /* is collision proof */ - 0, /* doesn't use key */ -}; diff --git a/src/lib/crypto/md5/ChangeLog b/src/lib/crypto/md5/ChangeLog index 1c0026add4..79fb94a7dd 100644 --- a/src/lib/crypto/md5/ChangeLog +++ b/src/lib/crypto/md5/ChangeLog @@ -1,3 +1,7 @@ +Sun Jul 19 12:00:00 1998 Marc Horowitz <marc@mit.edu> + + * *.c: replace the crypto layer. + Tue Mar 3 08:42:10 1998 Ezra Peisach <epeisach@kangaroo.mit.edu> * Makefile.in (t_cksum): Do not depend on libkrb5.a, use diff --git a/src/lib/crypto/md5/Makefile.in b/src/lib/crypto/md5/Makefile.in index 3707f897b8..219fa3081a 100644 --- a/src/lib/crypto/md5/Makefile.in +++ b/src/lib/crypto/md5/Makefile.in @@ -1,6 +1,6 @@ thisconfigdir=./.. BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des +CFLAGS = $(CCOPTS) $(DEFS) ##DOS##BUILDTOP = ..\..\.. ##DOS##PREFIXDIR=md5 @@ -10,35 +10,35 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) -RUN_SETUP = @KRB5_RUN_ENV@ +RUN_SETUP = @KRB5_RUN_ENV@ KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf -STLIBOBJS=md5.o md5glue.o md5crypto.o +STLIBOBJS= md5.o -OBJS= md5.$(OBJEXT) md5glue.$(OBJEXT) md5crypto.$(OBJEXT) -SRCS= $(srcdir)/md5.c $(srcdir)/md5glue.c $(srcdir)/md5crypto.c +OBJS= md5.$(OBJEXT) + +SRCS= $(srcdir)/md5.c ##DOS##LIBOBJS = $(OBJS) all-unix:: all-libobjs +includes:: depend + +depend:: $(SRCS) + t_mddriver: t_mddriver.o md5.o $(CC) $(CFLAGS) $(LDFLAGS) -o t_mddriver t_mddriver.o md5.o t_mddriver.exe: $(CC) $(CFLAGS2) -o t_mddriver.exe t_mddriver.c md5.c -t_cksum: t_cksum.o $(KRB5_BASE_DEPLIBS) - $(CC_LINK) -o t_cksum t_cksum.o $(KRB5_BASE_LIBS) - -check-unix:: t_mddriver t_cksum +check-unix:: t_mddriver $(RUN_SETUP) $(C)t_mddriver -x - $(RUN_SETUP) $(C)t_cksum "this is a test" check-windows:: t_mddriver$(EXEEXT) $(C)t_mddriver$(EXEEXT) -x clean:: $(RM) t_mddriver$(EXEEXT) t_mddriver.$(OBJEXT) - $(RM) t_cksum$(EXEEXT) t_cksum.$(OBJEXT) clean-unix:: clean-libobjs diff --git a/src/lib/crypto/md5/md5crypto.c b/src/lib/crypto/md5/md5crypto.c deleted file mode 100644 index b83e50e77b..0000000000 --- a/src/lib/crypto/md5/md5crypto.c +++ /dev/null @@ -1,353 +0,0 @@ -#include "k5-int.h" -#include "rsa-md5.h" -#include "des_int.h" /* we cheat a bit and call it directly... */ - -/* - * In Kerberos V5 Beta 5 and previous releases the RSA-MD5-DES implementation - * did not follow RFC1510. The folowing definitions control the compatibility - * with these releases. - * - * If MD5_K5BETA_COMPAT is defined, then compatability mode is enabled. That - * means that both checksum functions are compiled and available for use and - * the additional interface krb5_md5_crypto_compat_ctl() is defined. - * - * If MD5_K5BETA_COMPAT_DEF is defined and compatability mode is enabled, then - * the compatible behaviour becomes the default. - * - */ -#define MD5_K5BETA_COMPAT -#define MD5_K5BETA_COMPAT_DEF - - -/* Windows needs to these prototypes for the assignment below */ - -#ifdef MD5_K5BETA_COMPAT -krb5_error_code -krb5_md5_crypto_compat_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); -#endif - -krb5_error_code -krb5_md5_crypto_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_md5_crypto_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -static mit_des_cblock zero_ivec = { 0 }; - -static void -krb5_md5_calculate_cksum(md5ctx, confound, confound_length, in, in_length) - krb5_MD5_CTX *md5ctx; - krb5_pointer in; - size_t in_length; - krb5_pointer confound; - size_t confound_length; -{ - krb5_MD5Init(md5ctx); - if (confound && confound_length) - krb5_MD5Update(md5ctx, confound, confound_length); - krb5_MD5Update(md5ctx, in, in_length); - krb5_MD5Final(md5ctx); -} - -#ifdef MD5_K5BETA_COMPAT -krb5_error_code -krb5_md5_crypto_compat_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[OLD_RSA_MD5_DES_CKSUM_LENGTH]; - krb5_octet *input = (krb5_octet *)in; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - - krb5_MD5_CTX working; - - krb5_MD5Init(&working); - krb5_MD5Update(&working, input, in_length); - krb5_MD5Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD5_DES; - outcksum->length = OLD_RSA_MD5_DES_CKSUM_LENGTH; - - memcpy((char *)outtmp, (char *)&working.digest[0], 16); - - memset((char *)&working, 0, sizeof(working)); - - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *)seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD5; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0], - (mit_des_cblock *)outcksum->contents, - OLD_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} -#endif /* MD5_K5BETA_COMPAT */ - -krb5_error_code -krb5_md5_crypto_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet outtmp[NEW_RSA_MD5_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - krb5_MD5_CTX working; - - if (outcksum->length < NEW_RSA_MD5_DES_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - /* Generate the confounder in place */ - if ((retval = krb5_random_confounder(RSA_MD5_DES_CONFOUND_LENGTH, outtmp))) - return(retval); - - /* Calculate the checksum */ - krb5_md5_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD5_DES_CONFOUND_LENGTH, - in, - in_length); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD5_DES; - outcksum->length = NEW_RSA_MD5_DES_CKSUM_LENGTH; - - /* Now blast in the digest */ - memcpy((char *)&outtmp[RSA_MD5_DES_CONFOUND_LENGTH], - (char *)&working.digest[0], - RSA_MD5_CKSUM_LENGTH); - - /* Clean up the droppings */ - memset((char *)&working, 0, sizeof(working)); - - /* Set up the temporary copy of the key (see RFC 1510 section 6.4.5) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++) - tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0; - - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *) tmpkey; - keyblock.enctype = ENCTYPE_DES_CBC_MD5; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0], - (mit_des_cblock *)outcksum->contents, - NEW_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *)eblock.priv, - zero_ivec, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - return mit_des_finish_key(&eblock); -} - -krb5_error_code -krb5_md5_crypto_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet outtmp[NEW_RSA_MD5_DES_CKSUM_LENGTH]; - mit_des_cblock tmpkey; - krb5_encrypt_block eblock; - krb5_keyblock keyblock; - krb5_error_code retval; - size_t i; - - krb5_MD5_CTX working; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD5_DES) { -#ifdef MD5_K5BETA_COMPAT - /* - * We have a backwards compatibility problem here. Kerberos - * version 5 Beta 5 and previous releases did not correctly - * generate RSA-MD5-DES checksums. The way that we can - * differentiate is by the length of the provided checksum. - * If it's only OLD_RSA_MD5_DES_CKSUM_LENGTH, then it's the - * old style, otherwise it's the correct implementation. - */ - if (cksum->length == OLD_RSA_MD5_DES_CKSUM_LENGTH) { - /* - * If we're verifying the Old Style (tm) checksum, then we can just - * recalculate the checksum and encrypt it and see if it's the - * same. - */ - - /* Recalculate the checksum with no confounder */ - krb5_md5_calculate_cksum(&working, - (krb5_pointer) NULL, - (size_t) 0, - in, - in_length); - - /* Use the key "as-is" */ - keyblock.length = seed_length; - keyblock.contents = (krb5_octet *) seed; - keyblock.enctype = ENCTYPE_DES_CBC_MD5; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now encrypt the checksum */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)&working.digest[0], - (mit_des_cblock *)&outtmp[0], - OLD_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - keyblock.contents, - MIT_DES_ENCRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Compare the encrypted checksums */ - if (memcmp((char *) &outtmp[0], - (char *) cksum->contents, - OLD_RSA_MD5_DES_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else -#endif /* MD5_K5BETA_COMPAT */ - if (cksum->length == (NEW_RSA_MD5_DES_CKSUM_LENGTH)) { - /* - * If we're verifying the correct implementation, then we have - * to do a little more work because we must decrypt the checksum - * because it contains the confounder in it. So, figure out - * what our key variant is and then do it! - */ - - /* Set up the variant of the key (see RFC 1510 section 6.4.5) */ - memset((char *) tmpkey, 0, sizeof(mit_des_cblock)); - for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++) - tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0; - - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *) tmpkey; - keyblock.enctype = ENCTYPE_DES_CBC_MD5; - - if ((retval = mit_des_process_key(&eblock, &keyblock))) - return retval; - /* now decrypt it */ - retval = mit_des_cbc_encrypt((mit_des_cblock *)cksum->contents, - (mit_des_cblock *)&outtmp[0], - NEW_RSA_MD5_DES_CKSUM_LENGTH, - (struct mit_des_ks_struct *) - eblock.priv, - zero_ivec, - MIT_DES_DECRYPT); - if (retval) { - (void) mit_des_finish_key(&eblock); - return retval; - } - if ((retval = mit_des_finish_key(&eblock))) - return(retval); - - /* Now that we have the decrypted checksum, try to regenerate it */ - krb5_md5_calculate_cksum(&working, - (krb5_pointer) outtmp, - (size_t) RSA_MD5_DES_CONFOUND_LENGTH, - in, - in_length); - - /* Compare the checksums */ - if (memcmp((char *) &outtmp[RSA_MD5_DES_CONFOUND_LENGTH], - (char *) &working.digest[0], - RSA_MD5_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - - /* Clean up droppings */ - memset((char *)&working, 0, sizeof(working)); - return(retval); -} - -krb5_checksum_entry rsa_md5_des_cksumtable_entry = -#if defined(MD5_K5BETA_COMPAT) && defined(MD5_K5BETA_COMPAT_DEF) -{ - 0, - krb5_md5_crypto_compat_sum_func, - krb5_md5_crypto_verify_func, - OLD_RSA_MD5_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#else /* MD5_K5BETA_COMPAT && MD5_K5BETA_COMPAT_DEF */ -{ - 0, - krb5_md5_crypto_sum_func, - krb5_md5_crypto_verify_func, - NEW_RSA_MD5_DES_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; -#endif /* MD5_K5BETA_COMPAT && MD5_K5BETA_COMPAT_DEF */ - -#ifdef MD5_K5BETA_COMPAT -/* - * Turn on/off compatible checksum generation. - */ -void -krb5_md5_crypto_compat_ctl(scompat) - krb5_boolean scompat; -{ - if (scompat) { - rsa_md5_des_cksumtable_entry.sum_func = krb5_md5_crypto_compat_sum_func; - rsa_md5_des_cksumtable_entry.checksum_length = - OLD_RSA_MD5_DES_CKSUM_LENGTH; - } - else { - rsa_md5_des_cksumtable_entry.sum_func = krb5_md5_crypto_sum_func; - rsa_md5_des_cksumtable_entry.checksum_length = - NEW_RSA_MD5_DES_CKSUM_LENGTH; - } -} -#endif /* MD5_K5BETA_COMPAT */ - diff --git a/src/lib/crypto/md5/md5glue.c b/src/lib/crypto/md5/md5glue.c deleted file mode 100644 index 66d5aa7917..0000000000 --- a/src/lib/crypto/md5/md5glue.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "k5-int.h" -#include "rsa-md5.h" - -/* Windows needs to these prototypes for the assignment below */ - -krb5_error_code -krb5_md5_sum_func PROTOTYPE(( - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_md5_verify_func PROTOTYPE(( - krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -krb5_error_code -krb5_md5_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD5_CTX working; - - if (outcksum->length < RSA_MD5_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - krb5_MD5Init(&working); - krb5_MD5Update(&working, input, in_length); - krb5_MD5Final(&working); - - outcksum->checksum_type = CKSUMTYPE_RSA_MD5; - outcksum->length = RSA_MD5_CKSUM_LENGTH; - - memcpy((char *)outcksum->contents, (char *)&working.digest[0], 16); - - memset((char *)&working, 0, sizeof(working)); - return 0; -} - -krb5_error_code -krb5_md5_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_MD5_CTX working; - krb5_error_code retval; - - retval = 0; - if (cksum->checksum_type == CKSUMTYPE_RSA_MD5) { - if (cksum->length == RSA_MD5_CKSUM_LENGTH) { - krb5_MD5Init(&working); - krb5_MD5Update(&working, input, in_length); - krb5_MD5Final(&working); - - if (memcmp((char *) cksum->contents, - (char *) &working.digest[0], - RSA_MD5_CKSUM_LENGTH)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - memset((char *)&working, 0, sizeof(working)); - } - else - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - else - retval = KRB5KRB_AP_ERR_INAPP_CKSUM; - return retval; -} - -krb5_checksum_entry rsa_md5_cksumtable_entry = { - 0, - krb5_md5_sum_func, - krb5_md5_verify_func, - RSA_MD5_CKSUM_LENGTH, - 1, /* is collision proof */ - 0, /* doesn't use key */ -}; diff --git a/src/lib/crypto/md5/t_cksum.c b/src/lib/crypto/md5/t_cksum.c deleted file mode 100644 index 5bc63709d2..0000000000 --- a/src/lib/crypto/md5/t_cksum.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * lib/crypto/md5/t_cksum.c - * - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -/* - * t_cksum.c - Test checksum and checksum compatability for rsa-md[4,5]-des - */ - -#ifndef MD -#define MD 5 -#endif /* MD */ - -#include "k5-int.h" -#if MD == 4 -#include "rsa-md4.h" -#endif /* MD == 4 */ -#if MD == 5 -#include "rsa-md5.h" -#endif /* MD == 5 */ -#include "des_int.h" - -#define MD5_K5BETA_COMPAT -#define MD4_K5BETA_COMPAT - -#if MD == 4 -#define CONFOUNDER_LENGTH RSA_MD4_DES_CONFOUND_LENGTH -#define NEW_CHECKSUM_LENGTH NEW_RSA_MD4_DES_CKSUM_LENGTH -#define OLD_CHECKSUM_LENGTH OLD_RSA_MD4_DES_CKSUM_LENGTH -#define CHECKSUM_TYPE CKSUMTYPE_RSA_MD4_DES -#ifdef MD4_K5BETA_COMPAT -#define K5BETA_COMPAT 1 -#else /* MD4_K5BETA_COMPAT */ -#undef K5BETA_COMPAT -#endif /* MD4_K5BETA_COMPAT */ -#define CKSUM_FUNCTION krb5_md4_crypto_sum_func -#define COMPAT_FUNCTION krb5_md4_crypto_compat_sum_func -#define VERIFY_FUNCTION krb5_md4_crypto_verify_func -#endif /* MD == 4 */ - -#if MD == 5 -#define CONFOUNDER_LENGTH RSA_MD5_DES_CONFOUND_LENGTH -#define NEW_CHECKSUM_LENGTH NEW_RSA_MD5_DES_CKSUM_LENGTH -#define OLD_CHECKSUM_LENGTH OLD_RSA_MD5_DES_CKSUM_LENGTH -#define CHECKSUM_TYPE CKSUMTYPE_RSA_MD5_DES -#ifdef MD5_K5BETA_COMPAT -#define K5BETA_COMPAT 1 -#else /* MD5_K5BETA_COMPAT */ -#undef K5BETA_COMPAT -#endif /* MD5_K5BETA_COMPAT */ -#define CKSUM_FUNCTION krb5_md5_crypto_sum_func -#define COMPAT_FUNCTION krb5_md5_crypto_compat_sum_func -#define VERIFY_FUNCTION krb5_md5_crypto_verify_func -#endif /* MD == 5 */ - -static void -print_checksum(text, number, message, checksum) - char *text; - int number; - char *message; - krb5_checksum *checksum; -{ - int i; - - printf("%s MD%d checksum(\"%s\") = ", text, number, message); - for (i=0; i<checksum->length; i++) - printf("%02x", checksum->contents[i]); - printf("\n"); -} - -/* - * Test the checksum verification of Old Style (tm) and correct RSA-MD[4,5]-DES - * checksums. - */ -int -main(argc, argv) - int argc; - char **argv; -{ - int msgindex; - krb5_context kcontext; - krb5_encrypt_block encblock; - krb5_keyblock keyblock; - krb5_error_code kret; - krb5_checksum oldstyle_checksum; - krb5_checksum newstyle_checksum; - krb5_data pwdata; - char *pwd; - - pwd = "test password"; - pwdata.length = strlen(pwd); - pwdata.data = pwd; - krb5_use_enctype(kcontext, &encblock, DEFAULT_KDC_ENCTYPE); - if ((kret = mit_des_string_to_key(&encblock, &keyblock, &pwdata, NULL))) { - printf("mit_des_string_to_key choked with %d\n", kret); - return(kret); - } - if ((kret = mit_des_process_key(&encblock, &keyblock))) { - printf("mit_des_process_key choked with %d\n", kret); - return(kret); - } - - oldstyle_checksum.length = OLD_CHECKSUM_LENGTH; - if (!(oldstyle_checksum.contents = (krb5_octet *) malloc(OLD_CHECKSUM_LENGTH))) { - printf("cannot get memory for old style checksum\n"); - return(ENOMEM); - } - newstyle_checksum.length = NEW_CHECKSUM_LENGTH; - if (!(newstyle_checksum.contents = (krb5_octet *) - malloc(NEW_CHECKSUM_LENGTH))) { - printf("cannot get memory for new style checksum\n"); - return(ENOMEM); - } - for (msgindex = 1; msgindex < argc; msgindex++) { - if ((kret = CKSUM_FUNCTION(argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length, - &newstyle_checksum))) { - printf("krb5_calculate_checksum choked with %d\n", kret); - break; - } - print_checksum("correct", MD, argv[msgindex], &newstyle_checksum); -#ifdef K5BETA_COMPAT - if ((kret = COMPAT_FUNCTION(argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length, - &oldstyle_checksum))) { - printf("old style calculate_checksum choked with %d\n", kret); - break; - } - print_checksum("old", MD, argv[msgindex], &oldstyle_checksum); -#endif /* K5BETA_COMPAT */ - if ((kret = VERIFY_FUNCTION(&newstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on new checksum choked with %d\n", kret); - break; - } - printf("Verify succeeded for \"%s\"\n", argv[msgindex]); -#ifdef K5BETA_COMPAT - if ((kret = VERIFY_FUNCTION(&oldstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on old checksum choked with %d\n", kret); - break; - } - printf("Compatible checksum verify succeeded for \"%s\"\n", - argv[msgindex]); -#endif /* K5BETA_COMPAT */ - newstyle_checksum.contents[0]++; - if (!(kret = VERIFY_FUNCTION(&newstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on new checksum should have choked\n"); - break; - } - printf("Verify of bad checksum OK for \"%s\"\n", argv[msgindex]); -#ifdef K5BETA_COMPAT - oldstyle_checksum.contents[0]++; - if (!(kret = VERIFY_FUNCTION(&oldstyle_checksum, - argv[msgindex], - strlen(argv[msgindex]), - (krb5_pointer) keyblock.contents, - keyblock.length))) { - printf("verify on old checksum should have choked\n"); - break; - } - printf("Compatible checksum verify of altered checksum OK for \"%s\"\n", - argv[msgindex]); -#endif /* K5BETA_COMPAT */ - kret = 0; - } - if (!kret) - printf("%d tests passed successfully for MD%d checksum\n", argc-1, MD); - return(kret); -} diff --git a/src/lib/crypto/nfold.c b/src/lib/crypto/nfold.c new file mode 100644 index 0000000000..07c539ebea --- /dev/null +++ b/src/lib/crypto/nfold.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include <memory.h> + +/* +n-fold(k-bits): + l = lcm(n,k) + r = l/k + s = k-bits | k-bits rot 13 | k-bits rot 13*2 | ... | k-bits rot 13*(r-1) + compute the 1's complement sum: + n-fold = s[0..n-1]+s[n..2n-1]+s[2n..3n-1]+..+s[(k-1)*n..k*n-1] +*/ + +/* representation: msb first, assume n and k are multiples of 8, and + that k>=16. this is the case of all the cryptosystems which are + likely to be used. this function can be replaced if that + assumption ever fails. */ + +/* input length is in bits */ + +void +krb5_nfold(inbits, in, outbits, out) + int inbits; + krb5_const unsigned char *in; + int outbits; + unsigned char *out; +{ + int a,b,c,gcd,lcm; + int reps; + int byte, i, msbit; + + /* the code below is more readable if I make these bytes + instead of bits */ + + inbits >>= 3; + outbits >>= 3; + + /* first compute lcm(n,k) */ + + a = outbits; + b = inbits; + + while(b != 0) { + c = b; + b = a%b; + a = c; + } + + lcm = outbits*inbits/a; + + /* now do the real work */ + + memset(out, 0, outbits); + byte = 0; + + /* this will end up cycling through k lcm(k,n)/k times, which + is correct */ + for (i=lcm-1; i>=0; i--) { + /* compute the msbit in k which gets added into this byte */ + msbit = (/* first, start with the msbit in the first, unrotated + byte */ + ((inbits<<3)-1) + /* then, for each byte, shift to the right for each + repetition */ + +(((inbits<<3)+13)*(i/inbits)) + /* last, pick out the correct byte within that + shifted repetition */ + +((inbits-(i%inbits))<<3) + )%(inbits<<3); + + /* pull out the byte value itself */ + byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| + (in[((inbits)-(msbit>>3))%inbits])) + >>((msbit&7)+1))&0xff; + + /* do the addition */ + byte += out[i%outbits]; + out[i%outbits] = byte&0xff; + +#if 0 + printf("msbit[%d] = %d\tbyte = %02x\tsum = %03x\n", i, msbit, + (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| + (in[((inbits)-(msbit>>3))%inbits])) + >>((msbit&7)+1))&0xff, byte); +#endif + + /* keep around the carry bit, if any */ + byte >>= 8; + +#if 0 + printf("carry=%d\n", byte); +#endif + } + + /* if there's a carry bit left over, add it back in */ + if (byte) { + for (i=outbits-1; i>=0; i--) { + /* do the addition */ + byte += out[i]; + out[i] = byte&0xff; + + /* keep around the carry bit, if any */ + byte >>= 8; + } + } +} + diff --git a/src/lib/crypto/old_api_glue.c b/src/lib/crypto/old_api_glue.c new file mode 100644 index 0000000000..64be9b8891 --- /dev/null +++ b/src/lib/crypto/old_api_glue.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +krb5_error_code krb5_encrypt(context, inptr, outptr, size, eblock, ivec) + krb5_context context; + krb5_const krb5_pointer inptr; + krb5_pointer outptr; + krb5_const size_t size; + krb5_encrypt_block FAR * eblock; + krb5_pointer ivec; +{ + krb5_data inputd, ivecd; + krb5_enc_data outputd; + size_t blocksize, outlen; + krb5_error_code ret; + + if (ivec) { + if (ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + /* size is the length of the input cleartext data */ + inputd.length = size; + inputd.data = inptr; + + /* The size of the output buffer isn't part of the old api. Not too + safe. So, we assume here that it's big enough. */ + if (ret = krb5_c_encrypt_length(context, eblock->key->enctype, size, + &outlen)) + return(ret); + + outputd.ciphertext.length = outlen; + outputd.ciphertext.data = outptr; + + return(krb5_c_encrypt(context, eblock->key, 0, ivec?&ivecd:0, + &inputd, &outputd)); +} + +krb5_error_code krb5_decrypt(context, inptr, outptr, size, eblock, ivec) + krb5_context context; + krb5_const krb5_pointer inptr; + krb5_pointer outptr; + krb5_const size_t size; + krb5_encrypt_block FAR * eblock; + krb5_pointer ivec; +{ + krb5_enc_data inputd; + krb5_data outputd, ivecd; + size_t blocksize; + krb5_error_code ret; + + if (ivec) { + if (ret = krb5_c_block_size(context, eblock->key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + /* size is the length of the input ciphertext data */ + inputd.enctype = eblock->key->enctype; + inputd.ciphertext.length = size; + inputd.ciphertext.data = inptr; + + /* we don't really know how big this is, but the code tends to assume + that the output buffer size should be the same as the input + buffer size */ + outputd.length = size; + outputd.data = outptr; + + return(krb5_c_decrypt(context, eblock->key, 0, ivec?&ivecd:0, + &inputd, &outputd)); +} + +krb5_error_code krb5_process_key(context, eblock, key) + krb5_context context; + krb5_encrypt_block FAR * eblock; + krb5_const krb5_keyblock FAR * key; +{ + eblock->key = (krb5_keyblock *) key; + + return(0); +} + +krb5_error_code krb5_finish_key(context, eblock) + krb5_context context; + krb5_encrypt_block FAR * eblock; +{ + return(0); +} + +krb5_error_code krb5_string_to_key(context, eblock, keyblock, data, salt) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_keyblock FAR * keyblock; + krb5_const krb5_data FAR * data; + krb5_const krb5_data FAR * salt; +{ + return(krb5_c_string_to_key(context, eblock->crypto_entry, data, salt, + keyblock)); +} + +krb5_error_code krb5_init_random_key(context, eblock, keyblock, ptr) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_const krb5_keyblock FAR * keyblock; + krb5_pointer FAR * ptr; +{ + krb5_data data; + + data.length = keyblock->length; + data.data = keyblock->contents; + + return(krb5_c_random_seed(context, &data)); +} + +krb5_error_code krb5_finish_random_key(context, eblock, ptr) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_pointer FAR * ptr; +{ + return(0); +} + +krb5_error_code krb5_random_key(context, eblock, ptr, keyblock) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; + krb5_pointer ptr; + krb5_keyblock FAR * FAR * keyblock; +{ + krb5_keyblock *key; + krb5_error_code ret; + + if ((key = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL) + return(ENOMEM); + + if (ret = krb5_c_make_random_key(context, eblock->crypto_entry, key)) + free(key); + + *keyblock = key; + + return(ret); +} + +krb5_enctype krb5_eblock_enctype(context, eblock) + krb5_context context; + krb5_const krb5_encrypt_block FAR * eblock; +{ + return(eblock->crypto_entry); +} + +krb5_error_code krb5_use_enctype(context, eblock, enctype) + krb5_context context; + krb5_encrypt_block FAR * eblock; + krb5_const krb5_enctype enctype; +{ + eblock->crypto_entry = enctype; + + return(0); +} + +size_t krb5_encrypt_size(length, crypto) + size_t length; + krb5_enctype crypto; +{ + size_t ret; + + if (krb5_c_encrypt_length(/* XXX */ 0, crypto, length, &ret)) + return(-1); /* XXX */ + + return(ret); +} + +size_t krb5_checksum_size(context, ctype) + krb5_context context; + krb5_cksumtype ctype; +{ + size_t ret; + + if (krb5_c_checksum_length(context, ctype, &ret)) + return(-1); /* XXX */ + + return(ret); +} + +krb5_error_code krb5_calculate_checksum(context, ctype, in, in_length, + seed, seed_length, outcksum) + krb5_context context; + krb5_const krb5_cksumtype ctype; + krb5_const krb5_pointer in; + krb5_const size_t in_length; + krb5_const krb5_pointer seed; + krb5_const size_t seed_length; + krb5_checksum FAR * outcksum; +{ + krb5_data input; + krb5_keyblock key; + krb5_error_code ret; + krb5_checksum cksum; + + input.data = in; + input.length = in_length; + + key.length = seed_length; + key.contents = seed; + + if (ret = krb5_c_make_checksum(context, ctype, &key, 0, &input, &cksum)) + return(ret); + + if (outcksum->length < cksum.length) { + memset(cksum.contents, 0, cksum.length); + free(cksum.contents); + return(KRB5_BAD_MSIZE); + } + + outcksum->magic = cksum.magic; + outcksum->checksum_type = cksum.checksum_type; + memcpy(outcksum->contents, cksum.contents, cksum.length); + outcksum->length = cksum.length; + + free(cksum.contents); + + return(0); +} + +krb5_error_code krb5_verify_checksum(context, ctype, cksum, in, in_length, + seed, seed_length) + krb5_context context; + krb5_cksumtype ctype; + krb5_const krb5_checksum FAR * cksum; + krb5_const krb5_pointer in; + krb5_const size_t in_length; + krb5_const krb5_pointer seed; + krb5_const size_t seed_length; +{ + krb5_data input; + krb5_keyblock key; + krb5_error_code ret; + krb5_boolean valid; + + input.data = in; + input.length = in_length; + + key.length = seed_length; + key.contents = seed; + + if (ret = krb5_c_verify_checksum(context, &key, 0, &input, cksum, + &valid)) + return(ret); + + if (!valid) + return(KRB5KRB_AP_ERR_BAD_INTEGRITY); + + return(0); +} + +krb5_error_code krb5_random_confounder(size, ptr) + size_t size; + krb5_pointer ptr; +{ + krb5_data random; + + random.length = size; + random.data = ptr; + + return(krb5_c_random_make_octets(/* XXX */ 0, &random)); +} + +krb5_error_code krb5_encrypt_data(context, key, ivec, data, enc_data) + krb5_context context; + krb5_keyblock *key; + krb5_pointer ivec; + krb5_data *data; + krb5_enc_data *enc_data; +{ + krb5_error_code ret; + size_t enclen, blocksize; + krb5_data ivecd; + + if (ret = krb5_c_encrypt_length(context, key->enctype, data->length, + &enclen)) + return(ret); + + if (ivec) { + if (ret = krb5_c_block_size(context, key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + enc_data->magic = KV5M_ENC_DATA; + enc_data->kvno = 0; + enc_data->enctype = key->enctype; + enc_data->ciphertext.length = enclen; + if ((enc_data->ciphertext.data = malloc(enclen)) == NULL) + return(ENOMEM); + + if (ret = krb5_c_encrypt(context, key, 0, ivec?&ivecd:0, data, enc_data)) + free(enc_data->ciphertext.data); + + return(ret); +} + +krb5_error_code krb5_decrypt_data(context, key, ivec, enc_data, data) + krb5_context context; + krb5_keyblock *key; + krb5_pointer ivec; + krb5_enc_data *enc_data; + krb5_data *data; +{ + krb5_error_code ret; + krb5_data ivecd; + size_t blocksize; + + if (ivec) { + if (ret = krb5_c_block_size(context, key->enctype, &blocksize)) + return(ret); + + ivecd.length = blocksize; + ivecd.data = ivec; + } + + data->length = enc_data->ciphertext.length; + if ((data->data = (krb5_octet *) malloc(data->length)) == NULL) + return(ENOMEM); + + if (ret = krb5_c_decrypt(context, key, 0, ivec?&ivecd:0, enc_data, data)) + free(data->data); + + return(0); +} diff --git a/src/lib/crypto/os/.Sanitize b/src/lib/crypto/os/.Sanitize deleted file mode 100644 index 2e24ee69f4..0000000000 --- a/src/lib/crypto/os/.Sanitize +++ /dev/null @@ -1,39 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -.cvsignore -ChangeLog -Makefile.in -configure -configure.in -c_localaddr.c -c_ustime.c -rnd_confoun.c - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/src/lib/crypto/os/ChangeLog b/src/lib/crypto/os/ChangeLog deleted file mode 100644 index ebcb593a1b..0000000000 --- a/src/lib/crypto/os/ChangeLog +++ /dev/null @@ -1,204 +0,0 @@ -Wed Feb 18 16:08:30 1998 Tom Yu <tlyu@mit.edu> - - * Makefile.in: Remove trailing slash from thisconfigdir. Fix up - BUILDTOP for new conventions. - -Fri Feb 13 15:20:54 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * Makefile.in (thisconfigdir), configure.in: Point the - configuration directory at our parent, and remove our - local configure.in - -Mon Feb 2 17:02:29 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * Makefile.in: Define BUILDTOP and thisconfigdir in the Makefile - -Fri Nov 28 21:23:42 1997 Tom Yu <tlyu@mit.edu> - - * configure.in: Add AC_PROG_LN_S to deal with symlinking in - memmove.c. This is a kludge, as we really should have a more sane - way to deal with missing posix functions. - -Thu Sep 25 21:53:11 1997 Tom Yu <tlyu@mit.edu> - - * c_localaddr.c: Replace KRB5_USE_INET with something more sane. - -Tue Aug 12 09:09:14 1997 Ezra Peisach <epeisach@mit.edu> - - * Makefile.in (SRCS): Add $(srcdir) as needed. - -Fri Jul 4 00:13:02 1997 Theodore Y. Ts'o <tytso@mit.edu> - - * c_localaddr.c (local_addr_fallback_kludge): Added Winsock - kludge for finding your local IP address. May not work - for all stacks, so we use it as a fallback. - -Sat Feb 22 18:54:53 1997 Richard Basch <basch@lehman.com> - - * Makefile.in: Use some of the new library list build rules in - win-post.in - -Mon Feb 17 17:24:41 1997 Richard Basch <basch@lehman.com> - - * c_ustime.c: Fixed microsecond adjustment code (win32) - -Thu Nov 21 00:58:04 EST 1996 Richard Basch <basch@lehman.com> - - * Makefile.in: Win32 build - - * c_ustime.c: The Win32 time calculation is different from DOS' - so the DOS version shouldn't be trying to use the same - part of the ifdef. - - * rnd_confoun.c: Fix function declaration (win32) - -Sun Dec 29 21:54:42 1996 Tom Yu <tlyu@mit.edu> - - * Makefile.in: - * configure.in: Update to use new library building procedure. - -Wed Jun 12 00:12:52 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * c_ustime.c: Fix WIN32 to be _WIN32 - - * c_localaddr.c: Add #ifdef _WIN32 in places where we had #ifdef _MSDOS - - -Sat Feb 24 00:34:15 1996 Theodore Y. Ts'o <tytso@dcl> - - * c_ustime.c (krb5_crypto_us_timeofday): Add Windows 95/NT time - function. (Does this time function work under Windows? - We'll find out....) - -Thu Feb 15 10:57:27 1996 Ezra Peisach <epeisach@kangaroo.mit.edu> - - * c_localaddr.c: Set magic number in krb5_address. - -Fri Oct 6 22:00:48 1995 Theodore Y. Ts'o <tytso@dcl> - - * Makefile.in: Remove ##DOS!include of config/windows.in. - config/windows.in is now included by wconfig. - -Mon Sep 25 16:49:15 1995 Theodore Y. Ts'o <tytso@dcl> - - * Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the - Makefile. - -Fri Sep 22 12:00:00 1995 James Mattly <mattly@fusion.com> - - * c_localaddr.c: change close on a socket to closesocket, sockets on - macintosh arn't files - -Wed Sep 13 10:33:53 1995 Keith Vetter (keithv@fusion.com) - - * Makefile.in: PC builds all C files because of function name changes. - * c_localtime.c, c_ustime.c: removed INTERFACE keyword. - -Wed Sep 13 17:32:36 1995 Theodore Y. Ts'o <tytso@dcl> - - * c_localaddr.c (krb5_crypto_os_localaddr): Clear the buffer - before calling the SIOCGIFCONF ioctl. This makes purify - happy. - -Thu Sep 7 12:00:00 1995 James Mattly <mattly@fusion.com> - - * Renamed ustime.c to c_ustime.c - * Renamed localaddr.c to c_localaddr.c because Mac can't have - two files with the same name. - * Makefile.in, .Sanitize updated for the above change. - -Thu Aug 24 18:40:48 1995 Theodore Y. Ts'o <tytso@dcl> - - * .Sanitize: Update file list - -Sat Jul 29 03:17:21 1995 Tom Yu <tlyu@lothlorien.MIT.EDU> - - * localaddr.c (krb5_crypto_os_localaddr): Don't bash the return - from SIOCGIFCONF with the output of a SIOCGIFFLAGS. Duh. - -Wed Jul 19 17:17:54 1995 Tom Yu <tlyu@lothlorien.MIT.EDU> - - * localaddr.c: also add definition of max if it's not there. - - * localaddr.c: fix definition of ifreq_size so it actually works - -Mon Jul 17 16:04:00 1995 Sam Hartman <hartmans@tertius.mit.edu> - - * localaddr.c (krb5_crypto_os_localaddr): Deal with variable sized - ifreq structures if sockaddr contains sa_len field. - - * configure.in: Check to see if struct sockaddr has sa_len. - -Thu Jul 6 17:13:11 1995 Tom Yu <tlyu@lothlorien.MIT.EDU> - - * localaddr.c: migrated from lib/krb5/os - - * ustime.c: migrated from lib/krb5/os; removed context variable - from arglist. - - * Makefile.in: don't copy or remove localaddr.c and ustime.c; - they're local now. - -Fri Jun 9 19:18:41 1995 <tytso@rsx-11.mit.edu> - - * configure.in: Remove standardized set of autoconf macros, which - are now handled by CONFIG_RULES. - -Thu May 25 22:16:35 1995 Theodore Y. Ts'o (tytso@dcl) - - * configure.in, Makefile.in: Add support for shared libraries. - -Thu Apr 13 15:49:16 1995 Keith Vetter (keithv@fusion.com) - - * *.[ch]: removed unneeded INTERFACE from non-api functions. - -Sat Mar 25 15:38:23 1995 Mark Eichin <eichin@cygnus.com> - - * Makefile.in (memmove.c): memmove.c is in krb5/posix, not krb5/os. - -Wed Mar 22 11:44:07 1995 <tytso@rsx-11.mit.edu> - - * Makefile.in: Use $(SRCTOP) instead of $(srcdir), since Mac's - don't like dealing with $(U)$(U). - -Fri Mar 17 16:21:46 1995 Theodore Y. Ts'o (tytso@dcl) - - * Makefile.in: Fix rules for localdr.c, ustime.c, and memmove.c so - that they reference $(srcdir) where appropriate. - -Thu Mar 16 21:24:43 1995 John Gilmore (gnu at toad.com) - - * Makefile.in (LDFLAGS): Eliminate, comes in from pre.in. - (all-mac): Add. - (localaddr.c, ustime.c, memmove.c): Fix paths to work on Mac. - -Tue Mar 14 17:23:02 1995 Keith Vetter (keithv@fusion.com) - - * Makefile.in: no longer need to bring in ustime and localaddr for - windows since everything's going into one DLL in the end. - -Thu Mar 2 17:56:48 1995 Keith Vetter (keithv@fusion.com) - - * Makefile.in: changed LIBNAME for the PC, and brought in ustime - and localaddr from the krb/os directory. - * rnd_conf.c: added cast to the seed assignment. - -Mon Feb 20 16:25:36 1995 Keith Vetter (keithv@fusion.com) - - * Makfile.in: made to work for the PC - * rnd_confoun.c: added windows INTERFACE keyword - -Wed Jan 25 20:24:35 1995 John Gilmore (gnu at toad.com) - - * rnd_confoun.c: Replace <.../...> includes with "..."s. - -Mon Oct 24 14:58:14 1994 (tytso@rsx-11) - - * configure.in: - * rnd_confoun.c (krb5_random_confounder): Use the srand48/lrand48 - functions if available. - -Fri Oct 14 00:21:05 1994 Theodore Y. Ts'o (tytso@dcl) - - * Makefile.in: Remove symlinked files on make clean. - diff --git a/src/lib/crypto/os/Makefile.in b/src/lib/crypto/os/Makefile.in deleted file mode 100644 index d4c5f41416..0000000000 --- a/src/lib/crypto/os/Makefile.in +++ /dev/null @@ -1,28 +0,0 @@ -thisconfigdir=./.. -BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) - -##DOS##BUILDTOP = ..\..\.. -##DOS##PREFIXDIR=os -##DOS##OBJFILE=..\os.lst -##WIN16##LIBNAME=..\crypto.lib - -STLIBOBJS = rnd_confoun.o c_localaddr.o c_ustime.o @LIBOBJS@ - -COBJS= rnd_confoun.$(OBJEXT) c_localaddr.$(OBJEXT) c_ustime.$(OBJEXT) -OBJS= $(COBJS) $(LIBOBJS) - -SRCS= $(srcdir)/rnd_confoun.c $(srcdir)/c_localaddr.c $(srcdir)/c_ustime.c - -##DOS##LIBOBJS = $(COBJS) - -all-unix:: all-libobjs - -memmove.c: $(SRCTOP)$(S)lib$(S)krb5$(S)posix$(S)memmove.c - -$(LN) $(SRCTOP)$(S)lib$(S)krb5$(S)posix$(S)memmove.c $@ - -memmove.o: memmove.c - -clean-unix:: clean-libobjs -clean:: - $(RM) memmove.c diff --git a/src/lib/crypto/os/c_localaddr.c b/src/lib/crypto/os/c_localaddr.c deleted file mode 100644 index 3b3bcb474f..0000000000 --- a/src/lib/crypto/os/c_localaddr.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * lib/crypto/os/c_localaddr.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * Return the protocol addresses supported by this host. - * - * XNS support is untested, but "Should just work". - */ - - -#define NEED_SOCKETS -#include "k5-int.h" - -#if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS) && !defined(_WIN32) - -/* needed for solaris, harmless elsewhere... */ -#define BSD_COMP -#include <sys/ioctl.h> -#include <sys/time.h> -#include <errno.h> - -/* - * The SIOCGIF* ioctls require a socket. - * It doesn't matter *what* kind of socket they use, but it has to be - * a socket. - * - * Of course, you can't just ask the kernel for a socket of arbitrary - * type; you have to ask for one with a valid type. - * - */ -#ifdef HAVE_NETINET_IN_H - -#include <netinet/in.h> - -#ifndef USE_AF -#define USE_AF AF_INET -#define USE_TYPE SOCK_DGRAM -#define USE_PROTO 0 -#endif - -#endif - -#ifdef KRB5_USE_NS - -#include <netns/ns.h> - -#ifndef USE_AF -#define USE_AF AF_NS -#define USE_TYPE SOCK_DGRAM -#define USE_PROTO 0 /* guess */ -#endif - -#endif -/* - * Add more address families here. - */ - -/* - * BSD 4.4 defines the size of an ifreq to be - * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len - * However, under earlier systems, sa_len isn't present, so the size is - * just sizeof(struct ifreq) - */ -#ifdef HAVE_SA_LEN -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif -#define ifreq_size(i) max(sizeof(struct ifreq),\ - sizeof((i).ifr_name)+(i).ifr_addr.sa_len) -#else -#define ifreq_size(i) sizeof(struct ifreq) -#endif /* HAVE_SA_LEN*/ - - - -extern int errno; - -/* - * Return all the protocol addresses of this host. - * - * We could kludge up something to return all addresses, assuming that - * they're valid kerberos protocol addresses, but we wouldn't know the - * real size of the sockaddr or know which part of it was actually the - * host part. - * - * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's. - */ - -krb5_error_code -krb5_crypto_os_localaddr(addr) - krb5_address ***addr; -{ - struct ifreq *ifr, ifreq; - struct ifconf ifc; - int s, code, n, i; - char buf[1024]; - krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ]; - int n_found; - int mem_err = 0; - - memset(buf, 0, sizeof(buf)); - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - - s = socket (USE_AF, USE_TYPE, USE_PROTO); - if (s < 0) - return errno; - - code = ioctl (s, SIOCGIFCONF, (char *)&ifc); - if (code < 0) { - int retval = errno; - closesocket (s); - return retval; - } - n = ifc.ifc_len; - -n_found = 0; - for (i = 0; i < n; i+= ifreq_size(*ifr) ) { - krb5_address *address; - ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i); - - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); - if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) - continue; - -#ifdef IFF_LOOPBACK - if (ifreq.ifr_flags & IFF_LOOPBACK) - continue; -#endif - - if (!(ifreq.ifr_flags & IFF_UP)) - /* interface is down; skip */ - continue; - - /* ifr->ifr_addr has what we want! */ - switch (ifr->ifr_addr.sa_family) { -#ifdef HAVE_NETINET_IN_H - case AF_INET: - { - struct sockaddr_in *in = - (struct sockaddr_in *)&ifr->ifr_addr; - - address = (krb5_address *) - malloc (sizeof(krb5_address)); - if (address) { - address->magic = KV5M_ADDRESS; - address->addrtype = ADDRTYPE_INET; - address->length = sizeof(struct in_addr); - address->contents = (unsigned char *)malloc(address->length); - if (!address->contents) { - krb5_xfree(address); - address = 0; - mem_err++; - } else { - memcpy ((char *)address->contents, - (char *)&in->sin_addr, - address->length); - break; - } - } else mem_err++; - } -#endif -#ifdef KRB5_USE_NS - case AF_XNS: - { - struct sockaddr_ns *ns = - (struct sockaddr_ns *)&ifr->ifr_addr; - address = (krb5_address *) - malloc (sizeof (krb5_address) + sizeof (struct ns_addr)); - if (address) { - address->magic = KV5M_ADDRESS; - address->addrtype = ADDRTYPE_XNS; - - /* XXX should we perhaps use ns_host instead? */ - - address->length = sizeof(struct ns_addr); - address->contents = (unsigned char *)malloc(address->length); - if (!address->contents) { - krb5_xfree(address); - address = 0; - mem_err++; - } else { - memcpy ((char *)address->contents, - (char *)&ns->sns_addr, - address->length); - break; - } - } else mem_err++; - break; - } -#endif - /* - * Add more address families here.. - */ - default: - continue; - } - if (address) - addr_temp[n_found++] = address; - address = 0; - } - closesocket(s); - - *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1)); - if (*addr == 0) - mem_err++; - - if (mem_err) { - for (i=0; i<n_found; i++) { - krb5_xfree(addr_temp[i]); - addr_temp[i] = 0; - } - return ENOMEM; - } - - for (i=0; i<n_found; i++) { - (*addr)[i] = addr_temp[i]; - } - (*addr)[n_found] = 0; - return 0; -} - -#else /* Windows/Mac version */ - -/* - * Hold on to your lunch! Backup kludge method of obtaining your - * local IP address, courtesy of Windows Socket Network Programming, - * by Robert Quinn - */ -#if defined(_MSDOS) || defined(_WIN32) -static struct hostent *local_addr_fallback_kludge() -{ - static struct hostent host; - static SOCKADDR_IN addr; - static char * ip_ptrs[2]; - SOCKET sock; - int size = sizeof(SOCKADDR); - int err; - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) - return NULL; - - /* connect to arbitrary port and address (NOT loopback) */ - addr.sin_family = AF_INET; - addr.sin_port = htons(IPPORT_ECHO); - addr.sin_addr.s_addr = inet_addr("204.137.220.51"); - - err = connect(sock, (LPSOCKADDR) &addr, sizeof(SOCKADDR)); - if (err == SOCKET_ERROR) - return NULL; - - err = getsockname(sock, (LPSOCKADDR) &addr, (int FAR *) size); - if (err == SOCKET_ERROR) - return NULL; - - closesocket(sock); - - host.h_name = 0; - host.h_aliases = 0; - host.h_addrtype = AF_INET; - host.h_length = 4; - host.h_addr_list = ip_ptrs; - ip_ptrs[0] = (char *) &addr.sin_addr.s_addr; - ip_ptrs[1] = NULL; - - return &host; -} -#endif - -/* No ioctls in winsock so we just assume there is only one networking - * card per machine, so gethostent is good enough. - */ -krb5_error_code -krb5_crypto_os_localaddr (krb5_address ***addr) { - char host[64]; /* Name of local machine */ - struct hostent *hostrec; - int err; - - *addr = calloc (2, sizeof (krb5_address *)); - if (*addr == NULL) - return ENOMEM; - -#ifdef HAVE_MACSOCK_H - hostrec = getmyipaddr(); -#else /* HAVE_MACSOCK_H */ - err = 0; - - if (gethostname (host, sizeof(host))) { - err = WSAGetLastError(); - } - - if (!err) { - hostrec = gethostbyname (host); - if (hostrec == NULL) { - err = WSAGetLastError(); - } - } - - if (err) { - hostrec = local_addr_fallback_kludge(); - if (!hostrec) - return err; - } -#endif /* HAVE_MACSOCK_H */ - - (*addr)[0] = calloc (1, sizeof(krb5_address)); - if ((*addr)[0] == NULL) { - free (*addr); - return ENOMEM; - } - (*addr)[0]->magic = KV5M_ADDRESS; - (*addr)[0]->addrtype = hostrec->h_addrtype; - (*addr)[0]->length = hostrec->h_length; - (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length); - if (!(*addr)[0]->contents) { - free((*addr)[0]); - free(*addr); - return ENOMEM; - } else { - memcpy ((*addr)[0]->contents, - hostrec->h_addr, - (*addr)[0]->length); - } - /* FIXME, deal with the case where gethostent returns multiple addrs */ - - return(0); -} -#endif diff --git a/src/lib/crypto/os/rnd_confoun.c b/src/lib/crypto/os/rnd_confoun.c deleted file mode 100644 index e904cb5c7a..0000000000 --- a/src/lib/crypto/os/rnd_confoun.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * lib/crypto/os/rnd_confoun.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * krb5_random_confounder() - */ - -#include "k5-int.h" - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#ifdef TIME_WITH_SYS_TIME -#include <time.h> -#endif -#else -#include <time.h> -#endif - -#ifdef HAVE_SRAND48 -#define SRAND srand48 -#define RAND lrand48 -#define RAND_TYPE long -#endif - -#if !defined(RAND_TYPE) && defined(HAVE_SRAND) -#define SRAND srand -#define RAND rand -#define RAND_TYPE int -#endif - -#if !defined(RAND_TYPE) && defined(HAVE_SRANDOM) -#define SRAND srandom -#define RAND random -#define RAND_TYPE long -#endif - -#if !defined(RAND_TYPE) -You need a random number generator! -#endif - -/* - * Generate a random confounder - */ -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_random_confounder(size, fillin) -size_t size; -krb5_pointer fillin; -{ - static int seeded = 0; - register krb5_octet *real_fill; - RAND_TYPE rval; - - if (!seeded) { - /* time() defined in 4.12.2.4, but returns a time_t, which is an - "arithmetic type" (4.12.1) */ - rval = (RAND_TYPE) time(0); - SRAND(rval); -#ifdef HAVE_GETPID - rval = RAND(); - rval ^= getpid(); - SRAND(rval); -#endif - seeded = 1; - } - - real_fill = (krb5_octet *)fillin; - while (size > 0) { - rval = RAND(); - *real_fill = rval & 0xff; - real_fill++; - size--; - if (size) { - *real_fill = (rval >> 8) & 0xff; - real_fill++; - size--; - } - } - return 0; -} diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c new file mode 100644 index 0000000000..2d4f6647d4 --- /dev/null +++ b/src/lib/crypto/prng.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "enc_provider.h" + +/* This random number generator is a feedback generator based on a + block cipher. It uses DES by default, since it guaranteed to be + present in the system, but can be changed. As new seed data comes + in, the old state is folded with the new seed into new state. Each + time random bytes are requested, the seed is used as a key and + cblock, and the encryption is used as the output. The output is + fed back as new seed data, as described above. */ + +/* this can be replaced with another encryption provider, since + everything below uses it abstractly */ + +struct krb5_enc_provider *enc = &krb5_enc_des; + +/* XXX state. Should it be in krb5_context? */ + +static int inited = 0; +static size_t blocksize, keybytes, keylength; +static int random_count; +/* keybytes | state-block | encblock | key | new-keybytes | new-state-block */ +static unsigned char *random_state; +#define STATE (random_state) +#define STATEKEY (STATE) +#define STATEBLOCK (STATEKEY+keybytes) +#define STATESIZE (keybytes+blocksize) +#define OUTPUT (STATE) +#define OUTPUTSIZE (STATESIZE+blocksize) +#define RANDBLOCK (STATEBLOCK+blocksize) +#define KEYCONTENTS (RANDBLOCK+blocksize) +#define NEWSTATE (KEYCONTENTS+keylength) +#define ALLSTATESIZE (keybytes+blocksize*2+keylength+keybytes+blocksize) + +krb5_error_code +krb5_c_random_seed(krb5_context context, krb5_data *data) +{ + unsigned char *fold_input; + + if (inited == 0) { + /* this does a bunch of malloc'ing up front, so that + generating random keys doesn't have to malloc, so it can't + fail. seeding still malloc's, but that's less common. */ + + enc->block_size(&blocksize); + enc->keysize(&keybytes, &keylength); + if ((random_state = (unsigned char *) malloc(ALLSTATESIZE)) == NULL) + return(ENOMEM); + random_count = 0; + inited = 1; + + krb5_nfold(data->length*8, data->data, STATESIZE*8, STATE); + + return(0); + } + + if ((fold_input = + (unsigned char *) malloc(data->length+STATESIZE)) == NULL) + return(ENOMEM); + + memcpy(fold_input, data->data, data->length); + memcpy(fold_input+data->length, STATE, STATESIZE); + + krb5_nfold((data->length+STATESIZE)*8, fold_input, + STATESIZE*8, STATE); + free(fold_input); + return(0); +} + +krb5_error_code +krb5_c_random_make_octets(krb5_context context, krb5_data *data) +{ + krb5_error_code ret; + krb5_data data1, data2; + krb5_keyblock key; + int bytes; + + if (inited == 0) { + /* i need some entropy. I'd use the current time and pid, but + that could cause portability problems. */ + abort(); + } + + bytes = 0; + + while (bytes < data->length) { + if (random_count == 0) { + /* set up random krb5_data, and key to be filled in */ + data1.length = keybytes; + data1.data = STATEKEY; + key.length = keylength; + key.contents = KEYCONTENTS; + + /* fill it in */ + if (ret = ((*(enc->make_key))(&data1, &key))) + return(ret); + + /* encrypt the block */ + data1.length = blocksize; + data1.data = STATEBLOCK; + data2.length = blocksize; + data2.data = RANDBLOCK; + if (ret = ((*(enc->encrypt))(&key, NULL, &data1, &data2))) + return(ret); + + /* fold the new output back into the state */ + + krb5_nfold(OUTPUTSIZE*8, OUTPUT, STATESIZE*8, NEWSTATE); + memcpy(STATE, NEWSTATE, STATESIZE); + + random_count = blocksize; + } + + if ((data->length - bytes) <= random_count) { + memcpy(data->data + bytes, RANDBLOCK+(blocksize-random_count), + data->length - bytes); + random_count -= (data->length - bytes); + break; + } + + memcpy(data->data + bytes, RANDBLOCK+(blocksize - random_count), + random_count); + + bytes += random_count; + random_count = 0; + } + + return(0); +} diff --git a/src/lib/crypto/raw_des.c b/src/lib/crypto/raw_des.c deleted file mode 100644 index 65e0ebdbbd..0000000000 --- a/src/lib/crypto/raw_des.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * lib/crypto/raw-des.c - * - * Copyright 1994, 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "k5-int.h" -#include "des_int.h" - -krb5_error_code mit_raw_des_encrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -krb5_error_code mit_raw_des_decrypt_func - PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t, - krb5_encrypt_block *, krb5_pointer )); - -static krb5_cryptosystem_entry mit_raw_des_cryptosystem_entry = { - 0, - mit_raw_des_encrypt_func, - mit_raw_des_decrypt_func, - mit_des_process_key, - mit_des_finish_key, - mit_des_string_to_key, - mit_des_init_random_key, - mit_des_finish_random_key, - mit_des_random_key, - sizeof(mit_des_cblock), - 0, - sizeof(mit_des_cblock), - ENCTYPE_DES_CBC_RAW - }; - -krb5_cs_table_entry krb5_raw_des_cst_entry = { - 0, - &mit_raw_des_cryptosystem_entry, - 0 - }; - -krb5_error_code -mit_raw_des_decrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - return (mit_des_cbc_encrypt ((const mit_des_cblock *) in, - out, - size, - (struct mit_des_ks_struct *)key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_DECRYPT)); -} - -krb5_error_code -mit_raw_des_encrypt_func(in, out, size, key, ivec) - krb5_const_pointer in; - krb5_pointer out; - const size_t size; - krb5_encrypt_block * key; - krb5_pointer ivec; -{ - int sumsize; - - /* round up to des block size */ - - sumsize = krb5_roundup(size, sizeof(mit_des_cblock)); - - /* assemble crypto input into the output area, then encrypt in place. */ - - memset((char *)out, 0, sumsize); - memcpy((char *)out, (char *)in, size); - - /* We depend here on the ability of this DES implementation to - encrypt plaintext to ciphertext in-place. */ - return (mit_des_cbc_encrypt (out, - out, - sumsize, - (struct mit_des_ks_struct *)key->priv, - ivec ? ivec : (krb5_pointer)key->key->contents, - MIT_DES_ENCRYPT)); -} diff --git a/src/lib/crypto/sha/.Sanitize b/src/lib/crypto/sha/.Sanitize deleted file mode 100644 index 886bb2b0a3..0000000000 --- a/src/lib/crypto/sha/.Sanitize +++ /dev/null @@ -1,42 +0,0 @@ -# Sanitize.in for Kerberos V5 - -# Each directory to survive it's way into a release will need a file -# like this one called "./.Sanitize". All keyword lines must exist, -# and must exist in the order specified by this file. Each directory -# in the tree will be processed, top down, in the following order. - -# Hash started lines like this one are comments and will be deleted -# before anything else is done. Blank lines will also be squashed -# out. - -# The lines between the "Do-first:" line and the "Things-to-keep:" -# line are executed as a /bin/sh shell script before anything else is -# done in this - -Do-first: - -# All files listed between the "Things-to-keep:" line and the -# "Files-to-sed:" line will be kept. All other files will be removed. -# Directories listed in this section will have their own Sanitize -# called. Directories not listed will be removed in their entirety -# with rm -rf. - -Things-to-keep: - -.cvsignore -ChangeLog -Makefile.in -configure -configure.in -sha_crypto.c -sha_glue.c -shs.c -shs.h -hmac_sha.c -t_shs.c - -Things-to-lose: - -Do-last: - -# End of file. diff --git a/src/lib/crypto/sha/ChangeLog b/src/lib/crypto/sha/ChangeLog deleted file mode 100644 index 19abbbf6ed..0000000000 --- a/src/lib/crypto/sha/ChangeLog +++ /dev/null @@ -1,89 +0,0 @@ -Wed Feb 18 16:09:05 1998 Tom Yu <tlyu@mit.edu> - - * Makefile.in: Remove trailing slash from thisconfigdir. Fix up - BUILDTOP for new conventions. - -Fri Feb 13 15:20:54 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * Makefile.in (thisconfigdir), configure.in: Point the - configuration directory at our parent, and remove our - local configure.in - -Mon Feb 2 17:02:29 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * Makefile.in: Define BUILDTOP and thisconfigdir in the Makefile - -Tue Oct 28 16:37:18 1997 Tom Yu <tlyu@voltage-multiplier.mit.edu> - - * shs.c, sha_glue.c, hmac_sha.c: Fix to deal with LONG wider than - 32 bits. - - * t_shs.c: Print out the actual and expected values on error. - -Sat Feb 22 18:52:09 1997 Richard Basch <basch@lehman.com> - - * Makefile.in: Use some of the new library list build rules in - win-post.in - -Thu Jan 30 21:31:39 1997 Richard Basch <basch@lehman.com> - - * sha_crypto.c sha_glue.c: - Declare the functions to take const args where possible - Remove extra includes - - * sha_crypto.c: Function prototypes did not match function names. - -Thu Nov 21 00:58:04 EST 1996 Richard Basch <basch@lehman.com> - - * Makefile.in: Win32 build fixed - -Sun Dec 29 21:56:35 1996 Tom Yu <tlyu@mit.edu> - - * Makefile.in: - * configure.in: Update to use new library build procedure. - -Wed Aug 28 17:40:53 1996 Theodore Ts'o <tytso@rsts-11.mit.edu> - - * shs.c: Only include sys/types.h if present. - - * configure.in: Check for sys/types.h - -Thu Jun 13 10:54:27 1996 Ezra Peisach <epeisach@kangaroo.mit.edu> - - * hmac_sha.c: Include string.h for memcpy prototype - -Sat Jun 8 07:44:35 1996 Ezra Peisach (epeisach@mit.edu) - - * shs.c (longReverse): Test for big vs little endian failed for - little endian machines. - -Thu Jun 6 15:43:26 1996 Theodore Y. Ts'o <tytso@mit.edu> - - * shs.c (longReverse): Don't use htonl(); it doesn't exist under - Windows. Instead do the test by casting a pointer to an - integer to a char *. - -Mon May 20 17:15:32 1996 Theodore Y. Ts'o <tytso@mit.edu> - - * t_shs.c (main): Don't do timing tests; it takes too long! - -Tue May 14 17:09:36 1996 Richard Basch <basch@lehman.com> - - * .Sanitize: reflect current files - * Makefile.in: added hmac-sha - * hmac_sha.c: implement HMAC-SHA - * sha_crypto.c: use hmac-sha - * sha_glue.c: sanity check the passed in checksum length - * shs.h: replaced sha-des3 with hmac-sha - -Fri May 10 11:19:53 1996 Ezra Peisach <epeisach@kangaroo.mit.edu> - - * shs.c (longReverse): Remove extraneous \. - (expand): Start #define in first column. - -Fri May 10 01:19:18 1996 Richard Basch <basch@lehman.com> - - * Makefile.in configure.in t_shs.c sha_glue.c sha_crypto.c shs.c shs.h: - Initial check-in of the functions to support the NIST FIPS 180 - SHA algorithm. Provide interfaces for cksum-sha, cksum-sha-des3. - (enctype-des3-sha is also being defined) diff --git a/src/lib/crypto/sha/Makefile.in b/src/lib/crypto/sha/Makefile.in deleted file mode 100644 index 058ac0db00..0000000000 --- a/src/lib/crypto/sha/Makefile.in +++ /dev/null @@ -1,43 +0,0 @@ -thisconfigdir=./.. -BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des - -##DOS##BUILDTOP = ..\..\.. -##DOS##PREFIXDIR=sha -##DOS##OBJFILE=..\sha.lst -##WIN16##LIBNAME=..\crypto.lib - -STLIBOBJS=shs.o hmac_sha.o sha_crypto.o sha_glue.o - -OBJS= shs.$(OBJEXT) \ - hmac_sha.$(OBJEXT) \ - sha_crypto.$(OBJEXT) \ - sha_glue.$(OBJEXT) - -SRCS= $(srcdir)/shs.c \ - $(srcdir)/hmac_sha.c \ - $(srcdir)/sha_crypto.c \ - $(srcdir)/sha_glue.c - - -##DOS##LIBOBJS = $(OBJS) - - -all-unix:: all-libobjs - -t_shs: t_shs.o shs.o - $(CC) $(CFLAGS) $(LDFLAGS) -o t_shs t_shs.o shs.o - -t_shs.exe: - $(CC) $(CFLAGS2) -o t_shs.exe t_shs.c shs.c - -check-unix:: t_shs - $(C)t_shs -x - -check-windows:: t_shs$(EXEEXT) - $(C)t_shs$(EXEEXT) -x - -clean:: - $(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT) - -clean-unix:: clean-libobjs diff --git a/src/lib/crypto/sha/hmac_sha.c b/src/lib/crypto/sha/hmac_sha.c deleted file mode 100644 index d57092e69a..0000000000 --- a/src/lib/crypto/sha/hmac_sha.c +++ /dev/null @@ -1,101 +0,0 @@ -#include <string.h> -#include "shs.h" - -#define PAD_SZ 64 - - -krb5_error_code -hmac_sha(text, text_len, key, key_len, digest) - krb5_octet * text; /* pointer to data stream */ - int text_len; /* length of data stream */ - krb5_octet * key; /* pointer to authentication key */ - int key_len; /* length of authentication key */ - krb5_octet * digest; /* caller digest to be filled in */ -{ - SHS_INFO context; - krb5_octet k_ipad[PAD_SZ]; /* inner padding - key XORd with ipad */ - krb5_octet k_opad[PAD_SZ]; /* outer padding - key XORd with opad */ - int i; - krb5_octet *cp; - LONG *lp; - - /* sanity check parameters */ - if (!text || !key || !digest) - /* most heinous, probably should log something */ - return EINVAL; - - /* if key is longer than 64 bytes reset it to key=SHA(key) */ - if (key_len > sizeof(k_ipad)) { - shsInit(&context); - shsUpdate(&context, key, key_len); - shsFinal(&context); - - cp = digest; - lp = context.digest; - while (cp < digest + SHS_DIGESTSIZE) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = *lp++ & 0xff; - } - key = digest; - key_len = SHS_DIGESTSIZE; - } - - /* - * the HMAC_SHA transform looks like: - * - * SHA(K XOR opad, SHA(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ - - /* start out by storing key in pads */ - memset(k_ipad, 0x36, sizeof(k_ipad)); - memset(k_opad, 0x5c, sizeof(k_opad)); - - /* XOR key with ipad and opad values */ - for (i = 0; i < key_len; i++) { - k_ipad[i] ^= key[i]; - k_opad[i] ^= key[i]; - } - - /* - * perform inner SHA - */ - shsInit(&context); - shsUpdate(&context, k_ipad, sizeof(k_ipad)); - shsUpdate(&context, text, text_len); - shsFinal(&context); - - cp = digest; - lp = context.digest; - while (cp < digest + SHS_DIGESTSIZE) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = *lp++ & 0xff; - } - - /* - * perform outer SHA - */ - shsInit(&context); - shsUpdate(&context, k_opad, sizeof(k_opad)); - shsUpdate(&context, digest, SHS_DIGESTSIZE); - shsFinal(&context); - - cp = digest; - lp = context.digest; - while (cp < digest + SHS_DIGESTSIZE) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = *lp++ & 0xff; - } - - return 0; -} diff --git a/src/lib/crypto/sha/sha_crypto.c b/src/lib/crypto/sha/sha_crypto.c deleted file mode 100644 index b539b1199f..0000000000 --- a/src/lib/crypto/sha/sha_crypto.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "shs.h" - -/* Windows needs to these prototypes for the assignment below */ - -static krb5_error_code -krb5_sha_crypto_sum_func - PROTOTYPE((krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -static krb5_error_code -krb5_sha_crypto_verify_func - PROTOTYPE((krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -static krb5_error_code -krb5_sha_crypto_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_error_code retval; - - if (outcksum->length < HMAC_SHA_CKSUM_LENGTH) - return KRB5_BAD_MSIZE; - - outcksum->checksum_type = CKSUMTYPE_HMAC_SHA; - outcksum->length = HMAC_SHA_CKSUM_LENGTH; - - retval = hmac_sha(in, in_length, seed, seed_length, outcksum->contents); - return retval; -} - -static krb5_error_code -krb5_sha_crypto_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet digest[HMAC_SHA_CKSUM_LENGTH]; - krb5_error_code retval; - - if (cksum->checksum_type != CKSUMTYPE_HMAC_SHA) - return KRB5KRB_AP_ERR_INAPP_CKSUM; - if (cksum->length != HMAC_SHA_CKSUM_LENGTH) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - - retval = hmac_sha(in, in_length, seed, seed_length, digest); - if (retval) goto cleanup; - - if (memcmp((char *)digest, (char *)cksum->contents, cksum->length)) - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - -cleanup: - memset((char *)digest, 0, sizeof(digest)); - return retval; -} - -krb5_checksum_entry hmac_sha_cksumtable_entry = -{ - 0, - krb5_sha_crypto_sum_func, - krb5_sha_crypto_verify_func, - HMAC_SHA_CKSUM_LENGTH, - 1, /* is collision proof */ - 1, /* uses key */ -}; diff --git a/src/lib/crypto/sha/sha_glue.c b/src/lib/crypto/sha/sha_glue.c deleted file mode 100644 index 58a93b7230..0000000000 --- a/src/lib/crypto/sha/sha_glue.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "shs.h" - -krb5_error_code -krb5_sha_sum_func - PROTOTYPE((krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length, - krb5_checksum FAR *outcksum)); - -krb5_error_code -krb5_sha_verify_func - PROTOTYPE((krb5_const krb5_checksum FAR *cksum, - krb5_const krb5_pointer in, - krb5_const size_t in_length, - krb5_const krb5_pointer seed, - krb5_const size_t seed_length)); - -krb5_error_code -krb5_sha_sum_func(in, in_length, seed, seed_length, outcksum) - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; - krb5_checksum FAR *outcksum; -{ - krb5_octet *input = (krb5_octet *)in; - krb5_octet *cp; - LONG *lp; - SHS_INFO working; - - if (outcksum->length < SHS_DIGESTSIZE) - return KRB5_BAD_MSIZE; - - shsInit(&working); - shsUpdate(&working, input, in_length); - shsFinal(&working); - - outcksum->checksum_type = CKSUMTYPE_NIST_SHA; - outcksum->length = SHS_DIGESTSIZE; - - cp = outcksum->contents; - lp = working.digest; - while (lp < working.digest + 16) { - *cp++ = (*lp >> 24) & 0xff; - *cp++ = (*lp >> 16) & 0xff; - *cp++ = (*lp >> 8) & 0xff; - *cp++ = (*lp++) & 0xff; - } - memset((char *)&working, 0, sizeof(working)); - return 0; -} - -krb5_error_code -krb5_sha_verify_func(cksum, in, in_length, seed, seed_length) - krb5_const krb5_checksum FAR *cksum; - krb5_const krb5_pointer in; - krb5_const size_t in_length; - krb5_const krb5_pointer seed; - krb5_const size_t seed_length; -{ - krb5_octet *input = (krb5_octet *)in; - SHS_INFO working; - krb5_error_code retval; - int i; - krb5_octet *cp; - - if (cksum->checksum_type != CKSUMTYPE_NIST_SHA) - return KRB5KRB_AP_ERR_INAPP_CKSUM; - if (cksum->length != SHS_DIGESTSIZE) - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - - shsInit(&working); - shsUpdate(&working, input, in_length); - shsFinal(&working); - - retval = 0; - for (i = 0, cp = cksum->contents; i < 5; i++, cp += 4) { - if (working.digest[i] != - (LONG) cp[0] << 24 | (LONG) cp[1] << 16 | - (LONG) cp[2] << 8 | (LONG) cp[3]) { - retval = KRB5KRB_AP_ERR_BAD_INTEGRITY; - break; - } - } - memset((char *) &working, 0, sizeof(working)); - return retval; -} - -krb5_checksum_entry nist_sha_cksumtable_entry = { - 0, - krb5_sha_sum_func, - krb5_sha_verify_func, - SHS_DIGESTSIZE, - 1, /* is collision proof */ - 0, /* doesn't use key */ -}; diff --git a/src/lib/crypto/sha/shs.c b/src/lib/crypto/sha/shs.c deleted file mode 100644 index e18f3af9e2..0000000000 --- a/src/lib/crypto/sha/shs.c +++ /dev/null @@ -1,392 +0,0 @@ -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#include <string.h> -#include "shs.h" - -/* The SHS f()-functions. The f1 and f3 functions can be optimized to - save one boolean operation each - thanks to Rich Schroeppel, - rcs@cs.arizona.edu for discovering this */ - -#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */ -#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ -#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */ -#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ - -/* The SHS Mysterious Constants */ - -#define K1 0x5A827999L /* Rounds 0-19 */ -#define K2 0x6ED9EBA1L /* Rounds 20-39 */ -#define K3 0x8F1BBCDCL /* Rounds 40-59 */ -#define K4 0xCA62C1D6L /* Rounds 60-79 */ - -/* SHS initial values */ - -#define h0init 0x67452301L -#define h1init 0xEFCDAB89L -#define h2init 0x98BADCFEL -#define h3init 0x10325476L -#define h4init 0xC3D2E1F0L - -/* Note that it may be necessary to add parentheses to these macros if they - are to be called with expressions as arguments */ - -/* 32-bit rotate left - kludged with shifts */ - -#define ROTL(n,X) (((X) << (n)) & 0xffffffff | ((X) >> (32 - n))) - -/* The initial expanding function. The hash function is defined over an - 80-word expanded input array W, where the first 16 are copies of the input - data, and the remaining 64 are defined by - - W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] - - This implementation generates these values on the fly in a circular - buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this - optimization. - - The updated SHS changes the expanding function by adding a rotate of 1 - bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor - for this information */ - -#ifdef NEW_SHS -#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \ - W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ))) -#else -#define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^ \ - W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) -#endif /* NEW_SHS */ - -/* The prototype SHS sub-round. The fundamental sub-round is: - - a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; - b' = a; - c' = ROTL( 30, b ); - d' = c; - e' = d; - - but this is implemented by unrolling the loop 5 times and renaming the - variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. - This code is then replicated 20 times for each of the 4 functions, using - the next 20 values from the W[] array each time */ - -#define subRound(a, b, c, d, e, f, k, data) \ - ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, \ - e &= 0xffffffff, b = ROTL( 30, b ) ) - -/* Initialize the SHS values */ - -void shsInit(shsInfo) - SHS_INFO *shsInfo; -{ - /* Set the h-vars to their initial values */ - shsInfo->digest[ 0 ] = h0init; - shsInfo->digest[ 1 ] = h1init; - shsInfo->digest[ 2 ] = h2init; - shsInfo->digest[ 3 ] = h3init; - shsInfo->digest[ 4 ] = h4init; - - /* Initialise bit count */ - shsInfo->countLo = shsInfo->countHi = 0; -} - -/* Perform the SHS transformation. Note that this code, like MD5, seems to - break some optimizing compilers due to the complexity of the expressions - and the size of the basic block. It may be necessary to split it into - sections, e.g. based on the four subrounds - - Note that this corrupts the shsInfo->data area */ - -static void SHSTransform KRB5_PROTOTYPE((LONG *digest, LONG *data)); - -static -void SHSTransform(digest, data) - LONG *digest; - LONG *data; -{ - LONG A, B, C, D, E; /* Local vars */ - LONG eData[ 16 ]; /* Expanded data */ - - /* Set up first buffer and local data buffer */ - A = digest[ 0 ]; - B = digest[ 1 ]; - C = digest[ 2 ]; - D = digest[ 3 ]; - E = digest[ 4 ]; - memcpy(eData, data, sizeof (eData)); - - /* Heavy mangling, in 4 sub-rounds of 20 interations each. */ - subRound( A, B, C, D, E, f1, K1, eData[ 0 ] ); - subRound( E, A, B, C, D, f1, K1, eData[ 1 ] ); - subRound( D, E, A, B, C, f1, K1, eData[ 2 ] ); - subRound( C, D, E, A, B, f1, K1, eData[ 3 ] ); - subRound( B, C, D, E, A, f1, K1, eData[ 4 ] ); - subRound( A, B, C, D, E, f1, K1, eData[ 5 ] ); - subRound( E, A, B, C, D, f1, K1, eData[ 6 ] ); - subRound( D, E, A, B, C, f1, K1, eData[ 7 ] ); - subRound( C, D, E, A, B, f1, K1, eData[ 8 ] ); - subRound( B, C, D, E, A, f1, K1, eData[ 9 ] ); - subRound( A, B, C, D, E, f1, K1, eData[ 10 ] ); - subRound( E, A, B, C, D, f1, K1, eData[ 11 ] ); - subRound( D, E, A, B, C, f1, K1, eData[ 12 ] ); - subRound( C, D, E, A, B, f1, K1, eData[ 13 ] ); - subRound( B, C, D, E, A, f1, K1, eData[ 14 ] ); - subRound( A, B, C, D, E, f1, K1, eData[ 15 ] ); - subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) ); - subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) ); - subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) ); - subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) ); - - subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) ); - subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) ); - subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) ); - subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) ); - subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) ); - subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) ); - subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) ); - subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) ); - - subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) ); - subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) ); - subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) ); - subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) ); - subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) ); - subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) ); - subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) ); - subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) ); - - subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) ); - subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) ); - subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) ); - subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) ); - subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) ); - subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) ); - subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) ); - subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) ); - - /* Build message digest */ - digest[ 0 ] += A; - digest[ 0 ] &= 0xffffffff; - digest[ 1 ] += B; - digest[ 1 ] &= 0xffffffff; - digest[ 2 ] += C; - digest[ 2 ] &= 0xffffffff; - digest[ 3 ] += D; - digest[ 3 ] &= 0xffffffff; - digest[ 4 ] += E; - digest[ 4 ] &= 0xffffffff; -} - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. It is possible to make the code endianness- - independant by fiddling around with data at the byte level, but this - makes for very slow code, so we rely on the user to sort out endianness - at compile time */ - -void longReverse( LONG *buffer, int byteCount ) -{ - LONG value; - static int init = 0; - char *cp; - - switch (init) { - case 0: - init=1; - cp = (char *) &init; - if (*cp == 1) { - init=2; - break; - } - init=1; - /* fall through - MSB */ - case 1: - return; - } - - byteCount /= sizeof( LONG ); - while( byteCount-- ) { - value = *buffer; - value = ( ( value & 0xFF00FF00L ) >> 8 ) | - ( ( value & 0x00FF00FFL ) << 8 ); - *buffer++ = ( value << 16 ) | ( value >> 16 ); - } -} - -/* Update SHS for a block of data */ - -void shsUpdate(shsInfo, buffer, count) - SHS_INFO *shsInfo; - BYTE *buffer; - int count; -{ - LONG tmp; - int dataCount, canfill; - LONG *lp; - - /* Update bitcount */ - tmp = shsInfo->countLo; - shsInfo->countLo = tmp + (((LONG) count) << 3 ); - if ((shsInfo->countLo &= 0xffffffff) < tmp) - shsInfo->countHi++; /* Carry from low to high */ - shsInfo->countHi += count >> 29; - - /* Get count of bytes already in data */ - dataCount = (int) (tmp >> 3) & 0x3F; - - /* Handle any leading odd-sized chunks */ - if (dataCount) { - lp = shsInfo->data + dataCount / 4; - canfill = (count >= dataCount); - dataCount = SHS_DATASIZE - dataCount; - - if (dataCount % 4) { - /* Fill out a full 32 bit word first if needed -- this - is not very efficient (computed shift amount), - but it shouldn't happen often. */ - while (dataCount % 4 && count > 0) { - *lp |= (LONG) *buffer++ << ((3 - dataCount++ % 4) * 8); - count--; - } - lp++; - } - while (lp < shsInfo->data + 16) { - *lp = (LONG) *buffer++ << 24; - *lp |= (LONG) *buffer++ << 16; - *lp |= (LONG) *buffer++ << 8; - *lp++ |= (LONG) *buffer++; - if ((count -= 4) < 4 && lp < shsInfo->data + 16) { - *lp = 0; - switch (count % 4) { - case 3: - *lp |= (LONG) buffer[2] << 8; - case 2: - *lp |= (LONG) buffer[1] << 16; - case 1: - *lp |= (LONG) buffer[0] << 24; - } - break; - count = 0; - } - } - if (canfill) { - SHSTransform(shsInfo->digest, shsInfo->data); - } - } - - /* Process data in SHS_DATASIZE chunks */ - while (count >= SHS_DATASIZE) { - lp = shsInfo->data; - while (lp < shsInfo->data + 16) { - *lp = ((LONG) *buffer++) << 24; - *lp |= ((LONG) *buffer++) << 16; - *lp |= ((LONG) *buffer++) << 8; - *lp++ |= (LONG) *buffer++; - } - SHSTransform(shsInfo->digest, shsInfo->data); - count -= SHS_DATASIZE; - } - - if (count > 0) { - lp = shsInfo->data; - while (count > 4) { - *lp = ((LONG) *buffer++) << 24; - *lp |= ((LONG) *buffer++) << 16; - *lp |= ((LONG) *buffer++) << 8; - *lp++ |= (LONG) *buffer++; - count -= 4; - } - *lp = 0; - switch (count % 4) { - case 0: - *lp |= ((LONG) buffer[3]); - case 3: - *lp |= ((LONG) buffer[2]) << 8; - case 2: - *lp |= ((LONG) buffer[1]) << 16; - case 1: - *lp |= ((LONG) buffer[0]) << 24; - } - } -} - -/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern - 1 0* (64-bit count of bits processed, MSB-first) */ - -void shsFinal(shsInfo) - SHS_INFO *shsInfo; -{ - int count; - LONG *lp; - BYTE *dataPtr; - - /* Compute number of bytes mod 64 */ - count = (int) shsInfo->countLo; - count = (count >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - lp = shsInfo->data + count / 4; - switch (count % 4) { - case 3: - *lp++ |= (LONG) 0x80; - break; - case 2: - *lp++ |= (LONG) 0x80 << 8; - break; - case 1: - *lp++ |= (LONG) 0x80 << 16; - break; - case 0: - *lp++ = (LONG) 0x80 << 24; - } - - if (lp > shsInfo->data + 14) { - /* Pad out to 64 bytes if not enough room for length words */ - *lp = 0; - SHSTransform(shsInfo->digest, shsInfo->data); - lp = shsInfo->data; - } - /* Pad out to 56 bytes */ - while (lp < shsInfo->data + 14) - *lp++ = 0; - /* Append length in bits and transform */ - *lp++ = shsInfo->countHi; - *lp++ = shsInfo->countLo; - SHSTransform(shsInfo->digest, shsInfo->data); -} diff --git a/src/lib/crypto/sha/shs.h b/src/lib/crypto/sha/shs.h deleted file mode 100644 index 01acddb825..0000000000 --- a/src/lib/crypto/sha/shs.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _SHS_DEFINED - -#include <k5-int.h> - -#define _SHS_DEFINED - -/* Some useful types */ - -typedef krb5_octet BYTE; - -/* Old DOS/Windows compilers are case-insensitive */ -#if !defined(_MSDOS) && !defined(_WIN32) -typedef krb5_ui_4 LONG; -#endif - - -/* Define the following to use the updated SHS implementation */ -#define NEW_SHS /**/ - -/* The SHS block size and message digest sizes, in bytes */ - -#define SHS_DATASIZE 64 -#define SHS_DIGESTSIZE 20 - -/* The structure for storing SHS info */ - -typedef struct { - LONG digest[ 5 ]; /* Message digest */ - LONG countLo, countHi; /* 64-bit bit count */ - LONG data[ 16 ]; /* SHS data buffer */ - } SHS_INFO; - -/* Message digest functions (shs.c) */ -void shsInit - KRB5_PROTOTYPE((SHS_INFO *shsInfo)); -void shsUpdate - KRB5_PROTOTYPE((SHS_INFO *shsInfo, BYTE *buffer, int count)); -void shsFinal - KRB5_PROTOTYPE((SHS_INFO *shsInfo)); - - -/* Keyed Message digest functions (hmac_sha.c) */ -krb5_error_code hmac_sha - KRB5_PROTOTYPE((krb5_octet *text, - int text_len, - krb5_octet *key, - int key_len, - krb5_octet *digest)); - - -#define NIST_SHA_CKSUM_LENGTH SHS_DIGESTSIZE -#define HMAC_SHA_CKSUM_LENGTH SHS_DIGESTSIZE - - -extern krb5_checksum_entry - nist_sha_cksumtable_entry, - hmac_sha_cksumtable_entry; - -#endif /* _SHS_DEFINED */ diff --git a/src/lib/crypto/sha/t_shs.c b/src/lib/crypto/sha/t_shs.c deleted file mode 100644 index da55992ec9..0000000000 --- a/src/lib/crypto/sha/t_shs.c +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -* * -* SHS Test Code * -* * -****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include "shs.h" - -/* Test the SHS implementation */ - -#ifdef NEW_SHS - -static LONG shsTestResults[][ 5 ] = { - { 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, }, - { 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, }, - { 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, } - }; - -#else - -static LONG shsTestResults[][ 5 ] = { - { 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L }, - { 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L }, - { 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L } - }; -#endif /* NEW_SHS */ - -static int compareSHSresults(shsInfo, shsTestLevel) -SHS_INFO *shsInfo; -int shsTestLevel; -{ - int i, fail = 0; - - /* Compare the returned digest and required values */ - for( i = 0; i < 5; i++ ) - if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] ) - fail = 1; - if (fail) { - printf("\nExpected: "); - for (i = 0; i < 5; i++) { - printf("%8.8lx ", shsTestResults[shsTestLevel][i]); - } - printf("\nGot: "); - for (i = 0; i < 5; i++) { - printf("%8.8lx ", shsInfo->digest[i]); - } - printf("\n"); - return( -1 ); - } - return( 0 ); -} - -main() -{ - SHS_INFO shsInfo; - unsigned int i; - time_t secondCount; - BYTE data[ 200 ]; - - /* Make sure we've got the endianness set right. If the machine is - big-endian (up to 64 bits) the following value will be signed, - otherwise it will be unsigned. Unfortunately we can't test for odd - things like middle-endianness without knowing the size of the data - types */ - - /* Test SHS against values given in SHS standards document */ - printf( "Running SHS test 1 ... " ); - shsInit( &shsInfo ); - shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 ); - shsFinal( &shsInfo ); - if( compareSHSresults( &shsInfo, 0 ) == -1 ) - { - putchar( '\n' ); - puts( "SHS test 1 failed" ); - exit( -1 ); - } -#ifdef NEW_SHS - puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" ); -#else - puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" ); -#endif /* NEW_SHS */ - - printf( "Running SHS test 2 ... " ); - shsInit( &shsInfo ); - shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 ); - shsFinal( &shsInfo ); - if( compareSHSresults( &shsInfo, 1 ) == -1 ) - { - putchar( '\n' ); - puts( "SHS test 2 failed" ); - exit( -1 ); - } -#ifdef NEW_SHS - puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" ); -#else - puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" ); -#endif /* NEW_SHS */ - - printf( "Running SHS test 3 ... " ); - shsInit( &shsInfo ); - for( i = 0; i < 15625; i++ ) - shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 ); - shsFinal( &shsInfo ); - if( compareSHSresults( &shsInfo, 2 ) == -1 ) - { - putchar( '\n' ); - puts( "SHS test 3 failed" ); - exit( -1 ); - } -#ifdef NEW_SHS - puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" ); -#else - puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" ); -#endif /* NEW_SHS */ - -#if 0 - printf( "\nTesting speed for 100MB data... " ); - shsInit( &shsInfo ); - secondCount = time( NULL ); - for( i = 0; i < 500000U; i++ ) - shsUpdate( &shsInfo, data, 200 ); - secondCount = time( NULL ) - secondCount; - printf( "done. Time = %ld seconds, %ld kbytes/second.\n", \ - secondCount, 100500L / secondCount ); -#endif - - puts( "\nAll SHS tests passed" ); - exit( 0 ); -} diff --git a/src/lib/crypto/string_to_cksumtype.c b/src/lib/crypto/string_to_cksumtype.c new file mode 100644 index 0000000000..fe46e8a9be --- /dev/null +++ b/src/lib/crypto/string_to_cksumtype.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_string_to_cksumtype(string, cksumtypep) + char FAR * string; + krb5_cksumtype FAR * cksumtypep; +{ + int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (strcasecmp(krb5_cksumtypes_list[i].in_string, string) == 0) { + *cksumtypep = krb5_cksumtypes_list[i].ctype; + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/string_to_enctype.c b/src/lib/crypto/string_to_enctype.c new file mode 100644 index 0000000000..8d3e6a37e2 --- /dev/null +++ b/src/lib/crypto/string_to_enctype.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_string_to_enctype(string, enctypep) + char FAR * string; + krb5_enctype FAR * enctypep; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (strcasecmp(krb5_enctypes_list[i].in_string, string) == 0) { + *enctypep = krb5_enctypes_list[i].etype; + return(0); + } + } + + return(EINVAL); +} diff --git a/src/lib/crypto/string_to_key.c b/src/lib/crypto/string_to_key.c new file mode 100644 index 0000000000..a569e4954c --- /dev/null +++ b/src/lib/crypto/string_to_key.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_c_string_to_key(context, enctype, string, salt, key) + krb5_context context; + krb5_enctype enctype; + krb5_const krb5_data *string; + krb5_const krb5_data *salt; + krb5_keyblock *key; +{ + int i; + krb5_error_code ret; + struct krb5_enc_provider *enc; + size_t keybytes, keylength; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == enctype) + break; + } + + if (i == krb5_enctypes_length) + return(KRB5_BAD_ENCTYPE); + + enc = krb5_enctypes_list[i].enc; + + (*(enc->keysize))(&keybytes, &keylength); + + if ((key->contents = (krb5_octet *) malloc(keylength)) == NULL) + return(ENOMEM); + + key->magic = KV5M_KEYBLOCK; + key->enctype = enctype; + key->length = keylength; + + if (ret = ((*(krb5_enctypes_list[i].str2key))(enc, string, salt, key))) { + memset(key->contents, 0, keylength); + free(key->contents); + } + + return(ret); +} diff --git a/src/lib/crypto/t_nfold.c b/src/lib/crypto/t_nfold.c new file mode 100644 index 0000000000..2693318e14 --- /dev/null +++ b/src/lib/crypto/t_nfold.c @@ -0,0 +1,76 @@ +/* + * lib/crypto/t_nfold.c + * + * Copyright 1988, 1990 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * Program to test the correctness of nfold implementation. + * + * exit returns 0 ==> success + * -1 ==> error + */ + +#include <stdio.h> +#include <string.h> + +#include "k5-int.h" + +unsigned char *nfold_in[] = { + "basch", + "eichin", + "sommerfeld", + "MASSACHVSETTS INSTITVTE OF TECHNOLOGY" }; + +unsigned char nfold_192[4][24] = { + { 0x1a, 0xab, 0x6b, 0x42, 0x96, 0x4b, 0x98, 0xb2, 0x1f, 0x8c, 0xde, 0x2d, + 0x24, 0x48, 0xba, 0x34, 0x55, 0xd7, 0x86, 0x2c, 0x97, 0x31, 0x64, 0x3f }, + { 0x65, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x4b, 0x73, 0x2b, 0x4b, 0x1b, 0x43, + 0xda, 0x1a, 0x5b, 0x99, 0x5a, 0x58, 0xd2, 0xc6, 0xd0, 0xd2, 0xdc, 0xca }, + { 0x2f, 0x7a, 0x98, 0x55, 0x7c, 0x6e, 0xe4, 0xab, 0xad, 0xf4, 0xe7, 0x11, + 0x92, 0xdd, 0x44, 0x2b, 0xd4, 0xff, 0x53, 0x25, 0xa5, 0xde, 0xf7, 0x5c }, + { 0xdb, 0x3b, 0x0d, 0x8f, 0x0b, 0x06, 0x1e, 0x60, 0x32, 0x82, 0xb3, 0x08, + 0xa5, 0x08, 0x41, 0x22, 0x9a, 0xd7, 0x98, 0xfa, 0xb9, 0x54, 0x0c, 0x1b } +}; + +int +main(argc, argv) + int argc; + char *argv[]; +{ + unsigned char cipher_text[64]; + int i, j; + + printf("N-fold\n"); + for (i=0; i<sizeof(nfold_in)/sizeof(char *); i++) { + printf("\tInput:\t\"%.*s\"\n", strlen(nfold_in[i]), nfold_in[i]); + printf("\t192-Fold:\t"); + krb5_nfold(strlen(nfold_in[i])*8, nfold_in[i], 24*8, cipher_text); + for (j=0; j<24; j++) + printf("%s%02x", (j&3) ? "" : " ", cipher_text[j]); + printf("\n"); + if (memcmp(cipher_text, nfold_192[i], 24)) { + printf("verify: error in n-fold\n"); + exit(-1); + }; + } + printf("verify: N-fold is correct\n\n"); + + exit(0); +} diff --git a/src/lib/crypto/valid_cksumtype.c b/src/lib/crypto/valid_cksumtype.c new file mode 100644 index 0000000000..24108a3eca --- /dev/null +++ b/src/lib/crypto/valid_cksumtype.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_boolean valid_cksumtype(ctype) + krb5_cksumtype ctype; +{ + int i; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == ctype) + return(1); + } + + return(0); +} diff --git a/src/lib/crypto/valid_enctype.c b/src/lib/crypto/valid_enctype.c new file mode 100644 index 0000000000..03944c068c --- /dev/null +++ b/src/lib/crypto/valid_enctype.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "etypes.h" + +krb5_boolean valid_enctype(etype) + krb5_enctype etype; +{ + int i; + + for (i=0; i<krb5_enctypes_length; i++) { + if (krb5_enctypes_list[i].etype == etype) + return(1); + } + + return(0); +} diff --git a/src/lib/crypto/verify_checksum.c b/src/lib/crypto/verify_checksum.c new file mode 100644 index 0000000000..f2749c8dea --- /dev/null +++ b/src/lib/crypto/verify_checksum.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" +#include "cksumtypes.h" + +krb5_error_code +krb5_c_verify_checksum(context, key, usage, data, cksum, valid) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *data; + krb5_const krb5_checksum *cksum; + krb5_boolean *valid; +{ + int i; + size_t hashsize; + krb5_error_code ret; + krb5_data indata; + krb5_checksum computed; + + for (i=0; i<krb5_cksumtypes_length; i++) { + if (krb5_cksumtypes_list[i].ctype == cksum->checksum_type) + break; + } + + if (i == krb5_cksumtypes_length) + return(KRB5_BAD_ENCTYPE); + + /* if there's actually a verify function, call it */ + + indata.length = cksum->length; + indata.data = cksum->contents; + + if (krb5_cksumtypes_list[i].keyhash && + krb5_cksumtypes_list[i].keyhash->verify) + return((*(krb5_cksumtypes_list[i].keyhash->verify))(key, 0, data, + &indata, valid)); + + /* otherwise, make the checksum again, and compare */ + + if (ret = krb5_c_checksum_length(context, cksum->checksum_type, &hashsize)) + return(ret); + + if (cksum->length != hashsize) + return(KRB5_BAD_MSIZE); + + computed.length = hashsize; + + if (ret = krb5_c_make_checksum(context, cksum->checksum_type, key, usage, + data, &computed)) { + free(computed.contents); + return(ret); + } + + *valid = (memcmp(computed.contents, cksum->contents, hashsize) == 0); + + free(computed.contents); + + return(0); +} diff --git a/src/lib/des425/ChangeLog b/src/lib/des425/ChangeLog index ce04691e95..4eeef10287 100644 --- a/src/lib/des425/ChangeLog +++ b/src/lib/des425/ChangeLog @@ -1,6 +1,12 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * random_key.c, new_rnd_key.c: make the v4 compat random key code + use the krb5 crypto interface, instead of the des implementation + internals. + Wed Apr 15 18:03:43 1998 Tom Yu <tlyu@mit.edu> - * Makefile.in (SHLIB_EXPDEPS): + * Makefile.in (SHLIB_EXPDEPS): (SHLIB_EXPLIBS): Rename libcrypto -> libk5crypto. Tue Mar 3 08:59:03 1998 Ezra Peisach <epeisach@kangaroo.mit.edu> diff --git a/src/lib/des425/Makefile.in b/src/lib/des425/Makefile.in index 541a516e61..e96e03f999 100644 --- a/src/lib/des425/Makefile.in +++ b/src/lib/des425/Makefile.in @@ -14,7 +14,7 @@ PROG_RPATH=$(KRB5_LIBDIR) RUN_SETUP=@KRB5_RUN_ENV@ LIB=des425 -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 RELDIR=des425 # Depends on libk5crypto and libkrb5 @@ -27,7 +27,6 @@ SHLIB_RDIRS=$(KRB5_LIBDIR) STOBJLISTS=OBJS.ST STLIBOBJS=cksum.o \ - des.o \ enc_dec.o \ key_parity.o \ key_sched.o \ @@ -44,7 +43,6 @@ STLIBOBJS=cksum.o \ OBJS= cksum.$(OBJEXT) \ - des.$(OBJEXT) \ enc_dec.$(OBJEXT) \ key_parity.$(OBJEXT) \ key_sched.$(OBJEXT) \ @@ -60,7 +58,6 @@ OBJS= cksum.$(OBJEXT) \ k4_glue.$(OBJEXT) SRCS= $(srcdir)/cksum.c \ - $(srcdir)/des.c \ $(srcdir)/enc_dec.c \ $(srcdir)/key_parity.c \ $(srcdir)/key_sched.c \ diff --git a/src/lib/des425/new_rnd_key.c b/src/lib/des425/new_rnd_key.c index 943b9e03b5..4dd2e4be76 100644 --- a/src/lib/des425/new_rnd_key.c +++ b/src/lib/des425/new_rnd_key.c @@ -23,35 +23,34 @@ * */ - -#include "des.h" - -krb5_pointer des425_random_state = 0; - /* - * des_new_random_key: create a random des key - * - * Requires: des_set_random_number_generater_seed must be at called least - * once before this routine is called. - * - * Notes: the returned key has correct parity and is guarenteed not - * to be a weak des key. Des_generate_random_block is used to - * provide the random bits. + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -KRB5_DLLIMP int KRB5_CALLCONV -des_new_random_key(key) - mit_des_cblock key; -{ - krb5_keyblock * keyblock; - krb5_error_code kret; - kret = mit_des_random_key(NULL, des425_random_state, &keyblock); - if (kret) return kret; - - memcpy(key, keyblock->contents, sizeof(mit_des_cblock)); - krb5_free_keyblock(NULL, keyblock); - return 0; -} + +#include "des.h" /* * des_init_random_number_generator: @@ -71,67 +70,38 @@ void des_init_random_number_generator(key) mit_des_cblock key; { - krb5_keyblock keyblock; - krb5_encrypt_block eblock; - - krb5_use_enctype(NULL, &eblock, ENCTYPE_DES_CBC_CRC); + krb5_data seed; - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *)key; + seed.length = sizeof(key); + seed.data = key; - if (des425_random_state) - mit_des_finish_random_key(&eblock, &des425_random_state); - mit_des_init_random_key(&eblock, &keyblock, &des425_random_state); + if (krb5_c_random_seed(/* XXX */ 0, &seed)) + /* XXX */ abort(); } /* - * This module implements a random number generator faculty such that the next - * number in any random number stream is very hard to predict without knowing - * the seed for that stream even given the preceeding random numbers. - */ - -/* - * des_set_random_generator_seed: this routine is used to select a random - * number stream. The stream that results is - * totally determined by the passed in key. - * (I.e., calling this routine again with the - * same key allows repeating a sequence of - * random numbers) + * des_new_random_key: create a random des key + * + * Requires: des_set_random_number_generater_seed must be at called least + * once before this routine is called. * - * Requires: key is a valid des key. I.e., has correct parity and is not a - * weak des key. + * Notes: the returned key has correct parity and is guarenteed not + * to be a weak des key. Des_generate_random_block is used to + * provide the random bits. */ -KRB5_DLLIMP void KRB5_CALLCONV -des_set_random_generator_seed(key) +KRB5_DLLIMP int KRB5_CALLCONV +des_new_random_key(key) mit_des_cblock key; { - krb5_data seed; + krb5_keyblock keyblock; + krb5_error_code kret; - seed.length = sizeof(mit_des_cblock); - seed.data = (krb5_pointer) key; + kret = krb5_c_make_random_key(/* XXX */ 0, ENCTYPE_DES_CBC_CRC, &keyblock); + if (kret) return kret; + + memcpy(key, keyblock.contents, sizeof(mit_des_cblock)); + krb5_free_keyblock_contents(/* XXX */ 0, &keyblock); - if (!des425_random_state) - des_init_random_number_generator(key); - mit_des_set_random_generator_seed(&seed, des425_random_state); + return 0; } - -/* - * des_set_sequence_number: this routine is used to set the sequence number - * of the current random number stream. This routine - * may be used to "seek" within the current random - * number stream. - * - * Note that des_set_random_generator_seed resets the sequence number to 0. - */ -void -des_set_sequence_number(new_sequence_number) - mit_des_cblock new_sequence_number; -{ - krb5_data sequence; - - sequence.length = sizeof(new_sequence_number); - sequence.data = (char FAR *)new_sequence_number; - mit_des_set_random_sequence_number(&sequence, des425_random_state); -} diff --git a/src/lib/des425/random_key.c b/src/lib/des425/random_key.c index 04399c1f05..fde324dece 100644 --- a/src/lib/des425/random_key.c +++ b/src/lib/des425/random_key.c @@ -23,39 +23,48 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ #include "des.h" -extern krb5_pointer des425_random_state; - /* random_key */ int des_random_key(key) mit_des_cblock *key; { - krb5_encrypt_block eblock; krb5_keyblock keyblock; - krb5_keyblock *new_key; krb5_error_code kret; - mit_des_cblock nullkey; - - krb5_use_enctype(NULL, &eblock, ENCTYPE_DES_CBC_CRC); - - memset(nullkey, 0, sizeof(mit_des_cblock)); - mit_des_fixup_key_parity(*key); - - keyblock.enctype = ENCTYPE_DES_CBC_CRC; - keyblock.length = sizeof(mit_des_cblock); - keyblock.contents = (krb5_octet *)nullkey; - if (! des425_random_state) - mit_des_init_random_key(&eblock, &keyblock, &des425_random_state); + if (kret = krb5_c_make_random_key(/* XXX */ 0, ENCTYPE_DES_CBC_CRC, + &keyblock)) + return(kret); - kret = mit_des_random_key(NULL, des425_random_state, &new_key); - if (kret) return kret; + memcpy(key, keyblock.contents, sizeof(mit_des_cblock)); - memcpy(key, new_key->contents, sizeof(mit_des_cblock)); - krb5_free_keyblock(NULL, new_key); return(0); } diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in index 6835596f79..8432071335 100644 --- a/src/lib/gssapi/Makefile.in +++ b/src/lib/gssapi/Makefile.in @@ -9,7 +9,7 @@ LOCAL_SUBDIRS= generic krb5 MAC_SUBDIRS = generic krb5 LIB=gssapi_krb5 -LIBMAJOR=1 +LIBMAJOR=2 LIBMINOR=1 STOBJLISTS=generic/OBJS.ST krb5/OBJS.ST SHLIB_EXPDEPS=\ diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog index 74f13a4a3e..601ca76f6b 100644 --- a/src/lib/gssapi/generic/ChangeLog +++ b/src/lib/gssapi/generic/ChangeLog @@ -1,3 +1,8 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * gssapi.hin: define GSS_S_DUPLICATE_ELEMENT, GSS_S_NAME_NOT_MN, + and GSS_S_GAP_TOKEN as per gss v2 c bindings + 1998-06-08 Theodore Ts'o <tytso@rsts-11.mit.edu> * oid_ops.c (generic_gss_release_oid): Recognize our own "self" diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin index d00e19ab94..a30b794311 100644 --- a/src/lib/gssapi/generic/gssapi.hin +++ b/src/lib/gssapi/generic/gssapi.hin @@ -307,11 +307,10 @@ typedef int gss_cred_usage_t; #define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET) #define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET) #define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET) -/* - * XXX new functions. Check to get official error number assigments? - */ #define GSS_S_DUPLICATE_ELEMENT \ (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NAME_NOT_MN \ + (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET) /* * Supplementary info bits: @@ -320,9 +319,6 @@ typedef int gss_cred_usage_t; #define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) #define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) #define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) -/* - * XXX not in the cbindings yet. remove this comment when it is - */ #define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) diff --git a/src/lib/gssapi/generic/gssapi_err_generic.et b/src/lib/gssapi/generic/gssapi_err_generic.et index ddeed4227e..99ba45fe38 100644 --- a/src/lib/gssapi/generic/gssapi_err_generic.et +++ b/src/lib/gssapi/generic/gssapi_err_generic.et @@ -40,4 +40,7 @@ error_code G_BAD_HOSTNAME, "Hostname in SERVICE-NAME string could not be canonic error_code G_WRONG_MECH, "Mechanism is incorrect" error_code G_BAD_TOK_HEADER, "Token header is malformed or corrupt" error_code G_BAD_DIRECTION, "Packet was replayed in wrong direction" +error_code G_TOK_TRUNC, "Token is missing data" +error_code G_REFLECT, "Token was reflected" +error_code G_WRONG_TOKID, "Received token ID does not match expected token ID" end diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c index 627b5011bc..9e186a1538 100644 --- a/src/lib/gssapi/generic/util_token.c +++ b/src/lib/gssapi/generic/util_token.c @@ -205,9 +205,12 @@ gss_int32 g_verify_token_header(mech, body_size, buf_in, tok_type, toksize) if ((toksize-=2) < 0) return(G_BAD_TOK_HEADER); + if (ret) + return(ret); + if ((*buf++ != ((tok_type>>8)&0xff)) || - (*buf++ != (tok_type&0xff))) - return(G_BAD_TOK_HEADER); + (*buf++ != (tok_type&0xff))) + return(G_WRONG_TOKID); if (!ret) { *buf_in = buf; diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index a94aeb72d4..e12dfdb2b3 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,42 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * Makefile.in, accept_sec_context.c, acquire_cred.c, canon_name.c, + delete_sec_context.c, disp_status.c, gssapiP_krb5.h, + gssapi_err_krb5.et, gssapi_krb5.c, gssapi_krb5.h, + init_sec_context.c, inq_cred.c, inq_names.c, k5seal.c, k5unseal.c, + rel_oid.c, ser_sctx.c, util_cksum.c, util_crypt.c, util_seed.c, + util_seqnum.c, wrap_size_limit.c: convert to new crypto api. + Implement new krb5 v2 gssapi mechanism. + + * add_cred.c, util_ctxsetup.c: New files needed to implement the + krb5 v2 mech. + +Mon Sep 21 00:32:28 1998 Tom Yu <tlyu@mit.edu> + + * accept_sec_context.c (krb5_gss_accept_sec_context): Free authdat + even on success to avoid a memory leak. + + * util_cksum.c (kg_checksum_channel_bindings): Fix memory leak by + not allocating cksum->contents unless we have to return a + zero-filled one. + + * k5unseal.c (kg_unseal_v1): Fix memorly leak by not allocating + md5cksum.contents. + + * k5seal.c (make_seal_token_v1): Fix memory leak by not allocating + md5cksum.contents. + + * accept_sec_context.c (krb5_gss_accept_sec_context): Only free + ap_req.data if it was allocated by kg2_parse_token(), otherwise we + lose very badly trying to free the middle of a potentially + malloc()'ed block, possibly coredumping. + +Thu Sep 3 19:35:44 1998 Tom Yu <tlyu@mit.edu> + + * accept_sec_context.c (krb5_gss_accept_sec_context): Fix typo; + bash the enctype in ctx->subkey->enctype rather than just + "enctype", which nothing checks. + Fri Jul 24 21:13:53 1998 Tom Yu <tlyu@mit.edu> * wrap_size_limit.c (krb5_gss_wrap_size_limit): Fix to round down diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in index 5b74b81d99..00b575c34f 100644 --- a/src/lib/gssapi/krb5/Makefile.in +++ b/src/lib/gssapi/krb5/Makefile.in @@ -18,6 +18,7 @@ gssapi_err_krb5.c: gssapi_err_krb5.et SRCS = \ $(srcdir)/accept_sec_context.c \ $(srcdir)/acquire_cred.c \ + $(srcdir)/add_cred.c \ $(srcdir)/canon_name.c \ $(srcdir)/compare_name.c \ $(srcdir)/context_time.c \ @@ -50,6 +51,7 @@ SRCS = \ $(srcdir)/unseal.c \ $(srcdir)/util_cksum.c \ $(srcdir)/util_crypt.c \ + $(srcdir)/util_ctxsetup.c \ $(srcdir)/util_seed.c \ $(srcdir)/util_seqnum.c \ $(srcdir)/val_cred.c \ @@ -63,6 +65,7 @@ SRCS = \ OBJS = \ accept_sec_context.$(OBJEXT) \ acquire_cred.$(OBJEXT) \ + add_cred.$(OBJEXT) \ canon_name.$(OBJEXT) \ compare_name.$(OBJEXT) \ context_time.$(OBJEXT) \ @@ -95,6 +98,7 @@ OBJS = \ unseal.$(OBJEXT) \ util_cksum.$(OBJEXT) \ util_crypt.$(OBJEXT) \ + util_ctxsetup.$(OBJEXT) \ util_seed.$(OBJEXT) \ util_seqnum.$(OBJEXT) \ val_cred.$(OBJEXT) \ @@ -108,6 +112,7 @@ OBJS = \ STLIBOBJS = \ accept_sec_context.o \ acquire_cred.o \ + add_cred.o \ canon_name.o \ compare_name.o \ context_time.o \ @@ -140,6 +145,7 @@ STLIBOBJS = \ unseal.o \ util_cksum.o \ util_crypt.o \ + util_ctxsetup.o \ util_seed.o \ util_seqnum.o \ val_cred.o \ diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index ee204d3e0a..90e988ae05 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include "gssapiP_krb5.h" #include <memory.h> @@ -58,9 +84,8 @@ rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server, /* Decode, decrypt and store the forwarded creds in the local ccache. */ static krb5_error_code -rd_and_store_for_creds(context, auth_context, inbuf, out_cred) +rd_and_store_for_creds(context, inbuf, out_cred) krb5_context context; - krb5_auth_context auth_context; krb5_data *inbuf; krb5_gss_cred_id_t *out_cred; { @@ -69,10 +94,16 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred) krb5_ccache ccache; krb5_gss_cred_id_t cred = NULL; extern krb5_cc_ops krb5_mcc_ops; + krb5_auth_context auth_context = NULL; - if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))) + if ((retval = krb5_auth_con_init(context, &auth_context))) return(retval); + krb5_auth_con_setflags(context, auth_context, 0); + + if ((retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL))) + goto cleanup; + /* Lots of kludging going on here... Some day the ccache interface will be rewritten though */ @@ -91,47 +122,51 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred) /* generate a delegated credential handle */ if (out_cred) { - /* allocate memory for a cred_t... */ - if (!(cred = - (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) { - retval = ENOMEM; /* out of memory? */ - goto cleanup; - } + /* allocate memory for a cred_t... */ + if (!(cred = + (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))) { + retval = ENOMEM; /* out of memory? */ + goto cleanup; + } - /* zero it out... */ - memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); + /* zero it out... */ + memset(cred, 0, sizeof(krb5_gss_cred_id_rec)); - /* copy the client principle into it... */ - if ((retval = - krb5_copy_principal(context, creds[0]->client, &(cred->princ)))) { - retval = ENOMEM; /* out of memory? */ - xfree(cred); /* clean up memory on failure */ - cred = NULL; - goto cleanup; - } - - cred->usage = GSS_C_INITIATE; /* we can't accept with this */ - /* cred->princ already set */ - cred->actual_mechs = gss_mech_set_krb5_both; /* both mechs work */ - cred->prerfc_mech = cred->rfc_mech = 1; /* Ibid. */ - cred->keytab = NULL; /* no keytab associated with this... */ - cred->ccache = ccache; /* but there is a credential cache */ - cred->tgt_expire = creds[0]->times.endtime; /* store the end time */ + /* copy the client principle into it... */ + if ((retval = + krb5_copy_principal(context, creds[0]->client, &(cred->princ)))) { + retval = ENOMEM; /* out of memory? */ + xfree(cred); /* clean up memory on failure */ + cred = NULL; + goto cleanup; + } + + cred->usage = GSS_C_INITIATE; /* we can't accept with this */ + /* cred->princ already set */ + cred->prerfc_mech = 1; /* this cred will work with all three mechs */ + cred->rfc_mech = 1; + cred->rfcv2_mech = 1; + cred->keytab = NULL; /* no keytab associated with this... */ + cred->ccache = ccache; /* but there is a credential cache */ + cred->tgt_expire = creds[0]->times.endtime; /* store the end time */ } /* If there were errors, there might have been a memory leak - if (!cred) - if ((retval = krb5_cc_close(context, ccache))) - goto cleanup; - */ + if (!cred) + if ((retval = krb5_cc_close(context, ccache))) + goto cleanup; + */ cleanup: krb5_free_tgt_creds(context, creds); if (!cred && ccache) - (void)krb5_cc_close(context, ccache); + (void)krb5_cc_close(context, ccache); if (out_cred) - *out_cred = cred; /* return credential */ + *out_cred = cred; /* return credential */ + + if (auth_context) + krb5_auth_con_free(context, auth_context); return retval; } @@ -158,16 +193,17 @@ krb5_gss_accept_sec_context(minor_status, context_handle, unsigned char *ptr, *ptr2; char *sptr; long tmp; + size_t md5len; int bigend; krb5_gss_cred_id_t cred = 0; - krb5_data ap_req; + krb5_data ap_rep, ap_req, mic; int i; krb5_error_code code; krb5_address addr, *paddr; krb5_authenticator *authdat = 0; - krb5_checksum md5; + krb5_checksum reqcksum; krb5_principal name = NULL; - int gss_flags = 0; + krb5_ui_4 gss_flags = 0; int decode_req_message = 0; krb5_gss_ctx_id_rec *ctx = 0; krb5_enctype enctype; @@ -177,14 +213,18 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_auth_context auth_context = NULL; krb5_ticket * ticket = NULL; int option_id; - krb5_data option; - krb5_auth_context auth_context_cred = NULL; + krb5_data option, cksumdata; const gss_OID_desc *mech_used = NULL; OM_uint32 major_status = GSS_S_FAILURE; krb5_error krb_error_data; krb5_data scratch; gss_cred_id_t cred_handle = NULL; krb5_gss_cred_id_t deleg_cred = NULL; + int token_length; + int gsskrb5_vers; + int nctypes; + krb5_cksumtype *ctypes; + struct kg2_option fwcred; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -196,7 +236,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle, output_token->length = 0; output_token->value = NULL; token.value = 0; - md5.contents = 0; + reqcksum.contents = 0; + mic.data = 0; + ap_req.data = 0; + ap_rep.data = 0; + cksumdata.data = 0; if (mech_type) *mech_type = GSS_C_NULL_OID; @@ -217,18 +261,19 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* handle default cred handle */ if (verifier_cred_handle == GSS_C_NO_CREDENTIAL) { - major_status = krb5_gss_acquire_cred(&code, GSS_C_NO_NAME, - GSS_C_INDEFINITE, GSS_C_NO_OID_SET, - GSS_C_ACCEPT, &cred_handle, - NULL, NULL); - if (major_status != GSS_S_COMPLETE) - goto fail; - } else - cred_handle = verifier_cred_handle; + major_status = krb5_gss_acquire_cred(&code, GSS_C_NO_NAME, + GSS_C_INDEFINITE, GSS_C_NO_OID_SET, + GSS_C_ACCEPT, &cred_handle, + NULL, NULL); + if (major_status != GSS_S_COMPLETE) + goto fail; + } else { + cred_handle = verifier_cred_handle; + } - major_status = krb5_gss_validate_cred(minor_status, verifier_cred_handle); + major_status = krb5_gss_validate_cred(&code, verifier_cred_handle); if (GSS_ERROR(major_status)) - goto fail; + goto fail; cred = (krb5_gss_cred_id_t) cred_handle; @@ -236,9 +281,9 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if ((cred->usage != GSS_C_ACCEPT) && (cred->usage != GSS_C_BOTH)) { - code = 0; - major_status = GSS_S_NO_CRED; - goto fail; + code = 0; + major_status = GSS_S_NO_CRED; + goto fail; } /* verify the token's integrity, and leave the token in ap_req. @@ -246,60 +291,92 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ptr = (unsigned char *) input_token->value; - if ((err = g_verify_token_header((gss_OID) gss_mech_krb5, &(ap_req.length), - &ptr, KG_TOK_CTX_AP_REQ, - input_token->length))) { - /* - * Previous versions of this library used the old mech_id - * and some broken behavior (wrong IV on checksum - * encryption). We support the old mech_id for - * compatibility, and use it to decide when to use the - * old behavior. - */ - if (err != G_WRONG_MECH || - (code = g_verify_token_header((gss_OID) gss_mech_krb5_old, - &(ap_req.length), - &ptr, KG_TOK_CTX_AP_REQ, - input_token->length))) { - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } else { -#if 0 /* Don't restrict mechanisms when accepting contexts */ - if (! cred->prerfc_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } -#endif - mech_used = gss_mech_krb5_old; - } + if (!(code = g_verify_token_header((gss_OID) gss_mech_krb5, + &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, + input_token->length))) { + if (! cred->rfc_mech) { + code = G_WRONG_MECH; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + mech_used = gss_mech_krb5; + gsskrb5_vers = 1000; + } else if ((code == G_WRONG_MECH) && + !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old, + &(ap_req.length), + &ptr, KG_TOK_CTX_AP_REQ, + input_token->length))) { + /* + * Previous versions of this library used the old mech_id + * and some broken behavior (wrong IV on checksum + * encryption). We support the old mech_id for + * compatibility, and use it to decide when to use the + * old behavior. + */ + if (! cred->prerfc_mech) { + code = G_WRONG_MECH; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + mech_used = gss_mech_krb5_old; + gsskrb5_vers = 1000; + } else if ((code == G_WRONG_MECH) && + !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2, + &token_length, + &ptr, KG2_TOK_INITIAL, + input_token->length))) { + if (! cred->rfcv2_mech) { + code = G_WRONG_MECH; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; + } + mech_used = gss_mech_krb5_v2; + gsskrb5_vers = 2000; } else { -#if 0 /* Don't restrict mechanisms when accepting contexts */ - if (! cred->rfc_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } -#endif - mech_used = gss_mech_krb5; + major_status = GSS_S_DEFECTIVE_TOKEN; + goto fail; } - sptr = (char *) ptr; - TREAD_STR(sptr, ap_req.data, ap_req.length); - decode_req_message = 1; + if (gsskrb5_vers == 2000) { + /* gss krb5 v2 */ + + fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION; + fwcred.data = NULL; + + if (GSS_ERROR(major_status = + kg2_parse_token(&code, ptr, token_length, + &gss_flags, &nctypes, &ctypes, + delegated_cred_handle?1:0, + &fwcred, &ap_req, NULL))) { + goto fail; + } + + gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; + + gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; + if there's a delegation, we'll + set it below */ + } else { + /* gss krb5 v1 */ + + sptr = (char *) ptr; + TREAD_STR(sptr, ap_req.data, ap_req.length); + decode_req_message = 1; + } /* construct the sender_addr */ if ((input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) && (input_chan_bindings->initiator_addrtype == GSS_C_AF_INET)) { - /* XXX is this right? */ - addr.addrtype = ADDRTYPE_INET; - addr.length = input_chan_bindings->initiator_address.length; - addr.contents = input_chan_bindings->initiator_address.value; + /* XXX is this right? */ + addr.addrtype = ADDRTYPE_INET; + addr.length = input_chan_bindings->initiator_address.length; + addr.contents = input_chan_bindings->initiator_address.value; - paddr = &addr; + paddr = &addr; } else { - paddr = NULL; + paddr = NULL; } /* decode the AP_REQ message */ @@ -307,13 +384,18 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* decode the message */ if ((code = krb5_auth_con_init(context, &auth_context))) { - *minor_status = code; - return(GSS_S_FAILURE); + major_status = GSS_S_FAILURE; + goto fail; } if ((code = krb5_auth_con_setrcache(context, auth_context, cred->rcache))) { - *minor_status = code; - return(GSS_S_FAILURE); + major_status = GSS_S_FAILURE; + goto fail; } + if ((code = krb5_auth_con_setaddrs(context, auth_context, NULL, paddr))) { + major_status = GSS_S_FAILURE; + goto fail; + } + if ((code = krb5_rd_req(context, &auth_context, &ap_req, cred->princ, cred->keytab, NULL, &ticket))) { major_status = GSS_S_FAILURE; @@ -328,137 +410,142 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if ((authdat->authenticator->subkey == NULL) || (authdat->ticket->enc_part2 == NULL)) { code = KG_NO_SUBKEY; + major_status = GSS_S_FAILURE; goto fail; } #endif - /* verify that the checksum is correct */ + if (gsskrb5_vers == 2000) { + bigend = 1; + } else { + /* gss krb5 v1 */ - /* - The checksum may be either exactly 24 bytes, in which case - no options are specified, or greater than 24 bytes, in which case - one or more options are specified. Currently, the only valid - option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ). - */ - - if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) || - (authdat->checksum->length < 24)) { - code = 0; - major_status = GSS_S_BAD_BINDINGS; + /* stash this now, for later. */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, + &md5len)) { + major_status = GSS_S_FAILURE; goto fail; - } + } - /* - "Be liberal in what you accept, and - conservative in what you send" - -- rfc1123 + /* verify that the checksum is correct */ - This code will let this acceptor interoperate with an initiator - using little-endian or big-endian integer encoding. - */ + /* + The checksum may be either exactly 24 bytes, in which case + no options are specified, or greater than 24 bytes, in which case + one or more options are specified. Currently, the only valid + option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ). + */ + + if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) || + (authdat->checksum->length < 24)) { + code = 0; + major_status = GSS_S_BAD_BINDINGS; + goto fail; + } - ptr = (unsigned char *) authdat->checksum->contents; - bigend = 0; + /* + "Be liberal in what you accept, and + conservative in what you send" + -- rfc1123 - TREAD_INT(ptr, tmp, bigend); + This code will let this acceptor interoperate with an initiator + using little-endian or big-endian integer encoding. + */ - if (tmp != krb5_checksum_size(context, CKSUMTYPE_RSA_MD5)) { ptr = (unsigned char *) authdat->checksum->contents; - bigend = 1; + bigend = 0; TREAD_INT(ptr, tmp, bigend); - if (tmp != krb5_checksum_size(context, CKSUMTYPE_RSA_MD5)) { - major_status = GSS_S_FAILURE; - code = KG_BAD_LENGTH; - goto fail; + if (tmp != md5len) { + ptr = (unsigned char *) authdat->checksum->contents; + bigend = 1; + + TREAD_INT(ptr, tmp, bigend); + + if (tmp != md5len) { + code = KG_BAD_LENGTH; + major_status = GSS_S_FAILURE; + goto fail; + } } - } - /* at this point, bigend is set according to the initiator's byte order */ + /* at this point, bigend is set according to the initiator's + byte order */ - if ((code = kg_checksum_channel_bindings(context, input_chan_bindings, &md5, - bigend))) { - major_status = GSS_S_BAD_BINDINGS; - goto fail; - } + if ((code = kg_checksum_channel_bindings(context, input_chan_bindings, + &reqcksum, bigend))) { + major_status = GSS_S_BAD_BINDINGS; + goto fail; + } - TREAD_STR(ptr, ptr2, md5.length); - if (memcmp(ptr2, md5.contents, md5.length) != 0) { + TREAD_STR(ptr, ptr2, reqcksum.length); + if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) { code = 0; major_status = GSS_S_BAD_BINDINGS; goto fail; - } - - xfree(md5.contents); - md5.contents = 0; - - TREAD_INT(ptr, gss_flags, bigend); - gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; if there's - a delegation, we'll set it below */ - decode_req_message = 0; - - /* if the checksum length > 24, there are options to process */ + } - if(authdat->checksum->length > 24) { + xfree(reqcksum.contents); + reqcksum.contents = 0; - i = authdat->checksum->length - 24; + TREAD_INT(ptr, gss_flags, bigend); + gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; if + there's a delegation, we'll set + it below */ + decode_req_message = 0; - while(i>0) { + /* if the checksum length > 24, there are options to process */ - TREAD_INT16(ptr, option_id, bigend); + if(authdat->checksum->length > 24) { - switch(option_id) { + i = authdat->checksum->length - 24; - case KRB5_GSS_FOR_CREDS_OPTION: + while(i>0) { - TREAD_INT16(ptr, option.length, bigend); + TREAD_INT16(ptr, option_id, bigend); - /* have to use ptr2, since option.data is wrong type and - macro uses ptr as both lvalue and rvalue */ + switch(option_id) { - TREAD_STR(ptr, ptr2, bigend); - option.data = (char FAR *) ptr2; + case KRB5_GSS_FOR_CREDS_OPTION: - /* get a temporary auth_context structure for the - call to rd_and_store_for_creds() and clear its flags */ + TREAD_INT16(ptr, option.length, bigend); - if ((code = krb5_auth_con_init(context, - &auth_context_cred))) { - major_status = GSS_S_FAILURE; - goto fail; - } + /* have to use ptr2, since option.data is wrong type and + macro uses ptr as both lvalue and rvalue */ - krb5_auth_con_setflags(context, auth_context_cred, 0); + TREAD_STR(ptr, ptr2, bigend); + option.data = (char FAR *) ptr2; - /* store the delegated credential */ + /* store the delegated credential */ - rd_and_store_for_creds(context, auth_context_cred, - &option, - (delegated_cred_handle) ? - &deleg_cred : NULL); + if (code = rd_and_store_for_creds(context, &option, + (delegated_cred_handle) ? + &deleg_cred : NULL)) { + major_status = GSS_S_FAILURE; + goto fail; + } - i -= option.length + 4; + i -= option.length + 4; - krb5_auth_con_free(context, auth_context_cred); + gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ - gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ + break; - break; + /* default: */ + /* unknown options aren't an error */ - /* default: */ - /* unknown options aren't an error */ + } /* switch */ + } /* while */ + } /* if */ + } - } /* switch */ - } /* while */ - } /* if */ - /* create the ctx struct and start filling it in */ if ((ctx = (krb5_gss_ctx_id_rec *) xmalloc(sizeof(krb5_gss_ctx_id_rec))) == NULL) { - major_status = GSS_S_FAILURE; code = ENOMEM; + major_status = GSS_S_FAILURE; goto fail; } @@ -469,83 +556,177 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ctx->gss_flags = KG_IMPLFLAGS(gss_flags); ctx->seed_init = 0; ctx->big_endian = bigend; - - major_status = GSS_S_FAILURE; + ctx->gsskrb5_version = gsskrb5_vers; /* Intern the ctx pointer so that delete_sec_context works */ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { - code = G_VALIDATE_FAILED; - xfree(ctx); - ctx = 0; - goto fail; + xfree(ctx); + ctx = 0; + + code = G_VALIDATE_FAILED; + major_status = GSS_S_FAILURE; + goto fail; } - - if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) - goto fail; - if ((code = krb5_copy_principal(context, authdat->client, &ctx->there))) - goto fail; + if ((code = krb5_copy_principal(context, cred->princ, &ctx->here))) { + major_status = GSS_S_FAILURE; + goto fail; + } - /* done with authdat */ - krb5_free_authenticator(context, authdat); - authdat = 0; + if ((code = krb5_copy_principal(context, authdat->client, &ctx->there))) { + major_status = GSS_S_FAILURE; + goto fail; + } if ((code = krb5_auth_con_getremotesubkey(context, auth_context, - &ctx->subkey))) - goto fail; + &ctx->subkey))) { + major_status = GSS_S_FAILURE; + goto fail; + } /* use the session key if the subkey isn't present */ if (ctx->subkey == NULL) { if ((code = krb5_auth_con_getkey(context, auth_context, - &ctx->subkey))) - goto fail; + &ctx->subkey))) { + major_status = GSS_S_FAILURE; + goto fail; + } } if (ctx->subkey == NULL) { /* this isn't a very good error, but it's not clear to me this can actually happen */ + major_status = GSS_S_FAILURE; code = KRB5KDC_ERR_NULL_KEY; goto fail; } - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; - ctx->cksum_size = 8; - ctx->sealalg = 0; - break; + if (gsskrb5_vers == 2000) { + int cblen; + krb5_boolean valid; + + /* intersect the token ctypes with the local ctypes */ + + if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype, + &ctx->nctypes, &ctx->ctypes)) + goto fail; + + if (nctypes == 0) { + code = KRB5_CRYPTO_INTERNAL; + goto fail; + } + + kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); + + if (nctypes == 0) { + code = KG_NO_CTYPES; + goto fail; + } + + /* process the delegated cred, if any */ + + if (fwcred.data) { + krb5_data option; + + option.length = fwcred.length; + option.data = fwcred.data; + + if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) { + major_status = GSS_S_FAILURE; + goto fail; + } + + gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ + } + + /* construct the checksum buffer */ + + cblen = 4*5; + if (input_chan_bindings) + cblen += (input_chan_bindings->initiator_address.length+ + input_chan_bindings->acceptor_address.length+ + input_chan_bindings->application_data.length); + + cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2)); + + if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { + code = ENOMEM; + major_status = GSS_S_FAILURE; + goto fail; + } + + ptr2 = cksumdata.data; + + if (input_chan_bindings) { + TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1); + TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1); + TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1); + TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1); + TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1); + } else { + memset(ptr2, 0, cblen); + ptr2 += cblen; + } + + memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2))); + + if (code = krb5_c_verify_checksum(context, ctx->subkey, + KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, + &cksumdata, authdat->checksum, + &valid)) { + major_status = GSS_S_FAILURE; + goto fail; + } + + free(cksumdata.data); + cksumdata.data = 0; + + if (!valid) { + code = 0; + major_status = GSS_S_BAD_SIG; + goto fail; + } + } else { + /* gss krb5 v1 */ + + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = 0; + ctx->cksum_size = 8; + ctx->sealalg = 0; + break; #if 0 - case ENCTYPE_DES3_CBC_MD5: - enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = 3; - ctx->cksum_size = 16; - ctx->sealalg = 1; - break; + case ENCTYPE_DES3_CBC_MD5: + enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = 3; + ctx->cksum_size = 16; + ctx->sealalg = 1; + break; #endif - default: - code = KRB5_BAD_ENCTYPE; - goto fail; - } - - /* fill in the encryption descriptors */ + default: + code = KRB5_BAD_ENCTYPE; + goto fail; + } - krb5_use_enctype(context, &ctx->enc.eblock, enctype); - ctx->enc.processed = 0; + /* fill in the encryption descriptors */ - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key))) + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) { + major_status = GSS_S_FAILURE; goto fail; + } - for (i=0; i<ctx->enc.key->length; i++) - /*SUPPRESS 113*/ - ctx->enc.key->contents[i] ^= 0xf0; + for (i=0; i<ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; - krb5_use_enctype(context, &ctx->seq.eblock, enctype); - ctx->seq.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq.key))) + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { + major_status = GSS_S_FAILURE; goto fail; + } + } ctx->endtime = ticket->enc_part2->times.endtime; ctx->krb_flags = ticket->enc_part2->flags; @@ -554,13 +735,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_auth_con_getremoteseqnumber(context, auth_context, &ctx->seq_recv); - if ((code = krb5_timeofday(context, &now))) - goto fail; + if ((code = krb5_timeofday(context, &now))) { + major_status = GSS_S_FAILURE; + goto fail; + } if (ctx->endtime < now) { - code = 0; - major_status = GSS_S_CREDENTIALS_EXPIRED; - goto fail; + code = 0; + major_status = GSS_S_CREDENTIALS_EXPIRED; + goto fail; } g_order_init(&(ctx->seqstate), ctx->seq_recv, @@ -573,40 +756,156 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* generate an AP_REP if necessary */ if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) { - krb5_data ap_rep; - unsigned char * ptr; - if ((code = krb5_mk_rep(context, auth_context, &ap_rep))) - goto fail; - - krb5_auth_con_getlocalseqnumber(context, auth_context, &ctx->seq_send); - token.length = g_token_size((gss_OID) mech_used, ap_rep.length); - - if ((token.value = (unsigned char *) xmalloc(token.length)) == NULL) { - code = ENOMEM; - goto fail; - } - ptr = token.value; - g_make_token_header((gss_OID) mech_used, ap_rep.length, - &ptr, KG_TOK_CTX_AP_REP); - - TWRITE_STR(ptr, ap_rep.data, ap_rep.length); - xfree(ap_rep.data); + unsigned char * ptr; + if ((code = krb5_mk_rep(context, auth_context, &ap_rep))) { + major_status = GSS_S_FAILURE; + goto fail; + } + + krb5_auth_con_getlocalseqnumber(context, auth_context, + &ctx->seq_send); + + /* the reply token hasn't been sent yet, but that's ok. */ + ctx->established = 1; + + if (ctx->gsskrb5_version == 2000) { + krb5_ui_4 tok_flags; + + tok_flags = + (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0; + + cksumdata.length = 8 + 4*ctx->nctypes + 4; + + if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { + code = ENOMEM; + major_status = GSS_S_FAILURE; + goto fail; + } + + /* construct the token fields */ + + ptr = cksumdata.data; + + ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff; + ptr[1] = KG2_TOK_RESPONSE & 0xff; + + ptr[2] = (tok_flags >> 24) & 0xff; + ptr[3] = (tok_flags >> 16) & 0xff; + ptr[4] = (tok_flags >> 8) & 0xff; + ptr[5] = tok_flags & 0xff; + + ptr[6] = (ctx->nctypes >> 8) & 0xff; + ptr[7] = ctx->nctypes & 0xff; + + ptr += 8; + + for (i=0; i<ctx->nctypes; i++) { + ptr[i] = (ctx->ctypes[i] >> 24) & 0xff; + ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff; + ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff; + ptr[i+3] = ctx->ctypes[i] & 0xff; + + ptr += 4; + } + + memset(ptr, 0, 4); + + /* make the MIC token */ + + { + gss_buffer_desc text, token; + + text.length = cksumdata.length; + text.value = cksumdata.data; + + /* ctx->seq_send must be set before this call */ + + if (GSS_ERROR(major_status = + krb5_gss_get_mic(&code, ctx, + GSS_C_QOP_DEFAULT, + &text, &token))) + goto fail; + + mic.length = token.length; + mic.data = token.value; + } + + token.length = g_token_size((gss_OID) mech_used, + (cksumdata.length-2)+4+ap_rep.length+ + mic.length); + + if ((token.value = (unsigned char *) xmalloc(token.length)) + == NULL) { + code = ENOMEM; + major_status = GSS_S_FAILURE; + goto fail; + } + ptr = token.value; + g_make_token_header((gss_OID) mech_used, + (cksumdata.length-2)+4+ap_rep.length+mic.length, + &ptr, KG2_TOK_RESPONSE); + + memcpy(ptr, cksumdata.data+2, cksumdata.length-2); + ptr += cksumdata.length-2; + + ptr[0] = (ap_rep.length >> 8) & 0xff; + ptr[1] = ap_rep.length & 0xff; + memcpy(ptr+2, ap_rep.data, ap_rep.length); + + ptr += (2+ap_rep.length); + + ptr[0] = (mic.length >> 8) & 0xff; + ptr[1] = mic.length & 0xff; + memcpy(ptr+2, mic.data, mic.length); + + ptr += (2+mic.length); + + free(cksumdata.data); + cksumdata.data = 0; + + /* gss krb5 v2 */ + } else { + /* gss krb5 v1 */ + + token.length = g_token_size((gss_OID) mech_used, ap_rep.length); + + if ((token.value = (unsigned char *) xmalloc(token.length)) + == NULL) { + major_status = GSS_S_FAILURE; + code = ENOMEM; + goto fail; + } + ptr = token.value; + g_make_token_header((gss_OID) mech_used, ap_rep.length, + &ptr, KG_TOK_CTX_AP_REP); + + TWRITE_STR(ptr, ap_rep.data, ap_rep.length); + xfree(ap_rep.data); + + ctx->established = 1; + + } } else { - token.length = 0; - token.value = NULL; - ctx->seq_send = ctx->seq_recv; + token.length = 0; + token.value = NULL; + ctx->seq_send = ctx->seq_recv; + + ctx->established = 1; } /* set the return arguments */ if (src_name) { - if ((code = krb5_copy_principal(context, ctx->there, &name))) - goto fail; - /* intern the src_name */ - if (! kg_save_name((gss_name_t) name)) { - code = G_VALIDATE_FAILED; - goto fail; - } + if ((code = krb5_copy_principal(context, ctx->there, &name))) { + major_status = GSS_S_FAILURE; + goto fail; + } + /* intern the src_name */ + if (! kg_save_name((gss_name_t) name)) { + code = G_VALIDATE_FAILED; + major_status = GSS_S_FAILURE; + goto fail; + } } if (mech_type) @@ -618,7 +917,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (ret_flags) *ret_flags = ctx->gss_flags; - ctx->established = 1; *context_handle = ctx; *output_token = token; @@ -626,39 +924,54 @@ krb5_gss_accept_sec_context(minor_status, context_handle, *src_name = (gss_name_t) name; if (delegated_cred_handle && deleg_cred) { - if (!kg_save_cred_id((gss_cred_id_t) deleg_cred)) { - code = G_VALIDATE_FAILED; - goto fail; - } + if (!kg_save_cred_id((gss_cred_id_t) deleg_cred)) { + major_status = GSS_S_FAILURE; + code = G_VALIDATE_FAILED; + goto fail; + } - *delegated_cred_handle = (gss_cred_id_t) deleg_cred; + *delegated_cred_handle = (gss_cred_id_t) deleg_cred; } /* finally! */ *minor_status = 0; - return(GSS_S_COMPLETE); + major_status = GSS_S_COMPLETE; -fail: + fail: + if (ctypes) + free(ctypes); if (authdat) - krb5_free_authenticator(context, authdat); + krb5_free_authenticator(context, authdat); + if (reqcksum.contents) + xfree(reqcksum.contents); + if (ap_rep.data) + xfree(ap_rep.data); + if (mic.data) + xfree(mic.data); + if (cksumdata.data) + xfree(cksumdata.data); + + if (!GSS_ERROR(major_status)) + return(major_status); + + /* from here on is the real "fail" code */ + if (ctx) - (void) krb5_gss_delete_sec_context(minor_status, - (gss_ctx_id_t *) &ctx, NULL); + (void) krb5_gss_delete_sec_context(minor_status, + (gss_ctx_id_t *) &ctx, NULL); + if (deleg_cred) { /* free memory associated with the deleg credential */ + if (deleg_cred->ccache) + (void)krb5_cc_close(context, deleg_cred->ccache); + if (deleg_cred->princ) + krb5_free_principal(context, deleg_cred->princ); + xfree(deleg_cred); + } if (token.value) - xfree(token.value); + xfree(token.value); if (name) { - (void) kg_delete_name((gss_name_t) name); - krb5_free_principal(context, name); - } - if (md5.contents) - xfree(md5.contents); - if (deleg_cred) { /* free memory associated with the deleg credential */ - if (deleg_cred->ccache) - (void)krb5_cc_close(context, deleg_cred->ccache); - if (deleg_cred->princ) - krb5_free_principal(context, deleg_cred->princ); - xfree(deleg_cred); + (void) kg_delete_name((gss_name_t) name); + krb5_free_principal(context, name); } *minor_status = code; @@ -670,48 +983,75 @@ fail: * decode the authenticator to read out the gss_flags field. */ if (decode_req_message) { - krb5_ap_req * request; + krb5_ap_req * request; - if (decode_krb5_ap_req(&ap_req, &request)) - return (major_status); - if (request->ap_options & AP_OPTS_MUTUAL_REQUIRED) - gss_flags |= GSS_C_MUTUAL_FLAG; - krb5_free_ap_req(context, request); + if (decode_krb5_ap_req(&ap_req, &request)) + return (major_status); + if (request->ap_options & AP_OPTS_MUTUAL_REQUIRED) + gss_flags |= GSS_C_MUTUAL_FLAG; + krb5_free_ap_req(context, request); } if (cred && (gss_flags & GSS_C_MUTUAL_FLAG)) { - /* - * The client is expecting a response, so we can send an - * error token back - */ - memset(&krb_error_data, 0, sizeof(krb_error_data)); - - code -= ERROR_TABLE_BASE_krb5; - if (code < 0 || code > 128) - code = 60 /* KRB_ERR_GENERIC */; - - krb_error_data.error = code; - (void) krb5_us_timeofday(context, &krb_error_data.stime, - &krb_error_data.susec); - krb_error_data.server = cred->princ; + int tmsglen, toktype; + + /* + * The client is expecting a response, so we can send an + * error token back + */ + memset(&krb_error_data, 0, sizeof(krb_error_data)); + + code -= ERROR_TABLE_BASE_krb5; + if (code < 0 || code > 128) + code = 60 /* KRB_ERR_GENERIC */; + + krb_error_data.error = code; + (void) krb5_us_timeofday(context, &krb_error_data.stime, + &krb_error_data.susec); + krb_error_data.server = cred->princ; - code = krb5_mk_error(context, &krb_error_data, &scratch); - if (code) - return (major_status); + code = krb5_mk_error(context, &krb_error_data, &scratch); + if (code) + return (major_status); + + if (gsskrb5_vers == 2000) { + tmsglen = 12+scratch.length; + toktype = KG2_TOK_RESPONSE; + } else { + tmsglen = scratch.length; + toktype = KG_TOK_CTX_ERROR; + } - token.length = g_token_size((gss_OID) mech_used, scratch.length); - token.value = (unsigned char *) xmalloc(token.length); - if (!token.value) - return (major_status); + token.length = g_token_size((gss_OID) mech_used, tmsglen); + token.value = (unsigned char *) xmalloc(token.length); + if (!token.value) + return (major_status); - ptr = token.value; - g_make_token_header((gss_OID) mech_used, scratch.length, - &ptr, KG_TOK_CTX_ERROR); + ptr = token.value; + g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype); + + if (gsskrb5_vers == 2000) { + krb5_ui_4 flags; + + flags = KG2_RESP_FLAG_ERROR; + + ptr[0] = (flags << 24) & 0xff; + ptr[1] = (flags << 16) & 0xff; + ptr[2] = (flags << 8) & 0xff; + ptr[3] = flags & 0xff; + + memset(ptr+4, 0, 6); + + ptr[10] = (scratch.length << 8) & 0xff; + ptr[11] = scratch.length & 0xff; + + ptr += 12; + } - TWRITE_STR(ptr, scratch.data, scratch.length); - xfree(scratch.data); + TWRITE_STR(ptr, scratch.data, scratch.length); + xfree(scratch.data); - *output_token = token; + *output_token = token; } if (!verifier_cred_handle && cred_handle) { krb5_gss_release_cred(&code, cred_handle); diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 1ca1bf31a7..f968b7d4f6 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "gssapiP_krb5.h" #ifdef HAVE_STRING_H #include <string.h> @@ -248,8 +274,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, size_t i; krb5_gss_cred_id_t cred; gss_OID_set ret_mechs; - const gss_OID_set_desc FAR * valid_mechs; - int req_old, req_new; + int req_old, req_new, req_v2; OM_uint32 ret; krb5_error_code code; @@ -277,27 +302,24 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, contains krb5 */ if (desired_mechs == GSS_C_NULL_OID_SET) { - valid_mechs = gss_mech_set_krb5_both; req_old = 1; req_new = 1; + req_v2 = 1; } else { req_old = 0; req_new = 0; + req_v2 = 0; for (i=0; i<desired_mechs->count; i++) { if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i]))) req_old++; if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) req_new++; + if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i]))) + req_v2++; } - if (req_old && req_new) { - valid_mechs = gss_mech_set_krb5_both; - } else if (req_old) { - valid_mechs = gss_mech_set_krb5_old; - } else if (req_new) { - valid_mechs = gss_mech_set_krb5; - } else { + if (!req_old && !req_new && !req_v2) { *minor_status = 0; return(GSS_S_BAD_MECH); } @@ -314,9 +336,9 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, cred->usage = cred_usage; cred->princ = NULL; - cred->actual_mechs = valid_mechs; cred->prerfc_mech = req_old; cred->rfc_mech = req_new; + cred->rfcv2_mech = req_v2; cred->keytab = NULL; cred->ccache = NULL; @@ -407,17 +429,30 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, /* create mechs */ if (actual_mechs) { - if (! g_copy_OID_set(cred->actual_mechs, &ret_mechs)) { - if (cred->ccache) - (void)krb5_cc_close(context, cred->ccache); - if (cred->keytab) - (void)krb5_kt_close(context, cred->keytab); - if (cred->princ) - krb5_free_principal(context, cred->princ); - xfree(cred); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status, + &ret_mechs)) || + (cred->prerfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_old, + &ret_mechs))) || + (cred->rfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5, + &ret_mechs))) || + (cred->rfcv2_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_v2, + &ret_mechs)))) { + if (cred->ccache) + (void)krb5_cc_close(context, cred->ccache); + if (cred->keytab) + (void)krb5_kt_close(context, cred->keytab); + if (cred->princ) + krb5_free_principal(context, cred->princ); + xfree(cred); + /* *minor_status set above */ + return(ret); + } } /* intern the credential handle */ @@ -445,39 +480,3 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, return(GSS_S_COMPLETE); } - -/* V2 interface */ -OM_uint32 -krb5_gss_add_cred(minor_status, input_cred_handle, - desired_name, desired_mech, cred_usage, - initiator_time_req, acceptor_time_req, - output_cred_handle, actual_mechs, - initiator_time_rec, acceptor_time_rec) - OM_uint32 *minor_status; - gss_cred_id_t input_cred_handle; - gss_name_t desired_name; - gss_OID desired_mech; - gss_cred_usage_t cred_usage; - OM_uint32 initiator_time_req; - OM_uint32 acceptor_time_req; - gss_cred_id_t *output_cred_handle; - gss_OID_set *actual_mechs; - OM_uint32 *initiator_time_rec; - OM_uint32 *acceptor_time_rec; -{ - /* - * This does not apply to our single-mechanism implementation. Decide - * if the correct error is BAD_MECH or DUPLICATE_ELEMENT. - */ - - /* verify that the requested mechanism is the default, or - is krb5 */ - - if ((desired_mech != GSS_C_NULL_OID) && - (g_OID_equal(desired_mech, gss_mech_krb5))) - return(GSS_S_BAD_MECH); - - *minor_status = 0; - return(GSS_S_DUPLICATE_ELEMENT); -} - diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c new file mode 100644 index 0000000000..2a6fdb47b5 --- /dev/null +++ b/src/lib/gssapi/krb5/add_cred.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "gssapiP_krb5.h" +#ifdef HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + +/* + * $Id$ + */ + +/* V2 interface */ +OM_uint32 +krb5_gss_add_cred(minor_status, input_cred_handle, + desired_name, desired_mech, cred_usage, + initiator_time_req, acceptor_time_req, + output_cred_handle, actual_mechs, + initiator_time_rec, acceptor_time_rec) + OM_uint32 *minor_status; + gss_cred_id_t input_cred_handle; + gss_name_t desired_name; + gss_OID desired_mech; + gss_cred_usage_t cred_usage; + OM_uint32 initiator_time_req; + OM_uint32 acceptor_time_req; + gss_cred_id_t *output_cred_handle; + gss_OID_set *actual_mechs; + OM_uint32 *initiator_time_rec; + OM_uint32 *acceptor_time_rec; +{ + krb5_context context; + OM_uint32 major_status, lifetime; + krb5_gss_cred_id_t cred; + krb5_error_code code; + + /* this is pretty simple, since there's not really any difference + between the underlying mechanisms. The main hair is in copying + a mechanism if requested. */ + + /* check if the desired_mech is bogus */ + + if (!g_OID_equal(desired_mech, gss_mech_krb5_v2) && + !g_OID_equal(desired_mech, gss_mech_krb5) && + !g_OID_equal(desired_mech, gss_mech_krb5_old)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + + /* check if the desired_mech is bogus */ + + if ((cred_usage != GSS_C_INITIATE) && + (cred_usage != GSS_C_ACCEPT) && + (cred_usage != GSS_C_BOTH)) { + *minor_status = (OM_uint32) G_BAD_USAGE; + return(GSS_S_FAILURE); + } + + /* since the default credential includes all the mechanisms, + return an error for that case. */ + + /*SUPPRESS 29*/ + if (input_cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return(GSS_S_DUPLICATE_ELEMENT); + } + + /* verify the credential */ + if (GSS_ERROR(major_status = + krb5_gss_validate_cred(minor_status, input_cred_handle))) + return(major_status); + + cred = (krb5_gss_cred_id_t) input_cred_handle; + + /* check if the cred_usage is equal or "less" than the passed-in cred + if copying */ + + if (!((cred->usage == cred_usage) || + ((cred->usage == GSS_C_BOTH) && + (output_cred_handle != NULL)))) { + *minor_status = (OM_uint32) G_BAD_USAGE; + return(GSS_S_FAILURE); + } + + /* check that desired_mech isn't already in the credential */ + + if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) || + (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) || + (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) { + *minor_status = 0; + return(GSS_S_DUPLICATE_ELEMENT); + } + + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + + /* verify the desired_name */ + + /*SUPPRESS 29*/ + if ((desired_name != (gss_name_t) NULL) && + (! kg_validate_name(desired_name))) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME); + } + + /* make sure the desired_name is the same as the existing one */ + + if (desired_name && + !krb5_principal_compare(context, (krb5_principal) desired_name, + cred->princ)) { + *minor_status = 0; + return(GSS_S_BAD_NAME); + } + + /* copy the cred if necessary */ + + if (output_cred_handle) { + /* make a copy */ + krb5_gss_cred_id_t new_cred; + char *kttype, ktboth[1024]; + char *cctype, *ccname, ccboth[1024]; + + if ((new_cred = + (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) + == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + memset(new_cred, 0, sizeof(krb5_gss_cred_id_rec)); + + new_cred->usage = cred_usage; + new_cred->prerfc_mech = cred->prerfc_mech; + new_cred->rfc_mech = cred->rfc_mech; + new_cred->rfcv2_mech = cred->rfcv2_mech; + new_cred->tgt_expire = cred->tgt_expire; + + if (code = krb5_copy_principal(context, cred->princ, + &new_cred->princ)) { + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (cred->keytab) { + kttype = krb5_kt_get_type(context, cred->keytab); + if ((strlen(kttype)+2) > sizeof(ktboth)) { + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + strcpy(ktboth, kttype); + strcat(ktboth, ":"); + + if (code = krb5_kt_get_name(context, cred->keytab, + ktboth+strlen(ktboth), + sizeof(ktboth)-strlen(ktboth))) { + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (code = krb5_kt_resolve(context, ktboth, &new_cred->keytab)) { + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + new_cred->keytab = NULL; + } + + if (cred->rcache) { + /* Open the replay cache for this principal. */ + if ((code = krb5_get_server_rcache(context, + krb5_princ_component(context, cred->princ, 0), + &new_cred->rcache))) { + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + new_cred->rcache = NULL; + } + + if (cred->ccache) { + cctype = krb5_cc_get_type(context, cred->ccache); + ccname = krb5_cc_get_name(context, cred->ccache); + + if ((strlen(cctype)+strlen(ccname)+2) > sizeof(ccboth)) { + if (new_cred->rcache) + krb5_rc_close(context, new_cred->rcache); + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + strcpy(ccboth, cctype); + strcat(ccboth, ":"); + strcat(ccboth, ccname); + + if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) { + if (new_cred->rcache) + krb5_rc_close(context, new_cred->rcache); + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + new_cred->ccache = NULL; + } + + /* intern the credential handle */ + + if (! kg_save_cred_id((gss_cred_id_t) new_cred)) { + if (new_cred->ccache) + krb5_cc_close(context, new_cred->ccache); + if (new_cred->rcache) + krb5_rc_close(context, new_cred->rcache); + if (new_cred->keytab) + krb5_kt_close(context, new_cred->keytab); + krb5_free_principal(context, new_cred->princ); + free(new_cred); + + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_FAILURE); + } + + /* modify new_cred */ + + cred = new_cred; + } + + /* set the flag for the new mechanism */ + + if (g_OID_equal(desired_mech, gss_mech_krb5_old)) + cred->prerfc_mech = 1; + else if (g_OID_equal(desired_mech, gss_mech_krb5)) + cred->rfc_mech = 1; + else if (g_OID_equal(desired_mech, gss_mech_krb5_v2)) + cred->rfcv2_mech = 1; + + /* set the outputs */ + + if (GSS_ERROR(major_status = krb5_gss_inquire_cred(minor_status, cred, + NULL, &lifetime, + NULL, actual_mechs))) { + OM_uint32 dummy; + + if (output_cred_handle) + (void) krb5_gss_release_cred(&dummy, (gss_cred_id_t *) &cred); + + return(major_status); + } + + if (initiator_time_rec) + *initiator_time_rec = lifetime; + if (acceptor_time_rec) + *acceptor_time_rec = lifetime; + + if (output_cred_handle) + *output_cred_handle = cred; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/krb5/canon_name.c b/src/lib/gssapi/krb5/canon_name.c index 652745c7b8..688366e1f9 100644 --- a/src/lib/gssapi/krb5/canon_name.c +++ b/src/lib/gssapi/krb5/canon_name.c @@ -31,13 +31,12 @@ OM_uint32 krb5_gss_canonicalize_name(OM_uint32 *minor_status, const gss_OID mech_type, gss_name_t *output_name) { - if ((mech_type == GSS_C_NULL_OID) || - !g_OID_equal(mech_type, gss_mech_krb5)) { - if (minor_status) - *minor_status = 0; - return(GSS_S_BAD_MECH); - } - - return gss_duplicate_name(minor_status, input_name, - output_name); + if (!g_OID_equal(gss_mech_krb5_v2, mech_type) && + !g_OID_equal(gss_mech_krb5, mech_type) && + !g_OID_equal(gss_mech_krb5_old, mech_type)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } + + return(gss_duplicate_name(minor_status, input_name, output_name)); } diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c index 16964995a7..28c2358906 100644 --- a/src/lib/gssapi/krb5/delete_sec_context.c +++ b/src/lib/gssapi/krb5/delete_sec_context.c @@ -80,15 +80,11 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) if (ctx->seqstate) g_order_free(&(ctx->seqstate)); - if (ctx->enc.processed) - krb5_finish_key(context, &ctx->enc.eblock); - if (ctx->enc.key) - krb5_free_keyblock(context, ctx->enc.key); + if (ctx->enc) + krb5_free_keyblock(context, ctx->enc); - if (ctx->seq.processed) - krb5_finish_key(context, &ctx->seq.eblock); - if (ctx->seq.key) - krb5_free_keyblock(context, ctx->seq.key); + if (ctx->seq) + krb5_free_keyblock(context, ctx->seq); if (ctx->here) krb5_free_principal(context, ctx->here); @@ -105,6 +101,9 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token) if (ctx->mech_used) gss_release_oid(minor_status, &ctx->mech_used); + if (ctx->ctypes) + xfree(ctx->ctypes); + /* Zero out context */ memset(ctx, 0, sizeof(*ctx)); xfree(ctx); diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c index 4dc13843ce..3a6ba7b1ae 100644 --- a/src/lib/gssapi/krb5/disp_status.c +++ b/src/lib/gssapi/krb5/disp_status.c @@ -49,10 +49,12 @@ krb5_gss_display_status(minor_status, status_value, status_type, return(GSS_S_FAILURE); if ((mech_type != GSS_C_NULL_OID) && - (! g_OID_equal(gss_mech_krb5, mech_type))) { - *minor_status = 0; - return(GSS_S_BAD_MECH); - } + !g_OID_equal(gss_mech_krb5_v2, mech_type) && + !g_OID_equal(gss_mech_krb5, mech_type) && + !g_OID_equal(gss_mech_krb5_old, mech_type)) { + *minor_status = 0; + return(GSS_S_BAD_MECH); + } if (status_type == GSS_C_GSS_CODE) { return(g_display_major_status(minor_status, status_value, diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 11b7c50f44..bcbde38943 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -68,8 +68,17 @@ ((x) & (GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \ GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG))) +#define KG2_TOK_INITIAL 0x0101 +#define KG2_TOK_RESPONSE 0x0202 +#define KG2_TOK_MIC 0x0303 +#define KG2_TOK_WRAP_INTEG 0x0404 +#define KG2_TOK_WRAP_PRIV 0x0505 + #define KRB5_GSS_FOR_CREDS_OPTION 1 +#define KG2_RESP_FLAG_ERROR 0x0001 +#define KG2_RESP_FLAG_DELEG_OK 0x0002 + /** internal types **/ typedef krb5_principal krb5_gss_name_t; @@ -78,25 +87,19 @@ typedef struct _krb5_gss_cred_id_rec { /* name/type of credential */ gss_cred_usage_t usage; krb5_principal princ; /* this is not interned as a gss_name_t */ - const gss_OID_set_desc *actual_mechs; - int prerfc_mech; /* these are a cache of the set above */ + int prerfc_mech; int rfc_mech; + int rfcv2_mech; /* keytab (accept) data */ krb5_keytab keytab; + krb5_rcache rcache; /* ccache (init) data */ krb5_ccache ccache; krb5_timestamp tgt_expire; - krb5_rcache rcache; } krb5_gss_cred_id_rec, *krb5_gss_cred_id_t; -typedef struct _krb5_gss_enc_desc { - int processed; - krb5_keyblock *key; - krb5_encrypt_block eblock; -} krb5_gss_enc_desc; - typedef struct _krb5_gss_ctx_id_rec { int initiate; /* nonzero if initiating, zero if accepting */ OM_uint32 gss_flags; @@ -108,21 +111,35 @@ typedef struct _krb5_gss_ctx_id_rec { int signalg; int cksum_size; int sealalg; - krb5_gss_enc_desc enc; - krb5_gss_enc_desc seq; + krb5_keyblock *enc; + krb5_keyblock *seq; krb5_timestamp endtime; krb5_flags krb_flags; - krb5_int32 seq_send; - krb5_int32 seq_recv; + /* XXX these used to be signed. the old spec is inspecific, and + the new spec specifies unsigned. I don't believe that the change + affects the wire encoding. */ + krb5_ui_4 seq_send; + krb5_ui_4 seq_recv; void *seqstate; int established; int big_endian; krb5_auth_context auth_context; gss_OID_desc *mech_used; + int gsskrb5_version; + int nctypes; + krb5_cksumtype *ctypes; } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; extern void *kg_vdb; +struct kg2_option { + int option_id; /* set by caller */ + int length; /* filled in by parser */ + unsigned char *data; /* filled in by parser. points inside + passed-in token, so nothing needs to + be freed */ +}; + /* helper macros */ #define kg_save_name(name) g_save_name(&kg_vdb,name) @@ -151,12 +168,12 @@ krb5_error_code kg_checksum_channel_bindings int bigend)); krb5_error_code kg_make_seq_num PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, int direction, krb5_int32 seqnum, unsigned char *cksum, unsigned char *buf)); krb5_error_code kg_get_seq_num PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, unsigned char *cksum, unsigned char *buf, int *direction, krb5_int32 *seqnum)); @@ -164,19 +181,20 @@ krb5_error_code kg_make_seed PROTOTYPE((krb5_context context, krb5_keyblock *key, unsigned char *seed)); -int kg_confounder_size PROTOTYPE((krb5_gss_enc_desc *ed)); +int kg_confounder_size PROTOTYPE((krb5_context context, krb5_keyblock *key)); -krb5_error_code kg_make_confounder PROTOTYPE((krb5_gss_enc_desc *ed, - unsigned char *buf)); +krb5_error_code kg_make_confounder PROTOTYPE((krb5_context context, + krb5_keyblock *key, unsigned char *buf)); -int kg_encrypt_size PROTOTYPE((krb5_gss_enc_desc *ed, int n)); +int kg_encrypt_size PROTOTYPE((krb5_context context, + krb5_keyblock *key, int n)); krb5_error_code kg_encrypt PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); krb5_error_code kg_decrypt PROTOTYPE((krb5_context context, - krb5_gss_enc_desc *ed, + krb5_keyblock *key, krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); OM_uint32 kg_seal PROTOTYPE((krb5_context context, @@ -223,6 +241,23 @@ krb5_error_code kg_ctx_internalize PROTOTYPE((krb5_context kcontext, OM_uint32 kg_get_context PROTOTYPE((OM_uint32 *minor_status, krb5_context *context)); +OM_uint32 +kg2_parse_token PROTOTYPE((OM_uint32 *minor_status, + unsigned char *ptr, + int length, + krb5_ui_4 *flags, + int *nctypes, /* OUT */ + krb5_cksumtype **ctypes, /* OUT */ + int noptions, + struct kg2_option *options, /* INOUT */ + krb5_data *kmsg, + krb5_data *mic)); + +void kg2_intersect_ctypes PROTOTYPE((int *nc1, + krb5_cksumtype *c1, + int nc2, + const krb5_cksumtype *c2)); + /** declarations of internal name mechanism functions **/ OM_uint32 krb5_gss_acquire_cred diff --git a/src/lib/gssapi/krb5/gssapi_err_krb5.et b/src/lib/gssapi/krb5/gssapi_err_krb5.et index 54a126518b..3c9be6351f 100644 --- a/src/lib/gssapi/krb5/gssapi_err_krb5.et +++ b/src/lib/gssapi/krb5/gssapi_err_krb5.et @@ -35,4 +35,5 @@ error_code KG_CRED, "Bad magic number for krb5_gss_cred_id_t" error_code KG_ENC_DESC, "Bad magic number for krb5_gss_enc_desc" error_code KG_BAD_SEQ, "Sequence number in token is corrupt" error_code KG_EMPTY_CCACHE, "Credential cache is empty" +error_code KG_NO_CTYPES, "Acceptor and Initiator share no checksum types" end diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index c0942c39a6..aaa47ea065 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -21,6 +21,32 @@ */ /* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* * $Id$ */ @@ -43,6 +69,9 @@ * The OID of the proposed standard krb5 mechanism is: * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) * krb5(2) = 1.2.840.113554.1.2.2 + * The OID of the proposed standard krb5 v2 mechanism is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * krb5v2(3) = 1.2.840.113554.1.2.3 * */ @@ -58,8 +87,13 @@ const gss_OID_desc krb5_gss_oid_array[] = { {5, "\053\005\001\005\002"}, /* this is the official, rfc-specified OID */ {9, "\052\206\110\206\367\022\001\002\002"}, + /* these two are name type OID's */ {10, "\052\206\110\206\367\022\001\002\002\001"}, {10, "\052\206\110\206\367\022\001\002\002\002"}, + /* this is the v2 assigned OID */ + {9, "\052\206\110\206\367\022\001\002\003"}, + /* this is the official, rfc-specified OID again */ + {9, "\052\206\110\206\367\022\001\002\002"}, { 0, 0 } }; @@ -67,16 +101,21 @@ const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+0; const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+1; const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+2; const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+3; +const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+4; static const gss_OID_set_desc oidsets[] = { {1, (gss_OID) krb5_gss_oid_array+0}, {1, (gss_OID) krb5_gss_oid_array+1}, {2, (gss_OID) krb5_gss_oid_array+0}, + {1, (gss_OID) krb5_gss_oid_array+4}, + {2, (gss_OID) krb5_gss_oid_array+4}, }; const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+0; const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+1; const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2; +const gss_OID_set_desc * const gss_mech_set_krb5_v2 = oidsets+3; +const gss_OID_set_desc * const gss_mech_set_krb5_v1v2 = oidsets+4; void *kg_vdb = NULL; diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h index 63ac530f31..e4eccbb429 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.h +++ b/src/lib/gssapi/krb5/gssapi_krb5.h @@ -32,9 +32,12 @@ extern const gss_OID_desc * const gss_mech_krb5; extern const gss_OID_desc * const gss_mech_krb5_old; +extern const gss_OID_desc * const gss_mech_krb5_v2; extern const gss_OID_set_desc * const gss_mech_set_krb5; extern const gss_OID_set_desc * const gss_mech_set_krb5_old; extern const gss_OID_set_desc * const gss_mech_set_krb5_both; +extern const gss_OID_set_desc * const gss_mech_set_krb5_v2; +extern const gss_OID_set_desc * const gss_mech_set_krb5_v1v2; extern const gss_OID_desc * const gss_nt_krb5_name; extern const gss_OID_desc * const gss_nt_krb5_principal; diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 50855b58cf..4ff2085b4f 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "gssapiP_krb5.h" #include <memory.h> #include <stdlib.h> @@ -33,8 +59,257 @@ int krb5_gss_dbg_client_expcreds = 0; static krb5_error_code -make_ap_req(context, auth_context, cred, server, now, endtime, chan_bindings, - req_flags, krb_flags, mech_type, token) +make_ap_req_v2(context, auth_context, cred, server, now, endtime, + chan_bindings, req_flags, krb_flags, mech_type, + ret_nctypes, ret_ctypes, token) + krb5_context context; + krb5_auth_context * auth_context; + krb5_gss_cred_id_t cred; + krb5_principal server; + krb5_timestamp now; + krb5_timestamp *endtime; + gss_channel_bindings_t chan_bindings; + OM_uint32 *req_flags; + krb5_flags *krb_flags; + gss_OID mech_type; + int *ret_nctypes; + krb5_cksumtype **ret_ctypes; + gss_buffer_t token; +{ + krb5_flags mk_req_flags = 0; + krb5_int32 con_flags; + krb5_error_code code; + krb5_creds in_creds, *out_creds = 0; + krb5_data credmsg, cksumdata, ap_req; + int i, tlen, cblen, nctypes; + krb5_cksumtype *ctypes; + unsigned char *t, *ptr; + + credmsg.data = 0; + cksumdata.data = 0; + ap_req.data = 0; + ctypes = 0; + + /* this probably isn't necessary */ + if (*auth_context) + krb5_auth_con_free(context, *auth_context); + + *auth_context = 0; + + /* create the option data if necessary */ + + if (*req_flags & GSS_C_DELEG_FLAG) { + /* first get KRB_CRED message, so we know its length */ + + /* clear the time check flag that was set in krb5_auth_con_init() */ + krb5_auth_con_getflags(context, *auth_context, &con_flags); + krb5_auth_con_setflags(context, *auth_context, + con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME); + + code = krb5_fwd_tgt_creds(context, *auth_context, 0, + cred->princ, server, cred->ccache, 1, + &credmsg); + + /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */ + krb5_auth_con_setflags(context, *auth_context, con_flags); + + if (code) { + /* don't fail here; just don't accept/do the delegation + request */ + *req_flags &= ~GSS_C_DELEG_FLAG; + } else { + if (credmsg.length > KRB5_INT16_MAX) { + krb5_free_data_contents(context, &credmsg); + return(KRB5KRB_ERR_FIELD_TOOLONG); + } + } + } else { + credmsg.length = 0; + } + + /* + * Get the credential, for the session key etype + */ + + memset((char *) &in_creds, 0, sizeof(krb5_creds)); + + if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client))) + goto cleanup; + if ((code = krb5_copy_principal(context, server, &in_creds.server))) + goto cleanup; + in_creds.times.endtime = *endtime; + + if ((code = krb5_get_credentials(context, 0, cred->ccache, + &in_creds, &out_creds))) + goto cleanup; + + /* + * Enforce a stricter limit (without timeskew forgiveness at the + * boundaries) because accept_sec_context code is also similarly + * non-forgiving. + */ + if (!krb5_gss_dbg_client_expcreds && out_creds->times.endtime < now) { + code = KRB5KRB_AP_ERR_TKT_EXPIRED; + goto cleanup; + } + + /* construct the list of compatible cksum types */ + + if (code = krb5_c_keyed_checksum_types(context, + out_creds->keyblock.enctype, + &nctypes, &ctypes)) + goto cleanup; + + if (nctypes == 0) { + code = KRB5_CRYPTO_INTERNAL; + goto cleanup; + } + + /* construct the checksum fields */ + + cblen = 4*5; + if (chan_bindings) + cblen += (chan_bindings->initiator_address.length+ + chan_bindings->acceptor_address.length+ + chan_bindings->application_data.length); + + cksumdata.length = cblen + 8 + 4*nctypes + 4; + if (credmsg.length) + cksumdata.length += 4 + credmsg.length; + + if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) + goto cleanup; + + /* helper macros. This code currently depends on a long being 32 + bits, and htonl dtrt. */ + + ptr = cksumdata.data; + + if (chan_bindings) { + TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1); + TWRITE_BUF(ptr, chan_bindings->initiator_address, 1); + TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1); + TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1); + TWRITE_BUF(ptr, chan_bindings->application_data, 1); + } else { + memset(ptr, 0, cblen); + ptr += cblen; + } + + /* construct the token fields */ + + ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff; + ptr[1] = KG2_TOK_INITIAL & 0xff; + + ptr[2] = (*req_flags >> 24) & 0xff; + ptr[3] = (*req_flags >> 16) & 0xff; + ptr[4] = (*req_flags >> 8) & 0xff; + ptr[5] = *req_flags & 0xff; + + ptr[6] = (nctypes >> 8) & 0xff; + ptr[7] = nctypes & 0xff; + + ptr += 8; + + for (i=0; i<nctypes; i++) { + ptr[0] = (ctypes[i] >> 24) & 0xff; + ptr[1] = (ctypes[i] >> 16) & 0xff; + ptr[2] = (ctypes[i] >> 8) & 0xff; + ptr[3] = ctypes[i] & 0xff; + + ptr += 4; + } + + if (credmsg.length) { + ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff; + ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff; + + ptr[2] = (credmsg.length >> 8) & 0xff; + ptr[3] = credmsg.length & 0xff; + + ptr += 4; + + memcpy(ptr, credmsg.data, credmsg.length); + + ptr += credmsg.length; + } + + memset(ptr, 0, 4); + + /* call mk_req. subkey and ap_req need to be used or destroyed */ + + mk_req_flags = AP_OPTS_USE_SUBKEY; + + if (*req_flags & GSS_C_MUTUAL_FLAG) + mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; + + if ((code = krb5_mk_req_extended(context, auth_context, mk_req_flags, + &cksumdata, out_creds, &ap_req))) + goto cleanup; + + /* store the interesting stuff from creds and authent */ + *endtime = out_creds->times.endtime; + *krb_flags = out_creds->ticket_flags; + + /* build up the token */ + + /* allocate space for the token */ + tlen = g_token_size((gss_OID) mech_type, + (cksumdata.length-(2+cblen))+2+ap_req.length); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { + code = ENOMEM; + goto cleanup; + } + + ptr = t; + + g_make_token_header((gss_OID) mech_type, + (cksumdata.length-(2+cblen))+2+ap_req.length, + &ptr, KG2_TOK_INITIAL); + + /* skip over the channel bindings and the token id */ + memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2)); + ptr += cksumdata.length-(cblen+2); + ptr[0] = (ap_req.length >> 8) & 0xff; + ptr[1] = ap_req.length & 0xff; + ptr += 2; + memcpy(ptr, ap_req.data, ap_req.length); + + /* pass allocated data back */ + + *ret_nctypes = nctypes; + *ret_ctypes = ctypes; + + token->length = tlen; + token->value = (void *) t; + + code = 0; + +cleanup: + if (code) { + if (*auth_context) + krb5_auth_con_free(context, *auth_context); + if (ctypes) + krb5_free_cksumtypes(context, ctypes); + } + + if (out_creds) + krb5_free_creds(context, out_creds); + krb5_free_cred_contents(context, &in_creds); + if (credmsg.data) + free(credmsg.data); + if (ap_req.data) + free(ap_req.data); + if (cksumdata.data) + free(cksumdata.data); + + return(code); +} + +static krb5_error_code +make_ap_req_v1(context, auth_context, cred, server, now, endtime, + chan_bindings, req_flags, krb_flags, mech_type, token) krb5_context context; krb5_auth_context * auth_context; krb5_gss_cred_id_t cred; @@ -142,15 +417,16 @@ make_ap_req(context, auth_context, cred, server, now, endtime, chan_bindings, /* fill in the necessary fields in creds */ memset((char *) &in_creds, 0, sizeof(krb5_creds)); + if ((code = krb5_copy_principal(context, cred->princ, &in_creds.client))) goto cleanup; if ((code = krb5_copy_principal(context, server, &in_creds.server))) goto cleanup; - in_creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; in_creds.times.endtime = *endtime; + in_creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; /* - * Get the credential..., I don't know in 0 is a good value for the + * Get the credential..., I don't know if 0 is a good value for the * kdcoptions */ if ((code = krb5_get_credentials(context, 0, cred->ccache, @@ -222,10 +498,6 @@ cleanup: return (code); } -#define IS_KRB_ERROR(dat)\ - ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\ - (dat)->data[0] == 0x5e)) - OM_uint32 krb5_gss_init_sec_context(minor_status, claimant_cred_handle, context_handle, target_name, mech_type, @@ -251,10 +523,11 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, krb5_error_code code; krb5_gss_ctx_id_rec *ctx; krb5_timestamp now; - krb5_enctype enctype; gss_buffer_desc token; - int i; - int err; + int gsskrb5_vers; + int i, err; + krb5_ui_4 resp_flags, field_length, opt_id; + OM_uint32 major_status, dummy; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -289,15 +562,33 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, err = 0; if (mech_type == GSS_C_NULL_OID) { - mech_type = cred->rfc_mech?gss_mech_krb5:gss_mech_krb5_old; + if (cred->rfcv2_mech) { + mech_type = gss_mech_krb5_v2; + gsskrb5_vers = 2000; + } else if (cred->rfc_mech) { + mech_type = gss_mech_krb5; + gsskrb5_vers = 1000; + } else if (cred->prerfc_mech) { + mech_type = gss_mech_krb5_old; + gsskrb5_vers = 1000; + } else { + err = 1; + } + } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) { + if (!cred->rfcv2_mech) + err = 1; + gsskrb5_vers = 2000; } else if (g_OID_equal(mech_type, gss_mech_krb5)) { if (!cred->rfc_mech) err = 1; + gsskrb5_vers = 1000; } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) { if (!cred->prerfc_mech) err = 1; - } else + gsskrb5_vers = 1000; + } else { err = 1; + } if (err) { *minor_status = 0; @@ -351,6 +642,9 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ctx->seed_init = 0; ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ ctx->seqstate = 0; + ctx->gsskrb5_version = gsskrb5_vers; + ctx->nctypes = 0; + ctx->ctypes = 0; if ((code = krb5_timeofday(context, &now))) { free(ctx); @@ -377,63 +671,94 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, return(GSS_S_FAILURE); } - if ((code = make_ap_req(context, &(ctx->auth_context), cred, - ctx->there, now, &ctx->endtime, - input_chan_bindings, - &ctx->gss_flags, &ctx->krb_flags, mech_type, - &token))) { - krb5_free_principal(context, ctx->here); - krb5_free_principal(context, ctx->there); - xfree(ctx); - *minor_status = code; - - if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || - (code == KG_EMPTY_CCACHE)) - return GSS_S_NO_CRED; - if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) - return GSS_S_CREDENTIALS_EXPIRED; - return(GSS_S_FAILURE); - } - - krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &ctx->seq_send); - krb5_auth_con_getlocalsubkey(context, ctx->auth_context, &ctx->subkey); - - /* fill in the encryption descriptors */ - - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; - ctx->cksum_size = 8; - ctx->sealalg = 0; - break; + if (ctx->gsskrb5_version == 2000) { + /* gsskrb5 v2 */ + + ctx->gss_flags & ~GSS_C_DELEG_FLAG; + + if ((code = make_ap_req_v2(context, &(ctx->auth_context), cred, + ctx->there, now, &ctx->endtime, + input_chan_bindings, + &ctx->gss_flags, &ctx->krb_flags, + mech_type, &ctx->nctypes, &ctx->ctypes, + &token))) { + krb5_free_principal(context, ctx->here); + krb5_free_principal(context, ctx->there); + xfree(ctx); + *minor_status = code; + + if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || + (code == KG_EMPTY_CCACHE)) + return GSS_S_NO_CRED; + if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) + return GSS_S_CREDENTIALS_EXPIRED; + return(GSS_S_FAILURE); + } + + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, + &ctx->seq_send); + krb5_auth_con_getlocalsubkey(context, ctx->auth_context, + &ctx->subkey); + } else { + /* gsskrb5 v1 */ + + if ((code = make_ap_req_v1(context, &(ctx->auth_context), cred, + ctx->there, now, &ctx->endtime, + input_chan_bindings, + &ctx->gss_flags, &ctx->krb_flags, + mech_type, + &token))) { + krb5_free_principal(context, ctx->here); + krb5_free_principal(context, ctx->there); + xfree(ctx); + *minor_status = code; + + if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || + (code == KG_EMPTY_CCACHE)) + return GSS_S_NO_CRED; + if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) + return GSS_S_CREDENTIALS_EXPIRED; + return(GSS_S_FAILURE); + } + + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, + &ctx->seq_send); + krb5_auth_con_getlocalsubkey(context, ctx->auth_context, + &ctx->subkey); + + /* fill in the encryption descriptors */ + + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = 0; + ctx->cksum_size = 8; + ctx->sealalg = 0; + break; #if 0 - case ENCTYPE_DES3_CBC_MD5: - enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = 3; - ctx->cksum_size = 16; - ctx->sealalg = 1; - break; + case ENCTYPE_DES3_CBC_MD5: + enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = 3; + ctx->cksum_size = 16; + ctx->sealalg = 1; + break; #endif - default: - return GSS_S_FAILURE; - } + default: + return GSS_S_FAILURE; + } - /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ + /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ - krb5_use_enctype(context, &ctx->enc.eblock, enctype); - ctx->enc.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc.key))) - return(code); - for (i=0; i<ctx->enc.key->length; i++) - /*SUPPRESS 113*/ - ctx->enc.key->contents[i] ^= 0xf0; + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) + return(code); + for (i=0; i<ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; - krb5_use_enctype(context, &ctx->seq.eblock, enctype); - ctx->seq.processed = 0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq.key))) - return(code); + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) + return(code); + } /* at this point, the context is constructed and valid, hence, releaseable */ @@ -493,7 +818,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, } else { unsigned char *ptr; char *sptr; - krb5_data ap_rep; + krb5_data ap_rep, mic; krb5_ap_rep_enc_part *ap_rep_data; krb5_error *krb_error; @@ -512,11 +837,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, if ((ctx->established) || (((gss_cred_id_t) cred) != claimant_cred_handle) || ((ctx->gss_flags & GSS_C_MUTUAL_FLAG) == 0)) { - (void)krb5_gss_delete_sec_context(minor_status, - context_handle, NULL); - /* XXX this minor status is wrong if an arg was changed */ - *minor_status = KG_CONTEXT_ESTABLISHED; - return(GSS_S_FAILURE); + code = KG_CONTEXT_ESTABLISHED; + goto fail; } if (! krb5_principal_compare(context, ctx->there, @@ -538,47 +860,106 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ptr = (unsigned char *) input_token->value; - if ((err = g_verify_token_header((gss_OID) mech_type, &(ap_rep.length), - &ptr, KG_TOK_CTX_AP_REP, - input_token->length))) { + if (ctx->gsskrb5_version == 2000) { + int token_length; + int nctypes; + krb5_cksumtype *ctypes; + + /* gsskrb5 v2 */ + + if ((err = g_verify_token_header((gss_OID) mech_type, + &token_length, + &ptr, KG2_TOK_RESPONSE, + input_token->length))) { + (void)krb5_gss_delete_sec_context(minor_status, + context_handle, NULL); + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); + } + + if (GSS_ERROR(major_status = + kg2_parse_token(minor_status, ptr, token_length, + &resp_flags, &nctypes, &ctypes, + 0, NULL, &ap_rep, &mic))) { + free(ctypes); + (void)krb5_gss_delete_sec_context(&dummy, context_handle, NULL); + return(major_status); + } + + kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); + + free(ctypes); + + if (ctx->nctypes == 0) { + code = KG_NO_CTYPES; + goto fail; + } + + if (resp_flags & KG2_RESP_FLAG_ERROR) { + if (code = krb5_rd_error(context, &ap_rep, &krb_error)) + goto fail; + + if (krb_error->error) + code = krb_error->error + ERROR_TABLE_BASE_krb5; + else + code = 0; + + krb5_free_error(context, krb_error); + + goto fail; + } + + if (resp_flags & KG2_RESP_FLAG_DELEG_OK) + ctx->gss_flags |= GSS_C_DELEG_FLAG; + + /* drop through to ap_rep handling */ + } else { + /* gsskrb5 v1 */ + + if ((err = g_verify_token_header((gss_OID) mech_type, + &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length))) { if (g_verify_token_header((gss_OID) mech_type, &(ap_rep.length), &ptr, KG_TOK_CTX_ERROR, input_token->length) == 0) { - /* Handle a KRB_ERROR message from the server */ + /* Handle a KRB_ERROR message from the server */ - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); - code = krb5_rd_error(context, &ap_rep, &krb_error); - if (code) - goto fail; - if (krb_error->error) - code = krb_error->error + ERROR_TABLE_BASE_krb5; - else - code = 0; - krb5_free_error(context, krb_error); + code = krb5_rd_error(context, &ap_rep, &krb_error); + if (code) goto fail; + if (krb_error->error) + code = krb_error->error + ERROR_TABLE_BASE_krb5; + else + code = 0; + krb5_free_error(context, krb_error); + goto fail; } else { - *minor_status = err; - return(GSS_S_DEFECTIVE_TOKEN); + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); } - } + } - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + } /* decode the ap_rep */ - if ((code = krb5_rd_rep(context,ctx->auth_context,&ap_rep, + if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, &ap_rep_data))) { - /* - * XXX A hack for backwards compatiblity. - * To be removed in 1999 -- proven - */ - krb5_auth_con_setuseruserkey(context,ctx->auth_context,ctx->subkey); - if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, - &ap_rep_data))) - goto fail; + /* + * XXX A hack for backwards compatiblity. + * To be removed in 1999 -- proven + */ + krb5_auth_con_setuseruserkey(context, ctx->auth_context, + ctx->subkey); + if ((krb5_rd_rep(context, ctx->auth_context, &ap_rep, + &ap_rep_data))) + goto fail; } /* store away the sequence number */ @@ -593,6 +974,25 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, /* set established */ ctx->established = 1; + if (ctx->gsskrb5_version == 2000) { + gss_buffer_desc mic_data, mic_token; + + /* start with the token id */ + mic_data.value = ptr-2; + /* end before the ap-rep length */ + mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2)); + + mic_token.length = mic.length; + mic_token.value = mic.data; + + if (GSS_ERROR(major_status = + krb5_gss_verify_mic(minor_status, *context_handle, + &mic_data, &mic_token, NULL))) { + (void)krb5_gss_delete_sec_context(&dummy, context_handle, NULL); + return(major_status); + } + } + /* set returns */ if (time_rec) { @@ -602,7 +1002,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, } if (ret_flags) - *ret_flags = KG_IMPLFLAGS(req_flags); + *ret_flags = ctx->gss_flags; if (actual_mech_type) *actual_mech_type = mech_type; @@ -616,8 +1016,8 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, return(GSS_S_COMPLETE); fail: - (void)krb5_gss_delete_sec_context(minor_status, - (gss_ctx_id_t) ctx, NULL); + (void)krb5_gss_delete_sec_context(minor_status, context_handle, NULL); + *minor_status = code; return(GSS_S_FAILURE); } diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index ee5d436c19..c800012c84 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "gssapiP_krb5.h" OM_uint32 @@ -39,6 +65,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, krb5_deltat lifetime; krb5_principal ret_name; gss_OID_set mechs; + OM_uint32 ret; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -84,12 +111,26 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, } } - if (mechanisms) - if (! g_copy_OID_set(cred->actual_mechs, &mechs)) { - krb5_free_principal(context, ret_name); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + if (mechanisms) { + if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status, + &mechs)) || + (cred->prerfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_old, + &mechs))) || + (cred->rfc_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5, + &mechs))) || + (cred->rfcv2_mech && + GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, + gss_mech_krb5_v2, + &mechs)))) { + krb5_free_principal(context, ret_name); + /* *minor_status set above */ + return(ret); + } + } if (name) { if (! kg_save_name((gss_name_t) ret_name)) { @@ -139,7 +180,9 @@ krb5_gss_inquire_cred_by_mech(minor_status, cred_handle, * We only know how to handle our own creds. */ if ((mech_type != GSS_C_NULL_OID) && - !g_OID_equal(gss_mech_krb5, mech_type)) { + !g_OID_equal(gss_mech_krb5_old, mech_type) && + !g_OID_equal(gss_mech_krb5, mech_type) && + !g_OID_equal(gss_mech_krb5_v2, mech_type)) { *minor_status = 0; return(GSS_S_NO_CRED); } diff --git a/src/lib/gssapi/krb5/inq_names.c b/src/lib/gssapi/krb5/inq_names.c index 9c5f474509..01a1994301 100644 --- a/src/lib/gssapi/krb5/inq_names.c +++ b/src/lib/gssapi/krb5/inq_names.c @@ -43,10 +43,11 @@ krb5_gss_inquire_names_for_mech(minor_status, mechanism, name_types) * We only know how to handle our own mechanism. */ if ((mechanism != GSS_C_NULL_OID) && + !g_OID_equal(gss_mech_krb5_v2, mechanism) && !g_OID_equal(gss_mech_krb5, mechanism) && !g_OID_equal(gss_mech_krb5_old, mechanism)) { *minor_status = 0; - return(GSS_S_FAILURE); + return(GSS_S_BAD_MECH); } /* We're okay. Create an empty OID set */ diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index c174bb7cbf..e1877b71f9 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -20,15 +20,269 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "gssapiP_krb5.h" static krb5_error_code -make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, - signalg, cksum_size, sealalg, encrypt, toktype, - bigend, oid) +make_priv_token_v2 PROTOTYPE((krb5_context context, + krb5_keyblock *subkey, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + gss_OID oid)); + +static krb5_error_code +make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid) krb5_context context; - krb5_gss_enc_desc *enc_ed; - krb5_gss_enc_desc *seq_ed; + krb5_keyblock *subkey; + krb5_int32 *seqnum; + int direction; + gss_buffer_t text; + gss_buffer_t token; + gss_OID oid; +{ + krb5_data plain; + krb5_enc_data cipher; + krb5_error_code code; + size_t enclen; + int tlen; + unsigned char *t, *ptr; + + plain.data = 0; + cipher.ciphertext.data = 0; + t = 0; + + plain.length = 7+text->length; + if ((plain.data = (void *) malloc(plain.length)) == NULL) { + code = ENOMEM; + goto cleanup; + } + + plain.data[0] = (*seqnum >> 24) & 0xff; + plain.data[1] = (*seqnum >> 16) & 0xff; + plain.data[2] = (*seqnum >> 8) & 0xff; + plain.data[3] = *seqnum & 0xff; + + plain.data[4] = direction?0:0xff; + + plain.data[5] = (text->length >> 8) & 0xff; + plain.data[6] = text->length & 0xff; + + memcpy(plain.data+7, text->value, text->length); + + if (code = krb5_c_encrypt_length(context, subkey->enctype, + plain.length, &enclen)) + goto cleanup; + + tlen = g_token_size((gss_OID) oid, 2+enclen); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); + + ptr = t; + + g_make_token_header((gss_OID) oid, 2+enclen, &ptr, + KG2_TOK_WRAP_PRIV); + + ptr[0] = (enclen >> 8) & 0xff; + ptr[1] = enclen & 0xff; + + cipher.ciphertext.length = enclen; + cipher.ciphertext.data = ptr+2; + + if (code = krb5_c_encrypt(context, subkey, + KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, + 0, &plain, &cipher)) + goto cleanup; + + /* that's it. return the token */ + + (*seqnum)++; + + token->length = tlen; + token->value = (void *) t; + + code = 0; + +cleanup: + if (plain.data) + free(plain.data); + if (code) { + if (t) + free(t); + } + + return(code); +} + +static krb5_error_code +make_integ_token_v2 PROTOTYPE((krb5_context context, + krb5_keyblock *subkey, + krb5_cksumtype ctype, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + int toktype, + gss_OID oid)); + +static krb5_error_code +make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token, + toktype, oid) + krb5_context context; + krb5_keyblock *subkey; + krb5_cksumtype ctype; + krb5_int32 *seqnum; + int direction; + gss_buffer_t text; + gss_buffer_t token; + int toktype; + gss_OID oid; +{ + krb5_error_code code; + int tmp, tlen; + unsigned char *t, *ptr; + krb5_data plain; + krb5_checksum cksum; + + plain.data = 0; + t = 0; + cksum.contents = 0; + + /* assemble the checksum buffer and compute the checksum */ + + plain.length = 7+text->length; + + if ((plain.data = (char *) malloc(plain.length)) == NULL) + goto cleanup; + + plain.data[0] = (*seqnum >> 24) & 0xff; + plain.data[1] = (*seqnum >> 16) & 0xff; + plain.data[2] = (*seqnum >> 8) & 0xff; + plain.data[3] = *seqnum & 0xff; + + plain.data[4] = direction?0:0xff; + + plain.data[5] = (text->length >> 8) & 0xff; + plain.data[6] = text->length & 0xff; + + memcpy(plain.data+7, text->value, text->length); + + if (code = krb5_c_make_checksum(context, ctype, subkey, + (toktype == KG2_TOK_WRAP_INTEG)? + KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG: + KRB5_KEYUSAGE_GSS_TOK_MIC, + &plain, &cksum)) + goto cleanup; + + /* assemble the token itself */ + + if (toktype == KG2_TOK_WRAP_INTEG) + tmp = 4+(7+text->length)+2+cksum.length; + else + tmp = 4+(5)+2+cksum.length; + + tlen = g_token_size((gss_OID) oid, tmp); + + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); + + ptr = t; + + g_make_token_header((gss_OID) oid, tmp, &ptr, toktype); + + ptr[0] = (ctype >> 24) & 0xff; + ptr[1] = (ctype >> 16) & 0xff; + ptr[2] = (ctype >> 8) & 0xff; + ptr[3] = ctype & 0xff; + + ptr += 4; + + if (toktype == KG2_TOK_WRAP_INTEG) { + memcpy(ptr, plain.data, 7+text->length); + ptr += 7+text->length; + } else { + memcpy(ptr, plain.data, 5); + ptr += 5; + } + + ptr[0] = (cksum.length >> 8) & 0xff; + ptr[1] = cksum.length & 0xff; + ptr += 2; + + memcpy(ptr, cksum.contents, cksum.length); + + /* that's it. return the token */ + + (*seqnum)++; + + token->length = tlen; + token->value = (void *) t; + + code = 0; + +cleanup: + if (plain.data) + free(plain.data); + if (cksum.contents) + krb5_free_checksum_contents(context, &cksum); + if (code) { + if (t) + free(t); + } + + return(code); +} + +static krb5_error_code +make_seal_token_v1 PROTOTYPE((krb5_context context, + krb5_keyblock *enc, + krb5_keyblock *seq, + krb5_int32 *seqnum, + int direction, + gss_buffer_t text, + gss_buffer_t token, + int signalg, + int cksum_size, + int sealalg, + int encrypt, + int toktype, + int bigend, + gss_OID oid)); + +static krb5_error_code +make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, + signalg, cksum_size, sealalg, encrypt, toktype, + bigend, oid) + krb5_context context; + krb5_keyblock *enc; + krb5_keyblock *seq; krb5_int32 *seqnum; int direction; gss_buffer_t text; @@ -42,7 +296,9 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, gss_OID oid; { krb5_error_code code; + size_t sumlen; char *data_ptr; + krb5_data plaind; krb5_checksum md5cksum; krb5_checksum cksum; int conflen=0, tmsglen, tlen; @@ -54,7 +310,7 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, if (bigend && !encrypt) { tmsglen = text->length; } else { - conflen = kg_confounder_size(enc_ed); + conflen = kg_confounder_size(context, enc); /* XXX knows that des block size is 8 */ tmsglen = (conflen+text->length+8)&(~7); } @@ -96,27 +352,24 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, /* pad the plaintext, encrypt if needed, and stick it in the token */ - /* initialize the the cksum and allocate the contents buffer */ + /* initialize the the cksum */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + return(code); + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((md5cksum.contents = (krb5_octet *) xmalloc(md5cksum.length)) == NULL) { - return(ENOMEM); - } - + md5cksum.length = sumlen; if (toktype == KG_TOK_SEAL_MSG) { unsigned char *plain; unsigned char pad; if (!bigend || encrypt) { if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - xfree(md5cksum.contents); xfree(t); return(ENOMEM); } - if ((code = kg_make_confounder(enc_ed, plain))) { + if ((code = kg_make_confounder(context, enc, plain))) { xfree(plain); - xfree(md5cksum.contents); xfree(t); return(code); } @@ -133,12 +386,11 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, } if (encrypt) { - if ((code = kg_encrypt(context, enc_ed, NULL, (krb5_pointer) plain, + if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain, (krb5_pointer) (ptr+cksum_size+14), tmsglen))) { if (plain) xfree(plain); - xfree(md5cksum.contents); xfree(t); return(code); } @@ -156,7 +408,6 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { if (plain) xfree(plain); - xfree(md5cksum.contents); xfree(t); return(ENOMEM); } @@ -165,15 +416,15 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, (void) memcpy(data_ptr+8, text->value, text->length); else (void) memcpy(data_ptr+8, plain, tmsglen); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, data_ptr, - 8 + (bigend ? text->length : tmsglen), - 0, 0, &md5cksum); + plaind.length = 8 + (bigend ? text->length : tmsglen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + 0, 0, &plaind, &md5cksum); xfree(data_ptr); if (code) { if (plain) xfree(plain); - xfree(md5cksum.contents); xfree(t); return(code); memcpy(ptr+14+cksum_size, plain, tmsglen); @@ -185,18 +436,17 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, /* compute the checksum */ if (! (data_ptr = (char *) xmalloc(8 + text->length))) { - xfree(md5cksum.contents); xfree(t); return(ENOMEM); } (void) memcpy(data_ptr, ptr-2, 8); (void) memcpy(data_ptr+8, text->value, text->length); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, data_ptr, - 8 + text->length, - 0, 0, &md5cksum); + plaind.length = 8 + text->length; + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, + &plaind, &md5cksum); xfree(data_ptr); if (code) { - xfree(md5cksum.contents); xfree(t); return(code); } @@ -214,16 +464,19 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, DES encryption the long way, and keep the last block as the MAC */ + /* XXX not converted to new api since it's inside an #if 0 */ + /* initialize the the cksum and allocate the contents buffer */ cksum.checksum_type = CKSUMTYPE_DESCBC; cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) return(ENOMEM); + /* XXX not converted to new api since it's inside an #if 0 */ if (code = krb5_calculate_checksum(context, cksum.checksum_type, md5cksum.contents, 16, - seq_ed->key->contents, - seq_ed->key->length, + seq->contents, + seq->length, &cksum)) { xfree(cksum.contents); xfree(md5cksum.contents); @@ -235,9 +488,9 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, xfree(cksum.contents); #else - if ((code = kg_encrypt(context, seq_ed, + if ((code = kg_encrypt(context, seq, (g_OID_equal(oid, gss_mech_krb5_old) ? - seq_ed->key->contents : NULL), + seq->contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { xfree(md5cksum.contents); xfree(t); @@ -257,7 +510,7 @@ make_seal_token(context, enc_ed, seq_ed, seqnum, direction, text, token, /* create the seq_num */ - if ((code = kg_make_seq_num(context, seq_ed, direction?0:0xff, *seqnum, + if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, ptr+14, ptr+6))) { xfree(t); return(code); @@ -320,17 +573,42 @@ kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, return(GSS_S_FAILURE); } - if ((code = make_seal_token(context, &ctx->enc, &ctx->seq, - &ctx->seq_send, ctx->initiate, - input_message_buffer, output_message_buffer, - ctx->signalg, ctx->cksum_size, ctx->sealalg, - conf_req_flag, toktype, ctx->big_endian, - ctx->mech_used))) { + if (ctx->gsskrb5_version == 2000) { + if (toktype == KG_TOK_WRAP_MSG) { + if (conf_req_flag) + toktype = KG2_TOK_WRAP_PRIV; + else + toktype = KG2_TOK_WRAP_INTEG; + } else { + toktype = KG2_TOK_MIC; + } + + if (conf_req_flag) { + code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send, + ctx->initiate, input_message_buffer, + output_message_buffer, ctx->mech_used); + } else { + code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0], + &ctx->seq_send, ctx->initiate, + input_message_buffer, + output_message_buffer, toktype, + ctx->mech_used); + } + } else { + code = make_seal_token_v1(context, ctx->enc, ctx->seq, + &ctx->seq_send, ctx->initiate, + input_message_buffer, output_message_buffer, + ctx->signalg, ctx->cksum_size, ctx->sealalg, + conf_req_flag, toktype, ctx->big_endian, + ctx->mech_used); + } + + if (code) { *minor_status = code; return(GSS_S_FAILURE); } - if ((toktype == KG_TOK_SEAL_MSG) && conf_state) + if (conf_state) *conf_state = conf_req_flag; *minor_status = 0; diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index 041cae06a3..c32e3255d5 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "gssapiP_krb5.h" #include <memory.h> @@ -27,34 +53,417 @@ * $Id$ */ +static OM_uint32 +kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, + text, qop_state) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t text; + gss_qop_t *qop_state; +{ + size_t cksumlen; + krb5_error_code code; + krb5_data plain; + krb5_cksumtype tctype; + krb5_ui_4 tseqnum; + int tdirection; + krb5_checksum cksum; + krb5_boolean ckvalid; + krb5_timestamp now; + OM_uint32 retval; + + plain.data = 0; + cksum.contents = 0; + + /* verify the header */ + + if (bodysize < 11) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + /* allocate the checksum buffer */ + + plain.length = 7+text->length; + + if ((plain.data = (char *) malloc(plain.length)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + /* suck out the body parts from the token */ + + tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | + (ptr[2]<<8) | ptr[3]); + ptr += 4; + + memcpy(plain.data, ptr, 5); + tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); + ptr += 4; + tdirection = ptr[0]; + ptr += 1; + + cksum.length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 11; + + if (cksum.length != bodysize) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + cksum.contents = ptr; + cksum.checksum_type = tctype; + + /* finish assembling the checksum buffer and compute the checksum */ + + plain.data[5] = (text->length >> 8) & 0xff; + plain.data[6] = text->length & 0xff; + + memcpy(plain.data+7, text->value, text->length); + + if (code = krb5_c_verify_checksum(context, ctx->subkey, + KRB5_KEYUSAGE_GSS_TOK_MIC, + &plain, &cksum, &ckvalid)) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (!ckvalid) { + free(plain.data); + *minor_status = 0; + return(GSS_S_BAD_SIG); + } + + /* check context expiry */ + + if ((code = krb5_timeofday(context, &now))) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + free(plain.data); + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* do sequencing checks */ + + if ((ctx->initiate && tdirection != 0xff) || + (!ctx->initiate && tdirection != 0)) { + free(plain.data); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + retval = g_order_check(&(ctx->seqstate), tseqnum); + + free(plain.data); + + if (retval) { + *minor_status = 0; + return(retval); + } + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +static OM_uint32 +kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t output; + gss_qop_t *qop_state; +{ + krb5_error_code code; + OM_uint32 retval; + krb5_ui_4 tseqnum; + int tdirection; + int tmsglen; + unsigned char *tmsg; + krb5_data plain; + krb5_checksum tcksum; + krb5_boolean ckvalid; + krb5_timestamp now; + + output->length = 0; + output->value = NULL; + + /* read the body parts out of the message */ + + if (bodysize < 11) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | + (ptr[2]<<8) | ptr[3]); + ptr += 4; + + plain.data = ptr; + + tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); + ptr += 4; + tdirection = ptr[0]; + ptr += 1; + + tmsglen = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 11; + + if (bodysize < tmsglen) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tmsg = ptr; + ptr += tmsglen; + bodysize -= tmsglen; + + plain.length = ((char*)ptr) - ((char *)plain.data); + + tcksum.length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 2; + + if (bodysize != tcksum.length) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tcksum.contents = ptr; + + /* verify the MIC */ + + if (code = krb5_c_verify_checksum(context, ctx->subkey, + KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG, + &plain, &tcksum, &ckvalid)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (!ckvalid) { + *minor_status = 0; + return(GSS_S_BAD_SIG); + } + + /* check context expiry */ + + if ((code = krb5_timeofday(context, &now))) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* do sequencing checks */ + + if ((ctx->initiate && tdirection != 0xff) || + (!ctx->initiate && tdirection != 0)) { + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { + *minor_status = 0; + return(retval); + } + + if ((output->value = (void *) malloc(tmsglen)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + memcpy(output->value, tmsg, tmsglen); + output->length = tmsglen; + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +static OM_uint32 +kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t output; + gss_qop_t *qop_state; +{ + krb5_error_code code; + OM_uint32 retval; + krb5_enc_data cipher; + krb5_data plain; + krb5_ui_4 tseqnum; + int tdirection; + int tmsglen; + unsigned char *tmsg; + krb5_timestamp now; + + output->length = 0; + output->value = NULL; + + /* read the body parts out of the message */ + + if (bodysize < 2) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + cipher.ciphertext.length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 2; + + if (bodysize != cipher.ciphertext.length) { + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + cipher.ciphertext.data = ptr; + cipher.enctype = ENCTYPE_UNKNOWN; + + plain.length = cipher.ciphertext.length; + if ((plain.data = (char *) malloc(plain.length)) == NULL) { + *minor_status = 0; + return(GSS_S_FAILURE); + } + + /* decrypt (and implicitly verify) the encrypted data */ + + if (code = krb5_c_decrypt(context, ctx->subkey, + KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, + 0, &cipher, &plain)) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + /* parse out the encrypted fields */ + + ptr = plain.data; + bodysize = plain.length; + + if (bodysize < 7) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); + ptr += 4; + tdirection = ptr[0]; + ptr += 1; + + tmsglen = (ptr[0]<<8) | ptr[1]; + ptr += 2; + bodysize -= 7; + + /* check context expiry */ + + if ((code = krb5_timeofday(context, &now))) { + free(plain.data); + *minor_status = code; + return(GSS_S_FAILURE); + } + + if (now > ctx->endtime) { + free(plain.data); + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); + } + + /* do sequencing checks */ + + if ((ctx->initiate && tdirection != 0xff) || + (!ctx->initiate && tdirection != 0)) { + free(plain.data); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); + } + + if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { + free(plain.data); + *minor_status = 0; + return(retval); + } + + /* now copy out the data. can't do a strict equality check here, + since the output could be padded. */ + + if (bodysize < tmsglen) { + free(plain.data); + *minor_status = G_TOK_TRUNC; + return(GSS_S_DEFECTIVE_TOKEN); + } + + tmsg = ptr; + + if ((output->value = (void *) malloc(tmsglen)) == NULL) { + free(plain.data); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + memcpy(output->value, tmsg, tmsglen); + output->length = tmsglen; + + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; + + free(plain.data); + + *minor_status = 0; + return(GSS_S_COMPLETE); +} + /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX - conf_state is only valid if SEAL. - */ + conf_state is only valid if SEAL. */ OM_uint32 -kg_unseal(context, minor_status, context_handle, input_token_buffer, - message_buffer, conf_state, qop_state, toktype) +kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, + conf_state, qop_state, toktype) krb5_context context; OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t input_token_buffer; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; gss_buffer_t message_buffer; int *conf_state; int *qop_state; int toktype; { - krb5_gss_ctx_id_rec *ctx; krb5_error_code code; - int bodysize; int tmsglen; int conflen = 0; int signalg; int sealalg; gss_buffer_desc token; - unsigned char *ptr; krb5_checksum cksum; krb5_checksum desmac; krb5_checksum md5cksum; + krb5_data plaind; char *data_ptr; krb5_timestamp now; unsigned char *plain; @@ -64,38 +473,13 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, int direction; krb5_int32 seqnum; OM_uint32 retval; + size_t sumlen; if (toktype == KG_TOK_SEAL_MSG) { message_buffer->length = 0; message_buffer->value = NULL; } - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - /* parse the token, leave the data in message_buffer, setting conf_state */ - - /* verify the header */ - - ptr = (unsigned char *) input_token_buffer->value; - - if ((err = g_verify_token_header((gss_OID) ctx->mech_used, &bodysize, - &ptr, toktype, - input_token_buffer->length))) { - *minor_status = err; - return(GSS_S_DEFECTIVE_TOKEN); - } - /* get the sign and seal algorithms */ signalg = ptr[0] + (ptr[1]<<8); @@ -159,7 +543,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, return(GSS_S_FAILURE); } - if ((code = kg_decrypt(context, &ctx->enc, NULL, + if ((code = kg_decrypt(context, ctx->enc, NULL, ptr+14+cksum_len, plain, tmsglen))) { xfree(plain); *minor_status = code; @@ -174,7 +558,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, if ((sealalg == 0xffff) && ctx->big_endian) { token.length = tmsglen; } else { - conflen = kg_confounder_size(&ctx->enc); + conflen = kg_confounder_size(context, ctx->enc); token.length = tmsglen - conflen - plain[tmsglen-1]; } @@ -200,15 +584,12 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, /* compute the checksum of the message */ - /* initialize the the cksum and allocate the contents buffer */ + /* initialize the the cksum */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + return(code); + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((md5cksum.contents = (krb5_octet *) xmalloc(md5cksum.length)) == NULL) { - if (sealalg != 0xffff) - xfree(plain); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + md5cksum.length = sumlen; switch (signalg) { case 0: @@ -219,7 +600,6 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, if (! (data_ptr = (void *) xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { - xfree(md5cksum.contents); if (sealalg != 0xffff) xfree(plain); if (toktype == KG_TOK_SEAL_MSG) @@ -235,14 +615,13 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, else (void) memcpy(data_ptr+8, plain, plainlen); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, - data_ptr, 8 + - (ctx->big_endian ? token.length : - plainlen), 0, 0, &md5cksum); + plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, + &plaind, &md5cksum); xfree(data_ptr); if (code) { - xfree(md5cksum.contents); if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); *minor_status = code; @@ -264,6 +643,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, return(GSS_S_FAILURE); } + /* XXX not converted to new api since it's inside an #if 0 */ if (code = krb5_calculate_checksum(context, cksum.checksum_type, md5cksum.contents, 16, ctx->seq.key->contents, @@ -281,9 +661,9 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, xfree(cksum.contents); #else - if ((code = kg_encrypt(context, &ctx->seq, + if ((code = kg_encrypt(context, ctx->seq, (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq.key->contents : NULL), + ctx->seq->contents : NULL), md5cksum.contents, md5cksum.contents, 16))) { xfree(md5cksum.contents); if (toktype == KG_TOK_SEAL_MSG) @@ -333,15 +713,15 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, else (void) memcpy(data_ptr+8+sizeof(ctx->seed), plain, plainlen); - code = krb5_calculate_checksum(context, md5cksum.checksum_type, - data_ptr, 8 + sizeof(ctx->seed) + - (ctx->big_endian ? token.length : - plainlen), 0, 0, &md5cksum); - + plaind.length = 8 + sizeof(ctx->seed) + + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + xfree(md5cksum.contents); + code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, + &plaind, &md5cksum); xfree(data_ptr); if (code) { - xfree(md5cksum.contents); if (sealalg == 0) xfree(plain); if (toktype == KG_TOK_SEAL_MSG) @@ -394,7 +774,7 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, /* do sequencing checks */ - if ((code = kg_get_seq_num(context, &(ctx->seq), ptr+14, ptr+6, &direction, + if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, &seqnum))) { if (toktype == KG_TOK_SEAL_MSG) xfree(token.value); @@ -417,3 +797,88 @@ kg_unseal(context, minor_status, context_handle, input_token_buffer, *minor_status = 0; return(retval); } + +/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX + conf_state is only valid if SEAL. */ + +OM_uint32 +kg_unseal(context, minor_status, context_handle, input_token_buffer, + message_buffer, conf_state, qop_state, toktype) + krb5_context context; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_token_buffer; + gss_buffer_t message_buffer; + int *conf_state; + int *qop_state; + int toktype; +{ + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + int err; + OM_uint32 retval; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } + + ctx = (krb5_gss_ctx_id_rec *) context_handle; + + if (! ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } + + /* parse the token, leave the data in message_buffer, setting conf_state */ + + /* verify the header */ + + ptr = (unsigned char *) input_token_buffer->value; + + if (ctx->gsskrb5_version == 2000) { + if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, KG2_TOK_MIC, + input_token_buffer->length))) { + return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, + message_buffer, qop_state)); + } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, + KG2_TOK_WRAP_INTEG, + input_token_buffer->length))) { + if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status, + ctx, ptr, bodysize, + message_buffer, qop_state))) + return(retval); + + if (conf_state) + *conf_state = 0; + return(GSS_S_COMPLETE); + } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, + KG2_TOK_WRAP_PRIV, + input_token_buffer->length))) { + if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status, + ctx, ptr, bodysize, + message_buffer, qop_state))) + return(retval); + + if (conf_state) + *conf_state = 1; + return(GSS_S_COMPLETE); + } + } else { + if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, toktype, + input_token_buffer->length))) { + return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, + message_buffer, conf_state, qop_state, + toktype)); + } + } + + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); +} diff --git a/src/lib/gssapi/krb5/rel_oid.c b/src/lib/gssapi/krb5/rel_oid.c index f35727e3f1..afb2171b86 100644 --- a/src/lib/gssapi/krb5/rel_oid.c +++ b/src/lib/gssapi/krb5/rel_oid.c @@ -63,7 +63,8 @@ krb5_gss_internal_release_oid(minor_status, oid) * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize. */ - if ((*oid != gss_mech_krb5) && + if ((*oid != gss_mech_krb5_v2) && + (*oid != gss_mech_krb5) && (*oid != gss_mech_krb5_old) && (*oid != gss_nt_krb5_name) && (*oid != gss_nt_krb5_principal)) { diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 36e70d742c..36a16d426e 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -40,192 +40,6 @@ * still be done. --marc */ -/* - * Determine the size required for this krb5_gss_enc_desc. - */ -static krb5_error_code -kg_enc_desc_size(kcontext, arg, sizep) - krb5_context kcontext; - krb5_pointer arg; - size_t *sizep; -{ - krb5_error_code kret; - krb5_gss_enc_desc *edescp; - size_t required; - - /* - * krb5_gss_cred_id_t requires: - * krb5_int32 for KG_ENC_DESC - * krb5_int32 for processed. - * krb5_int32 for trailer. - */ - kret = EINVAL; - if ((edescp = (krb5_gss_enc_desc *) arg)) { - required = 3*sizeof(krb5_int32); - if (edescp->key) - kret = krb5_size_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) edescp->key, - &required); - else - kret = 0; - - /* - * We need to use size_opaque here because we're not sure as to the - * ancestry of this eblock, and we can't be sure that the magic number - * is set in it, so we ASSuME that it's ok. - */ - if (!kret) - kret = krb5_size_opaque(kcontext, - KV5M_ENCRYPT_BLOCK, - (krb5_pointer) &edescp->eblock, - &required); - - if (!kret) - *sizep += required; - } - return(kret); -} - -/* - * Externalize this krb5_gss_enc_desc. - */ -static krb5_error_code -kg_enc_desc_externalize(kcontext, arg, buffer, lenremain) - krb5_context kcontext; - krb5_pointer arg; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_gss_enc_desc *enc_desc; - size_t required; - krb5_octet *bp; - size_t remain; - - required = 0; - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - if ((enc_desc = (krb5_gss_enc_desc *) arg)) { - kret = ENOMEM; - if (!kg_enc_desc_size(kcontext, arg, &required) && - (required <= remain)) { - /* Our identifier */ - (void) krb5_ser_pack_int32(KG_ENC_DESC, &bp, &remain); - - /* Now static data */ - (void) krb5_ser_pack_int32((krb5_int32) enc_desc->processed, - &bp, &remain); - - /* Now pack up dynamic data */ - if (enc_desc->key) - kret = krb5_externalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer) enc_desc->key, - &bp, &remain); - else - kret = 0; - - if (!kret) - kret = krb5_externalize_opaque(kcontext, - KV5M_ENCRYPT_BLOCK, - (krb5_pointer)&enc_desc->eblock, - &bp, &remain); - if (!kret) { - (void) krb5_ser_pack_int32(KG_ENC_DESC, &bp, &remain); - *buffer = bp; - *lenremain = remain; - } - } - } - return(kret); -} - -/* - * Internalize this krb5_gss_enc_desc. - */ -static krb5_error_code -kg_enc_desc_internalize(kcontext, argp, buffer, lenremain) - krb5_context kcontext; - krb5_pointer *argp; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_gss_enc_desc *edescp; - krb5_int32 ibuf; - krb5_octet *bp; - krb5_encrypt_block *eblockp; - size_t remain; - - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - /* Read our magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - ibuf = 0; - if (ibuf == KG_ENC_DESC) { - kret = ENOMEM; - - /* Get an enc_desc */ - if ((remain >= (2*sizeof(krb5_int32))) && - (edescp = (krb5_gss_enc_desc *) - xmalloc(sizeof(krb5_gss_enc_desc)))) { - memset(edescp, 0, sizeof(krb5_gss_enc_desc)); - - /* Get the static data */ - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - edescp->processed = (int) ibuf; - - /* edescp->key */ - if ((kret = krb5_internalize_opaque(kcontext, - KV5M_KEYBLOCK, - (krb5_pointer *) &edescp->key, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - - /* edescp->eblock */ - if (!kret && - (kret = krb5_internalize_opaque(kcontext, - KV5M_ENCRYPT_BLOCK, - (krb5_pointer *) &eblockp, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - else { - /* Successful, copy in allocated eblock to our structure */ - memcpy(&edescp->eblock, eblockp, sizeof(edescp->eblock)); - krb5_xfree(eblockp); - } - - /* trailer */ - if (!kret && - !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && - (ibuf == KG_ENC_DESC)) { - *buffer = bp; - *lenremain = remain; - *argp = (krb5_pointer) edescp; - } - else { - if (!kret && (ibuf != KG_ENC_DESC)) - kret = EINVAL; - if (edescp->eblock.key) - krb5_free_keyblock(kcontext, edescp->eblock.key); - if (edescp->eblock.priv && edescp->eblock.priv_size) - krb5_xfree(edescp->eblock.priv); - if (edescp->key) - krb5_free_keyblock(kcontext, edescp->key); - xfree(edescp); - } - } - } - return(kret); -} - static krb5_error_code kg_oid_externalize(kcontext, arg, buffer, lenremain) krb5_context kcontext; @@ -416,12 +230,15 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_int32 for seq_recv. * krb5_int32 for established. * krb5_int32 for big_endian. + * krb5_int32 for gsskrb5_version. + * krb5_int32 for nctypes. * krb5_int32 for trailer. */ kret = EINVAL; if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { - required = 14*sizeof(krb5_int32); + required = 16*sizeof(krb5_int32); required += sizeof(ctx->seed); + required += ctx->nctypes*sizeof(krb5_int32); kret = 0; if (!kret && ctx->here) @@ -442,14 +259,16 @@ kg_ctx_size(kcontext, arg, sizep) (krb5_pointer) ctx->subkey, &required); - if (!kret) - kret = kg_enc_desc_size(kcontext, - (krb5_pointer) &ctx->enc, + if (!kret && ctx->enc) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->enc, &required); - if (!kret) - kret = kg_enc_desc_size(kcontext, - (krb5_pointer) &ctx->seq, + if (!kret && ctx->seq) + kret = krb5_size_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->seq, &required); if (!kret) @@ -486,6 +305,7 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) size_t required; krb5_octet *bp; size_t remain; + int i; required = 0; bp = *buffer; @@ -526,6 +346,10 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version, + &bp, &remain); + (void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes, + &bp, &remain); /* Now dynamic data */ kret = 0; @@ -552,14 +376,16 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) (krb5_pointer) ctx->subkey, &bp, &remain); - if (!kret) - kret = kg_enc_desc_externalize(kcontext, - (krb5_pointer) &ctx->enc, + if (!kret && ctx->enc) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->enc, &bp, &remain); - if (!kret) - kret = kg_enc_desc_externalize(kcontext, - (krb5_pointer) &ctx->seq, + if (!kret && ctx->seq) + kret = krb5_externalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer) ctx->seq, &bp, &remain); if (!kret && ctx->seqstate) @@ -571,6 +397,13 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) KV5M_AUTH_CONTEXT, (krb5_pointer) ctx->auth_context, &bp, &remain); + + for (i=0; i<ctx->nctypes; i++) { + if (!kret) { + kret = krb5_ser_pack_int32((krb5_int32) ctx->ctypes[i], + &bp, &remain); + } + } if (!kret) { (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); @@ -597,7 +430,7 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) krb5_int32 ibuf; krb5_octet *bp; size_t remain; - krb5_gss_enc_desc *edp; + int i; bp = *buffer; remain = *lenremain; @@ -640,6 +473,10 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) ctx->established = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->big_endian = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->gsskrb5_version = (int) ibuf; + (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->nctypes = (int) ibuf; if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp, &remain))) { @@ -670,29 +507,21 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) if (kret == EINVAL) kret = 0; } - if (!kret) { - if ((kret = kg_enc_desc_internalize(kcontext, - (krb5_pointer *) &edp, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - else { - memcpy(&ctx->enc, edp, sizeof(ctx->enc)); - xfree(edp); - } + if (!kret && + (kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) &ctx->enc, + &bp, &remain))) { + if (kret == EINVAL) + kret = 0; } - if (!kret) { - if ((kret = kg_enc_desc_internalize(kcontext, - (krb5_pointer *) &edp, - &bp, &remain))) { - if (kret == EINVAL) - kret = 0; - } - else { - memcpy(&ctx->seq, edp, sizeof(ctx->seq)); - xfree(edp); - } + if (!kret && + (kret = krb5_internalize_opaque(kcontext, + KV5M_KEYBLOCK, + (krb5_pointer *) &ctx->seq, + &bp, &remain))) { + if (kret == EINVAL) + kret = 0; } if (!kret) { @@ -708,6 +537,22 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (krb5_pointer *) &ctx->auth_context, &bp, &remain); + if (!kret) { + if (ctx->nctypes) { + if ((ctx->ctypes = (krb5_cksumtype *) + malloc(ctx->nctypes*sizeof(krb5_cksumtype))) == NULL){ + kret = ENOMEM; + } + + for (i=0; i<ctx->nctypes; i++) { + if (!kret) { + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + ctx->ctypes[i] = (krb5_cksumtype) ibuf; + } + } + } + } + /* Get trailer */ if (!kret && !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && @@ -719,18 +564,10 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) else { if (!kret && (ibuf != KG_CONTEXT)) kret = EINVAL; - if (ctx->seq.eblock.key) - krb5_free_keyblock(kcontext, ctx->seq.eblock.key); - if (ctx->seq.eblock.priv && ctx->seq.eblock.priv_size) - krb5_xfree(ctx->seq.eblock.priv); - if (ctx->seq.key) - krb5_free_keyblock(kcontext, ctx->seq.key); - if (ctx->enc.eblock.key) - krb5_free_keyblock(kcontext, ctx->enc.eblock.key); - if (ctx->enc.eblock.priv && ctx->enc.eblock.priv_size) - krb5_xfree(ctx->enc.eblock.priv); - if (ctx->enc.key) - krb5_free_keyblock(kcontext, ctx->enc.key); + if (ctx->seq) + krb5_free_keyblock(kcontext, ctx->seq); + if (ctx->enc) + krb5_free_keyblock(kcontext, ctx->enc); if (ctx->subkey) krb5_free_keyblock(kcontext, ctx->subkey); if (ctx->there) diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index 68561f10b3..10e6b657fd 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -36,20 +36,25 @@ kg_checksum_channel_bindings(context, cb, cksum, bigend) { int len; char *buf, *ptr; + size_t sumlen; + krb5_data plaind; krb5_error_code code; - /* initialize the the cksum and allocate the contents buffer */ + /* initialize the the cksum */ + if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) + return(code); + cksum->checksum_type = CKSUMTYPE_RSA_MD5; - cksum->length = krb5_checksum_size(context, CKSUMTYPE_RSA_MD5); - if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { - return(ENOMEM); - } + cksum->length = sumlen; /* generate a buffer full of zeros if no cb specified */ if (cb == GSS_C_NO_CHANNEL_BINDINGS) { - memset(cksum->contents, '\0', cksum->length); - return(0); + if ((cksum->contents = (krb5_octet *) xmalloc(cksum->length)) == NULL) { + return(ENOMEM); + } + memset(cksum->contents, '\0', cksum->length); + return(0); } /* create the buffer to checksum into */ @@ -75,9 +80,11 @@ kg_checksum_channel_bindings(context, cb, cksum, bigend) /* checksum the data */ - if (code = krb5_calculate_checksum(context, CKSUMTYPE_RSA_MD5, - buf, len, NULL, 0, cksum)) { - xfree(cksum->contents); + plaind.length = len; + plaind.data = buf; + + if (code = krb5_c_make_checksum(context, CKSUMTYPE_RSA_MD5, 0, 0, + &plaind, cksum)) { xfree(buf); return(code); } diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 1684377ad6..93d46946c1 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include "gssapiP_krb5.h" #include <memory.h> @@ -31,103 +57,126 @@ static unsigned char zeros[8] = {0,0,0,0,0,0,0,0}; int -kg_confounder_size(ed) - krb5_gss_enc_desc *ed; +kg_confounder_size(context, key) + krb5_context context; + krb5_keyblock *key; { - /* XXX Abstraction violation!!! */ + krb5_error_code code; + size_t blocksize; + + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(-1); /* XXX */ - return(ed->eblock.crypto_entry->block_length); + return(blocksize); } krb5_error_code -kg_make_confounder(ed, buf) - krb5_gss_enc_desc *ed; +kg_make_confounder(context, key, buf) + krb5_context context; + krb5_keyblock *key; unsigned char *buf; { - /* XXX Abstraction violation!!! */ + krb5_error_code code; + size_t blocksize; + krb5_data random; + + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(code); - return(krb5_random_confounder(ed->eblock.crypto_entry->block_length, buf)); + random.length = blocksize; + random.data = buf; + + return(krb5_c_random_make_octets(context, &random)); } int -kg_encrypt_size(ed, n) - krb5_gss_enc_desc *ed; +kg_encrypt_size(context, key, n) + krb5_context context; + krb5_keyblock *key; int n; { - return(krb5_encrypt_size(n, ed->eblock.crypto_entry)); + krb5_error_code code; + size_t enclen; + + if (code = krb5_c_encrypt_length(context, key->enctype, n, &enclen)) + return(-1); /* XXX */ + + return(enclen); } krb5_error_code -kg_encrypt(context, ed, iv, in, out, length) +kg_encrypt(context, key, iv, in, out, length) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; krb5_pointer iv; krb5_pointer in; krb5_pointer out; int length; { krb5_error_code code; - krb5_pointer tmp; - - if (! ed->processed) { - if (code = krb5_process_key(context, &ed->eblock, ed->key)) - return(code); - ed->processed = 1; + size_t blocksize; + krb5_data ivd, *pivd, inputd; + krb5_enc_data outputd; + + if (iv) { + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(code); + + ivd.length = blocksize; + ivd.data = iv; + pivd = &ivd; + } else { + pivd = NULL; } - /* this is lame. the krb5 encryption interfaces no longer allow - you to encrypt in place. perhaps this should be fixed, but - dealing here is easier for now --marc */ - - if ((tmp = (krb5_pointer) xmalloc(length)) == NULL) - return(ENOMEM); + inputd.length = length; + inputd.data = in; - memcpy(tmp, in, length); + outputd.ciphertext.length = length; + outputd.ciphertext.data = out; - code = krb5_encrypt(context, tmp, out, length, &ed->eblock, - iv?iv:(krb5_pointer)zeros); - - xfree(tmp); - - if (code) - return(code); - - return(0); + return(krb5_c_encrypt(context, key, + /* XXX this routine is only used for the old + bare-des stuff which doesn't use the + key usage */ 0, pivd, &inputd, &outputd)); } /* length is the length of the cleartext. */ krb5_error_code -kg_decrypt(context, ed, iv, in, out, length) +kg_decrypt(context, key, iv, in, out, length) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; krb5_pointer iv; krb5_pointer in; krb5_pointer out; int length; { krb5_error_code code; - int elen; - char *buf; - - if (! ed->processed) { - if (code = krb5_process_key(context, &ed->eblock, ed->key)) - return(code); - ed->processed = 1; + size_t blocksize, enclen; + krb5_data ivd, *pivd, outputd; + krb5_enc_data inputd; + + if (iv) { + if (code = krb5_c_block_size(context, key->enctype, &blocksize)) + return(code); + + ivd.length = blocksize; + ivd.data = iv; + pivd = &ivd; + } else { + pivd = NULL; } - elen = krb5_encrypt_size(length, ed->eblock.crypto_entry); - if ((buf = (char *) xmalloc(elen)) == NULL) - return(ENOMEM); - - if (code = krb5_decrypt(context, in, buf, elen, &ed->eblock, - iv?iv:(krb5_pointer)zeros)) { - xfree(buf); - return(code); - } + inputd.enctype = ENCTYPE_UNKNOWN; + inputd.ciphertext.length = length; + inputd.ciphertext.data = in; - memcpy(out, buf, length); - xfree(buf); + outputd.length = length; + outputd.data = out; - return(0); + return(krb5_c_decrypt(context, key, + /* XXX this routine is only used for the old + bare-des stuff which doesn't use the + key usage */ 0, pivd, &inputd, &outputd)); } diff --git a/src/lib/gssapi/krb5/util_ctxsetup.c b/src/lib/gssapi/krb5/util_ctxsetup.c new file mode 100644 index 0000000000..0add6bf73f --- /dev/null +++ b/src/lib/gssapi/krb5/util_ctxsetup.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "gssapiP_krb5.h" + +/* from the token, flags is stored directly. nctypes/ctypes is + allocated and returns the length and list of ctypes in the token. + noptions/options lists all the options which the caller cares + about. Those which are present in the token are filled in; the + order and length are not changed. If an error is returned, the + option list is in an indeterminate state. */ + +OM_uint32 +kg2_parse_token(minor_status, ptr, token_length, flags, nctypes, ctypes, + noptions, options, kmsg, mic) + OM_uint32 *minor_status; + unsigned char *ptr; + int token_length; + krb5_ui_4 *flags; + int *nctypes; /* OUT */ + krb5_cksumtype **ctypes; /* OUT */ + int noptions; + struct kg2_option *options; /* INOUT */ + krb5_data *kmsg; + krb5_data *mic; +{ + int field_length, i; + int opt_id; + + *ctypes = 0; + + /* read the flags */ + + if (token_length < 4) + goto defective; + *flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; + ptr += 4; + token_length -= 4; + + /* read out the token list */ + + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + *nctypes = field_length; + + if (*nctypes == 0) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + if ((*ctypes = (krb5_cksumtype *) + malloc((*nctypes) * sizeof(krb5_cksumtype))) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + for (i=0; i<field_length; i++) { + if (token_length < 4) + goto defective; + + (*ctypes)[i] = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | + (ptr[2]<<8) | ptr[3]); + ptr += 4; + token_length -= 4; + } + + do { + if (token_length < 4) + goto defective; + opt_id = (ptr[0]<<8) | ptr[1]; + field_length = (ptr[2]<<8) | ptr[3]; + ptr += 4; + token_length -= 4; + + if (token_length < field_length) + goto defective; + + for (i=0; i<noptions; i++) { + if (options[i].option_id = opt_id) { + options[i].length = field_length; + options[i].data = ptr; + } + break; + } + + ptr += field_length; + token_length -= field_length; + } while (opt_id); + + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + if (token_length < field_length) + goto defective; + + kmsg->length = field_length; + kmsg->data = ptr; + + ptr += field_length; + token_length -= field_length; + + /* if there's anything left, assume it's a mic. the mic isn't + necessarily present */ + + if (mic && token_length) { + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + if (token_length < field_length) + goto defective; + + mic->length = field_length; + mic->data = ptr; + + ptr += field_length; + token_length -= field_length; + } else if (mic) { + mic->length = 0; + mic->data = ptr; + } + + if (token_length) + goto defective; + + return(GSS_S_COMPLETE); + +defective: + if (*ctypes) + free(*ctypes); + + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); +} + +/* nc1/c1 will be modified to contain the intersection of the + two lists. */ + +void +kg2_intersect_ctypes(nc1, c1, nc2, c2) + int *nc1; + krb5_cksumtype *c1; + int nc2; + const krb5_cksumtype *c2; +{ + int i, j, count; + krb5_cksumtype tmp; + + count = 0; + + for (i=0; i<*nc1; i++) { + /* first, check to make sure that c1[i] isn't a duplicate in c1 */ + for (j=0; j<i; j++) + if (c1[i] == c1[j]) + break; + if (j<i) + continue; + /* check if c1[i] is in c2. If it is, keep it by swapping + it into c1[count] and incrementing count. If count < i, then + that field has already been looked at and skipped as + not intersecting, which is ok. */ + + for (j=0; j<nc2; j++) + if (c1[i] == c2[j]) + break; + if ((j<nc2) && (count != i)) { + tmp = c1[count]; + c1[count] = c1[i]; + c1[i] = tmp; + } + count++; + } + + *nc1 = count; +} + diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c index 14f3652452..206ee68a7b 100644 --- a/src/lib/gssapi/krb5/util_seed.c +++ b/src/lib/gssapi/krb5/util_seed.c @@ -36,24 +36,20 @@ kg_make_seed(context, key, seed) unsigned char *seed; { krb5_error_code code; - krb5_gss_enc_desc ed; + krb5_keyblock *tmpkey; int i; - if (code = krb5_copy_keyblock(context, key, &ed.key)) + if (code = krb5_copy_keyblock(context, key, &tmpkey)) return(code); /* reverse the key bytes, as per spec */ - for (i=0; i<ed.key->length; i++) - ed.key->contents[i] = key->contents[key->length - 1 - i]; + for (i=0; i<tmpkey->length; i++) + tmpkey->contents[i] = key->contents[key->length - 1 - i]; - krb5_use_enctype(context, &ed.eblock, ENCTYPE_DES_CBC_RAW); - ed.processed = 0; + code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16); - code = kg_encrypt(context, &ed, NULL, zeros, seed, 16); - - krb5_finish_key(context, &ed.eblock); - krb5_free_keyblock(context, ed.key); + krb5_free_keyblock(context, tmpkey); return(code); } diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c index ed9293f778..e14b2f3fec 100644 --- a/src/lib/gssapi/krb5/util_seqnum.c +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -27,9 +27,9 @@ */ krb5_error_code -kg_make_seq_num(context, ed, direction, seqnum, cksum, buf) +kg_make_seq_num(context, key, direction, seqnum, cksum, buf) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; int direction; krb5_int32 seqnum; unsigned char *cksum; @@ -47,12 +47,12 @@ kg_make_seq_num(context, ed, direction, seqnum, cksum, buf) plain[6] = direction; plain[7] = direction; - return(kg_encrypt(context, ed, cksum, plain, buf, 8)); + return(kg_encrypt(context, key, cksum, plain, buf, 8)); } -krb5_error_code kg_get_seq_num(context, ed, cksum, buf, direction, seqnum) +krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) krb5_context context; - krb5_gss_enc_desc *ed; + krb5_keyblock *key; unsigned char *cksum; unsigned char *buf; int *direction; @@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, ed, cksum, buf, direction, seqnum) krb5_error_code code; unsigned char plain[8]; - if (code = kg_decrypt(context, ed, cksum, buf, plain, 8)) + if (code = kg_decrypt(context, key, cksum, buf, plain, 8)) return(code); if ((plain[4] != plain[5]) || diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c index f2366d16e2..7459492609 100644 --- a/src/lib/gssapi/krb5/wrap_size_limit.c +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -20,6 +20,32 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "gssapiP_krb5.h" /* @@ -39,8 +65,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, { krb5_context context; krb5_gss_ctx_id_rec *ctx; - OM_uint32 cfsize; - OM_uint32 ohlen; + krb5_error_code code; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -63,19 +88,86 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, return(GSS_S_NO_CONTEXT); } - /* Calculate the token size and subtract that from the output size */ - cfsize = (conf_req_flag) ? kg_confounder_size(&ctx->enc) : 0; - ohlen = g_token_size((gss_OID) ctx->mech_used, - (unsigned int) cfsize + ctx->cksum_size + 14); + if (ctx->gsskrb5_version == 2000) { + if (conf_req_flag) { + /* this is pretty gross. take the max output, and call + krb5_c_encrypt_length to see how much overhead is added + on. subtract that much, and see if it fits in the + requested space. If not, start subtracting 1 until it + does. This doesn't necessarily give us the optimal + packing, but I think that's ok (I could start adding 1 + until I went over, but that seems like it's not worth + the effort). This is probably O(blocksize), but that's + never going to be large. */ + + OM_uint32 headerlen, plainlen; + size_t enclen; + + headerlen = g_token_size((gss_OID) ctx->mech_used, 2); + plainlen = req_output_size - headerlen; + + if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, + plainlen, &enclen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + plainlen -= plainlen - (enclen - plainlen); + + if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, + plainlen, &enclen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } - if (ohlen < req_output_size) + while (headerlen + enclen > req_output_size) { + plainlen--; + + if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, + plainlen, &enclen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + } + + /* subtract off the fixed size inside the encrypted part */ + + plainlen -= 7; + + *max_input_size = plainlen; + } else { + size_t cksumlen; + OM_uint32 headerlen; + + if (code = krb5_c_checksum_length(context, ctx->ctypes[0], + &cksumlen)) { + *minor_status = code; + return(GSS_S_FAILURE); + } + + headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen); + + *max_input_size = req_output_size - headerlen; + } + } else { + OM_uint32 cfsize; + OM_uint32 ohlen; + + /* Calculate the token size and subtract that from the output size */ + cfsize = (conf_req_flag) ? kg_confounder_size(context, ctx->enc) : 0; + ohlen = g_token_size((gss_OID) ctx->mech_used, + (unsigned int) cfsize + ctx->cksum_size + 14); + + if (ohlen < req_output_size) /* * Cannot have trailer length that will cause us to pad over * our length */ *max_input_size = (req_output_size - ohlen - 1) & (~7); - else + else *max_input_size = 0; + } + *minor_status = 0; return(GSS_S_COMPLETE); } diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index ae8bb7e1b1..64dc648d6c 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,14 @@ +Thu Aug 13 17:21:06 1998 Tom Yu <tlyu@mit.edu> + + * alt_prof.c (krb5_read_realm_params): Fix to check + "supported_enctypes" if "kdc_supported_enctypes" isn't there. + +Wed Aug 12 20:19:08 1998 Tom Yu <tlyu@mit.edu> + + * alt_prof.c (krb5_read_realm_params): Use + "kdc_supported_enctypes" instead of "supported_enctypes" so that + the KDC and the kadmind will use different enctype lists. + Wed Jul 8 04:48:50 1998 Geoffrey J. King <gjking@mit.edu> * logger.c: Add the function krb5_klog_reopen() which closes diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index b2260d67a8..934785322b 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -866,8 +866,15 @@ krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp) } /* Get the value for the supported enctype/salttype matrix */ - hierarchy[2] = "supported_enctypes"; - if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) { + /* XXX This is so that the kdc will search a different + enctype list than kadmind */ + hierarchy[2] = "kdc_supported_enctypes"; + kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); + if (kret) { + hierarchy[2] = "supported_enctypes"; + kret = krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); + } + if (!kret) { krb5_string_to_keysalts(svalue, ", \t", /* Tuple separators */ ":.-", /* Key/salt separators */ diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog index e1e761ce53..5f46d21854 100644 --- a/src/lib/kadm5/clnt/ChangeLog +++ b/src/lib/kadm5/clnt/ChangeLog @@ -1,3 +1,12 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * client_init.c (_kadm5_init_any): try the krb5 v2 mechanism + first, and if that fails, try the krb5 v1 mech. + +Sun Jul 26 18:11:56 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (LIBMAJOR): bump libmajor + Wed Apr 15 18:05:57 1998 Tom Yu <tlyu@mit.edu> * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in index 662bc76019..b125ea7a1a 100644 --- a/src/lib/kadm5/clnt/Makefile.in +++ b/src/lib/kadm5/clnt/Makefile.in @@ -3,7 +3,7 @@ BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U) CFLAGS = $(CCOPTS) $(DEFS) -I$(BUILDTOP)/include/kadm5 LIB=kadm5clnt -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 STOBJLISTS=../OBJS.ST OBJS.ST SHLIB_EXPDEPS=\ diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c index 11cd77c748..96c5907af7 100644 --- a/src/lib/kadm5/clnt/client_init.c +++ b/src/lib/kadm5/clnt/client_init.c @@ -4,6 +4,32 @@ * $Header$ */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #if !defined(lint) && !defined(__CODECENTER__) static char *rcsid = "$Header$"; #endif @@ -444,12 +470,26 @@ static kadm5_ret_t _kadm5_init_any(char *client_name, &minor_stat, gss_client_creds, gss_target, - GSS_C_NULL_OID, + gss_mech_krb5_v2, + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + 0, + NULL, + NULL, + NULL); + + if (!handle->clnt->cl_auth) + handle->clnt->cl_auth = auth_gssapi_create(handle->clnt, + &gssstat, + &minor_stat, + gss_client_creds, + gss_target, + gss_mech_krb5, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, 0, NULL, NULL, NULL); + (void) gss_release_name(&minor_stat, &gss_target); #endif /* ! INIT_TEST */ diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index 04011541b1..67dbe38429 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,11 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * server_kdb.c, svr_principal.c: convert to new crypto api + +Sun Jul 26 18:09:55 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (LIBMAJOR): bump libmajor + Wed Apr 15 18:06:14 1998 Tom Yu <tlyu@mit.edu> * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in index ff6552bd72..53e4698635 100644 --- a/src/lib/kadm5/srv/Makefile.in +++ b/src/lib/kadm5/srv/Makefile.in @@ -6,7 +6,7 @@ CFLAGS = $(CCOPTS) $(DEFS) -I$(BUILDTOP)/include/kadm5 @HESIOD_DEFS@ ##DOSLIBNAME = libkadm5srv.lib LIB=kadm5srv -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 STOBJLISTS=../OBJS.ST OBJS.ST SHLIB_EXPDEPS=\ diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c index 1a900a380f..2487f88e02 100644 --- a/src/lib/kadm5/srv/server_kdb.c +++ b/src/lib/kadm5/srv/server_kdb.c @@ -15,12 +15,10 @@ static char *rcsid = "$Header$"; #include "server_internal.h" krb5_principal master_princ; -krb5_encrypt_block master_encblock; krb5_keyblock master_keyblock; krb5_db_entry master_db; krb5_principal hist_princ; -krb5_encrypt_block hist_encblock; krb5_keyblock hist_key; krb5_db_entry hist_db; krb5_kvno hist_kvno; @@ -49,11 +47,8 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, master_keyblock.enctype = handle->params.enctype; - krb5_use_enctype(handle->context, &master_encblock, - master_keyblock.enctype); - if (ret = krb5_db_fetch_mkey(handle->context, master_princ, - &master_encblock, from_keyboard, + master_keyblock.enctype, from_keyboard, FALSE /* only prompt once */, handle->params.stash_file, NULL /* I'm not sure about this, @@ -65,21 +60,11 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, goto done; if ((ret = krb5_db_verify_master_key(handle->context, master_princ, - &master_keyblock, - &master_encblock))) { + &master_keyblock))) { krb5_db_fini(handle->context); return ret; } - /* the kdc gets the db mkvno here. The admin server never uses this - bit of information, so there's no reason to retrieve it. */ - - if ((ret = krb5_process_key(handle->context, &master_encblock, - &master_keyblock))) { - krb5_db_fini(handle->context); - goto done; - } - done: if (r == NULL) free(realm); @@ -190,16 +175,10 @@ krb5_error_code kdb_init_hist(kadm5_server_handle_t handle, char *r) &key_data)) goto done; - if (ret = krb5_dbekd_decrypt_key_data(handle->context, &master_encblock, + if (ret = krb5_dbekd_decrypt_key_data(handle->context, &master_keyblock, key_data, &hist_key, NULL)) goto done; - krb5_use_enctype(handle->context, &hist_encblock, hist_key.enctype); - - if ((ret = krb5_process_key(handle->context, &hist_encblock, - &hist_key)) != KSUCCESS) - goto done; - hist_kvno = key_data->key_data_kvno; done: diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index ee45723a47..9504556ffb 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -22,8 +22,6 @@ static char *rcsid = "$Header$"; extern krb5_principal master_princ; extern krb5_principal hist_princ; -extern krb5_encrypt_block master_encblock; -extern krb5_encrypt_block hist_encblock; extern krb5_keyblock master_keyblock; extern krb5_keyblock hist_key; extern krb5_db_entry master_db; @@ -236,7 +234,7 @@ kadm5_create_principal(void *server_handle, /* initialize the keys */ - if (ret = krb5_dbe_cpw(handle->context, &master_encblock, + if (ret = krb5_dbe_cpw(handle->context, &master_keyblock, handle->params.keysalts, handle->params.num_keysalts, password, @@ -816,20 +814,20 @@ done: * Arguments: * * context (r) the krb5 context - * histkey_encblock (r) the encblock that hist_key_data is + * hist_keyblock (r) the key that hist_key_data is * encrypted in * n_new_key_data (r) length of new_key_data * new_key_data (r) keys to check against - * pw_hist_data, encrypted in histkey_encblock + * pw_hist_data, encrypted in hist_keyblock * n_pw_hist_data (r) length of pw_hist_data * pw_hist_data (r) passwords to check new_key_data against * * Effects: * For each new_key in new_key_data: - * decrypt new_key with the master_encblock + * decrypt new_key with the master_keyblock * for each password in pw_hist_data: * for each hist_key in password: - * decrypt hist_key with histkey_encblock + * decrypt hist_key with hist_keyblock * compare the new_key and hist_key * * Returns krb5 errors, KADM5_PASS_RESUSE if a key in @@ -837,7 +835,7 @@ done: */ static kadm5_ret_t check_pw_reuse(krb5_context context, - krb5_encrypt_block *histkey_encblock, + krb5_keyblock *hist_keyblock, int n_new_key_data, krb5_key_data *new_key_data, int n_pw_hist_data, osa_pw_hist_ent *pw_hist_data) { @@ -847,7 +845,7 @@ check_pw_reuse(krb5_context context, for (x = 0; x < n_new_key_data; x++) { if (ret = krb5_dbekd_decrypt_key_data(context, - &master_encblock, + &master_keyblock, &(new_key_data[x]), &newkey, NULL)) return(ret); @@ -855,7 +853,7 @@ check_pw_reuse(krb5_context context, for (z = 0; z < pw_hist_data[y].n_key_data; z++) { if (ret = krb5_dbekd_decrypt_key_data(context, - histkey_encblock, + hist_keyblock, &pw_hist_data[y].key_data[z], &histkey, NULL)) return(ret); @@ -894,8 +892,8 @@ check_pw_reuse(krb5_context context, * Effects: * * hist->key_data is allocated to store n_key_data key_datas. Each - * element of key_data is decrypted with master_encblock, re-encrypted - * in hist_encblock, and added to hist->key_data. hist->n_key_data is + * element of key_data is decrypted with master_keyblock, re-encrypted + * in hist_key, and added to hist->key_data. hist->n_key_data is * set to n_key_data. */ int create_history_entry(krb5_context context, int n_key_data, @@ -912,12 +910,12 @@ int create_history_entry(krb5_context context, int n_key_data, for (i = 0; i < n_key_data; i++) { if (ret = krb5_dbekd_decrypt_key_data(context, - &master_encblock, + &master_keyblock, &key_data[i], &key, &salt)) return ret; if (ret = krb5_dbekd_encrypt_key_data(context, - &hist_encblock, + &hist_key, &key, &salt, key_data[i].key_data_kvno, &hist->key_data[i])) @@ -1052,7 +1050,7 @@ kadm5_chpass_principal(void *server_handle, KADM5_POLICY, &pol, principal))) goto done; - if (ret = krb5_dbe_cpw(handle->context, &master_encblock, + if (ret = krb5_dbe_cpw(handle->context, &master_keyblock, handle->params.keysalts, handle->params.num_keysalts, password, 0 /* increment kvno */, &kdb)) @@ -1090,7 +1088,7 @@ kadm5_chpass_principal(void *server_handle, goto done; if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, 1, &hist)) goto done; @@ -1102,7 +1100,7 @@ kadm5_chpass_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1171,7 +1169,7 @@ kadm5_randkey_principal(void *server_handle, if ((ret = kdb_get_entry(handle, principal, &kdb, &adb))) return(ret); - if (ret = krb5_dbe_crk(handle->context, &master_encblock, + if (ret = krb5_dbe_crk(handle->context, &master_keyblock, handle->params.keysalts, handle->params.num_keysalts, &kdb)) @@ -1213,7 +1211,7 @@ kadm5_randkey_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1316,7 +1314,7 @@ kadm5_setv4key_principal(void *server_handle, keysalt.data.data = NULL; if (ret = krb5_dbekd_encrypt_key_data(handle->context, - &master_encblock, + &master_keyblock, keyblock, &keysalt, kvno + 1, kdb.key_data)) { @@ -1361,7 +1359,7 @@ kadm5_setv4key_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1402,9 +1400,9 @@ kadm5_setkey_principal(void *server_handle, krb5_int32 now; kadm5_policy_ent_rec pol; krb5_key_data *key_data; - int i, kvno, ret, last_pwd, have_pol = 0; - int deskeys; + int i, j, kvno, ret, last_pwd, have_pol = 0; kadm5_server_handle_t handle = server_handle; + krb5_boolean similar; CHECK_HANDLE(server_handle); @@ -1415,14 +1413,16 @@ kadm5_setkey_principal(void *server_handle, principal, hist_princ)) == TRUE)) return KADM5_PROTECT_PRINCIPAL; - for (i = 0, deskeys = 0; i < n_keys; i++) { - if (keyblocks[i].enctype == ENCTYPE_DES_CBC_MD4 || - keyblocks[i].enctype == ENCTYPE_DES_CBC_MD5 || - keyblocks[i].enctype == ENCTYPE_DES_CBC_RAW || - keyblocks[i].enctype == ENCTYPE_DES_CBC_CRC) - deskeys++; - if (deskeys > 1) - return KADM5_SETKEY_DUP_ENCTYPES; + for (i = 0; i < n_keys; i++) { + 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) + return KADM5_SETKEY_DUP_ENCTYPES; + } } if ((ret = kdb_get_entry(handle, principal, &kdb, &adb))) @@ -1443,7 +1443,7 @@ kadm5_setkey_principal(void *server_handle, for (i = 0; i < n_keys; i++) { if (ret = krb5_dbekd_encrypt_key_data(handle->context, - &master_encblock, + &master_keyblock, &keyblocks[i], NULL, kvno + 1, &kdb.key_data[i])) @@ -1488,7 +1488,7 @@ kadm5_setkey_principal(void *server_handle, } if (ret = check_pw_reuse(handle->context, - &hist_encblock, + &hist_key, kdb.n_key_data, kdb.key_data, adb.old_key_len, adb.old_keys)) goto done; @@ -1521,7 +1521,7 @@ done: /* * Allocate an array of n_key_data krb5_keyblocks, fill in each * element with the results of decrypting the nth key in key_data with - * master_encblock, and if n_keys is not NULL fill it in with the + * master_keyblock, and if n_keys is not NULL fill it in with the * number of keys decrypted. */ static int decrypt_key_data(krb5_context context, @@ -1538,7 +1538,7 @@ static int decrypt_key_data(krb5_context context, for (i = 0; i < n_key_data; i++) { if (ret = krb5_dbekd_decrypt_key_data(context, - &master_encblock, + &master_keyblock, &key_data[i], &keys[i], NULL)) { @@ -1609,7 +1609,7 @@ kadm5_ret_t kadm5_decrypt_key(void *server_handle, return ret; if (ret = krb5_dbekd_decrypt_key_data(handle->context, - &master_encblock, key_data, + &master_keyblock, key_data, keyblock, keysalt)) return ret; diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index ec0b38457c..e12270d5c8 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,33 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * kdb_xdr.c, kdb_cpw.c: remove the special knowledge of ENCTYPE + string-to-key equivalances. the crypto api has a function for + this now. + + * decrypt_key.c, encrypt_key.c, fetch_mkey.c, kdb_cpw.c, + kdb_db2.c, kdb_db2.h, kdb_dbm.c, keytab.c, verify_mky.c: change or + remove all the places krb5_encrypt_block was used + (this is mostly relevant to kdb manipulations). It was usually + used to specify an enctype (which is now implied by the keyblock), + or to store or pass in a processed key (now the api just takes a + key directly, so these structures and functions do, too). The kdb + key manuipulation functions also need to be made to use the new + api. + +Fri Sep 25 19:42:10 1998 Tom Yu <tlyu@mit.edu> + + * kdb_xdr.c (krb5_dbe_search_enctype): Re-order booleans so that + similar doesn't get checked unless (ktype >= 0) to avoid it being + stack garbage. + +Sun Aug 16 16:52:10 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (SHLIB_EXPLIBS): Include $(LIBS) so building on AIX works + +Sun Jul 26 18:12:22 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (LIBMAJOR): bump libmajor + 1998-05-06 Theodore Ts'o <tytso@rsts-11.mit.edu> * t_kdb.c (main): POSIX states that getopt returns -1 diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in index 9ec4b23d48..c44b58631d 100644 --- a/src/lib/kdb/Makefile.in +++ b/src/lib/kdb/Makefile.in @@ -7,14 +7,14 @@ PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) LIB=kdb5 -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 RELDIR=kdb # Depends on libk5crypto and libkrb5 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(TOPLIBD)/libkrb5$(SHLIBEXT) -SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto +SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto $(LIBS) SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c index 2aa199ac7e..0cfdbda8e0 100644 --- a/src/lib/kdb/decrypt_key.c +++ b/src/lib/kdb/decrypt_key.c @@ -24,6 +24,32 @@ * krb5_kdb_encrypt_key(), krb5_kdb_decrypt_key functions */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" /* @@ -33,40 +59,53 @@ */ krb5_error_code -krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) +krb5_dbekd_decrypt_key_data(context, mkey, key_data, dbkey, keysalt) krb5_context context; - krb5_encrypt_block * eblock; + const krb5_keyblock * mkey; const krb5_key_data * key_data; - krb5_keyblock * keyblock; + krb5_keyblock * dbkey; krb5_keysalt * keysalt; { krb5_error_code retval = 0; krb5_int16 tmplen; krb5_octet * ptr; + krb5_enc_data cipher; + krb5_data plain; - keyblock->magic = KV5M_KEYBLOCK; - keyblock->enctype = key_data->key_data_type[0]; - - /* Decrypt key_data_contents */ - if ((keyblock->contents = (krb5_octet *)malloc(krb5_encrypt_size( - key_data->key_data_length[0] - 2, eblock->crypto_entry))) == NULL) - return ENOMEM; - - keyblock->length = 0; ptr = key_data->key_data_contents[0]; + if (ptr) { krb5_kdb_decode_int16(ptr, tmplen); ptr += 2; - keyblock->length = (int) tmplen; - if ((retval = krb5_decrypt(context, (krb5_pointer) ptr, - (krb5_pointer)keyblock->contents, - key_data->key_data_length[0] - 2, - eblock, 0))) { - krb5_xfree(keyblock->contents); - keyblock->contents = 0; - keyblock->length = 0; + + cipher.enctype = ENCTYPE_UNKNOWN; + cipher.ciphertext.length = key_data->key_data_length[0]-2; + cipher.ciphertext.data = ptr; + plain.length = key_data->key_data_length[0]-2; + if ((plain.data = (krb5_octet *) malloc(plain.length)) == NULL) + return(ENOMEM); + + if ((retval = krb5_c_decrypt(context, mkey, 0 /* XXX */, 0, + &cipher, &plain))) { + krb5_xfree(plain.data); return retval; } + + /* tmplen is the true length of the key. plain.data is the + plaintext data length, but it may be padded, since the + old-style etypes didn't store the real length. I can check + to make sure that there are enough bytes, but I can't do + any better than that. */ + + if (tmplen > plain.length) { + krb5_xfree(plain.data); + return(KRB5_CRYPTO_INTERNAL); + } + + dbkey->magic = KV5M_KEYBLOCK; + dbkey->enctype = key_data->key_data_type[0]; + dbkey->length = tmplen; + dbkey->contents = plain.data; } /* Decode salt data */ @@ -75,9 +114,11 @@ krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) keysalt->type = key_data->key_data_type[1]; if ((keysalt->data.length = key_data->key_data_length[1])) { if (!(keysalt->data.data=(char *)malloc(keysalt->data.length))){ - krb5_xfree(keyblock->contents); - keyblock->contents = 0; - keyblock->length = 0; + if (key_data->key_data_contents[0]) { + krb5_xfree(dbkey->contents); + dbkey->contents = 0; + dbkey->length = 0; + } return ENOMEM; } memcpy(keysalt->data.data, key_data->key_data_contents[1], @@ -90,5 +131,6 @@ krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt) keysalt->data.length = 0; } } + return retval; } diff --git a/src/lib/kdb/encrypt_key.c b/src/lib/kdb/encrypt_key.c index ea7d17ca78..7bcfe11eb1 100644 --- a/src/lib/kdb/encrypt_key.c +++ b/src/lib/kdb/encrypt_key.c @@ -24,6 +24,32 @@ * krb5_kdb_encrypt_key(), krb5_kdb_decrypt_key functions */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" /* @@ -33,10 +59,10 @@ */ krb5_error_code -krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) +krb5_dbekd_encrypt_key_data(context, mkey, dbkey, keysalt, keyver, key_data) krb5_context context; - krb5_encrypt_block * eblock; - const krb5_keyblock * keyblock; + const krb5_keyblock * mkey; + const krb5_keyblock * dbkey; const krb5_keysalt * keysalt; int keyver; krb5_key_data * key_data; @@ -44,8 +70,10 @@ krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) krb5_error_code retval; krb5_keyblock tmp; krb5_octet * ptr; - krb5_int16 len; + size_t len; int i; + krb5_data plain; + krb5_enc_data cipher; for (i = 0; i < key_data->key_data_ver; i++) if (key_data->key_data_contents[i]) @@ -58,39 +86,32 @@ krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) * The First element of the type/length/contents * fields is the key type/length/contents */ - key_data->key_data_type[0] = keyblock->enctype; - key_data->key_data_length[0] = krb5_encrypt_size(keyblock->length, - eblock->crypto_entry) + 2; + if ((retval = krb5_c_encrypt_length(context, mkey->enctype, dbkey->length, + &len))) + return(retval); - /* - * because of checksum space requirements imposed by the encryption - * interface, we need to copy the input key into a larger area. - */ - tmp.contents = (krb5_octet *)malloc(key_data->key_data_length[0] - 2); - len = tmp.length = keyblock->length; - if (tmp.contents == NULL) - return ENOMEM; + if ((ptr = (krb5_octet *) malloc(2 + len)) == NULL) + return(ENOMEM); - memcpy((char *)tmp.contents, (const char *)keyblock->contents, tmp.length); - key_data->key_data_contents[0] = ptr = (krb5_octet *)malloc( - key_data->key_data_length[0]); - if (key_data->key_data_contents[0] == NULL) { - krb5_xfree(tmp.contents); - return ENOMEM; - } + key_data->key_data_type[0] = dbkey->enctype; + key_data->key_data_length[0] = 2 + len; + key_data->key_data_contents[0] = ptr; - krb5_kdb_encode_int16(len, ptr); + krb5_kdb_encode_int16(dbkey->length, ptr); ptr += 2; - if ((retval = krb5_encrypt(context, (krb5_pointer) tmp.contents, - (krb5_pointer)(ptr), tmp.length, - eblock, 0))) { + + plain.length = dbkey->length; + plain.data = dbkey->contents; + + cipher.ciphertext.length = len; + cipher.ciphertext.data = ptr; + + if ((retval = krb5_c_encrypt(context, mkey, /* XXX */ 0, 0, + &plain, &cipher))) { krb5_xfree(key_data->key_data_contents[0]); - krb5_xfree(tmp.contents); return retval; } - krb5_xfree(tmp.contents); - /* After key comes the salt in necessary */ if (keysalt) { if (keysalt->type > 0) { @@ -108,5 +129,6 @@ krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data) } } } + return retval; } diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c index 5eda4eae6b..829e0283cd 100644 --- a/src/lib/kdb/fetch_mkey.c +++ b/src/lib/kdb/fetch_mkey.c @@ -25,6 +25,32 @@ * Fetch a database master key from somewhere. */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" /* these are available to other funcs, and the pointers may be reassigned */ @@ -52,10 +78,11 @@ char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; #endif krb5_error_code -krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, key) +krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile, + salt, key) krb5_context context; krb5_principal mname; - krb5_encrypt_block * eblock; + krb5_enctype etype; krb5_boolean fromkeyboard; krb5_boolean twice; char *keyfile; @@ -67,7 +94,6 @@ krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, k krb5_data pwd; int size = sizeof(password); - if (fromkeyboard) { krb5_data scratch; @@ -83,8 +109,9 @@ krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, k if (retval) return retval; } - retval = krb5_string_to_key(context, eblock, key, &pwd, - salt ? salt : &scratch); + retval = krb5_c_string_to_key(context, etype, &pwd, salt?salt:&scratch, + key); + if (!salt) krb5_xfree(scratch.data); memset(password, 0, sizeof(password)); /* erase it */ @@ -142,7 +169,8 @@ krb5_db_fetch_mkey(context, mname, eblock, fromkeyboard, twice, keyfile, salt, k key->contents = 0; } else retval = 0; - krb5_use_enctype(context, eblock, key->enctype); + + key->enctype = etype; errout: (void) fclose(kf); diff --git a/src/lib/kdb/kdb_cpw.c b/src/lib/kdb/kdb_cpw.c index ec7419e1c6..d68d784c19 100644 --- a/src/lib/kdb/kdb_cpw.c +++ b/src/lib/kdb/kdb_cpw.c @@ -22,6 +22,32 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include "krb5/adm.h" #include <stdio.h> @@ -61,32 +87,23 @@ cleanup_key_data(context, count, data) free(data); } -/* - * Currently we can only generate random keys for preinitialized - * krb5_encrypt_block with a seed. This is bogus but currently - * necessary to insure that we don't generate two keys with the - * same data. - */ static krb5_error_code -add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) +add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; krb5_db_entry * db_entry; int kvno; { krb5_principal krbtgt_princ; - krb5_keyblock krbtgt_key, * key; - krb5_pointer krbtgt_seed; - krb5_encrypt_block krbtgt_eblock; + krb5_keyblock key; krb5_db_entry krbtgt_entry; krb5_key_data * krbtgt_kdata; - krb5_boolean more, found; + krb5_boolean more; int max_kvno, one, i, j; krb5_error_code retval; - memset(&krbtgt_key, 0, sizeof(krbtgt_key)); retval = krb5_build_principal_ext(context, &krbtgt_princ, db_entry->princ->realm.length, db_entry->princ->realm.data, @@ -119,17 +136,9 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) } for (i = 0; i < ks_tuple_count; i++) { - krb5_enctype new_enctype, old_enctype; + krb5_boolean similar; - switch (new_enctype = ks_tuple[i].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - new_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } - found = 0; + similar = 0; /* * We could use krb5_keysalt_iterate to replace this loop, or use @@ -137,74 +146,44 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno) * circular library dependencies. */ for (j = 0; j < i; j++) { - switch (old_enctype = ks_tuple[j].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - old_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } - if (old_enctype == new_enctype) { - found = 1; + if ((retval = krb5_c_enctype_compare(context, + ks_tuple[i].ks_enctype, + ks_tuple[j].ks_enctype, + &similar))) + return(retval); + + if (similar) break; - } } - if (found) - continue; - if (retval = krb5_dbe_create_key_data(context, db_entry)) - goto add_key_rnd_err; - if (retval = krb5_dbe_find_enctype(context, &krbtgt_entry, - ks_tuple[i].ks_enctype, - -1, 0, &krbtgt_kdata)) - goto add_key_rnd_err; + if (similar) + continue; - /* Decrypt key */ - if (retval = krb5_dbekd_decrypt_key_data(context, master_eblock, - krbtgt_kdata,&krbtgt_key,NULL)) + if (retval = krb5_dbe_create_key_data(context, db_entry)) goto add_key_rnd_err; - /* Init key */ - krbtgt_key.enctype = ks_tuple[i].ks_enctype; - krb5_use_enctype(context, &krbtgt_eblock, ks_tuple[i].ks_enctype); - if (retval = krb5_process_key(context, &krbtgt_eblock, &krbtgt_key)) { - goto add_key_rnd_err; - } + /* there used to be code here to extract the old key, and derive + a new key from it. Now that there's a unified prng, that isn't + necessary. */ - /* Init random generator */ - if (retval = krb5_init_random_key(context, &krbtgt_eblock, - &krbtgt_key, &krbtgt_seed)) { - krb5_finish_key(context, &krbtgt_eblock); + /* make new key */ + if ((retval = krb5_c_make_random_key(context, ks_tuple[i].ks_enctype, + &key))) goto add_key_rnd_err; - } - if (retval = krb5_random_key(context,&krbtgt_eblock,krbtgt_seed,&key)) { - krb5_finish_random_key(context, &krbtgt_eblock, &krbtgt_seed); - krb5_finish_key(context, &krbtgt_eblock); - goto add_key_rnd_err; - } + retval = krb5_dbekd_encrypt_key_data(context, master_key, + &key, NULL, kvno, + &db_entry->key_data[db_entry->n_key_data-1]); - krb5_finish_random_key(context, &krbtgt_eblock, &krbtgt_seed); - krb5_finish_key(context, &krbtgt_eblock); + krb5_free_keyblock_contents(context, &key); - if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock, - key, NULL, kvno, - &db_entry->key_data[db_entry->n_key_data-1])) { - krb5_free_keyblock(context, key); + if (retval) goto add_key_rnd_err; - } - - /* Finish random key */ - krb5_free_keyblock(context, key); } -add_key_rnd_err:; +add_key_rnd_err: krb5_db_free_principal(context, &krbtgt_entry, one); - if (krbtgt_key.contents && krbtgt_key.length) { - memset(krbtgt_key.contents, 0, krbtgt_key.length); - krb5_xfree(krbtgt_key.contents); - } + return(retval); } @@ -215,9 +194,9 @@ add_key_rnd_err:; * As a side effect all old keys are nuked. */ krb5_error_code -krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) +krb5_dbe_crk(context, master_key, ks_tuple, ks_tuple_count, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; krb5_db_entry * db_entry; @@ -237,7 +216,7 @@ krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) /* increment the kvno */ kvno++; - if (retval = add_key_rnd(context, master_eblock, ks_tuple, + if (retval = add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; @@ -255,9 +234,9 @@ krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) * As a side effect all old keys older than the max kvno are nuked. */ krb5_error_code -krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) +krb5_dbe_ark(context, master_key, ks_tuple, ks_tuple_count, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; krb5_db_entry * db_entry; @@ -278,7 +257,7 @@ krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) /* increment the kvno */ kvno++; - if (retval = add_key_rnd(context, master_eblock, ks_tuple, + if (retval = add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; @@ -307,10 +286,10 @@ krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry) * If passwd is NULL the assumes that the caller wants a random password. */ static krb5_error_code -add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, +add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry, kvno) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; char * passwd; @@ -318,7 +297,6 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, int kvno; { krb5_error_code retval; - krb5_encrypt_block key_eblock; krb5_keysalt key_salt; krb5_keyblock key; krb5_data pwd; @@ -328,40 +306,30 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, retval = 0; for (i = 0; i < ks_tuple_count; i++) { - krb5_enctype new_enctype, old_enctype; + krb5_boolean similar; + + similar = 0; - switch (new_enctype = ks_tuple[i].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - new_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } /* * We could use krb5_keysalt_iterate to replace this loop, or use * krb5_keysalt_is_present for the loop below, but we want to avoid * circular library dependencies. */ - for (found = j = 0; j < i; j++) { - if (ks_tuple[j].ks_salttype == ks_tuple[i].ks_salttype) { - switch (old_enctype = ks_tuple[j].ks_enctype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - old_enctype = ENCTYPE_DES_CBC_CRC; - default: - break; - } - if (old_enctype == new_enctype) { - found = 1; - break; - } - } + for (j = 0; j < i; j++) { + if ((retval = krb5_c_enctype_compare(context, + ks_tuple[i].ks_enctype, + ks_tuple[j].ks_enctype, + &similar))) + return(retval); + + if (similar && + (ks_tuple[j].ks_salttype == ks_tuple[i].ks_salttype)) + break; } - if (found) + + if (j < i) continue; - krb5_use_enctype(context, &key_eblock, ks_tuple[i].ks_enctype); + if (retval = krb5_dbe_create_key_data(context, db_entry)) return(retval); @@ -422,8 +390,9 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, pwd.data = passwd; pwd.length = strlen(passwd); - if (retval = krb5_string_to_key(context, &key_eblock, &key, &pwd, - &key_salt.data)) { + + if ((retval = krb5_c_string_to_key(context, ks_tuple[i].ks_enctype, + &pwd, &key_salt.data, &key))) { if (key_salt.data.data) free(key_salt.data.data); return(retval); @@ -433,7 +402,7 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, key_salt.data.length = krb5_princ_realm(context, db_entry->princ)->length; - if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock, &key, + if (retval = krb5_dbekd_encrypt_key_data(context, master_key, &key, (const krb5_keysalt *)&key_salt, kvno, &db_entry->key_data[db_entry->n_key_data-1])) { if (key_salt.data.data) @@ -455,10 +424,10 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd, * As a side effect all old keys are nuked. */ krb5_error_code -krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, +krb5_dbe_cpw(context, master_key, ks_tuple, ks_tuple_count, passwd, new_kvno, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; char * passwd; @@ -483,7 +452,7 @@ krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, if (new_kvno < old_kvno+1) new_kvno = old_kvno+1; - if (retval = add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, + if (retval = add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry, new_kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; @@ -501,9 +470,9 @@ krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, * As a side effect all old keys older than the max kvno are nuked. */ krb5_error_code -krb5_dbe_apw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, db_entry) +krb5_dbe_apw(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry) krb5_context context; - krb5_encrypt_block * master_eblock; + krb5_keyblock * master_key; krb5_key_salt_tuple * ks_tuple; int ks_tuple_count; char * passwd; @@ -526,7 +495,7 @@ krb5_dbe_apw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, db_entry) /* increment the kvno */ new_kvno = old_kvno+1; - if (retval = add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, + if (retval = add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry, new_kvno)) { cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); db_entry->n_key_data = key_data_count; diff --git a/src/lib/kdb/kdb_db2.c b/src/lib/kdb/kdb_db2.c index 80c9213dd3..ab4d07e231 100644 --- a/src/lib/kdb/kdb_db2.c +++ b/src/lib/kdb/kdb_db2.c @@ -22,6 +22,32 @@ * */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #if HAVE_UNISTD_H #include <unistd.h> #endif @@ -325,9 +351,9 @@ krb5_db2_db_close_database(context) * Set/Get the master key associated with the database */ krb5_error_code -krb5_db2_db_set_mkey(context, eblock) +krb5_db2_db_set_mkey(context, key) krb5_context context; - krb5_encrypt_block *eblock; + krb5_keyblock *key; { krb5_db2_context *db_ctx; @@ -335,14 +361,14 @@ krb5_db2_db_set_mkey(context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - db_ctx->db_master_key = eblock; + db_ctx->db_master_key = key; return 0; } krb5_error_code -krb5_db2_db_get_mkey(context, eblock) +krb5_db2_db_get_mkey(context, key) krb5_context context; - krb5_encrypt_block **eblock; + krb5_keyblock **key; { krb5_db2_context *db_ctx; @@ -350,7 +376,7 @@ krb5_db2_db_get_mkey(context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - *eblock = db_ctx->db_master_key; + *key = db_ctx->db_master_key; return 0; } diff --git a/src/lib/kdb/kdb_db2.h b/src/lib/kdb/kdb_db2.h index d17fde4769..f2f01311e7 100644 --- a/src/lib/kdb/kdb_db2.h +++ b/src/lib/kdb/kdb_db2.h @@ -58,7 +58,7 @@ typedef struct _krb5_db2_context { int db_locks_held; /* Number of times locked */ int db_lock_mode; /* Last lock mode, e.g. greatest*/ krb5_boolean db_nb_locks; /* [Non]Blocking lock modes */ - krb5_encrypt_block *db_master_key; /* Master key of database */ + krb5_keyblock *db_master_key; /* Master key of database */ } krb5_db2_context; #define KRB5_DB2_MAX_RETRY 5 diff --git a/src/lib/kdb/kdb_dbm.c b/src/lib/kdb/kdb_dbm.c index 1ae241dfa0..7af32d720b 100644 --- a/src/lib/kdb/kdb_dbm.c +++ b/src/lib/kdb/kdb_dbm.c @@ -330,10 +330,10 @@ krb5_dbm_db_close_database(context) * The should really reference the db_context */ krb5_error_code -krb5_dbm_db_set_mkey(context, db_context, eblock) +krb5_dbm_db_set_mkey(context, db_context, key) krb5_context context; krb5_db_context * db_context; - krb5_encrypt_block * eblock; + krb5_keyblock * key; { krb5_db_context *db_ctx; @@ -341,15 +341,15 @@ krb5_dbm_db_set_mkey(context, db_context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - db_ctx->db_master_key = eblock; + db_ctx->db_master_key = key; return 0; } krb5_error_code -krb5_dbm_db_get_mkey(context, db_context, eblock) +krb5_dbm_db_get_mkey(context, db_context, key) krb5_context context; krb5_db_context * db_context; - krb5_encrypt_block **eblock; + krb5_keyblock **key; { krb5_db_context *db_ctx; @@ -357,7 +357,7 @@ krb5_dbm_db_get_mkey(context, db_context, eblock) return(KRB5_KDB_DBNOTINITED); db_ctx = context->db_context; - *eblock = db_ctx->db_master_key; + *key = db_ctx->db_master_key; return 0; } diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c index 209e4f3ca9..a26b7f79da 100644 --- a/src/lib/kdb/kdb_xdr.c +++ b/src/lib/kdb/kdb_xdr.c @@ -735,40 +735,27 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) } } - /* - * ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD4, ENCTYPE_DES_CBC_MD5, - * ENCTYPE_DES_CBC_RAW all use the same key. - */ - switch (ktype) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - ktype = ENCTYPE_DES_CBC_CRC; - break; - default: - break; - } - maxkvno = -1; datap = (krb5_key_data *) NULL; for (i = *start; i < dbentp->n_key_data; i++) { - krb5_enctype db_ktype; - krb5_int32 db_stype; - - switch (db_ktype = dbentp->key_data[i].key_data_type[0]) { - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - db_ktype = ENCTYPE_DES_CBC_CRC; - default: - break; - } + krb5_boolean similar; + krb5_error_code ret; + krb5_int32 db_stype; + if (dbentp->key_data[i].key_data_ver > 1) { db_stype = dbentp->key_data[i].key_data_type[1]; } else { db_stype = KRB5_KDB_SALTTYPE_NORMAL; } - if (((db_ktype == (krb5_enctype) ktype) || (ktype < 0)) && + + if (ktype >= 0) { + if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype, + dbentp->key_data[i].key_data_type[0], + &similar))) + return(ret); + } + + if (((ktype < 0) || similar) && ((db_stype == stype) || (stype < 0))) { if (kvno >= 0) { if (kvno == dbentp->key_data[i].key_data_kvno) { diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c index 9c184b5148..63a7bf7c88 100644 --- a/src/lib/kdb/keytab.c +++ b/src/lib/kdb/keytab.c @@ -89,7 +89,7 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry) krb5_enctype enctype; krb5_keytab_entry * entry; { - krb5_encrypt_block * master_key; + krb5_keyblock * master_key; krb5_error_code kerror = 0; krb5_key_data * key_data; krb5_db_entry db_entry; diff --git a/src/lib/kdb/verify_mky.c b/src/lib/kdb/verify_mky.c index 121c721488..4bab17024e 100644 --- a/src/lib/kdb/verify_mky.c +++ b/src/lib/kdb/verify_mky.c @@ -29,16 +29,13 @@ /* * Verify that the master key in *mkey matches the database entry * for mprinc. - * - * eblock points to an encrypt_block used for the realm in question. */ krb5_error_code -krb5_db_verify_master_key(context, mprinc, mkey, eblock) +krb5_db_verify_master_key(context, mprinc, mkey) krb5_context context; krb5_principal mprinc; krb5_keyblock *mkey; - krb5_encrypt_block *eblock; { krb5_error_code retval; krb5_db_entry master_entry; @@ -60,24 +57,18 @@ krb5_db_verify_master_key(context, mprinc, mkey, eblock) return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, eblock, mkey))) { - krb5_db_free_principal(context, &master_entry, nprinc); - return(retval); - } - if ((retval = krb5_dbekd_decrypt_key_data(context, eblock, + if ((retval = krb5_dbekd_decrypt_key_data(context, mkey, &master_entry.key_data[0], &tempkey, NULL))) { - (void) krb5_finish_key(context, eblock); krb5_db_free_principal(context, &master_entry, nprinc); return retval; } + if (mkey->length != tempkey.length || - memcmp((char *)mkey->contents, (char *)tempkey.contents,mkey->length)) { + memcmp((char *)mkey->contents, + (char *)tempkey.contents,mkey->length)) { retval = KRB5_KDB_BADMASTERKEY; - (void) krb5_finish_key(context, eblock); - } else - retval = krb5_finish_key(context, eblock); + } memset((char *)tempkey.contents, 0, tempkey.length); krb5_xfree(tempkey.contents); diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog index 54e185d2ec..0162fc450f 100644 --- a/src/lib/krb4/ChangeLog +++ b/src/lib/krb4/ChangeLog @@ -1,3 +1,26 @@ +Wed Aug 12 18:32:44 1998 Tom Yu <tlyu@mit.edu> + + * rd_req.c (krb_set_key): Nuke the krb5_keyblock if it's set. + (krb_set_key_krb5): New function to set a static krb5_keyblock for + decryption purposes. + (krb_clear_key_krb5): New function to clear the static + krb5_keyblock if it's set. + (krb_rd_req): Call decomp_ticket or decomp_tkt_krb5 as appropriate + to the key type. + + * decomp_tkt.c (decomp_tkt_krb5): New wrapper to call + dcmp_tkt_int. + (decomp_ticket): Transform into wrapper to call dcmp_tkt_int. + (dcmp_tkt_int): New internal function; use a krb5_keyblock to + decrypt the ticket if present; else just use plain old C_Block. + + * cr_tkt.c (krb_create_ticket): Transform into a wrapper that + calls krb_cr_tkt_int. + (krb_cr_tkt_krb5): New wrapper to call krb_cr_tkt_int. + (krb_cr_tkt_int): New internal function that potentially uses a + krb5_keyblock to encrypt the ticket, or just a C_Block if the + krb5_keyblock is not set. + Mon Aug 10 17:51:59 1998 Matthew D Hancher <mdh@mit.edu> * rd_svc_key.c (read_service_key): Don't call krb5_kt_close() if @@ -12,6 +35,14 @@ Fri Aug 7 11:04:03 1998 Tom Yu <tlyu@mit.edu> * tf_util.c (tf_init): Add call to getuid() to initialize me. +Thu Jul 30 13:13:30 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * tf_util.c (tf_init): s/,/= so getuid() actually gets called + +Sun Jul 26 17:51:24 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (LIBMAJOR): Bump libmajor + Thu Jul 9 19:35:01 1998 Matthew D Hancher <mdh@mit.edu> * tf_util.c (tf_init): Fixed a potential race condition in the opening diff --git a/src/lib/krb4/Makefile.in b/src/lib/krb4/Makefile.in index f75a6327bf..af2dca43c5 100644 --- a/src/lib/krb4/Makefile.in +++ b/src/lib/krb4/Makefile.in @@ -8,7 +8,7 @@ DEFINES=-I$(srcdir)/../../include/kerberosIV ##DOS##OBJFILE=krb4.lst LIB=krb4 -LIBMAJOR=1 +LIBMAJOR=2 LIBMINOR=0 RELDIR=krb4 diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c index 39ed53859c..a8224f879a 100644 --- a/src/lib/krb4/cr_tkt.c +++ b/src/lib/krb4/cr_tkt.c @@ -13,7 +13,7 @@ #include "krb.h" #include "prot.h" #include <string.h> - +#include <krb5.h> /* * Create ticket takes as arguments information that should be in a * ticket, and the KTEXT object in which the ticket should be @@ -69,9 +69,53 @@ * <=7 bytes null null pad to 8 byte multiple * */ +int +krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key, k5key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + short life; /* Lifetime of the ticket */ + long time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + C_Block key; /* Service's secret key */ +{ + return krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, + key, NULL); +} -int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, - session, life, time_sec, sname, sinstance, key) +int +krb_cr_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, k5key) + KTEXT tkt; /* Gets filled in by the ticket */ + unsigned char flags; /* Various Kerberos flags */ + char *pname; /* Principal's name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + long paddress; /* Net address of requesting entity */ + char *session; /* Session key inserted in ticket */ + short life; /* Lifetime of the ticket */ + long time_sec; /* Issue time and date */ + char *sname; /* Service Name */ + char *sinstance; /* Instance Name */ + krb5_keyblock *k5key; /* NULL if not present */ +{ + C_Block key; + + return krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, + key, k5key); +} + +static int +krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, + session, life, time_sec, sname, sinstance, key, k5key) KTEXT tkt; /* Gets filled in by the ticket */ unsigned char flags; /* Various Kerberos flags */ char *pname; /* Principal's name */ @@ -84,6 +128,7 @@ int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, char *sname; /* Service Name */ char *sinstance; /* Instance Name */ C_Block key; /* Service's secret key */ + krb5_keyblock *k5key; /* NULL if not present */ { Key_schedule key_s; register char *data; /* running index into ticket */ @@ -124,10 +169,43 @@ int krb_create_ticket(tkt, flags, pname, pinstance, prealm, paddress, } #ifndef NOENCRYPTION - /* Encrypt the ticket in the services key */ - key_sched(key,key_s); - pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, - (long) tkt->length,key_s,(C_Block *)key,1); + /* Encrypt the ticket in the services key */ + if (k5key != NULL) { + /* block locals */ + krb5_data in; + krb5_enc_data out; + krb5_error_code ret; + size_t enclen; + + in.length = tkt->length; + in.data = tkt->dat; + /* XXX assumes context arg is ignored */ + ret = krb5_c_encrypt_length(NULL, k5key->enctype, + (size_t)in.length, &enclen); + if (ret) + return KFAILURE; + out.ciphertext.length = enclen; + out.ciphertext.data = malloc(enclen); + if (out.ciphertext.data == NULL) + return KFAILURE; /* XXX maybe ENOMEM? */ + + /* XXX assumes context arg is ignored */ + ret = krb5_c_encrypt(NULL, k5key, KRB5_KEYUSAGE_KDC_REP_TICKET, + NULL, &in, &out); + if (ret) { + free(out.ciphertext.data); + return KFAILURE; + } else { + tkt->length = out.ciphertext.length; + memcpy(tkt->dat, out.ciphertext.data, out.ciphertext.length); + memset(out.ciphertext.data, 0, out.ciphertext.length); + free(out.ciphertext.data); + } + } else { + key_sched(key,key_s); + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, + (long) tkt->length,key_s,(C_Block *)key,1); + } #endif /* !NOENCRYPTION */ return 0; } diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c index 3c59523687..d4dfd4edcb 100644 --- a/src/lib/krb4/decomp_tkt.c +++ b/src/lib/krb4/decomp_tkt.c @@ -13,6 +13,7 @@ #include "krb.h" #include "prot.h" #include <string.h> +#include <krb5.h> #ifdef KRB_CRYPT_DEBUG extern int krb_debug; @@ -65,6 +66,57 @@ decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, * (to decrypt the ticket) */ Key_schedule key_s; /* The precomputed key schedule */ { + return + dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, + paddress, session, life, time_sec, sname, sinstance, + key, key_s, NULL); +} + +int +decomp_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, k5key) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + unsigned KRB4_32 *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned KRB4_32 *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + krb5_keyblock *k5key; /* krb5 keyblock of service */ +{ + C_Block key; /* placeholder; doesn't get used */ + Key_schedule key_s; /* placeholder; doesn't get used */ + + return + dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s, k5key); +} + +static int +dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, + life, time_sec, sname, sinstance, key, key_s, k5key) + KTEXT tkt; /* The ticket to be decoded */ + unsigned char *flags; /* Kerberos ticket flags */ + char *pname; /* Authentication name */ + char *pinstance; /* Principal's instance */ + char *prealm; /* Principal's authentication domain */ + unsigned KRB4_32 *paddress; /* Net address of entity + * requesting ticket */ + C_Block session; /* Session key inserted in ticket */ + int *life; /* Lifetime of the ticket */ + unsigned KRB4_32 *time_sec; /* Issue time and date */ + char *sname; /* Service name */ + char *sinstance; /* Service instance */ + C_Block key; /* Service's secret key + * (to decrypt the ticket) */ + Key_schedule key_s; /* The precomputed key schedule */ + krb5_keyblock *k5key; /* krb5 keyblock of service */ +{ static int tkt_swap_bytes; unsigned char *uptr; char *ptr = (char *)tkt->dat; @@ -83,8 +135,37 @@ decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session, memset(keybuf, 0, sizeof(keybuf)); /* Clear the buffer */ } #endif - pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, - (long) tkt->length,key_s,(C_Block *) key,0); + if (k5key != NULL) { + /* block locals */ + krb5_enc_data in; + krb5_data out; + krb5_error_code ret; + + in.enctype = k5key->enctype; + in.kvno = 0; + in.ciphertext.length = tkt->length; + in.ciphertext.data = tkt->dat; + out.length = tkt->length; + out.data = malloc(tkt->length); + if (out.data == NULL) + return KFAILURE; /* XXX maybe ENOMEM? */ + + /* XXX note the following assumes that context arg isn't used */ + ret = + krb5_c_decrypt(NULL, k5key, + KRB5_KEYUSAGE_KDC_REP_TICKET, NULL, &in, &out); + if (ret) { + free(out.data); + return KFAILURE; + } else { + memcpy(tkt->dat, out.data, out.length); + memset(out.data, 0, out.length); + free(out.data); + } + } else { + pcbc_encrypt((C_Block *)tkt->dat,(C_Block *)tkt->dat, + (long) tkt->length,key_s,(C_Block *) key,0); + } #endif /* ! NOENCRYPTION */ #ifdef KRB_CRYPT_DEBUG if (krb_debug) { diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c index 79564e4f37..a78aadc881 100644 --- a/src/lib/krb4/rd_req.c +++ b/src/lib/krb4/rd_req.c @@ -32,6 +32,7 @@ static int st_kvno; /* version number for this key */ static char st_rlm[REALM_SZ]; /* server's realm */ static char st_nam[ANAME_SZ]; /* service name */ static char st_inst[INST_SZ]; /* server's instance */ +static int krb5_key; /* whether krb5 key is used for decrypt */ /* * This file contains two functions. krb_set_key() takes a DES @@ -62,11 +63,18 @@ static char st_inst[INST_SZ]; /* server's instance */ * krb_rd_req(). */ +#include <krb5.h> +static krb5_keyblock srv_k5key; + int krb_set_key(key,cvt) char *key; int cvt; { + if (krb5_key) + /* XXX assumes that context arg is ignored */ + krb5_free_keyblock_contents(NULL, &srv_k5key); + krb5_key = 0; #ifdef NOENCRYPTION memset(ky, 0, sizeof(ky)); return KSUCCESS; @@ -79,6 +87,25 @@ krb_set_key(key,cvt) #endif /* NOENCRYPTION */ } +int +krb_set_key_krb5(ctx, key) + krb5_context ctx; + krb5_keyblock *key; +{ + if (krb5_key) + krb5_free_keyblock_contents(ctx, &srv_k5key); + krb5_key = 1; + return krb5_copy_keyblock_contents(ctx, key, &srv_k5key); +} + +void +krb_clear_key_krb5(ctx) + krb5_context ctx; +{ + if (krb5_key) + krb5_free_keyblock_contents(ctx, &srv_k5key); + krb5_key = 0; +} /* * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or @@ -234,15 +261,25 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) /* Decrypt and take apart ticket */ #endif - if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, - &(ad->address),ad->session, &(ad->life), - &(ad->time_sec),sname,iname,ky,serv_key)) { + if (!krb5_key) { + if (decomp_ticket(tkt,&ad->k_flags,ad->pname,ad->pinst,ad->prealm, + &(ad->address),ad->session, &(ad->life), + &(ad->time_sec),sname,iname,ky,serv_key)) { #ifdef KRB_CRYPT_DEBUG - log("Can't decode ticket"); + log("Can't decode ticket"); #endif - return(RD_AP_UNDEC); + return(RD_AP_UNDEC); + } + } else { + if (decomp_tkt_krb5(tkt, &ad->k_flags, ad->pname, ad->pinst, + ad->prealm, &ad->address, ad->session, + &ad->life, &ad->time_sec, sname, iname, + srv_k5key)) { + return RD_AP_UNDEC; + } } + #ifdef KRB_CRYPT_DEBUG if (krb_ap_req_debug) { log("Ticket Contents."); diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c index b3eb0b43a9..1c7aadd9fa 100644 --- a/src/lib/krb4/tf_util.c +++ b/src/lib/krb4/tf_util.c @@ -182,7 +182,7 @@ int tf_init(tf_name, rw) int rw; { int wflag; - uid_t me, getuid(); + uid_t me= getuid(); struct stat stat_buf, stat_buffd; #ifdef TKT_SHMEM char shmidname[MAXPATHLEN]; diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog index f7922150e9..f1e1e81f93 100644 --- a/src/lib/krb5/ChangeLog +++ b/src/lib/krb5/ChangeLog @@ -1,3 +1,11 @@ +Thu Jul 30 13:12:57 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * configure.in: Test for sa_len so localaddr works on NetBSD. + +Sun Jul 26 17:46:47 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (LIBMAJOR): bump to 2 + Wed Apr 15 18:07:20 1998 Tom Yu <tlyu@mit.edu> * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in index 4864a2f94f..12ce18512b 100644 --- a/src/lib/krb5/Makefile.in +++ b/src/lib/krb5/Makefile.in @@ -28,8 +28,8 @@ LIBDONE= error_tables/DONE asn.1/DONE ccache/DONE ccache/stdio/DONE \ #SHLIB_LIBDIRS= @SHLIB_LIBDIRS@ LIB=krb5 -LIBMAJOR=1 -LIBMINOR=2 +LIBMAJOR=2 +LIBMINOR=1 STOBJLISTS= \ error_tables/OBJS.ST \ diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog index a42ad235c3..ca3f679f50 100644 --- a/src/lib/krb5/asn.1/ChangeLog +++ b/src/lib/krb5/asn.1/ChangeLog @@ -1,3 +1,10 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * asn1buf.c (asn1buf_sync): interoperation testing against heimdal + revealed a bug. if extra fields are present in a SEQUENCE, they + are not ignored and skipped. This caused the decoder to get out + of sync. + Thu Jul 2 15:30:25 1998 Theodore Y. Ts'o <tytso@mit.edu> * asn1_encode.c: Make the magic Macintosh EPOCH offset be 70 years diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c index 30dad8b491..52ac387d50 100644 --- a/src/lib/krb5/asn.1/asn1buf.c +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -93,7 +93,7 @@ void asn1buf_sync(buf, subbuf) asn1buf * buf; asn1buf * subbuf; { - buf->next = subbuf->next; + buf->next = subbuf->bound + 1; } asn1_error_code asn1buf_destroy(buf) diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog index 2a4d39551d..71aa06dc82 100644 --- a/src/lib/krb5/ccache/ChangeLog +++ b/src/lib/krb5/ccache/ChangeLog @@ -7,6 +7,10 @@ Fri Aug 20 18:30:00 1998 Miro Jurisic <meeroh@mit.edu> * Added Frank's CCache API cache implementation and made it default on the Mac +Thu Jul 30 13:12:30 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * ccbase.c: Enable memory ccache (merge adapted from Kerbnet) + 1998-05-27 Theodore Ts'o <tytso@rsts-11.mit.edu> * Makefile.in: Add ccache/memory as a directory to be recursively diff --git a/src/lib/krb5/ccache/ccapi/Makefile.in b/src/lib/krb5/ccache/ccapi/Makefile.in deleted file mode 100644 index e47ded4432..0000000000 --- a/src/lib/krb5/ccache/ccapi/Makefile.in +++ /dev/null @@ -1,21 +0,0 @@ -thisconfigdir=./../.. -BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)$(S)$(U) -CFLAGS = $(CCOPTS) $(DEFS) - -##DOS##BUILDTOP = ..\..\..\.. -##DOS##PREFIXDIR = ccache\file -##DOS##OBJFILE = file.lst -##WIN16##LIBNAME=..\..\krb5.lib - -STLIBOBJS = \ - stdcc.o \ - stdcc_util.o - -OBJS = stdcc.${OBJEXT} stdcc_util.${OBJEXT} - -SRCS = $(srcdir)/stdcc.c $(srcdir)/stdcc_util.c - -##DOS##LIBOBJS = $(OBJS) - -all-unix:: all-libobjs -clean-unix:: clean-libobjs diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c deleted file mode 100644 index 2b9007bf81..0000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc.c +++ /dev/null @@ -1,394 +0,0 @@ -/********************************************************** - * - * stdcc.c - additions to the Kerberos 5 library to support the memory credentical cache API - * - * Revision 1.1.1.1 - Frank Dabek July 1998 - * - **********************************************************/ - -#include "stdcc.h" -#include "string.h" - -//declare our global object wanna-be -//must be installed in ccdefops.c -krb5_cc_ops krb5_cc_stdcc_ops = { - 0, - "API", - krb5_stdcc_get_name, - krb5_stdcc_resolve, - krb5_stdcc_generate_new, - krb5_stdcc_initialize, - krb5_stdcc_destroy, - krb5_stdcc_close, - krb5_stdcc_store, - krb5_stdcc_retrieve, - krb5_stdcc_get_principal, - krb5_stdcc_start_seq_get, - krb5_stdcc_next_cred, - krb5_stdcc_end_seq_get, - krb5_stdcc_remove, - krb5_stdcc_set_flags, -}; - -// -- generate_new -------------------------------- -// - create a new cache with a unique name, corresponds to creating a named cache -// - iniitialize the API here if we have to. -krb5_error_code krb5_stdcc_generate_new - (krb5_context context, krb5_ccache *id ) - - { - - krb5_ccache newCache; - char name[kStringLiteralLen]; - cc_time_t time; - int err; - - //make sure the API has been intialized - if (gCntrlBlock == NULL) { - err = cc_initialize(&gCntrlBlock, CC_API_VER_1, NULL, NULL); - if (err != CC_NOERROR) return err; - } - - //allocate the cache structure - newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); - if (newCache == NULL) return KRB5_CC_NOMEM; - - //create a unique name - cc_get_change_time(gCntrlBlock, &time); - sprintf(name, "gen_new_cache%d", time); - - //create the new cache - err = cc_create(gCntrlBlock, name, CC_CRED_V5, - name, 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache) ); - if (err != CC_NOERROR) return err; - - //setup some fields - newCache->ops = &krb5_cc_stdcc_ops; - newCache->data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData)); - - //return a pointer to the new cache - *id = newCache; - - return CC_NOERROR; - } - -// -- resolve ------------------------------ -// -// - create a new cache with the name stored in residual -krb5_error_code krb5_stdcc_resolve - (krb5_context context, krb5_ccache *id , const char *residual ) { - - krb5_ccache newCache; - int err,pos; - char *cName; - - //make sure the API has been intialized - if (gCntrlBlock == NULL) { - err = cc_initialize(&gCntrlBlock, CC_API_VER_1, NULL, NULL); - if (err != CC_NOERROR) return err; - } - - newCache = (krb5_ccache) malloc(sizeof(struct _krb5_ccache)); - if (newCache == NULL) return KRB5_CC_NOMEM; - - newCache->ops = &krb5_cc_stdcc_ops; - newCache->data = (stdccCacheDataPtr)malloc(sizeof(stdccCacheData)); - if (newCache->data == NULL) return KRB5_CC_NOMEM; - - cName = residual; - //attempt to find a cache by the same name before creating it - err = cc_open(gCntrlBlock, cName, CC_CRED_V5, 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache)); - //we didn't find it.. create it. - if (err) { - err = cc_create(gCntrlBlock, cName, CC_CRED_V5, cName, - 0L, &(((stdccCacheDataPtr)(newCache->data))->NamedCache) ); - if (err != CC_NOERROR) return err; //still an error, return it - } - - //return new cache structure - *id = newCache; - return CC_NOERROR; - } - - // -- initialize -------------------------------- - //-initialize the cache, check to see if one already exists for this principal - // if not set our principal to this principal. This searching enables ticket sharing - krb5_error_code krb5_stdcc_initialize - (krb5_context context, krb5_ccache id, krb5_principal princ) - - { - - int err, err1, found; - //char cName[kStringLiteralLen]; - char *cName = nil; - ccache_p *testNC = NULL; - ccache_it *it; - char *p = NULL, *targetName = NULL; - - //test id for null - if (id == NULL) return KRB5_CC_NOMEM; - - //test for initialized API - if (gCntrlBlock == NULL) - return CC_NO_EXIST; - - //create a principal name for the named cache - err = krb5_unparse_name(context, princ, &cName); - if (err) - return(err); - - //sprintf(cName, "%s@%s", krb5_princ_name(context, princ)->data, krb5_princ_realm(context, princ)->data); - - //look for a cache already extant for this principal - it = NULL; - found = err = 0; - while ((err != CC_END) && (!found)) { - err = cc_seq_fetch_NCs(gCntrlBlock, &testNC, &it); - if (err == CC_NOERROR) { - cc_get_principal(gCntrlBlock, testNC, &p); - if (strcmp(p, cName) == 0) { - found = 1; - cc_get_name(gCntrlBlock, testNC, &targetName); - } - cc_free_principal(gCntrlBlock, p); - err1 = cc_close(gCntrlBlock, &testNC); - } - } - - if (!found) - //we didn't find one with the name we were looking for, use the one we had and change the name - cc_set_principal(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), CC_CRED_V5, cName); - else { - //we found a cache for this guy, lets trash ours and use that one - let's not; sgm 10/7/98 - //cc_destroy(gCntrlBlock, &(((stdccCacheDataPtr)(id->data))->NamedCache)); - err = cc_open(gCntrlBlock, targetName, CC_CRED_V5, 0L, &(((stdccCacheDataPtr)(id->data))->NamedCache)); - if (err != CC_NOERROR) return err; //error opening - cc_free_name(gCntrlBlock, targetName); - } - - free(cName); - - return CC_NOERROR; - - } - - -// -- store ---------------------------------- -// - store some credentials in our cache - krb5_error_code krb5_stdcc_store - (krb5_context context, krb5_ccache id , krb5_creds *creds ) { - - cred_union *cu = NULL; - int err; - - - //copy the fields from the almost identical structures - dupK52cc(context, creds, &cu); - - //finally store the credential - //store will copy (that is duplicate) everything - err = cc_store(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache, *cu); - if (err != CC_NOERROR) return err; - - //free the cred union - err = cc_free_creds(gCntrlBlock, &cu); - - return err; -} - - -// -- start_seq_get -------------------------- -// - begin an iterator call to get all of the credentials in the cache -krb5_error_code krb5_stdcc_start_seq_get -(krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) { - - //all we have to do is initialize the cursor - *cursor = NULL; - return CC_NOERROR; -} - -// -- next cred --------------------------- -// - get the next credential in the cache as part of an iterator call -// - this maps to call to cc_seq_fetch_creds -krb5_error_code krb5_stdcc_next_cred - (krb5_context context, - krb5_ccache id , - krb5_cc_cursor *cursor , - krb5_creds *creds ) { - - int err; - cred_union *credU = NULL; - cc_creds *c = NULL; - - err = cc_seq_fetch_creds(gCntrlBlock, ((stdccCacheDataPtr)(id->data))->NamedCache, - &credU, (ccache_it **)cursor); - - if (err != CC_NOERROR) - return err; - - //copy data (with translation) - dupCCtoK5(context, credU->cred.pV5Cred, creds); - - //free our version of the cred - cc_free_creds(gCntrlBlock, &credU); - - return CC_NOERROR; - -} - - -// -- retreive ------------------- -// - try to find a matching credential in the cache -krb5_error_code krb5_stdcc_retrieve - (krb5_context context, - krb5_ccache id, - krb5_flags whichfields, - krb5_creds *mcreds, - krb5_creds *creds ) { - - krb5_cc_cursor curs = NULL; - krb5_creds *fetchcreds; - - fetchcreds = (krb5_creds *)malloc(sizeof(krb5_creds)); - if (fetchcreds == NULL) return KRB5_CC_NOMEM; - - //we're going to use the iterators - krb5_stdcc_start_seq_get(context, id, &curs); - - while (krb5_stdcc_next_cred(context, id, &curs, fetchcreds) == CC_NOERROR) { - //look at each credential for a match - //use this match routine since it takes the whichfields and the API doesn't - if (stdccCredsMatch(context, fetchcreds, mcreds, whichfields)) { - //we found it, copy and exit - *creds = *fetchcreds; - krb5_stdcc_end_seq_get(context, id, &curs); - return CC_NOERROR; - } - //free copy allocated by next_cred - krb5_free_cred_contents(context, fetchcreds); - } - - //no luck, end get and exti - krb5_stdcc_end_seq_get(context, id, &curs); - - return KRB5_CC_NOTFOUND; -} - -// -- end seq ------------------------ -// - just free up the storage assoicated with the cursor (if we could) - krb5_error_code krb5_stdcc_end_seq_get - (krb5_context context, krb5_ccache id , krb5_cc_cursor *cursor ) { - - //the limitation of the Ccache api and the seq calls - //causes trouble. cursor might have already been freed - //and anyways it is in the mac's heap so we need FreePtr - //but all i have is free - // FreePtr(*cursor); - - //LEAK IT! - *cursor = NULL; - } - -// -- close --------------------------- -// - free our pointers to the NC -krb5_error_code -krb5_stdcc_close(context, id, princ) - krb5_context context; - krb5_ccache id; - krb5_principal princ; -{ - - //free it - free((stdccCacheDataPtr)(id->data)); - //null it out - (stdccCacheDataPtr)(id->data) = NULL; - - return CC_NOERROR; -} - -// -- destroy ------------- -// - free our storage and the cache -krb5_error_code -krb5_stdcc_destroy (krb5_context context, krb5_ccache id ) { - - int err; - - //destroy the named cache - err = cc_destroy(gCntrlBlock, &(((stdccCacheDataPtr)(id->data))->NamedCache)); - //free the pointer to the record that held the pointer to the cache - free((stdccCacheDataPtr)(id->data)); - //null it out - (stdccCacheDataPtr)(id->data) = NULL; - - return err; -} - - -// -- getname --------------------------- -// - return the name of the named cache -char * krb5_stdcc_get_name - (krb5_context context, krb5_ccache id ) { - - char *ret = NULL; - int err; - - //just a wrapper - err = cc_get_name(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), &ret); - - if (err != CC_NOERROR) - return ret; - else - return NULL; - -} - -// -- get_principal --------------------------- -// - return the principal associated with the named cache -krb5_error_code -krb5_stdcc_get_principal (krb5_context context, krb5_ccache id , krb5_principal *princ ) { - - int err; - char *name = NULL; - - //another wrapper - err = cc_get_principal(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), &name); - - if (err != CC_NOERROR) - return err; - - //turn it into a krb principal - err = krb5_parse_name(context, name, princ); - - return err; -} - -// -- set_flags --------------------------- -// - currently a NOP since we don't store any flags in the NC -krb5_error_code krb5_stdcc_set_flags - (krb5_context context, krb5_ccache id , krb5_flags flags ) { - - return CC_NOERROR; -} - -// - remove --------------------------- -// - remove the specified credentials from the NC -krb5_error_code krb5_stdcc_remove - (krb5_context context, krb5_ccache id , krb5_flags flags, krb5_creds *creds ) { - - cred_union *cu = NULL; - int err; - - //convert to a cred union - dupK52cc(context, creds, &cu); - - //remove it - err = cc_remove_cred(gCntrlBlock, (((stdccCacheDataPtr)(id->data))->NamedCache), *cu); - if (err != CC_NOERROR) return err; - - //free the temp cred union - err = cc_free_creds(gCntrlBlock, &cu); - if (err != CC_NOERROR) return err; - - return CC_NOERROR; - } -
\ No newline at end of file diff --git a/src/lib/krb5/ccache/ccapi/stdcc.h b/src/lib/krb5/ccache/ccapi/stdcc.h deleted file mode 100644 index c157770c49..0000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc.h +++ /dev/null @@ -1,73 +0,0 @@ -//#include "k5-int.h" -#include "krb5.h" - -#if defined(macintosh) -#include "CCache.h" -#endif - -#if defined(_MSDOS) || defined(_WIN32) -#include "cacheapi.h" -#endif - -#define kStringLiteralLen 255 - -//globals to be exported -extern krb5_cc_ops krb5_cc_stdcc_ops; - -//structure to stash in the cache's data field -//only holds another pointer to the actual cache right now -typedef struct _stdccCacheData { - ccache_p *NamedCache; -} stdccCacheData, *stdccCacheDataPtr; - - -//function protoypes complete with bogus windowsesque macros.. - -KRB5_DLLIMP krb5_error_code krb5_stdcc_close - KRB5_PROTOTYPE((krb5_context, krb5_ccache id )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_destroy - KRB5_PROTOTYPE((krb5_context, krb5_ccache id )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_end_seq_get - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_cc_cursor *cursor )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_generate_new - KRB5_PROTOTYPE((krb5_context, krb5_ccache *id )); - -KRB5_DLLIMP char * krb5_stdcc_get_name - KRB5_PROTOTYPE((krb5_context, krb5_ccache id )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_get_principal - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_principal *princ )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_initialize - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_principal princ )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_next_cred - KRB5_PROTOTYPE((krb5_context, - krb5_ccache id , - krb5_cc_cursor *cursor , - krb5_creds *creds )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_resolve - KRB5_PROTOTYPE((krb5_context, krb5_ccache *id , const char *residual )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_retrieve - KRB5_PROTOTYPE((krb5_context, - krb5_ccache id , - krb5_flags whichfields , - krb5_creds *mcreds , - krb5_creds *creds )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_start_seq_get - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_cc_cursor *cursor )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_store - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_creds *creds )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_set_flags - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_flags flags )); - -KRB5_DLLIMP krb5_error_code krb5_stdcc_remove - KRB5_PROTOTYPE((krb5_context, krb5_ccache id , krb5_flags flags, krb5_creds *creds)); diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c deleted file mode 100644 index 4f4fcfc50a..0000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.c +++ /dev/null @@ -1,368 +0,0 @@ -// stdcc_util.c -// utility functions used in implementing the ccache api for krb5 -// not publicly exported -// Frank Dabek, July 1998 - -#include <stdlib.h> -#include <string.h> -#include "stdcc_util.h" -#include "krb5.h" -#include "kv5m_err.h" - -#define fieldSize 255 - -/* on the Mac, we need the calls which allocate memory for the Credentials Cache to use - Ptr's in the system help, so that they stay global and so that bad things don't happen - when we call DisposePtr() on them. However, on other systems, malloc is probably the - right thing to use. - So for any place where we allocate memory for the Credentials Cache, use sys_alloc() and - define it accordingly. -*/ - -#if defined(macintosh) -#define sys_alloc(size) NewSafePtrSys(size) -#else -#define sys_alloc(size) malloc(size) -#endif - -#if defined(macintosh) -//stolen from CCacheUtils.c -// -- NewSafePtrSys ----------------- -// - analagous to NewSafePtr but memory is allocated in the system heap -Ptr NewSafePtrSys(long size) { - - Ptr retPtr; - - retPtr = NewPtrSys(size); - - if (retPtr != NULL) - HoldMemory(retPtr, size); - - return retPtr; -} -#endif - -// CopyCCDataArrayToK5 -// - copy and translate the null terminated arrays of data records -// used in k5 tickets -int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray) { - - cc_data *ccAdr, **cbase; - krb5_address *kAdr, **kbase, **constKBase; - int numRecords = 0; - - - if (whichArray == kAddressArray) { - //check pointer - if (cc->addresses == NULL) { - kc->addresses = NULL; - return 0; } - } else if (whichArray == kAuthDataArray) { - //check pointer - if (cc->authdata == NULL) { - kc->authdata = NULL; - return 0; } - } else return -1; - - - cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata; - //calc number of records - while (*cbase++ != NULL) numRecords++; - //allocate new array - constKBase = kbase = (krb5_address **)malloc((numRecords+1)*sizeof(char *)); - //reset base - cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata; - - - //copy records - while (*cbase != NULL) { - *kbase = (krb5_address *)malloc(sizeof(krb5_address)); - kAdr = *kbase; - ccAdr = *cbase; - kAdr->magic = (whichArray == kAddressArray) ? KV5M_ADDRESS : KV5M_AUTHDATA; - kAdr->addrtype = ccAdr->type; - kAdr->length = ccAdr->length; - kAdr->contents = (krb5_octet *)malloc(kAdr->length); - memcpy(kAdr->contents, ccAdr->data, kAdr->length); - //next element please - kbase++; cbase++; - } - - //write terminator - *kbase = NULL; - if (whichArray == kAddressArray) kc->addresses = constKBase; - else kc->authdata = (krb5_authdata **)constKBase; - - return 0; -} - -// copyK5DataArrayToCC -// - analagous to above, but in the other direction -int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray) { - - cc_data *ccAdr, **cbase, **constCBase; - krb5_address *kAdr, **kbase; - int numRecords = 0; - - - if (whichArray == kAddressArray) { - //check pointer - if (kc->addresses == NULL) { - cc->addresses = NULL; - return 0; } - } else if (whichArray == kAuthDataArray) { - //check pointer - if (kc->authdata == NULL) { - cc->authdata = NULL; - return 0; } - } else return -1; - - - kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata; - //calc number of records - while (*kbase++ != NULL) numRecords++; - //allocate new array - constCBase = cbase = (cc_data **)sys_alloc((numRecords+1)*sizeof(char *)); - //reset base - kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata; - - - //copy records - while (*kbase != NULL) { - *cbase = (cc_data *)sys_alloc(sizeof(krb5_address)); - kAdr = *kbase; - ccAdr = *cbase; - ccAdr->type = kAdr->addrtype; - ccAdr->length = kAdr->length; - ccAdr->data = (unsigned char *)sys_alloc(ccAdr->length); - memcpy(ccAdr->data, kAdr->contents, kAdr->length); - //next element please - kbase++; cbase++; - } - - //write terminator - *cbase = NULL; - if (whichArray == kAddressArray) cc->addresses = (cc_data **)constCBase; - else cc->authdata = (cc_data **)constCBase; - - return 0; -} - - -// dupcctok5 -// - allocate an empty k5 style ticket and copy info from the cc_creds ticket -void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) { - - int err; - - //allocate and copy - //copy all of those damn fields back - err = krb5_parse_name(context, src->client, &(dest->client)); - err = krb5_parse_name(context, src->server, &(dest->server)); - if (err) return; //parsename fails w/o krb5.ini for example - - //copy keyblock - dest->keyblock.enctype = src->keyblock.type; - dest->keyblock.length = src->keyblock.length; - dest->keyblock.contents = (krb5_octet *)malloc(dest->keyblock.length); - memcpy(dest->keyblock.contents, src->keyblock.data, dest->keyblock.length); - - //copy times - dest->times.authtime = src->authtime; - dest->times.starttime = src->starttime; - dest->times.endtime = src->endtime; - dest->times.renew_till = src->renew_till; - dest->is_skey = src->is_skey; - dest->ticket_flags = src->ticket_flags; - - //more branching fields - copyCCDataArrayToK5(src, dest, kAddressArray); - dest->ticket.length = src->ticket.length; - dest->ticket.data = (char *)malloc(src->ticket.length); - memcpy(dest->ticket.data, src->ticket.data, src->ticket.length); - dest->second_ticket.length = src->second_ticket.length; - (dest->second_ticket).data = ( char *)malloc(src->second_ticket.length); - memcpy(dest->second_ticket.data, src->second_ticket.data, src->second_ticket.length); - - //zero out magic number - dest->magic = 0; - //later - //copyCCDataArrayToK5(src, dest, kAuthDataArray); - //krb5 docs say that authdata can be nulled out if we - //only want default behavior - dest->authdata = NULL; - - return; -} - -// dupK52CC -// - analagous to above but in the reverse direction -void dupK52cc(krb5_context context, krb5_creds *creds, cred_union **cu) { - - krb5_address **tA; - krb5_authdata **tAd; - cc_creds *c; - int err; - #ifdef macintosh - char *tempname = NULL; - #endif - - if (cu == NULL) return; - - //allocate the cred_union - *cu = (cred_union *)sys_alloc(sizeof(cred_union)); - if ((*cu) == NULL) return; - (*cu)->cred_type = CC_CRED_V5; - - //allocate creds structure (and install) - c = (cc_creds *)sys_alloc(sizeof(cc_creds)); - if (c == NULL) return; - (*cu)->cred.pV5Cred = c; - - //convert krb5 principals to flat principals - #ifdef macintosh - //and make sure the memory for c->client and c->server is on the system heap with NewPtr - //for the Mac (krb5_unparse_name puts it in appl heap with malloc) - err = krb5_unparse_name(context, creds->client, &tempname); - c->client = sys_alloc(strlen(tempname)); - if (c->client != NULL) - strcpy(c->client,tempname); - free(tempname); - tempname = NULL; - - err = krb5_unparse_name(context, creds->server, &tempname); - c->server = sys_alloc(strlen(tempname)); - if (c->server != NULL) - strcpy(c->server,tempname); - free(tempname); - #else - err = krb5_unparse_name(context, creds->client, &(c->client)); - err = krb5_unparse_name(context, creds->server, &(c->server)); - #endif - if (err) return; - - //copy more fields - c->keyblock.type = creds->keyblock.enctype; - c->keyblock.length = creds->keyblock.length; - - if (creds->keyblock.contents != NULL) { - c->keyblock.data = (unsigned char *)sys_alloc(creds->keyblock.length); - memcpy(c->keyblock.data, creds->keyblock.contents, creds->keyblock.length); - } else { - c->keyblock.data = NULL; - } - - c->authtime = creds->times.authtime; - c->starttime = creds->times.starttime; - c->endtime = creds->times.endtime; - c->renew_till = creds->times.renew_till; - c->is_skey = creds->is_skey; - c->ticket_flags = creds->ticket_flags; - - copyK5DataArrayToCC(creds, c, kAddressArray); - - c->ticket.length = creds->ticket.length; - if (creds->ticket.data != NULL) { - c->ticket.data = (unsigned char *)sys_alloc(creds->ticket.length); - memcpy(c->ticket.data, creds->ticket.data, creds->ticket.length); - } else { - c->ticket.data = NULL; - } - - c->second_ticket.length = creds->second_ticket.length; - if (creds->second_ticket.data != NULL) { - c->second_ticket.data = (unsigned char *)sys_alloc(creds->second_ticket.length); - memcpy(c->second_ticket.data, creds->second_ticket.data, creds->second_ticket.length); - } else { - c->second_ticket.data = NULL; - } - - c->authdata = NULL; - - return; -} - - -// bitTst -// - utility function for below function -int bitTst(int var, int mask) { - - return var & mask; -} - -// stdccCredsMatch -// - check to see if the creds match based on the whichFields variable -// NOTE: if whichfields is zero we are now comparing 'standard fields.' -// This is the bug that was killing fetch for a week. The behaviour -// is what krb5 expects, however. -int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields) { - - krb5_ticket_times b, m; - krb5_authdata **bp, **mp; - krb5_boolean retval; - krb5_principal_data p1, p2; - - - //always check the standard fields - if ((krb5_principal_compare(context, base->client, match->client) && - krb5_principal_compare(context, base->server, match->server)) == false) - return FALSE; - - if (bitTst(whichfields, KRB5_TC_MATCH_TIMES)) { - //test for matching times - //according to the file cache implementation we do: - if (match->times.renew_till) { - if (match->times.renew_till > base->times.renew_till) - return FALSE; /* this one expires too late */ - } - if (match->times.endtime) { - if (match->times.endtime > base->times.endtime) - return FALSE; /* this one expires too late */ - } - } //continue search - - if (bitTst(whichfields, KRB5_TC_MATCH_IS_SKEY)) - if (base->is_skey != match->is_skey) return false; - - if (bitTst(whichfields, KRB5_TC_MATCH_FLAGS)) - if (base->ticket_flags != match->ticket_flags) return false; - - if (bitTst(whichfields, KRB5_TC_MATCH_TIMES_EXACT)) { - b = base->times; m = match->times; - if ((b.authtime != m.authtime) || - (b.starttime != m.starttime) || - (b.endtime != m.endtime) || - (b.renew_till != m.renew_till)) return false; - } - - if (bitTst(whichfields, KRB5_TC_MATCH_AUTHDATA)) { - bp = base->authdata; - mp = match->authdata; - if ((bp != NULL) && (mp != NULL)) { - while ( (bp) && (*bp != NULL) ){ - if (( (*bp)->ad_type != (*mp)->ad_type) || - ( (*bp)->length != (*mp)->length) || - ( memcmp( (*bp)->contents, (*mp)->contents, (*bp)->length) != 0)) return false; - mp++; bp++; - } - } - } - - if (bitTst(whichfields, KRB5_TC_MATCH_SRV_NAMEONLY)) { - //taken from cc_retrv.c - retval = krb5_principal_compare(context, base->client,match->client); - if (!retval) return false; - - } - - if (bitTst(whichfields, KRB5_TC_MATCH_2ND_TKT)) - if ( (base->second_ticket.length != match->second_ticket.length) || - (memcmp(base->second_ticket.data, match->second_ticket.data, base->second_ticket.length) != 0)) - return false; - - if (bitTst(whichfields, KRB5_TC_MATCH_KTYPE)) - if (base->keyblock.enctype != match->keyblock.enctype) return false; - - //if we fall through to here, they must match - return true; -} diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h deleted file mode 100644 index 7d0af3dcb4..0000000000 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.h +++ /dev/null @@ -1,25 +0,0 @@ -//stdcc_util.h -// -// Frank Dabek, July 1998 - -#if defined(macintosh) -#include "CCache.h" -#endif - -#if defined(_MSDOS) || defined(_WIN32) -#include "cacheapi.h" -#endif - -#include "krb5.h" - -//protoypes for private functions declared in stdcc_util.c -int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray); -int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray); -void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest); -void dupK52cc(krb5_context context, krb5_creds *creds, cred_union **cu); -int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields); -int bitTst(int var, int mask); -void typeK52cc(krb5_context context, krb5_creds *creds, cc_creds *c, char **client, char **server); -#define kAddressArray 4 -#define kAuthDataArray 5 - diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c index 4570f8053c..ae89334a0f 100644 --- a/src/lib/krb5/ccache/ccbase.c +++ b/src/lib/krb5/ccache/ccbase.c @@ -31,7 +31,11 @@ struct krb5_cc_typelist krb5_cc_ops *ops; struct krb5_cc_typelist *next; }; -static struct krb5_cc_typelist *cc_typehead = 0; +extern krb5_cc_ops krb5_mcc_ops; + +static struct krb5_cc_typelist cc_entry = { &krb5_mcc_ops, NULL }; + +static struct krb5_cc_typelist *cc_typehead = &cc_entry; /* * Register a new credentials cache type diff --git a/src/lib/krb5/configure.in b/src/lib/krb5/configure.in index 1f924319a5..b42fbf0cee 100644 --- a/src/lib/krb5/configure.in +++ b/src/lib/krb5/configure.in @@ -12,6 +12,7 @@ AC_CHECK_FUNCS(flock fchmod chmod strftime strptime geteuid setenv unsetenv gete AC_REPLACE_FUNCS(vfprintf vsprintf strdup strcasecmp strerror memmove daemon getuid sscanf syslog) KRB5_AC_REGEX_FUNCS dnl +KRB5_SOCKADDR_SA_LEN KRB5_BUILD_LIBRARY_WITH_DEPS KRB5_BUILD_LIBOBJS KRB5_BUILD_PROGRAM diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et index d8f8533c8b..b483116e1d 100644 --- a/src/lib/krb5/error_tables/krb5_err.et +++ b/src/lib/krb5/error_tables/krb5_err.et @@ -315,4 +315,6 @@ error_code KRB5_CHPW_PWDNULL, "New password cannot be zero length" error_code KRB5_CHPW_FAIL, "Password change failed" error_code KRB5_KT_FORMAT, "Bad format in keytab" +error_code KRB5_NOPERM_ETYPE, "Encryption type not permitted" + end diff --git a/src/lib/krb5/keytab/file/ChangeLog b/src/lib/krb5/keytab/file/ChangeLog index 2120127db1..4e575b6519 100644 --- a/src/lib/krb5/keytab/file/ChangeLog +++ b/src/lib/krb5/keytab/file/ChangeLog @@ -1,3 +1,8 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * ktf_g_ent.c (krb5_ktfile_get_entry): restructure the code to use + the compare_enctypes function and not leak memory + Fri Feb 27 18:03:33 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> * Makefile.in: Changed thisconfigdir to point at the lib/krb5 diff --git a/src/lib/krb5/keytab/file/ktf_g_ent.c b/src/lib/krb5/keytab/file/ktf_g_ent.c index 7122cb41d5..57d6edabd6 100644 --- a/src/lib/krb5/keytab/file/ktf_g_ent.c +++ b/src/lib/krb5/keytab/file/ktf_g_ent.c @@ -41,6 +41,7 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry) krb5_keytab_entry cur_entry, new_entry; krb5_error_code kerror = 0; int found_wrong_kvno = 0; + krb5_boolean similar; /* Open the keyfile for reading */ if ((kerror = krb5_ktfileint_openr(context, id))) @@ -53,53 +54,69 @@ krb5_ktfile_get_entry(context, id, principal, kvno, enctype, entry) cur_entry.principal = 0; cur_entry.vno = 0; cur_entry.key.contents = 0; + while (TRUE) { - krb5_enctype entry_type; - if ((kerror = krb5_ktfileint_read_entry(context, id, &new_entry))) break; - switch (enctype) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_RAW: - enctype = ENCTYPE_DES_CBC_CRC; - break; + /* by the time this loop exits, it must either free cur_entry, + and copy new_entry there, or free new_entry. Otherwise, it + leaks. */ + + /* if the enctype is not ignored and doesn't match, free new_entry + and continue to the next */ + + if (enctype != IGNORE_ENCTYPE) { + if ((kerror = krb5_c_enctype_compare(context, enctype, + new_entry.key.enctype, + &similar))) { + krb5_kt_free_entry(context, &new_entry); + break; + } + + if (!similar) { + krb5_kt_free_entry(context, &new_entry); + continue; + } } - entry_type = new_entry.key.enctype; - switch(entry_type) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_RAW: - entry_type = ENCTYPE_DES_CBC_CRC; - break; + /* if the principal isn't the one requested, free new_entry + and continue to the next. */ + + if (!krb5_principal_compare(context, principal, new_entry.principal)) { + krb5_kt_free_entry(context, &new_entry); + continue; } - if (((enctype == IGNORE_ENCTYPE)|| - (entry_type == enctype))&& - krb5_principal_compare(context, principal, new_entry.principal)) { - if (kvno == IGNORE_VNO) { - if (! cur_entry.principal || - (cur_entry.vno < new_entry.vno)) - { - krb5_kt_free_entry(context, &cur_entry); - cur_entry = new_entry; - } - } else { - if (new_entry.vno == kvno) { - krb5_kt_free_entry(context, &cur_entry); - cur_entry = new_entry; - break; - } else - found_wrong_kvno++; - } + if (kvno == IGNORE_VNO) { + /* if this is the first match, or if the new vno is + bigger, free the current and keep the new. Otherwise, + free the new. */ + + if (! cur_entry.principal || + (new_entry.vno > cur_entry.vno)) { + krb5_kt_free_entry(context, &cur_entry); + cur_entry = new_entry; + } else { + krb5_kt_free_entry(context, &new_entry); + } } else { + /* if this kvno matches, free the current (will there ever + be one?), keep the new, and break out. Otherwise, remember + that we were here so we can return the right error, and + free the new */ + + if (new_entry.vno == kvno) { + krb5_kt_free_entry(context, &cur_entry); + cur_entry = new_entry; + break; + } else { + found_wrong_kvno++; krb5_kt_free_entry(context, &new_entry); + } } } + if (kerror == KRB5_KT_END) { if (cur_entry.principal) kerror = 0; diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 49d6ef3bb5..9d1cfb02a0 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,39 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * vfy_increds.c: rearrange the code a bit to make it more clear + that the logic is correct. + + * str_conv.c: remove enctype and cksumtype string converstions. + They're in the crypto library now, since the information drops + right into the enctype table. + + * ser_eblk.c: ifdef the whole file out, since it's not used + anywhere. it should probably be deleted, but I'm not sure about + backward-compatibility issues yet. + + * rd_req_dec.c: check the auth_context permit-all flag and + permitted_enctypes list, and reject the request if the policy + check fails. + + * init_ctx.c: add code to initialize the prng. It's not great, + but can be improved, and the prng is reseeded when new keys are + processed. Read permitted_enctypes from the krb5.conf file, and + provide accessor functions for it. Make the various etype list + parsers share code as a side effect. + + * get_creds.c: add krb5_get_{validat,renew}ed_creds functions, + which are part of the new init_creds api. The prototypes were + already in, krb5.hin but there was no implementing code. + + * auth_con.c, auth_con.h: add a list of permitted enctypes to the + auth_context for rd_req to check, and create accessor functions + for this list. + + * Makefile.in, enc_helper.c: add enc_helper.c. This provides a + wrapper around the conventional way the library encrypts and wraps + encoded asn.1 structures, so the code isn't repeated in a dozen + places. + Wed Aug 19 17:27:51 1998 Tom Yu <tlyu@mit.edu> * conv_princ.c: Add some additional entries to sconv_list that diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index ec6384e072..3c734210c0 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -32,6 +32,7 @@ STLIBOBJS= \ cp_key_cnt.o \ decode_kdc.o \ decrypt_tk.o \ + enc_helper.o \ encode_kdc.o \ encrypt_tk.o \ free_rtree.o \ @@ -114,6 +115,7 @@ OBJS= addr_comp.$(OBJEXT) \ cp_key_cnt.$(OBJEXT) \ decode_kdc.$(OBJEXT) \ decrypt_tk.$(OBJEXT) \ + enc_helper.$(OBJEXT) \ encode_kdc.$(OBJEXT) \ encrypt_tk.$(OBJEXT) \ free_rtree.$(OBJEXT) \ @@ -197,6 +199,7 @@ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/cp_key_cnt.c \ $(srcdir)/decode_kdc.c \ $(srcdir)/decrypt_tk.c \ + $(srcdir)/enc_helper.c \ $(srcdir)/encode_kdc.c \ $(srcdir)/encrypt_tk.c \ $(srcdir)/free_rtree.c \ diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c index 3795086235..335f7ae7dd 100644 --- a/src/lib/krb5/krb/auth_con.c +++ b/src/lib/krb5/krb/auth_con.c @@ -1,4 +1,3 @@ - #include "k5-int.h" #include "auth_con.h" @@ -71,6 +70,8 @@ krb5_auth_con_free(context, auth_context) krb5_free_keyblock(context, auth_context->remote_subkey); if (auth_context->rcache) krb5_rc_close(context, auth_context->rcache); + if (auth_context->permitted_etypes) + krb5_xfree(auth_context->permitted_etypes); free(auth_context); return 0; } @@ -274,12 +275,16 @@ krb5_auth_con_initivector(context, auth_context) krb5_context context; krb5_auth_context auth_context; { + krb5_error_code ret; + if (auth_context->keyblock) { - int size = krb5_enctype_array[auth_context->keyblock->enctype]-> - system->block_length; + size_t blocksize; - if ((auth_context->i_vector = (krb5_pointer)malloc(size))) { - memset(auth_context->i_vector, 0, size); + if ((ret = krb5_c_block_size(context, auth_context->keyblock->enctype, + &blocksize))) + return(ret); + if ((auth_context->i_vector = (krb5_pointer)malloc(blocksize))) { + memset(auth_context->i_vector, 0, blocksize); return 0; } return ENOMEM; @@ -347,3 +352,58 @@ krb5_auth_con_getrcache(context, auth_context, rcache) return 0; } +krb5_error_code +krb5_auth_con_setpermetypes(context, auth_context, permetypes) + krb5_context context; + krb5_auth_context auth_context; + const krb5_enctype * permetypes; +{ + krb5_enctype * newpe; + int i; + + for (i=0; permetypes[i]; i++) + ; + i++; /* include the zero */ + + if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype))) + == NULL) + return(ENOMEM); + + if (auth_context->permitted_etypes) + krb5_xfree(auth_context->permitted_etypes); + + auth_context->permitted_etypes = newpe; + + memcpy(newpe, permetypes, i*sizeof(krb5_enctype)); + + return 0; +} + +krb5_error_code +krb5_auth_con_getpermetypes(context, auth_context, permetypes) + krb5_context context; + krb5_auth_context auth_context; + krb5_enctype ** permetypes; +{ + krb5_enctype * newpe; + int i; + + if (! auth_context->permitted_etypes) { + *permetypes = NULL; + return(0); + } + + for (i=0; auth_context->permitted_etypes[i]; i++) + ; + i++; /* include the zero */ + + if ((newpe = (krb5_enctype *) malloc(i*sizeof(krb5_enctype))) + == NULL) + return(ENOMEM); + + *permetypes = newpe; + + memcpy(newpe, auth_context->permitted_etypes, i*sizeof(krb5_enctype)); + + return(0); +} diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h index 9d9df0e867..e6704169ed 100644 --- a/src/lib/krb5/krb/auth_con.h +++ b/src/lib/krb5/krb/auth_con.h @@ -20,6 +20,7 @@ struct _krb5_auth_context { krb5_cksumtype safe_cksumtype; /* mk_safe, ... */ krb5_pointer i_vector; /* mk_priv, rd_priv only */ krb5_rcache rcache; + krb5_enctype * permitted_etypes; /* rd_req */ }; diff --git a/src/lib/krb5/krb/decode_kdc.c b/src/lib/krb5/krb/decode_kdc.c index 71e01a8111..60c983878f 100644 --- a/src/lib/krb5/krb/decode_kdc.c +++ b/src/lib/krb5/krb/decode_kdc.c @@ -48,18 +48,28 @@ krb5_decode_kdc_rep(context, enc_rep, key, dec_rep) { krb5_error_code retval; krb5_kdc_rep *local_dec_rep; + krb5_keyusage usage; - if (krb5_is_as_rep(enc_rep)) + if (krb5_is_as_rep(enc_rep)) { + usage = KRB5_KEYUSAGE_AS_REP_ENCPART; retval = decode_krb5_as_rep(enc_rep, &local_dec_rep); - else if (krb5_is_tgs_rep(enc_rep)) + } else if (krb5_is_tgs_rep(enc_rep)) { + usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; + /* KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY would go here, except + that this client code base doesn't ever put a subkey in the + tgs_req authenticator, so the tgs_rep is never encrypted in + one. (Check send_tgs.c:krb5_send_tgs_basic(), near the top + where authent.subkey is set to 0) */ retval = decode_krb5_tgs_rep(enc_rep, &local_dec_rep); - else + } else { return KRB5KRB_AP_ERR_MSG_TYPE; + } if (retval) return retval; - if (retval = krb5_kdc_rep_decrypt_proc(context, key, 0, local_dec_rep)) + if (retval = krb5_kdc_rep_decrypt_proc(context, key, &usage, + local_dec_rep)) krb5_free_kdc_rep(context, local_dec_rep); else *dec_rep = local_dec_rep; diff --git a/src/lib/krb5/krb/decrypt_tk.c b/src/lib/krb5/krb/decrypt_tk.c index 354a3f2a06..47f675591a 100644 --- a/src/lib/krb5/krb/decrypt_tk.c +++ b/src/lib/krb5/krb/decrypt_tk.c @@ -42,43 +42,27 @@ krb5_decrypt_tkt_part(context, srv_key, ticket) register krb5_ticket FAR *ticket; { krb5_enc_tkt_part *dec_tkt_part; - krb5_encrypt_block eblock; krb5_data scratch; krb5_error_code retval; if (!valid_enctype(ticket->enc_part.enctype)) return KRB5_PROG_ETYPE_NOSUPP; - /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, ticket->enc_part.enctype); - scratch.length = ticket->enc_part.ciphertext.length; if (!(scratch.data = malloc(ticket->enc_part.ciphertext.length))) return(ENOMEM); - /* do any necessary key pre-processing */ - if (retval = krb5_process_key(context, &eblock, srv_key)) { - free(scratch.data); - return(retval); - } - /* call the encryption routine */ - if (retval = krb5_decrypt(context, - (krb5_pointer) ticket->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, scratch.length, - &eblock, 0)) { - (void) krb5_finish_key(context, &eblock); + if (retval = krb5_c_decrypt(context, srv_key, + KRB5_KEYUSAGE_KDC_REP_TICKET, 0, + &ticket->enc_part, &scratch)) { free(scratch.data); return retval; } + #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} - retval = krb5_finish_key(context, &eblock); - if (retval) { - clean_scratch(); - return retval; - } /* now decode the decrypted stuff */ retval = decode_krb5_enc_tkt_part(&scratch, &dec_tkt_part); if (!retval) { diff --git a/src/lib/krb5/krb/enc_helper.c b/src/lib/krb5/krb/enc_helper.c new file mode 100644 index 0000000000..ff42149370 --- /dev/null +++ b/src/lib/krb5/krb/enc_helper.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "k5-int.h" + +krb5_error_code +krb5_encrypt_helper(context, key, usage, plain, cipher) + krb5_context context; + krb5_const krb5_keyblock *key; + krb5_keyusage usage; + krb5_const krb5_data *plain; + krb5_enc_data *cipher; +{ + krb5_error_code ret; + size_t enclen; + + if (ret = krb5_c_encrypt_length(context, key->enctype, plain->length, + &enclen)) + return(ret); + + cipher->ciphertext.length = enclen; + if ((cipher->ciphertext.data = (char *) malloc(enclen)) == NULL) + return(ret); + + if (ret = krb5_c_encrypt(context, key, usage, 0, plain, cipher)) + free(cipher->ciphertext.data); + + return(ret); +} + diff --git a/src/lib/krb5/krb/encode_kdc.c b/src/lib/krb5/krb/encode_kdc.c index bb9311f6af..e20c1f5364 100644 --- a/src/lib/krb5/krb/encode_kdc.c +++ b/src/lib/krb5/krb/encode_kdc.c @@ -41,10 +41,12 @@ /* due to argument promotion rules, we need to use the DECLARG/OLDDECLARG stuff... */ krb5_error_code -krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep) +krb5_encode_kdc_rep(context, type, encpart, using_subkey, client_key, + dec_rep, enc_rep) krb5_context context; const krb5_msgtype type; const krb5_enc_kdc_rep_part * encpart; + int using_subkey; const krb5_keyblock * client_key; krb5_kdc_rep * dec_rep; krb5_data ** enc_rep; @@ -52,14 +54,20 @@ krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep) krb5_data *scratch; krb5_error_code retval; krb5_enc_kdc_rep_part tmp_encpart; - krb5_encrypt_block eblock; + krb5_keyusage usage; if (!valid_enctype(dec_rep->enc_part.enctype)) return KRB5_PROG_ETYPE_NOSUPP; switch (type) { case KRB5_AS_REP: + usage = KRB5_KEYUSAGE_AS_REP_ENCPART; + break; case KRB5_TGS_REP: + if (using_subkey) + usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY; + else + usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; break; default: return KRB5_BADMSGTYPE; @@ -89,23 +97,8 @@ krb5_encode_kdc_rep(context, type, encpart, client_key, dec_rep, enc_rep) #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ krb5_free_data(context, scratch); } - krb5_use_enctype(context, &eblock, client_key->enctype); - dec_rep->enc_part.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - dec_rep->enc_part.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - dec_rep->enc_part.ciphertext.length - scratch->length); - if (!(dec_rep->enc_part.ciphertext.data = - malloc(dec_rep->enc_part.ciphertext.length))) { - retval = ENOMEM; - goto clean_scratch; - } + retval = krb5_encrypt_helper(context, client_key, usage, scratch, + &dec_rep->enc_part); #define cleanup_encpart() { \ (void) memset(dec_rep->enc_part.ciphertext.data, 0, \ @@ -114,30 +107,10 @@ free(dec_rep->enc_part.ciphertext.data); \ dec_rep->enc_part.ciphertext.length = 0; \ dec_rep->enc_part.ciphertext.data = 0;} - retval = krb5_process_key(context, &eblock, client_key); - if (retval) { - goto clean_encpart; - } - -#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);} - - retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) dec_rep->enc_part.ciphertext.data, - scratch->length, &eblock, 0); - if (retval) { - goto clean_prockey; - } - - dec_rep->enc_part.enctype = krb5_eblock_enctype(context, &eblock); - - /* do some cleanup */ cleanup_scratch(); - retval = krb5_finish_key(context, &eblock); - if (retval) { - cleanup_encpart(); - return retval; - } + if (retval) + return(retval); /* now it's ready to be encoded for the wire! */ @@ -149,18 +122,9 @@ dec_rep->enc_part.ciphertext.data = 0;} retval = encode_krb5_tgs_rep(dec_rep, enc_rep); break; } + if (retval) cleanup_encpart(); - return retval; - - clean_prockey: - cleanup_prockey(); - clean_encpart: - cleanup_encpart(); - clean_scratch: - cleanup_scratch(); return retval; } - - diff --git a/src/lib/krb5/krb/encrypt_tk.c b/src/lib/krb5/krb/encrypt_tk.c index cb1fb28b9d..e1a1b1850e 100644 --- a/src/lib/krb5/krb/encrypt_tk.c +++ b/src/lib/krb5/krb/encrypt_tk.c @@ -44,7 +44,6 @@ krb5_encrypt_tkt_part(context, srv_key, dec_ticket) const krb5_keyblock *srv_key; register krb5_ticket *dec_ticket; { - krb5_encrypt_block eblock; krb5_data *scratch; krb5_error_code retval; register krb5_enc_tkt_part *dec_tkt_part = dec_ticket->enc_part2; @@ -57,64 +56,12 @@ krb5_encrypt_tkt_part(context, srv_key, dec_ticket) #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ krb5_free_data(context, scratch); } - krb5_use_enctype(context, &eblock, srv_key->enctype); - - dec_ticket->enc_part.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - dec_ticket->enc_part.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - dec_ticket->enc_part.ciphertext.length - scratch->length); - if (!(dec_ticket->enc_part.ciphertext.data = - malloc(dec_ticket->enc_part.ciphertext.length))) { - retval = ENOMEM; - goto clean_scratch; - } - -#define cleanup_encpart() {\ -(void) memset(dec_ticket->enc_part.ciphertext.data, 0,\ - dec_ticket->enc_part.ciphertext.length); \ -free(dec_ticket->enc_part.ciphertext.data); \ -dec_ticket->enc_part.ciphertext.length = 0; \ -dec_ticket->enc_part.ciphertext.data = 0;} - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, srv_key))) { - goto clean_encpart; - } - -#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);} - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) dec_ticket->enc_part.ciphertext.data, - scratch->length, &eblock, 0))) { - goto clean_prockey; - } - - dec_ticket->enc_part.enctype = srv_key->enctype; - - /* ticket is now assembled-- do some cleanup */ - cleanup_scratch(); - - if ((retval = krb5_finish_key(context, &eblock))) { - cleanup_encpart(); - return retval; - } - - return 0; + retval = krb5_encrypt_helper(context, srv_key, + KRB5_KEYUSAGE_KDC_REP_TICKET, scratch, + &dec_ticket->enc_part); - clean_prockey: - cleanup_prockey(); - clean_encpart: - cleanup_encpart(); - clean_scratch: cleanup_scratch(); - return retval; + return(retval); } diff --git a/src/lib/krb5/krb/gen_seqnum.c b/src/lib/krb5/krb/gen_seqnum.c index 3694d2cd07..4b3cd6fe6a 100644 --- a/src/lib/krb5/krb/gen_seqnum.c +++ b/src/lib/krb5/krb/gen_seqnum.c @@ -38,71 +38,15 @@ krb5_generate_seq_number(context, key, seqno) const krb5_keyblock *key; krb5_int32 *seqno; { - krb5_pointer random_state; - krb5_encrypt_block eblock; - krb5_keyblock *subkey = 0; + krb5_data seed; krb5_error_code retval; - struct tval { - krb5_int32 seconds; - krb5_int32 microseconds; - } timenow; - krb5_octet *intmp = 0, *outtmp = 0; - int esize; - if (!valid_enctype(key->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; - - krb5_use_enctype(context, &eblock, key->enctype); - - if ((retval = krb5_init_random_key(context, &eblock, key, &random_state))) + seed.length = key->length; + seed.data = key->contents; + if ((retval = krb5_c_random_seed(context, &seed))) return(retval); - - if ((retval = krb5_random_key(context, &eblock, random_state, &subkey))) { - (void) krb5_finish_random_key(context, &eblock, &random_state); - return retval; - } - /* ignore the error if any, since we've already gotten the key out */ - if ((retval = krb5_finish_random_key(context, &eblock, &random_state))) { - krb5_free_keyblock(context, subkey); - return retval; - } - - esize = krb5_encrypt_size(sizeof(timenow), eblock.crypto_entry); - intmp = (krb5_octet *)malloc(esize); - if (!intmp) { - retval = ENOMEM; - goto cleanup; - } - outtmp = (krb5_octet *)malloc(esize); - if (!outtmp) { - retval = ENOMEM; - goto cleanup; - } - if ((retval = krb5_process_key(context, &eblock, subkey))) { - goto cleanup; - } - if ((retval = krb5_us_timeofday(context, &timenow.seconds, - &timenow.microseconds))) { - goto cleanup; - } - memcpy((char *)intmp, (char *)&timenow, sizeof(timenow)); - - retval = krb5_encrypt(context, (krb5_pointer)intmp, (krb5_pointer)outtmp, - sizeof(timenow), &eblock, 0); - (void) krb5_finish_key(context, &eblock); - if (retval) - goto cleanup; - - memcpy((char *) seqno, (char *)outtmp, sizeof(krb5_int32)); - -cleanup: - if (subkey) - krb5_free_keyblock(context, subkey); - if (intmp) - krb5_xfree(intmp); - if (outtmp) - krb5_xfree(outtmp); - return retval; + seed.length = sizeof(*seqno); + seed.data = (char *) seqno; + return(krb5_c_random_make_octets(context, &seed)); } - diff --git a/src/lib/krb5/krb/gen_subkey.c b/src/lib/krb5/krb/gen_subkey.c index 89e21a1b79..861d61e722 100644 --- a/src/lib/krb5/krb/gen_subkey.c +++ b/src/lib/krb5/krb/gen_subkey.c @@ -32,24 +32,21 @@ krb5_generate_subkey(context, key, subkey) const krb5_keyblock *key; krb5_keyblock **subkey; { - krb5_pointer random_state; - krb5_encrypt_block eblock; krb5_error_code retval; + krb5_data seed; - if (!valid_enctype(key->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + seed.length = key->length; + seed.data = key->contents; + if ((retval = krb5_c_random_seed(context, &seed))) + return(retval); - krb5_use_enctype(context, &eblock, key->enctype); + if ((*subkey = (krb5_keyblock *) malloc(sizeof(krb5_keyblock))) == NULL) + return(ENOMEM); - if ((retval = krb5_init_random_key(context, &eblock, key, &random_state))) - return(retval); - if ((retval = krb5_random_key(context, &eblock, random_state, subkey))) { - (void) krb5_finish_random_key(context, &eblock, &random_state); + if ((retval = krb5_c_make_random_key(context, key->enctype, *subkey))) { krb5_xfree(*subkey); - return retval; - } - /* ignore the error if any, since we've already gotten the key out */ - (void) krb5_finish_random_key(context, &eblock, &random_state); - return 0; -} + return(retval); + } + return(0); +} diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c index 3a1ec526b7..37f2bb5a93 100644 --- a/src/lib/krb5/krb/get_creds.c +++ b/src/lib/krb5/krb/get_creds.c @@ -160,12 +160,6 @@ krb5_get_credentials_val_renew_core(context, options, ccache, krb5_creds **tgts = 0; krb5_flags fields; - retval = krb5_get_credentials_core(context, options, ccache, - in_creds, out_creds, - &mcreds, &fields); - - if (retval) return retval; - switch(which) { case INT_GC_VALIDATE: retval = krb5_get_cred_from_kdc_validate(context, ccache, @@ -219,3 +213,104 @@ krb5_get_credentials_renew(context, options, ccache, in_creds, out_creds) in_creds, out_creds, INT_GC_RENEW)); } + +static krb5_error_code +krb5_validate_or_renew_creds(context, creds, client, ccache, in_tkt_service, + validate) + krb5_context context; + krb5_creds *creds; + krb5_principal client; + krb5_ccache ccache; + char *in_tkt_service; + int validate; +{ + krb5_error_code ret; + krb5_creds in_creds; /* only client and server need to be filled in */ + krb5_creds *out_creds; + krb5_creds **tgts; + + memset((char *)&in_creds, 0, sizeof(krb5_creds)); + + in_creds.server = NULL; + tgts = NULL; + + in_creds.client = client; + + if (in_tkt_service) { + /* this is ugly, because so are the data structures involved. I'm + in the library, so I'm going to manipulate the data structures + directly, otherwise, it will be worse. */ + + if (ret = krb5_parse_name(context, in_tkt_service, &in_creds.server)) + goto cleanup; + + /* stuff the client realm into the server principal. + realloc if necessary */ + if (in_creds.server->realm.length < in_creds.client->realm.length) + if ((in_creds.server->realm.data = + (char *) realloc(in_creds.server->realm.data, + in_creds.client->realm.length)) == NULL) { + ret = ENOMEM; + goto cleanup; + } + + in_creds.server->realm.length = in_creds.client->realm.length; + memcpy(in_creds.server->realm.data, in_creds.client->realm.data, + in_creds.client->realm.length); + } else { + if (ret = krb5_build_principal_ext(context, &in_creds.server, + in_creds.client->realm.length, + in_creds.client->realm.data, + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME, + in_creds.client->realm.length, + in_creds.client->realm.data, + 0)) + goto cleanup; + } + + if (validate) + ret = krb5_get_cred_from_kdc_validate(context, ccache, + &in_creds, &out_creds, &tgts); + else + ret = krb5_get_cred_from_kdc_renew(context, ccache, + &in_creds, &out_creds, &tgts); + + /* ick. copy the struct contents, free the container */ + + *creds = *out_creds; + krb5_xfree(out_creds); + +cleanup: + + if (in_creds.server) + krb5_free_principal(context, in_creds.server); + if (tgts) + krb5_free_tgt_creds(context, tgts); + + return(ret); +} + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_get_validated_creds(context, creds, client, ccache, in_tkt_service) + krb5_context context; + krb5_creds *creds; + krb5_principal client; + krb5_ccache ccache; + char *in_tkt_service; +{ + return(krb5_validate_or_renew_creds(context, creds, client, ccache, + in_tkt_service, 1)); +} + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_get_renewed_creds(context, creds, client, ccache, in_tkt_service) + krb5_context context; + krb5_creds *creds; + krb5_principal client; + krb5_ccache ccache; + char *in_tkt_service; +{ + return(krb5_validate_or_renew_creds(context, creds, client, ccache, + in_tkt_service, 0)); +} diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index 45a076246f..c517062f86 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -16,7 +16,6 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, krb5_data *password; krb5_error_code ret; krb5_data defsalt; - krb5_encrypt_block eblock; char *clientstr; char promptstr[1024]; krb5_prompt prompt; @@ -35,11 +34,6 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, as_key->length = 0; } - if (!valid_enctype(etype)) - return(KRB5_PROG_ETYPE_NOSUPP); - - krb5_use_enctype(context, &eblock, etype); - if (password->data[0] == '\0') { if (prompter == NULL) return(EIO); @@ -70,7 +64,7 @@ krb5_get_as_key_password(context, client, etype, prompter, prompter_data, defsalt.length = 0; } - ret = krb5_string_to_key(context, &eblock, as_key, password, salt); + ret = krb5_c_string_to_key(context, etype, password, salt, as_key); if (defsalt.length) krb5_xfree(defsalt.data); diff --git a/src/lib/krb5/krb/in_tkt_pwd.c b/src/lib/krb5/krb/in_tkt_pwd.c index 7373f62f19..e03883e9d7 100644 --- a/src/lib/krb5/krb/in_tkt_pwd.c +++ b/src/lib/krb5/krb/in_tkt_pwd.c @@ -47,15 +47,9 @@ pwd_keyproc(context, type, salt, keyseed, key) krb5_keyblock ** key; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data * password; int pwsize; - if (!valid_enctype(type)) - return KRB5_PROG_ETYPE_NOSUPP; - - krb5_use_enctype(context, &eblock, type); - password = (krb5_data *)keyseed; if (!password->length) { @@ -73,8 +67,9 @@ pwd_keyproc(context, type, salt, keyseed, key) if (!(*key = (krb5_keyblock *)malloc(sizeof(**key)))) return ENOMEM; - if ((retval = krb5_string_to_key(context, &eblock, *key, password, salt))) + if ((retval = krb5_c_string_to_key(context, type, password, salt, *key))) krb5_xfree(*key); + return(retval); } diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index daa9fd95f8..2285b0f421 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -23,6 +23,32 @@ * krb5_init_contex() */ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + #include "k5-int.h" #include <ctype.h> #include "brand.c" @@ -37,6 +63,8 @@ krb5_init_context(context) { krb5_context ctx = 0; krb5_error_code retval; + krb5_timestamp now; + krb5_data seed; int tmp; /* Initialize error tables */ @@ -70,6 +98,14 @@ krb5_init_context(context) if ((retval = krb5_os_init_context(ctx))) goto cleanup; + /* initialize the prng (not well, but passable) */ + if ((retval = krb5_timeofday(ctx, &now))) + goto cleanup; + seed.length = sizeof(now); + seed.data = (char *) &now; + if ((retval = krb5_c_random_seed(ctx, &seed))) + goto cleanup; + ctx->default_realm = 0; profile_get_integer(ctx->profile, "libdefaults", "clockskew", 0, 5 * 60, &tmp); @@ -197,26 +233,27 @@ krb5_set_default_in_tkt_ktypes(context, ktypes) return 0; } -krb5_error_code -krb5_get_default_in_tkt_ktypes(context, ktypes) - krb5_context context; - krb5_enctype **ktypes; +static krb5_error_code +get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list) + krb5_context context; + krb5_enctype **ktypes; + char *profstr; + int ctx_count; + krb5_enctype FAR *ctx_list; { - krb5_enctype * old_ktypes; + krb5_enctype *old_ktypes; if (context->in_tkt_ktype_count) { - /* application-set defaults */ - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * - (context->in_tkt_ktype_count + 1)))) { - memcpy(old_ktypes, context->in_tkt_ktypes, sizeof(krb5_enctype) * - context->in_tkt_ktype_count); - old_ktypes[context->in_tkt_ktype_count] = 0; - } else { - return ENOMEM; - } + /* application-set defaults */ + if ((old_ktypes = + (krb5_enctype *)malloc(sizeof(krb5_enctype) * + (ctx_count + 1)))) { + memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count); + old_ktypes[ctx_count] = 0; + } else { + return ENOMEM; + } } else { - /* taken directly from krb5_get_tgs_ktypes... */ /* XXX - For now, we only support libdefaults Perhaps this should be extended to allow for per-host / per-realm @@ -228,9 +265,9 @@ krb5_get_default_in_tkt_ktypes(context, ktypes) int i, j, count; krb5_error_code code; - code = profile_get_string(context->profile, - "libdefaults", "default_tkt_enctypes", NULL, - "des-cbc-md5 des-cbc-crc", + code = profile_get_string(context->profile, "libdefaults", profstr, + NULL, + "des3-hmac-sha1 des-cbc-md5 des-cbc-crc", &retval); if (code) return code; @@ -280,6 +317,16 @@ krb5_get_default_in_tkt_ktypes(context, ktypes) } krb5_error_code +krb5_get_default_in_tkt_ktypes(context, ktypes) + krb5_context context; + krb5_enctype **ktypes; +{ + return(get_profile_etype_list(context, ktypes, "default_tkt_enctypes", + context->in_tkt_ktype_count, + context->in_tkt_ktypes)); +} + +krb5_error_code krb5_set_default_tgs_ktypes(context, ktypes) krb5_context context; const krb5_enctype *ktypes; @@ -317,80 +364,40 @@ krb5_get_tgs_ktypes(context, princ, ktypes) krb5_const_principal princ; krb5_enctype **ktypes; { - krb5_enctype * old_ktypes; - - if (context->tgs_ktype_count) { - - /* Application-set defaults */ - - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * - (context->tgs_ktype_count + 1)))) { - memcpy(old_ktypes, context->tgs_ktypes, sizeof(krb5_enctype) * - context->tgs_ktype_count); - old_ktypes[context->tgs_ktype_count] = 0; - } else { - return ENOMEM; - } - } else { - /* - XXX - For now, we only support libdefaults - Perhaps this should be extended to allow for per-host / per-realm - session key types. - */ - - char *retval; - char *sp, *ep; - int i, j, count; - krb5_error_code code; + return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes", + context->tgs_ktype_count, + context->tgs_ktypes)); +} - code = profile_get_string(context->profile, - "libdefaults", "default_tgs_enctypes", NULL, - "des-cbc-md5 des-cbc-crc", - &retval); - if (code) - return code; +krb5_error_code +krb5_get_permitted_enctypes(context, ktypes) + krb5_context context; + krb5_enctype **ktypes; +{ + return(get_profile_etype_list(context, ktypes, "permitted_enctypes", + context->tgs_ktype_count, + context->tgs_ktypes)); +} - count = 0; - sp = retval; - while (sp) { - for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++) - ; - if (*ep) { - *ep++ = '\0'; - while (isspace(*ep)) - ep++; - } else - ep = (char *) NULL; +krb5_boolean +krb5_is_permitted_enctype(context, etype) + krb5_context context; + krb5_enctype etype; +{ + krb5_enctype *list, *ptr; + krb5_boolean ret; - count++; - sp = ep; - } - - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) == - (krb5_enctype *) NULL) - return ENOMEM; - - sp = retval; - j = 0; - i = 1; - while (1) { - if (! krb5_string_to_enctype(sp, &old_ktypes[j])) - j++; + if (krb5_get_permitted_enctypes(context, &list)) + return(0); - if (i++ >= count) - break; + + ret = 0; - /* skip to next token */ - while (*sp) sp++; - while (! *sp) sp++; - } + for (ptr = list; *ptr; ptr++) + if (*ptr == etype) + ret = 1; - old_ktypes[j] = (krb5_enctype) 0; - free(retval); - } + krb5_xfree(list); - *ktypes = old_ktypes; - return 0; + return(ret); } diff --git a/src/lib/krb5/krb/kdc_rep_dc.c b/src/lib/krb5/krb/kdc_rep_dc.c index e9431aef94..a9cbcf39bb 100644 --- a/src/lib/krb5/krb/kdc_rep_dc.c +++ b/src/lib/krb5/krb/kdc_rep_dc.c @@ -41,12 +41,15 @@ krb5_kdc_rep_decrypt_proc(context, key, decryptarg, dec_rep) krb5_kdc_rep * dec_rep; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data scratch; krb5_enc_kdc_rep_part *local_encpart; + krb5_keyusage usage; - if (!valid_enctype(dec_rep->enc_part.enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + if (decryptarg) { + usage = *(const krb5_keyusage *) decryptarg; + } else { + usage = KRB5_KEYUSAGE_AS_REP_ENCPART; + } /* set up scratch decrypt/decode area */ @@ -55,30 +58,16 @@ krb5_kdc_rep_decrypt_proc(context, key, decryptarg, dec_rep) return(ENOMEM); } - /* put together an eblock for this encryption */ - - krb5_use_enctype(context, &eblock, dec_rep->enc_part.enctype); + dec_rep->enc_part.enctype; - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, key))) { + if ((retval = krb5_c_decrypt(context, key, usage, 0, &dec_rep->enc_part, + &scratch))) { free(scratch.data); return(retval); } - /* call the decryption routine */ - if ((retval = krb5_decrypt(context, (krb5_pointer) dec_rep->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); - free(scratch.data); - return retval; - } #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} - if ((retval = krb5_finish_key(context, &eblock))) { - clean_scratch(); - return retval; - } /* and do the decode */ retval = decode_krb5_enc_kdc_rep_part(&scratch, &local_encpart); diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c index 17c4f8c7f7..87eeca9619 100644 --- a/src/lib/krb5/krb/kfree.c +++ b/src/lib/krb5/krb/kfree.c @@ -149,6 +149,16 @@ krb5_free_checksum(context, val) } KRB5_DLLIMP void KRB5_CALLCONV +krb5_free_checksum_contents(context, val) + krb5_context context; + register krb5_checksum *val; +{ + if (val->contents) + krb5_xfree(val->contents); + return; +} + +KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cred(context, val) krb5_context context; register krb5_cred FAR *val; @@ -572,3 +582,4 @@ krb5_free_unparsed_name(context, val) krb5_xfree(val); return; } + diff --git a/src/lib/krb5/krb/mk_cred.c b/src/lib/krb5/krb/mk_cred.c index 23545fb612..cdda80d062 100644 --- a/src/lib/krb5/krb/mk_cred.c +++ b/src/lib/krb5/krb/mk_cred.c @@ -28,12 +28,8 @@ encrypt_credencpart(context, pcredpart, pkeyblock, pencdata) krb5_enc_data * pencdata; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data * scratch; - if (pkeyblock && !valid_enctype(pkeyblock->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; - /* start by encoding to-be-encrypted part of the message */ if ((retval = encode_krb5_enc_cred_part(pcredpart, &scratch))) return retval; @@ -49,47 +45,11 @@ encrypt_credencpart(context, pcredpart, pkeyblock, pencdata) return 0; } - /* put together an eblock for this encryption */ - - pencdata->kvno = 0; - pencdata->enctype = pkeyblock->enctype; - - krb5_use_enctype(context, &eblock, pkeyblock->enctype); - pencdata->ciphertext.length = krb5_encrypt_size(scratch->length, - eblock.crypto_entry); - - /* add padding area, and zero it */ - if (!(scratch->data = (char *)realloc(scratch->data, - pencdata->ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - - memset(scratch->data + scratch->length, 0, - pencdata->ciphertext.length - scratch->length); - if (!(pencdata->ciphertext.data = - (char *)malloc(pencdata->ciphertext.length))) { - retval = ENOMEM; - goto clean_scratch; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, pkeyblock))) { - goto clean_encpart; - } - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer)scratch->data, - (krb5_pointer)pencdata->ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); - goto clean_encpart; - } - - retval = krb5_finish_key(context, &eblock); + retval = krb5_encrypt_helper(context, pkeyblock, + KRB5_KEYUSAGE_KRB_CRED_ENCPART, + scratch, pencdata); -clean_encpart: if (retval) { memset(pencdata->ciphertext.data, 0, pencdata->ciphertext.length); free(pencdata->ciphertext.data); @@ -97,7 +57,6 @@ clean_encpart: pencdata->ciphertext.data = 0; } -clean_scratch: memset(scratch->data, 0, scratch->length); krb5_free_data(context, scratch); diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c index 7986e18562..2e7f2ce255 100644 --- a/src/lib/krb5/krb/mk_priv.c +++ b/src/lib/krb5/krb/mk_priv.c @@ -41,13 +41,10 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr, krb5_data * outbuf; { krb5_error_code retval; - krb5_encrypt_block eblock; krb5_priv privmsg; krb5_priv_enc_part privmsg_enc_part; - krb5_data *scratch1, *scratch2; - - if (!valid_enctype(keyblock->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + krb5_data *scratch1, *scratch2, ivdata; + size_t blocksize, enclen; privmsg.enc_part.kvno = 0; /* XXX allow user-set? */ privmsg.enc_part.enctype = keyblock->enctype; @@ -66,52 +63,42 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr, return retval; /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, keyblock->enctype); - privmsg.enc_part.ciphertext.length = krb5_encrypt_size(scratch1->length, - eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch1->data = realloc(scratch1->data, - privmsg.enc_part.ciphertext.length))) { - /* may destroy scratch1->data */ - krb5_xfree(scratch1); - return ENOMEM; - } + if ((retval = krb5_c_encrypt_length(context, keyblock->enctype, + scratch1->length, &enclen))) + goto clean_scratch; - memset(scratch1->data + scratch1->length, 0, - privmsg.enc_part.ciphertext.length - scratch1->length); + privmsg.enc_part.ciphertext.length = enclen; if (!(privmsg.enc_part.ciphertext.data = malloc(privmsg.enc_part.ciphertext.length))) { retval = ENOMEM; goto clean_scratch; } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, keyblock))) - goto clean_encpart; - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch1->data, - (krb5_pointer) privmsg.enc_part.ciphertext.data, - scratch1->length, &eblock, i_vector))) { - krb5_finish_key(context, &eblock); - goto clean_encpart; + if (i_vector) { + if ((retval = krb5_c_block_size(context, keyblock->enctype, + &blocksize))) + goto clean_encpart; + + ivdata.length = blocksize; + ivdata.data = i_vector; } + if ((retval = krb5_c_encrypt(context, keyblock, + KRB5_KEYUSAGE_KRB_PRIV_ENCPART, + i_vector?&ivdata:0, + scratch1, &privmsg.enc_part))) + goto clean_encpart; + /* put last block into the i_vector */ + if (i_vector) memcpy(i_vector, privmsg.enc_part.ciphertext.data + - (privmsg.enc_part.ciphertext.length - - eblock.crypto_entry->block_length), - eblock.crypto_entry->block_length); + (privmsg.enc_part.ciphertext.length - blocksize), + blocksize); - if ((retval = encode_krb5_priv(&privmsg, &scratch2))) { - krb5_finish_key(context, &eblock); - goto clean_encpart; - } - - /* encode private message */ - if ((retval = krb5_finish_key(context, &eblock))) + if ((retval = encode_krb5_priv(&privmsg, &scratch2))) goto clean_encpart; *outbuf = *scratch2; diff --git a/src/lib/krb5/krb/mk_rep.c b/src/lib/krb5/krb/mk_rep.c index 45784284c3..f0398475f5 100644 --- a/src/lib/krb5/krb/mk_rep.c +++ b/src/lib/krb5/krb/mk_rep.c @@ -45,14 +45,11 @@ krb5_mk_rep(context, auth_context, outbuf) krb5_error_code retval; krb5_enctype enctype; krb5_ap_rep_enc_part repl; - krb5_encrypt_block eblock; krb5_ap_rep reply; krb5_data * scratch; krb5_data * toutbuf; - /* verify a valid enctype is available */ - if (!valid_enctype(enctype = auth_context->keyblock->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; + enctype = auth_context->keyblock->enctype; /* Make the reply */ if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) || @@ -72,49 +69,16 @@ krb5_mk_rep(context, auth_context, outbuf) if ((retval = encode_krb5_ap_rep_enc_part(&repl, &scratch))) return retval; - /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, enctype); - reply.enc_part.enctype = enctype; - reply.enc_part.kvno = 0; /* XXX user set? */ - - reply.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length, - eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - reply.enc_part.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - reply.enc_part.ciphertext.length - scratch->length); - if (!(reply.enc_part.ciphertext.data = - malloc(reply.enc_part.ciphertext.length))) { - retval = ENOMEM; + if ((retval = krb5_encrypt_helper(context, auth_context->keyblock, + KRB5_KEYUSAGE_AP_REP_ENCPART, + scratch, &reply.enc_part))) goto cleanup_scratch; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, auth_context->keyblock))) - goto cleanup_encpart; - - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) reply.enc_part.ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); - goto cleanup_encpart; - } - - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup_encpart; if (!(retval = encode_krb5_ap_rep(&reply, &toutbuf))) { *outbuf = *toutbuf; krb5_xfree(toutbuf); } -cleanup_encpart: memset(reply.enc_part.ciphertext.data, 0, reply.enc_part.ciphertext.length); free(reply.enc_part.ciphertext.data); reply.enc_part.ciphertext.length = 0; diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c index 726bb434b0..1530f79616 100644 --- a/src/lib/krb5/krb/mk_req_ext.c +++ b/src/lib/krb5/krb/mk_req_ext.c @@ -84,7 +84,6 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, krb5_ap_req request; krb5_data *scratch = 0; - krb5_encrypt_block eblock; krb5_data *toutbuf; request.ap_options = ap_req_options & AP_OPTS_WIRE_MASK; @@ -98,12 +97,6 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, if ((retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket))) return(retval); - /* verify a valid enctype is available */ - if (!valid_enctype(in_creds->keyblock.enctype)) { - retval = KRB5_PROG_ETYPE_NOSUPP; - goto cleanup; - } - /* verify that the ticket is not expired */ if ((retval = krb5_validate_times(context, &in_creds->times)) != 0) goto cleanup; @@ -135,27 +128,18 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, &(*auth_context)->local_subkey))) goto cleanup; - if (in_data) { if ((*auth_context)->req_cksumtype == 0x8003) { /* XXX Special hack for GSSAPI */ checksum.checksum_type = 0x8003; checksum.length = in_data->length; checksum.contents = (krb5_octet *) in_data->data; - } else { - /* Generate checksum, XXX What should the seed be? */ - checksum.length = - krb5_checksum_size(context, (*auth_context)->req_cksumtype); - if ((checksum.contents = (krb5_octet *)malloc(checksum.length)) == NULL) { - retval = ENOMEM; - goto cleanup; - } - if ((retval = krb5_calculate_checksum(context, - (*auth_context)->req_cksumtype, - in_data->data, in_data->length, - (*auth_context)->keyblock->contents, - (*auth_context)->keyblock->length, - &checksum))) + } else { + if ((retval = krb5_c_make_checksum(context, + (*auth_context)->req_cksumtype, + (*auth_context)->keyblock, + KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, + in_data, &checksum))) goto cleanup_cksum; } checksump = &checksum; @@ -188,43 +172,12 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, (*auth_context)->authentp->checksum = NULL; (*auth_context)->authentp->authorization_data = NULL; - /* put together an eblock for this encryption */ - - krb5_use_enctype(context, &eblock, in_creds->keyblock.enctype); - request.authenticator.enctype = in_creds->keyblock.enctype; - request.authenticator.kvno = 0; - request.authenticator.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - request.authenticator.ciphertext.length))) { - /* may destroy scratch->data */ - retval = ENOMEM; - goto cleanup_cksum; - } - memset(scratch->data + scratch->length, 0, - request.authenticator.ciphertext.length - scratch->length); - if (!(request.authenticator.ciphertext.data = - malloc(request.authenticator.ciphertext.length))) { - retval = ENOMEM; - goto cleanup_cksum; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, &(in_creds)->keyblock))) - goto cleanup; - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) request.authenticator.ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); + if ((retval = krb5_encrypt_helper(context, &in_creds->keyblock, + KRB5_KEYUSAGE_AP_REQ_AUTH, + scratch, &request.authenticator))) goto cleanup_cksum; - } - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup_cksum; - if ((retval = encode_krb5_ap_req(&request, &toutbuf))) goto cleanup_cksum; #ifdef HAVE_C_STRUCTURE_ASSIGNMENT diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c index 1a44a75e59..0d5a490804 100644 --- a/src/lib/krb5/krb/mk_safe.c +++ b/src/lib/krb5/krb/mk_safe.c @@ -90,18 +90,11 @@ krb5_mk_safe_basic(context, userdata, keyblock, replaydata, local_addr, if ((retval = encode_krb5_safe(&safemsg, &scratch1))) return retval; - safe_checksum.length = krb5_checksum_size(context, sumtype); - if (!(safe_checksum.contents = (krb5_octet *) malloc(safe_checksum.length))) { - - retval = ENOMEM; - goto cleanup_scratch; - } - if ((retval = krb5_calculate_checksum(context, sumtype, scratch1->data, - scratch1->length, - (krb5_pointer) keyblock->contents, - keyblock->length, &safe_checksum))) { + if ((retval = krb5_c_make_checksum(context, sumtype, keyblock, + KRB5_KEYUSAGE_KRB_SAFE_CKSUM, + scratch1, &safe_checksum))) goto cleanup_checksum; - } + safemsg.checksum = &safe_checksum; if ((retval = encode_krb5_safe(&safemsg, &scratch2))) { goto cleanup_checksum; diff --git a/src/lib/krb5/krb/preauth.c b/src/lib/krb5/krb/preauth.c index c106dd15a3..ab1432fdb0 100644 --- a/src/lib/krb5/krb/preauth.c +++ b/src/lib/krb5/krb/preauth.c @@ -160,6 +160,10 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc, for (pa = preauth_to_use, size=0; *pa; pa++, size++) { if ((*pa)->pa_type == KRB5_PADATA_ETYPE_INFO) { + /* XXX use the first one. Is there another way to disambiguate? */ + if (etype_info) + continue; + scratch.length = (*pa)->length; scratch.data = (char *) (*pa)->contents; retval = decode_krb5_etype_info(&scratch, &etype_info); @@ -219,6 +223,8 @@ krb5_error_code krb5_obtain_padata(context, preauth_to_use, key_proc, } cleanup: + if (etype_info) + krb5_free_etype_info(context, etype_info); if (f_salt) krb5_xfree(salt.data); if (send_pa_list) @@ -294,9 +300,6 @@ obtain_enc_ts_padata(context, in_padata, etype_info, def_enc_key, krb5_data * scratch; krb5_enc_data enc_data; krb5_pa_data * pa; - - - enc_data.ciphertext.data = 0; retval = krb5_us_timeofday(context, &pa_enc.patimestamp, &pa_enc.pausec); if (retval) @@ -305,8 +308,11 @@ obtain_enc_ts_padata(context, in_padata, etype_info, def_enc_key, if ((retval = encode_krb5_pa_enc_ts(&pa_enc, &scratch)) != 0) return retval; - if ((retval = krb5_encrypt_data(context, def_enc_key, 0, scratch, - &enc_data))) + enc_data.ciphertext.data = 0; + + if ((retval = krb5_encrypt_helper(context, def_enc_key, + KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS, + scratch, &enc_data))) goto cleanup; krb5_free_data(context, scratch); diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c index 0a154f6e14..86d325d7b9 100644 --- a/src/lib/krb5/krb/preauth2.c +++ b/src/lib/krb5/krb/preauth2.c @@ -117,12 +117,16 @@ krb5_error_code pa_enc_timestamp(krb5_context context, if (ret = encode_krb5_pa_enc_ts(&pa_enc, &tmp)) return(ret); - ret = krb5_encrypt_data(context, as_key, 0, tmp, &enc_data); + ret = krb5_encrypt_helper(context, as_key, + KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS, + tmp, &enc_data); krb5_free_data(context, tmp); - if (ret) + if (ret) { + krb5_xfree(enc_data.ciphertext.data); return(ret); + } ret = encode_krb5_enc_data(&enc_data, &tmp); @@ -215,7 +219,6 @@ krb5_error_code pa_sam(krb5_context context, char banner[100], prompt[100], response[100]; krb5_data response_data; krb5_prompt kprompt; - krb5_encrypt_block eblock; krb5_data defsalt; krb5_sam_challenge *sam_challenge = 0; krb5_sam_response sam_response; @@ -281,13 +284,6 @@ krb5_error_code pa_sam(krb5_context context, as_key->length = 0; } - /* XXX the server uses this fixed enctype, so we will, too. */ - - if (!valid_enctype(ENCTYPE_DES_CBC_MD5)) - return(KRB5_PROG_ETYPE_NOSUPP); - - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - #if 0 if ((salt->length == -1) && (salt->data == NULL)) { if (ret = krb5_principal2salt(context, request->client, @@ -305,8 +301,11 @@ krb5_error_code pa_sam(krb5_context context, salt = NULL; #endif - ret = krb5_string_to_key(context, &eblock, as_key, - &response_data, salt); + /* XXX the server uses this fixed enctype, so we will, too. */ + + ret = krb5_c_string_to_key(context, ENCTYPE_DES_CBC_MD5, + &response_data, salt, as_key); + if (defsalt.length) krb5_xfree(defsalt.data); diff --git a/src/lib/krb5/krb/rd_cred.c b/src/lib/krb5/krb/rd_cred.c index 7537ac990a..86c5ccf727 100644 --- a/src/lib/krb5/krb/rd_cred.c +++ b/src/lib/krb5/krb/rd_cred.c @@ -19,7 +19,6 @@ decrypt_credencdata(context, pcred, pkeyblock, pcredenc) krb5_cred_enc_part * pcredenc; { krb5_cred_enc_part * ppart; - krb5_encrypt_block eblock; krb5_error_code retval; krb5_data scratch; @@ -28,28 +27,9 @@ decrypt_credencdata(context, pcred, pkeyblock, pcredenc) return ENOMEM; if (pkeyblock != NULL) { - if (!valid_enctype(pcred->enc_part.enctype)) { - free(scratch.data); - return KRB5_PROG_ETYPE_NOSUPP; - } - - /* put together an eblock for this decryption */ - krb5_use_enctype(context, &eblock, pcred->enc_part.enctype); - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, pkeyblock))) - goto cleanup; - - /* call the decryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer) pcred->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { - (void)krb5_finish_key(context, &eblock); - goto cleanup; - } - - if ((retval = krb5_finish_key(context, &eblock))) + if ((retval = krb5_c_decrypt(context, pkeyblock, + KRB5_KEYUSAGE_KRB_CRED_ENCPART, 0, + &pcred->enc_part, &scratch))) goto cleanup; } else { memcpy(scratch.data, pcred->enc_part.ciphertext.data, scratch.length); diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c index c4e1ed0b6f..f08975f221 100644 --- a/src/lib/krb5/krb/rd_priv.c +++ b/src/lib/krb5/krb/rd_priv.c @@ -66,8 +66,9 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr, krb5_error_code retval; krb5_priv * privmsg; krb5_data scratch; - krb5_encrypt_block eblock; krb5_priv_enc_part * privmsg_enc_part; + size_t blocksize; + krb5_data ivdata; if (!krb5_is_krb_priv(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; @@ -76,43 +77,33 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr, if ((retval = decode_krb5_priv(inbuf, &privmsg))) return retval; - if (!valid_enctype(privmsg->enc_part.enctype)) { - retval = KRB5_PROG_ETYPE_NOSUPP; - goto cleanup_privmsg; + if (i_vector) { + if ((retval = krb5_c_block_size(context, keyblock->enctype, + &blocksize))) + goto cleanup_privmsg; + + ivdata.length = blocksize; + ivdata.data = i_vector; } - - /* put together an eblock for this decryption */ - krb5_use_enctype(context, &eblock, privmsg->enc_part.enctype); + scratch.length = privmsg->enc_part.ciphertext.length; - if (!(scratch.data = malloc(scratch.length))) { retval = ENOMEM; goto cleanup_privmsg; } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, keyblock))) + if ((retval = krb5_c_decrypt(context, keyblock, + KRB5_KEYUSAGE_KRB_PRIV_ENCPART, + i_vector?&ivdata:0, + &privmsg->enc_part, &scratch))) goto cleanup_scratch; - /* call the decryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer) privmsg->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, i_vector))) { - krb5_finish_key(context, &eblock); - goto cleanup_scratch; - } - /* if i_vector is set, put last block into the i_vector */ if (i_vector) memcpy(i_vector, privmsg->enc_part.ciphertext.data + - (privmsg->enc_part.ciphertext.length - - eblock.crypto_entry->block_length), - eblock.crypto_entry->block_length); - - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup_scratch; + (privmsg->enc_part.ciphertext.length - blocksize), + blocksize); /* now decode the decrypted stuff */ if ((retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part))) diff --git a/src/lib/krb5/krb/rd_rep.c b/src/lib/krb5/krb/rd_rep.c index d4d559d14a..411a61ddbb 100644 --- a/src/lib/krb5/krb/rd_rep.c +++ b/src/lib/krb5/krb/rd_rep.c @@ -47,7 +47,6 @@ krb5_rd_rep(context, auth_context, inbuf, repl) { krb5_error_code retval; krb5_ap_rep * reply; - krb5_encrypt_block eblock; krb5_data scratch; if (!krb5_is_ap_rep(inbuf)) @@ -60,35 +59,15 @@ krb5_rd_rep(context, auth_context, inbuf, repl) /* put together an eblock for this encryption */ - if (!valid_enctype(reply->enc_part.enctype)) { - krb5_free_ap_rep(context, reply); - return KRB5_PROG_ETYPE_NOSUPP; - } - krb5_use_enctype(context, &eblock, reply->enc_part.enctype); - scratch.length = reply->enc_part.ciphertext.length; if (!(scratch.data = malloc(scratch.length))) { krb5_free_ap_rep(context, reply); return(ENOMEM); } - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, - auth_context->keyblock))) { - goto errout; - } - - /* call the encryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer) reply->enc_part.ciphertext.data, - (krb5_pointer) scratch.data, - scratch.length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); - goto errout; - } - - /* finished with the top-level encoding of the ap_rep */ - if ((retval = krb5_finish_key(context, &eblock))) + if ((retval = krb5_c_decrypt(context, auth_context->keyblock, + KRB5_KEYUSAGE_AP_REP_ENCPART, 0, + &reply->enc_part, &scratch))) goto clean_scratch; /* now decode the decrypted stuff */ diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index 0c62c19df1..cdbdc81dff 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -57,7 +57,8 @@ */ static krb5_error_code decrypt_authenticator - PROTOTYPE((krb5_context, const krb5_ap_req *, krb5_authenticator **)); + PROTOTYPE((krb5_context, const krb5_ap_req *, krb5_authenticator **, + int)); #define in_clock_skew(date) (labs((date)-currenttime) < context->clockskew) @@ -119,8 +120,12 @@ krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab, return retval; } + /* XXX this is an evil hack. check_valid_flag is set iff the call + is not from inside the kdc. we can use this to determine which + key usage to use */ if ((retval = decrypt_authenticator(context, req, - &((*auth_context)->authentp)))) + &((*auth_context)->authentp), + check_valid_flag))) goto cleanup; if (!krb5_principal_compare(context, (*auth_context)->authentp->client, @@ -243,14 +248,66 @@ krb5_rd_req_decoded_opt(context, auth_context, req, server, keytab, } } + /* check if the various etypes are permitted */ + + if ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_PERMIT_ALL) { + /* no etype check needed */; + } else if ((*auth_context)->permitted_etypes == NULL) { + /* check against the default set */ + if ((!krb5_is_permitted_enctype(context, + req->ticket->enc_part.enctype)) || + (!krb5_is_permitted_enctype(context, + req->ticket->enc_part2->session->enctype)) || + (((*auth_context)->authentp->subkey) && + !krb5_is_permitted_enctype(context, + (*auth_context)->authentp->subkey->enctype))) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + } else { + /* check against the set in the auth_context */ + int i; + + for (i=0; (*auth_context)->permitted_etypes[i]; i++) + if ((*auth_context)->permitted_etypes[i] == + req->ticket->enc_part.enctype) + break; + if (!(*auth_context)->permitted_etypes[i]) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + + for (i=0; (*auth_context)->permitted_etypes[i]; i++) + if ((*auth_context)->permitted_etypes[i] == + req->ticket->enc_part2->session->enctype) + break; + if (!(*auth_context)->permitted_etypes[i]) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + + if ((*auth_context)->authentp->subkey) { + for (i=0; (*auth_context)->permitted_etypes[i]; i++) + if ((*auth_context)->permitted_etypes[i] == + (*auth_context)->authentp->subkey->enctype) + break; + if (!(*auth_context)->permitted_etypes[i]) { + retval = KRB5_NOPERM_ETYPE; + goto cleanup; + } + } + } + (*auth_context)->remote_seq_number = (*auth_context)->authentp->seq_number; if ((*auth_context)->authentp->subkey) { if ((retval = krb5_copy_keyblock(context, (*auth_context)->authentp->subkey, &((*auth_context)->remote_subkey)))) goto cleanup; - } else + } else { (*auth_context)->remote_subkey = 0; + } + if ((retval = krb5_copy_keyblock(context, req->ticket->enc_part2->session, &((*auth_context)->keyblock)))) goto cleanup; @@ -322,52 +379,34 @@ krb5_rd_req_decoded_anyflag(context, auth_context, req, server, keytab, } static krb5_error_code -decrypt_authenticator(context, request, authpp) +decrypt_authenticator(context, request, authpp, is_ap_req) krb5_context context; const krb5_ap_req *request; krb5_authenticator **authpp; + int is_ap_req; { krb5_authenticator *local_auth; krb5_error_code retval; - krb5_encrypt_block eblock; krb5_data scratch; krb5_keyblock *sesskey; sesskey = request->ticket->enc_part2->session; - if (!valid_enctype(sesskey->enctype)) - return KRB5_PROG_ETYPE_NOSUPP; - - /* put together an eblock for this encryption */ - - krb5_use_enctype(context, &eblock, request->authenticator.enctype); - scratch.length = request->authenticator.ciphertext.length; if (!(scratch.data = malloc(scratch.length))) return(ENOMEM); - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, sesskey))) { + if ((retval = krb5_c_decrypt(context, sesskey, + is_ap_req?KRB5_KEYUSAGE_AP_REQ_AUTH: + KRB5_KEYUSAGE_TGS_REQ_AUTH, 0, + &request->authenticator, &scratch))) { free(scratch.data); return(retval); } - /* call the encryption routine */ - if ((retval = krb5_decrypt(context, - (krb5_pointer)request->authenticator.ciphertext.data, - (krb5_pointer)scratch.data, - scratch.length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); - free(scratch.data); - return retval; - } #define clean_scratch() {memset(scratch.data, 0, scratch.length); \ free(scratch.data);} - if ((retval = krb5_finish_key(context, &eblock))) { - clean_scratch(); - return retval; - } /* now decode the decrypted stuff */ if (!(retval = decode_krb5_authenticator(&scratch, &local_auth))) { *authpp = local_auth; diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c index 5f0fcd6ca6..1c5aca21ca 100644 --- a/src/lib/krb5/krb/rd_safe.c +++ b/src/lib/krb5/krb/rd_safe.c @@ -59,6 +59,7 @@ krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr, krb5_checksum our_cksum, *his_cksum; krb5_octet zero_octet = 0; krb5_data *scratch; + krb5_boolean valid; if (!krb5_is_krb_safe(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; @@ -122,14 +123,14 @@ krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr, message->checksum = his_cksum; - retval = krb5_verify_checksum(context, his_cksum->checksum_type, - his_cksum, scratch->data, scratch->length, - (krb5_pointer) keyblock->contents, - keyblock->length); + retval = krb5_c_verify_checksum(context, keyblock, + KRB5_KEYUSAGE_KRB_SAFE_CKSUM, + scratch, his_cksum, &valid); + (void) memset((char *)scratch->data, 0, scratch->length); krb5_free_data(context, scratch); - if (retval) { + if (!valid) { retval = KRB5KRB_AP_ERR_MODIFIED; goto cleanup; } diff --git a/src/lib/krb5/krb/send_tgs.c b/src/lib/krb5/krb/send_tgs.c index b06ef2bfc7..19de14e1aa 100644 --- a/src/lib/krb5/krb/send_tgs.c +++ b/src/lib/krb5/krb/send_tgs.c @@ -55,21 +55,15 @@ krb5_send_tgs_basic(context, in_data, in_cred, outbuf) krb5_checksum checksum; krb5_authenticator authent; krb5_ap_req request; - krb5_encrypt_block eblock; krb5_data * scratch; krb5_data * toutbuf; /* Generate checksum */ - checksum.length = krb5_checksum_size(context, context->kdc_req_sumtype); - if ((checksum.contents = (krb5_octet *) malloc(checksum.length)) == NULL) - return(ENOMEM); - - if ((retval = krb5_calculate_checksum(context, context->kdc_req_sumtype, - in_data->data, in_data->length, - (krb5_pointer) in_cred->keyblock.contents, - in_cred->keyblock.length, - &checksum))) { - free(checksum.contents); + if ((retval = krb5_c_make_checksum(context, context->kdc_req_sumtype, + &in_cred->keyblock, + KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM, + in_data, &checksum))) { + free(checksum.contents); return(retval); } @@ -102,43 +96,11 @@ krb5_send_tgs_basic(context, in_data, in_cred, outbuf) /* Cleanup scratch and scratch data */ goto cleanup_data; - /* put together an eblock for this encryption */ - krb5_use_enctype(context, &eblock, in_cred->keyblock.enctype); - request.authenticator.enctype = in_cred->keyblock.enctype; - request.authenticator.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - request.authenticator.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_free_ticket(context, request.ticket); - retval = ENOMEM; - goto cleanup_scratch; - } - memset(scratch->data + scratch->length, 0, - request.authenticator.ciphertext.length - scratch->length); - - if (!(request.authenticator.ciphertext.data = - malloc(request.authenticator.ciphertext.length))) { - retval = ENOMEM; - goto cleanup_ticket; - } - - /* do any necessary key pre-processing */ - if ((retval = krb5_process_key(context, &eblock, &(in_cred)->keyblock))) - goto cleanup; - /* call the encryption routine */ - if ((retval=krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer)request.authenticator.ciphertext.data, - scratch->length, &eblock, 0))) { - krb5_finish_key(context, &eblock); - goto cleanup; - } - - if ((retval = krb5_finish_key(context, &eblock))) - goto cleanup; + if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock, + KRB5_KEYUSAGE_TGS_REQ_AUTH, + scratch, &request.authenticator))) + goto cleanup_ticket; retval = encode_krb5_ap_req(&request, &toutbuf); *outbuf = *toutbuf; @@ -185,6 +147,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, ktypes, sname, addrs, krb5_timestamp time_now; krb5_pa_data **combined_padata; krb5_pa_data ap_req_padata; + size_t enclen; /* * in_creds MUST be a valid credential NOT just a partially filled in @@ -212,50 +175,21 @@ krb5_send_tgs(context, kdcoptions, timestruct, ktypes, sname, addrs, if (authorization_data) { /* need to encrypt it in the request */ - krb5_encrypt_block eblock; if ((retval = encode_krb5_authdata((const krb5_authdata**)authorization_data, &scratch))) return(retval); - krb5_use_enctype(context, &eblock, in_cred->keyblock.enctype); - tgsreq.authorization_data.enctype = in_cred->keyblock.enctype; - tgsreq.authorization_data.kvno = 0; /* ticket session key has */ - /* no version */ - tgsreq.authorization_data.ciphertext.length = - krb5_encrypt_size(scratch->length, eblock.crypto_entry); - /* add padding area, and zero it */ - if (!(scratch->data = realloc(scratch->data, - tgsreq.authorization_data.ciphertext.length))) { - /* may destroy scratch->data */ - krb5_xfree(scratch); - return ENOMEM; - } - memset(scratch->data + scratch->length, 0, - tgsreq.authorization_data.ciphertext.length - scratch->length); - if (!(tgsreq.authorization_data.ciphertext.data = - malloc(tgsreq.authorization_data.ciphertext.length))) { - krb5_free_data(context, scratch); - return ENOMEM; - } - if ((retval = krb5_process_key(context, &eblock, - &in_cred->keyblock))) { - krb5_free_data(context, scratch); - return retval; - } - /* call the encryption routine */ - if ((retval = krb5_encrypt(context, (krb5_pointer) scratch->data, - (krb5_pointer) tgsreq.authorization_data.ciphertext.data, - scratch->length, &eblock, 0))) { - (void) krb5_finish_key(context, &eblock); + + if ((retval = krb5_encrypt_helper(context, &in_cred->keyblock, + KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY, + scratch, + &tgsreq.authorization_data))) { krb5_xfree(tgsreq.authorization_data.ciphertext.data); krb5_free_data(context, scratch); return retval; - } - krb5_free_data(context, scratch); - if ((retval = krb5_finish_key(context, &eblock))) { - krb5_xfree(tgsreq.authorization_data.ciphertext.data); - return retval; } + + krb5_free_data(context, scratch); } /* Get the encryption types list */ diff --git a/src/lib/krb5/krb/ser_actx.c b/src/lib/krb5/krb/ser_actx.c index 5705b711fc..42b9bfeb64 100644 --- a/src/lib/krb5/krb/ser_actx.c +++ b/src/lib/krb5/krb/ser_actx.c @@ -56,7 +56,6 @@ krb5_error_code krb5_ser_authdata_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_address_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_authenticator_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_checksum_init KRB5_PROTOTYPE((krb5_context)); -krb5_error_code krb5_ser_encrypt_block_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_keyblock_init KRB5_PROTOTYPE((krb5_context)); krb5_error_code krb5_ser_principal_init KRB5_PROTOTYPE((krb5_context)); @@ -95,17 +94,20 @@ krb5_auth_context_size(kcontext, arg, sizep) */ kret = EINVAL; if ((auth_context = (krb5_auth_context) arg)) { - required = sizeof(krb5_int32)*8; - kret = 0; + /* Calculate size required by i_vector - ptooey */ - if (auth_context->i_vector && auth_context->keyblock) - required += (size_t) - krb5_enctype_array[auth_context->keyblock->enctype]-> - system->block_length; + if (auth_context->i_vector && auth_context->keyblock) { + kret = krb5_c_block_size(kcontext, auth_context->keyblock->enctype, + &required); + } else { + required = 0; + } + + required += sizeof(krb5_int32)*8; /* Calculate size required by remote_addr, if appropriate */ - if (auth_context->remote_addr) { + if (!kret && auth_context->remote_addr) { kret = krb5_size_opaque(kcontext, KV5M_ADDRESS, (krb5_pointer) auth_context->remote_addr, @@ -226,18 +228,25 @@ krb5_auth_context_externalize(kcontext, arg, buffer, lenremain) (void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype, &bp, &remain); + kret = 0; + /* Now figure out the number of bytes for i_vector and write it */ - obuf = (!auth_context->i_vector) ? 0 : (krb5_int32) - krb5_enctype_array[auth_context->keyblock->enctype]-> - system->block_length; - (void) krb5_ser_pack_int32(obuf, &bp, &remain); + if (auth_context->i_vector) { + kret = krb5_c_block_size(kcontext, + auth_context->keyblock->enctype, + &obuf); + } else { + obuf = 0; + } + + if (!kret) + (void) krb5_ser_pack_int32(obuf, &bp, &remain); /* Now copy i_vector */ - if (auth_context->i_vector) + if (!kret && auth_context->i_vector) (void) krb5_ser_pack_bytes(auth_context->i_vector, (size_t) obuf, &bp, &remain); - kret = 0; /* Now handle remote_addr, if appropriate */ if (!kret && auth_context->remote_addr) { @@ -556,8 +565,6 @@ krb5_ser_auth_context_init(kcontext) if (!kret) kret = krb5_ser_checksum_init(kcontext); if (!kret) - kret = krb5_ser_encrypt_block_init(kcontext); - if (!kret) kret = krb5_ser_keyblock_init(kcontext); if (!kret) kret = krb5_ser_principal_init(kcontext); diff --git a/src/lib/krb5/krb/ser_eblk.c b/src/lib/krb5/krb/ser_eblk.c index 20b3da6726..04e21faab5 100644 --- a/src/lib/krb5/krb/ser_eblk.c +++ b/src/lib/krb5/krb/ser_eblk.c @@ -22,6 +22,8 @@ * */ +#if 0 /* i don't believe this is used anywhere --marc */ + /* * ser_eblk.c - Serialize a krb5_encblock structure. */ @@ -249,3 +251,5 @@ krb5_ser_encrypt_block_init(kcontext) { return(krb5_register_serializer(kcontext, &krb5_encrypt_block_ser_entry)); } + +#endif diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c index 6346aef234..b30638d4fb 100644 --- a/src/lib/krb5/krb/str_conv.c +++ b/src/lib/krb5/krb/str_conv.c @@ -31,17 +31,13 @@ * * String decoding: * ---------------- - * krb5_string_to_enctype() - Convert string to krb5_enctype. * krb5_string_to_salttype() - Convert string to salttype (krb5_int32) - * krb5_string_to_cksumtype() - Convert string to krb5_cksumtype; * krb5_string_to_timestamp() - Convert string to krb5_timestamp. * krb5_string_to_deltat() - Convert string to krb5_deltat. * * String encoding: * ---------------- - * krb5_enctype_to_string() - Convert krb5_enctype to string. * krb5_salttype_to_string() - Convert salttype (krb5_int32) to string. - * krb5_cksumtype_to_string() - Convert krb5_cksumtype to string. * krb5_timestamp_to_string() - Convert krb5_timestamp to string. * krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string * krb5_deltat_to_string() - Convert krb5_deltat to string. @@ -52,24 +48,12 @@ /* * Local data structures. */ -struct enctype_lookup_entry { - krb5_enctype ktt_enctype; /* Keytype */ - const char * ktt_specifier; /* How to recognize it */ - const char * ktt_output; /* How to spit it out */ -}; - struct salttype_lookup_entry { krb5_int32 stt_enctype; /* Salt type */ const char * stt_specifier; /* How to recognize it */ const char * stt_output; /* How to spit it out */ }; -struct cksumtype_lookup_entry { - krb5_cksumtype cst_cksumtype; /* Checksum type */ - const char * cst_specifier; /* How to recognize it */ - const char * cst_output; /* How to spit it out */ -}; - struct deltat_match_entry { const char * dt_scan_format; /* sscanf format */ int dt_nmatch; /* Number to match */ @@ -83,21 +67,6 @@ struct deltat_match_entry { * Local strings */ -/* Keytype strings */ -static const char enctype_des_in[] = "des"; -static const char enctype_null_in[] = "null"; -static const char enctype_descbccrc_in[] = "des-cbc-crc"; -static const char enctype_descbcmd4_in[] = "des-cbc-md4"; -static const char enctype_descbcmd5_in[] = "des-cbc-md5"; -static const char enctype_des3cbcsha_in[] = "des3-cbc-sha"; -static const char enctype_descbcraw_in[] = "des-cbc-raw"; -static const char enctype_null_out[] = "Null"; -static const char enctype_descbccrc_out[] = "DES cbc mode with CRC-32"; -static const char enctype_descbcmd4_out[] = "DES cbc mode with RSA-MD4"; -static const char enctype_descbcmd5_out[] = "DES cbc mode with RSA-MD5"; -static const char enctype_des3cbcsha_out[] = "DES-3 cbc mode with NIST-SHA"; -static const char enctype_descbcraw_out[] = "DES cbc mode raw"; - /* Salttype strings */ static const char stype_v5_in[] = "normal"; static const char stype_v4_in[] = "v4"; @@ -112,24 +81,6 @@ static const char stype_olrealm_out[] = "Version 5 - Realm Only"; static const char stype_special_out[] = "Special"; static const char stype_afs3_out[] = "AFS version 3"; -/* Checksum type strings */ -static const char cstype_crc32_in[] = "crc32"; -static const char cstype_md4_in[] = "md4"; -static const char cstype_md4des_in[] = "md4-des"; -static const char cstype_descbc_in[] = "des-cbc"; -static const char cstype_md5_in[] = "md5"; -static const char cstype_md5des_in[] = "md5-des"; -static const char cstype_sha_in[] = "sha"; -static const char cstype_hmacsha_in[] = "hmac-sha"; -static const char cstype_crc32_out[] = "CRC-32"; -static const char cstype_md4_out[] = "RSA-MD4"; -static const char cstype_md4des_out[] = "RSA-MD4 with DES cbc mode"; -static const char cstype_descbc_out[] = "DES cbc mode"; -static const char cstype_md5_out[] = "RSA-MD5"; -static const char cstype_md5des_out[] = "RSA-MD5 with DES cbc mode"; -static const char cstype_sha_out[] = "NIST-SHA"; -static const char cstype_hmacsha_out[] = "HMAC-SHA"; - /* Absolute time strings */ static const char atime_full_digits[] = "%y%m%d%H%M%S"; static const char atime_full_digits_d[] = "%y.%m.%d.%H.%M.%S"; @@ -184,20 +135,6 @@ static const char dt_output_hms[] = "%d:%02d:%02d"; * Lookup tables. */ -static const struct enctype_lookup_entry enctype_table[] = { -/* krb5_enctype input specifier output string */ -/*------------- ----------------------- ------------------------*/ -{ ENCTYPE_NULL, enctype_null_in, enctype_null_out }, -{ ENCTYPE_DES_CBC_MD5, enctype_des_in, enctype_descbcmd5_out }, -{ ENCTYPE_DES_CBC_CRC, enctype_descbccrc_in, enctype_descbccrc_out }, -{ ENCTYPE_DES_CBC_MD4, enctype_descbcmd4_in, enctype_descbcmd4_out }, -{ ENCTYPE_DES_CBC_MD5, enctype_descbcmd5_in, enctype_descbcmd5_out }, -{ ENCTYPE_DES3_CBC_SHA, enctype_des3cbcsha_in, enctype_des3cbcsha_out }, -{ ENCTYPE_DES_CBC_RAW, enctype_descbcraw_in, enctype_descbcraw_out } -}; -static const int enctype_table_nents = sizeof(enctype_table)/ - sizeof(enctype_table[0]); - static const struct salttype_lookup_entry salttype_table[] = { /* salt type input specifier output string */ /*----------------------------- ----------------------- ------------------*/ @@ -211,21 +148,6 @@ static const struct salttype_lookup_entry salttype_table[] = { static const int salttype_table_nents = sizeof(salttype_table)/ sizeof(salttype_table[0]); -static const struct cksumtype_lookup_entry cksumtype_table[] = { -/* krb5_cksumtype input specifier output string */ -/*----------------------- --------------------- ------------------------*/ -{ CKSUMTYPE_CRC32, cstype_crc32_in, cstype_crc32_out }, -{ CKSUMTYPE_RSA_MD4, cstype_md4_in, cstype_md4_out }, -{ CKSUMTYPE_RSA_MD4_DES, cstype_md4des_in, cstype_md4des_out }, -{ CKSUMTYPE_DESCBC, cstype_descbc_in, cstype_descbc_out }, -{ CKSUMTYPE_RSA_MD5, cstype_md5_in, cstype_md5_out }, -{ CKSUMTYPE_RSA_MD5_DES, cstype_md5des_in, cstype_md5des_out }, -{ CKSUMTYPE_NIST_SHA, cstype_sha_in, cstype_sha_out }, -{ CKSUMTYPE_HMAC_SHA, cstype_hmacsha_in, cstype_hmacsha_out } -}; -static const int cksumtype_table_nents = sizeof(cksumtype_table)/ - sizeof(cksumtype_table[0]); - static const char * const atime_format_table[] = { atime_full_digits_Y, /* yyyymmddhhmmss */ atime_full_digits_Yd, /* yyyy.mm.dd.hh.mm.ss */ @@ -403,30 +325,6 @@ strptime(buf, format, tm) } #endif /* HAVE_STRPTIME */ -/* - * String to internal datatype routines. - * - * These routines return 0 for success, EINVAL for invalid entry. - */ -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_string_to_enctype(string, enctypep) - char FAR * string; - krb5_enctype FAR * enctypep; -{ - int i; - int found; - - found = 0; - for (i=0; i<enctype_table_nents; i++) { - if (!strcasecmp(string, enctype_table[i].ktt_specifier)) { - found = 1; - *enctypep = enctype_table[i].ktt_enctype; - break; - } - } - return((found) ? 0 : EINVAL); -} - KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_salttype(string, salttypep) char FAR * string; @@ -447,25 +345,6 @@ krb5_string_to_salttype(string, salttypep) } KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_string_to_cksumtype(string, cksumtypep) - char FAR * string; - krb5_cksumtype FAR * cksumtypep; -{ - int i; - int found; - - found = 0; - for (i=0; i<cksumtype_table_nents; i++) { - if (!strcasecmp(string, cksumtype_table[i].cst_specifier)) { - found = 1; - *cksumtypep = cksumtype_table[i].cst_cksumtype; - break; - } - } - return((found) ? 0 : EINVAL); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_timestamp(string, timestampp) char FAR * string; krb5_timestamp FAR * timestampp; @@ -545,33 +424,6 @@ krb5_string_to_deltat(string, deltatp) * if the supplied buffer/length will not contain the output. */ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_enctype_to_string(enctype, buffer, buflen) - krb5_enctype enctype; - char FAR * buffer; - size_t buflen; -{ - int i; - const char *out; - - out = (char *) NULL; - for (i=0; i<enctype_table_nents; i++) { - if (enctype == enctype_table[i].ktt_enctype) { - out = enctype_table[i].ktt_output; - break; - } - } - if (out) { - if (buflen > strlen(out)) - strcpy(buffer, out); - else - out = (char *) NULL; - return((out) ? 0 : ENOMEM); - } - else - return(EINVAL); -} - -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_salttype_to_string(salttype, buffer, buflen) krb5_int32 salttype; char FAR * buffer; diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c index bb8ea349b0..85a8465030 100644 --- a/src/lib/krb5/krb/vfy_increds.c +++ b/src/lib/krb5/krb/vfy_increds.c @@ -68,12 +68,7 @@ krb5_verify_init_creds(krb5_context context, krb5_creds in_creds, *out_creds; krb5_auth_context authcon; krb5_data ap_req; - int keytab_key_exists, rd_req_succeeds, nofail; - keytab_key_exists = 0; - rd_req_succeeds = 0; - nofail = 0; - /* KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN */ server = NULL; @@ -103,11 +98,31 @@ krb5_verify_init_creds(krb5_context context, goto cleanup; } - if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte)) - goto cleanup; + if (ret = krb5_kt_get_entry(context, keytab, server, 0, 0, &kte)) { + /* this means there is no keying material. This is ok, as long as + it is not prohibited by the configuration */ + + krb5_error_code ret2; + int nofail; + + if (options && + (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) { + if (options->ap_req_nofail) + goto cleanup; + } else if ((ret2 = krb5_appdefault_boolean(context, + &creds->client->realm, + "verify_ap_req_nofail", + &nofail)) + == 0) { + if (nofail) + goto cleanup; + } + + ret = 0; + goto cleanup; + } krb5_kt_free_entry(context, &kte); - keytab_key_exists = 1; /* If the creds are for the server principal, we're set, just do a mk_req. Otherwise, do a get_credentials first. */ @@ -166,61 +181,37 @@ krb5_verify_init_creds(krb5_context context, NULL, NULL)) goto cleanup; - rd_req_succeeds = 1; - -cleanup: - /* I could test the error case first, but then there would be a - chance that the verification would succeed when there was - actually a significant failure (some transient condition could - make rd_req fail, and this would not be a problem if nofail was - not set */ - - if (!keytab_key_exists) { - krb5_error_code ret2; - - if (options && - (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) - nofail = options->ap_req_nofail; - else if ((ret2 = krb5_appdefault_boolean(context, &creds->client->realm, - "verify_ap_req_nofail", - &nofail)) - == 0) - ; - else - nofail = 0; - } - - if ((keytab_key_exists && rd_req_succeeds) || - (!keytab_key_exists && !nofail)) { - ret = 0; + /* if we get this far, then the verification succeeded. We can + still fail if the library stuff here fails, but that's it */ - if (ccache_arg && ccache) { - if (*ccache_arg == NULL) { - krb5_ccache retcc; + if (ccache_arg && ccache) { + if (*ccache_arg == NULL) { + krb5_ccache retcc; - retcc = NULL; + retcc = NULL; - if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) || - (ret = krb5_cc_initialize(context, retcc, creds->client)) || - (ret = krb5_cc_copy_creds_except(context, ccache, retcc, - creds->server))) { + if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) || + (ret = krb5_cc_initialize(context, retcc, creds->client)) || + (ret = krb5_cc_copy_creds_except(context, ccache, retcc, + creds->server))) { if (retcc) - krb5_cc_destroy(context, retcc); - } else { + krb5_cc_destroy(context, retcc); + } else { *ccache_arg = retcc; - } - } else { - /* if this returns an error, then that's the return - from this function */ - ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg, - server); - } - } + } + } else { + ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg, + server); + } } - if (!server_arg) + /* if any of the above paths returned an errors, then ret is set + accordingly. either that, or it's zero, which is fine, too */ + +cleanup: + if (!server_arg && server) krb5_free_principal(context, server); - if (!keytab_arg) + if (!keytab_arg && keytab) krb5_kt_close(context, keytab); if (ccache) krb5_cc_destroy(context, ccache); @@ -233,6 +224,3 @@ cleanup: return(ret); } - - - diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 0ee4a7192f..84f0dec670 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,16 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * c_ustime.c, localaddr.c: moved here from lib/crypto + + * ktdefname.c (krb5_kt_default_name): there is code in the tree + (notably, the admin server code) which uses globals to set the + keytab which will be used by gssapi. this is gross, and we need a + better answer. However, even that didn't work if there was an env + var or krb5.conf variable, since those override krb5_defkeyname. + Add a new global, krb5_overridekeyname, which really does override + all the other keytab locators. While I'm at it, make the buffer + overflow checks sane. + Fri Sep 25 22:32:16 1998 Theodore Y. Ts'o <tytso@mit.edu> * ccdefname.c: We shouldn't try to use the CCache API on Unix diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in index 9e132dbc86..56edfac36b 100644 --- a/src/lib/krb5/os/Makefile.in +++ b/src/lib/krb5/os/Makefile.in @@ -12,6 +12,7 @@ PROG_RPATH=$(KRB5_LIBDIR) STLIBOBJS= \ an_to_ln.o \ + c_ustime.o \ def_realm.o \ DNR.o \ ccdefname.o \ @@ -54,6 +55,7 @@ STLIBOBJS= \ OBJS= \ an_to_ln.$(OBJEXT) \ + c_ustime.$(OBJEXT) \ def_realm.$(OBJEXT) \ DNR.$(OBJEXT) \ ccdefname.$(OBJEXT) \ @@ -96,6 +98,7 @@ OBJS= \ SRCS= \ $(srcdir)/an_to_ln.c \ + $(srcdir)/c_ustime.c \ $(srcdir)/def_realm.c \ $(srcdir)/DNR.c \ $(srcdir)/ccdefname.c \ diff --git a/src/lib/crypto/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c index e790acc956..350c1aa5c7 100644 --- a/src/lib/crypto/os/c_ustime.c +++ b/src/lib/krb5/os/c_ustime.c @@ -27,7 +27,7 @@ #define NEED_SOCKETS #include "k5-int.h" -#ifdef macintosh +#ifdef _MACINTOSH /* We're a Macintosh -- do Mac time things. */ diff --git a/src/lib/krb5/os/ktdefname.c b/src/lib/krb5/os/ktdefname.c index c645635ab0..0493244f61 100644 --- a/src/lib/krb5/os/ktdefname.c +++ b/src/lib/krb5/os/ktdefname.c @@ -30,6 +30,9 @@ extern char *krb5_defkeyname; +/* this is a an exceedinly gross thing. */ +char *krb5_overridekeyname = NULL; + KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_default_name(context, name, namesize) krb5_context context; @@ -40,19 +43,24 @@ krb5_kt_default_name(context, name, namesize) krb5_error_code code; char *retval; - if ((context->profile_secure == FALSE) && + if (krb5_overridekeyname) { + if ((size_t) namesize < (strlen(krb5_overridekeyname)+1)) + return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, krb5_overridekeyname); + } else if ((context->profile_secure == FALSE) && (cp = getenv("KRB5_KTNAME"))) { - strncpy(name, cp, namesize); - if (strlen(cp) >= (size_t) namesize) + if ((size_t) namesize < (strlen(cp)+1)) return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, cp); } else if (((code = profile_get_string(context->profile, "libdefaults", "default_keytab_name", NULL, NULL, &retval)) == 0) && retval) { - strncpy(name, retval, namesize); - if ((size_t) namesize < strlen(retval)) + if ((size_t) namesize < (strlen(retval)+1)) return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, retval); + free(retval); } else { #if defined (_MSDOS) || defined(_WIN32) { @@ -66,9 +74,9 @@ krb5_kt_default_name(context, name, namesize) sprintf(name, krb5_defkeyname, defname); } #else - strncpy(name, krb5_defkeyname, namesize); - if ((size_t) namesize < strlen(krb5_defkeyname)) + if ((size_t) namesize < (strlen(krb5_defkeyname)+1)) return KRB5_CONFIG_NOTENUFSPACE; + strcpy(name, krb5_defkeyname); #endif } return 0; diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c index cb204b597e..9f33e5d98b 100644 --- a/src/lib/krb5/os/localaddr.c +++ b/src/lib/krb5/os/localaddr.c @@ -20,16 +20,329 @@ * this software for any purpose. It is provided "as is" without express * or implied warranty. * - * Just a stub that calls krb5_crypto_os_localaddr(). * + * Return the protocol addresses supported by this host. + * + * XNS support is untested, but "Should just work". */ +#define NEED_SOCKETS #include "k5-int.h" +#if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS) && !defined(_WIN32) + +/* needed for solaris, harmless elsewhere... */ +#define BSD_COMP +#include <sys/ioctl.h> +#include <sys/time.h> +#include <errno.h> + +/* + * The SIOCGIF* ioctls require a socket. + * It doesn't matter *what* kind of socket they use, but it has to be + * a socket. + * + * Of course, you can't just ask the kernel for a socket of arbitrary + * type; you have to ask for one with a valid type. + * + */ +#ifdef HAVE_NETINET_IN_H + +#include <netinet/in.h> + +#ifndef USE_AF +#define USE_AF AF_INET +#define USE_TYPE SOCK_DGRAM +#define USE_PROTO 0 +#endif + +#endif + +#ifdef KRB5_USE_NS + +#include <netns/ns.h> + +#ifndef USE_AF +#define USE_AF AF_NS +#define USE_TYPE SOCK_DGRAM +#define USE_PROTO 0 /* guess */ +#endif + +#endif +/* + * Add more address families here. + */ + +/* + * BSD 4.4 defines the size of an ifreq to be + * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len + * However, under earlier systems, sa_len isn't present, so the size is + * just sizeof(struct ifreq) + */ +#ifdef HAVE_SA_LEN +#ifndef max +#define max(a,b) ((a) > (b) ? (a) : (b)) +#endif +#define ifreq_size(i) max(sizeof(struct ifreq),\ + sizeof((i).ifr_name)+(i).ifr_addr.sa_len) +#else +#define ifreq_size(i) sizeof(struct ifreq) +#endif /* HAVE_SA_LEN*/ + + + +extern int errno; + +/* + * Return all the protocol addresses of this host. + * + * We could kludge up something to return all addresses, assuming that + * they're valid kerberos protocol addresses, but we wouldn't know the + * real size of the sockaddr or know which part of it was actually the + * host part. + * + * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's. + */ + KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_os_localaddr(context, addr) krb5_context context; krb5_address FAR * FAR * FAR *addr; { - return krb5_crypto_os_localaddr(addr); + struct ifreq *ifr, ifreq; + struct ifconf ifc; + int s, code, n, i; + char buf[1024]; + krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ]; + int n_found; + int mem_err = 0; + + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + s = socket (USE_AF, USE_TYPE, USE_PROTO); + if (s < 0) + return errno; + + code = ioctl (s, SIOCGIFCONF, (char *)&ifc); + if (code < 0) { + int retval = errno; + closesocket (s); + return retval; + } + n = ifc.ifc_len; + +n_found = 0; + for (i = 0; i < n; i+= ifreq_size(*ifr) ) { + krb5_address *address; + ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i); + + strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); + if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) + continue; + +#ifdef IFF_LOOPBACK + if (ifreq.ifr_flags & IFF_LOOPBACK) + continue; +#endif + + if (!(ifreq.ifr_flags & IFF_UP)) + /* interface is down; skip */ + continue; + + /* ifr->ifr_addr has what we want! */ + switch (ifr->ifr_addr.sa_family) { +#ifdef HAVE_NETINET_IN_H + case AF_INET: + { + struct sockaddr_in *in = + (struct sockaddr_in *)&ifr->ifr_addr; + + address = (krb5_address *) + malloc (sizeof(krb5_address)); + if (address) { + address->magic = KV5M_ADDRESS; + address->addrtype = ADDRTYPE_INET; + address->length = sizeof(struct in_addr); + address->contents = (unsigned char *)malloc(address->length); + if (!address->contents) { + krb5_xfree(address); + address = 0; + mem_err++; + } else { + memcpy ((char *)address->contents, + (char *)&in->sin_addr, + address->length); + break; + } + } else mem_err++; + } +#endif +#ifdef KRB5_USE_NS + case AF_XNS: + { + struct sockaddr_ns *ns = + (struct sockaddr_ns *)&ifr->ifr_addr; + address = (krb5_address *) + malloc (sizeof (krb5_address) + sizeof (struct ns_addr)); + if (address) { + address->magic = KV5M_ADDRESS; + address->addrtype = ADDRTYPE_XNS; + + /* XXX should we perhaps use ns_host instead? */ + + address->length = sizeof(struct ns_addr); + address->contents = (unsigned char *)malloc(address->length); + if (!address->contents) { + krb5_xfree(address); + address = 0; + mem_err++; + } else { + memcpy ((char *)address->contents, + (char *)&ns->sns_addr, + address->length); + break; + } + } else mem_err++; + break; + } +#endif + /* + * Add more address families here.. + */ + default: + continue; + } + if (address) + addr_temp[n_found++] = address; + address = 0; + } + closesocket(s); + + *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1)); + if (*addr == 0) + mem_err++; + + if (mem_err) { + for (i=0; i<n_found; i++) { + krb5_xfree(addr_temp[i]); + addr_temp[i] = 0; + } + return ENOMEM; + } + + for (i=0; i<n_found; i++) { + (*addr)[i] = addr_temp[i]; + } + (*addr)[n_found] = 0; + return 0; +} + +#else /* Windows/Mac version */ + +/* + * Hold on to your lunch! Backup kludge method of obtaining your + * local IP address, courtesy of Windows Socket Network Programming, + * by Robert Quinn + */ +#if defined(_MSDOS) || defined(_WIN32) +static struct hostent *local_addr_fallback_kludge() +{ + static struct hostent host; + static SOCKADDR_IN addr; + static char * ip_ptrs[2]; + SOCKET sock; + int size = sizeof(SOCKADDR); + int err; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == INVALID_SOCKET) + return NULL; + + /* connect to arbitrary port and address (NOT loopback) */ + addr.sin_family = AF_INET; + addr.sin_port = htons(IPPORT_ECHO); + addr.sin_addr.s_addr = inet_addr("204.137.220.51"); + + err = connect(sock, (LPSOCKADDR) &addr, sizeof(SOCKADDR)); + if (err == SOCKET_ERROR) + return NULL; + + err = getsockname(sock, (LPSOCKADDR) &addr, (int FAR *) size); + if (err == SOCKET_ERROR) + return NULL; + + closesocket(sock); + + host.h_name = 0; + host.h_aliases = 0; + host.h_addrtype = AF_INET; + host.h_length = 4; + host.h_addr_list = ip_ptrs; + ip_ptrs[0] = (char *) &addr.sin_addr.s_addr; + ip_ptrs[1] = NULL; + + return &host; +} +#endif + +/* No ioctls in winsock so we just assume there is only one networking + * card per machine, so gethostent is good enough. + */ +krb5_error_code +krb5_os_localaddr (krb5_context context, krb5_address ***addr) { + char host[64]; /* Name of local machine */ + struct hostent *hostrec; + int err; + + *addr = calloc (2, sizeof (krb5_address *)); + if (*addr == NULL) + return ENOMEM; + +#ifdef HAVE_MACSOCK_H + hostrec = getmyipaddr(); +#else /* HAVE_MACSOCK_H */ + err = 0; + + if (gethostname (host, sizeof(host))) { + err = WSAGetLastError(); + } + + if (!err) { + hostrec = gethostbyname (host); + if (hostrec == NULL) { + err = WSAGetLastError(); + } + } + + if (err) { + hostrec = local_addr_fallback_kludge(); + if (!hostrec) + return err; + } +#endif /* HAVE_MACSOCK_H */ + + (*addr)[0] = calloc (1, sizeof(krb5_address)); + if ((*addr)[0] == NULL) { + free (*addr); + return ENOMEM; + } + (*addr)[0]->magic = KV5M_ADDRESS; + (*addr)[0]->addrtype = hostrec->h_addrtype; + (*addr)[0]->length = hostrec->h_length; + (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length); + if (!(*addr)[0]->contents) { + free((*addr)[0]); + free(*addr); + return ENOMEM; + } else { + memcpy ((*addr)[0]->contents, + hostrec->h_addr, + (*addr)[0]->length); + } + /* FIXME, deal with the case where gethostent returns multiple addrs */ + + return(0); } +#endif diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index c0ccf7e38c..d8187ac3a6 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -46,7 +46,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) const char *realm_kdc_names[4]; char **masterlist, **hostlist, *host, *port, *cp; krb5_error_code code; - int i, j, out, count; + int i, j, out, count, ismaster; struct sockaddr *addr_p; struct sockaddr_in *sin_p; struct hostent *hp; @@ -103,6 +103,9 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) } if (master_index) { + *master_index = 0; + *nmasters = 0; + realm_kdc_names[0] = "realms"; realm_kdc_names[1] = host; realm_kdc_names[2] = "admin_server"; @@ -113,10 +116,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) krb5_xfree(host); - if (code) { - *master_index = 0; - *nmasters = 0; - } else { + if (code == 0) { for (i=0; masterlist[i]; i++) { host = masterlist[i]; @@ -138,11 +138,10 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) krb5_xfree(host); } - /* at this point, is master is non-NULL, then either the master kdc + /* at this point, if master is non-NULL, then either the master kdc is required, and there is one, or the master kdc is not required, and there may or may not be one. */ - #ifdef HAVE_NETINET_IN_H if (sec_udpport) count = count * 2; @@ -175,10 +174,15 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) continue; } - if (masterlist) - for (j=0; masterlist[j]; j++) - if (strcasecmp(hostlist[i], masterlist[j]) == 0) + ismaster = 0; + if (masterlist) { + for (j=0; masterlist[j]; j++) { + if (strcasecmp(hostlist[i], masterlist[j]) == 0) { *master_index = out; + ismaster = 1; + } + } + } switch (hp->h_addrtype) { @@ -211,7 +215,7 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) default: break; } - if (masterlist) + if (ismaster) *nmasters = out - *master_index; /* Free the hostlist entry we are looping over. */ @@ -219,6 +223,11 @@ krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) hostlist[i] = 0; } + if (masterlist) { + for (i=0; masterlist[i]; i++) + free(masterlist[i]); + free(masterlist); + } free ((char *)hostlist); diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog index 7db8539231..50ec692cba 100644 --- a/src/lib/rpc/ChangeLog +++ b/src/lib/rpc/ChangeLog @@ -1,3 +1,12 @@ +1998-10-27 Marc Horowitz <marc@mit.edu> + + * svc_auth_gssapi.c, auth_gssapi.h: fix the set_name prototype, + add a new unset_names function + +Sun Jul 26 18:13:39 1998 Sam Hartman <hartmans@utwig.mesas.com> + + * Makefile.in (LIBMAJOR): bump libmajor + Wed Apr 15 18:07:38 1998 Tom Yu <tlyu@mit.edu> * Makefile.in (SHLIB_EXPDEPS): diff --git a/src/lib/rpc/Makefile.in b/src/lib/rpc/Makefile.in index 1340d3ffd4..a03ef026f0 100644 --- a/src/lib/rpc/Makefile.in +++ b/src/lib/rpc/Makefile.in @@ -6,7 +6,7 @@ CFLAGS = $(CCOPTS) $(DEFS) -DGSSAPI_KRB5 -DDEBUG_GSSAPI=0 ##DOSLIBNAME=libgssrpc.lib LIB=gssrpc -LIBMAJOR=2 +LIBMAJOR=3 LIBMINOR=0 STOBJLISTS=OBJS.ST SHLIB_EXPDEPS= \ diff --git a/src/lib/rpc/auth_gssapi.h b/src/lib/rpc/auth_gssapi.h index 218b5cb9d3..2cdd20f2fe 100644 --- a/src/lib/rpc/auth_gssapi.h +++ b/src/lib/rpc/auth_gssapi.h @@ -111,8 +111,10 @@ PROTOTYPE((CLIENT *clnt, char *service_name)); void auth_gssapi_display_status PROTOTYPE((char *msg, OM_uint32 major, OM_uint32 minor)); -bool_t _svcauth_gssapi_set_name -PROTOTYPE((char *name, gss_OID name_type)); +bool_t _svcauth_gssapi_set_names +PROTOTYPE((auth_gssapi_name *names, int num)); +void _svcauth_gssapi_unset_names +PROTOTYPE(()); void _svcauth_set_log_badauth_func PROTOTYPE((auth_gssapi_log_badauth_func func, diff --git a/src/lib/rpc/svc_auth_gssapi.c b/src/lib/rpc/svc_auth_gssapi.c index 2a3233ee93..df59859f0d 100644 --- a/src/lib/rpc/svc_auth_gssapi.c +++ b/src/lib/rpc/svc_auth_gssapi.c @@ -887,7 +887,7 @@ done: } /* - * Function: _svcauth_gssapi_set_name + * Function: _svcauth_gssapi_set_names * * Purpose: Sets the list of service names for which incoming * authentication requests should be honored. @@ -917,6 +917,13 @@ bool_t _svcauth_gssapi_set_names(names, num) goto fail; for (i = 0; i < num; i++) { + server_name_list[i] = 0; + server_creds_list[i] = 0; + } + + server_creds_count = num; + + for (i = 0; i < num; i++) { in_buf.value = names[i].name; in_buf.length = strlen(in_buf.value) + 1; @@ -939,19 +946,41 @@ bool_t _svcauth_gssapi_set_names(names, num) } } - server_creds_count = num; - return TRUE; fail: - /* memory leak: not releasing names/creds already acquired */ - if (server_creds_list) + _svcauth_gssapi_unset_names(); + + return FALSE; +} + +/* Function: _svcauth_gssapi_unset_names + * + * Purpose: releases the names and credentials allocated by + * _svcauth_gssapi_set_names + */ + +void _svcauth_gssapi_unset_names() +{ + int i; + OM_uint32 minor_stat; + + if (server_creds_list) { + for (i = 0; i < server_creds_count; i++) + if (server_creds_list[i]) + gss_release_cred(&minor_stat, &server_creds_list[i]); free(server_creds_list); - if (server_name_list) + } + + if (server_name_list) { + for (i = 0; i < server_creds_count; i++) + if (server_name_list[i]) + gss_release_name(&minor_stat, &server_name_list[i]); free(server_name_list); - return FALSE; + } } + /* * Function: _svcauth_gssapi_set_log_badauth_func * |