svn rev #22138: branches/fast/src/ include/ kdc/ lib/krb5/asn.1/ lib/krb5/krb/
hartmans@MIT.EDU
hartmans at MIT.EDU
Thu Mar 26 01:37:19 EDT 2009
http://src.mit.edu/fisheye/changelog/krb5/?cs=22138
Commit By: hartmans
Log Message:
Remove FAST finish checksum
Per discussion on ietf-krb-wg, the checksum is unnecessary if a nonce
is included in the response . For this to be secure, the cookie needs
to be inner padata when FAST is used.
* kdc/fast.c: when constructing fast responses include the nonce
* lib/krb5/krb/fast.c: generate a random nonce for each time a fast request is constructed
* add nonce field to fast_response
* remove checksum field from fast_finished
* Look for cookie as inner padata when FAST is used
Changed Files:
U branches/fast/src/include/k5-int.h
U branches/fast/src/kdc/do_as_req.c
U branches/fast/src/kdc/fast_util.c
U branches/fast/src/kdc/kdc_util.h
U branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c
U branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c
U branches/fast/src/lib/krb5/asn.1/krb5_decode.c
U branches/fast/src/lib/krb5/krb/fast.c
U branches/fast/src/lib/krb5/krb/fast.h
U branches/fast/src/lib/krb5/krb/kfree.c
Modified: branches/fast/src/include/k5-int.h
===================================================================
--- branches/fast/src/include/k5-int.h 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/include/k5-int.h 2009-03-26 05:37:18 UTC (rev 22138)
@@ -989,19 +989,19 @@
#define UNSUPPORTED_CRITICAL_FAST_OPTIONS 0x00ff
#define KRB5_FAST_OPTION_HIDE_CLIENT_NAMES 0x01
- typedef struct _krb5_fast_finished {
- krb5_timestamp timestamp;
- krb5_int32 usec;
- krb5_principal client;
- krb5_checksum checksum;
- krb5_checksum ticket_checksum;
- } krb5_fast_finished;
+typedef struct _krb5_fast_finished {
+ krb5_timestamp timestamp;
+ krb5_int32 usec;
+ krb5_principal client;
+ krb5_checksum ticket_checksum;
+} krb5_fast_finished;
- typedef struct _krb5_fast_response {
- krb5_magic magic;
+typedef struct _krb5_fast_response {
+ krb5_magic magic;
krb5_pa_data **padata;
krb5_keyblock *rep_key;
krb5_fast_finished *finished;
+ krb5_int32 nonce;
} krb5_fast_response;
Modified: branches/fast/src/kdc/do_as_req.c
===================================================================
--- branches/fast/src/kdc/do_as_req.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/kdc/do_as_req.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -766,7 +766,7 @@
}
}
retval = kdc_fast_handle_error(kdc_context, rstate,
- pa, &errpkt);
+ request, pa, &errpkt);
if (retval == 0)
retval = krb5_mk_error(kdc_context, &errpkt, scratch);
free(errpkt.text.data);
Modified: branches/fast/src/kdc/fast_util.c
===================================================================
--- branches/fast/src/kdc/fast_util.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/kdc/fast_util.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -113,10 +113,7 @@
krb5_clear_error_message(kdc_context);
fast_padata = find_pa_data(request->padata,
KRB5_PADATA_FX_FAST);
- cookie_padata = find_pa_data(request->padata, KRB5_PADATA_FX_COOKIE);
- if (fast_padata == NULL)
- return 0; /*no fast*/
-
+ if (fast_padata != NULL){
scratch.length = fast_padata->length;
scratch.data = (char *) fast_padata->contents;
retval = decode_krb5_pa_fx_fast_request(&scratch, &fast_armored_req);
@@ -171,7 +168,20 @@
if ((fast_req->fast_options & UNSUPPORTED_CRITICAL_FAST_OPTIONS) !=0)
retval = KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION;
}
- if (retval == 0 && cookie_padata != NULL) {
+ if (retval == 0)
+ cookie_padata = find_pa_data(fast_req->req_body->padata, KRB5_PADATA_FX_COOKIE);
+ if (retval == 0) {
+ state->fast_options = fast_req->fast_options;
+ if (request->kdc_state == state)
+ request->kdc_state = NULL;
+ krb5_free_kdc_req( kdc_context, request);
+ *requestptr = fast_req->req_body;
+ fast_req->req_body = NULL;
+
+ }
+ }
+ else cookie_padata = find_pa_data(request->padata, KRB5_PADATA_FX_COOKIE);
+ if (retval == 0 && cookie_padata != NULL) {
krb5_pa_data *new_padata = malloc(sizeof (krb5_pa_data));
if (new_padata != NULL) {
retval = ENOMEM;
@@ -188,16 +198,7 @@
}
}
}
- if (retval == 0) {
- state->fast_options = fast_req->fast_options;
- if (request->kdc_state == state)
- request->kdc_state = NULL;
- krb5_free_kdc_req( kdc_context, request);
- *requestptr = fast_req->req_body;
- fast_req->req_body = NULL;
-
- }
- if (fast_req)
+ if (fast_req)
krb5_free_fast_req( kdc_context, fast_req);
if (fast_armored_req)
krb5_free_fast_armored_req(kdc_context, fast_armored_req);
@@ -232,7 +233,9 @@
}
krb5_error_code kdc_fast_response_handle_padata
-(struct kdc_request_state *state, krb5_kdc_rep *rep, const krb5_data *pkt)
+(struct kdc_request_state *state,
+ krb5_kdc_req *request,
+ krb5_kdc_rep *rep)
{
krb5_error_code retval = 0;
krb5_fast_finished finish;
@@ -246,7 +249,8 @@
return 0;
memset(&finish, 0, sizeof(finish));
fast_response.padata = rep->padata;
- fast_response.rep_key = state->reply_key;
+ fast_response.rep_key = state->reply_key;
+ fast_response.nonce = request->nonce;
fast_response.finished = &finish;
finish.client = rep->client;
pa_array = calloc(3, sizeof(*pa_array));
@@ -263,12 +267,7 @@
retval = krb5_c_make_checksum(kdc_context, cksumtype,
state->armor_key, KRB5_KEYUSAGE_FAST_FINISHED,
encoded_ticket, &finish.ticket_checksum);
-/* xxx checksum should be something else; sticking ticket_checksum there is a placeholder*/
if (retval == 0)
- retval = krb5_c_make_checksum(kdc_context, cksumtype,
- state->armor_key, KRB5_KEYUSAGE_FAST_FINISHED,
- encoded_ticket, &finish.checksum);
- if (retval == 0)
retval = encode_krb5_fast_response(&fast_response, &encoded_fast_response);
if (retval == 0) {
pa[0].pa_type = KRB5_PADATA_FX_FAST;
@@ -286,10 +285,8 @@
krb5_free_data(kdc_context, encoded_fast_response);
if (encoded_ticket)
krb5_free_data(kdc_context, encoded_ticket);
- if (finish.checksum.contents)
- krb5_free_checksum_contents(kdc_context, &finish.checksum);
if (finish.ticket_checksum.contents)
- krb5_free_checksum_contents(kdc_context, &finish.checksum);
+ krb5_free_checksum_contents(kdc_context, &finish.ticket_checksum);
return retval;
}
@@ -301,6 +298,7 @@
*/
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 retval = 0;
@@ -335,6 +333,7 @@
pa[0].contents = (unsigned char *) encoded_fx_error->data;
inner_pa[size++] = &pa[0];
resp.padata = inner_pa;
+ resp.nonce = request->nonce;
resp.rep_key = NULL;
resp.finished = NULL;
}
Modified: branches/fast/src/kdc/kdc_util.h
===================================================================
--- branches/fast/src/kdc/kdc_util.h 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/kdc/kdc_util.h 2009-03-26 05:37:18 UTC (rev 22138)
@@ -323,9 +323,12 @@
struct kdc_request_state *state);
krb5_error_code kdc_fast_response_handle_padata
-(struct kdc_request_state *state, krb5_kdc_rep *rep, const krb5_data *pkt);
+(struct kdc_request_state *state,
+ krb5_kdc_req *request,
+ krb5_kdc_rep *rep);
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);
Modified: branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c
===================================================================
--- branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/asn.1/asn1_k_decode.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -1653,7 +1653,6 @@
{
setup();
val->client = NULL;
- val->checksum.contents = NULL;
val->ticket_checksum.contents = NULL;
{begin_structure();
get_field(val->timestamp, 0, asn1_decode_kerberos_time);
@@ -1661,14 +1660,12 @@
alloc_field(val->client);
get_field(val->client, 2, asn1_decode_realm);
get_field(val->client, 3, asn1_decode_principal_name);
- get_field(val->checksum, 4, asn1_decode_checksum);
- get_field(val->ticket_checksum, 5, asn1_decode_checksum);
+ get_field(val->ticket_checksum, 4, asn1_decode_checksum);
end_structure();
}
return 0;
error_out:
krb5_free_principal(NULL, val->client);
- krb5_free_checksum_contents(NULL, &val->checksum);
krb5_free_checksum_contents( NULL, &val->ticket_checksum);
return retval;
}
Modified: branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c
===================================================================
--- branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/asn.1/asn1_k_encode.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -1224,8 +1224,7 @@
FIELDOF_NORM( krb5_fast_finished, int32, usec, 1),
FIELDOF_NORM( krb5_fast_finished, realm_of_principal, client, 2),
FIELDOF_NORM(krb5_fast_finished, principal, client, 3),
- FIELDOF_NORM( krb5_fast_finished, checksum, checksum, 4),
- FIELDOF_NORM( krb5_fast_finished, checksum, ticket_checksum, 5),
+ FIELDOF_NORM( krb5_fast_finished, checksum, ticket_checksum, 4),
};
DEFSEQTYPE( fast_finished, krb5_fast_finished, fast_finished_fields, 0);
@@ -1236,6 +1235,7 @@
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_fast_finished, finished, 2, 2),
+ FIELDOF_NORM(krb5_fast_response, int32, nonce, 3),
};
static unsigned int fast_response_optional (const void *p)
Modified: branches/fast/src/lib/krb5/asn.1/krb5_decode.c
===================================================================
--- branches/fast/src/lib/krb5/asn.1/krb5_decode.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/asn.1/krb5_decode.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -1142,7 +1142,8 @@
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->finished, 2, asn1_decode_fast_finished_ptr);
- end_structure(); }
+ get_field(rep->nonce, 3, asn1_decode_int32);
+ end_structure(); }
rep->magic = KV5M_FAST_RESPONSE;
cleanup(free);
}
Modified: branches/fast/src/lib/krb5/krb/fast.c
===================================================================
--- branches/fast/src/lib/krb5/krb/fast.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/krb/fast.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -159,7 +159,7 @@
krb5_error_code
krb5int_fast_prep_req (krb5_context context, struct krb5int_fast_request_state *state,
- const krb5_kdc_req *request,
+ krb5_kdc_req *request,
const krb5_data *to_be_checksummed, kdc_req_encoder_proc encoder,
krb5_data **encoded_request)
{
@@ -172,6 +172,8 @@
krb5_data *encoded_armored_req = NULL;
krb5_data *local_encoded_result = NULL;
krb5_cksumtype cksumtype;
+ krb5_data random_data;
+ char random_buf[4];
assert(state != NULL);
assert(state->fast_outer_request.padata == NULL);
@@ -179,6 +181,14 @@
if (state->armor_key == NULL) {
return encoder(request, encoded_request);
}
+/* Fill in a fresh random nonce for each inner request*/
+ random_data.length = 4;
+ random_data.data = (char *)random_buf;
+ retval = krb5_c_random_make_octets(context, &random_data);
+ if (retval == 0) {
+ request->nonce = 0x7fffffff & load_32_n(random_buf);
+ state->nonce = request->nonce;
+ }
fast_req.req_body = request;
if (fast_req.req_body->padata == NULL) {
fast_req.req_body->padata = calloc(1, sizeof(krb5_pa_data *));
@@ -287,6 +297,12 @@
krb5_free_pa_data(context, result);
result = NULL;
if (retval == 0) {
+ if (fast_response->nonce != state->nonce) {
+ krb5_set_error_message(context, KRB5_KDCREP_MODIFIED, "Nonce in reply did not match expected value");
+ retval = KRB5_KDCREP_MODIFIED;
+ }
+ }
+ if (retval == 0) {
fx_error_pa = krb5int_find_pa_data(context, fast_response->padata, KRB5_PADATA_FX_ERROR);
if (fx_error_pa == NULL) {
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED, "Expecting FX_ERROR pa-data inside FAST container");
Modified: branches/fast/src/lib/krb5/krb/fast.h
===================================================================
--- branches/fast/src/lib/krb5/krb/fast.h 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/krb/fast.h 2009-03-26 05:37:18 UTC (rev 22138)
@@ -39,6 +39,7 @@
krb5_ui_4 fast_state_flags;
krb5_ui_4 fast_options;
krb5_data cookie_contents;
+ krb5_int32 nonce;
};
krb5_error_code
@@ -49,7 +50,7 @@
krb5_error_code
krb5int_fast_prep_req (krb5_context context, struct krb5int_fast_request_state *state,
- const krb5_kdc_req *request,
+ krb5_kdc_req *request,
const krb5_data *to_be_checksummed, kdc_req_encoder_proc encoder,
krb5_data **encoded_request);
krb5_error_code
Modified: branches/fast/src/lib/krb5/krb/kfree.c
===================================================================
--- branches/fast/src/lib/krb5/krb/kfree.c 2009-03-26 05:37:15 UTC (rev 22137)
+++ branches/fast/src/lib/krb5/krb/kfree.c 2009-03-26 05:37:18 UTC (rev 22138)
@@ -828,7 +828,6 @@
if (!val)
return;
krb5_free_principal(context, val->client);
- krb5_free_checksum_contents(context, &val->checksum);
krb5_free_checksum_contents(context, &val->ticket_checksum);
free(val);
}
More information about the cvs-krb5
mailing list