summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/crypto/arcfour/arcfour.c11
-rw-r--r--src/lib/crypto/arcfour/arcfour.h5
-rw-r--r--src/lib/crypto/etypes.c8
-rw-r--r--src/lib/krb5/asn.1/asn1_k_encode.c6
-rw-r--r--src/lib/krb5/asn.1/krb5_decode.c6
-rw-r--r--src/lib/krb5/krb/Makefile.in4
-rw-r--r--src/lib/krb5/krb/fast.c42
-rw-r--r--src/lib/krb5/krb/fast.h9
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c39
-rw-r--r--src/lib/krb5/krb/kfree.c1
-rw-r--r--src/lib/krb5/krb/preauth2.c35
-rw-r--r--src/lib/krb5/krb/t_ad_fx_armor.c36
12 files changed, 162 insertions, 40 deletions
diff --git a/src/lib/crypto/arcfour/arcfour.c b/src/lib/crypto/arcfour/arcfour.c
index ea3129688a..8d35d7eefc 100644
--- a/src/lib/crypto/arcfour/arcfour.c
+++ b/src/lib/crypto/arcfour/arcfour.c
@@ -8,6 +8,8 @@ of RSA Data Security)
*/
#include "k5-int.h"
#include "arcfour-int.h"
+#include "../hash_provider/hash_provider.h"
+
const char *const krb5int_arcfour_l40 = "fortybits";
void
@@ -304,3 +306,12 @@ krb5_arcfour_decrypt(const struct krb5_enc_provider *enc,
return (ret);
}
+ krb5_error_code krb5int_arcfour_prf(
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ const krb5_data *in, krb5_data *out)
+ {
+ assert(out->length == 20);
+ return krb5_hmac(&krb5int_hash_sha1, key, 1, in, out);
+ }
diff --git a/src/lib/crypto/arcfour/arcfour.h b/src/lib/crypto/arcfour/arcfour.h
index e8ff203ca1..be408febc6 100644
--- a/src/lib/crypto/arcfour/arcfour.h
+++ b/src/lib/crypto/arcfour/arcfour.h
@@ -34,5 +34,10 @@ extern krb5_error_code krb5int_arcfour_string_to_key(
extern const struct krb5_enc_provider krb5int_enc_arcfour;
extern const struct krb5_aead_provider krb5int_aead_arcfour;
+ krb5_error_code krb5int_arcfour_prf(
+ const struct krb5_enc_provider *enc,
+ const struct krb5_hash_provider *hash,
+ const krb5_keyblock *key,
+ const krb5_data *in, krb5_data *out);
#endif /* ARCFOUR_H */
diff --git a/src/lib/crypto/etypes.c b/src/lib/crypto/etypes.c
index e7f547b91a..debf585fa7 100644
--- a/src/lib/crypto/etypes.c
+++ b/src/lib/crypto/etypes.c
@@ -119,10 +119,10 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
"ArcFour with HMAC/md5",
&krb5int_enc_arcfour,
&krb5int_hash_md5,
- 0,
+ 20,
krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
- NULL, /*PRF*/
+ krb5int_arcfour_prf, /*PRF*/
CKSUMTYPE_HMAC_MD5_ARCFOUR,
&krb5int_aead_arcfour,
0 /*flags*/ },
@@ -131,10 +131,10 @@ const struct krb5_keytypes krb5_enctypes_list[] = {
"Exportable ArcFour with HMAC/md5",
&krb5int_enc_arcfour,
&krb5int_hash_md5,
- 0,
+ 20,
krb5_arcfour_encrypt_length, krb5_arcfour_encrypt,
krb5_arcfour_decrypt, krb5int_arcfour_string_to_key,
- NULL, /*PRF*/
+ krb5int_arcfour_prf, /*PRF*/
CKSUMTYPE_HMAC_MD5_ARCFOUR,
&krb5int_aead_arcfour,
ETYPE_WEAK
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index efa75643d5..ed01b7560d 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -1211,7 +1211,7 @@ DEFFIELDTYPE(fast_req_padata, krb5_kdc_req,
DEFPTRTYPE(ptr_fast_req_padata, fast_req_padata);
static const struct field_info fast_req_fields[] = {
- FIELDOF_NORM(krb5_fast_req, int32, fast_options, 0),
+ FIELDOF_NORM(krb5_fast_req, krb5_flags, fast_options, 0),
FIELDOF_NORM( krb5_fast_req, ptr_fast_req_padata, req_body, 1),
FIELDOF_NORM( krb5_fast_req, ptr_kdc_req_body, req_body, 2),
};
@@ -1233,7 +1233,7 @@ DEFPTRTYPE( ptr_fast_finished, fast_finished);
static const struct field_info fast_response_fields[] = {
FIELDOF_NORM(krb5_fast_response, ptr_seqof_pa_data, padata, 0),
- FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, rep_key, 1, 1),
+ FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, strengthen_key, 1, 1),
FIELDOF_OPT( krb5_fast_response, ptr_fast_finished, finished, 2, 2),
FIELDOF_NORM(krb5_fast_response, int32, nonce, 3),
};
@@ -1242,7 +1242,7 @@ static unsigned int fast_response_optional (const void *p)
{
unsigned int optional = 0;
const krb5_fast_response *val = p;
- if (val->rep_key)
+ if (val->strengthen_key)
optional |= (1u <<1);
if (val->finished)
optional |= (1u<<2);
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c
index 9080d97ec7..7a08ec8884 100644
--- a/src/lib/krb5/asn.1/krb5_decode.c
+++ b/src/lib/krb5/asn.1/krb5_decode.c
@@ -1114,7 +1114,7 @@ krb5_error_code decode_krb5_fast_req
alloc_field(rep->req_body);
clear_field(rep, req_body->padata);
{begin_structure();
- get_field(rep->fast_options, 0, asn1_decode_int32);
+ get_field(rep->fast_options, 0, asn1_decode_krb5_flags);
opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data);
get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body);
end_structure(); }
@@ -1137,10 +1137,10 @@ krb5_error_code decode_krb5_fast_response
alloc_field(rep);
clear_field(rep, finished);
clear_field(rep, padata);
- clear_field(rep,rep_key);
+ clear_field(rep,strengthen_key);
{begin_structure();
get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data);
- opt_field(rep->rep_key, 1, asn1_decode_encryption_key_ptr);
+ opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr);
opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr);
get_field(rep->nonce, 3, asn1_decode_int32);
end_structure(); }
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index acc18f6f46..c5256b3137 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -271,6 +271,7 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/srv_dec_tkt.c \
$(srcdir)/srv_rcache.c \
$(srcdir)/str_conv.c \
+ $(srcdir)/t_ad_fx_armor.c \
$(srcdir)/tgtname.c \
$(srcdir)/unparse.c \
$(srcdir)/valid_times.c \
@@ -317,6 +318,9 @@ T_PRINC_OBJS= t_princ.o parse.o unparse.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
+ $(CC_LINK) -o $@ $< $(KRB5_BASE_LIBS)
+
t_authdata: t_authdata.o copy_auth.o
$(CC_LINK) -o $@ $< copy_auth.o $(KRB5_BASE_LIBS)
diff --git a/src/lib/krb5/krb/fast.c b/src/lib/krb5/krb/fast.c
index e9f54be788..ef57e6d832 100644
--- a/src/lib/krb5/krb/fast.c
+++ b/src/lib/krb5/krb/fast.c
@@ -299,6 +299,8 @@ static krb5_error_code decrypt_fast_reply
free(scratch.data);
if (encrypted_response)
krb5_free_enc_data(context, encrypted_response);
+ if (local_resp)
+ krb5_free_fast_response(context, local_resp);
return retval;
}
@@ -376,9 +378,11 @@ krb5int_fast_process_error(krb5_context context, struct krb5int_fast_request_sta
fast_response->padata = NULL;
/*
* If there is more than the fx_error padata, then we want
- * to retry the error
+ * to retry the error if a cookie is present
*/
*retry = (*out_padata)[1] != NULL;
+ if (krb5int_find_pa_data(context, *out_padata, KRB5_PADATA_FX_COOKIE) == NULL)
+ *retry = 0;
}
if (fx_error)
krb5_free_error(context, fx_error);
@@ -408,14 +412,14 @@ krb5int_fast_process_error(krb5_context context, struct krb5int_fast_request_sta
krb5_error_code krb5int_fast_process_response
(krb5_context context, struct krb5int_fast_request_state *state,
krb5_kdc_rep *resp,
- krb5_keyblock **as_key)
+ krb5_keyblock **strengthen_key)
{
krb5_error_code retval = 0;
krb5_fast_response *fast_response = NULL;
krb5_data *encoded_ticket = NULL;
krb5_boolean cksum_valid;
krb5_clear_error_message(context);
- *as_key = NULL;
+ *strengthen_key = NULL;
if (state->armor_key == 0)
return 0;
retval = decrypt_fast_reply(context, state, resp->padata,
@@ -442,8 +446,8 @@ krb5_error_code krb5int_fast_process_response
krb5_free_principal(context, resp->client);
resp->client = fast_response->finished->client;
fast_response->finished->client = NULL;
- *as_key = fast_response->rep_key;
- fast_response->rep_key = NULL;
+ *strengthen_key = fast_response->strengthen_key;
+ fast_response->strengthen_key = NULL;
krb5_free_pa_data(context, resp->padata);
resp->padata = fast_response->padata;
fast_response->padata = NULL;
@@ -454,6 +458,29 @@ krb5_error_code krb5int_fast_process_response
krb5_free_data(context, encoded_ticket);
return retval;
}
+
+krb5_error_code krb5int_fast_reply_key(krb5_context context,
+ krb5_keyblock *strengthen_key,
+ krb5_keyblock *existing_key,
+ krb5_keyblock *out_key)
+{
+ krb5_keyblock *key = NULL;
+ krb5_error_code retval = 0;
+ krb5_free_keyblock_contents(context, out_key);
+ if (strengthen_key) {
+ retval = krb5_c_fx_cf2_simple(context, strengthen_key,
+ "strengthenkey", existing_key, "replykey", &key);
+ if (retval == 0) {
+ *out_key = *key;
+ free(key);
+ }
+ } else {
+ retval = krb5_copy_keyblock_contents(context, existing_key, out_key);
+ }
+ return retval;
+}
+
+
krb5_error_code
krb5int_fast_make_state( krb5_context context, struct krb5int_fast_request_state **state)
{
@@ -473,11 +500,6 @@ krb5int_fast_free_state( krb5_context context, struct krb5int_fast_request_state
/*We are responsible for none of the store in the fast_outer_req*/
krb5_free_keyblock(context, state->armor_key);
krb5_free_fast_armor(context, state->armor);
- if (state->cookie) {
- free(state->cookie->contents);
- free(state->cookie);
- state->cookie = NULL;
- }
free(state);
}
diff --git a/src/lib/krb5/krb/fast.h b/src/lib/krb5/krb/fast.h
index e21df6504b..4cc142335e 100644
--- a/src/lib/krb5/krb/fast.h
+++ b/src/lib/krb5/krb/fast.h
@@ -38,7 +38,6 @@ struct krb5int_fast_request_state {
krb5_fast_armor *armor;
krb5_ui_4 fast_state_flags;
krb5_ui_4 fast_options;
- krb5_pa_data *cookie;
krb5_int32 nonce;
};
@@ -61,7 +60,7 @@ krb5int_fast_process_error(krb5_context context, struct krb5int_fast_request_sta
krb5_error_code krb5int_fast_process_response
(krb5_context context, struct krb5int_fast_request_state *state,
krb5_kdc_rep *resp,
- krb5_keyblock **as_key);
+ krb5_keyblock **strengthen_key);
krb5_error_code
krb5int_fast_make_state( krb5_context context, struct krb5int_fast_request_state **state);
@@ -73,5 +72,11 @@ krb5_error_code krb5int_fast_as_armor
krb5_gic_opt_ext *opte,
krb5_kdc_req *request);
+krb5_error_code krb5int_fast_reply_key(krb5_context context,
+ krb5_keyblock *strengthen_key,
+ krb5_keyblock *existing_key,
+ krb5_keyblock *output_key);
+
+
#endif
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 30a38cdae9..2944652ffc 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -967,8 +967,8 @@ krb5_get_init_creds(krb5_context context,
int loopcount;
krb5_data salt;
krb5_data s2kparams;
- krb5_keyblock as_key;
- krb5_keyblock *fast_as_key = NULL;
+ krb5_keyblock as_key, encrypting_key;
+ krb5_keyblock *strengthen_key = NULL;
krb5_error *err_reply;
krb5_kdc_rep *local_as_reply;
krb5_timestamp time_now;
@@ -994,6 +994,8 @@ krb5_get_init_creds(krb5_context context,
preauth_to_use = NULL;
kdc_padata = NULL;
as_key.length = 0;
+ encrypting_key.length = 0;
+ encrypting_key.contents = NULL;
salt.length = 0;
salt.data = NULL;
@@ -1340,8 +1342,6 @@ krb5_get_init_creds(krb5_context context,
out_padata = NULL;
krb5_free_error(context, err_reply);
err_reply = NULL;
- if (ret)
- goto cleanup;
ret = sort_krb5_padata_sequence(context,
&request.server->realm,
preauth_to_use);
@@ -1399,7 +1399,7 @@ krb5_get_init_creds(krb5_context context,
/* process any preauth data in the as_reply */
krb5_clear_preauth_context_use_counts(context);
ret = krb5int_fast_process_response(context, fast_state,
- local_as_reply, &fast_as_key);
+ local_as_reply, &strengthen_key);
if (ret)
goto cleanup;
if ((ret = sort_krb5_padata_sequence(context, &request.server->realm,
@@ -1447,18 +1447,15 @@ krb5_get_init_creds(krb5_context context,
it. If decrypting the as_rep fails, or if there isn't an
as_key at all yet, then use the gak_fct to get one, and try
again. */
- if (fast_as_key) {
- if (as_key.length)
- krb5_free_keyblock_contents(context, &as_key);
- as_key = *fast_as_key;
- free(fast_as_key);
- fast_as_key = NULL;
- }
- if (as_key.length)
- ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
- NULL, &as_key, krb5_kdc_rep_decrypt_proc,
+ if (as_key.length) {
+ ret = krb5int_fast_reply_key(context, strengthen_key, &as_key,
+ &encrypting_key);
+ if (ret)
+ goto cleanup;
+ ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
+ NULL, &encrypting_key, krb5_kdc_rep_decrypt_proc,
NULL);
- else
+ } else
ret = -1;
if (ret) {
@@ -1470,6 +1467,10 @@ krb5_get_init_creds(krb5_context context,
&as_key, gak_data))))
goto cleanup;
+ ret = krb5int_fast_reply_key(context, strengthen_key, &as_key,
+ &encrypting_key);
+ if (ret)
+ goto cleanup;
if ((ret = decrypt_as_reply(context, NULL, local_as_reply, NULL,
NULL, &as_key, krb5_kdc_rep_decrypt_proc,
NULL)))
@@ -1511,8 +1512,10 @@ cleanup:
}
}
krb5_preauth_request_context_fini(context);
- krb5_free_keyblock(context, fast_as_key);
- if (fast_state)
+ krb5_free_keyblock(context, strengthen_key);
+ if (encrypting_key.contents)
+ krb5_free_keyblock_contents(context, &encrypting_key);
+ if (fast_state)
krb5int_fast_free_state(context, fast_state);
if (out_padata)
krb5_free_pa_data(context, out_padata);
diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
index d17d46bc7d..bec9a61bfa 100644
--- a/src/lib/krb5/krb/kfree.c
+++ b/src/lib/krb5/krb/kfree.c
@@ -819,6 +819,7 @@ void krb5_free_fast_response(krb5_context context, krb5_fast_response *val)
return;
krb5_free_pa_data(context, val->padata);
krb5_free_fast_finished(context, val->finished);
+ krb5_free_keyblock(context, val->strengthen_key);
free(val);
}
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 4c7dd5e607..73f4e79b61 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -646,6 +646,36 @@ krb5_error_code pa_salt(krb5_context context,
}
static
+krb5_error_code pa_fx_cookie(krb5_context context,
+ krb5_kdc_req *request,
+ krb5_pa_data *in_padata,
+ krb5_pa_data **out_padata,
+ krb5_data *salt,
+ krb5_data *s2kparams,
+ krb5_enctype *etype,
+ krb5_keyblock *as_key,
+ krb5_prompter_fct prompter,
+ void *prompter_data,
+ krb5_gic_get_as_key_fct gak_fct,
+ void *gak_data)
+{
+ krb5_pa_data *pa = calloc(1, sizeof(krb5_pa_data));
+ krb5_octet *contents;
+ if (pa == NULL)
+ return ENOMEM;
+ contents = malloc(in_padata->length);
+ if (contents == NULL) {
+ free(pa);
+ return ENOMEM;
+ }
+ *pa = *in_padata;
+ pa->contents = contents;
+ memcpy(contents, in_padata->contents, pa->length);
+ *out_padata = pa;
+ return 0;
+}
+
+static
krb5_error_code pa_enc_timestamp(krb5_context context,
krb5_kdc_req *request,
krb5_pa_data *in_padata,
@@ -1710,6 +1740,11 @@ static const pa_types_t pa_types[] = {
PA_REAL,
},
{
+ KRB5_PADATA_FX_COOKIE,
+ pa_fx_cookie,
+ PA_INFO,
+ },
+ {
-1,
NULL,
0,
diff --git a/src/lib/krb5/krb/t_ad_fx_armor.c b/src/lib/krb5/krb/t_ad_fx_armor.c
new file mode 100644
index 0000000000..74d7e5f1ab
--- /dev/null
+++ b/src/lib/krb5/krb/t_ad_fx_armor.c
@@ -0,0 +1,36 @@
+#include <memory.h>
+#include <stdio.h>
+#include <krb5/krb5.h>
+
+#define test(x) do {retval = (x); \
+ if(retval != 0) { \
+ const char *errmsg = krb5_get_error_message(context, retval); \
+ fprintf(stderr, "Error message: %s\n", errmsg); \
+ abort(); } \
+ } while(0);
+
+krb5_authdata ad_fx_armor = {0, KRB5_AUTHDATA_FX_ARMOR, 1, ""};
+krb5_authdata *array[] = {&ad_fx_armor, NULL};
+
+
+int main( int argc, char **argv)
+{
+ krb5_context context;
+ krb5_ccache ccache = NULL;
+ krb5_creds creds, *out_creds = NULL;
+ krb5_error_code retval = 0;
+ test(krb5_init_context(&context));
+ memset(&creds, 0, sizeof(creds));
+ creds.authdata = array;
+ test(krb5_cc_default(context, &ccache));
+ test(krb5_cc_get_principal(context, ccache, &creds.client));
+ test(krb5_parse_name(context, argv[1], &creds.server));
+ test(krb5_get_credentials(context, 0, ccache, &creds, &out_creds));
+ test(krb5_cc_destroy(context, ccache));
+ test(krb5_cc_default(context, &ccache));
+ test(krb5_cc_initialize(context, ccache, out_creds->client));
+ test(krb5_cc_store_cred(context, ccache, out_creds));
+ test(krb5_cc_close(context,ccache));
+ return 0;
+
+}