diff options
| author | Sam Hartman <hartmans@mit.edu> | 2009-04-03 04:03:45 +0000 |
|---|---|---|
| committer | Sam Hartman <hartmans@mit.edu> | 2009-04-03 04:03:45 +0000 |
| commit | 4e609bf313a80dbc2247a73d1303b2068eec9acd (patch) | |
| tree | 9ac56fbff02569ca272eff8d98227b3efbe92f39 /src/kdc | |
| parent | 6d48a7deaeed3dcb5dce55d8e9730c47512a904e (diff) | |
| download | krb5-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.c | 17 | ||||
| -rw-r--r-- | src/kdc/do_tgs_req.c | 8 | ||||
| -rw-r--r-- | src/kdc/fast_util.c | 87 | ||||
| -rw-r--r-- | src/kdc/kdc_preauth.c | 16 | ||||
| -rw-r--r-- | src/kdc/kdc_util.c | 4 | ||||
| -rw-r--r-- | src/kdc/kdc_util.h | 14 |
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); + |
