aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hartman <hartmans@mit.edu>2009-12-02 16:16:19 +0000
committerSam Hartman <hartmans@mit.edu>2009-12-02 16:16:19 +0000
commit6770c3eadf86f06e1b9c0f4e6e9f19da581508d5 (patch)
tree624d81c03c372033eeb1d404abe70a4165d8530c
parentdff020edc6d720068c69b4d4f720fc8e1c0f7cf6 (diff)
downloadkrb5-6770c3eadf86f06e1b9c0f4e6e9f19da581508d5.zip
krb5-6770c3eadf86f06e1b9c0f4e6e9f19da581508d5.tar.gz
krb5-6770c3eadf86f06e1b9c0f4e6e9f19da581508d5.tar.bz2
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
-rw-r--r--src/kdc/do_as_req.c14
-rw-r--r--src/kdc/do_tgs_req.c33
-rw-r--r--src/kdc/kdc_preauth.c11
-rw-r--r--src/kdc/kdc_util.c59
-rw-r--r--src/kdc/kdc_util.h6
-rw-r--r--src/lib/krb5/libkrb5.exports1
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