summaryrefslogtreecommitdiffstats
path: root/src/kdc
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2009-04-03 04:03:45 +0000
committerSam Hartman <hartmans@mit.edu>2009-04-03 04:03:45 +0000
commit4e609bf313a80dbc2247a73d1303b2068eec9acd (patch)
tree9ac56fbff02569ca272eff8d98227b3efbe92f39 /src/kdc
parent6d48a7deaeed3dcb5dce55d8e9730c47512a904e (diff)
downloadkrb5-4e609bf313a80dbc2247a73d1303b2068eec9acd.tar.gz
krb5-4e609bf313a80dbc2247a73d1303b2068eec9acd.tar.xz
krb5-4e609bf313a80dbc2247a73d1303b2068eec9acd.zip
Merge fast branch at 22166 onto trunk
ticket: 6436 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22167 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kdc')
-rw-r--r--src/kdc/do_as_req.c17
-rw-r--r--src/kdc/do_tgs_req.c8
-rw-r--r--src/kdc/fast_util.c87
-rw-r--r--src/kdc/kdc_preauth.c16
-rw-r--r--src/kdc/kdc_util.c4
-rw-r--r--src/kdc/kdc_util.h14
6 files changed, 123 insertions, 23 deletions
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 7b590f4e0..4f1715d67 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -119,6 +119,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
krb5_keylist_node *tmp_mkey_list;
struct kdc_request_state *state = NULL;
krb5_data encoded_req_body;
+ krb5_keyblock *as_encrypting_key = NULL;
#if APPLE_PKINIT
@@ -592,7 +593,7 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
goto errout;
}
ticket_reply.enc_part.kvno = server_key->key_data_kvno;
- errcode = kdc_fast_response_handle_padata(state, request, &reply);
+ errcode = kdc_fast_response_handle_padata(state, request, &reply, client_keyblock.enctype);
if (errcode) {
status = "fast response handling";
goto errout;
@@ -602,8 +603,13 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
reply.enc_part.enctype = client_keyblock.enctype;
- errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart,
- 0, &client_keyblock, &reply, response);
+ errcode = kdc_fast_handle_reply_key(state, &client_keyblock, &as_encrypting_key);
+ if (errcode) {
+ status = "generating reply key";
+ goto errout;
+ }
+ errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart,
+ 0, as_encrypting_key, &reply, response);
reply.enc_part.kvno = client_key->key_data_kvno;
if (errcode) {
status = "ENCODE_KDC_REP";
@@ -637,7 +643,8 @@ errout:
egress:
if (pa_context)
free_padata_context(kdc_context, &pa_context);
-
+ if (as_encrypting_key)
+ krb5_free_keyblock(kdc_context, as_encrypting_key);
if (errcode)
emsg = krb5_get_error_message(kdc_context, errcode);
@@ -760,7 +767,7 @@ prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request, int e
if (pa == NULL)
retval = ENOMEM;
else for (size = 0; td[size]; size++) {
- krb5_pa_data *pad = malloc(sizeof(krb5_pa_data *));
+ krb5_pa_data *pad = malloc(sizeof(krb5_pa_data ));
if (pad == NULL) {
retval = ENOMEM;
break;
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index e06d94dfc..598c87971 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -878,7 +878,8 @@ tgt_again:
reply.enc_part.enctype = subkey ? subkey->enctype :
header_ticket->enc_part2->session->enctype;
- errcode = kdc_fast_response_handle_padata(state, request, &reply);
+ errcode = kdc_fast_response_handle_padata(state, request, &reply,
+ subkey?subkey->enctype:header_ticket->enc_part2->session->enctype);
if (errcode !=0 ) {
status = "Preparing FAST padata";
goto cleanup;
@@ -972,7 +973,7 @@ prepare_error_tgs (struct kdc_request_state *state,
krb5_data **response, const char *status)
{
krb5_error errpkt;
- krb5_error_code retval;
+ krb5_error_code retval = 0;
krb5_data *scratch;
errpkt.ctime = request->nonce;
@@ -997,7 +998,8 @@ prepare_error_tgs (struct kdc_request_state *state,
}
errpkt.e_data.length = 0;
errpkt.e_data.data = NULL;
- retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
+ if (state)
+ retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt);
if (retval) {
free(scratch);
free(errpkt.text.data);
diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c
index 10d1d3eb6..ac6aa22c4 100644
--- a/src/kdc/fast_util.c
+++ b/src/kdc/fast_util.c
@@ -50,7 +50,7 @@ static krb5_error_code armor_ap_request
krb5_ticket *ticket = NULL;
krb5_keyblock *subkey = NULL;
- assert(armor->armor_type = KRB5_FAST_ARMOR_AP_REQUEST);
+ assert(armor->armor_type == KRB5_FAST_ARMOR_AP_REQUEST);
krb5_clear_error_message(kdc_context);
retval = krb5_auth_con_init(kdc_context, &authcontext);
if (retval == 0)
@@ -251,8 +251,8 @@ void kdc_free_rstate
return;
if (s->armor_key)
krb5_free_keyblock(kdc_context, s->armor_key);
- if (s->reply_key)
- krb5_free_keyblock(kdc_context, s->reply_key);
+ if (s->strengthen_key)
+ krb5_free_keyblock(kdc_context, s->strengthen_key);
if (s->cookie) {
free(s->cookie->contents);
free(s->cookie);
@@ -263,24 +263,33 @@ void kdc_free_rstate
krb5_error_code kdc_fast_response_handle_padata
(struct kdc_request_state *state,
krb5_kdc_req *request,
- krb5_kdc_rep *rep)
+ krb5_kdc_rep *rep, krb5_enctype enctype)
{
krb5_error_code retval = 0;
krb5_fast_finished finish;
krb5_fast_response fast_response;
krb5_data *encoded_ticket = NULL;
krb5_data *encrypted_reply = NULL;
- krb5_pa_data *pa = NULL, **pa_array;
+ krb5_pa_data *pa = NULL, **pa_array = NULL;
krb5_cksumtype cksumtype = CKSUMTYPE_RSA_MD5;
krb5_pa_data *empty_padata[] = {NULL};
+ krb5_keyblock *strengthen_key = NULL;
if (!state->armor_key)
return 0;
memset(&finish, 0, sizeof(finish));
+ retval = krb5_init_keyblock(kdc_context, enctype, 0, &strengthen_key);
+ if (retval == 0)
+ retval = krb5_c_make_random_key(kdc_context, enctype, strengthen_key);
+ if (retval == 0) {
+ state->strengthen_key = strengthen_key;
+ strengthen_key = NULL;
+ }
+
fast_response.padata = rep->padata;
if (fast_response.padata == NULL)
fast_response.padata = &empty_padata[0];
- fast_response.rep_key = state->reply_key;
+ fast_response.strengthen_key = state->strengthen_key;
fast_response.nonce = request->nonce;
fast_response.finished = &finish;
finish.client = rep->client;
@@ -309,15 +318,20 @@ krb5_error_code kdc_fast_response_handle_padata
pa_array[0] = &pa[0];
rep->padata = pa_array;
pa_array = NULL;
+ free(encrypted_reply);
encrypted_reply = NULL;
pa = NULL;
}
if (pa)
free(pa);
+ if (pa_array)
+ free(pa_array);
if (encrypted_reply)
krb5_free_data(kdc_context, encrypted_reply);
if (encoded_ticket)
krb5_free_data(kdc_context, encoded_ticket);
+ if (strengthen_key != NULL)
+ krb5_free_keyblock(kdc_context, strengthen_key);
if (finish.ticket_checksum.contents)
krb5_free_checksum_contents(kdc_context, &finish.ticket_checksum);
return retval;
@@ -339,8 +353,8 @@ krb5_error_code kdc_fast_handle_error
krb5_fast_response resp;
krb5_error fx_error;
krb5_data *encoded_fx_error = NULL, *encrypted_reply = NULL;
- krb5_pa_data pa[2];
- krb5_pa_data *outer_pa[3];
+ krb5_pa_data pa[1];
+ krb5_pa_data *outer_pa[3], *cookie = NULL;
krb5_pa_data **inner_pa = NULL;
size_t size = 0;
krb5_data *encoded_e_data = NULL;
@@ -366,15 +380,26 @@ krb5_error_code kdc_fast_handle_error
pa[0].length = encoded_fx_error->length;
pa[0].contents = (unsigned char *) encoded_fx_error->data;
inner_pa[size++] = &pa[0];
- resp.padata = inner_pa;
+ if (find_pa_data(inner_pa, KRB5_PADATA_FX_COOKIE) == NULL)
+ retval = kdc_preauth_get_cookie(state, &cookie);
+ }
+ if (cookie != NULL)
+ inner_pa[size++] = cookie;
+ if (retval == 0) {
+ resp.padata = inner_pa;
resp.nonce = request->nonce;
- resp.rep_key = NULL;
+ resp.strengthen_key = NULL;
resp.finished = NULL;
}
if (retval == 0)
retval = encrypt_fast_reply(state, &resp, &encrypted_reply);
if (inner_pa)
free(inner_pa); /*contained storage from caller and our stack*/
+ if (cookie) {
+ free(cookie->contents);
+ free(cookie);
+ cookie = NULL;
+ }
if (retval == 0) {
pa[0].pa_type = KRB5_PADATA_FX_FAST;
pa[0].length = encrypted_reply->length;
@@ -396,3 +421,45 @@ krb5_error_code kdc_fast_handle_error
krb5_free_data(kdc_context, encoded_fx_error);
return retval;
}
+
+krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
+ krb5_keyblock *existing_key,
+ krb5_keyblock **out_key)
+{
+ krb5_error_code retval = 0;
+ if (state->armor_key)
+ retval = krb5_c_fx_cf2_simple(kdc_context,
+ state->strengthen_key, "strengthenkey",
+ existing_key,
+ "replykey", out_key);
+ else retval = krb5_copy_keyblock(kdc_context, existing_key, out_key);
+ return retval;
+}
+
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+ krb5_pa_data **cookie)
+{
+ char *contents;
+ krb5_pa_data *pa = NULL;
+ /* In our current implementation, the only purpose served by
+ * returning a cookie is to indicate that a conversation should
+ * continue on error. Thus, the cookie can have a constant
+ * string. If cookies are used for real, versioning so that KDCs
+ * can be upgraded, keying, expiration and many other issues need
+ * to be considered.
+ */
+ contents = strdup("MIT");
+ if (contents == NULL)
+ return ENOMEM;
+ pa = calloc(1, sizeof(krb5_pa_data));
+ if (pa == NULL) {
+ free(contents);
+ return ENOMEM;
+ }
+ pa->pa_type = KRB5_PADATA_FX_COOKIE;
+ pa->length = strlen(contents);
+ pa->contents = (unsigned char *) contents;
+ *cookie = pa;
+ return 0;
+}
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index cf269753d..3dda38150 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -290,6 +290,17 @@ static krb5_preauth_systems static_preauth_systems[] = {
0
},
{
+ "FAST",
+ KRB5_PADATA_FX_FAST,
+ PA_HARDWARE,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0
+ },
+ {
"etype-info",
KRB5_PADATA_ETYPE_INFO,
0,
@@ -961,7 +972,8 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
e_data->data = 0;
hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
- pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+1));
+ /* Allocate 1 entry for the terminator and one for the cookie*/
+ pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+21));
if (pa_data == 0)
return;
memset(pa_data, 0, sizeof(krb5_pa_data *) * (n_preauth_systems+1));
@@ -995,6 +1007,8 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
"%spreauth required but hint list is empty",
hw_only ? "hw" : "");
}
+/* If we fail to get the cookie it is probably still reasonable to continue with the response*/
+ kdc_preauth_get_cookie(request->kdc_state, pa);
retval = encode_krb5_padata_sequence(pa_data, &edat);
if (retval)
goto errout;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 08d84db68..8e531f03b 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -347,13 +347,13 @@ kdc_process_tgs_req(krb5_kdc_req *request, const krb5_fulladdr *from,
authenticator->authorization_data,
KRB5_AUTHDATA_FX_ARMOR, &authdata);
if (retval != 0)
- goto cleanup_auth_context;
+ goto cleanup_authenticator;
if (authdata&& authdata[0]) {
krb5_set_error_message(kdc_context, KRB5KDC_ERR_POLICY,
"ticket valid only as FAST armor");
retval = KRB5KDC_ERR_POLICY;
krb5_free_authdata(kdc_context, authdata);
- goto cleanup_auth_context;
+ goto cleanup_authenticator;
}
krb5_free_authdata(kdc_context, authdata);
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 90de8d39b..060442604 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -302,11 +302,12 @@ void log_tgs_alt_tgt(krb5_principal p);
struct kdc_request_state {
krb5_keyblock *armor_key;
- krb5_keyblock *reply_key; /*When replaced by FAST*/
+ krb5_keyblock *strengthen_key;
krb5_pa_data *cookie;
krb5_int32 fast_options;
krb5_int32 fast_internal_flags;
};
+
krb5_error_code kdc_make_rstate(struct kdc_request_state **out);
void kdc_free_rstate
(struct kdc_request_state *s);
@@ -325,12 +326,21 @@ krb5_error_code kdc_find_fast
krb5_error_code kdc_fast_response_handle_padata
(struct kdc_request_state *state,
krb5_kdc_req *request,
- krb5_kdc_rep *rep);
+ krb5_kdc_rep *rep,
+ krb5_enctype enctype);
krb5_error_code kdc_fast_handle_error
(krb5_context context, struct kdc_request_state *state,
krb5_kdc_req *request,
krb5_pa_data **in_padata, krb5_error *err);
+krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
+ krb5_keyblock *existing_key,
+ krb5_keyblock **out_key);
+
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+ krb5_pa_data **cookie);
+