summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-07-29 16:10:32 +0000
committerGreg Hudson <ghudson@mit.edu>2009-07-29 16:10:32 +0000
commitd71bb0ac2c2f24486971aca60efe0b5d7e878c30 (patch)
treea8222af86306199b03c2656f40baaf47bbc85094 /src
parent0479bee230a5fb18a7b1333dcf2678250241438f (diff)
downloadkrb5-d71bb0ac2c2f24486971aca60efe0b5d7e878c30.tar.gz
krb5-d71bb0ac2c2f24486971aca60efe0b5d7e878c30.tar.xz
krb5-d71bb0ac2c2f24486971aca60efe0b5d7e878c30.zip
Enctype list configuration enhancements
In the processing code for enctype lists, add support for "DEFAULT" to indicate the default list, for families (des/des3/aes/rc4), and for removing entries from the current list (-foo). Also add unit tests and document. ticket: 6539 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22469 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/include/k5-int.h4
-rw-r--r--src/lib/krb5/krb/Makefile.in11
-rw-r--r--src/lib/krb5/krb/init_ctx.c200
-rw-r--r--src/lib/krb5/krb/t_etypes.c201
4 files changed, 338 insertions, 78 deletions
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index d4407b99d..c2f112709 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2795,6 +2795,10 @@ krb5int_pac_sign(krb5_context context,
const krb5_keyblock *privsvr_key,
krb5_data *data);
+krb5_error_code krb5int_parse_enctype_list(krb5_context context, char *profstr,
+ krb5_enctype *default_list,
+ krb5_enctype **result);
+
#ifdef DEBUG_ERROR_LOCATIONS
#define krb5_set_error_message(ctx, code, ...) \
krb5_set_error_message_fl(ctx, code, __FILE__, __LINE__, __VA_ARGS__)
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index db1f82372..1a08eccc4 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -284,7 +284,8 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/t_deltat.c \
$(srcdir)/t_expand.c \
$(srcdir)/t_pac.c \
- $(srcdir)/t_princ.c
+ $(srcdir)/t_princ.c \
+ $(srcdir)/t_etypes.c
# Someday, when we have a "maintainer mode", do this right:
BISON=bison
@@ -316,6 +317,8 @@ T_PAC_OBJS= t_pac.o pac.o
T_PRINC_OBJS= t_princ.o parse.o unparse.o
+T_ETYPES_OBJS= t_etypes.o init_ctx.o
+
t_walk_rtree: $(T_WALK_RTREE_OBJS) $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o t_walk_rtree $(T_WALK_RTREE_OBJS) $(KRB5_BASE_LIBS)
t_ad_fx_armor: t_ad_fx_armor.o
@@ -344,8 +347,11 @@ t_pac: $(T_PAC_OBJS) $(KRB5_BASE_DEPLIBS)
t_princ: $(T_PRINC_OBJS) $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o t_princ $(T_PRINC_OBJS) $(KRB5_BASE_LIBS)
+t_etypes: $(T_ETYPES_OBJS) $(KRB5_BASE_DEPLIBS)
+ $(CC_LINK) -o t_etypes $(T_ETYPES_OBJS) $(KRB5_BASE_LIBS)
+
TEST_PROGS= t_walk_rtree t_kerb t_ser t_deltat t_expand t_authdata t_pac \
- t_princ
+ t_princ t_etypes
check-unix:: $(TEST_PROGS)
KRB5_CONFIG=$(srcdir)/t_krb5.conf ; export KRB5_CONFIG ;\
@@ -382,6 +388,7 @@ check-unix:: $(TEST_PROGS)
$(RUN_SETUP) $(VALGRIND) ./t_authdata
$(RUN_SETUP) $(VALGRIND) ./t_pac
$(RUN_SETUP) $(VALGRIND) ./t_princ
+ $(RUN_SETUP) $(VALGRIND) ./t_etypes
clean::
$(RM) $(OUTPRE)t_walk_rtree$(EXEEXT) $(OUTPRE)t_walk_rtree.$(OBJEXT) \
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index e6ae2a712..2545be396 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -60,19 +60,20 @@
#include "../krb5_libinit.h"
#endif
+/* This must be the largest enctype value defined in krb5.h. */
+#define MAX_ENCTYPE ENCTYPE_ARCFOUR_HMAC_EXP
+
/* The des-mdX entries are last for now, because it's easy to
configure KDCs to issue TGTs with des-mdX keys and then not accept
them. This'll be fixed, but for better compatibility, let's prefer
des-crc for now. */
-#define DEFAULT_ETYPE_LIST \
- "aes256-cts-hmac-sha1-96 " \
- "aes128-cts-hmac-sha1-96 " \
- "des3-cbc-sha1 arcfour-hmac-md5 " \
- "des-cbc-crc des-cbc-md5 des-cbc-md4 "
-
-/* Not included:
- "aes128-cts-hmac-sha1-96 " \
- */
+static krb5_enctype default_enctype_list[] = {
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_DES3_CBC_SHA1,
+ ENCTYPE_ARCFOUR_HMAC,
+ ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
+ 0
+};
#if (defined(_WIN32))
extern krb5_error_code krb5_vercheck();
@@ -344,92 +345,137 @@ krb5_set_default_tgs_ktypes(krb5_context context, const krb5_enctype *etypes)
return set_default_etype_var(context, etypes, &context->tgs_etypes);
}
+/*
+ * Add etype to, or remove etype from, list (of size MAX_ENCTYPE + 1)
+ * which has *count entries. Filter out weak enctypes if allow_weak
+ * is false.
+ */
+static void
+mod_list(krb5_enctype etype, krb5_boolean add, krb5_boolean allow_weak,
+ krb5_enctype *list, unsigned int *count)
+{
+ unsigned int i;
+
+ assert(etype > 0 && etype <= MAX_ENCTYPE);
+ if (!allow_weak && krb5_c_weak_enctype(etype))
+ return;
+ for (i = 0; i < *count; i++) {
+ if (list[i] == etype) {
+ if (!add) {
+ for (; i < *count - 1; i++)
+ list[i] = list[i + 1];
+ (*count)--;
+ }
+ return;
+ }
+ }
+ if (add) {
+ assert(*count < MAX_ENCTYPE);
+ list[(*count)++] = etype;
+ }
+}
+
+/*
+ * Set *result to a zero-terminated list of enctypes resulting from
+ * parsing profstr. profstr may be modified during parsing.
+ */
+krb5_error_code
+krb5int_parse_enctype_list(krb5_context context, char *profstr,
+ krb5_enctype *default_list, krb5_enctype **result)
+{
+ char *token, *delim = " \t\r\n,", *save = NULL;
+ krb5_boolean sel, weak = context->allow_weak_crypto;
+ krb5_enctype etype, list[MAX_ENCTYPE];
+ unsigned int i, count = 0;
+
+ *result = NULL;
+
+ /* Walk through the words in profstr. */
+ for (token = strtok_r(profstr, delim, &save); token;
+ token = strtok_r(NULL, delim, &save)) {
+ /* Determine if we are adding or removing enctypes. */
+ sel = TRUE;
+ if (*token == '+' || *token == '-')
+ sel = (*token++ == '+');
+
+ if (strcasecmp(token, "DEFAULT") == 0) {
+ /* Set all enctypes in the default list. */
+ for (i = 0; default_list[i]; i++)
+ mod_list(default_list[i], sel, weak, list, &count);
+ } else if (strcasecmp(token, "des") == 0) {
+ mod_list(ENCTYPE_DES_CBC_CRC, sel, weak, list, &count);
+ mod_list(ENCTYPE_DES_CBC_MD5, sel, weak, list, &count);
+ mod_list(ENCTYPE_DES_CBC_MD4, sel, weak, list, &count);
+ } else if (strcasecmp(token, "des3") == 0) {
+ mod_list(ENCTYPE_DES3_CBC_SHA1, sel, weak, list, &count);
+ } else if (strcasecmp(token, "aes") == 0) {
+ mod_list(ENCTYPE_AES256_CTS_HMAC_SHA1_96, sel, weak, list, &count);
+ mod_list(ENCTYPE_AES128_CTS_HMAC_SHA1_96, sel, weak, list, &count);
+ } else if (strcasecmp(token, "rc4") == 0) {
+ mod_list(ENCTYPE_ARCFOUR_HMAC, sel, weak, list, &count);
+ } else if (krb5_string_to_enctype(token, &etype) == 0) {
+ /* Set a specific enctype. */
+ mod_list(etype, sel, weak, list, &count);
+ }
+ }
+
+ list[count] = 0;
+ return copy_enctypes(context, list, result);
+}
+
+/*
+ * Set *etypes_ptr to a zero-terminated list of enctypes. ctx_list
+ * (containing application-specified enctypes) is used if non-NULL;
+ * otherwise the libdefaults profile string specified by profkey is
+ * used. default_list is the default enctype list to be used while
+ * parsing profile strings, and is also used if the profile string is
+ * not set.
+ */
static krb5_error_code
-get_profile_etype_list(krb5_context context, krb5_enctype **ktypes,
- char *profstr, krb5_enctype *ctx_list)
+get_profile_etype_list(krb5_context context, krb5_enctype **etypes_ptr,
+ char *profkey, krb5_enctype *ctx_list,
+ krb5_enctype *default_list)
{
- krb5_enctype *old_ktypes;
- krb5_enctype ktype;
+ krb5_enctype *etypes;
krb5_error_code code;
+ char *profstr;
+
+ *etypes_ptr = NULL;
if (ctx_list) {
- code = copy_enctypes(context, ctx_list, &old_ktypes);
+ /* Use application defaults. */
+ code = copy_enctypes(context, ctx_list, &etypes);
if (code)
return code;
} else {
- /*
- XXX - For now, we only support libdefaults
- Perhaps this should be extended to allow for per-host / per-realm
- session key types.
- */
-
- char *retval = NULL;
- char *sp = NULL, *ep = NULL;
- int i, j, count;
-
- code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, profstr,
- NULL, DEFAULT_ETYPE_LIST, &retval);
+ /* Parse profile setting, or "DEFAULT" if not specified. */
+ code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+ profkey, NULL, "DEFAULT", &profstr);
+ if (code)
+ return code;
+ code = krb5int_parse_enctype_list(context, profstr, default_list,
+ &etypes);
+ profile_release_string(profstr);
if (code)
return code;
-
- count = 0;
- sp = retval;
- while (*sp) {
- for (ep = sp; *ep && (*ep != ',') && !isspace((int) (*ep)); ep++)
- ;
- if (*ep) {
- *ep++ = '\0';
- while (isspace((int) (*ep)) || *ep == ',')
- *ep++ = '\0';
- }
- count++;
- sp = ep;
- }
-
- if ((old_ktypes =
- (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
- (krb5_enctype *) NULL) {
- profile_release_string(retval);
- return ENOMEM;
- }
-
- sp = retval;
- j = 0;
- i = 1;
- while (1) {
- if (!krb5_string_to_enctype(sp, &ktype) &&
- (context->allow_weak_crypto || !krb5_c_weak_enctype(ktype))) {
- old_ktypes[j] = ktype;
- j++;
- }
- if (i++ >= count)
- break;
-
- /* skip to next token */
- while (*sp) sp++;
- while (! *sp) sp++;
- }
-
- old_ktypes[j] = (krb5_enctype) 0;
- profile_release_string(retval);
}
- if (old_ktypes[0] == 0) {
- free (old_ktypes);
- *ktypes = 0;
+ if (etypes[0] == 0) {
+ free(etypes);
return KRB5_CONFIG_ETYPE_NOSUPP;
}
- *ktypes = old_ktypes;
+ *etypes_ptr = etypes;
return 0;
}
krb5_error_code
krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes)
{
- return(get_profile_etype_list(context, ktypes,
+ return get_profile_etype_list(context, ktypes,
KRB5_CONF_DEFAULT_TKT_ENCTYPES,
- context->in_tkt_etypes));
+ context->in_tkt_etypes,
+ default_enctype_list);
}
void
@@ -447,11 +493,13 @@ krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, krb5_encty
/* This one is set *only* by reading the config file; it's not
set by the application. */
return get_profile_etype_list(context, ktypes,
- KRB5_CONF_DEFAULT_TKT_ENCTYPES, NULL);
+ KRB5_CONF_DEFAULT_TKT_ENCTYPES, NULL,
+ default_enctype_list);
else
return get_profile_etype_list(context, ktypes,
KRB5_CONF_DEFAULT_TGS_ENCTYPES,
- context->tgs_etypes);
+ context->tgs_etypes,
+ default_enctype_list);
}
krb5_error_code KRB5_CALLCONV
@@ -459,7 +507,7 @@ krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes)
{
return get_profile_etype_list(context, ktypes,
KRB5_CONF_PERMITTED_ENCTYPES,
- context->tgs_etypes);
+ context->tgs_etypes, default_enctype_list);
}
krb5_boolean
diff --git a/src/lib/krb5/krb/t_etypes.c b/src/lib/krb5/krb/t_etypes.c
new file mode 100644
index 000000000..648a7eeb1
--- /dev/null
+++ b/src/lib/krb5/krb/t_etypes.c
@@ -0,0 +1,201 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * t_etypes.c -- test program for krb5int_parse_enctype_list
+ *
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "k5-int.h"
+#include <stdio.h>
+#include "com_err.h"
+
+static struct {
+ const char *str;
+ krb5_enctype defaults[64];
+ krb5_enctype expected_noweak[64];
+ krb5_enctype expected[64];
+} tests[] = {
+ /* Empty string, unused default list */
+ { "",
+ { ENCTYPE_DES_CBC_CRC, 0 },
+ { 0 },
+ { 0 }
+ },
+ /* Single weak enctype */
+ { "des-cbc-md4",
+ { 0 },
+ { 0 },
+ { ENCTYPE_DES_CBC_MD4, 0 }
+ },
+ /* Single non-weak enctype */
+ { "aes128-cts-hmac-sha1-96",
+ { 0 },
+ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 },
+ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 }
+ },
+ /* Two enctypes, one an alias, one weak */
+ { "rc4-hmac des-cbc-md5",
+ { 0 },
+ { ENCTYPE_ARCFOUR_HMAC, 0 },
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_DES_CBC_MD5, 0 }
+ },
+ /* Three enctypes, all weak, case variation, funky separators */
+ { " deS-HMac-shA1 , arCFour-hmaC-mD5-exp\tdeS3-Cbc-RAw\n",
+ { 0 },
+ { 0 },
+ { ENCTYPE_DES_HMAC_SHA1, ENCTYPE_ARCFOUR_HMAC_EXP,
+ ENCTYPE_DES3_CBC_RAW, 0 }
+ },
+ /* Default set with enctypes added (one weak in each pair) */
+ { "DEFAULT des-cbc-raw +des3-hmac-sha1",
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC_EXP, 0 },
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_DES3_CBC_SHA1, 0 },
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC_EXP,
+ ENCTYPE_DES_CBC_RAW, ENCTYPE_DES3_CBC_SHA1, 0 }
+ },
+ /* Default set with enctypes removed */
+ { "default -aes128-cts -des-hmac-sha1",
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_HMAC_SHA1, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_DES_CBC_MD5, 0 }
+ },
+ /* Family followed by enctype */
+ { "aes des3-cbc-sha1-kd",
+ { 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_DES3_CBC_SHA1, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_DES3_CBC_SHA1, 0 }
+ },
+ /* Enctype followed by two families */
+ { "+rc4-hmAC des3 +des",
+ { 0 },
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_DES3_CBC_SHA1, 0 },
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4 }
+ },
+ /* Default set with family added and enctype removed */
+ { "DEFAULT +aes -arcfour-hmac-md5",
+ { ENCTYPE_ARCFOUR_HMAC, ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES_CBC_CRC, 0 },
+ { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 },
+ { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 }
+ },
+ /* Default set with families removed and enctypes added (one redundant) */
+ { "DEFAULT -des -des3 rc4-hmac rc4-hmac-exp",
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_DES3_CBC_SHA1, ENCTYPE_ARCFOUR_HMAC,
+ ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_ARCFOUR_HMAC, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_ARCFOUR_HMAC, ENCTYPE_ARCFOUR_HMAC_EXP, 0 }
+ },
+ /* Default set with family moved to front */
+ { "des3 +DEFAULT",
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ ENCTYPE_DES3_CBC_SHA1, 0 },
+ { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 },
+ { ENCTYPE_DES3_CBC_SHA1, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96, 0 }
+ },
+ /* Two families with default set removed (exotic case), enctype added */
+ { "aes +rc4 -DEFaulT des3-hmac-sha1",
+ { ENCTYPE_AES128_CTS_HMAC_SHA1_96, ENCTYPE_DES3_CBC_SHA1,
+ ENCTYPE_ARCFOUR_HMAC, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_DES3_CBC_SHA1, 0 },
+ { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_DES3_CBC_SHA1, 0 }
+ }
+};
+
+static void show_enctypes(krb5_context ctx, krb5_enctype *list)
+{
+ unsigned int i;
+
+ for (i = 0; list[i]; i++) {
+ fprintf(stderr, "%d", (int) list[i]);
+ if (list[i + 1])
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "\n");
+}
+
+static void compare(krb5_context ctx, krb5_enctype *result,
+ krb5_enctype *expected, const char *profstr,
+ krb5_boolean weak)
+{
+ unsigned int i;
+
+ for (i = 0; result[i]; i++) {
+ if (result[i] != expected[i])
+ break;
+ }
+ if (!result[i] && !expected[i]) /* Success! */
+ return;
+ fprintf(stderr, "Unexpected result while parsing: %s\n", profstr);
+ fprintf(stderr, "Expected: ");
+ show_enctypes(ctx, expected);
+ fprintf(stderr, "Result: ");
+ show_enctypes(ctx, result);
+ fprintf(stderr, "allow_weak_crypto was %s\n", weak ? "true" : "false");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context ctx;
+ krb5_error_code ret;
+ krb5_enctype *list;
+ krb5_boolean weak;
+ unsigned int i;
+ char *copy;
+
+ ret = krb5_init_context(&ctx);
+ if (ret) {
+ com_err("krb5_init_context", ret, "");
+ return 2;
+ }
+ for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
+ for (weak = FALSE; weak <= TRUE; weak++) {
+ ctx->allow_weak_crypto = weak;
+ copy = strdup(tests[i].str);
+ ret = krb5int_parse_enctype_list(ctx, copy, tests[i].defaults,
+ &list);
+ if (ret) {
+ com_err("krb5int_parse_enctype_list", ret, "");
+ return 2;
+ }
+ compare(ctx, list,
+ (weak) ? tests[i].expected : tests[i].expected_noweak,
+ tests[i].str, weak);
+ free(copy);
+ free(list);
+ }
+ }
+ return 0;
+}
+