From 6770c3eadf86f06e1b9c0f4e6e9f19da581508d5 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Wed, 2 Dec 2009 16:16:19 +0000 Subject: Implement KDC side of protected negotiation: * Move return_enc_padata so reply key is available * Include checksum of reply if requested * export encode_krb5_checksum so we can call it from the KDC git-svn-id: svn://anonsvn.mit.edu/krb5/branches/fast-negotiate@23412 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/do_as_req.c | 14 ++++++----- src/kdc/do_tgs_req.c | 33 +++++++++++++++++++------ src/kdc/kdc_preauth.c | 11 ++++----- src/kdc/kdc_util.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ src/kdc/kdc_util.h | 6 ++++- src/lib/krb5/libkrb5.exports | 1 + 6 files changed, 103 insertions(+), 21 deletions(-) diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 6f2a1e1..4951d29 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -557,12 +557,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt, reply.client->realm.data, reply.client->data->data); #endif /* APPLE_PKINIT */ - errcode = return_enc_padata(kdc_context, req_pkt, request, - &server, &reply_encpart); - if (errcode) { - status = "KDC_RETURN_ENC_PADATA"; - goto errout; - } errcode = handle_authdata(kdc_context, @@ -608,6 +602,14 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt, status = "generating reply key"; goto errout; } + errcode = return_enc_padata(kdc_context, req_pkt, request, + as_encrypting_key, + &server, &reply_encpart); + if (errcode) { + status = "KDC_RETURN_ENC_PADATA"; + 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; diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index 4bd24cf..ce0ff39 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -756,14 +756,6 @@ tgt_again: goto cleanup; } - if (is_referral && isflagset(s_flags, KRB5_KDB_FLAG_CANONICALIZE)) { - errcode = return_enc_padata(kdc_context, pkt, request, - &server, &reply_encpart); - if (errcode) { - status = "KDC_RETURN_ENC_PADATA"; - goto cleanup; - } - } /* * Only add the realm of the presented tgt to the transited list if @@ -955,6 +947,31 @@ tgt_again: status = "generating reply key"; goto cleanup; } + if (is_referral && isflagset(s_flags, KRB5_KDB_FLAG_CANONICALIZE)) { + errcode = return_enc_padata(kdc_context, pkt, request, + reply_key, + &server, &reply_encpart); + if (errcode) { + status = "KDC_RETURN_ENC_PADATA"; + goto cleanup; + } else {/*Not refferal*/ + int idx = 0; + reply_encpart.enc_padata = calloc(3, sizeof(krb5_pa_data *)); + if (reply_encpart.enc_padata == NULL) { + errcode = ENOMEM; + status = "Allocating enc_padata"; + goto cleanup; + } + errcode = kdc_handle_protected_negotiation(pkt, request, + reply_key, reply_encpart.enc_padata, &idx); + if (errcode != 0) { + status = "protected negotiation"; + goto cleanup; + } + } + + } + errcode = krb5_encode_kdc_rep(kdc_context, KRB5_TGS_REP, &reply_encpart, subkey ? 1 : 0, reply_key, diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 5266012..83d92b0 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -3066,6 +3066,7 @@ include_pac_p(krb5_context context, krb5_kdc_req *request) krb5_error_code return_enc_padata(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + krb5_keyblock *reply_key, krb5_db_entry *server, krb5_enc_kdc_rep_part *reply_encpart) { @@ -3081,13 +3082,10 @@ return_enc_padata(krb5_context context, if (reply_encpart->enc_padata == NULL) { return ENOMEM; } - - tl_data.tl_data_type = KRB5_TL_SVR_REFERRAL_DATA; - code = krb5_dbe_lookup_tl_data(context, server, &tl_data); if (code || tl_data.tl_data_length == 0) - return 0; /* no server referrals to return */ + goto negotiate; /* no server referrals to return */ pa_data = (krb5_pa_data *)malloc(sizeof(*pa_data)); if (pa_data == NULL) @@ -3105,8 +3103,9 @@ return_enc_padata(krb5_context context, reply_encpart->enc_padata[idx++] = pa_data; reply_encpart->enc_padata[1] = NULL; - - return 0; +negotiate: + return kdc_handle_protected_negotiation(req_pkt, request, reply_key, + reply_encpart->enc_padata, &idx); } #if 0 diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 39c6be6..0d9ca97 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -2651,3 +2651,62 @@ kdc_get_ticket_endtime(krb5_context context, *out_endtime = starttime + life; } + +/** + * Handle protected negotiation of FAST using enc_padata + * - If ENCPADATA_REQ_ENC_PA_REP is present, then: + * - Return ENCPADATA_REQ_ENC_PA_REP with checksum of AS-REQ from client + * - Include PADATA_FX_FAST in the enc_padata to indicate FAST + * @pre @c out_enc_padata has space for at least two more padata + * @param index in/out index into @c out_enc_padata for next item + */ +krb5_error_code +kdc_handle_protected_negotiation( krb5_data *req_pkt, krb5_kdc_req *request, + const krb5_keyblock *reply_key, krb5_pa_data **out_enc_padata, int *idx) +{ + krb5_error_code retval = 0; + krb5_checksum checksum; + krb5_data *out = NULL; + krb5_pa_data *pa; + assert(out_enc_padata != NULL); + pa = krb5int_find_pa_data(kdc_context, request->padata, KRB5_ENCPADATA_REQ_ENC_PA_REP); + if (pa == NULL) + return 0; + checksum.contents = NULL; + pa = malloc(sizeof(krb5_pa_data)); + if (pa == NULL) + return ENOMEM; + pa->magic = KV5M_PA_DATA; + pa->pa_type = KRB5_ENCPADATA_REQ_ENC_PA_REP; + retval = krb5_c_make_checksum(kdc_context,0, reply_key, KRB5_KEYUSAGE_AS_REQ, + req_pkt, &checksum); + if (retval != 0) + goto cleanup; + retval = encode_krb5_checksum(&checksum, &out); + if (retval != 0) + goto cleanup; + pa->contents = (krb5_octet *) out->data; + pa->length = out->length; + out_enc_padata[(*idx)++] = pa; + pa = NULL; + out->data = NULL; + pa = malloc(sizeof(krb5_pa_data)); + if (pa == NULL) { + retval = ENOMEM; + goto cleanup; + } + pa->magic = KV5M_PA_DATA; + pa->pa_type = KRB5_PADATA_FX_FAST; + pa->length = 0; + pa->contents = NULL; + out_enc_padata[(*idx)++] = pa; + pa = NULL; +cleanup: + if (checksum.contents) + krb5_free_checksum_contents(kdc_context, &checksum); + if (out != NULL) + krb5_free_data(kdc_context, out); + if (pa != NULL) + free(pa); + return retval; +} diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 289acd5..353bbfc 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -252,6 +252,7 @@ include_pac_p(krb5_context context, krb5_kdc_req *request); krb5_error_code return_enc_padata(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + krb5_keyblock *reply_key, krb5_db_entry *server, krb5_enc_kdc_rep_part *reply_encpart); @@ -393,7 +394,10 @@ krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state, krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state, krb5_pa_data **cookie); - +krb5_error_code +kdc_handle_protected_negotiation( krb5_data *req_pkt, krb5_kdc_req *request, + const krb5_keyblock *reply_key, + krb5_pa_data **out_enc_padata, int *idx); diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index 5f61733..91abb64 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -53,6 +53,7 @@ encode_krb5_as_rep encode_krb5_as_req encode_krb5_authdata encode_krb5_authenticator +encode_krb5_checksum encode_krb5_cred encode_krb5_enc_cred_part encode_krb5_enc_data -- cgit v1.1