From: Sam Hartman Date: Thu, 26 Mar 2009 05:36:17 +0000 (+0000) Subject: Define FAST encoders and decoders X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6aa812e8962250227cdb2cd7270feda7170570c;p=thirdparty%2Fkrb5.git Define FAST encoders and decoders Initial implementation of FAST encoders and decoders git-svn-id: svn://anonsvn.mit.edu/krb5/branches/fast@22117 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 5a467bbf95..c72544cd0f 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1288,6 +1288,16 @@ void KRB5_CALLCONV krb5_free_pa_pac_req void KRB5_CALLCONV krb5_free_etype_list (krb5_context, krb5_etype_list * ); +void KRB5_CALLCONV krb5_free_fast_armor +(krb5_context, krb5_fast_armor *); +void KRB5_CALLCONV krb5_free_fast_armored_req +(krb5_context, krb5_fast_armored_req *); +void KRB5_CALLCONV krb5_free_fast_req(krb5_context, krb5_fast_req *); +void KRB5_CALLCONV krb5_free_fast_finished +(krb5_context, krb5_fast_finished *); +void KRB5_CALLCONV krb5_free_fast_response +(krb5_context, krb5_fast_response *); + /* #include "krb5/wordsize.h" -- comes in through base-defs.h. */ #include "com_err.h" #include "k5-plugin.h" @@ -1597,6 +1607,13 @@ krb5_error_code encode_krb5_pa_pac_req krb5_error_code encode_krb5_etype_list (const krb5_etype_list * , krb5_data **); +krb5_error_code encode_krb5_pa_fx_fast_request +(const krb5_fast_armored_req *, krb5_data **); +krb5_error_code encode_krb5_fast_req +(const krb5_fast_req *, krb5_data **); +krb5_error_code encode_krb5_pa_fx_fast_reply +(const krb5_fast_response *, krb5_data **); + /************************************************************************* * End of prototypes for krb5_encode.c *************************************************************************/ @@ -1756,6 +1773,16 @@ krb5_error_code decode_krb5_pa_pac_req krb5_error_code decode_krb5_etype_list (const krb5_data *, krb5_etype_list **); +krb5_error_code decode_krb5_pa_fx_fast_request +(const krb5_data *, krb5_fast_armored_req **); + +krb5_error_code decode_krb5_fast_req +(const krb5_data *, krb5_fast_req **); + + +krb5_error_code decode_krb5_pa_fx_fast_reply +(const krb5_data *, krb5_fast_response **); + struct _krb5_key_data; /* kdb.h */ struct ldap_seqof_key_data { diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index 25cc4cc623..2c11f46010 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -1625,6 +1625,60 @@ error_out: return retval; } +asn1_error_code asn1_decode_fast_armor +(asn1buf *buf, krb5_fast_armor *val) +{ + setup(); + val->armor_value.data = NULL; + {begin_structure(); + get_field(val->armor_type, 0, asn1_decode_int32); + get_lenfield(val->armor_value.length, val->armor_value.data, + 1, asn1_decode_charstring); + end_structure(); + } + return 0; + error_out: + krb5_free_data_contents( NULL, &val->armor_value); + return retval; +} + +asn1_error_code asn1_decode_fast_armor_ptr +(asn1buf *buf, krb5_fast_armor **valptr) +{ + decode_ptr(krb5_fast_armor *, asn1_decode_fast_armor); +} + +asn1_error_code asn1_decode_fast_finished +(asn1buf *buf, krb5_fast_finished *val) +{ + setup(); + val->client = NULL; + val->checksum.contents = NULL; + val->ticket_checksum.contents = NULL; + {begin_structure(); + get_field(val->timestamp, 0, asn1_decode_kerberos_time); + get_field(val->usec, 1, asn1_decode_int32); + 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); + 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; +} +asn1_error_code asn1_decode_fast_finished_ptr +(asn1buf *buf, krb5_fast_finished **valptr) +{ + decode_ptr( krb5_fast_finished *, asn1_decode_fast_finished); +} + + #ifndef DISABLE_PKINIT /* PKINIT */ diff --git a/src/lib/krb5/asn.1/asn1_k_decode.h b/src/lib/krb5/asn.1/asn1_k_decode.h index f258f65c4d..7444443ba5 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.h +++ b/src/lib/krb5/asn.1/asn1_k_decode.h @@ -266,4 +266,16 @@ asn1_error_code asn1_decode_pa_for_user asn1_error_code asn1_decode_pa_pac_req (asn1buf *buf, krb5_pa_pac_req *val); +asn1_error_code asn1_decode_fast_armor +(asn1buf *buf, krb5_fast_armor *val); + +asn1_error_code asn1_decode_fast_armor_ptr +(asn1buf *buf, krb5_fast_armor **val); + +asn1_error_code asn1_decode_fast_finished +(asn1buf *buf, krb5_fast_finished *val); + +asn1_error_code asn1_decode_fast_finished_ptr +(asn1buf *buf, krb5_fast_finished **val); + #endif diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c index 4790b57f19..bcec13817e 100644 --- a/src/lib/krb5/asn.1/asn1_k_encode.c +++ b/src/lib/krb5/asn.1/asn1_k_encode.c @@ -1177,6 +1177,79 @@ DEFSEQTYPE(pa_pac_request, krb5_pa_pac_req, pa_pac_request_fields, 0); DEFFIELDTYPE(etype_list, krb5_etype_list, FIELDOF_SEQOF_INT32(krb5_etype_list, int32_ptr, etypes, length, -1)); +/* draft-ietf-krb-wg-preauth-framework-09 */ +static const struct field_info fast_armor_fields[] = { + FIELDOF_NORM(krb5_fast_armor, int32, armor_type, 0), + FIELDOF_NORM( krb5_fast_armor, ostring_data, armor_value, 1), +}; + +DEFSEQTYPE( fast_armor, krb5_fast_armor, fast_armor_fields, 0); +DEFPTRTYPE( ptr_fast_armor, fast_armor); + +static const struct field_info fast_armored_req_fields[] = { + FIELDOF_OPT( krb5_fast_armored_req, ptr_fast_armor, armor, 0, 0), + FIELDOF_NORM( krb5_fast_armored_req, checksum, req_checksum, 1), + FIELDOF_NORM( krb5_fast_armored_req, encrypted_data, enc_part, 2), +}; + +static unsigned int fast_armored_req_optional (const void *p) { + const krb5_fast_armored_req *val = p; + unsigned int optional = 0; + if (val->armor) + optional |= (1u)<<0; + return optional; +} + +DEFSEQTYPE( fast_armored_req, krb5_fast_armored_req, fast_armored_req_fields, fast_armored_req_optional); +DEFFIELDTYPE( pa_fx_fast_request, krb5_fast_armored_req, + FIELDOF_ENCODEAS( krb5_fast_armored_req, fast_armored_req, 0)); + +static const struct field_info fast_req_fields[] = { + FIELDOF_NORM(krb5_fast_req, int32, fast_options, 0), + FIELDOF_NORM( krb5_fast_req, ptr_seqof_pa_data, req_body.padata, 1), + FIELDOF_NORM( krb5_fast_req, kdc_req_body, req_body, 2), +}; + +DEFSEQTYPE(fast_req, krb5_fast_req, fast_req_fields, 0); + + +static const struct field_info fast_finished_fields[] = { + FIELDOF_NORM( krb5_fast_finished, kerberos_time, timestamp, 0), + 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), +}; + +DEFSEQTYPE( fast_finished, krb5_fast_finished, fast_finished_fields, 0); + +DEFPTRTYPE( ptr_fast_finished, fast_finished); + +static const struct field_info fast_response_fields[] = { + 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), +}; + +static unsigned int fast_response_optional (const void *p) +{ + unsigned int optional = 0; + const krb5_fast_response *val = p; + if (val->rep_key) + optional |= (1u <<1); + if (val->finished) + optional |= (1u<<2); + return optional; +} +DEFSEQTYPE( fast_response, krb5_fast_response, fast_response_fields, fast_response_optional); + +DEFFIELDTYPE(pa_fx_fast_reply, krb5_fast_response, + FIELDOF_ENCODEAS(krb5_fast_response, fast_response, 0)); + + + + /* Exported complete encoders -- these produce a krb5_data with the encoding in the correct byte order. */ @@ -1243,6 +1316,9 @@ MAKE_FULL_ENCODER(encode_krb5_pa_svr_referral_data, pa_svr_referral_data); MAKE_FULL_ENCODER(encode_krb5_pa_server_referral_data, pa_server_referral_data); MAKE_FULL_ENCODER(encode_krb5_etype_list, etype_list); +MAKE_FULL_ENCODER(encode_krb5_pa_fx_fast_request, pa_fx_fast_request); +MAKE_FULL_ENCODER( encode_krb5_fast_req, fast_req); +MAKE_FULL_ENCODER( encode_krb5_pa_fx_fast_reply, pa_fx_fast_reply); diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c index b118c453c3..68ab751e52 100644 --- a/src/lib/krb5/asn.1/krb5_decode.c +++ b/src/lib/krb5/asn.1/krb5_decode.c @@ -94,9 +94,9 @@ if ((var) == NULL) clean_return(ENOMEM) /* process a structure *******************************************/ /* decode an explicit tag and place the number in tagnum */ -#define next_tag() \ +#define next_tag_from_buf(buf) \ { taginfo t2; \ - retval = asn1_get_tag_2(&subbuf, &t2); \ + retval = asn1_get_tag_2(&(buf), &t2); \ if (retval) clean_return(retval); \ asn1class = t2.asn1class; \ construction = t2.construction; \ @@ -104,6 +104,8 @@ if ((var) == NULL) clean_return(ENOMEM) indef = t2.indef; \ taglen = t2.length; \ } +#define next_tag() next_tag_from_buf(subbuf) + static asn1_error_code asn1_get_eoc_tag (asn1buf *buf) @@ -1080,6 +1082,71 @@ decode_krb5_etype_list(const krb5_data *code, krb5_etype_list **repptr) cleanup(free); } +krb5_error_code decode_krb5_pa_fx_fast_request +(const krb5_data *code, krb5_fast_armored_req **repptr) +{ + setup(krb5_fast_armored_req *); + alloc_field(rep); + clear_field(rep, armor); + { + int indef; + unsigned int taglen; + next_tag_from_buf(buf); + if (tagnum != 0) + clean_return(ASN1_BAD_ID); + } + {begin_structure(); + opt_field(rep->armor, 0, asn1_decode_fast_armor_ptr); + get_field(rep->req_checksum, 1, asn1_decode_checksum); + get_field(rep->enc_part, 2, asn1_decode_encrypted_data); + end_structure();} + rep->magic = KV5M_FAST_ARMORED_REQ; + cleanup(free); +} + +krb5_error_code decode_krb5_fast_req +(const krb5_data *code, krb5_fast_req **repptr) +{ + setup(krb5_fast_req *); + alloc_field(rep); + clear_field(rep, req_body.padata); + {begin_structure(); + + + get_field(rep->fast_options, 0, asn1_decode_int32); + opt_field(rep->req_body.padata, 1, asn1_decode_sequence_of_pa_data); + get_field(rep->req_body, 2, asn1_decode_kdc_req_body); + end_structure(); } + rep->magic = KV5M_FAST_REQ; + cleanup(free); +} + +krb5_error_code decode_krb5_pa_fx_fast_reply +(const krb5_data *code, krb5_fast_response **repptr) +{ + setup(krb5_fast_response *); + + alloc_field(rep); + clear_field(rep, finished); + clear_field(rep, padata); + clear_field(rep,rep_key); + { + int indef; + unsigned int taglen; + next_tag_from_buf(buf); + if (tagnum != 0) + clean_return(ASN1_BAD_ID); + } + {begin_structure(); + 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(); } + rep->magic = KV5M_FAST_RESPONSE; + cleanup(free); +} + + #ifndef DISABLE_PKINIT krb5_error_code decode_krb5_pa_pk_as_req(const krb5_data *code, krb5_pa_pk_as_req **repptr)