merge new-crypto branch

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@5332 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Johan Danielsson
1999-02-11 21:03:59 +00:00
parent 0a6c3f7fde
commit aaae186ab9
83 changed files with 4175 additions and 1509 deletions

208
ChangeLog
View File

@@ -107,6 +107,10 @@ Sun Nov 29 01:56:21 1998 Assar Westerlund <assar@sics.se>
* configure.in: add hesiod * configure.in: add hesiod
Wed Nov 25 11:37:48 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* lib/krb5/krb5_err.et: add some codes from kerberos-revisions-03
Mon Nov 23 12:53:48 1998 Assar Westerlund <assar@sics.se> Mon Nov 23 12:53:48 1998 Assar Westerlund <assar@sics.se>
* lib/kadm5/log.c: rename delete -> remove * lib/kadm5/log.c: rename delete -> remove
@@ -135,6 +139,10 @@ Sun Nov 22 06:54:48 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/get_cred.c: re-structure code. remove limits on ASN1 * lib/krb5/get_cred.c: re-structure code. remove limits on ASN1
generated bits. generated bits.
Sun Nov 22 01:49:50 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* kdc/hprop.c (v4_prop): fix bogus indexing
Sat Nov 21 23:12:27 1998 Assar Westerlund <assar@sics.se> Sat Nov 21 23:12:27 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/free.c (krb5_xfree): new function * lib/krb5/free.c (krb5_xfree): new function
@@ -155,10 +163,82 @@ Sat Nov 21 23:12:27 1998 Assar Westerlund <assar@sics.se>
* admin/ktutil.c (kt_remove): some more type correctness. * admin/ktutil.c (kt_remove): some more type correctness.
Sat Nov 21 16:49:20 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* kuser/klist.c: try to list enctypes as keytypes
* kuser/kinit.c: remove extra `--cache' option, add `--enctypes'
to set list of enctypes to use
* kadmin/load.c: load strings as hex
* kadmin/dump.c: dump hex as string is possible
* admin/ktutil.c: use print_version()
* configure.in, acconfig.h: test for hesiod
Sun Nov 15 17:28:19 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* lib/krb5/crypto.c: add some crypto debug code
* lib/krb5/get_in_tkt.c (_krb5_extract_ticket): don't use fixed
buffer when encoding ticket
* lib/krb5/auth_context.c (re-)implement `krb5_auth_setenctype'
* kdc/kerberos5.c: allow mis-match of tgt session key, and service
session key
* admin/ktutil.c: keytype -> enctype
Fri Nov 13 05:35:48 1998 Assar Westerlund <assar@sics.se> Fri Nov 13 05:35:48 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/krb5.h (KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE): added * lib/krb5/krb5.h (KRB5_TGS_NAME, KRB5_TGS_NAME_SIZE): added
Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/rd_req.c: adapt to new crypto api
* lib/krb5/rd_rep.c: adapt to new crypto api
* lib/krb5/rd_priv.c: adopt to new crypto api
* lib/krb5/rd_cred.c: adopt to new crypto api
* lib/krb5/principal.c: ENOMEM -> ERANGE
* lib/krb5/mk_safe.c: cleanup and adopt to new crypto api
* lib/krb5/mk_req_ext.c: adopt to new crypto api
* lib/krb5/mk_req.c: get enctype from auth_context keyblock
* lib/krb5/mk_rep.c: cleanup and adopt to new crypto api
* lib/krb5/mk_priv.c: adopt to new crypto api
* lib/krb5/keytab.c: adopt to new crypto api
* lib/krb5/get_in_tkt_with_skey.c: adopt to new crypto api
* lib/krb5/get_in_tkt_with_keytab.c: adopt to new crypto api
* lib/krb5/get_in_tkt_pw.c: adopt to new crypto api
* lib/krb5/get_in_tkt.c: adopt to new crypto api
* lib/krb5/get_cred.c: adopt to new crypto api
* lib/krb5/generate_subkey.c: use new crypto api
* lib/krb5/context.c: rename etype functions to enctype ditto
* lib/krb5/build_auth.c: use new crypto api
* lib/krb5/auth_context.c: remove enctype and cksumtype from
auth_context
Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se> Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
* kdc/connect.c (handle_udp, handle_tcp): correct type of `n' * kdc/connect.c (handle_udp, handle_tcp): correct type of `n'
@@ -168,6 +248,10 @@ Mon Nov 2 01:15:06 1998 Assar Westerlund <assar@sics.se>
* appl/rsh/rshd.c (recv_krb5_auth): disable `do_encrypt' if not * appl/rsh/rshd.c (recv_krb5_auth): disable `do_encrypt' if not
encrypting. encrypting.
Tue Sep 15 18:41:38 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* admin/ktutil.c: fix printing of unrecognized keytypes
Tue Sep 15 17:02:33 1998 Johan Danielsson <joda@hella.pdc.kth.se> Tue Sep 15 17:02:33 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* lib/kadm5/set_keys.c: add KEYTYPE_USE_AFS3_SALT to keytype if * lib/kadm5/set_keys.c: add KEYTYPE_USE_AFS3_SALT to keytype if
@@ -188,6 +272,70 @@ Tue Aug 25 23:30:52 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/context.c (krb5_get_use_admin_kdc, * lib/krb5/context.c (krb5_get_use_admin_kdc,
krb5_set_use_admin_kdc): new functions krb5_set_use_admin_kdc): new functions
Tue Aug 18 22:24:12 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/crypto.c: remove all calls to abort(); check return
value from _key_schedule;
(RSA_MD[45]_DES_verify): zero tmp and res;
(RSA_MD5_DES3_{verify,checksum}): implement
Mon Aug 17 20:18:46 1998 Assar Westerlund <assar@sics.se>
* kdc/kerberos4.c (swap32): conditionalize
* lib/krb5/mk_req_ext.c (krb5_mk_req_internal): new function
* lib/krb5/get_host_realm.c (krb5_get_host_realm): if the hostname
returned from gethostby*() isn't a FQDN, try with the original
hostname
* lib/krb5/get_cred.c (make_pa_tgs_req): use krb5_mk_req_internal
and correct key usage
* lib/krb5/crypto.c (verify_checksum): make static
* admin/ktutil.c (kt_list): use krb5_enctype_to_string
Sun Aug 16 20:57:56 1998 Assar Westerlund <assar@sics.se>
* kadmin/cpw.c (do_cpw_entry): use asprintf for the prompt
* kadmin/ank.c (ank): print principal name in prompt
* lib/krb5/crypto.c (hmac): always allocate space for checksum.
never trust c.checksum.length
(_get_derived_key): try to return the derived key
Sun Aug 16 19:48:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/crypto.c (hmac): fix some peculiarities and bugs
(get_checksum_key): assume usage is `formatted'
(create_checksum,verify_checksum): moved the guts of the krb5_*
functions here, both take `formatted' key-usages
(encrypt_internal_derived): fix various bogosities
(derive_key): drop key_type parameter (already given by the
encryption_type)
* kdc/kerberos5.c (check_flags): handle case where client is NULL
* kdc/connect.c (process_request): return zero after processing
kerberos 4 request
Sun Aug 16 18:38:15 1998 Johan Danielsson <joda@blubb.pdc.kth.se>
* lib/krb5/crypto.c: merge x-*.[ch] into one file
* lib/krb5/cache.c: remove residual from krb5_ccache_data
Fri Aug 14 16:28:23 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/x-crypto.c (derive_key): move DES3 specific code to
separate function (will eventually end up someplace else)
* lib/krb5/x-crypto.c (krb5_string_to_key_derived): allocate key
* configure.in, acconfig.h: test for four valued krb_put_int
Thu Aug 13 23:46:29 1998 Assar Westerlund <assar@emma.pdc.kth.se> Thu Aug 13 23:46:29 1998 Assar Westerlund <assar@emma.pdc.kth.se>
* Release 0.0t * Release 0.0t
@@ -197,6 +345,14 @@ Thu Aug 13 22:40:17 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/config_file.c (parse_binding): remove trailing * lib/krb5/config_file.c (parse_binding): remove trailing
whitespace whitespace
Wed Aug 12 20:15:11 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* lib/krb5/x-checksum.c (krb5_verify_checksum): pass checksum type
to krb5_create_checksum
* lib/krb5/x-key.c: implement DES3_string_to_key_derived; fix a
few typos
Wed Aug 5 12:39:54 1998 Assar Westerlund <assar@emma.pdc.kth.se> Wed Aug 5 12:39:54 1998 Assar Westerlund <assar@emma.pdc.kth.se>
* Release 0.0s * Release 0.0s
@@ -207,6 +363,58 @@ Thu Jul 30 23:12:17 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/mk_error.c (krb5_mk_error): realloc until you die * lib/krb5/mk_error.c (krb5_mk_error): realloc until you die
Thu Jul 23 19:49:03 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* kdc/kdc_locl.h: proto for `get_des_key'
* configure.in: test for four valued el_init
* kuser/klist.c: keytype -> enctype
* kpasswd/kpasswdd.c (change): use new `krb5_string_to_key*'
* kdc/hprop.c (v4_prop, ka_convert): convert to a set of keys
* kdc/kaserver.c: use `get_des_key'
* kdc/524.c: use new crypto api
* kdc/kerberos4.c: use new crypto api
* kdc/kerberos5.c: always treat keytypes as enctypes; use new
crypto api
* kdc/kstash.c: adapt to new crypto api
* kdc/string2key.c: adapt to new crypto api
* admin/srvconvert.c: add keys for all possible enctypes
* admin/ktutil.c: keytype -> enctype
* appl/rsh/rshd.c: use krb5_verify_authenticator_checksum
* lib/gssapi/init_sec_context.c: get enctype from auth_context
keyblock
* lib/hdb/hdb.c: remove hdb_*_keytype2key
* lib/kadm5/set_keys.c: adapt to new crypto api
* lib/kadm5/rename_s.c: adapt to new crypto api
* lib/kadm5/get_s.c: adapt to new crypto api
* lib/kadm5/create_s.c: add keys for des-cbc-crc, des-cbc-md4,
des-cbc-md5, and des3-cbc-sha1
* lib/krb5/heim_err.et: error message for unsupported salt
* lib/krb5/codec.c: short-circuit these functions, since they are
not needed any more
* lib/krb5/rd_safe.c: cleanup and adapt to new crypto api
Mon Jul 13 23:00:59 1998 Assar Westerlund <assar@sics.se> Mon Jul 13 23:00:59 1998 Assar Westerlund <assar@sics.se>
* lib/krb5/send_to_kdc.c (krb5_sendto_kdc): don't advance * lib/krb5/send_to_kdc.c (krb5_sendto_kdc): don't advance

View File

@@ -17,6 +17,14 @@
#undef HAVE_U_INT32_T #undef HAVE_U_INT32_T
#undef HAVE_U_INT64_T #undef HAVE_U_INT64_T
#undef HAVE_FOUR_VALUED_KRB_PUT_INT
#ifdef HAVE_FOUR_VALUED_KRB_PUT_INT
#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (L), (S))
#else
#define KRB_PUT_INT(F, T, L, S) krb_put_int((F), (T), (L))
#endif
/* Define this to the type ssize_t should be */ /* Define this to the type ssize_t should be */
#undef ssize_t #undef ssize_t
@@ -178,6 +186,9 @@
/* Define if you have a readline compatible library */ /* Define if you have a readline compatible library */
#undef HAVE_READLINE #undef HAVE_READLINE
/* define if el_init takes four arguments */
#undef HAVE_FOUR_VALUED_EL_INIT
/* Define if you have hesiod */ /* Define if you have hesiod */
#undef HESIOD #undef HESIOD
@@ -229,6 +240,12 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
#define AUTHENTICATION 1 #define AUTHENTICATION 1
#endif #endif
/* Define if you have hesiod */
#undef HESIOD
/* define if you want key-deriving des3 code */
#undef NEW_DES3_CODE
/* Set this if you want des encryption */ /* Set this if you want des encryption */
#undef DES_ENCRYPTION #undef DES_ENCRYPTION

View File

@@ -54,7 +54,7 @@ kt_list(int argc, char **argv)
} }
printf("%s", "Version"); printf("%s", "Version");
printf(" "); printf(" ");
printf("%-6s", "Type"); printf("%-15s", "Type");
printf(" "); printf(" ");
printf("%s", "Principal"); printf("%s", "Principal");
printf("\n"); printf("\n");
@@ -62,8 +62,10 @@ kt_list(int argc, char **argv)
char *p; char *p;
printf(" %3d ", entry.vno); printf(" %3d ", entry.vno);
printf(" "); printf(" ");
krb5_keytype_to_string(context, entry.keyblock.keytype, &p); ret = krb5_enctype_to_string(context, entry.keyblock.keytype, &p);
printf("%-6s", p); if (ret != 0)
asprintf(&p, "unknown (%d)", entry.keyblock.keytype);
printf("%-15s", p);
free(p); free(p);
printf(" "); printf(" ");
krb5_unparse_name(context, entry.principal, &p); krb5_unparse_name(context, entry.principal, &p);
@@ -85,12 +87,12 @@ kt_remove(int argc, char **argv)
krb5_principal principal = NULL; krb5_principal principal = NULL;
int kvno = 0; int kvno = 0;
char *keytype_string = NULL; char *keytype_string = NULL;
krb5_keytype keytype = KEYTYPE_NULL; krb5_enctype enctype = 0;
int help_flag = 0; int help_flag = 0;
struct getargs args[] = { struct getargs args[] = {
{ "principal", 'p', arg_string, NULL, "principal to remove" }, { "principal", 'p', arg_string, NULL, "principal to remove" },
{ "kvno", 'V', arg_integer, NULL, "key version to remove" }, { "kvno", 'V', arg_integer, NULL, "key version to remove" },
{ "keytype", 't', arg_string, NULL, "key type to remove" }, { "enctype", 't', arg_string, NULL, "enctype to remove" },
{ "help", 'h', arg_flag, NULL } { "help", 'h', arg_flag, NULL }
}; };
int num_args = sizeof(args) / sizeof(args[0]); int num_args = sizeof(args) / sizeof(args[0]);
@@ -116,11 +118,11 @@ kt_remove(int argc, char **argv)
} }
} }
if(keytype_string) { if(keytype_string) {
ret = krb5_string_to_keytype(context, keytype_string, &keytype); ret = krb5_string_to_enctype(context, keytype_string, &enctype);
if(ret) { if(ret) {
int t; int t;
if(sscanf(keytype_string, "%d", &t) == 1) if(sscanf(keytype_string, "%d", &t) == 1)
keytype = (krb5_keytype)t; enctype = t;
else { else {
krb5_warn(context, ret, "%s", keytype_string); krb5_warn(context, ret, "%s", keytype_string);
if(principal) if(principal)
@@ -129,14 +131,14 @@ kt_remove(int argc, char **argv)
} }
} }
} }
if (!principal && !keytype && !kvno) { if (!principal && !enctype && !kvno) {
krb5_warnx(context, krb5_warnx(context,
"You must give at least one of " "You must give at least one of "
"principal, keytype or kvno."); "principal, enctype or kvno.");
return 0; return 0;
} }
entry.principal = principal; entry.principal = principal;
entry.keyblock.keytype = keytype; entry.keyblock.keytype = enctype;
entry.vno = kvno; entry.vno = kvno;
ret = krb5_kt_remove_entry(context, keytab, &entry); ret = krb5_kt_remove_entry(context, keytab, &entry);
if(ret) if(ret)
@@ -154,15 +156,15 @@ kt_add(int argc, char **argv)
char buf[128]; char buf[128];
char *principal_string = NULL; char *principal_string = NULL;
int kvno = -1; int kvno = -1;
char *keytype_string = NULL; char *enctype_string = NULL;
krb5_keytype keytype; krb5_enctype enctype;
char *password_string = NULL; char *password_string = NULL;
int random_flag = 0; int random_flag = 0;
int help_flag = 0; int help_flag = 0;
struct getargs args[] = { struct getargs args[] = {
{ "principal", 'p', arg_string, NULL, "principal of key", "principal"}, { "principal", 'p', arg_string, NULL, "principal of key", "principal"},
{ "kvno", 'V', arg_integer, NULL, "key version of key" }, { "kvno", 'V', arg_integer, NULL, "key version of key" },
{ "keytype", 't', arg_string, NULL, "key type of key" }, { "enctype", 'e', arg_string, NULL, "encryption type of key" },
{ "password", 'w', arg_string, NULL, "password for key"}, { "password", 'w', arg_string, NULL, "password for key"},
{ "random", 'r', arg_flag, NULL, "generate random key" }, { "random", 'r', arg_flag, NULL, "generate random key" },
{ "help", 'h', arg_flag, NULL } { "help", 'h', arg_flag, NULL }
@@ -172,7 +174,7 @@ kt_add(int argc, char **argv)
int i = 0; int i = 0;
args[i++].value = &principal_string; args[i++].value = &principal_string;
args[i++].value = &kvno; args[i++].value = &kvno;
args[i++].value = &keytype_string; args[i++].value = &enctype_string;
args[i++].value = &password_string; args[i++].value = &password_string;
args[i++].value = &random_flag; args[i++].value = &random_flag;
args[i++].value = &help_flag; args[i++].value = &help_flag;
@@ -196,19 +198,19 @@ kt_add(int argc, char **argv)
krb5_warn(context, ret, "%s", principal_string); krb5_warn(context, ret, "%s", principal_string);
return 0; return 0;
} }
if(keytype_string == NULL) { if(enctype_string == NULL) {
printf("Keytype: "); printf("Encryption type: ");
fgets(buf, sizeof(buf), stdin); fgets(buf, sizeof(buf), stdin);
buf[strcspn(buf, "\r\n")] = '\0'; buf[strcspn(buf, "\r\n")] = '\0';
keytype_string = buf; enctype_string = buf;
} }
ret = krb5_string_to_keytype(context, keytype_string, &keytype); ret = krb5_string_to_enctype(context, enctype_string, &enctype);
if(ret) { if(ret) {
int t; int t;
if(sscanf(keytype_string, "%d", &t) == 1) if(sscanf(enctype_string, "%d", &t) == 1)
keytype = (krb5_keytype)t; enctype = t;
else { else {
krb5_warn(context, ret, "%s", keytype_string); krb5_warn(context, ret, "%s", enctype_string);
if(entry.principal) if(entry.principal)
krb5_free_principal(context, entry.principal); krb5_free_principal(context, entry.principal);
return 0; return 0;
@@ -224,14 +226,11 @@ kt_add(int argc, char **argv)
des_read_pw_string(buf, sizeof(buf), "Password: ", 1); des_read_pw_string(buf, sizeof(buf), "Password: ", 1);
password_string = buf; password_string = buf;
} }
if(password_string) { if(password_string)
krb5_data salt; krb5_string_to_key(context, enctype, password_string,
krb5_get_salt(entry.principal, &salt); entry.principal, &entry.keyblock);
krb5_string_to_key(password_string, &salt, keytype, &entry.keyblock); else
krb5_data_free(&salt); krb5_generate_random_keyblock(context, enctype, &entry.keyblock);
} else {
krb5_generate_random_keyblock(context, keytype, &entry.keyblock);
}
entry.vno = kvno; entry.vno = kvno;
ret = krb5_kt_add_entry(context, keytab, &entry); ret = krb5_kt_add_entry(context, keytab, &entry);
if(ret) if(ret)
@@ -313,8 +312,10 @@ main(int argc, char **argv)
usage(1); usage(1);
if(help_flag) if(help_flag)
usage(0); usage(0);
if(version_flag) if(version_flag) {
krb5_errx(context, 0, "%s", heimdal_version); print_version(NULL);
exit(0);
}
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if(argc == 0) if(argc == 0)

View File

@@ -151,7 +151,6 @@ srvconv(int argc, char **argv)
} }
entry.vno = kvno; entry.vno = kvno;
entry.keyblock.keytype = KEYTYPE_DES;
entry.keyblock.keyvalue.data = key; entry.keyblock.keyvalue.data = key;
entry.keyblock.keyvalue.length = 8; entry.keyblock.keyvalue.length = 8;
@@ -168,6 +167,11 @@ srvconv(int argc, char **argv)
} }
} }
entry.keyblock.keytype = ETYPE_DES_CBC_MD5;
ret = krb5_kt_add_entry(context, keytab, &entry);
entry.keyblock.keytype = ETYPE_DES_CBC_MD4;
ret = krb5_kt_add_entry(context, keytab, &entry);
entry.keyblock.keytype = ETYPE_DES_CBC_CRC;
ret = krb5_kt_add_entry(context, keytab, &entry); ret = krb5_kt_add_entry(context, keytab, &entry);
krb5_free_principal(context, entry.principal); krb5_free_principal(context, entry.principal);
if(ret) { if(ret) {

View File

@@ -11,7 +11,7 @@ AFSPROGS =
endif endif
bin_PROGRAMS = $(AFSPROGS) bin_PROGRAMS = $(AFSPROGS)
LDADD = $(top_builddir)/lib/kafs/libkafs.a \ LDADD = $(top_builddir)/lib/kafs/libkafs.a $(AIX_EXTRA_KAFS) \
$(LIB_krb4) \ $(LIB_krb4) \
$(top_builddir)/lib/krb5/libkrb5.la \ $(top_builddir)/lib/krb5/libkrb5.la \
$(top_builddir)/lib/asn1/libasn1.la \ $(top_builddir)/lib/asn1/libasn1.la \

View File

@@ -1,3 +1,7 @@
Tue Dec 1 14:44:29 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* ftpd/Makefile.am: link with extra libs for aix
Sun Nov 22 10:28:20 1998 Assar Westerlund <assar@sics.se> Sun Nov 22 10:28:20 1998 Assar Westerlund <assar@sics.se>
* ftpd/ftpd.c (retrying): support on-the-fly decompression * ftpd/ftpd.c (retrying): support on-the-fly decompression
@@ -33,6 +37,10 @@ Tue Sep 1 16:56:42 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* ftp/cmds.c (quote1): fix % quoting bug * ftp/cmds.c (quote1): fix % quoting bug
Fri Aug 14 17:10:06 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* ftp/krb4.c: krb_put_int -> KRB_PUT_INT
Tue Jun 30 18:07:15 1998 Assar Westerlund <assar@sics.se> Tue Jun 30 18:07:15 1998 Assar Westerlund <assar@sics.se>
* ftp/security.c (auth): free `app_data' * ftp/security.c (auth): free `app_data'

View File

@@ -152,7 +152,7 @@ krb4_adat(void *app_data, void *buf, size_t len)
cs = auth_dat.checksum + 1; cs = auth_dat.checksum + 1;
{ {
unsigned char tmp[4]; unsigned char tmp[4];
krb_put_int(cs, tmp, 4, sizeof(tmp)); KRB_PUT_INT(cs, tmp, 4, sizeof(tmp));
tmp_len = krb_mk_safe(tmp, msg, 4, &d->key, &LOCAL_ADDR, &REMOTE_ADDR); tmp_len = krb_mk_safe(tmp, msg, 4, &d->key, &LOCAL_ADDR, &REMOTE_ADDR);
} }
if(tmp_len < 0){ if(tmp_len < 0){

View File

@@ -40,7 +40,7 @@ gssapi.c:
CLEANFILES = security.c security.h krb4.c gssapi.c CLEANFILES = security.c security.h krb4.c gssapi.c
if KRB4 if KRB4
afslib = $(top_builddir)/lib/kafs/libkafs.a afslib = $(top_builddir)/lib/kafs/libkafs.a $(AIX_EXTRA_KAFS)
else else
afslib = afslib =
endif endif

View File

@@ -68,9 +68,12 @@ do_read (int fd,
ret = krb5_net_read (context, &fd, buf, outer_len); ret = krb5_net_read (context, &fd, buf, outer_len);
if (ret != outer_len) if (ret != outer_len)
return ret; return ret;
status = krb5_decrypt(context, buf, outer_len,
ETYPE_DES_CBC_CRC, /* XXX */
keyblock, &data);
status = krb5_decrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
buf, outer_len, &data);
if (status) if (status)
errx (1, "%s", krb5_get_err_text (context, status)); errx (1, "%s", krb5_get_err_text (context, status));
memcpy (buf, data.data, len); memcpy (buf, data.data, len);
@@ -98,12 +101,9 @@ do_write (int fd, void *buf, size_t sz)
u_int32_t len; u_int32_t len;
int ret; int ret;
status = krb5_encrypt (context, status = krb5_encrypt(context, crypto, KRB5_KU_OTHER_ENCRYPTED,
buf, buf, sz, &data);
sz,
ETYPE_DES_CBC_CRC, /* XXX */
keyblock,
&data);
if (status) if (status)
errx (1, "%s", krb5_get_err_text(context, status)); errx (1, "%s", krb5_get_err_text(context, status));
len = htonl(sz); len = htonl(sz);

View File

@@ -44,6 +44,7 @@ int do_encrypt;
int do_forward; int do_forward;
krb5_context context; krb5_context context;
krb5_keyblock *keyblock; krb5_keyblock *keyblock;
krb5_crypto crypto;
des_key_schedule schedule; des_key_schedule schedule;
des_cblock iv; des_cblock iv;
@@ -278,6 +279,11 @@ send_krb5_auth(int s,
errx (1, "krb5_auth_con_getkey: %s", errx (1, "krb5_auth_con_getkey: %s",
krb5_get_err_text(context, status)); krb5_get_err_text(context, status));
krb5_crypto_init(context, keyblock, 0, &crypto);
if(status)
errx (1, "krb5_crypto_init: %s",
krb5_get_err_text(context, status));
len = strlen(remote_user) + 1; len = strlen(remote_user) + 1;
if (net_write (s, remote_user, len) != len) if (net_write (s, remote_user, len) != len)
err (1, "write"); err (1, "write");

View File

@@ -122,6 +122,7 @@ extern enum auth_method auth_method;
extern int do_encrypt; extern int do_encrypt;
extern krb5_context context; extern krb5_context context;
extern krb5_keyblock *keyblock; extern krb5_keyblock *keyblock;
extern krb5_crypto crypto;
extern des_key_schedule schedule; extern des_key_schedule schedule;
extern des_cblock iv; extern des_cblock iv;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -43,6 +43,7 @@ enum auth_method auth_method;
krb5_context context; krb5_context context;
krb5_keyblock *keyblock; krb5_keyblock *keyblock;
krb5_crypto crypto;
des_key_schedule schedule; des_key_schedule schedule;
des_cblock iv; des_cblock iv;
@@ -225,7 +226,6 @@ recv_krb5_auth (int s, u_char *buf,
krb5_auth_context auth_context = NULL; krb5_auth_context auth_context = NULL;
krb5_ticket *ticket; krb5_ticket *ticket;
krb5_error_code status; krb5_error_code status;
krb5_authenticator authenticator;
krb5_data cksum_data; krb5_data cksum_data;
krb5_principal server; krb5_principal server;
@@ -269,33 +269,31 @@ recv_krb5_auth (int s, u_char *buf,
status = krb5_auth_con_getkey (context, auth_context, &keyblock); status = krb5_auth_con_getkey (context, auth_context, &keyblock);
if (status) if (status)
syslog_and_die ("krb5_auth_con_getkey: %s", syslog_and_die ("krb5_auth_con_getkey: %s",
krb5_get_err_text(context, status)); krb5_get_err_text(context, status));
status = krb5_auth_getauthenticator (context, status = krb5_crypto_init(context, keyblock, 0, &crypto);
auth_context, if(status)
&authenticator); syslog_and_die("krb5_crypto_init: %s",
if (status) krb5_get_err_text(context, status));
syslog_and_die ("krb5_auth_getauthenticator: %s",
krb5_get_err_text(context, status));
cksum_data.length = asprintf ((char **)&cksum_data.data, cksum_data.length = asprintf ((char **)&cksum_data.data,
"%u:%s%s", "%u:%s%s",
ntohs(thisaddr.sin_port), ntohs(thisaddr.sin_port),
cmd, cmd,
server_username); server_username);
status = krb5_verify_checksum (context, status = krb5_verify_authenticator_checksum(context,
cksum_data.data, auth_context,
cksum_data.length, cksum_data.data,
keyblock, cksum_data.length);
authenticator->cksum);
if (status) if (status)
syslog_and_die ("krb5_verify_checksum: %s", syslog_and_die ("krb5_verify_authenticator_checksum: %s",
krb5_get_err_text(context, status)); krb5_get_err_text(context, status));
free (cksum_data.data); free (cksum_data.data);
krb5_free_authenticator (context, &authenticator);
recv_krb5_creds (s, auth_context, server_username, ticket->client); recv_krb5_creds (s, auth_context, server_username, ticket->client);

View File

@@ -4,6 +4,18 @@ Mon Feb 1 04:08:36 1999 Assar Westerlund <assar@sics.se>
if we actually have IPv6. From "Brandon S. Allbery KF8NH" if we actually have IPv6. From "Brandon S. Allbery KF8NH"
<allbery@kf8nh.apk.net> <allbery@kf8nh.apk.net>
Sat Nov 21 16:51:00 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* telnetd/sys_term.c (cleanup): don't call vhangup() on sgi:s
Fri Aug 14 16:29:18 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* libtelnet/kerberos.c: krb_put_int -> KRB_PUT_INT
Thu Jul 23 20:29:05 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* libtelnet/kerberos5.c: use krb5_verify_authenticator_checksum
Wed May 27 04:19:17 1998 Assar Westerlund <assar@sics.se> Wed May 27 04:19:17 1998 Assar Westerlund <assar@sics.se>
* telnet/sys_bsd.c (process_rings): correct call to `stilloob' * telnet/sys_bsd.c (process_rings): correct call to `stilloob'

View File

@@ -620,13 +620,13 @@ pack_cred(CREDENTIALS *cred, unsigned char *buf)
p += REALM_SZ; p += REALM_SZ;
memcpy(p, cred->session, 8); memcpy(p, cred->session, 8);
p += 8; p += 8;
p += krb_put_int(cred->lifetime, p, 4, 4); p += KRB_PUT_INT(cred->lifetime, p, 4, 4);
p += krb_put_int(cred->kvno, p, 4, 4); p += KRB_PUT_INT(cred->kvno, p, 4, 4);
p += krb_put_int(cred->ticket_st.length, p, 4, 4); p += KRB_PUT_INT(cred->ticket_st.length, p, 4, 4);
memcpy(p, cred->ticket_st.dat, cred->ticket_st.length); memcpy(p, cred->ticket_st.dat, cred->ticket_st.length);
p += cred->ticket_st.length; p += cred->ticket_st.length;
p += krb_put_int(0, p, 4, 4); p += KRB_PUT_INT(0, p, 4, 4);
p += krb_put_int(cred->issue_date, p, 4, 4); p += KRB_PUT_INT(cred->issue_date, p, 4, 4);
memcpy (p, cred->pname, ANAME_SZ); memcpy (p, cred->pname, ANAME_SZ);
p += ANAME_SZ; p += ANAME_SZ;
memcpy (p, cred->pinst, INST_SZ); memcpy (p, cred->pinst, INST_SZ);

View File

@@ -256,7 +256,6 @@ kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
krb5_keyblock *key_block; krb5_keyblock *key_block;
char *name; char *name;
krb5_principal server; krb5_principal server;
krb5_authenticator authenticator;
int zero = 0; int zero = 0;
if (cnt-- < 1) if (cnt-- < 1)
@@ -327,55 +326,29 @@ kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
free (errbuf); free (errbuf);
return; return;
} }
ret = krb5_auth_con_getkey(context, auth_context, &key_block);
if (ret) {
Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1);
auth_finished(ap, AUTH_REJECT);
if (auth_debug_mode)
printf("Kerberos V5: "
"krb5_auth_con_getkey failed (%s)\r\n",
krb5_get_err_text(context, ret));
return;
}
ret = krb5_auth_getauthenticator (context, {
auth_context,
&authenticator);
if (ret) {
Data(ap, KRB_REJECT, "krb5_auth_getauthenticator failed", -1);
auth_finished(ap, AUTH_REJECT);
if (auth_debug_mode)
printf("Kerberos V5: "
"krb5_auth_getauthenticator failed (%s)\r\n",
krb5_get_err_text(context, ret));
return;
}
if (authenticator->cksum) {
char foo[2]; char foo[2];
foo[0] = ap->type; foo[0] = ap->type;
foo[1] = ap->way; foo[1] = ap->way;
ret = krb5_verify_authenticator_checksum(context,
auth_context,
foo,
sizeof(foo));
ret = krb5_verify_checksum (context,
foo,
sizeof(foo),
key_block,
authenticator->cksum);
if (ret) { if (ret) {
Data(ap, KRB_REJECT, "No checksum", -1); char *errbuf;
asprintf(&errbuf, "Bad checksum: %s",
krb5_get_err_text(context, ret));
Data(ap, KRB_REJECT, errbuf, -1);
if (auth_debug_mode) if (auth_debug_mode)
printf ("No checksum\r\n"); printf ("%s\r\n", errbuf);
krb5_free_authenticator (context, free(errbuf);
&authenticator);
return; return;
} }
} }
krb5_free_authenticator (context,
&authenticator);
ret = krb5_auth_con_getremotesubkey (context, ret = krb5_auth_con_getremotesubkey (context,
auth_context, auth_context,
&key_block); &key_block);
@@ -416,7 +389,9 @@ kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
name ? name : ""); name ? name : "");
} }
if(key_block->keytype == KEYTYPE_DES) { if(key_block->keytype == ETYPE_DES_CBC_MD5 ||
key_block->keytype == ETYPE_DES_CBC_MD4 ||
key_block->keytype == ETYPE_DES_CBC_CRC) {
Session_Key skey; Session_Key skey;
skey.type = SK_DES; skey.type = SK_DES;

View File

@@ -1602,8 +1602,10 @@ cleanup(int sig)
#if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP) #if defined(HAVE_UTMPX_H) || !defined(HAVE_LOGWTMP)
rmut(); rmut();
#ifdef HAVE_VHANGUP #ifdef HAVE_VHANGUP
#ifndef __sgi
vhangup(); /* XXX */ vhangup(); /* XXX */
#endif #endif
#endif
#else #else
char *p; char *p;

View File

@@ -1,6 +1,6 @@
dnl $Id$ dnl $Id$
dnl dnl
dnl AC_TEST_PACKAGE(package,header,lib,linkline) dnl AC_TEST_PACKAGE(package,header,lib,linkline,default location)
AC_DEFUN(AC_TEST_PACKAGE, AC_DEFUN(AC_TEST_PACKAGE,
[ [
AC_MSG_CHECKING(for $1) AC_MSG_CHECKING(for $1)
@@ -32,16 +32,20 @@ define([foo], translit($1, [a-z], [A-Z]))
@@@syms="$syms foo"@@@ @@@syms="$syms foo"@@@
END END
if test -n "$with_$1"; then if test -n "$with_$1" -o -n "$5"; then
AC_DEFINE([foo]) dnl AC_DEFINE([foo])
if test "$with_$1" != "yes"; then if test -n "$with_$1" -a "$with_$1" != "yes"; then
$1_dir=$with_$1 $1_dir="$with_$1"
elif test -n "$5"; then
$1_dir="$5"
fi fi
dnl Try to find include dnl Try to find include
if test -n "$with_$1_include"; then if test -n "$with_$1_include"; then
trydir=$with_$1_include trydir=$with_$1_include
elif test "$with_$1" != "yes"; then elif test -n "$with_$1" -a "$with_$1" != "yes"; then
trydir="$with_$1 $with_$1/include" trydir="$with_$1 $with_$1/include"
elif test -n "$5"; then
trydir="$5/include"
else else
trydir= trydir=
fi fi
@@ -57,14 +61,16 @@ dnl Try to find include
done done
if test -n "$found"; then if test -n "$found"; then
$1_include=$res $1_include=$res
else elif test -n "$with_$1"; then
AC_MSG_ERROR(Cannot find $2) AC_MSG_ERROR(Cannot find $2)
fi fi
dnl Try to find lib dnl Try to find lib
if test -n "$with_$1_lib"; then if test -n "$with_$1_lib"; then
trydir=$with_$1_lib trydir=$with_$1_lib
elif test "$with_$1" != "yes"; then elif test -n "$with_$1" -a "$with_$1" != "yes"; then
trydir="$with_$1 $with_$1/lib" trydir="$with_$1 $with_$1/lib"
elif test -n "$5"; then
trydir="$5/lib"
else else
trydir= trydir=
fi fi
@@ -83,11 +89,18 @@ dnl Try to find lib
done done
if test -n "$found"; then if test -n "$found"; then
$1_lib=$res $1_lib=$res
else elif test -n "$with_$1"; then
AC_MSG_ERROR(Cannot find $3) AC_MSG_ERROR(Cannot find $3)
fi fi
AC_MSG_RESULT([headers $$1_include, libraries $$1_lib]) if test -n "$$1_include" -o -n "$$1_lib"; then
AC_DEFINE_UNQUOTED(foo) AC_MSG_RESULT([headers $$1_include, libraries $$1_lib])
AC_DEFINE_UNQUOTED(foo)
if test "$with_$1" = "" -a "$5"; then
with_$1="$5"
fi
else
AC_MSG_RESULT(no)
fi
if test -n "$$1_include"; then if test -n "$$1_include"; then
foo[INCLUDE]="-I$$1_include" foo[INCLUDE]="-I$$1_include"
fi fi

View File

@@ -3,6 +3,10 @@ AC_REVISION($Revision$)
AC_INIT(lib/krb5/send_to_kdc.c) AC_INIT(lib/krb5/send_to_kdc.c)
AM_CONFIG_HEADER(include/config.h) AM_CONFIG_HEADER(include/config.h)
AC_CONFIG_AUX_DIR_DEFAULT
if test "`uname`" = AIX; then
INSTALL="$ac_install_sh"
fi
AM_INIT_AUTOMAKE(heimdal,0.0u) AM_INIT_AUTOMAKE(heimdal,0.0u)
AC_PREFIX_DEFAULT(/usr/heimdal) AC_PREFIX_DEFAULT(/usr/heimdal)
@@ -20,6 +24,8 @@ case "$host" in
;; ;;
esac esac
test -z "$CFLAGS" && CFLAGS="-g"
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CC AC_PROG_CC
@@ -39,7 +45,6 @@ if test "$GCC" = "yes"; then
fi fi
AC_SUBST(WFLAGS) AC_SUBST(WFLAGS)
AC_SUBST(WFLAGS_NOUNUSED) AC_SUBST(WFLAGS_NOUNUSED)
test -z "$CFLAGS" && CFLAGS="-g"
berkeley_db=db berkeley_db=db
AC_ARG_WITH(berkeley-db, AC_ARG_WITH(berkeley-db,
@@ -49,7 +54,7 @@ if test "$withval" = no; then
fi fi
]) ])
AC_TEST_PACKAGE(krb4,krb.h,libkrb.a,-lkrb) AC_TEST_PACKAGE(krb4,krb.h,libkrb.a,-lkrb,/usr/athena)
if test "$with_krb4"; then if test "$with_krb4"; then
AC_DEFINE(KRB4, 1) AC_DEFINE(KRB4, 1)
@@ -57,11 +62,45 @@ if test "$with_krb4"; then
INCLUDE_krb4="$KRB4INCLUDE" INCLUDE_krb4="$KRB4INCLUDE"
EXTRA_LIB45=lib45.a EXTRA_LIB45=lib45.a
AC_SUBST(EXTRA_LIB45) AC_SUBST(EXTRA_LIB45)
AC_CACHE_CHECK(for four valued krb_put_int, ac_cv_func_krb_put_int_four,
[save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $INCLUDE_krb4"
AC_TRY_COMPILE([#include <krb.h>],[
char tmp[4];
krb_put_int(17, tmp, 4, sizeof(tmp));],
ac_cv_func_krb_put_int_four=yes,
ac_cv_func_krb_put_int_four=no)
CFLAGS="$save_CFLAGS"
])
if test "$ac_cv_func_krb_put_int_four" = yes; then
AC_DEFINE(HAVE_FOUR_VALUED_KRB_PUT_INT, 1)
fi
fi fi
AM_CONDITIONAL(KRB4, test "$with_krb4")dnl AM_CONDITIONAL(KRB4, test "$with_krb4")dnl
AC_SUBST(LIB_krb4)dnl AC_SUBST(LIB_krb4)dnl
AC_SUBST(INCLUDE_krb4)dnl AC_SUBST(INCLUDE_krb4)dnl
AM_CONDITIONAL(AIX, test `uname` = AIX)dnl AM_CONDITIONAL(AIX, test "`uname`" = AIX)dnl
AM_CONDITIONAL(AIX4, test "`uname`" = AIX -a "`uname -v`" = 4)
aix_dynamic_afs=yes
AM_CONDITIONAL(AIX_DYNAMIC_AFS, test "$aix_dynamic_afs" = yes)dnl
if test "`uname`" = AIX ;then
if test "$aix_dynamic_afs" = yes; then
AC_FIND_FUNC_NO_LIBS(dlopen, dl)
if test "$ac_cv_funclib_dlopen" = yes; then
AIX_EXTRA_KAFS=
elif test "$ac_cv_funclib_dlopen" != no; then
AIX_EXTRA_KAFS="$ac_cv_funclib_dlopen"
else
AIX_EXTRA_KAFS=-lld
fi
else
AIX_EXTRA_KAFS=
fi
fi
AM_CONDITIONAL(HAVE_DLOPEN, test "$ac_cv_funclib_dlopen" != no)dnl
AC_SUBST(AFS_EXTRA_LD)dnl
AC_SUBST(AIX_EXTRA_KAFS)dnl
AC_ARG_ENABLE(kaserver, AC_ARG_ENABLE(kaserver,
[ --enable-kaserver if you want the KDC to try to emulate a kaserver], [ --enable-kaserver if you want the KDC to try to emulate a kaserver],
@@ -85,7 +124,7 @@ fi
otp=yes otp=yes
AC_ARG_ENABLE(otp, AC_ARG_ENABLE(otp,
[ --disable-otp if you don't want OTP support], [ --disable-otp if you don't want OTP support],
[ [
if test "$enableval" = "no"; then if test "$enableval" = "no"; then
otp=no otp=no
@@ -99,6 +138,18 @@ fi
AC_SUBST(LIB_otp) AC_SUBST(LIB_otp)
AC_SUBST(OTP_dir) AC_SUBST(OTP_dir)
new_des3_code=no
AC_ARG_ENABLE(new-des3-code,
[ --enable-new-des3-code to make new key-deriving des3 the default],
[
if test "$enableval" = "yes"; then
new_des3_code=yes
fi
])
if test "$new_des3_code" = "yes"; then
AC_DEFINE(NEW_DES3_CODE, 1)
fi
AC_PATH_PROG(NROFF, nroff) AC_PATH_PROG(NROFF, nroff)
AC_PATH_PROG(GROFF, groff) AC_PATH_PROG(GROFF, groff)
AC_CACHE_CHECK(how to format man pages,ac_cv_sys_man_format, AC_CACHE_CHECK(how to format man pages,ac_cv_sys_man_format,
@@ -547,6 +598,17 @@ dnl Tests for editline
dnl dnl
AC_FIND_FUNC_NO_LIBS(el_init, edit) AC_FIND_FUNC_NO_LIBS(el_init, edit)
if test "$ac_cv_func_el_init" = yes ; then
AC_CACHE_CHECK(for four argument el_init, ac_cv_func_el_init_four,[
AC_TRY_COMPILE([#include <stdio.h>
#include <histedit.h>],
[el_init("", NULL, NULL, NULL);],
ac_cv_func_el_init_four=yes,
ac_cv_func_el_init_four=no)])
if test "$ac_cv_func_el_init_four" = yes; then
AC_DEFINE(HAVE_FOUR_VALUED_EL_INIT, 1)
fi
fi
AC_FIND_FUNC_NO_LIBS(readline, edit readline) AC_FIND_FUNC_NO_LIBS(readline, edit readline)
ac_foo=no ac_foo=no
if test "$with_readline"; then if test "$with_readline"; then

View File

@@ -0,0 +1,244 @@
Network Working Group M. Horowitz
<draft-horowitz-key-derivation-01.txt> Cygnus Solutions
Internet-Draft March, 1997
Key Derivation for Authentication, Integrity, and Privacy
Status of this Memo
This document is an Internet-Draft. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
To learn the current status of any Internet-Draft, please check the
``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
Directories on ds.internic.net (US East Coast), nic.nordu.net
(Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
Rim).
Distribution of this memo is unlimited. Please send comments to the
author.
Abstract
Recent advances in cryptography have made it desirable to use longer
cryptographic keys, and to make more careful use of these keys. In
particular, it is considered unwise by some cryptographers to use the
same key for multiple purposes. Since most cryptographic-based
systems perform a range of functions, such as authentication, key
exchange, integrity, and encryption, it is desirable to use different
cryptographic keys for these purposes.
This RFC does not define a particular protocol, but defines a set of
cryptographic transformations for use with arbitrary network
protocols and block cryptographic algorithm.
Deriving Keys
In order to use multiple keys for different functions, there are two
possibilities:
- Each protocol ``key'' contains multiple cryptographic keys. The
implementation would know how to break up the protocol ``key'' for
use by the underlying cryptographic routines.
- The protocol ``key'' is used to derive the cryptographic keys.
The implementation would perform this derivation before calling
Horowitz [Page 1]
Internet Draft Key Derivation March, 1997
the underlying cryptographic routines.
In the first solution, the system has the opportunity to provide
separate keys for different functions. This has the advantage that
if one of these keys is broken, the others remain secret. However,
this comes at the cost of larger ``keys'' at the protocol layer. In
addition, since these ``keys'' may be encrypted, compromising the
cryptographic key which is used to encrypt them compromises all the
component keys. Also, the not all ``keys'' are used for all possible
functions. Some ``keys'', especially those derived from passwords,
are generated from limited amounts of entropy. Wasting some of this
entropy on cryptographic keys which are never used is unwise.
The second solution uses keys derived from a base key to perform
cryptographic operations. By carefully specifying how this key is
used, all of the advantages of the first solution can be kept, while
eliminating some disadvantages. In particular, the base key must be
used only for generating the derived keys, and this derivation must
be non-invertible and entropy-preserving. Given these restrictions,
compromise of one derived keys does not compromise the other subkeys.
Attack of the base key is limited, since it is only used for
derivation, and is not exposed to any user data.
Since the derived key has as much entropy as the base keys (if the
cryptosystem is good), password-derived keys have the full benefit of
all the entropy in the password.
To generate a derived key from a base key:
Derived Key = DK(Base Key, Well-Known Constant)
where
DK(Key, Constant) = n-truncate(E(Key, Constant))
In this construction, E(Key, Plaintext) is a block cipher, Constant
is a well-known constant defined by the protocol, and n-truncate
truncates its argument by taking the first n bits; here, n is the key
size of E.
If the output of E is is shorter than n bits, then some entropy in
the key will be lost. If the Constant is smaller than the block size
of E, then it must be padded so it may be encrypted. If the Constant
is larger than the block size, then it must be folded down to the
block size to avoid chaining, which affects the distribution of
entropy.
In any of these situations, a variation of the above construction is
used, where the folded Constant is encrypted, and the resulting
output is fed back into the encryption as necessary (the | indicates
concatentation):
K1 = E(Key, n-fold(Constant))
K2 = E(Key, K1)
Horowitz [Page 2]
Internet Draft Key Derivation March, 1997
K3 = E(Key, K2)
K4 = ...
DK(Key, Constant) = n-truncate(K1 | K2 | K3 | K4 ...)
n-fold is an algorithm which takes m input bits and ``stretches''
them to form n output bits with no loss of entropy, as described in
[Blumenthal96]. In this document, n-fold is always used to produce n
bits of output, where n is the key size of E.
If the size of the Constant is not equal to the block size of E, then
the Constant must be n-folded to the block size of E. This number is
used as input to E. If the block size of E is less than the key
size, then the output from E is taken as input to a second invocation
of E. This process is repeated until the number of bits accumulated
is greater than or equal to the key size of E. When enough bits have
been computed, the first n are taken as the derived key.
Since the derived key is the result of one or more encryptions in the
base key, deriving the base key from the derived key is equivalent to
determining the key from a very small number of plaintext/ciphertext
pairs. Thus, this construction is as strong as the cryptosystem
itself.
Deriving Keys from Passwords
When protecting information with a password or other user data, it is
necessary to convert an arbitrary bit string into an encryption key.
In addition, it is sometimes desirable that the transformation from
password to key be difficult to reverse. A simple variation on the
construction in the prior section can be used:
Key = DK(n-fold(Password), Well-Known Constant)
The n-fold algorithm is reversible, so recovery of the n-fold output
is equivalent to recovery of Password. However, recovering the n-
fold output is difficult for the same reason recovering the base key
from a derived key is difficult.
Traditionally, the transformation from plaintext to ciphertext, or
vice versa, is determined by the cryptographic algorithm and the key.
A simple way to think of derived keys is that the transformation is
determined by the cryptographic algorithm, the constant, and the key.
For interoperability, the constants used to derive keys for different
purposes must be specified in the protocol specification. The
constants must not be specified on the wire, or else an attacker who
determined one derived key could provide the associated constant and
spoof data using that derived key, rather than the one the protocol
designer intended.
Horowitz [Page 3]
Internet Draft Key Derivation March, 1997
Determining which parts of a protocol require their own constants is
an issue for the designer of protocol using derived keys.
Security Considerations
This entire document deals with security considerations relating to
the use of cryptography in network protocols.
Acknowledgements
I would like to thank Uri Blumenthal, Hugo Krawczyk, and Bill
Sommerfeld for their contributions to this document.
References
[Blumenthal96] Blumenthal, U., "A Better Key Schedule for DES-Like
Ciphers", Proceedings of PRAGOCRYPT '96, 1996.
Author's Address
Marc Horowitz
Cygnus Solutions
955 Massachusetts Avenue
Cambridge, MA 02139
Phone: +1 617 354 7688
Email: marc@cygnus.com
Horowitz [Page 4]

View File

@@ -0,0 +1,244 @@
Network Working Group M. Horowitz
<draft-horowitz-key-derivation-01.txt> Cygnus Solutions
Internet-Draft March, 1997
Key Derivation for Authentication, Integrity, and Privacy
Status of this Memo
This document is an Internet-Draft. Internet-Drafts are working
documents of the Internet Engineering Task Force (IETF), its areas,
and its working groups. Note that other groups may also distribute
working documents as Internet-Drafts.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as ``work in progress.''
To learn the current status of any Internet-Draft, please check the
``1id-abstracts.txt'' listing contained in the Internet-Drafts Shadow
Directories on ds.internic.net (US East Coast), nic.nordu.net
(Europe), ftp.isi.edu (US West Coast), or munnari.oz.au (Pacific
Rim).
Distribution of this memo is unlimited. Please send comments to the
author.
Abstract
Recent advances in cryptography have made it desirable to use longer
cryptographic keys, and to make more careful use of these keys. In
particular, it is considered unwise by some cryptographers to use the
same key for multiple purposes. Since most cryptographic-based
systems perform a range of functions, such as authentication, key
exchange, integrity, and encryption, it is desirable to use different
cryptographic keys for these purposes.
This RFC does not define a particular protocol, but defines a set of
cryptographic transformations for use with arbitrary network
protocols and block cryptographic algorithm.
Deriving Keys
In order to use multiple keys for different functions, there are two
possibilities:
- Each protocol ``key'' contains multiple cryptographic keys. The
implementation would know how to break up the protocol ``key'' for
use by the underlying cryptographic routines.
- The protocol ``key'' is used to derive the cryptographic keys.
The implementation would perform this derivation before calling
Horowitz [Page 1]
Internet Draft Key Derivation March, 1997
the underlying cryptographic routines.
In the first solution, the system has the opportunity to provide
separate keys for different functions. This has the advantage that
if one of these keys is broken, the others remain secret. However,
this comes at the cost of larger ``keys'' at the protocol layer. In
addition, since these ``keys'' may be encrypted, compromising the
cryptographic key which is used to encrypt them compromises all the
component keys. Also, the not all ``keys'' are used for all possible
functions. Some ``keys'', especially those derived from passwords,
are generated from limited amounts of entropy. Wasting some of this
entropy on cryptographic keys which are never used is unwise.
The second solution uses keys derived from a base key to perform
cryptographic operations. By carefully specifying how this key is
used, all of the advantages of the first solution can be kept, while
eliminating some disadvantages. In particular, the base key must be
used only for generating the derived keys, and this derivation must
be non-invertible and entropy-preserving. Given these restrictions,
compromise of one derived keys does not compromise the other subkeys.
Attack of the base key is limited, since it is only used for
derivation, and is not exposed to any user data.
Since the derived key has as much entropy as the base keys (if the
cryptosystem is good), password-derived keys have the full benefit of
all the entropy in the password.
To generate a derived key from a base key:
Derived Key = DK(Base Key, Well-Known Constant)
where
DK(Key, Constant) = n-truncate(E(Key, Constant))
In this construction, E(Key, Plaintext) is a block cipher, Constant
is a well-known constant defined by the protocol, and n-truncate
truncates its argument by taking the first n bits; here, n is the key
size of E.
If the output of E is is shorter than n bits, then some entropy in
the key will be lost. If the Constant is smaller than the block size
of E, then it must be padded so it may be encrypted. If the Constant
is larger than the block size, then it must be folded down to the
block size to avoid chaining, which affects the distribution of
entropy.
In any of these situations, a variation of the above construction is
used, where the folded Constant is encrypted, and the resulting
output is fed back into the encryption as necessary (the | indicates
concatentation):
K1 = E(Key, n-fold(Constant))
K2 = E(Key, K1)
Horowitz [Page 2]
Internet Draft Key Derivation March, 1997
K3 = E(Key, K2)
K4 = ...
DK(Key, Constant) = n-truncate(K1 | K2 | K3 | K4 ...)
n-fold is an algorithm which takes m input bits and ``stretches''
them to form n output bits with no loss of entropy, as described in
[Blumenthal96]. In this document, n-fold is always used to produce n
bits of output, where n is the key size of E.
If the size of the Constant is not equal to the block size of E, then
the Constant must be n-folded to the block size of E. This number is
used as input to E. If the block size of E is less than the key
size, then the output from E is taken as input to a second invocation
of E. This process is repeated until the number of bits accumulated
is greater than or equal to the key size of E. When enough bits have
been computed, the first n are taken as the derived key.
Since the derived key is the result of one or more encryptions in the
base key, deriving the base key from the derived key is equivalent to
determining the key from a very small number of plaintext/ciphertext
pairs. Thus, this construction is as strong as the cryptosystem
itself.
Deriving Keys from Passwords
When protecting information with a password or other user data, it is
necessary to convert an arbitrary bit string into an encryption key.
In addition, it is sometimes desirable that the transformation from
password to key be difficult to reverse. A simple variation on the
construction in the prior section can be used:
Key = DK(n-fold(Password), Well-Known Constant)
The n-fold algorithm is reversible, so recovery of the n-fold output
is equivalent to recovery of Password. However, recovering the n-
fold output is difficult for the same reason recovering the base key
from a derived key is difficult.
Traditionally, the transformation from plaintext to ciphertext, or
vice versa, is determined by the cryptographic algorithm and the key.
A simple way to think of derived keys is that the transformation is
determined by the cryptographic algorithm, the constant, and the key.
For interoperability, the constants used to derive keys for different
purposes must be specified in the protocol specification. The
constants must not be specified on the wire, or else an attacker who
determined one derived key could provide the associated constant and
spoof data using that derived key, rather than the one the protocol
designer intended.
Horowitz [Page 3]
Internet Draft Key Derivation March, 1997
Determining which parts of a protocol require their own constants is
an issue for the designer of protocol using derived keys.
Security Considerations
This entire document deals with security considerations relating to
the use of cryptography in network protocols.
Acknowledgements
I would like to thank Uri Blumenthal, Hugo Krawczyk, and Bill
Sommerfeld for their contributions to this document.
References
[Blumenthal96] Blumenthal, U., "A Better Key Schedule for DES-Like
Ciphers", Proceedings of PRAGOCRYPT '96, 1996.
Author's Address
Marc Horowitz
Cygnus Solutions
955 Massachusetts Avenue
Cambridge, MA 02139
Phone: +1 617 354 7688
Email: marc@cygnus.com
Horowitz [Page 4]

View File

@@ -88,7 +88,15 @@ add_new_key(int argc, char **argv)
password = "hemlig"; password = "hemlig";
} }
if(password == NULL){ if(password == NULL){
if(des_read_pw_string(pwbuf, sizeof(pwbuf), "Password: ", 1)) char *princ_name;
char *prompt;
krb5_unparse_name(context, princ_ent, &princ_name);
asprintf (&prompt, "%s's Password: ", princ_name);
free (princ_name);
ret = des_read_pw_string (pwbuf, sizeof(pwbuf), prompt, 1);
free (prompt);
if (ret)
goto out; goto out;
password = pwbuf; password = pwbuf;
} }

View File

@@ -61,17 +61,21 @@ usage(void)
static int static int
do_cpw_entry(krb5_principal principal, void *data) do_cpw_entry(krb5_principal principal, void *data)
{ {
char *pw, pwbuf[128], prompt[128], *pr; char *pw, pwbuf[128];
struct cpw_entry_data *e = data; struct cpw_entry_data *e = data;
krb5_error_code ret = 0; krb5_error_code ret = 0;
pw = e->password; pw = e->password;
if(e->random == 0){ if(e->random == 0){
if(pw == NULL){ if(pw == NULL){
krb5_unparse_name(context, principal, &pr); char *princ_name;
snprintf(prompt, sizeof(prompt), "%s's Password: ", pr); char *prompt;
free(pr);
krb5_unparse_name(context, principal, &princ_name);
asprintf(&prompt, "%s's Password: ", princ_name);
free (princ_name);
ret = des_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 1); ret = des_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 1);
free (prompt);
if(ret){ if(ret){
return 0; /* XXX error code? */ return 0; /* XXX error code? */
} }

View File

@@ -50,7 +50,7 @@ RCSID("$Id$");
kvno kvno
keys... keys...
mkvno (unused) mkvno (unused)
keytype enctype
keyvalue keyvalue
salt (- means use normal salt) salt (- means use normal salt)
creation date and principal creation date and principal
@@ -67,10 +67,24 @@ RCSID("$Id$");
static void static void
append_hex(char *str, krb5_data *data) append_hex(char *str, krb5_data *data)
{ {
int i; int i, s = 1;
char *p = calloc(1, data->length * 2 + 1); char *p;
p = data->data;
for(i = 0; i < data->length; i++) for(i = 0; i < data->length; i++)
sprintf(p + 2 * i, "%02x", ((u_char*)data->data)[i]); if(!isalnum(p[i]) && p[i] != '.'){
s = 0;
break;
}
if(s){
p = calloc(1, data->length + 2 + 1);
p[0] = '\"';
p[data->length + 1] = '\"';
memcpy(p + 1, data->data, data->length);
}else{
p = calloc(1, data->length * 2 + 1);
for(i = 0; i < data->length; i++)
sprintf(p + 2 * i, "%02x", ((u_char*)data->data)[i]);
}
strcat(str, p); strcat(str, p);
free(p); free(p);
} }
@@ -117,6 +131,20 @@ hdb_entry2string(hdb_entry *ent, char **str)
ent->keys.val[i].key.keytype); ent->keys.val[i].key.keytype);
strcat(buf, p); strcat(buf, p);
free(p); free(p);
#if 0
if(ent->keys.val[i].enctypes != NULL) {
int j;
for(j = 0; j < ent->keys.val[i].enctypes->len; j++) {
char tmp[16];
snprintf(tmp, sizeof(tmp), "%u",
ent->keys.val[i].enctypes->val[j]);
if(j > 0)
strcat(buf, ",");
strcat(buf, tmp);
}
}
strcat(buf, ":");
#endif
append_hex(buf, &ent->keys.val[i].key.keyvalue); append_hex(buf, &ent->keys.val[i].key.keyvalue);
strcat(buf, ":"); strcat(buf, ":");
if(ent->keys.val[i].salt){ if(ent->keys.val[i].salt){
@@ -174,6 +202,7 @@ hdb_entry2string(hdb_entry *ent, char **str)
asprintf(&p, "%d", HDBFlags2int(ent->flags)); asprintf(&p, "%d", HDBFlags2int(ent->flags));
strcat(buf, p); strcat(buf, p);
free(p); free(p);
#if 0
strcat(buf, " "); strcat(buf, " ");
if(ent->etypes == NULL || ent->etypes->len == 0) if(ent->etypes == NULL || ent->etypes->len == 0)
@@ -187,6 +216,7 @@ hdb_entry2string(hdb_entry *ent, char **str)
strcat(buf, ":"); strcat(buf, ":");
} }
} }
#endif
*str = strdup(buf); *str = strdup(buf);

View File

@@ -147,10 +147,14 @@ parse_keys(hdb_entry *ent, char *str)
key->salt->type = type; key->salt->type = type;
if (p_len) { if (p_len) {
krb5_data_alloc(&key->salt->salt, (p_len - 1) / 2 + 1); if(*p == '\"'){
for(i = 0; i < p_len; i += 2){ krb5_data_copy(&key->salt->salt, p + 1, p_len - 2);
sscanf(p + i, "%02x", &tmp); }else{
((u_char*)key->salt->salt.data)[i / 2] = tmp; krb5_data_alloc(&key->salt->salt, (p_len - 1) / 2 + 1);
for(i = 0; i < p_len; i += 2){
sscanf(p + i, "%02x", &tmp);
((u_char*)key->salt->salt.data)[i / 2] = tmp;
}
} }
} else } else
krb5_data_zero (&key->salt->salt); krb5_data_zero (&key->salt->salt);
@@ -184,11 +188,12 @@ parse_hdbflags2int(char *str)
return int2HDBFlags(i); return int2HDBFlags(i);
} }
#if 0
static void static void
parse_etypes(char *str, unsigned **val, unsigned *len) parse_etypes(char *str, unsigned **val, unsigned *len)
{ {
unsigned v; unsigned v;
*val = NULL; *val = NULL;
*len = 0; *len = 0;
while(sscanf(str, "%u", &v) == 1) { while(sscanf(str, "%u", &v) == 1) {
@@ -200,6 +205,7 @@ parse_etypes(char *str, unsigned **val, unsigned *len)
str++; str++;
} }
} }
#endif
static void static void
doit(char *filename, int merge) doit(char *filename, int merge)
@@ -292,12 +298,14 @@ doit(char *filename, int merge)
ent.max_life = parse_integer(NULL, e.max_life); ent.max_life = parse_integer(NULL, e.max_life);
ent.max_renew = parse_integer(NULL, e.max_renew); ent.max_renew = parse_integer(NULL, e.max_renew);
ent.flags = parse_hdbflags2int(e.flags); ent.flags = parse_hdbflags2int(e.flags);
#if 0
ALLOC(ent.etypes); ALLOC(ent.etypes);
parse_etypes(e.etypes, &ent.etypes->val, &ent.etypes->len); parse_etypes(e.etypes, &ent.etypes->val, &ent.etypes->len);
if(ent.etypes->len == 0) { if(ent.etypes->len == 0) {
free(ent.etypes); free(ent.etypes);
ent.etypes = NULL; ent.etypes = NULL;
} }
#endif
db->store(context, db, 1, &ent); db->store(context, db, 1, &ent);
hdb_free_entry (context, &ent); hdb_free_entry (context, &ent);

View File

@@ -47,6 +47,7 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
{ {
krb5_error_code ret = 0; krb5_error_code ret = 0;
krb5_principal sprinc = NULL; krb5_principal sprinc = NULL;
krb5_crypto crypto;
hdb_entry *server; hdb_entry *server;
Key *skey; Key *skey;
krb5_data et_data; krb5_data et_data;
@@ -65,18 +66,19 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
from, spn); from, spn);
goto out; goto out;
} }
ret = hdb_etype2key(context, server, t->enc_part.etype, &skey); ret = hdb_enctype2key(context, server, t->enc_part.etype, &skey);
if(ret){ if(ret){
kdc_log(0, "No suitable key found for server (%s) " kdc_log(0, "No suitable key found for server (%s) "
"when converting ticket from ", spn, from); "when converting ticket from ", spn, from);
goto out; goto out;
} }
ret = krb5_decrypt (context, krb5_crypto_init(context, &skey->key, 0, &crypto);
t->enc_part.cipher.data, ret = krb5_decrypt_EncryptedData (context,
t->enc_part.cipher.length, crypto,
t->enc_part.etype, KRB5_KU_TICKET,
&skey->key, &t->enc_part,
&et_data); &et_data);
krb5_crypto_destroy(context, crypto);
if(ret){ if(ret){
kdc_log(0, "Failed to decrypt ticket from %s for %s", from, spn); kdc_log(0, "Failed to decrypt ticket from %s for %s", from, spn);
goto out; goto out;
@@ -118,7 +120,7 @@ do_524(Ticket *t, krb5_data *reply, const char *from)
kdc_log(0, "Failed to encode v4 ticket (%s)", spn); kdc_log(0, "Failed to encode v4 ticket (%s)", spn);
goto out; goto out;
} }
ret = hdb_etype2key(context, server, KEYTYPE_DES, &skey); ret = get_des_key(server, &skey);
if(ret){ if(ret){
kdc_log(0, "No DES key for server (%s)", spn); kdc_log(0, "No DES key for server (%s)", spn);
goto out; goto out;

View File

@@ -289,6 +289,7 @@ process_request(unsigned char *buf,
else if(maybe_version4(buf, len)){ else if(maybe_version4(buf, len)){
*sendlength = 0; /* elbitapmoc sdrawkcab XXX */ *sendlength = 0; /* elbitapmoc sdrawkcab XXX */
do_version4(buf, len, reply, from, (struct sockaddr_in*)addr); do_version4(buf, len, reply, from, (struct sockaddr_in*)addr);
return 0;
}else if(decode_Ticket(buf, len, &ticket, &i) == 0){ }else if(decode_Ticket(buf, len, &ticket, &i) == 0){
ret = do_524(&ticket, reply, from); ret = do_524(&ticket, reply, from);
free_Ticket(&ticket); free_Ticket(&ticket);

View File

@@ -149,13 +149,13 @@ v4_prop(void *arg, Principal *p)
free(s); free(s);
} }
ent.keys.len = 1; ent.kvno = p->key_version;
ALLOC(ent.keys.val); ent.keys.len = 3;
ent.keys.val = malloc(ent.keys.len * sizeof(*ent.keys.val));
ent.keys.val[0].mkvno = p->kdc_key_ver; ent.keys.val[0].mkvno = p->kdc_key_ver;
ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt)); ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
ent.keys.val[0].salt->type = pa_pw_salt; ent.keys.val[0].salt->type = pa_pw_salt;
ent.kvno = p->key_version; ent.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
ent.keys.val[0].key.keytype = KEYTYPE_DES;
krb5_data_alloc(&ent.keys.val[0].key.keyvalue, sizeof(des_cblock)); krb5_data_alloc(&ent.keys.val[0].key.keyvalue, sizeof(des_cblock));
{ {
@@ -170,6 +170,10 @@ v4_prop(void *arg, Principal *p)
ent.flags.invalid = 1; ent.flags.invalid = 1;
} }
} }
copy_Key(&ent.keys.val[0], &ent.keys.val[1]);
ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
copy_Key(&ent.keys.val[0], &ent.keys.val[2]);
ent.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
ALLOC(ent.max_life); ALLOC(ent.max_life);
*ent.max_life = krb_life_to_time(0, p->max_life); *ent.max_life = krb_life_to_time(0, p->max_life);
@@ -270,17 +274,21 @@ ka_convert(struct prop_data *pd, int fd, struct ka_entry *ent, const char *cell)
krb5_warn(pd->context, ret, "krb5_425_conv_principal"); krb5_warn(pd->context, ret, "krb5_425_conv_principal");
return 0; return 0;
} }
hdb.keys.len = 1; hdb.kvno = ntohl(ent->kvno);
ALLOC(hdb.keys.val); hdb.keys.len = 3;
hdb.keys.val = malloc(hdb.keys.len * sizeof(*hdb.keys.val));
hdb.keys.val[0].mkvno = 0; /* XXX */ hdb.keys.val[0].mkvno = 0; /* XXX */
hdb.keys.val[0].salt = calloc(1, sizeof(*hdb.keys.val[0].salt)); hdb.keys.val[0].salt = calloc(1, sizeof(*hdb.keys.val[0].salt));
hdb.keys.val[0].salt->type = hdb_afs3_salt; hdb.keys.val[0].salt->type = hdb_afs3_salt;
hdb.keys.val[0].salt->salt.data = strdup(cell); hdb.keys.val[0].salt->salt.data = strdup(cell);
hdb.keys.val[0].salt->salt.length = strlen(cell); hdb.keys.val[0].salt->salt.length = strlen(cell);
hdb.kvno = ntohl(ent->kvno); hdb.keys.val[0].key.keytype = ETYPE_DES_CBC_MD5;
hdb.keys.val[0].key.keytype = KEYTYPE_DES;
krb5_data_copy(&hdb.keys.val[0].key.keyvalue, ent->key, sizeof(ent->key)); krb5_data_copy(&hdb.keys.val[0].key.keyvalue, ent->key, sizeof(ent->key));
copy_Key(&hdb.keys.val[0], &hdb.keys.val[1]);
hdb.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
copy_Key(&hdb.keys.val[0], &hdb.keys.val[2]);
hdb.keys.val[2].key.keytype = ETYPE_DES_CBC_CRC;
ALLOC(hdb.max_life); ALLOC(hdb.max_life);
*hdb.max_life = ntohl(ent->max_life); *hdb.max_life = ntohl(ent->max_life);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -422,7 +422,7 @@ do_authenticate (struct rx_header *hdr,
} }
/* find a DES key */ /* find a DES key */
ret = hdb_keytype2key(context, client_entry, KEYTYPE_DES, &ckey); ret = get_des_key(client_entry, &ckey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply); make_error_reply (hdr, KANOKEYS, reply);
@@ -430,7 +430,7 @@ do_authenticate (struct rx_header *hdr,
} }
/* find a DES key */ /* find a DES key */
ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey); ret = get_des_key(server_entry, &skey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply); make_error_reply (hdr, KANOKEYS, reply);
@@ -595,7 +595,7 @@ do_getticket (struct rx_header *hdr,
} }
/* find a DES key */ /* find a DES key */
ret = hdb_keytype2key(context, krbtgt_entry, KEYTYPE_DES, &kkey); ret = get_des_key(krbtgt_entry, &kkey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply); make_error_reply (hdr, KANOKEYS, reply);
@@ -603,7 +603,7 @@ do_getticket (struct rx_header *hdr,
} }
/* find a DES key */ /* find a DES key */
ret = hdb_keytype2key(context, server_entry, KEYTYPE_DES, &skey); ret = get_des_key(server_entry, &skey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
make_error_reply (hdr, KANOKEYS, reply); make_error_reply (hdr, KANOKEYS, reply);

View File

@@ -87,6 +87,7 @@ krb5_error_code do_version4 (unsigned char*, size_t, krb5_data*, const char*,
krb5_error_code encode_v4_ticket (void*, size_t, EncTicketPart*, krb5_error_code encode_v4_ticket (void*, size_t, EncTicketPart*,
PrincipalName*, size_t*); PrincipalName*, size_t*);
krb5_error_code encrypt_v4_ticket (void*, size_t, des_cblock*, EncryptedData*); krb5_error_code encrypt_v4_ticket (void*, size_t, des_cblock*, EncryptedData*);
krb5_error_code get_des_key(hdb_entry*, Key**);
int maybe_version4 (unsigned char*, int); int maybe_version4 (unsigned char*, int);
#endif #endif

View File

@@ -111,6 +111,18 @@ db_fetch4(const char *name, const char *instance, const char *realm)
return ent; return ent;
} }
krb5_error_code
get_des_key(hdb_entry *principal, Key **key)
{
krb5_error_code ret;
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD5, key);
if(ret)
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_MD4, key);
if(ret)
ret = hdb_enctype2key(context, principal, ETYPE_DES_CBC_CRC, key);
return ret;
}
#define RCHECK(X, L) if(X){make_err_reply(reply, KFAILURE, "Packet too short"); goto L;} #define RCHECK(X, L) if(X){make_err_reply(reply, KFAILURE, "Packet too short"); goto L;}
krb5_error_code krb5_error_code
@@ -172,7 +184,7 @@ do_version4(unsigned char *buf,
goto out1; goto out1;
} }
ret = hdb_keytype2key(context, client, KEYTYPE_DES, &ckey); ret = get_des_key(client, &ckey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */ /* XXX */
@@ -195,7 +207,7 @@ do_version4(unsigned char *buf,
} }
#endif #endif
ret = hdb_keytype2key(context, server, KEYTYPE_DES, &skey); ret = get_des_key(server, &skey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */ /* XXX */
@@ -275,7 +287,7 @@ do_version4(unsigned char *buf,
goto out2; goto out2;
} }
ret = hdb_keytype2key(context, tgt, KEYTYPE_DES, &tkey); ret = get_des_key(tgt, &tkey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */ /* XXX */
@@ -283,7 +295,6 @@ do_version4(unsigned char *buf,
"No DES key in database (krbtgt)"); "No DES key in database (krbtgt)");
goto out2; goto out2;
} }
RCHECK(krb5_ret_int8(sp, &ticket_len), out2); RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
RCHECK(krb5_ret_int8(sp, &req_len), out2); RCHECK(krb5_ret_int8(sp, &req_len), out2);
@@ -347,12 +358,12 @@ do_version4(unsigned char *buf,
goto out2; goto out2;
} }
ret = hdb_keytype2key(context, server, KEYTYPE_DES, &skey); ret = get_des_key(server, &skey);
if(ret){ if(ret){
kdc_log(0, "%s", krb5_get_err_text(context, ret)); kdc_log(0, "%s", krb5_get_err_text(context, ret));
/* XXX */ /* XXX */
make_err_reply(reply, KDC_NULL_KEY, make_err_reply(reply, KDC_NULL_KEY,
"Server has no DES key"); "No DES key in database (server)");
goto out2; goto out2;
} }
@@ -513,7 +524,9 @@ encode_v4_ticket(void *buf, size_t len, EncTicketPart *et,
sp->store(sp, tmp, sizeof(tmp)); sp->store(sp, tmp, sizeof(tmp));
} }
if(et->key.keytype != KEYTYPE_DES || if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
et->key.keytype != ETYPE_DES_CBC_MD4 &&
et->key.keytype != ETYPE_DES_CBC_CRC) ||
et->key.keyvalue.length != 8) et->key.keyvalue.length != 8)
return -1; return -1;
sp->store(sp, et->key.keyvalue.data, 8); sp->store(sp, et->key.keyvalue.data, 8);

View File

@@ -76,6 +76,40 @@ find_padata(KDC_REQ *req, int *start, int type)
return NULL; return NULL;
} }
#if 0
static krb5_error_code
find_keys(hdb_entry *client,
hdb_entry *server,
Key **ckey,
krb5_enctype *cetype,
Key **skey,
krb5_enctype *setype,
unsigned *etypes,
unsigned num_etypes)
{
int i;
krb5_error_code ret;
for(i = 0; i < num_etypes; i++) {
if(client){
ret = hdb_enctype2key(context, client, etypes[i], ckey);
if(ret)
continue;
}
if(server){
ret = hdb_enctype2key(context, server, etypes[i], skey);
if(ret)
continue;
}
if(etype)
*cetype = *setype = etypes[i];
return 0;
}
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
#else
static krb5_error_code static krb5_error_code
find_etype(hdb_entry *princ, unsigned *etypes, unsigned len, find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
Key **key, int *index) Key **key, int *index)
@@ -83,49 +117,21 @@ find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
int i; int i;
krb5_error_code ret = -1; krb5_error_code ret = -1;
for(i = 0; i < len ; i++) for(i = 0; i < len ; i++)
if((ret = hdb_etype2key(context, princ, etypes[i], key)) == 0) if((ret = hdb_enctype2key(context, princ, etypes[i], key)) == 0)
break; break;
if(index) *index = i; if(index) *index = i;
return ret; return ret;
} }
static krb5_error_code static krb5_error_code
find_keys1(hdb_entry *client, hdb_entry *server, find_keys(hdb_entry *client,
Key **ckey, krb5_enctype *cetype, hdb_entry *server,
Key **skey, krb5_enctype *setype, Key **ckey,
krb5_enctype *sess_ktype, krb5_enctype *cetype,
unsigned *etypes, unsigned num_etypes) Key **skey,
{ krb5_enctype *setype,
int i; unsigned *etypes,
krb5_error_code ret; unsigned num_etypes)
for(i = 0; i < num_etypes; i++) {
if(client){
ret = hdb_etype2key(context, client, etypes[i], ckey);
if(ret)
continue;
}
if(server){
ret = hdb_etype2key(context, server, etypes[i], skey);
if(ret)
continue;
}
if(cetype)
*cetype = etypes[i];
if(setype)
*setype = etypes[i];
if(sess_ktype)
*sess_ktype = etypes[i];
return 0;
}
return KRB5KDC_ERR_ETYPE_NOSUPP;
}
static krb5_error_code
find_keys2(hdb_entry *client, hdb_entry *server,
Key **ckey, krb5_enctype *cetype,
Key **skey, krb5_enctype *setype,
krb5_keytype *sess_ktype,
unsigned *etypes, unsigned num_etypes)
{ {
int i; int i;
krb5_error_code ret; krb5_error_code ret;
@@ -140,43 +146,29 @@ find_keys2(hdb_entry *client, hdb_entry *server,
} }
if(server){ if(server){
/* find session key type */ /* find server key */
ret = find_etype(server, etypes, num_etypes, skey, NULL); ret = find_etype(server, etypes, num_etypes, skey, NULL);
if(ret){ if(ret){
kdc_log(0, "Server has no support for etypes"); kdc_log(0, "Server has no support for etypes");
return KRB5KDC_ERR_ETYPE_NOSUPP; return KRB5KDC_ERR_ETYPE_NOSUPP;
} }
*sess_ktype = (*skey)->key.keytype; *setype = (*skey)->key.keytype;
}
if(server){
/* find server key */
*skey = NULL;
#define is_better(x, y) ((x) > (y))
for(i = 0; i < server->keys.len; i++){
if(*skey == NULL || is_better(server->keys.val[i].key.keytype,
(*skey)->key.keytype))
*skey = &server->keys.val[i];
}
if(*skey == NULL){
kdc_log(0, "No key found for server");
return KRB5KDC_ERR_NULL_KEY;
}
ret = krb5_keytype_to_etype(context, (*skey)->key.keytype, setype);
if(ret)
return ret;
} }
return 0; return 0;
} }
#endif
static krb5_error_code static krb5_error_code
encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek, encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
krb5_enctype setype, int skvno, EncryptionKey *skey, krb5_enctype etype,
krb5_enctype cetype, int ckvno, EncryptionKey *ckey, int skvno, EncryptionKey *skey,
int ckvno, EncryptionKey *ckey,
krb5_data *reply) krb5_data *reply)
{ {
unsigned char buf[8192]; /* XXX The data could be indefinite */ unsigned char buf[8192]; /* XXX The data could be indefinite */
size_t len; size_t len;
krb5_error_code ret; krb5_error_code ret;
krb5_crypto crypto;
ret = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), et, &len); ret = encode_EncTicketPart(buf + sizeof(buf) - 1, sizeof(buf), et, &len);
if(ret) { if(ret) {
@@ -185,13 +177,18 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
return ret; return ret;
} }
krb5_crypto_init(context, skey, etype, &crypto);
krb5_encrypt_EncryptedData(context, krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TICKET,
buf + sizeof(buf) - len, buf + sizeof(buf) - len,
len, len,
setype,
skvno, skvno,
skey,
&rep->ticket.enc_part); &rep->ticket.enc_part);
krb5_crypto_destroy(context, crypto);
if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep) if(rep->msg_type == krb_as_rep && !encode_as_rep_as_tgs_rep)
ret = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf), ret = encode_EncASRepPart(buf + sizeof(buf) - 1, sizeof(buf),
@@ -204,18 +201,27 @@ encode_reply(KDC_REP *rep, EncTicketPart *et, EncKDCRepPart *ek,
krb5_get_err_text(context, ret)); krb5_get_err_text(context, ret));
return ret; return ret;
} }
krb5_encrypt_EncryptedData(context, krb5_crypto_init(context, ckey, 0, &crypto);
buf + sizeof(buf) - len, if(rep->msg_type == krb_as_rep) {
len, krb5_encrypt_EncryptedData(context,
cetype, crypto,
ckvno, KRB5_KU_AS_REP_ENC_PART,
ckey, buf + sizeof(buf) - len,
&rep->enc_part); len,
ckvno,
if(rep->msg_type == krb_as_rep) &rep->enc_part);
ret = encode_AS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len); ret = encode_AS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
else } else {
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TGS_REP_ENC_PART_SESSION,
buf + sizeof(buf) - len,
len,
ckvno,
&rep->enc_part);
ret = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len); ret = encode_TGS_REP(buf + sizeof(buf) - 1, sizeof(buf), rep, &len);
}
krb5_crypto_destroy(context, crypto);
if(ret) { if(ret) {
kdc_log(0, "Failed to encode KDC-REP: %s", kdc_log(0, "Failed to encode KDC-REP: %s",
krb5_get_err_text(context, ret)); krb5_get_err_text(context, ret));
@@ -243,51 +249,47 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client)
krb5_error_code ret = 0; krb5_error_code ret = 0;
int i; int i;
ETYPE_INFO pa; ETYPE_INFO pa;
ETYPE_INFO_ENTRY *tmp;
unsigned char *buf; unsigned char *buf;
size_t len; size_t len;
pa.val = NULL;
pa.len = 0;
for(i = 0; i < client->keys.len; i++){
krb5_enctype *etypes, *e;
krb5_enctype ex[2];
ex[0] = client->keys.val[i].key.keytype; pa.len = client->keys.len;
ex[1] = 0; pa.val = malloc(pa.len * sizeof(*pa.val));
if(context->ktype_is_etype) if(pa.val == NULL)
ret = krb5_keytype_to_etypes(context, return ENOMEM;
client->keys.val[i].key.keytype, for(i = 0; i < client->keys.len; i++) {
&etypes); pa.val[i].etype = client->keys.val[i].key.keytype;
else ALLOC(pa.val[i].salttype);
etypes = ex; if(client->keys.val[i].salt){
for(e = etypes; *e; e++){ #if 0
tmp = realloc(pa.val, (pa.len + 1) * sizeof(*pa.val)); if(client->keys.val[i].salt->type == hdb_pw_salt)
if(tmp == NULL) { *pa.val[i].salttype = 0; /* or 1? or NULL? */
free_ETYPE_INFO(&pa); else if(client->keys.val[i].salt->type == hdb_afs3_salt)
return ret; *pa.val[i].salttype = 2;
}
pa.val = tmp;
pa.val[pa.len].etype = *e;
ALLOC(pa.val[pa.len].salttype);
if(client->keys.val[i].salt){
*pa.val[pa.len].salttype = client->keys.val[i].salt->type;
ALLOC(pa.val[pa.len].salt);
ret = copy_octet_string(&client->keys.val[i].salt->salt,
pa.val[pa.len].salt);
if(tmp == NULL) {
free_ETYPE_INFO(&pa);
return ret;
}
}
else { else {
*pa.val[pa.len].salttype = pa_pw_salt; free_ETYPE_INFO(&pa);
pa.val[pa.len].salt = NULL; kdc_log(0, "unknown salt-type: %d",
client->keys.val[i].salt->type);
return KRB5KRB_ERR_GENERIC;
} }
pa.len++; /* according to `the specs', we can't send a salt if
we have AFS3 salted key, but that requires that you
*know* what cell you are using (e.g by assuming
that the cell is the same as the realm in lower
case) */
#else
*pa.val[i].salttype = client->keys.val[i].salt->type;
#endif
krb5_copy_data(context, &client->keys.val[i].salt->salt,
&pa.val[i].salt);
} else {
#if 0
*pa.val[i].salttype = 1; /* or 0 with salt? */
#else
*pa.val[i].salttype = pa_pw_salt;
#endif
pa.val[i].salt = NULL;
} }
if(context->ktype_is_etype)
free(etypes);
} }
len = length_ETYPE_INFO(&pa); len = length_ETYPE_INFO(&pa);
buf = malloc(len); buf = malloc(len);
@@ -313,29 +315,29 @@ check_flags(hdb_entry *client, const char *client_name,
hdb_entry *server, const char *server_name, hdb_entry *server, const char *server_name,
krb5_boolean is_as_req) krb5_boolean is_as_req)
{ {
/* check client */ if(client != NULL) {
if (client != NULL) { /* check client */
if (client->flags.invalid) { if (client->flags.invalid) {
kdc_log(0, "Client (%s) has invalid bit set", client_name); kdc_log(0, "Client (%s) has invalid bit set", client_name);
return KRB5KDC_ERR_POLICY; return KRB5KDC_ERR_POLICY;
} }
if(!client->flags.client){ if(!client->flags.client){
kdc_log(0, "Principal may not act as client -- %s", kdc_log(0, "Principal may not act as client -- %s",
client_name); client_name);
return KRB5KDC_ERR_POLICY; return KRB5KDC_ERR_POLICY;
} }
if (client->valid_start && *client->valid_start > kdc_time) { if (client->valid_start && *client->valid_start > kdc_time) {
kdc_log(0, "Client not yet valid -- %s", client_name); kdc_log(0, "Client not yet valid -- %s", client_name);
return KRB5KDC_ERR_CLIENT_NOTYET; return KRB5KDC_ERR_CLIENT_NOTYET;
} }
if (client->valid_end && *client->valid_end < kdc_time) { if (client->valid_end && *client->valid_end < kdc_time) {
kdc_log(0, "Client expired -- %s", client_name); kdc_log(0, "Client expired -- %s", client_name);
return KRB5KDC_ERR_NAME_EXP; return KRB5KDC_ERR_NAME_EXP;
} }
if (client->pw_end && *client->pw_end < kdc_time if (client->pw_end && *client->pw_end < kdc_time
&& !server->flags.change_pw) { && !server->flags.change_pw) {
kdc_log(0, "Client's key has expired -- %s", client_name); kdc_log(0, "Client's key has expired -- %s", client_name);
@@ -410,17 +412,13 @@ as_rep(KDC_REQ *req,
KDCOptions f = b->kdc_options; KDCOptions f = b->kdc_options;
hdb_entry *client = NULL, *server = NULL; hdb_entry *client = NULL, *server = NULL;
krb5_enctype cetype, setype; krb5_enctype cetype, setype;
#ifndef KTYPE_IS_ETYPE
krb5_keytype sess_ktype;
#else
krb5_enctype sess_ktype;
#endif
EncTicketPart et; EncTicketPart et;
EncKDCRepPart ek; EncKDCRepPart ek;
krb5_principal client_princ, server_princ; krb5_principal client_princ, server_princ;
char *client_name, *server_name; char *client_name, *server_name;
krb5_error_code ret = 0; krb5_error_code ret = 0;
const char *e_text = NULL; const char *e_text = NULL;
krb5_crypto crypto;
Key *ckey, *skey; Key *ckey, *skey;
@@ -495,7 +493,7 @@ as_rep(KDC_REQ *req,
goto out; goto out;
} }
ret = hdb_etype2key(context, client, enc_data.etype, &pa_key); ret = hdb_enctype2key(context, client, enc_data.etype, &pa_key);
if(ret){ if(ret){
e_text = "No key matches pa-data"; e_text = "No key matches pa-data";
ret = KRB5KDC_ERR_PREAUTH_FAILED; ret = KRB5KDC_ERR_PREAUTH_FAILED;
@@ -505,10 +503,13 @@ as_rep(KDC_REQ *req,
continue; continue;
} }
krb5_crypto_init(context, &pa_key->key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context, ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_PA_ENC_TIMESTAMP,
&enc_data, &enc_data,
&pa_key->key,
&ts_data); &ts_data);
krb5_crypto_destroy(context, crypto);
free_EncryptedData(&enc_data); free_EncryptedData(&enc_data);
if(ret){ if(ret){
e_text = "Failed to decrypt PA-DATA"; e_text = "Failed to decrypt PA-DATA";
@@ -567,7 +568,7 @@ as_rep(KDC_REQ *req,
pa->padata_value.length = 0; pa->padata_value.length = 0;
pa->padata_value.data = NULL; pa->padata_value.data = NULL;
ret = get_pa_etype_info(&method_data, client); ret = get_pa_etype_info(&method_data, client); /* XXX check ret */
len = length_METHOD_DATA(&method_data); len = length_METHOD_DATA(&method_data);
buf = malloc(len); buf = malloc(len);
@@ -593,35 +594,22 @@ as_rep(KDC_REQ *req,
ret = 0; ret = 0;
goto out2; goto out2;
} }
if(context->ktype_is_etype) ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
ret = find_keys1(client, server, &ckey, &cetype, &skey, &setype, b->etype.val, b->etype.len);
&sess_ktype, b->etype.val, b->etype.len);
else
ret = find_keys2(client, server, &ckey, &cetype, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
if(ret) { if(ret) {
kdc_log(0, "Server/client has no support for etypes"); kdc_log(0, "Server/client has no support for etypes");
goto out; goto out;
} }
{ {
char *cet, *set = NULL, *skt = NULL; char *cet;
krb5_etype_to_string(context, cetype, &cet); char *set;
if(context->ktype_is_etype){ krb5_enctype_to_string(context, cetype, &cet);
kdc_log(5, "Using %s", cet); krb5_enctype_to_string(context, setype, &set);
}else{ kdc_log(5, "Using %s/%s", cet, set);
if(cetype != setype)
krb5_etype_to_string(context, setype, &set);
krb5_keytype_to_string(context, sess_ktype, &skt);
if(set)
kdc_log(5, "Using %s/%s/%s", cet, set, skt);
else
kdc_log(5, "Using %s/%s", cet, skt);
}
free(skt);
free(set);
free(cet); free(cet);
free(set);
} }
@@ -678,13 +666,7 @@ as_rep(KDC_REQ *req,
goto out; goto out;
} }
if(context->ktype_is_etype) { krb5_generate_random_keyblock(context, setype, &et.key);
krb5_keytype kt;
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
krb5_generate_random_keyblock(context, kt, &et.key);
et.key.keytype = sess_ktype;
}else
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
copy_PrincipalName(b->cname, &et.cname); copy_PrincipalName(b->cname, &et.cname);
copy_Realm(&b->realm, &et.crealm); copy_Realm(&b->realm, &et.crealm);
@@ -774,12 +756,12 @@ as_rep(KDC_REQ *req,
ek.nonce = b->nonce; ek.nonce = b->nonce;
if (client->valid_end || client->pw_end) { if (client->valid_end || client->pw_end) {
ALLOC(ek.key_expiration); ALLOC(ek.key_expiration);
if (client->valid_end) if (client->valid_end) {
if (client->pw_end) if (client->pw_end)
*ek.key_expiration = min(*client->valid_end, *client->pw_end); *ek.key_expiration = min(*client->valid_end, *client->pw_end);
else else
*ek.key_expiration = *client->valid_end; *ek.key_expiration = *client->valid_end;
else } else
*ek.key_expiration = *client->pw_end; *ek.key_expiration = *client->pw_end;
} else } else
ek.key_expiration = NULL; ek.key_expiration = NULL;
@@ -803,7 +785,7 @@ as_rep(KDC_REQ *req,
set_salt_padata (&rep.padata, ckey->salt); set_salt_padata (&rep.padata, ckey->salt);
ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key, ret = encode_reply(&rep, &et, &ek, setype, server->kvno, &skey->key,
cetype, client->kvno, &ckey->key, reply); client->kvno, &ckey->key, reply);
free_EncTicketPart(&et); free_EncTicketPart(&et);
free_EncKDCRepPart(&ek); free_EncKDCRepPart(&ek);
free_AS_REP(&rep); free_AS_REP(&rep);
@@ -1017,21 +999,16 @@ tgs_make_reply(KDC_REQ_BODY *b,
EncTicketPart et; EncTicketPart et;
KDCOptions f = b->kdc_options; KDCOptions f = b->kdc_options;
krb5_error_code ret; krb5_error_code ret;
krb5_enctype setype; krb5_enctype etype;
Key *skey; Key *skey;
EncryptionKey *ekey; EncryptionKey *ekey;
#ifndef KTYPE_IS_ETYPE
krb5_keytype sess_ktype;
#else
krb5_enctype sess_ktype;
#endif
if(adtkt) { if(adtkt) {
int i; int i;
krb5_keytype kt; krb5_keytype kt;
ekey = &adtkt->key; ekey = &adtkt->key;
for(i = 0; i < b->etype.len; i++){ for(i = 0; i < b->etype.len; i++){
ret = krb5_etype_to_keytype(context, b->etype.val[i], &kt); ret = krb5_enctype_to_keytype(context, b->etype.val[i], &kt);
if(ret) if(ret)
continue; continue;
if(adtkt->key.keytype == kt) if(adtkt->key.keytype == kt)
@@ -1039,18 +1016,10 @@ tgs_make_reply(KDC_REQ_BODY *b,
} }
if(i == b->etype.len) if(i == b->etype.len)
return KRB5KDC_ERR_ETYPE_NOSUPP; return KRB5KDC_ERR_ETYPE_NOSUPP;
setype = b->etype.val[i]; etype = b->etype.val[i];
if(context->ktype_is_etype)
sess_ktype = b->etype.val[i];
else
sess_ktype = kt;
}else{ }else{
if(context->ktype_is_etype) ret = find_keys(NULL, server, NULL, NULL, &skey, &etype,
ret = find_keys1(NULL, server, NULL, NULL, &skey, &setype, b->etype.val, b->etype.len);
&sess_ktype, b->etype.val, b->etype.len);
else
ret = find_keys2(NULL, server, NULL, NULL, &skey, &setype,
&sess_ktype, b->etype.val, b->etype.len);
if(ret) { if(ret) {
kdc_log(0, "Server has no support for etypes"); kdc_log(0, "Server has no support for etypes");
return ret; return ret;
@@ -1146,13 +1115,7 @@ tgs_make_reply(KDC_REQ_BODY *b,
/* XXX Check enc-authorization-data */ /* XXX Check enc-authorization-data */
et.authorization_data = auth_data; et.authorization_data = auth_data;
if(context->ktype_is_etype) { krb5_generate_random_keyblock(context, etype, &et.key);
krb5_keytype kt;
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
krb5_generate_random_keyblock(context, kt, &et.key);
et.key.keytype = sess_ktype;
}else
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
et.crealm = tgt->crealm; et.crealm = tgt->crealm;
et.cname = tgt->cname; et.cname = tgt->cname;
@@ -1179,8 +1142,8 @@ tgs_make_reply(KDC_REQ_BODY *b,
CAST session key. Should the DES3 etype be added to the CAST session key. Should the DES3 etype be added to the
etype list, even if we don't want a session key with etype list, even if we don't want a session key with
DES3? */ DES3? */
ret = encode_reply(&rep, &et, &ek, setype, adtkt ? 0 : server->kvno, ekey, ret = encode_reply(&rep, &et, &ek, etype, adtkt ? 0 : server->kvno, ekey,
cetype, 0, &tgt->key, reply); 0, &tgt->key, reply);
out: out:
free_TGS_REP(&rep); free_TGS_REP(&rep);
free_TransitedEncoding(&et.transited); free_TransitedEncoding(&et.transited);
@@ -1196,12 +1159,14 @@ out:
static krb5_error_code static krb5_error_code
tgs_check_authenticator(krb5_auth_context ac, tgs_check_authenticator(krb5_auth_context ac,
KDC_REQ_BODY *b, krb5_keyblock *key) KDC_REQ_BODY *b,
krb5_keyblock *key)
{ {
krb5_authenticator auth; krb5_authenticator auth;
size_t len; size_t len;
unsigned char buf[8192]; unsigned char buf[8192];
krb5_error_code ret; krb5_error_code ret;
krb5_crypto crypto;
krb5_auth_getauthenticator(context, ac, &auth); krb5_auth_getauthenticator(context, ac, &auth);
if(auth->cksum == NULL){ if(auth->cksum == NULL){
@@ -1215,10 +1180,10 @@ tgs_check_authenticator(krb5_auth_context ac,
*/ */
if ( if (
#if 0 #if 0
!krb5_checksum_is_keyed(auth->cksum->cksumtype) !krb5_checksum_is_keyed(context, auth->cksum->cksumtype)
|| ||
#endif #endif
!krb5_checksum_is_collision_proof(auth->cksum->cksumtype)) { !krb5_checksum_is_collision_proof(context, auth->cksum->cksumtype)) {
kdc_log(0, "Bad checksum type in authenticator: %d", kdc_log(0, "Bad checksum type in authenticator: %d",
auth->cksum->cksumtype); auth->cksum->cksumtype);
ret = KRB5KRB_AP_ERR_INAPP_CKSUM; ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
@@ -1233,9 +1198,14 @@ tgs_check_authenticator(krb5_auth_context ac,
krb5_get_err_text(context, ret)); krb5_get_err_text(context, ret));
goto out; goto out;
} }
ret = krb5_verify_checksum(context, buf + sizeof(buf) - len, len, krb5_crypto_init(context, key, 0, &crypto);
key, ret = krb5_verify_checksum(context,
crypto,
KRB5_KU_TGS_REQ_AUTH_CKSUM,
buf + sizeof(buf) - len,
len,
auth->cksum); auth->cksum);
krb5_crypto_destroy(context, crypto);
if(ret){ if(ret){
kdc_log(0, "Failed to verify checksum: %s", kdc_log(0, "Failed to verify checksum: %s",
krb5_get_err_text(context, ret)); krb5_get_err_text(context, ret));
@@ -1282,6 +1252,7 @@ tgs_rep2(KDC_REQ_BODY *b,
krb5_ticket *ticket = NULL; krb5_ticket *ticket = NULL;
krb5_flags ap_req_options; krb5_flags ap_req_options;
const char *e_text = NULL; const char *e_text = NULL;
krb5_crypto crypto;
hdb_entry *krbtgt = NULL; hdb_entry *krbtgt = NULL;
EncTicketPart *tgt; EncTicketPart *tgt;
@@ -1335,10 +1306,10 @@ tgs_rep2(KDC_REQ_BODY *b,
goto out2; goto out2;
} }
ret = hdb_etype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey); ret = hdb_enctype2key(context, krbtgt, ap_req.ticket.enc_part.etype, &tkey);
if(ret){ if(ret){
char *str; char *str;
krb5_etype_to_string(context, ap_req.ticket.enc_part.etype, &str); krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
kdc_log(0, "No server key found for %s", str); kdc_log(0, "No server key found for %s", str);
free(str); free(str);
ret = KRB5KRB_AP_ERR_BADKEYVER; ret = KRB5KRB_AP_ERR_BADKEYVER;
@@ -1390,10 +1361,13 @@ tgs_rep2(KDC_REQ_BODY *b,
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out2; goto out2;
} }
krb5_crypto_init(context, subkey, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context, ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
b->enc_authorization_data, b->enc_authorization_data,
subkey,
&ad); &ad);
krb5_crypto_destroy(context, crypto);
if(ret){ if(ret){
kdc_log(0, "Failed to decrypt enc-authorization-data"); kdc_log(0, "Failed to decrypt enc-authorization-data");
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
@@ -1455,7 +1429,7 @@ tgs_rep2(KDC_REQ_BODY *b,
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
goto out; goto out;
} }
ret = hdb_etype2key(context, uu, t->enc_part.etype, &tkey); ret = hdb_enctype2key(context, uu, t->enc_part.etype, &tkey);
if(ret){ if(ret){
ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */ ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
goto out; goto out;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -71,18 +71,23 @@ int main(int argc, char **argv)
krb5_errx(context, 0, "%s", heimdal_version); krb5_errx(context, 0, "%s", heimdal_version);
key.keytype = KEYTYPE_DES; key.keytype = ETYPE_DES_CBC_MD5; /* XXX */
key.keyvalue.length = sizeof(des_cblock);
key.keyvalue.data = malloc(key.keyvalue.length);
if(v4_keyfile){ if(v4_keyfile){
f = fopen(v4_keyfile, "r"); f = fopen(v4_keyfile, "r");
if(f == NULL) if(f == NULL)
krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile); krb5_err(context, 1, errno, "fopen(%s)", v4_keyfile);
key.keyvalue.length = sizeof(des_cblock);
key.keyvalue.data = malloc(key.keyvalue.length);
fread(key.keyvalue.data, 1, key.keyvalue.length, f); fread(key.keyvalue.data, 1, key.keyvalue.length, f);
fclose(f); fclose(f);
}else{ }else{
krb5_salt salt;
salt.salttype = KRB5_PW_SALT;
/* XXX better value? */
salt.saltvalue.data = NULL;
salt.saltvalue.length = 0;
des_read_pw_string(buf, sizeof(buf), "Master key: ", 1); des_read_pw_string(buf, sizeof(buf), "Master key: ", 1);
des_string_to_key(buf, key.keyvalue.data); krb5_string_to_key_salt(context, key.keytype, buf, salt, &key);
} }
#ifdef HAVE_UMASK #ifdef HAVE_UMASK

View File

@@ -47,7 +47,7 @@ int afs;
char *principal; char *principal;
char *cell; char *cell;
char *password; char *password;
char *keytype_str = "des"; char *keytype_str = "des-cbc-md5";
int version; int version;
int help; int help;
@@ -73,12 +73,15 @@ usage(int status)
} }
static void static void
tokey(krb5_context context, const char *password, krb5_data *salt, tokey(krb5_context context,
krb5_keytype keytype, const char *label) krb5_enctype enctype,
const char *password,
krb5_salt salt,
const char *label)
{ {
int i; int i;
krb5_keyblock key; krb5_keyblock key;
krb5_string_to_key(password, salt, keytype, &key); krb5_string_to_key_salt(context, enctype, password, salt, &key);
printf("%s: ", label); printf("%s: ", label);
for(i = 0; i < key.keyvalue.length; i++) for(i = 0; i < key.keyvalue.length; i++)
printf("%02x", ((unsigned char*)key.keyvalue.data)[i]); printf("%02x", ((unsigned char*)key.keyvalue.data)[i]);
@@ -91,10 +94,10 @@ main(int argc, char **argv)
{ {
krb5_context context; krb5_context context;
krb5_principal princ; krb5_principal princ;
krb5_data salt; krb5_salt salt;
int optind; int optind;
char buf[1024]; char buf[1024];
krb5_keytype keytype; krb5_enctype etype;
krb5_error_code ret; krb5_error_code ret;
set_progname(argv[0]); set_progname(argv[0]);
@@ -120,11 +123,21 @@ main(int argc, char **argv)
if(!version5 && !version4 && !afs) if(!version5 && !version4 && !afs)
version5 = 1; version5 = 1;
ret = krb5_string_to_keytype(context, keytype_str, &keytype); ret = krb5_string_to_enctype(context, keytype_str, &etype);
#if 0
if(ret) {
krb5_keytype keytype;
ret = krb5_string_to_keytype(context, keytype_str, &keytype);
ret = krb5_keytype_to_enctype(context, keytype, &etype);
}
#endif
if(ret) if(ret)
krb5_err(context, 1, ret, "%s", keytype); krb5_err(context, 1, ret, "%s", keytype_str);
if(keytype != KEYTYPE_DES && (afs || version4)) if((etype != ETYPE_DES_CBC_CRC &&
etype != ETYPE_DES_CBC_MD4 &&
etype != ETYPE_DES_CBC_MD5) &&
(afs || version4))
krb5_errx(context, 1, krb5_errx(context, 1,
"DES is the only valid keytype for AFS and Kerberos 4"); "DES is the only valid keytype for AFS and Kerberos 4");
@@ -150,20 +163,21 @@ main(int argc, char **argv)
if(version5){ if(version5){
krb5_parse_name(context, principal, &princ); krb5_parse_name(context, principal, &princ);
salt.length = 0; krb5_get_pw_salt(context, princ, &salt);
salt.data = NULL; tokey(context, etype, password, salt, "Kerberos v5 key");
krb5_get_salt(princ, &salt); krb5_free_salt(context, salt);
tokey(context, password, &salt, keytype, "Kerberos v5 key");
} }
if(version4){ if(version4){
salt.length = 0; salt.salttype = KRB5_PW_SALT;
salt.data = NULL; salt.saltvalue.length = 0;
tokey(context, password, &salt, KEYTYPE_DES, "Kerberos v4 key"); salt.saltvalue.data = NULL;
tokey(context, ETYPE_DES_CBC_MD5, password, salt, "Kerberos v4 key");
} }
if(afs){ if(afs){
salt.length = strlen(cell); salt.salttype = KRB5_AFS3_SALT;
salt.data = cell; salt.saltvalue.length = strlen(cell);
tokey(context, password, &salt, KEYTYPE_DES_AFS3, "AFS key"); salt.saltvalue.data = cell;
tokey(context, ETYPE_DES_CBC_MD5, password, salt, "AFS key");
} }
return 0; return 0;
} }

View File

@@ -212,7 +212,7 @@ change (krb5_auth_context auth_context,
char *c; char *c;
kadm5_principal_ent_rec ent; kadm5_principal_ent_rec ent;
krb5_key_data *kd; krb5_key_data *kd;
krb5_data salt; krb5_salt salt;
krb5_keyblock new_keyblock; krb5_keyblock new_keyblock;
char *pwd_reason; char *pwd_reason;
int unchanged; int unchanged;
@@ -247,15 +247,17 @@ change (krb5_auth_context auth_context,
*/ */
kd = &ent.key_data[0]; kd = &ent.key_data[0];
salt.length = kd->key_data_length[1]; salt.salttype = KRB5_PW_SALT;
salt.data = kd->key_data_contents[1]; salt.saltvalue.length = kd->key_data_length[1];
salt.saltvalue.data = kd->key_data_contents[1];
memset (&new_keyblock, 0, sizeof(new_keyblock)); memset (&new_keyblock, 0, sizeof(new_keyblock));
krb5_string_to_key_data (pwd_data, krb5_string_to_key_data_salt (context,
&salt, kd->key_data_type[0],
kd->key_data_type[0], *pwd_data,
&new_keyblock); salt,
&new_keyblock);
unchanged = new_keyblock.keytype == kd->key_data_type[0] unchanged = new_keyblock.keytype == kd->key_data_type[0]
&& new_keyblock.keyvalue.length == kd->key_data_length[0] && new_keyblock.keyvalue.length == kd->key_data_length[0]

View File

@@ -15,7 +15,7 @@ kauth_SOURCES = kinit.c kauth_options.c
noinst_PROGRAMS = kfoo kverify noinst_PROGRAMS = kfoo kverify
if KRB4 if KRB4
AFSLIB=$(top_builddir)/lib/kafs/libkafs.a AFSLIB=$(top_builddir)/lib/kafs/libkafs.a $(AIX_EXTRA_KAFS)
else else
AFSLIB= AFSLIB=
endif endif

View File

@@ -55,6 +55,7 @@ char *renew_life = NULL;
char *server = NULL; char *server = NULL;
char *cred_cache = NULL; char *cred_cache = NULL;
char *start_str = NULL; char *start_str = NULL;
struct getarg_strings etype_str;
int use_keytab = 0; int use_keytab = 0;
char *keytab_str = NULL; char *keytab_str = NULL;
#ifdef KRB4 #ifdef KRB4
@@ -73,9 +74,6 @@ struct getargs args[] = {
{ "cache", 'c', arg_string, &cred_cache, { "cache", 'c', arg_string, &cred_cache,
"credentials cache", "cachename" }, "credentials cache", "cachename" },
{ "cache", 'c', arg_string, &cred_cache,
"credentials cache", "cachename" },
{ "forwardable", 'f', arg_flag, &forwardable, { "forwardable", 'f', arg_flag, &forwardable,
"get forwardable tickets"}, "get forwardable tickets"},
@@ -109,6 +107,9 @@ struct getargs args[] = {
{ "validate", 'v', arg_flag, &validate_flag, { "validate", 'v', arg_flag, &validate_flag,
"validate TGT" }, "validate TGT" },
{ "enctypes", 'e', arg_strings, &etype_str,
"encryption type to use", "enctype" },
{ "version", 0, arg_flag, &version_flag }, { "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag } { "help", 0, arg_flag, &help_flag }
}; };
@@ -272,6 +273,23 @@ main (int argc, char **argv)
start_time = tmp; start_time = tmp;
} }
if(etype_str.num_strings) {
krb5_enctype *enctype = NULL;
int i;
enctype = malloc(etype_str.num_strings * sizeof(*enctype));
if(enctype == NULL)
errx(1, "out of memory");
for(i = 0; i < etype_str.num_strings; i++) {
ret = krb5_string_to_enctype(context,
etype_str.strings[i],
&enctype[i]);
if(ret)
errx(1, "unrecognized enctype: %s", etype_str.strings[i]);
}
krb5_get_init_creds_opt_set_etype_list(&opt, enctype,
etype_str.num_strings);
}
argc -= optind; argc -= optind;
argv += optind; argv += optind;

View File

@@ -104,17 +104,26 @@ print_cred_verbose(krb5_context context, krb5_creds *cred)
size_t len; size_t len;
char *s; char *s;
decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len); decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
krb5_etype_to_string(context, t.enc_part.etype, &s); krb5_enctype_to_string(context, t.enc_part.etype, &s);
printf("Ticket etype: %s", s); printf("Ticket etype: %s", s);
free(s); free(s);
if(t.enc_part.kvno) if(t.enc_part.kvno)
printf(", kvno %d", *t.enc_part.kvno); printf(", kvno %d", *t.enc_part.kvno);
printf("\n"); printf("\n");
if(cred->session.keytype != t.enc_part.etype) {
ret = krb5_keytype_to_string(context, cred->session.keytype, &str);
if(ret == KRB5_PROG_KEYTYPE_NOSUPP)
ret = krb5_enctype_to_string(context, cred->session.keytype,
&str);
if(ret)
krb5_warn(context, ret, "session keytype");
else {
printf("Session key: %s\n", str);
free(str);
}
}
free_Ticket(&t); free_Ticket(&t);
} }
krb5_keytype_to_string(context, cred->session.keytype, &str);
printf("Session key: %s\n", str);
free(str);
printf("Auth time: %s\n", printable_time_long(cred->times.authtime)); printf("Auth time: %s\n", printable_time_long(cred->times.authtime));
if(cred->times.authtime != cred->times.starttime) if(cred->times.authtime != cred->times.starttime)
printf("Start time: %s\n", printable_time_long(cred->times.starttime)); printf("Start time: %s\n", printable_time_long(cred->times.starttime));

View File

@@ -182,15 +182,19 @@ init_auth
goto failure; goto failure;
} }
#if 1
enctype = (*context_handle)->auth_context->keyblock->keytype;
#else
if ((*context_handle)->auth_context->enctype) if ((*context_handle)->auth_context->enctype)
enctype = (*context_handle)->auth_context->enctype; enctype = (*context_handle)->auth_context->enctype;
else { else {
kret = krb5_keytype_to_etype(gssapi_krb5_context, kret = krb5_keytype_to_enctype(gssapi_krb5_context,
(*context_handle)->auth_context->keyblock->keytype, (*context_handle)->auth_context->keyblock->keytype,
&enctype); &enctype);
if (kret) if (kret)
return kret; return kret;
} }
#endif

View File

@@ -182,15 +182,19 @@ init_auth
goto failure; goto failure;
} }
#if 1
enctype = (*context_handle)->auth_context->keyblock->keytype;
#else
if ((*context_handle)->auth_context->enctype) if ((*context_handle)->auth_context->enctype)
enctype = (*context_handle)->auth_context->enctype; enctype = (*context_handle)->auth_context->enctype;
else { else {
kret = krb5_keytype_to_etype(gssapi_krb5_context, kret = krb5_keytype_to_enctype(gssapi_krb5_context,
(*context_handle)->auth_context->keyblock->keytype, (*context_handle)->auth_context->keyblock->keytype,
&enctype); &enctype);
if (kret) if (kret)
return kret; return kret;
} }
#endif

View File

@@ -41,65 +41,31 @@
RCSID("$Id$"); RCSID("$Id$");
krb5_error_code krb5_error_code
hdb_next_keytype2key(krb5_context context, hdb_next_enctype2key(krb5_context context,
hdb_entry *e, hdb_entry *e,
krb5_keytype keytype, krb5_enctype enctype,
Key **key) Key **key)
{ {
int i; Key *k;
if(*key)
i = *key - e->keys.val + 1; for (k = *key ? *key : e->keys.val;
else k < e->keys.val + e->keys.len;
i = 0; k++)
for(; i < e->keys.len; i++) if(k->key.keytype == enctype){
if(e->keys.val[i].key.keytype == keytype){ *key = k;
*key = &e->keys.val[i];
return 0; return 0;
} }
return KRB5_PROG_ETYPE_NOSUPP; /* XXX */ return KRB5_PROG_ETYPE_NOSUPP; /* XXX */
} }
krb5_error_code krb5_error_code
hdb_keytype2key(krb5_context context, hdb_enctype2key(krb5_context context,
hdb_entry *e, hdb_entry *e,
krb5_keytype keytype, krb5_enctype enctype,
Key **key) Key **key)
{ {
*key = NULL; *key = NULL;
return hdb_next_keytype2key(context,e, keytype, key); return hdb_next_enctype2key(context, e, enctype, key);
}
krb5_error_code
hdb_next_etype2key(krb5_context context,
hdb_entry *e,
krb5_enctype etype,
Key **key)
{
krb5_keytype keytype;
krb5_error_code ret;
if(e->etypes) {
/* check if the etype is listed as `supported' by this principal */
int i;
for(i = 0; i < e->etypes->len; i++)
if(etype == e->etypes->val[i])
break;
if(i == e->etypes->len)
return KRB5_PROG_ETYPE_NOSUPP;
}
ret = krb5_etype_to_keytype(context, etype, &keytype);
if(ret)
return ret;
return hdb_next_keytype2key(context, e, keytype, key);
}
krb5_error_code
hdb_etype2key(krb5_context context,
hdb_entry *e,
krb5_enctype etype,
Key **key)
{
*key = NULL;
return hdb_next_etype2key(context,e, etype, key);
} }
/* this is a bit ugly, but will get better when the crypto framework /* this is a bit ugly, but will get better when the crypto framework
@@ -109,7 +75,7 @@ krb5_error_code
hdb_process_master_key(krb5_context context, EncryptionKey key, hdb_process_master_key(krb5_context context, EncryptionKey key,
krb5_data *schedule) krb5_data *schedule)
{ {
if(key.keytype != KEYTYPE_DES) if(key.keytype != ETYPE_DES_CBC_MD5)
return KRB5_PROG_KEYTYPE_NOSUPP; return KRB5_PROG_KEYTYPE_NOSUPP;
schedule->length = sizeof(des_key_schedule); schedule->length = sizeof(des_key_schedule);
schedule->data = malloc(schedule->length); schedule->data = malloc(schedule->length);

View File

@@ -91,15 +91,16 @@ kadm5_s_create_principal(void *server_handle,
kadm5_free_principal_ent(server_handle, defent); kadm5_free_principal_ent(server_handle, defent);
/* XXX this should be fixed */ /* XXX this should be fixed */
ent.keys.len = 2; ent.keys.len = 4;
ent.keys.val = calloc(ent.keys.len, sizeof(*ent.keys.val)); ent.keys.val = calloc(ent.keys.len, sizeof(*ent.keys.val));
ent.keys.val[0].key.keytype = KEYTYPE_DES; ent.keys.val[0].key.keytype = ETYPE_DES_CBC_CRC;
/* flag as version 4 compatible salt; ignored by _kadm5_set_keys /* flag as version 4 compatible salt; ignored by _kadm5_set_keys
if we don't want to be compatible */ if we don't want to be compatible */
ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt)); ent.keys.val[0].salt = calloc(1, sizeof(*ent.keys.val[0].salt));
ent.keys.val[0].salt->type = hdb_pw_salt; ent.keys.val[0].salt->type = hdb_pw_salt;
ent.keys.val[1].key.keytype = KEYTYPE_DES3; ent.keys.val[1].key.keytype = ETYPE_DES_CBC_MD4;
ent.keys.val[2].key.keytype = ETYPE_DES_CBC_MD5;
ent.keys.val[3].key.keytype = ETYPE_DES3_CBC_SHA1;
ret = _kadm5_set_keys(context, &ent, password); ret = _kadm5_set_keys(context, &ent, password);
ent.created_by.time = time(NULL); ent.created_by.time = time(NULL);

View File

@@ -121,8 +121,9 @@ kadm5_s_get_principal(void *server_handle,
int i; int i;
Key *key; Key *key;
krb5_key_data *kd; krb5_key_data *kd;
krb5_data salt, *sp; krb5_salt salt;
krb5_get_salt(ent.principal, &salt); krb5_data *sp;
krb5_get_pw_salt(context->context, ent.principal, &salt);
out->key_data = malloc(ent.keys.len * sizeof(*out->key_data)); out->key_data = malloc(ent.keys.len * sizeof(*out->key_data));
for(i = 0; i < ent.keys.len; i++){ for(i = 0; i < ent.keys.len; i++){
key = &ent.keys.val[i]; key = &ent.keys.val[i];
@@ -147,7 +148,7 @@ kadm5_s_get_principal(void *server_handle,
if(key->salt) if(key->salt)
sp = &key->salt->salt; sp = &key->salt->salt;
else else
sp = &salt; sp = &salt.saltvalue;
kd->key_data_length[1] = sp->length; kd->key_data_length[1] = sp->length;
kd->key_data_contents[1] = malloc(kd->key_data_length[1]); kd->key_data_contents[1] = malloc(kd->key_data_length[1]);
if(kd->key_data_length[1] != 0 if(kd->key_data_length[1] != 0
@@ -159,7 +160,7 @@ kadm5_s_get_principal(void *server_handle,
memcpy(kd->key_data_contents[1], sp->data, kd->key_data_length[1]); memcpy(kd->key_data_contents[1], sp->data, kd->key_data_length[1]);
out->n_key_data = i + 1; out->n_key_data = i + 1;
} }
krb5_data_free(&salt); krb5_free_salt(context->context, salt);
} }
if(ret){ if(ret){
kadm5_free_principal_ent(context, out); kadm5_free_principal_ent(context, out);

View File

@@ -68,8 +68,10 @@ kadm5_s_rename_principal(void *server_handle,
/* fix salt */ /* fix salt */
int i; int i;
Salt salt; Salt salt;
krb5_get_salt(source, &salt.salt); krb5_salt salt2;
krb5_get_pw_salt(context->context, source, &salt2);
salt.type = hdb_pw_salt; salt.type = hdb_pw_salt;
salt.salt = salt2.saltvalue;
for(i = 0; i < ent.keys.len; i++){ for(i = 0; i < ent.keys.len; i++){
if(ent.keys.val[i].salt == NULL){ if(ent.keys.val[i].salt == NULL){
ent.keys.val[i].salt = malloc(sizeof(*ent.keys.val[i].salt)); ent.keys.val[i].salt = malloc(sizeof(*ent.keys.val[i].salt));
@@ -78,7 +80,7 @@ kadm5_s_rename_principal(void *server_handle,
break; break;
} }
} }
free_Salt(&salt); krb5_free_salt(context->context, salt2);
} }
if(ret) if(ret)
goto out2; goto out2;

View File

@@ -42,14 +42,13 @@ RCSID("$Id$");
kadm5_ret_t kadm5_ret_t
_kadm5_set_keys(kadm5_server_context *context, _kadm5_set_keys(kadm5_server_context *context,
hdb_entry *ent, const char *password) hdb_entry *ent,
const char *password)
{ {
int i; int i;
krb5_data salt;
kadm5_ret_t ret = 0; kadm5_ret_t ret = 0;
Key *key; Key *key;
krb5_get_salt(ent->principal, &salt);
for(i = 0; i < ent->keys.len; i++) { for(i = 0; i < ent->keys.len; i++) {
key = &ent->keys.val[i]; key = &ent->keys.val[i];
if(key->salt && if(key->salt &&
@@ -62,21 +61,27 @@ _kadm5_set_keys(kadm5_server_context *context,
key->salt = NULL; key->salt = NULL;
} }
krb5_free_keyblock_contents(context->context, &key->key); krb5_free_keyblock_contents(context->context, &key->key);
{ /* XXX check for DES key and AFS3 salt? */
krb5_keytype kt = key->key.keytype; if(key->salt) {
if(kt == KEYTYPE_DES && krb5_salt salt;
key->salt && salt.salttype = key->salt->type;
key->salt->type == hdb_afs3_salt) salt.saltvalue = key->salt->salt;
kt |= KEYTYPE_USE_AFS3_SALT; ret = krb5_string_to_key_salt(context->context,
ret = krb5_string_to_key(password, key->key.keytype,
key->salt ? &key->salt->salt : &salt, password,
kt, salt,
&key->key);
} else
ret = krb5_string_to_key(context->context,
key->key.keytype,
password,
ent->principal,
&key->key); &key->key);
} if(ret) {
if(ret) krb5_warn(context->context, ret, "string-to-key failed");
break; break;
}
} }
ent->kvno++; ent->kvno++;
krb5_data_free(&salt);
return ret; return ret;
} }

View File

@@ -1,7 +1,15 @@
Tue Dec 1 14:45:15 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* Makefile.am: fix AIX linkage
Sun Nov 22 10:40:44 1998 Assar Westerlund <assar@sics.se> Sun Nov 22 10:40:44 1998 Assar Westerlund <assar@sics.se>
* Makefile.in (WFLAGS): set * Makefile.in (WFLAGS): set
Sat Nov 21 16:55:19 1998 Johan Danielsson <joda@hella.pdc.kth.se>
* afskrb5.c: add homedir support
Sun Sep 6 20:16:27 1998 Assar Westerlund <assar@sics.se> Sun Sep 6 20:16:27 1998 Assar Westerlund <assar@sics.se>
* add new functionality for specifying the homedir to krb_afslog * add new functionality for specifying the homedir to krb_afslog

View File

@@ -2,33 +2,60 @@
AUTOMAKE_OPTIONS = no-dependencies foreign AUTOMAKE_OPTIONS = no-dependencies foreign
INCLUDES = -I$(top_builddir)/include $(INCLUDE_krb4) -DLIBDIR=\"$(libdir)\" INCLUDES = \
-I$(top_builddir)/include \
$(INCLUDE_krb4) \
-DLIBDIR=\"$(libdir)\" \
$(AFS_EXTRA_DEFS)
if KRB4 if KRB4
AFSLIBS = libkafs.a AFSLIBS = libkafs.a
if AIX
AFS_EXTRA_LIBS = afslib.so
else
AFS_EXTRA_LIBS =
endif
else else
AFSLIBS = AFSLIBS =
AFS_EXTRA_LIBS =
endif endif
if AIX
AFSL_EXP = $(srcdir)/afsl.exp
if AIX4
AFS_EXTRA_LD = -bnoentry
else
AFS_EXTRA_LD = -e _nostart
endif
if AIX_DYNAMIC_AFS
if HAVE_DLOPEN
AIX_SRC =
else
AIX_SRC = dlfcn.c
endif
AFS_EXTRA_LIBS = afslib.so
AFS_EXTRA_DEFS =
else
AIX_SRC = afslib.c
AFS_EXTRA_LIBS =
AFS_EXTRA_DEFS = -DSTATIC_AFS
endif
else
AFSL_EXP =
endif # AIX
lib_LIBRARIES = $(AFSLIBS) lib_LIBRARIES = $(AFSLIBS)
foodir=$(libdir) foodir = $(libdir)
foo_DATA = $(AFS_EXTRA_LIBS) foo_DATA = $(AFS_EXTRA_LIBS)
EXTRA_DATA = afslib.so EXTRA_DATA = afslib.so
CLEANFILES= $(AFS_EXTRA_LIBS) CLEANFILES= $(AFS_EXTRA_LIBS)
libkafs_a_SOURCES = afssys.c afskrb.c afskrb5.c common.c libkafs_a_SOURCES = afssys.c afskrb.c afskrb5.c common.c $(AIX_SRC)
#afslib_so_SOURCES = afslib.c #afslib_so_SOURCES = afslib.c
# AIX: this almost works with gcc, but somehow it fails to use the # AIX: this almost works with gcc, but somehow it fails to use the
# correct ld, use ld instead # correct ld, use ld instead
afslib.so: afslib.o afslib.so: afslib.o
ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp -bnoentry afslib.o -lc ld -o $@ -bM:SRE -bI:$(srcdir)/afsl.exp -bE:$(srcdir)/afslib.exp $(AFS_EXTRA_LD) afslib.o -lc
$(OBJECTS): ../../include/config.h $(OBJECTS): ../../include/config.h

View File

@@ -24,7 +24,6 @@ libkrb5_la_SOURCES = \
build_auth.c \ build_auth.c \
cache.c \ cache.c \
changepw.c \ changepw.c \
checksum.c \
codec.c \ codec.c \
config_file.c \ config_file.c \
convert_creds.c \ convert_creds.c \
@@ -32,8 +31,8 @@ libkrb5_la_SOURCES = \
context.c \ context.c \
crc.c \ crc.c \
creds.c \ creds.c \
crypto.c \
data.c \ data.c \
encrypt.c \
fcache.c \ fcache.c \
free.c \ free.c \
free_host_realm.c \ free_host_realm.c \
@@ -67,6 +66,7 @@ libkrb5_la_SOURCES = \
mk_safe.c \ mk_safe.c \
net_read.c \ net_read.c \
net_write.c \ net_write.c \
n-fold.c \
padata.c \ padata.c \
principal.c \ principal.c \
prog_setup.c \ prog_setup.c \
@@ -87,7 +87,6 @@ libkrb5_la_SOURCES = \
store_emem.c \ store_emem.c \
store_fd.c \ store_fd.c \
store_mem.c \ store_mem.c \
str2key.c \
ticket.c \ ticket.c \
time.c \ time.c \
transited.c \ transited.c \

View File

@@ -58,8 +58,6 @@ krb5_auth_con_init(krb5_context context,
memset (p->authenticator, 0, sizeof(*p->authenticator)); memset (p->authenticator, 0, sizeof(*p->authenticator));
p->flags = KRB5_AUTH_CONTEXT_DO_TIME; p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
p->cksumtype = CKSUMTYPE_NONE; /* CKSUMTYPE_RSA_MD5_DES */
p->enctype = ETYPE_NULL; /* ETYPE_DES_CBC_MD5 */
p->local_address = NULL; p->local_address = NULL;
p->remote_address = NULL; p->remote_address = NULL;
*auth_context = p; *auth_context = p;
@@ -282,8 +280,7 @@ krb5_auth_setcksumtype(krb5_context context,
krb5_auth_context auth_context, krb5_auth_context auth_context,
krb5_cksumtype cksumtype) krb5_cksumtype cksumtype)
{ {
auth_context->cksumtype = cksumtype; abort();
return 0;
} }
krb5_error_code krb5_error_code
@@ -291,8 +288,7 @@ krb5_auth_getcksumtype(krb5_context context,
krb5_auth_context auth_context, krb5_auth_context auth_context,
krb5_cksumtype *cksumtype) krb5_cksumtype *cksumtype)
{ {
*cksumtype = auth_context->cksumtype; abort();
return 0;
} }
krb5_error_code krb5_error_code
@@ -300,7 +296,12 @@ krb5_auth_setenctype(krb5_context context,
krb5_auth_context auth_context, krb5_auth_context auth_context,
krb5_enctype etype) krb5_enctype etype)
{ {
auth_context->enctype = etype; if(auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
ALLOC(auth_context->keyblock, 1);
if(auth_context->keyblock == NULL)
return ENOMEM;
auth_context->keyblock->keytype = etype;
return 0; return 0;
} }
@@ -309,8 +310,7 @@ krb5_auth_getenctype(krb5_context context,
krb5_auth_context auth_context, krb5_auth_context auth_context,
krb5_enctype *etype) krb5_enctype *etype)
{ {
*etype = auth_context->enctype; abort();
return 0;
} }
krb5_error_code krb5_error_code

View File

@@ -54,6 +54,7 @@ krb5_build_authenticator (krb5_context context,
size_t buf_size; size_t buf_size;
size_t len; size_t len;
krb5_error_code ret; krb5_error_code ret;
krb5_crypto crypto;
auth = malloc(sizeof(*auth)); auth = malloc(sizeof(*auth));
if (auth == NULL) if (auth == NULL)
@@ -129,10 +130,14 @@ krb5_build_authenticator (krb5_context context,
} }
} while(ret == ASN1_OVERFLOW); } while(ret == ASN1_OVERFLOW);
ret = krb5_encrypt (context, buf + buf_size - len, len, ret = krb5_crypto_init(context, &cred->session, enctype, &crypto);
enctype, ret = krb5_encrypt (context,
&cred->session, crypto,
KRB5_KU_AP_REQ_AUTH,
buf + buf_size - len,
len,
result); result);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
goto fail; goto fail;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -93,7 +93,7 @@ krb5_cc_resolve(krb5_context context,
if(ret) return ret; if(ret) return ret;
} }
for(i = 0; context->cc_ops[i].prefix && i < context->num_ops; i++) for(i = 0; i < context->num_ops && context->cc_ops[i].prefix; i++)
if(strncmp(context->cc_ops[i].prefix, residual, if(strncmp(context->cc_ops[i].prefix, residual,
strlen(context->cc_ops[i].prefix)) == 0){ strlen(context->cc_ops[i].prefix)) == 0){
krb5_ccache p; krb5_ccache p;
@@ -187,9 +187,6 @@ krb5_cc_close(krb5_context context,
{ {
krb5_error_code ret; krb5_error_code ret;
ret = id->ops->close(context, id); ret = id->ops->close(context, id);
#if 0 /* XXX */
free(id->residual);
#endif
free(id); free(id);
return ret; return ret;
} }

View File

@@ -40,9 +40,13 @@
RCSID("$Id$"); RCSID("$Id$");
/* these functions convert does what the normal asn.1-functions does, /* these functions does what the normal asn.1-functions does, but
but converts the keytype to/from the on-the-wire enctypes */ converts the keytype to/from the on-the-wire enctypes */
#if 1
#define DECODE(T, K) return decode_ ## T((void*)data, length, t, len)
#define ENCODE(T, K) return encode_ ## T(data, length, t, len)
#else
#define DECODE(T, K) \ #define DECODE(T, K) \
{ \ { \
krb5_error_code ret; \ krb5_error_code ret; \
@@ -63,6 +67,7 @@ RCSID("$Id$");
return ret; \ return ret; \
return encode_ ## T(data, length, t, len); \ return encode_ ## T(data, length, t, len); \
} }
#endif
krb5_error_code krb5_error_code
krb5_decode_EncTicketPart (krb5_context context, krb5_decode_EncTicketPart (krb5_context context,
@@ -171,6 +176,9 @@ krb5_decode_EncKrbCredPart (krb5_context context,
EncKrbCredPart *t, EncKrbCredPart *t,
size_t *len) size_t *len)
{ {
#if 1
return decode_EncKrbCredPart((void*)data, length, t, len);
#else
krb5_error_code ret; krb5_error_code ret;
int i; int i;
ret = decode_EncKrbCredPart((void*)data, length, t, len); ret = decode_EncKrbCredPart((void*)data, length, t, len);
@@ -180,6 +188,7 @@ krb5_decode_EncKrbCredPart (krb5_context context,
if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 1))) if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 1)))
break; break;
return ret; return ret;
#endif
} }
krb5_error_code krb5_error_code
@@ -189,6 +198,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
EncKrbCredPart *t, EncKrbCredPart *t,
size_t *len) size_t *len)
{ {
#if 0
krb5_error_code ret = 0; krb5_error_code ret = 0;
int i; int i;
@@ -196,6 +206,7 @@ krb5_encode_EncKrbCredPart (krb5_context context,
if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 0))) if((ret = krb5_decode_keyblock(context, &t->ticket_info.val[i].key, 0)))
break; break;
if(ret) return ret; if(ret) return ret;
#endif
return encode_EncKrbCredPart (data, length, t, len); return encode_EncKrbCredPart (data, length, t, len);
} }
@@ -206,6 +217,9 @@ krb5_decode_ETYPE_INFO (krb5_context context,
ETYPE_INFO *t, ETYPE_INFO *t,
size_t *len) size_t *len)
{ {
#if 1
return decode_ETYPE_INFO((void*)data, length, t, len);
#else
krb5_error_code ret; krb5_error_code ret;
int i; int i;
@@ -217,6 +231,7 @@ krb5_decode_ETYPE_INFO (krb5_context context,
break; break;
} }
return ret; return ret;
#endif
} }
krb5_error_code krb5_error_code
@@ -226,6 +241,7 @@ krb5_encode_ETYPE_INFO (krb5_context context,
ETYPE_INFO *t, ETYPE_INFO *t,
size_t *len) size_t *len)
{ {
#if 0
krb5_error_code ret = 0; krb5_error_code ret = 0;
int i; int i;
@@ -235,5 +251,6 @@ krb5_encode_ETYPE_INFO (krb5_context context,
if((ret = krb5_decode_keytype(context, &t->val[i].etype, 0))) if((ret = krb5_decode_keytype(context, &t->val[i].etype, 0)))
break; break;
if(ret) return ret; if(ret) return ret;
#endif
return encode_ETYPE_INFO (data, length, t, len); return encode_ETYPE_INFO (data, length, t, len);
} }

View File

@@ -40,6 +40,8 @@
RCSID("$Id$"); RCSID("$Id$");
int issuid(void); /* XXX */
krb5_error_code krb5_error_code
krb5_init_context(krb5_context *context) krb5_init_context(krb5_context *context)
{ {
@@ -86,9 +88,6 @@ krb5_init_context(krb5_context *context)
if (val >= 0) if (val >= 0)
p->max_retries = val; p->max_retries = val;
p->ktype_is_etype = krb5_config_get_bool(p, NULL, "libdefaults",
"ktype_is_etype", NULL);
p->http_proxy = krb5_config_get_string(p, NULL, "libdefaults", p->http_proxy = krb5_config_get_string(p, NULL, "libdefaults",
"http_proxy", NULL); "http_proxy", NULL);
@@ -101,7 +100,7 @@ krb5_init_context(krb5_context *context)
for(i = 0; etypes[i]; i++); for(i = 0; etypes[i]; i++);
p->etypes = malloc((i+1) * sizeof(*p->etypes)); p->etypes = malloc((i+1) * sizeof(*p->etypes));
for(j = 0, k = 0; j < i; j++) { for(j = 0, k = 0; j < i; j++) {
if(krb5_string_to_etype(p, etypes[j], &p->etypes[k]) == 0) if(krb5_string_to_enctype(p, etypes[j], &p->etypes[k]) == 0)
k++; k++;
} }
p->etypes[k] = ETYPE_NULL; p->etypes[k] = ETYPE_NULL;
@@ -169,24 +168,24 @@ krb5_error_code
krb5_set_default_in_tkt_etypes(krb5_context context, krb5_set_default_in_tkt_etypes(krb5_context context,
const krb5_enctype *etypes) const krb5_enctype *etypes)
{ {
int i; int i;
krb5_enctype *p = NULL; krb5_enctype *p = NULL;
if(etypes) { if(etypes) {
i = 0; i = 0;
while(etypes[i]) while(etypes[i])
if(!krb5_etype_valid(context, etypes[i++])) if(!krb5_enctype_valid(context, etypes[i++]))
return KRB5_PROG_ETYPE_NOSUPP; return KRB5_PROG_ETYPE_NOSUPP;
++i; ++i;
ALLOC(p, i); ALLOC(p, i);
if(!p) if(!p)
return ENOMEM; return ENOMEM;
memmove(p, etypes, i * sizeof(krb5_enctype)); memmove(p, etypes, i * sizeof(krb5_enctype));
} }
if(context->etypes) if(context->etypes)
free(context->etypes); free(context->etypes);
context->etypes = p; context->etypes = p;
return 0; return 0;
} }

2108
lib/krb5/crypto.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -46,17 +46,9 @@ krb5_generate_subkey(krb5_context context,
krb5_keyblock **subkey) krb5_keyblock **subkey)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_keyblock *k; ALLOC(*subkey, 1);
ret = krb5_generate_random_keyblock(context, key->keytype, *subkey);
k = malloc(sizeof(**subkey)); if(ret)
if (k == NULL) free(*subkey);
return ENOMEM; return ret;
ret = krb5_generate_random_keyblock(context, key->keytype, k);
if(ret){
free(k);
return ret;
}
*subkey = k;
return 0;
} }

View File

@@ -103,8 +103,10 @@ make_pa_tgs_req(krb5_context context,
} }
free_Ticket(&ticket); free_Ticket(&ticket);
ret = krb5_mk_req_extended(context, &ac, 0, &in_data, creds,
&padata->padata_value); ret = krb5_mk_req_internal(context, &ac, 0, &in_data, creds,
&padata->padata_value,
KRB5_KU_TGS_REQ_AUTH_CKSUM);
} }
out: out:
@@ -115,71 +117,6 @@ out:
return 0; return 0;
} }
/*
*
*/
static krb5_error_code
init_tgs_req1(krb5_context context,
krb5_authdata *authdata,
krb5_creds *krbtgt,
krb5_keyblock **subkey,
TGS_REQ *t)
{
krb5_error_code ret;
krb5_auth_context ac;
krb5_keyblock *key = NULL;
ret = krb5_auth_con_init(context, &ac);
if(ret)
return ret;
ret = krb5_generate_subkey (context, &krbtgt->session, &key);
if (ret)
goto out;
ret = krb5_auth_con_setlocalsubkey(context, ac, key);
if (ret)
goto out;
if(authdata->len){
size_t len;
unsigned char *buf;
krb5_enctype etype;
len = length_AuthorizationData(authdata);
buf = malloc(len);
if (buf == NULL) {
ret = ENOMEM;
goto out;
}
ret = encode_AuthorizationData(buf + len - 1, len, authdata, &len);
ALLOC(t->req_body.enc_authorization_data, 1);
if (t->req_body.enc_authorization_data == NULL) {
free (buf);
ret = ENOMEM;
goto out;
}
krb5_keytype_to_etype(context, key->keytype, &etype);
krb5_encrypt_EncryptedData(context, buf, len, etype, 0,
key, t->req_body.enc_authorization_data);
free (buf);
} else {
t->req_body.enc_authorization_data = NULL;
}
ret = make_pa_tgs_req(context,
ac,
&t->req_body,
t->padata->val,
krbtgt);
out:
if (ret == 0)
*subkey = key;
else
krb5_free_keyblock (context, key);
krb5_auth_con_free(context, ac);
return ret;
}
/* /*
* Create a tgs-req in `t' with `addresses', `flags', `second_ticket' * Create a tgs-req in `t' with `addresses', `flags', `second_ticket'
* (if not-NULL), `in_creds', `krbtgt', and returning the generated * (if not-NULL), `in_creds', `krbtgt', and returning the generated
@@ -204,19 +141,13 @@ init_tgs_req (krb5_context context,
t->pvno = 5; t->pvno = 5;
t->msg_type = krb_tgs_req; t->msg_type = krb_tgs_req;
if (in_creds->session.keytype) { if (in_creds->session.keytype) {
krb5_enctype *etypes; krb5_enctype foo[2];
foo[0] = in_creds->session.keytype;
ret = krb5_keytype_to_etypes(context, foo[1] = 0;
in_creds->session.keytype,
&etypes);
if (ret)
return ret;
ret = krb5_init_etype(context, ret = krb5_init_etype(context,
&t->req_body.etype.len, &t->req_body.etype.len,
&t->req_body.etype.val, &t->req_body.etype.val,
etypes); foo);
free (etypes);
} else { } else {
ret = krb5_init_etype(context, ret = krb5_init_etype(context,
&t->req_body.etype.len, &t->req_body.etype.len,
@@ -224,27 +155,27 @@ init_tgs_req (krb5_context context,
NULL); NULL);
} }
if (ret) if (ret)
goto out; goto fail;
t->req_body.addresses = addresses; t->req_body.addresses = addresses;
t->req_body.kdc_options = flags.b; t->req_body.kdc_options = flags.b;
ret = copy_Realm(&in_creds->server->realm, &t->req_body.realm); ret = copy_Realm(&in_creds->server->realm, &t->req_body.realm);
if (ret) if (ret)
goto out; goto fail;
ALLOC(t->req_body.sname, 1); ALLOC(t->req_body.sname, 1);
if (t->req_body.sname == NULL) { if (t->req_body.sname == NULL) {
ret = ENOMEM; ret = ENOMEM;
goto out; goto fail;
} }
ret = copy_PrincipalName(&in_creds->server->name, t->req_body.sname); ret = copy_PrincipalName(&in_creds->server->name, t->req_body.sname);
if (ret) if (ret)
goto out; goto fail;
/* req_body.till should be NULL if there is no endtime specified, /* req_body.till should be NULL if there is no endtime specified,
but old MIT code (like DCE secd) doesn't like that */ but old MIT code (like DCE secd) doesn't like that */
ALLOC(t->req_body.till, 1); ALLOC(t->req_body.till, 1);
if(t->req_body.till == NULL){ if(t->req_body.till == NULL){
ret = ENOMEM; ret = ENOMEM;
goto out; goto fail;
} }
*t->req_body.till = in_creds->times.endtime; *t->req_body.till = in_creds->times.endtime;
@@ -253,31 +184,73 @@ init_tgs_req (krb5_context context,
ALLOC(t->req_body.additional_tickets, 1); ALLOC(t->req_body.additional_tickets, 1);
if (t->req_body.additional_tickets == NULL) { if (t->req_body.additional_tickets == NULL) {
ret = ENOMEM; ret = ENOMEM;
goto out; goto fail;
} }
ALLOC_SEQ(t->req_body.additional_tickets, 1); ALLOC_SEQ(t->req_body.additional_tickets, 1);
if (t->req_body.additional_tickets->val == NULL) { if (t->req_body.additional_tickets->val == NULL) {
ret = ENOMEM; ret = ENOMEM;
goto out; goto fail;
} }
ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val); ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val);
if (ret) if (ret)
goto out; goto fail;
} }
ALLOC(t->padata, 1); ALLOC(t->padata, 1);
if (t->padata == NULL) { if (t->padata == NULL) {
ret = ENOMEM; ret = ENOMEM;
goto out; goto fail;
} }
ALLOC_SEQ(t->padata, 1); ALLOC_SEQ(t->padata, 1);
if (t->padata->val == NULL) { if (t->padata->val == NULL) {
ret = ENOMEM; ret = ENOMEM;
goto out; goto fail;
} }
ret = init_tgs_req1 (context, &in_creds->authdata, krbtgt, subkey, t); {
krb5_auth_context ac;
krb5_keyblock *key;
ret = krb5_auth_con_init(context, &ac);
if(ret)
return ret;
ret = krb5_generate_subkey (context, &krbtgt->session, &key);
ret = krb5_auth_con_setlocalsubkey(context, ac, key);
if(ret == ENOMEM)
/* XXX */;
out: if(in_creds->authdata.len){
size_t len;
unsigned char *buf;
krb5_crypto crypto;
len = length_AuthorizationData(&in_creds->authdata);
buf = malloc(len);
ret = encode_AuthorizationData(buf + len - 1, len, &in_creds->authdata, &len);
ALLOC(t->req_body.enc_authorization_data, 1);
ret = krb5_crypto_init(context, key, 0, &crypto);
krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
/* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */
buf,
len,
0,
t->req_body.enc_authorization_data);
krb5_crypto_destroy(context, crypto);
}else
t->req_body.enc_authorization_data = NULL;
ret = make_pa_tgs_req(context,
ac,
&t->req_body,
t->padata->val,
krbtgt);
if(ret)
goto fail;
*subkey = key;
krb5_auth_con_free(context, ac);
}
fail:
if (ret) if (ret)
free_TGS_REQ (t); free_TGS_REQ (t);
return ret; return ret;
@@ -316,36 +289,36 @@ get_krbtgt(krb5_context context,
/* DCE compatible decrypt proc */ /* DCE compatible decrypt proc */
static krb5_error_code static krb5_error_code
decrypt_tkt_with_subkey (krb5_context context, decrypt_tkt_with_subkey (krb5_context context,
const krb5_keyblock *key, krb5_keyblock *key,
krb5_key_usage usage,
krb5_const_pointer subkey, krb5_const_pointer subkey,
krb5_kdc_rep *dec_rep) krb5_kdc_rep *dec_rep)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_data data; krb5_data data;
size_t size; size_t size;
krb5_data save; krb5_crypto crypto;
ret = krb5_data_copy(&save, dec_rep->kdc_rep.enc_part.cipher.data, krb5_crypto_init(context, key, 0, &crypto);
dec_rep->kdc_rep.enc_part.cipher.length); ret = krb5_decrypt_EncryptedData (context,
if(ret) crypto,
return ret; usage,
&dec_rep->kdc_rep.enc_part,
ret = krb5_decrypt (context, &data);
dec_rep->kdc_rep.enc_part.cipher.data, krb5_crypto_destroy(context, crypto);
dec_rep->kdc_rep.enc_part.cipher.length,
dec_rep->kdc_rep.enc_part.etype,
key,
&data);
if(ret && subkey){ if(ret && subkey){
ret = krb5_decrypt (context, save.data, save.length, /* DCE compat -- try to decrypt with subkey */
dec_rep->kdc_rep.enc_part.etype, krb5_crypto_init(context, (krb5_keyblock*)subkey, 0, &crypto);
(krb5_keyblock*)subkey, /* local subkey */ ret = krb5_decrypt_EncryptedData (context,
&data); crypto,
KRB5_KU_TGS_REP_ENC_PART_SUB_KEY,
&dec_rep->kdc_rep.enc_part,
&data);
krb5_crypto_destroy(context, crypto);
} }
krb5_data_free(&save);
if (ret) if (ret)
return ret; return ret;
ret = krb5_decode_EncASRepPart(context, ret = krb5_decode_EncASRepPart(context,
data.data, data.data,
data.length, data.length,
@@ -473,6 +446,7 @@ get_cred_kdc(krb5_context context,
*out_creds, *out_creds,
&krbtgt->session, &krbtgt->session,
NULL, NULL,
KRB5_KU_TGS_REP_ENC_PART_SESSION,
&krbtgt->addresses, &krbtgt->addresses,
nonce, nonce,
TRUE, TRUE,

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *

View File

@@ -95,17 +95,7 @@ krb5_get_forwarded_creds (krb5_context context,
u_char buf[1024]; u_char buf[1024];
int32_t sec, usec; int32_t sec, usec;
krb5_kdc_flags kdc_flags; krb5_kdc_flags kdc_flags;
krb5_enctype enctype; krb5_crypto crypto;
if (auth_context->enctype)
enctype = auth_context->enctype;
else {
ret = krb5_keytype_to_etype (context,
auth_context->local_subkey->keytype,
&enctype);
if (ret)
return ret;
}
addrs.len = 0; addrs.len = 0;
addrs.val = NULL; addrs.val = NULL;
@@ -226,13 +216,15 @@ krb5_get_forwarded_creds (krb5_context context,
return ret; return ret;
} }
krb5_crypto_init(context, auth_context->local_subkey, 0, &crypto);
ret = krb5_encrypt_EncryptedData (context, ret = krb5_encrypt_EncryptedData (context,
crypto,
KRB5_KU_KRB_CRED,
buf + sizeof(buf) - len, buf + sizeof(buf) - len,
len, len,
enctype,
0, 0,
auth_context->local_subkey,
&cred.enc_part); &cred.enc_part);
krb5_crypto_destroy(context, crypto);
if (ret) { if (ret) {
free_KRB_CRED(&cred); free_KRB_CRED(&cred);
return ret; return ret;

View File

@@ -65,6 +65,7 @@ krb5_get_host_realm(krb5_context context,
const krb5_config_binding *l; const krb5_config_binding *l;
struct in_addr addr; struct in_addr addr;
struct hostent *hostent; struct hostent *hostent;
char *orig_host;
if (host == NULL) { if (host == NULL) {
if (gethostname (hostname, sizeof(hostname))) if (gethostname (hostname, sizeof(hostname)))
@@ -72,6 +73,8 @@ krb5_get_host_realm(krb5_context context,
host = hostname; host = hostname;
} }
orig_host = host;
addr.s_addr = inet_addr(host); addr.s_addr = inet_addr(host);
hostent = roken_gethostbyname (host); hostent = roken_gethostbyname (host);
if (hostent == NULL && addr.s_addr != INADDR_NONE) if (hostent == NULL && addr.s_addr != INADDR_NONE)
@@ -111,6 +114,9 @@ krb5_get_host_realm(krb5_context context,
} else { } else {
const char *dot = strchr (host, '.'); const char *dot = strchr (host, '.');
if (dot == NULL)
dot = strchr (orig_host, '.');
if (dot != NULL) { if (dot != NULL) {
(*realms)[0] = strdup (dot + 1); (*realms)[0] = strdup (dot + 1);
if ((*realms)[0] == NULL) { if ((*realms)[0] == NULL) {

View File

@@ -80,20 +80,25 @@ cleanup:
static krb5_error_code static krb5_error_code
decrypt_tkt (krb5_context context, decrypt_tkt (krb5_context context,
const krb5_keyblock *key, krb5_keyblock *key,
unsigned usage,
krb5_const_pointer decrypt_arg, krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep) krb5_kdc_rep *dec_rep)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_data data; krb5_data data;
size_t size; size_t size;
krb5_crypto crypto;
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context,
crypto,
usage,
&dec_rep->kdc_rep.enc_part,
&data);
krb5_crypto_destroy(context, crypto);
ret = krb5_decrypt (context,
dec_rep->kdc_rep.enc_part.cipher.data,
dec_rep->kdc_rep.enc_part.cipher.length,
dec_rep->kdc_rep.enc_part.etype,
key,
&data);
if (ret) if (ret)
return ret; return ret;
@@ -119,6 +124,7 @@ _krb5_extract_ticket(krb5_context context,
krb5_creds *creds, krb5_creds *creds,
krb5_keyblock *key, krb5_keyblock *key,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_key_usage key_usage,
krb5_addresses *addrs, krb5_addresses *addrs,
unsigned nonce, unsigned nonce,
krb5_boolean allow_server_mismatch, krb5_boolean allow_server_mismatch,
@@ -147,12 +153,16 @@ _krb5_extract_ticket(krb5_context context,
/* extract ticket */ /* extract ticket */
{ {
unsigned char buf[1024]; unsigned char *buf;
size_t len; size_t len;
encode_Ticket(buf + sizeof(buf) - 1, sizeof(buf), len = length_Ticket(&rep->kdc_rep.ticket);
&rep->kdc_rep.ticket, &len); buf = malloc(len);
creds->ticket.data = malloc(len); if(buf == NULL) {
memcpy(creds->ticket.data, buf + sizeof(buf) - len, len); ret = ENOMEM;
goto out;
}
encode_Ticket(buf + len - 1, len, &rep->kdc_rep.ticket, &len);
creds->ticket.data = buf;
creds->ticket.length = len; creds->ticket.length = len;
creds->second_ticket.length = 0; creds->second_ticket.length = 0;
creds->second_ticket.data = NULL; creds->second_ticket.data = NULL;
@@ -183,7 +193,7 @@ _krb5_extract_ticket(krb5_context context,
if (decrypt_proc == NULL) if (decrypt_proc == NULL)
decrypt_proc = decrypt_tkt; decrypt_proc = decrypt_tkt;
ret = (*decrypt_proc)(context, key, decryptarg, rep); ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
if (ret) if (ret)
goto out; goto out;
@@ -294,6 +304,7 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
krb5_error_code ret; krb5_error_code ret;
int32_t sec, usec; int32_t sec, usec;
unsigned usec2; unsigned usec2;
krb5_crypto crypto;
krb5_us_timeofday (context, &sec, &usec); krb5_us_timeofday (context, &sec, &usec);
p.patimestamp = sec; p.patimestamp = sec;
@@ -307,13 +318,15 @@ make_pa_enc_timestamp(krb5_context context, PA_DATA *pa,
if (ret) if (ret)
return ret; return ret;
krb5_crypto_init(context, key, 0, &crypto);
ret = krb5_encrypt_EncryptedData(context, ret = krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_PA_ENC_TIMESTAMP,
buf + sizeof(buf) - len, buf + sizeof(buf) - len,
len, len,
etype,
0, 0,
key,
&encdata); &encdata);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
return ret; return ret;
@@ -338,31 +351,29 @@ add_padata(krb5_context context,
krb5_principal client, krb5_principal client,
krb5_key_proc key_proc, krb5_key_proc key_proc,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keytype keytype, krb5_enctype enctype,
krb5_data *salt) krb5_salt *salt)
{ {
krb5_error_code ret; krb5_error_code ret;
PA_DATA *pa2; PA_DATA *pa2;
krb5_keyblock *key; krb5_keyblock *key;
krb5_enctype etype; krb5_salt salt2;
krb5_data salt2;
krb5_data_zero(&salt2);
if(salt == NULL) { if(salt == NULL) {
/* default to standard salt */ /* default to standard salt */
ret = krb5_get_salt (client, &salt2); ret = krb5_get_pw_salt (context, client, &salt2);
salt = &salt2; salt = &salt2;
} }
ret = (*key_proc)(context, keytype, salt, keyseed, &key); ret = (*key_proc)(context, enctype, *salt, keyseed, &key);
krb5_data_free(&salt2); if(salt == &salt2)
krb5_free_salt(context, salt2);
if (ret) if (ret)
return ret; return ret;
pa2 = realloc(md->val, (md->len + 1) * sizeof(*md->val)); pa2 = realloc(md->val, (md->len + 1) * sizeof(*md->val));
if(pa2 == NULL) if(pa2 == NULL)
return ENOMEM; return ENOMEM;
md->val = pa2; md->val = pa2;
krb5_keytype_to_etype(context, keytype, &etype); ret = make_pa_enc_timestamp(context, &md->val[md->len], enctype, key);
ret = make_pa_enc_timestamp(context, &md->val[md->len], etype, key);
krb5_free_keyblock (context, key); krb5_free_keyblock (context, key);
if(ret) if(ret)
return ret; return ret;
@@ -384,7 +395,7 @@ init_as_req (krb5_context context,
AS_REQ *a) AS_REQ *a)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_data salt; krb5_salt salt;
krb5_enctype etype; krb5_enctype etype;
memset(a, 0, sizeof(*a)); memset(a, 0, sizeof(*a));
@@ -478,29 +489,30 @@ init_as_req (krb5_context context,
} }
a->padata->val = tmp; a->padata->val = tmp;
for(j = 0; j < preauth->val[i].info.len; j++) { for(j = 0; j < preauth->val[i].info.len; j++) {
krb5_keytype keytype = preauth->val[i].info.val[j].etype; krb5_salt *sp = &salt;
if(preauth->val[i].info.val[j].salttype && if(preauth->val[i].info.val[j].salttype)
*preauth->val[i].info.val[j].salttype == salt.salttype = *preauth->val[i].info.val[j].salttype;
KRB5_PA_AFS3_SALT) { else
if(keytype != KEYTYPE_DES) { salt.salttype = KRB5_PW_SALT;
ret = KRB5_PROG_KEYTYPE_NOSUPP; if(preauth->val[i].info.val[j].salt)
goto fail; salt.saltvalue = *preauth->val[i].info.val[j].salt;
} else
keytype = KEYTYPE_DES_AFS3; if(salt.salttype == KRB5_PW_SALT)
} sp = NULL;
else
krb5_data_zero(&salt.saltvalue);
add_padata(context, a->padata, creds->client, add_padata(context, a->padata, creds->client,
key_proc, keyseed, keytype, key_proc, keyseed,
preauth->val[i].info.val[j].salt); preauth->val[i].info.val[j].etype,
sp);
} }
} }
} }
} else } else
/* not sure this is the way to use `ptypes' */ /* not sure this is the way to use `ptypes' */
if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE) if (ptypes == NULL || *ptypes == KRB5_PADATA_NONE)
a->padata = NULL; a->padata = NULL;
else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) { else if (*ptypes == KRB5_PADATA_ENC_TIMESTAMP) {
krb5_keytype keytype;
ALLOC(a->padata, 1); ALLOC(a->padata, 1);
if (a->padata == NULL) { if (a->padata == NULL) {
ret = ENOMEM; ret = ENOMEM;
@@ -509,18 +521,15 @@ init_as_req (krb5_context context,
a->padata->len = 0; a->padata->len = 0;
a->padata->val = NULL; a->padata->val = NULL;
ret = krb5_etype_to_keytype(context, etype, &keytype);
if(ret)
goto fail;
/* make a v5 salted pa-data */ /* make a v5 salted pa-data */
add_padata(context, a->padata, creds->client, add_padata(context, a->padata, creds->client,
key_proc, keyseed, keytype, NULL); key_proc, keyseed, etype, NULL);
/* make a v4 salted pa-data */ /* make a v4 salted pa-data */
krb5_data_zero(&salt); salt.salttype = KRB5_PW_SALT;
krb5_data_zero(&salt.saltvalue);
add_padata(context, a->padata, creds->client, add_padata(context, a->padata, creds->client,
key_proc, keyseed, keytype, &salt); key_proc, keyseed, etype, &salt);
} else { } else {
ret = KRB5_PREAUTH_BAD_TYPE; ret = KRB5_PREAUTH_BAD_TYPE;
goto fail; goto fail;
@@ -550,7 +559,7 @@ krb5_get_in_cred(krb5_context context,
krb5_kdc_rep rep; krb5_kdc_rep rep;
krb5_data req, resp; krb5_data req, resp;
char buf[BUFSIZ]; char buf[BUFSIZ];
krb5_data salt; krb5_salt salt;
krb5_keyblock *key; krb5_keyblock *key;
size_t size; size_t size;
krb5_kdc_flags opts; krb5_kdc_flags opts;
@@ -627,32 +636,33 @@ krb5_get_in_cred(krb5_context context,
} }
} }
if(pa) { if(pa) {
krb5_keytype keytype; salt.salttype = pa->padata_type;
ret = krb5_etype_to_keytype(context, etype, &keytype); salt.saltvalue = pa->padata_value;
if(pa->padata_type == pa_afs3_salt){
if(keytype != KEYTYPE_DES) ret = (*key_proc)(context, etype, salt, keyseed, &key);
return KRB5_PROG_KEYTYPE_NOSUPP;
keytype = KEYTYPE_DES_AFS3;
}
ret = (*key_proc)(context, keytype, &pa->padata_value, keyseed, &key);
} else { } else {
/* make a v5 salted pa-data */ /* make a v5 salted pa-data */
krb5_keytype keytype; ret = krb5_get_pw_salt (context, creds->client, &salt);
salt.length = 0;
salt.data = NULL;
ret = krb5_get_salt (creds->client, &salt);
if (ret) if (ret)
return ret; return ret;
ret = krb5_etype_to_keytype(context, etype, &keytype); ret = (*key_proc)(context, etype, salt, keyseed, &key);
ret = (*key_proc)(context, keytype, &salt, keyseed, &key); krb5_free_salt(context, salt);
krb5_data_free (&salt);
} }
if (ret) if (ret)
return ret; return ret;
ret = _krb5_extract_ticket(context, &rep, creds, key, keyseed, ret = _krb5_extract_ticket(context,
NULL, nonce, FALSE, decrypt_proc, decryptarg); &rep,
creds,
key,
keyseed,
KRB5_KU_AS_REP_ENC_PART,
NULL,
nonce,
FALSE,
decrypt_proc,
decryptarg);
memset (key->keyvalue.data, 0, key->keyvalue.length); memset (key->keyvalue.data, 0, key->keyvalue.length);
krb5_free_keyblock_contents (context, key); krb5_free_keyblock_contents (context, key);
free (key); free (key);

View File

@@ -42,28 +42,25 @@ RCSID("$Id$");
krb5_error_code krb5_error_code
krb5_password_key_proc (krb5_context context, krb5_password_key_proc (krb5_context context,
krb5_keytype type, krb5_enctype type,
krb5_data *salt, krb5_salt salt,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keyblock **key) krb5_keyblock **key)
{ {
krb5_error_code ret; krb5_error_code ret;
char *password = (char *)keyseed; char *password = (char *)keyseed;
char buf[BUFSIZ]; char buf[BUFSIZ];
*key = malloc (sizeof (**key)); *key = malloc (sizeof (**key));
if (*key == NULL) if (*key == NULL)
return ENOMEM; return ENOMEM;
(*key)->keytype = type; if (password == NULL) {
(*key)->keyvalue.length = 0; des_read_pw_string (buf, sizeof(buf), "Password: ", 0);
(*key)->keyvalue.data = NULL; password = buf;
if (password == NULL) { }
des_read_pw_string (buf, sizeof(buf), "Password: ", 0); ret = krb5_string_to_key_salt (context, type, password, salt, *key);
password = buf; memset (buf, 0, sizeof(buf));
} return ret;
ret = krb5_string_to_key (password, salt, type, *key);
memset (buf, 0, sizeof(buf));
return ret;
} }
krb5_error_code krb5_error_code

View File

@@ -42,8 +42,8 @@ RCSID("$Id$");
krb5_error_code krb5_error_code
krb5_keytab_key_proc (krb5_context context, krb5_keytab_key_proc (krb5_context context,
krb5_keytype type, krb5_enctype enctype,
krb5_data *salt, krb5_salt salt,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keyblock **key) krb5_keyblock **key)
{ {
@@ -60,7 +60,7 @@ krb5_keytab_key_proc (krb5_context context,
real_keytab = keytab; real_keytab = keytab;
ret = krb5_kt_get_entry (context, real_keytab, principal, ret = krb5_kt_get_entry (context, real_keytab, principal,
0, type, &entry); 0, enctype, &entry);
if (keytab == NULL) if (keytab == NULL)
krb5_kt_close (context, real_keytab); krb5_kt_close (context, real_keytab);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -42,8 +42,8 @@ RCSID("$Id$");
static krb5_error_code static krb5_error_code
krb5_skey_key_proc (krb5_context context, krb5_skey_key_proc (krb5_context context,
krb5_keytype type, krb5_enctype type,
krb5_data *salt, krb5_salt salt,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keyblock **key) krb5_keyblock **key)
{ {

View File

@@ -11,5 +11,6 @@ prefix HEIM_ERR
error_code LOG_PARSE, "Error parsing log destination" error_code LOG_PARSE, "Error parsing log destination"
error_code V4_PRINC_NO_CONV, "Failed to convert v4 principal" error_code V4_PRINC_NO_CONV, "Failed to convert v4 principal"
error_code SALTTYPE_NOSUPP, "Salt type is not supported by enctype"
end end

View File

@@ -132,7 +132,7 @@ krb5_kt_read_service_key(krb5_context context,
krb5_pointer keyprocarg, krb5_pointer keyprocarg,
krb5_principal principal, krb5_principal principal,
krb5_kvno vno, krb5_kvno vno,
krb5_keytype keytype, krb5_enctype enctype,
krb5_keyblock **key) krb5_keyblock **key)
{ {
krb5_keytab keytab; krb5_keytab keytab;
@@ -147,7 +147,7 @@ krb5_kt_read_service_key(krb5_context context,
if (r) if (r)
return r; return r;
r = krb5_kt_get_entry (context, keytab, principal, vno, keytype, &entry); r = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
krb5_kt_close (context, keytab); krb5_kt_close (context, keytab);
if (r) if (r)
return r; return r;
@@ -191,14 +191,14 @@ kt_compare(krb5_context context,
krb5_keytab_entry *entry, krb5_keytab_entry *entry,
krb5_const_principal principal, krb5_const_principal principal,
krb5_kvno vno, krb5_kvno vno,
krb5_keytype keytype) krb5_enctype enctype)
{ {
if(principal != NULL && if(principal != NULL &&
!krb5_principal_compare(context, entry->principal, principal)) !krb5_principal_compare(context, entry->principal, principal))
return FALSE; return FALSE;
if(vno && vno != entry->vno) if(vno && vno != entry->vno)
return FALSE; return FALSE;
if(keytype && keytype != entry->keyblock.keytype) if(enctype && enctype != entry->keyblock.keytype)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
@@ -208,14 +208,14 @@ krb5_kt_get_entry(krb5_context context,
krb5_keytab id, krb5_keytab id,
krb5_const_principal principal, krb5_const_principal principal,
krb5_kvno kvno, krb5_kvno kvno,
krb5_keytype keytype, krb5_enctype enctype,
krb5_keytab_entry *entry) krb5_keytab_entry *entry)
{ {
krb5_keytab_entry tmp; krb5_keytab_entry tmp;
krb5_error_code r; krb5_error_code r;
krb5_kt_cursor cursor; krb5_kt_cursor cursor;
if(id->get) return (*id->get)(context, id, principal, kvno, keytype, entry); if(id->get) return (*id->get)(context, id, principal, kvno, enctype, entry);
r = krb5_kt_start_seq_get (context, id, &cursor); r = krb5_kt_start_seq_get (context, id, &cursor);
if (r) if (r)
@@ -223,7 +223,7 @@ krb5_kt_get_entry(krb5_context context,
entry->vno = 0; entry->vno = 0;
while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) { while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
if (kt_compare(context, &tmp, principal, 0, keytype)) { if (kt_compare(context, &tmp, principal, 0, enctype)) {
if (kvno == tmp.vno) { if (kvno == tmp.vno) {
krb5_kt_copy_entry_contents (context, &tmp, entry); krb5_kt_copy_entry_contents (context, &tmp, entry);
krb5_kt_free_entry (context, &tmp); krb5_kt_free_entry (context, &tmp);

View File

@@ -71,6 +71,9 @@ typedef const void *krb5_const_pointer;
typedef octet_string krb5_data; typedef octet_string krb5_data;
struct krb5_crypto_data;
typedef struct krb5_crypto_data *krb5_crypto;
typedef enum krb5_cksumtype { typedef enum krb5_cksumtype {
CKSUMTYPE_NONE = 0, CKSUMTYPE_NONE = 0,
CKSUMTYPE_CRC32 = 1, CKSUMTYPE_CRC32 = 1,
@@ -93,11 +96,20 @@ typedef enum krb5_enctype {
ETYPE_DES_CBC_MD4 = 2, ETYPE_DES_CBC_MD4 = 2,
ETYPE_DES_CBC_MD5 = 3, ETYPE_DES_CBC_MD5 = 3,
ETYPE_DES3_CBC_MD5 = 5, ETYPE_DES3_CBC_MD5 = 5,
ETYPE_DES3_CBC_SHA1 = 7, #if NEW_DES3_CODE
ETYPE_NEW_DES3_CBC_SHA1 = 7,
ETYPE_DES3_CBC_SHA1 = ETYPE_NEW_DES3_CBC_SHA1,
#else
ETYPE_OLD_DES3_CBC_SHA1 = 7,
ETYPE_NEW_DES3_CBC_SHA1 = 99,
ETYPE_DES3_CBC_SHA1 = ETYPE_OLD_DES3_CBC_SHA1,
#endif
ETYPE_SIGN_DSA_GENERATE = 8, ETYPE_SIGN_DSA_GENERATE = 8,
ETYPE_ENCRYPT_RSA_PRIV = 9, ETYPE_ENCRYPT_RSA_PRIV = 9,
ETYPE_ENCRYPT_RSA_PUB = 10, ETYPE_ENCRYPT_RSA_PUB = 10,
ETYPE_ENCTYPE_PK_CROSS = 48 ETYPE_ENCTYPE_PK_CROSS = 48,
ETYPE_DES_CBC_NONE = 0x1000,
ETYPE_DES3_CBC_NONE = 0x1001
} krb5_enctype; } krb5_enctype;
typedef enum krb5_preauthtype { typedef enum krb5_preauthtype {
@@ -108,11 +120,73 @@ typedef enum krb5_preauthtype {
KRB5_PADATA_ENC_SECURID KRB5_PADATA_ENC_SECURID
} krb5_preauthtype; } krb5_preauthtype;
typedef enum krb5_key_usage {
KRB5_KU_PA_ENC_TIMESTAMP = 1,
/* AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
client key (section 5.4.1) */
KRB5_KU_TICKET = 2,
/* AS-REP Ticket and TGS-REP Ticket (includes tgs session key or
application session key), encrypted with the service key
(section 5.4.2) */
KRB5_KU_AS_REP_ENC_PART = 3,
/* AS-REP encrypted part (includes tgs session key or application
session key), encrypted with the client key (section 5.4.2) */
KRB5_KU_TGS_REQ_AUTH_DAT_SESSION = 4,
/* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
session key (section 5.4.1) */
KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY = 5,
/* TGS-REQ KDC-REQ-BODY AuthorizationData, encrypted with the tgs
authenticator subkey (section 5.4.1) */
KRB5_KU_TGS_REQ_AUTH_CKSUM = 6,
/* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator cksum, keyed
with the tgs session key (sections 5.3.2, 5.4.1) */
KRB5_KU_TGS_REQ_AUTH = 7,
/* TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes tgs
authenticator subkey), encrypted with the tgs session key
(section 5.3.2) */
KRB5_KU_TGS_REP_ENC_PART_SESSION = 8,
/* TGS-REP encrypted part (includes application session key),
encrypted with the tgs session key (section 5.4.2) */
KRB5_KU_TGS_REP_ENC_PART_SUB_KEY = 9,
/* TGS-REP encrypted part (includes application session key),
encrypted with the tgs authenticator subkey (section 5.4.2) */
KRB5_KU_AP_REQ_AUTH_CKSUM = 10,
/* AP-REQ Authenticator cksum, keyed with the application session
key (section 5.3.2) */
KRB5_KU_AP_REQ_AUTH = 11,
/* AP-REQ Authenticator (includes application authenticator
subkey), encrypted with the application session key (section
5.3.2) */
KRB5_KU_AP_REQ_ENC_PART = 12,
/* AP-REP encrypted part (includes application session subkey),
encrypted with the application session key (section 5.5.2) */
KRB5_KU_KRB_PRIV = 13,
/* KRB-PRIV encrypted part, encrypted with a key chosen by the
application (section 5.7.1) */
KRB5_KU_KRB_CRED = 14,
/* KRB-CRED encrypted part, encrypted with a key chosen by the
application (section 5.8.1) */
KRB5_KU_KRB_SAFE_CKSUM = 15,
/* KRB-SAFE cksum, keyed with a key chosen by the application
(section 5.6.1) */
KRB5_KU_OTHER_ENCRYPTED = 16,
/* Data which is defined in some specification outside of
Kerberos to be encrypted using an RFC1510 encryption type. */
KRB5_KU_OTHER_CKSUM = 17
/* Data which is defined in some specification outside of
Kerberos to be checksummed using an RFC1510 checksum type. */
} krb5_key_usage;
typedef enum krb5_salttype { typedef enum krb5_salttype {
KRB5_PA_PW_SALT = pa_pw_salt, KRB5_PW_SALT = pa_pw_salt,
KRB5_PA_AFS3_SALT = pa_afs3_salt KRB5_AFS3_SALT = pa_afs3_salt
}krb5_salttype; }krb5_salttype;
typedef struct krb5_salt {
krb5_salttype salttype;
krb5_data saltvalue;
} krb5_salt;
typedef ETYPE_INFO krb5_preauthinfo; typedef ETYPE_INFO krb5_preauthinfo;
typedef struct { typedef struct {
@@ -139,14 +213,10 @@ typedef HostAddress krb5_address;
typedef HostAddresses krb5_addresses; typedef HostAddresses krb5_addresses;
#define KEYTYPE_USE_AFS3_SALT 0x10000 /* XXX */
#define KEYTYPE_KEYTYPE_MASK 0xffff /* XXX */
typedef enum krb5_keytype { typedef enum krb5_keytype {
KEYTYPE_NULL = 0, KEYTYPE_NULL = 0,
KEYTYPE_DES = 1, KEYTYPE_DES = 1,
KEYTYPE_DES3 = 7, KEYTYPE_DES3 = 7
KEYTYPE_DES_AFS3 = KEYTYPE_DES | KEYTYPE_USE_AFS3_SALT
} krb5_keytype; } krb5_keytype;
typedef EncryptionKey krb5_keyblock; typedef EncryptionKey krb5_keyblock;
@@ -158,7 +228,6 @@ struct krb5_cc_ops;
#define KRB5_DEFAULT_CCROOT "FILE:/tmp/krb5cc_" #define KRB5_DEFAULT_CCROOT "FILE:/tmp/krb5cc_"
typedef struct krb5_ccache_data { typedef struct krb5_ccache_data {
char *residual;
struct krb5_cc_ops *ops; struct krb5_cc_ops *ops;
krb5_data data; krb5_data data;
}krb5_ccache_data; }krb5_ccache_data;
@@ -289,7 +358,6 @@ typedef struct krb5_context_data {
struct krb5_log_facility *warn_dest; struct krb5_log_facility *warn_dest;
krb5_cc_ops *cc_ops; krb5_cc_ops *cc_ops;
int num_ops; int num_ops;
krb5_boolean ktype_is_etype;
const char *http_proxy; const char *http_proxy;
const char *time_fmt; const char *time_fmt;
krb5_boolean log_utc; krb5_boolean log_utc;
@@ -351,7 +419,7 @@ struct krb5_keytab_data {
krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t); krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t);
krb5_error_code (*close)(krb5_context, krb5_keytab); krb5_error_code (*close)(krb5_context, krb5_keytab);
krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal, krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal,
krb5_kvno, krb5_keytype, krb5_keytab_entry*); krb5_kvno, krb5_enctype, krb5_keytab_entry*);
krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*); krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*);
krb5_error_code (*next_entry)(krb5_context, krb5_keytab, krb5_error_code (*next_entry)(krb5_context, krb5_keytab,
krb5_keytab_entry*, krb5_kt_cursor*); krb5_keytab_entry*, krb5_kt_cursor*);
@@ -378,9 +446,7 @@ enum {
}; };
typedef struct krb5_auth_context_data { typedef struct krb5_auth_context_data {
int32_t flags; unsigned int flags;
krb5_cksumtype cksumtype;
krb5_enctype enctype;
krb5_address *local_address; krb5_address *local_address;
krb5_address *remote_address; krb5_address *remote_address;
@@ -443,12 +509,13 @@ typedef int (*krb5_prompter_fct)(krb5_context context,
krb5_prompt prompts[]); krb5_prompt prompts[]);
typedef krb5_error_code (*krb5_key_proc)(krb5_context context, typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
krb5_keytype type, krb5_enctype type,
krb5_data *salt, krb5_salt salt,
krb5_const_pointer keyseed, krb5_const_pointer keyseed,
krb5_keyblock **key); krb5_keyblock **key);
typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context, typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
const krb5_keyblock *key, krb5_keyblock *key,
krb5_key_usage usage,
krb5_const_pointer decrypt_arg, krb5_const_pointer decrypt_arg,
krb5_kdc_rep *dec_rep); krb5_kdc_rep *dec_rep);

View File

@@ -38,31 +38,33 @@ error_code SERVER_NOMATCH, "Requested server and ticket don't match"
# 27-30 are reserved # 27-30 are reserved
index 31 index 31
prefix KRB5KRB_AP_ERR prefix KRB5KRB_AP
error_code BAD_INTEGRITY, "Decrypt integrity check failed" error_code ERR_BAD_INTEGRITY, "Decrypt integrity check failed"
error_code TKT_EXPIRED, "Ticket expired" error_code ERR_TKT_EXPIRED, "Ticket expired"
error_code TKT_NYV, "Ticket not yet valid" error_code ERR_TKT_NYV, "Ticket not yet valid"
error_code REPEAT, "Request is a replay" error_code ERR_REPEAT, "Request is a replay"
error_code NOT_US, "The ticket isn't for us" error_code ERR_NOT_US, "The ticket isn't for us"
error_code BADMATCH, "Ticket/authenticator don't match" error_code ERR_BADMATCH, "Ticket/authenticator don't match"
error_code SKEW, "Clock skew too great" error_code ERR_SKEW, "Clock skew too great"
error_code BADADDR, "Incorrect net address" error_code ERR_BADADDR, "Incorrect net address"
error_code BADVERSION, "Protocol version mismatch" error_code ERR_BADVERSION, "Protocol version mismatch"
error_code MSG_TYPE, "Invalid message type" error_code ERR_MSG_TYPE, "Invalid message type"
error_code MODIFIED, "Message stream modified" error_code ERR_MODIFIED, "Message stream modified"
error_code BADORDER, "Message out of order" error_code ERR_BADORDER, "Message out of order"
error_code ILL_CR_TKT, "Illegal cross-realm ticket" error_code ERR_ILL_CR_TKT, "Illegal cross-realm ticket"
error_code BADKEYVER, "Key version is not available" error_code ERR_BADKEYVER, "Key version is not available"
error_code NOKEY, "Service key not available" error_code ERR_NOKEY, "Service key not available"
error_code MUT_FAIL, "Mutual authentication failed" error_code ERR_MUT_FAIL, "Mutual authentication failed"
error_code BADDIRECTION, "Incorrect message direction" error_code ERR_BADDIRECTION, "Incorrect message direction"
error_code METHOD, "Alternative authentication method required" error_code ERR_METHOD, "Alternative authentication method required"
error_code BADSEQ, "Incorrect sequence number in message" error_code ERR_BADSEQ, "Incorrect sequence number in message"
error_code INAPP_CKSUM, "Inappropriate type of checksum in message" error_code ERR_INAPP_CKSUM, "Inappropriate type of checksum in message"
error_code PATH_NOT_ACCEPTED, "Policy rejects transited path"
# 51-59 are reserved
index 60
prefix KRB5KRB_ERR prefix KRB5KRB_ERR
error_code RESPONSE_TOO_BIG, "Response too big for UDP, retry with TCP"
# 53-59 are reserved
index 60
error_code GENERIC, "Generic error (see e-text)" error_code GENERIC, "Generic error (see e-text)"
error_code FIELD_TOOLONG, "Field is too long for this implementation" error_code FIELD_TOOLONG, "Field is too long for this implementation"

View File

@@ -62,7 +62,7 @@ krb5_mk_priv(krb5_context context,
int32_t sec, usec; int32_t sec, usec;
KerberosTime sec2; KerberosTime sec2;
unsigned usec2; unsigned usec2;
krb5_enctype enctype; krb5_crypto crypto;
/* XXX - Is this right? */ /* XXX - Is this right? */
@@ -73,14 +73,6 @@ krb5_mk_priv(krb5_context context,
else else
key = auth_context->keyblock; key = auth_context->keyblock;
if (auth_context->enctype)
enctype = auth_context->enctype;
else {
ret = krb5_keytype_to_etype (context, key->keytype, &enctype);
if (ret)
return ret;
}
krb5_us_timeofday (context, &sec, &usec); krb5_us_timeofday (context, &sec, &usec);
part.user_data = *userdata; part.user_data = *userdata;
@@ -127,11 +119,17 @@ krb5_mk_priv(krb5_context context,
s.pvno = 5; s.pvno = 5;
s.msg_type = krb_priv; s.msg_type = krb_priv;
s.enc_part.etype = enctype; s.enc_part.etype = key->keytype;
s.enc_part.kvno = NULL; s.enc_part.kvno = NULL;
ret = krb5_encrypt (context, buf + buf_size - len, len, krb5_crypto_init(context, key, 0, &crypto);
enctype, key, &s.enc_part.cipher); ret = krb5_encrypt (context,
crypto,
KRB5_KU_KRB_PRIV,
buf + buf_size - len,
len,
&s.enc_part.cipher);
krb5_crypto_destroy(context, crypto);
if (ret) { if (ret) {
free(buf); free(buf);
return ret; return ret;

View File

@@ -48,10 +48,10 @@ krb5_mk_rep(krb5_context context,
krb5_error_code ret; krb5_error_code ret;
AP_REP ap; AP_REP ap;
EncAPRepPart body; EncAPRepPart body;
krb5_enctype etype;
u_char *buf = NULL; u_char *buf = NULL;
size_t buf_size; size_t buf_size;
size_t len; size_t len;
krb5_crypto crypto;
ap.pvno = 5; ap.pvno = 5;
ap.msg_type = krb_ap_rep; ap.msg_type = krb_ap_rep;
@@ -72,86 +72,50 @@ krb5_mk_rep(krb5_context context,
} else } else
body.seq_number = NULL; body.seq_number = NULL;
krb5_keytype_to_etype(context, (*auth_context)->keyblock->keytype, &etype); ap.enc_part.etype = (*auth_context)->keyblock->keytype;
ap.enc_part.etype = etype;
ap.enc_part.kvno = NULL; ap.enc_part.kvno = NULL;
buf_size = 1024; buf_size = length_EncAPRepPart(&body);
buf = malloc (buf_size); buf = malloc (buf_size);
if (buf == NULL) { if (buf == NULL) {
free_EncAPRepPart (&body); free_EncAPRepPart (&body);
return ENOMEM; return ENOMEM;
} }
do { ret = krb5_encode_EncAPRepPart (context,
ret = krb5_encode_EncAPRepPart (context, buf + buf_size - 1, buf + buf_size - 1,
buf_size, buf_size,
&body, &len); &body,
if (ret) { &len);
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free(buf);
free_EncAPRepPart (&body);
return ENOMEM;
}
buf = tmp;
} else {
free_EncAPRepPart (&body);
free(buf);
return ret;
}
}
} while(ret == ASN1_OVERFLOW);
free_EncAPRepPart (&body);
krb5_crypto_init(context, (*auth_context)->keyblock,
0 /* ap.enc_part.etype */, &crypto);
ret = krb5_encrypt (context, ret = krb5_encrypt (context,
buf + buf_size - len, len, crypto,
ap.enc_part.etype, KRB5_KU_AP_REQ_ENC_PART,
(*auth_context)->keyblock, buf + buf_size - len,
len,
&ap.enc_part.cipher); &ap.enc_part.cipher);
krb5_crypto_destroy(context, crypto);
if (ret) { if (ret) {
free(buf); free(buf);
free_EncAPRepPart (&body);
return ret; return ret;
} }
do { buf_size = length_AP_REP(&ap);
ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len); buf = realloc(buf, buf_size);
if (ret) { if(buf == NULL) {
if (ret == ASN1_OVERFLOW) { free_AP_REP (&ap);
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free_AP_REP (&ap);
free_EncAPRepPart (&body);
free (buf);
return ENOMEM;
}
buf = tmp;
} else {
free_AP_REP (&ap);
free_EncAPRepPart (&body);
free(buf);
return ret;
}
}
} while (ret == ASN1_OVERFLOW);
free_AP_REP (&ap);
free_EncAPRepPart (&body);
outbuf->length = len;
outbuf->data = malloc(len);
if (outbuf->data == NULL) {
free (buf);
return ENOMEM; return ENOMEM;
} }
memcpy(outbuf->data, buf + buf_size - len, len); ret = encode_AP_REP (buf + buf_size - 1, buf_size, &ap, &len);
free (buf);
free_AP_REP (&ap);
if(len != buf_size)
abort();
outbuf->data = buf;
outbuf->length = len;
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -82,9 +82,8 @@ krb5_mk_req(krb5_context context,
if (r) if (r)
return r; return r;
this_cred.times.endtime = 0; this_cred.times.endtime = 0;
if (auth_context && *auth_context && (*auth_context)->enctype) if (auth_context && *auth_context && (*auth_context)->keyblock)
krb5_etype_to_keytype(context, (*auth_context)->enctype, this_cred.session.keytype = (*auth_context)->keyblock->keytype;
&this_cred.session.keytype);
r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred); r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
if (r) if (r)

View File

@@ -41,20 +41,19 @@
RCSID("$Id$"); RCSID("$Id$");
krb5_error_code krb5_error_code
krb5_mk_req_extended(krb5_context context, krb5_mk_req_internal(krb5_context context,
krb5_auth_context *auth_context, krb5_auth_context *auth_context,
const krb5_flags ap_req_options, const krb5_flags ap_req_options,
krb5_data *in_data, krb5_data *in_data,
krb5_creds *in_creds, krb5_creds *in_creds,
krb5_data *outbuf) krb5_data *outbuf,
krb5_key_usage usage)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_data authenticator; krb5_data authenticator;
Checksum c; Checksum c;
Checksum *c_opt; Checksum *c_opt;
krb5_cksumtype cksumtype;
krb5_auth_context ac; krb5_auth_context ac;
krb5_enctype enctype;
if(auth_context) { if(auth_context) {
if(*auth_context == NULL) if(*auth_context == NULL)
@@ -67,6 +66,7 @@ krb5_mk_req_extended(krb5_context context,
if(ret) if(ret)
return ret; return ret;
#if 0
{ {
/* This is somewhat bogus since we're possibly overwriting a /* This is somewhat bogus since we're possibly overwriting a
value specified by the user, but it's the easiest way to make value specified by the user, but it's the easiest way to make
@@ -78,9 +78,9 @@ krb5_mk_req_extended(krb5_context context,
in_creds->ticket.length, in_creds->ticket.length,
&ticket, &ticket,
NULL); NULL);
krb5_etype_to_keytype (context, krb5_enctype_to_keytype (context,
ticket.enc_part.etype, ticket.enc_part.etype,
&ticket_keytype); &ticket_keytype);
if (ticket_keytype == in_creds->session.keytype) if (ticket_keytype == in_creds->session.keytype)
krb5_auth_setenctype(context, krb5_auth_setenctype(context,
@@ -88,32 +88,22 @@ krb5_mk_req_extended(krb5_context context,
ticket.enc_part.etype); ticket.enc_part.etype);
free_Ticket(&ticket); free_Ticket(&ticket);
} }
#endif
krb5_free_keyblock(context, ac->keyblock); krb5_free_keyblock(context, ac->keyblock);
krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock); krb5_copy_keyblock(context, &in_creds->session, &ac->keyblock);
if (ac->enctype)
enctype = ac->enctype;
else {
ret = krb5_keytype_to_etype(context,
ac->keyblock->keytype,
&enctype);
if (ret)
return ret;
}
if (ac->cksumtype)
cksumtype = ac->cksumtype;
else
krb5_keytype_to_cksumtype (context, ac->keyblock->keytype, &cksumtype);
if (in_data) { if (in_data) {
ret = krb5_create_checksum (context, krb5_crypto crypto;
cksumtype, krb5_crypto_init(context, ac->keyblock, 0, &crypto);
in_data->data, ret = krb5_create_checksum(context,
in_data->length, crypto,
ac->keyblock, usage,
&c); in_data->data,
in_data->length,
&c);
krb5_crypto_destroy(context, crypto);
c_opt = &c; c_opt = &c;
} else { } else {
c_opt = NULL; c_opt = NULL;
@@ -121,7 +111,7 @@ krb5_mk_req_extended(krb5_context context,
ret = krb5_build_authenticator (context, ret = krb5_build_authenticator (context,
ac, ac,
enctype, ac->keyblock->keytype,
in_creds, in_creds,
c_opt, c_opt,
NULL, NULL,
@@ -131,9 +121,26 @@ krb5_mk_req_extended(krb5_context context,
if (ret) if (ret)
return ret; return ret;
ret = krb5_build_ap_req (context, enctype, in_creds, ap_req_options, ret = krb5_build_ap_req (context, ac->keyblock->keytype,
authenticator, outbuf); in_creds, ap_req_options, authenticator, outbuf);
if(auth_context == NULL) if(auth_context == NULL)
krb5_auth_con_free(context, ac); krb5_auth_con_free(context, ac);
return ret; return ret;
} }
krb5_error_code
krb5_mk_req_extended(krb5_context context,
krb5_auth_context *auth_context,
const krb5_flags ap_req_options,
krb5_data *in_data,
krb5_creds *in_creds,
krb5_data *outbuf)
{
return krb5_mk_req_internal (context,
auth_context,
ap_req_options,
in_data,
in_creds,
outbuf,
KRB5_KU_AP_REQ_AUTH_CKSUM);
}

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997 Kungliga Tekniska H<>gskolan * Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -56,17 +56,7 @@ krb5_mk_safe(krb5_context context,
size_t buf_size; size_t buf_size;
size_t len; size_t len;
unsigned tmp_seq; unsigned tmp_seq;
krb5_cksumtype cksumtype; krb5_crypto crypto;
if (auth_context->cksumtype)
cksumtype = auth_context->cksumtype;
else {
ret = krb5_keytype_to_cksumtype (context,
auth_context->keyblock->keytype,
&cksumtype);
if (ret)
return ret;
}
s.pvno = 5; s.pvno = 5;
s.msg_type = krb_safe; s.msg_type = krb_safe;
@@ -92,68 +82,30 @@ krb5_mk_safe(krb5_context context,
s.cksum.checksum.length = 0; s.cksum.checksum.length = 0;
buf_size = 1024; buf_size = length_KRB_SAFE(&s);
buf = malloc (buf_size); buf = malloc(buf_size + 128); /* add some for checksum */
if (buf == NULL) { if(buf == NULL)
return ENOMEM; return ENOMEM;
} ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
ret = krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
do { ret = krb5_create_checksum(context,
ret = encode_KRB_SAFE (buf + buf_size - 1, crypto,
buf_size, KRB5_KU_KRB_SAFE_CKSUM,
&s, buf + buf_size - len,
&len); len,
if (ret) { &s.cksum);
if (ret == ASN1_OVERFLOW) { krb5_crypto_destroy(context, crypto);
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free (buf);
return ENOMEM;
}
buf = tmp;
} else {
free (buf);
return ENOMEM;
}
}
} while (ret == ASN1_OVERFLOW);
ret = krb5_create_checksum (context,
cksumtype,
buf + buf_size - len,
len,
auth_context->keyblock,
&s.cksum);
if (ret) { if (ret) {
free (buf); free (buf);
return ret; return ret;
} }
do { buf_size = length_KRB_SAFE(&s);
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len); buf = realloc(buf, buf_size);
if (ret) { if(buf == NULL)
if (ret == ASN1_OVERFLOW) { return ENOMEM;
u_char *tmp;
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size, &s, &len);
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
free (buf);
free_Checksum (&s.cksum);
return ENOMEM;
}
buf = tmp;
} else {
free (buf);
free_Checksum (&s.cksum);
return ret;
}
}
} while (ret == ASN1_OVERFLOW);
free_Checksum (&s.cksum); free_Checksum (&s.cksum);
outbuf->length = len; outbuf->length = len;

88
lib/krb5/n-fold.c Normal file
View File

@@ -0,0 +1,88 @@
#include "krb5_locl.h"
static void
rr13(unsigned char *buf, size_t len)
{
unsigned char *tmp;
int bytes = (len + 7) / 8;
int i;
const int bits = 13 % len;
const int lbit = len % 8;
tmp = malloc(bytes);
memcpy(tmp, buf, bytes);
if(lbit) {
/* pad final byte with inital bits */
tmp[bytes - 1] &= 0xff << (8 - lbit);
for(i = lbit; i < 8; i += len)
tmp[bytes - 1] |= buf[0] >> i;
}
for(i = 0; i < bytes; i++) {
int bb;
int b1, s1, b2, s2;
/* calculate first bit position of this byte */
bb = 8 * i - bits;
while(bb < 0)
bb += len;
/* byte offset and shift count */
b1 = bb / 8;
s1 = bb % 8;
if(bb + 8 > bytes * 8)
/* watch for wraparound */
s2 = (len + 8 - s1) % 8;
else
s2 = 8 - s1;
b2 = (b1 + 1) % bytes;
buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2);
}
free(tmp);
}
/* Add `b' to `a', both beeing one's complement numbers. */
static void
add1(unsigned char *a, unsigned char *b, size_t len)
{
int i;
int carry = 0;
for(i = len - 1; i >= 0; i--){
int x = a[i] + b[i] + carry;
carry = x > 0xff;
a[i] = x & 0xff;
}
for(i = len - 1; carry && i >= 0; i--){
int x = a[i] + carry;
carry = x > 0xff;
a[i] = carry & 0xff;
}
}
void
n_fold(const void *str, size_t len, void *key, size_t size)
{
/* if len < size we need at most N * len bytes, ie < 2 * size;
if len > size we need at most 2 * len */
size_t maxlen = 2 * max(size, len);
size_t l = 0;
unsigned char *tmp = malloc(maxlen);
unsigned char *buf = malloc(len);
memcpy(buf, str, len);
memset(key, 0, size);
do {
memcpy(tmp + l, buf, len);
l += len;
rr13(buf, len * 8);
while(l >= size) {
add1(key, tmp, size);
l -= size;
if(l == 0)
break;
memmove(tmp, tmp + size, l);
}
} while(l != 0);
memset(buf, 0, len);
free(buf);
memset(tmp, 0, maxlen);
free(tmp);
}

View File

@@ -186,6 +186,8 @@ unparse_name_fixed(krb5_context context,
if(i) if(i)
add_char(name, index, len, '/'); add_char(name, index, len, '/');
index = quote_string(princ_ncomp(principal, i), name, index, len); index = quote_string(princ_ncomp(principal, i), name, index, len);
if(index == len)
return ERANGE;
} }
/* add realm if different from default realm */ /* add realm if different from default realm */
if(short_form) { if(short_form) {
@@ -202,7 +204,7 @@ unparse_name_fixed(krb5_context context,
add_char(name, index, len, '@'); add_char(name, index, len, '@');
index = quote_string(princ_realm(principal), name, index, len); index = quote_string(princ_realm(principal), name, index, len);
if(index == len) if(index == len)
return ENOMEM; /* XXX */ return ERANGE;
} }
return 0; return 0;
} }

View File

@@ -51,6 +51,7 @@ krb5_rd_cred (krb5_context context,
KRB_CRED cred; KRB_CRED cred;
EncKrbCredPart enc_krb_cred_part; EncKrbCredPart enc_krb_cred_part;
krb5_data enc_krb_cred_part_data; krb5_data enc_krb_cred_part_data;
krb5_crypto crypto;
int i; int i;
ret = decode_KRB_CRED (in_data->data, in_data->length, ret = decode_KRB_CRED (in_data->data, in_data->length,
@@ -68,12 +69,13 @@ krb5_rd_cred (krb5_context context,
goto out; goto out;
} }
ret = krb5_decrypt (context, krb5_crypto_init(context, auth_context->remote_subkey, 0, &crypto);
cred.enc_part.cipher.data, ret = krb5_decrypt_EncryptedData(context,
cred.enc_part.cipher.length, crypto,
cred.enc_part.etype, KRB5_KU_KRB_CRED,
auth_context->remote_subkey, &cred.enc_part,
&enc_krb_cred_part_data); &enc_krb_cred_part_data);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
goto out; goto out;

View File

@@ -53,6 +53,7 @@ krb5_rd_priv(krb5_context context,
size_t len; size_t len;
krb5_data plain; krb5_data plain;
krb5_keyblock *key; krb5_keyblock *key;
krb5_crypto crypto;
memset(&priv, 0, sizeof(priv)); memset(&priv, 0, sizeof(priv));
ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len); ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
@@ -76,12 +77,13 @@ krb5_rd_priv(krb5_context context,
else else
key = auth_context->keyblock; key = auth_context->keyblock;
ret = krb5_decrypt (context, krb5_crypto_init(context, key, 0, &crypto);
priv.enc_part.cipher.data, ret = krb5_decrypt_EncryptedData(context,
priv.enc_part.cipher.length, crypto,
priv.enc_part.etype, KRB5_KU_KRB_PRIV,
key, &priv.enc_part,
&plain); &plain);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
goto failure; goto failure;

View File

@@ -50,6 +50,7 @@ krb5_rd_rep(krb5_context context,
AP_REP ap_rep; AP_REP ap_rep;
size_t len; size_t len;
krb5_data data; krb5_data data;
krb5_crypto crypto;
krb5_data_zero (&data); krb5_data_zero (&data);
ret = 0; ret = 0;
@@ -66,10 +67,13 @@ krb5_rd_rep(krb5_context context,
goto out; goto out;
} }
krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
ret = krb5_decrypt_EncryptedData (context, ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_AP_REQ_ENC_PART,
&ap_rep.enc_part, &ap_rep.enc_part,
auth_context->keyblock,
&data); &data);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
goto out; goto out;

View File

@@ -42,19 +42,22 @@ RCSID("$Id$");
static krb5_error_code static krb5_error_code
decrypt_tkt_enc_part (krb5_context context, decrypt_tkt_enc_part (krb5_context context,
const krb5_keyblock *key, krb5_keyblock *key,
EncryptedData *enc_part, EncryptedData *enc_part,
EncTicketPart *decr_part) EncTicketPart *decr_part)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_data plain; krb5_data plain;
size_t len; size_t len;
krb5_crypto crypto;
ret = krb5_decrypt (context, krb5_crypto_init(context, key, 0, &crypto);
enc_part->cipher.data, ret = krb5_decrypt_EncryptedData (context,
enc_part->cipher.length, crypto,
enc_part->etype, KRB5_KU_TICKET,
key, &plain); enc_part,
&plain);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
return ret; return ret;
@@ -73,12 +76,15 @@ decrypt_authenticator (krb5_context context,
krb5_error_code ret; krb5_error_code ret;
krb5_data plain; krb5_data plain;
size_t len; size_t len;
krb5_crypto crypto;
ret = krb5_decrypt (context, krb5_crypto_init(context, key, 0, &crypto);
enc_part->cipher.data, ret = krb5_decrypt_EncryptedData (context,
enc_part->cipher.length, crypto,
enc_part->etype, KRB5_KU_AP_REQ_AUTH,
key, &plain); enc_part,
&plain);
krb5_crypto_destroy(context, crypto);
if (ret) if (ret)
return ret; return ret;
@@ -145,6 +151,45 @@ krb5_decrypt_ticket(krb5_context context,
return 0; return 0;
} }
krb5_error_code
krb5_verify_authenticator_checksum(krb5_context context,
krb5_auth_context ac,
void *data,
size_t len)
{
krb5_error_code ret;
krb5_keyblock *key;
krb5_authenticator authenticator;
krb5_crypto crypto;
ret = krb5_auth_getauthenticator (context,
ac,
&authenticator);
if(ret)
return ret;
if(authenticator->cksum == NULL)
return -17;
ret = krb5_auth_con_getkey(context, ac, &key);
if(ret) {
krb5_free_authenticator(context, &authenticator);
return ret;
}
ret = krb5_crypto_init(context, key, 0, &crypto);
if(ret)
goto out;
ret = krb5_verify_checksum (context,
crypto,
KRB5_KU_AP_REQ_AUTH_CKSUM,
data,
len,
authenticator->cksum);
krb5_crypto_destroy(context, crypto);
out:
krb5_free_authenticator(context, &authenticator);
krb5_free_keyblock(context, key);
return ret;
}
krb5_error_code krb5_error_code
krb5_verify_ap_req(krb5_context context, krb5_verify_ap_req(krb5_context context,
krb5_auth_context *auth_context, krb5_auth_context *auth_context,
@@ -303,7 +348,6 @@ get_key_from_keytab(krb5_context context,
krb5_keytab_entry entry; krb5_keytab_entry entry;
krb5_error_code ret; krb5_error_code ret;
int kvno; int kvno;
krb5_keytype keytype;
krb5_keytab real_keytab; krb5_keytab real_keytab;
if(keytab == NULL) if(keytab == NULL)
@@ -316,17 +360,11 @@ get_key_from_keytab(krb5_context context,
else else
kvno = 0; kvno = 0;
ret = krb5_etype_to_keytype (context,
ap_req->ticket.enc_part.etype,
&keytype);
if (ret)
goto out;
ret = krb5_kt_get_entry (context, ret = krb5_kt_get_entry (context,
real_keytab, real_keytab,
server, server,
kvno, kvno,
keytype, ap_req->ticket.enc_part.etype,
&entry); &entry);
if(ret) if(ret)
goto out; goto out;

View File

@@ -50,48 +50,36 @@ verify_checksum(krb5_context context,
size_t buf_size; size_t buf_size;
size_t len; size_t len;
Checksum c; Checksum c;
krb5_crypto crypto;
c = safe->cksum; c = safe->cksum;
safe->cksum.cksumtype = 0; safe->cksum.cksumtype = 0;
safe->cksum.checksum.data = NULL; safe->cksum.checksum.data = NULL;
safe->cksum.checksum.length = 0; safe->cksum.checksum.length = 0;
buf_size = 1024;
buf = malloc (buf_size); buf_size = length_KRB_SAFE(safe);
buf = malloc(buf_size);
if (buf == NULL) { if (buf == NULL) {
free_Checksum(&c); ret = ENOMEM;
return ENOMEM; goto out;
} }
do { ret = encode_KRB_SAFE (buf + buf_size - 1,
ret = encode_KRB_SAFE (buf + buf_size - 1, buf_size,
buf_size, safe,
safe, &len);
&len); krb5_crypto_init(context, auth_context->keyblock, 0, &crypto);
if (ret) {
if (ret == ASN1_OVERFLOW) {
u_char *tmp;
buf_size *= 2;
tmp = realloc (buf, buf_size);
if (tmp == NULL) {
ret = ENOMEM;
goto out;
}
buf = tmp;
} else {
goto out;
}
}
} while(ret == ASN1_OVERFLOW);
ret = krb5_verify_checksum (context, ret = krb5_verify_checksum (context,
crypto,
KRB5_KU_KRB_SAFE_CKSUM,
buf + buf_size - len, buf + buf_size - len,
len, len,
auth_context->keyblock,
&c); &c);
krb5_crypto_destroy(context, crypto);
out: out:
free_Checksum (&c); safe->cksum = c;
free (buf); free (buf);
return ret; return ret;
} }
@@ -118,8 +106,8 @@ krb5_rd_safe(krb5_context context,
ret = KRB5KRB_AP_ERR_MSG_TYPE; ret = KRB5KRB_AP_ERR_MSG_TYPE;
goto failure; goto failure;
} }
if (!krb5_checksum_is_keyed(safe.cksum.cksumtype) if (!krb5_checksum_is_keyed(context, safe.cksum.cksumtype)
|| !krb5_checksum_is_collision_proof(safe.cksum.cksumtype)) { || !krb5_checksum_is_collision_proof(context, safe.cksum.cksumtype)) {
ret = KRB5KRB_AP_ERR_INAPP_CKSUM; ret = KRB5KRB_AP_ERR_INAPP_CKSUM;
goto failure; goto failure;
} }

View File

@@ -1,462 +0,0 @@
/*
* Copyright (c) 1997, 1998 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Kungliga Tekniska
* H<>gskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <krb5_locl.h>
RCSID("$Id$");
/*
* Reverse 8 bytes
*/
static void
reverse (unsigned char *s)
{
static const unsigned char tbl[] = {
0x0,
0x8,
0x4,
0xC,
0x2,
0xA,
0x6,
0xE,
0x1,
0x9,
0x5,
0xD,
0x3,
0xB,
0x7,
0xF
};
char tmp;
#define REVONE(str, i, j) \
do { tmp = str[i]; str[i] = str[j]; str[j] = tmp;} while(0)
REVONE(s,0,7);
REVONE(s,1,6);
REVONE(s,2,5);
REVONE(s,3,4);
#undef REVONE
#define REVTWO(q) \
q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4])
REVTWO(s[0]);
REVTWO(s[1]);
REVTWO(s[2]);
REVTWO(s[3]);
REVTWO(s[4]);
REVTWO(s[5]);
REVTWO(s[6]);
REVTWO(s[7]);
#undef REVTWO
}
/*
* A = A xor B. A & B is 8 bytes.
*/
static void
xor (des_cblock *key, const unsigned char *b)
{
unsigned char *a = (unsigned char*)key;
a[0] ^= b[0];
a[1] ^= b[1];
a[2] ^= b[2];
a[3] ^= b[3];
a[4] ^= b[4];
a[5] ^= b[5];
a[6] ^= b[6];
a[7] ^= b[7];
}
/*
* Init a from b
*/
static void
init (unsigned char *a, const unsigned char *b)
{
a[0] = b[0] << 1;
a[1] = b[1] << 1;
a[2] = b[2] << 1;
a[3] = b[3] << 1;
a[4] = b[4] << 1;
a[5] = b[5] << 1;
a[6] = b[6] << 1;
a[7] = b[7] << 1;
}
static void
DES_string_to_key(const char *str, size_t len, des_cblock *key)
{
/* could use des_string_to_key here, but then `str' must be zero
terminated, and the final weak-key check has to be added */
int even, i;
des_key_schedule sched;
memset (key, 0, sizeof(des_cblock));
even = 0;
for (i = 0; i < len; i += 8) {
unsigned char tmp[8];
init (tmp, (const unsigned char*)(str + i));
if (even) {
reverse (tmp);
init (tmp, tmp);
}
even = !even;
xor (key, tmp);
}
des_set_odd_parity (key);
des_set_key (key, sched);
des_cbc_cksum ((des_cblock *)str, key, len, sched, key);
des_set_odd_parity (key);
if (des_is_weak_key (key))
xor (key, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
}
static void
rr13(unsigned char *buf, size_t len)
{
int i;
/* assert(len >= 3); */
unsigned a = buf[0], b = buf[len-1];
#define F(A, B) ((((A) << 3) | ((B) >> 5)) & 0xff)
buf[0] = F(buf[len-2], buf[len-1]);
for(i = len - 3; i >= 1; i--)
buf[i + 2] = F(buf[i], buf[i+1]);
buf[2] = F(a, buf[1]);
buf[1] = F(b, a);
#undef F
}
/* Add `b' to `a', both beeing one's complement numbers. */
static void
add1(unsigned char *a, unsigned char *b, size_t len)
{
int i;
int carry = 0;
for(i = len - 1; i >= 0; i--){
int x = a[i] + b[i] + carry;
carry = x > 0xff;
a[i] = x & 0xff;
}
for(i = len - 1; carry && i >= 0; i--){
int x = a[i] + carry;
carry = x > 0xff;
a[i] = carry & 0xff;
}
}
/* key should point to a buffer of at least size (24) bytes */
static void
fold(const unsigned char *str, size_t len, unsigned char *key)
{
const int size = 24;
/* if len < size we need at most N * len bytes, ie < 2 * size;
if len > size we need at most 2 * len */
size_t maxlen = 2 * max(size, len);
size_t l = 0;
unsigned char *tmp = malloc(maxlen);
unsigned char *buf = malloc(len);
memcpy(buf, str, len);
memset(key, 0, size);
do {
memcpy(tmp + l, buf, len);
l += len;
rr13(buf, len);
while(l >= size) {
add1(key, tmp, size);
l -= size;
if(l == 0)
break;
memmove(tmp, tmp + size, l);
}
} while(l != 0);
memset(buf, 0, len);
free(buf);
memset(tmp, 0, maxlen);
free(tmp);
}
static void
DES3_string_to_key(const unsigned char *str, size_t len, des_cblock *keys)
{
unsigned char tmp[24];
des_cblock ivec;
des_key_schedule s[3];
int i;
fold(str, len, tmp);
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + 8 * i, 8);
des_set_odd_parity(keys + i);
if(des_is_weak_key(keys + i))
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
des_set_key(keys + i, s[i]);
}
memset(&ivec, 0, sizeof(ivec));
des_ede3_cbc_encrypt((void*)tmp, (void*)tmp, sizeof(tmp),
s[0], s[1], s[2], &ivec, 1);
memset(s, 0, sizeof(s));
for(i = 0; i < 3; i++){
memcpy(keys + i, tmp + 8 * i, 8);
des_set_odd_parity(keys + i);
if(des_is_weak_key(keys + i))
xor(keys + i, (unsigned char*)"\0\0\0\0\0\0\0\xf0");
}
memset(tmp, 0, sizeof(tmp));
}
/* This defines the Andrew string_to_key function. It accepts a password
* string as input and converts its via a one-way encryption algorithm to a DES
* encryption key. It is compatible with the original Andrew authentication
* service password database.
*/
/*
* Short passwords, i.e 8 characters or less.
*/
static void
afs_cmu_StringToKey (const char *pw, size_t pw_len,
const char *cell, size_t cell_len,
des_cblock *key)
{
char password[8+1]; /* crypt is limited to 8 chars anyway */
int i;
memset (password, 0, sizeof(password));
if(cell_len > 8) cell_len = 8;
strncpy (password, cell, cell_len);
if(pw_len > 8) pw_len = 8;
for (i=0; i < pw_len; i++)
password[i] ^= pw[i];
for (i=0; i<8; i++)
if (password[i] == '\0') password[i] = 'X';
/* crypt only considers the first 8 characters of password but for some
reason returns eleven characters of result (plus the two salt chars). */
strncpy((char *)key, (char *)crypt(password, "#~") + 2, sizeof(des_cblock));
/* parity is inserted into the LSB so leftshift each byte up one bit. This
allows ascii characters with a zero MSB to retain as much significance
as possible. */
{ char *keybytes = (char *)key;
unsigned int temp;
for (i = 0; i < 8; i++) {
temp = (unsigned int) keybytes[i];
keybytes[i] = (unsigned char) (temp << 1);
}
}
des_fixup_key_parity (key);
}
/*
* Long passwords, i.e 9 characters or more.
*/
static void
afs_transarc_StringToKey (const char *pw, size_t pw_len,
const char *cell, size_t cell_len,
des_cblock *key)
{
des_key_schedule schedule;
des_cblock temp_key;
des_cblock ivec;
char password[512];
size_t passlen;
memcpy(password, pw, min(pw_len, sizeof(password)));
if(pw_len < sizeof(password))
memcpy(password + pw_len, cell, min(cell_len,
sizeof(password) - pw_len));
passlen = min(sizeof(password), pw_len + cell_len);
memcpy(&ivec, "kerberos", 8);
memcpy(&temp_key, "kerberos", 8);
des_fixup_key_parity (&temp_key);
des_key_sched (&temp_key, schedule);
des_cbc_cksum ((des_cblock *)password, &ivec, passlen, schedule, &ivec);
memcpy(&temp_key, &ivec, 8);
des_fixup_key_parity (&temp_key);
des_key_sched (&temp_key, schedule);
des_cbc_cksum ((des_cblock *)password, key, passlen, schedule, &ivec);
memset(&schedule, 0, sizeof(schedule));
memset(&temp_key, 0, sizeof(temp_key));
memset(&ivec, 0, sizeof(ivec));
memset(password, 0, sizeof(password));
des_fixup_key_parity (key);
}
static void
AFS3_string_to_key(const char *pw, size_t pw_len,
const char *cell, size_t cell_len,
des_cblock *key)
{
if(pw_len > 8)
afs_transarc_StringToKey (pw, pw_len, cell, cell_len, key);
else
afs_cmu_StringToKey (pw, pw_len, cell, cell_len, key);
}
static void *
get_str(const void *pw, size_t pw_len, const void *salt, size_t salt_len,
size_t *ret_len)
{
char *p;
size_t len = pw_len + salt_len;
len = (len + 7) & ~7;
p = calloc(len, 1);
if(p == NULL)
return NULL;
memcpy(p, pw, pw_len);
memcpy(p + pw_len, salt, salt_len);
*ret_len = len;
return p;
}
static krb5_error_code
string_to_key_internal (const unsigned char *str,
size_t str_len,
krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key)
{
size_t len;
unsigned char *s = NULL;
krb5_error_code ret;
switch(ktype & KEYTYPE_KEYTYPE_MASK){
case KEYTYPE_DES:{
des_cblock tmpkey;
if(ktype & KEYTYPE_USE_AFS3_SALT)
AFS3_string_to_key(str, str_len, salt->data, salt->length, &tmpkey);
else{
s = get_str(str, str_len, salt->data, salt->length, &len);
if(s == NULL)
return ENOMEM;
DES_string_to_key(s, len, &tmpkey);
}
ret = krb5_data_copy(&key->keyvalue, tmpkey, sizeof(des_cblock));
memset(&tmpkey, 0, sizeof(tmpkey));
break;
}
case KEYTYPE_DES3:{
des_cblock keys[3];
s = get_str(str, str_len, salt->data, salt->length, &len);
if(s == NULL)
return ENOMEM;
/* only des should pad to 8 */
DES3_string_to_key(s, str_len + salt->length, keys);
ret = krb5_data_copy(&key->keyvalue, keys, sizeof(keys));
memset(keys, 0, sizeof(keys));
break;
}
default:
ret = KRB5_PROG_KEYTYPE_NOSUPP;
break;
}
if(s){
memset(s, 0, len);
free(s);
}
if(ret)
return ret;
key->keytype = ktype & KEYTYPE_KEYTYPE_MASK;
return 0;
}
krb5_error_code
krb5_string_to_key (const char *str,
krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key)
{
return string_to_key_internal ((const unsigned char *)str,
strlen(str), salt, ktype, key);
}
krb5_error_code
krb5_string_to_key_data (krb5_data *str,
krb5_data *salt,
krb5_keytype ktype,
krb5_keyblock *key)
{
return string_to_key_internal (str->data, str->length, salt, ktype, key);
}
krb5_error_code
krb5_get_salt (krb5_principal princ,
krb5_data *salt)
{
size_t len;
int i;
krb5_error_code err;
char *p;
len = strlen(princ->realm);
for (i = 0; i < princ->name.name_string.len; ++i)
len += strlen(princ->name.name_string.val[i]);
err = krb5_data_alloc (salt, len);
if (err)
return err;
p = salt->data;
strncpy (p, princ->realm, strlen(princ->realm));
p += strlen(princ->realm);
for (i = 0; i < princ->name.name_string.len; ++i) {
strncpy (p,
princ->name.name_string.val[i],
strlen(princ->name.name_string.val[i]));
p += strlen(princ->name.name_string.val[i]);
}
return 0;
}

View File

@@ -114,7 +114,7 @@ make_path(struct tr_realm *r, const char *from, const char *to)
return ENOMEM; return ENOMEM;
} }
strncpy(path->realm, from, p - from); strncpy(path->realm, from, p - from);
path->realm[p - from] = 0; path->realm[p - from] = '\0';
p--; p--;
} }
}else }else
@@ -136,8 +136,8 @@ make_paths(struct tr_realm *realms, const char *client_realm,
/* it *might* be that you can have more than one empty /* it *might* be that you can have more than one empty
component in a row, at least that's how I interpret the component in a row, at least that's how I interpret the
"," exception in 1510 */ "," exception in 1510 */
if(r->realm[0] == 0){ if(r->realm[0] == '\0'){
while(r->next && r->next->realm[0] == 0) while(r->next && r->next->realm[0] == '\0')
r = r->next; r = r->next;
if(r->next) if(r->next)
next_realm = r->next->realm; next_realm = r->next->realm;
@@ -218,11 +218,11 @@ make_realm(char *realm)
quote = 1; quote = 1;
continue; continue;
} }
if(p[0] == '.' && p[1] == 0) if(p[0] == '.' && p[1] == '\0')
r->trailing_dot = 1; r->trailing_dot = 1;
*q++ = *p; *q++ = *p;
} }
*q = 0; *q = '\0';
return r; return r;
} }
@@ -262,7 +262,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
if(tr[i] == ','){ if(tr[i] == ','){
tmp = malloc(tr + i - start + 1); tmp = malloc(tr + i - start + 1);
strncpy(tmp, start, tr + i - start); strncpy(tmp, start, tr + i - start);
tmp[tr + i - start] = 0; tmp[tr + i - start] = '\0';
r = make_realm(tmp); r = make_realm(tmp);
if(r == NULL){ if(r == NULL){
free_realms(*realms); free_realms(*realms);
@@ -274,7 +274,7 @@ decode_realms(const char *tr, int length, struct tr_realm **realms)
} }
tmp = malloc(tr + i - start + 1); tmp = malloc(tr + i - start + 1);
strncpy(tmp, start, tr + i - start); strncpy(tmp, start, tr + i - start);
tmp[tr + i - start] = 0; tmp[tr + i - start] = '\0';
r = make_realm(tmp); r = make_realm(tmp);
if(r == NULL){ if(r == NULL){
free_realms(*realms); free_realms(*realms);
@@ -311,7 +311,7 @@ krb5_domain_x500_decode(krb5_data tr, char ***realms, int *num_realms,
/* remove empty components */ /* remove empty components */
q = &r; q = &r;
for(p = r; p; ){ for(p = r; p; ){
if(p->realm[0] == 0){ if(p->realm[0] == '\0'){
free(p->realm); free(p->realm);
*q = p->next; *q = p->next;
free(p); free(p);
@@ -354,7 +354,7 @@ krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding)
} }
len += num_realms - 1; len += num_realms - 1;
s = malloc(len + 1); s = malloc(len + 1);
*s = 0; *s = '\0';
for(i = 0; i < num_realms; i++){ for(i = 0; i < num_realms; i++){
if(i && i < num_realms - 1) if(i && i < num_realms - 1)
strcat(s, ","); strcat(s, ",");

View File

@@ -31,6 +31,10 @@ Tue Sep 8 05:18:31 1998 Assar Westerlund <assar@sics.se>
* recvmsg.c (recvmsg): patch from bpreece@unity.ncsu.edu * recvmsg.c (recvmsg): patch from bpreece@unity.ncsu.edu
Fri Sep 4 16:29:27 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* vsyslog.c: asprintf -> vasprintf
Tue Aug 18 22:25:52 1998 Assar Westerlund <assar@sics.se> Tue Aug 18 22:25:52 1998 Assar Westerlund <assar@sics.se>
* getarg.h (arg_printusage): new signature * getarg.h (arg_printusage): new signature
@@ -47,6 +51,10 @@ Fri Jul 24 21:56:02 1998 Assar Westerlund <assar@sics.se>
* simple_exec.c (simple_execvp): loop around waitpid when errno == * simple_exec.c (simple_execvp): loop around waitpid when errno ==
EINTR EINTR
Thu Jul 23 20:24:35 1998 Johan Danielsson <joda@emma.pdc.kth.se>
* Makefile.am: net_{read,write}.c
Wed Jul 22 21:38:35 1998 Assar Westerlund <assar@sics.se> Wed Jul 22 21:38:35 1998 Assar Westerlund <assar@sics.se>
* simple_exec.c (simple_execlp): initialize `argv' * simple_exec.c (simple_execlp): initialize `argv'

View File

@@ -21,9 +21,9 @@ libroken_la_SOURCES = \
issuid.c \ issuid.c \
k_getpwnam.c \ k_getpwnam.c \
k_getpwuid.c \ k_getpwuid.c \
mini_inetd.c \
net_read.c \ net_read.c \
net_write.c \ net_write.c \
mini_inetd.c \
parse_time.c \ parse_time.c \
parse_units.c \ parse_units.c \
print_version.c \ print_version.c \

View File

@@ -54,7 +54,7 @@ vsyslog(int pri, const char *fmt, va_list ap)
{ {
char *p; char *p;
asprintf (&p, fmt, ap); vasprintf (&p, fmt, ap);
syslog (pri, "%s", p); syslog (pri, "%s", p);
free (p); free (p);
} }