From 0af4df0af5fb856419681e8d259a5229c59e361f Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Sat, 11 Feb 2012 23:25:21 +0000 Subject: [PATCH] Change optional handling in ASN.1 encoder Create a new atype_optional with a function pointer to decide whether the type is present in the C object. For simple cases, sequences just reference the optional version of a type. For more complex cases (such as when the presence of the usec field of a sequence depends on whether the timestamp is set), we define a predicate on the structure object and nest the field type inside the optional type. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25692 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/asn.1/asn1_encode.c | 19 +- src/lib/krb5/asn.1/asn1_encode.h | 51 +- src/lib/krb5/asn.1/asn1_k_encode.c | 884 ++++++++------------------ src/lib/krb5/asn.1/ldap_key_seq.c | 29 +- src/lib/krb5/error_tables/asn1_err.et | 1 + 5 files changed, 343 insertions(+), 641 deletions(-) diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c index 42fefeaec..85b804a38 100644 --- a/src/lib/krb5/asn.1/asn1_encode.c +++ b/src/lib/krb5/asn.1/asn1_encode.c @@ -400,6 +400,14 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a, return encode_atype(buf, (const char *)val + off->dataoff, off->basetype, tag_out); } + case atype_optional: { + const struct optional_info *opt = a->tinfo; + assert(opt->is_present != NULL); + if (opt->is_present(val)) + return encode_atype(buf, val, opt->basetype, tag_out); + else + return ASN1_OMITTED; + } case atype_counted: { const struct counted_info *counted = a->tinfo; const void *dataptr = (const char *)val + counted->dataoff; @@ -555,18 +563,13 @@ encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq, size_t *len_out) { asn1_error_code ret; - unsigned int not_present; size_t i, len, sum = 0; - const struct atype_info *a; - /* If any fields might be optional, get a bitmask of fields not present. */ - not_present = (seq->optional == NULL) ? 0 : seq->optional(val); for (i = seq->n_fields; i > 0; i--) { - a = seq->fields[i - 1]; - if ((1u << (i - 1)) & not_present) + ret = encode_atype_and_tag(buf, val, seq->fields[i - 1], &len); + if (ret == ASN1_OMITTED) continue; - ret = encode_atype_and_tag(buf, val, a, &len); - if (ret) + else if (ret != 0) return ret; sum += len; } diff --git a/src/lib/krb5/asn.1/asn1_encode.h b/src/lib/krb5/asn.1/asn1_encode.h index ba6151d12..5515aadf2 100644 --- a/src/lib/krb5/asn.1/asn1_encode.h +++ b/src/lib/krb5/asn.1/asn1_encode.h @@ -77,6 +77,13 @@ enum atype_type { /* Actual thing to be encoded is at an offset from the original pointer. * tinfo is a struct offset_info *. */ atype_offset, + /* + * Indicates a sequence field which may or may not be present in an object. + * tinfo is a struct optional_info *. Must be used within a sequence, + * although the optional type may be nested within offset, ptr, and/or tag + * types. + */ + atype_optional, /* * Actual thing to be encoded is an object at an offset from the original * pointer, combined with an integer at a different offset, in a manner @@ -126,6 +133,11 @@ struct offset_info { const struct atype_info *basetype; }; +struct optional_info { + int (*is_present)(const void *); + const struct atype_info *basetype; +}; + struct counted_info { unsigned int dataoff : 9; unsigned int lenoff : 9; @@ -184,10 +196,6 @@ struct choice_info { }; struct seq_info { - /* If present, returns a bitmask indicating which fields are present. The - * bit (1 << N) corresponds to index N in the fields array. */ - unsigned int (*optional)(const void *); - /* Indicates an array of sequence field descriptors. */ const struct atype_info **fields; size_t n_fields; /* Currently all sequences are assumed to be extensible. */ @@ -224,10 +232,10 @@ struct seq_info { } /* A sequence, defined by the indicated series of types, and an optional * function indicating which fields are not present. */ -#define DEFSEQTYPE(DESCNAME, CTYPENAME, FIELDS, OPT) \ +#define DEFSEQTYPE(DESCNAME, CTYPENAME, FIELDS) \ typedef CTYPENAME aux_type_##DESCNAME; \ static const struct seq_info aux_seqinfo_##DESCNAME = { \ - OPT, FIELDS, sizeof(FIELDS)/sizeof(FIELDS[0]) \ + FIELDS, sizeof(FIELDS)/sizeof(FIELDS[0]) \ }; \ const struct atype_info k5_atype_##DESCNAME = { \ atype_sequence, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME \ @@ -305,6 +313,37 @@ struct seq_info { #define DEFCOUNTEDTYPE_SIGNED(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, CDESC) \ DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, 1, CDESC) +/* Optional sequence fields. The basic form allows arbitrary test and + * initializer functions to be used. */ +#define DEFOPTIONALTYPE(DESCNAME, PRESENT, BASEDESC) \ + typedef aux_type_##BASEDESC aux_type_##DESCNAME; \ + static const struct optional_info aux_info_##DESCNAME = { \ + PRESENT, &k5_atype_##BASEDESC \ + }; \ + const struct atype_info k5_atype_##DESCNAME = { \ + atype_optional, sizeof(aux_type_##DESCNAME), \ + &aux_info_##DESCNAME \ + } +/* This form defines an is_present function for a zero-valued integer or null + * pointer of the base type's C type. */ +#define DEFOPTIONALZEROTYPE(DESCNAME, BASEDESC) \ + static int \ + aux_present_##DESCNAME(const void *p) \ + { \ + return *(aux_type_##BASEDESC *)p != 0; \ + } \ + DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, BASEDESC) +/* This form defines an is_present function for a null or empty null-terminated + * array of the base type's C type. */ +#define DEFOPTIONALEMPTYTYPE(DESCNAME, BASEDESC) \ + static int \ + aux_present_##DESCNAME(const void *p) \ + { \ + const aux_type_##BASEDESC *val = p; \ + return (*val != NULL && **val != NULL); \ + } \ + DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, BASEDESC) + /* * This encodes a pointer-to-pointer-to-thing where the passed-in * value points to a null-terminated list of pointers to objects to be diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c index 3dc9c74e3..ea4b02316 100644 --- a/src/lib/krb5/asn.1/asn1_k_encode.c +++ b/src/lib/krb5/asn.1/asn1_k_encode.c @@ -32,13 +32,24 @@ DEFINT_IMMEDIATE(krb5_version, KVNO); DEFINTTYPE(int32, krb5_int32); DEFPTRTYPE(int32_ptr, int32); DEFCOUNTEDSEQOFTYPE(cseqof_int32, krb5_int32, int32_ptr); +DEFOPTIONALZEROTYPE(opt_int32, int32); DEFUINTTYPE(uint, unsigned int); DEFUINTTYPE(octet, krb5_octet); DEFUINTTYPE(ui_4, krb5_ui_4); +DEFOPTIONALZEROTYPE(opt_uint, uint); +DEFOPTIONALZEROTYPE(opt_ui_4, ui_4); + +static int +nonempty_data(const void *p) +{ + const krb5_data *val = p; + return (val->data != NULL && val->length != 0); +} DEFCOUNTEDDERTYPE(der, char *, unsigned int); DEFCOUNTEDTYPE(der_data, krb5_data, data, length, der); +DEFOPTIONALTYPE(opt_der_data, nonempty_data, der_data); DEFCOUNTEDSTRINGTYPE(octetstring, unsigned char *, unsigned int, k5_asn1_encode_bytestring, ASN1_OCTETSTRING); @@ -46,18 +57,22 @@ DEFCOUNTEDSTRINGTYPE(s_octetstring, char *, unsigned int, k5_asn1_encode_bytestring, ASN1_OCTETSTRING); DEFCOUNTEDTYPE(ostring_data, krb5_data, data, length, s_octetstring); DEFPTRTYPE(ostring_data_ptr, ostring_data); +DEFOPTIONALTYPE(opt_ostring_data, nonempty_data, ostring_data); +DEFOPTIONALZEROTYPE(opt_ostring_data_ptr, ostring_data_ptr); DEFCOUNTEDSTRINGTYPE(generalstring, char *, unsigned int, k5_asn1_encode_bytestring, ASN1_GENERALSTRING); DEFCOUNTEDSTRINGTYPE(u_generalstring, unsigned char *, unsigned int, k5_asn1_encode_bytestring, ASN1_GENERALSTRING); DEFCOUNTEDTYPE(gstring_data, krb5_data, data, length, generalstring); +DEFOPTIONALTYPE(opt_gstring_data, nonempty_data, gstring_data); DEFPTRTYPE(gstring_data_ptr, gstring_data); DEFCOUNTEDSEQOFTYPE(cseqof_gstring_data, krb5_int32, gstring_data_ptr); DEFOFFSETTYPE(realm_of_principal_data, krb5_principal_data, realm, gstring_data); DEFPTRTYPE(realm_of_principal, realm_of_principal_data); +DEFOPTIONALZEROTYPE(opt_realm_of_principal, realm_of_principal); DEFFIELD(princname_0, krb5_principal_data, type, 0, int32); DEFCNFIELD(princname_1, krb5_principal_data, data, length, 1, @@ -65,8 +80,9 @@ DEFCNFIELD(princname_1, krb5_principal_data, data, length, 1, static const struct atype_info *princname_fields[] = { &k5_atype_princname_0, &k5_atype_princname_1 }; -DEFSEQTYPE(principal_data, krb5_principal_data, princname_fields, NULL); +DEFSEQTYPE(principal_data, krb5_principal_data, princname_fields); DEFPTRTYPE(principal, principal_data); +DEFOPTIONALZEROTYPE(opt_principal, principal); static asn1_error_code encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag) @@ -79,35 +95,35 @@ encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag) return k5_asn1_encode_generaltime(buf, val, &rettag->length); } DEFFNTYPE(kerberos_time, krb5_timestamp, encode_kerberos_time); +DEFOPTIONALZEROTYPE(opt_kerberos_time, kerberos_time); DEFFIELD(address_0, krb5_address, addrtype, 0, int32); DEFCNFIELD(address_1, krb5_address, contents, length, 1, octetstring); const static struct atype_info *address_fields[] = { &k5_atype_address_0, &k5_atype_address_1 }; -DEFSEQTYPE(address, krb5_address, address_fields, NULL); +DEFSEQTYPE(address, krb5_address, address_fields); DEFPTRTYPE(address_ptr, address); +DEFOPTIONALZEROTYPE(opt_address_ptr, address_ptr); DEFNULLTERMSEQOFTYPE(seqof_host_addresses, address_ptr); DEFPTRTYPE(ptr_seqof_host_addresses, seqof_host_addresses); +DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_host_addresses, ptr_seqof_host_addresses); DEFFIELD(enc_data_0, krb5_enc_data, enctype, 0, int32); -DEFFIELD(enc_data_1, krb5_enc_data, kvno, 1, uint); +DEFFIELD(enc_data_1, krb5_enc_data, kvno, 1, opt_uint); DEFFIELD(enc_data_2, krb5_enc_data, ciphertext, 2, ostring_data); static const struct atype_info *encrypted_data_fields[] = { &k5_atype_enc_data_0, &k5_atype_enc_data_1, &k5_atype_enc_data_2 }; -static unsigned int -optional_encrypted_data (const void *vptr) +DEFSEQTYPE(encrypted_data, krb5_enc_data, encrypted_data_fields); +static int +nonempty_enc_data(const void *p) { - const krb5_enc_data *val = vptr; - unsigned int not_present = 0; - if (val->kvno == 0) - not_present |= (1u << 1); - return not_present; + const krb5_enc_data *val = p; + return (val->ciphertext.data != NULL); } -DEFSEQTYPE(encrypted_data, krb5_enc_data, encrypted_data_fields, - optional_encrypted_data); +DEFOPTIONALTYPE(opt_encrypted_data, nonempty_enc_data, encrypted_data); /* * The encode_bitstring function wants an array of bytes (since PKINIT @@ -125,41 +141,45 @@ encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag) return k5_asn1_encode_bitstring(buf, &cptr, 4, &rettag->length); } DEFFNTYPE(krb5_flags, krb5_flags, encode_krb5_flags); +DEFOPTIONALZEROTYPE(opt_krb5_flags, krb5_flags); DEFFIELD(authdata_0, krb5_authdata, ad_type, 0, int32); DEFCNFIELD(authdata_1, krb5_authdata, contents, length, 1, octetstring); static const struct atype_info *authdata_elt_fields[] = { &k5_atype_authdata_0, &k5_atype_authdata_1 }; -DEFSEQTYPE(authdata_elt, krb5_authdata, authdata_elt_fields, NULL); +DEFSEQTYPE(authdata_elt, krb5_authdata, authdata_elt_fields); DEFPTRTYPE(authdata_elt_ptr, authdata_elt); DEFNONEMPTYNULLTERMSEQOFTYPE(auth_data, authdata_elt_ptr); DEFPTRTYPE(auth_data_ptr, auth_data); +DEFOPTIONALEMPTYTYPE(opt_auth_data_ptr, auth_data_ptr); DEFFIELD(keyblock_0, krb5_keyblock, enctype, 0, int32); DEFCNFIELD(keyblock_1, krb5_keyblock, contents, length, 1, octetstring); static const struct atype_info *encryption_key_fields[] = { &k5_atype_keyblock_0, &k5_atype_keyblock_1 }; -DEFSEQTYPE(encryption_key, krb5_keyblock, encryption_key_fields, NULL); +DEFSEQTYPE(encryption_key, krb5_keyblock, encryption_key_fields); DEFPTRTYPE(ptr_encryption_key, encryption_key); +DEFOPTIONALZEROTYPE(opt_ptr_encryption_key, ptr_encryption_key); DEFFIELD(checksum_0, krb5_checksum, checksum_type, 0, int32); DEFCNFIELD(checksum_1, krb5_checksum, contents, length, 1, octetstring); static const struct atype_info *checksum_fields[] = { &k5_atype_checksum_0, &k5_atype_checksum_1 }; -DEFSEQTYPE(checksum, krb5_checksum, checksum_fields, NULL); +DEFSEQTYPE(checksum, krb5_checksum, checksum_fields); DEFPTRTYPE(checksum_ptr, checksum); DEFNULLTERMSEQOFTYPE(seqof_checksum, checksum_ptr); DEFPTRTYPE(ptr_seqof_checksum, seqof_checksum); +DEFOPTIONALZEROTYPE(opt_checksum_ptr, checksum_ptr); DEFFIELD(last_req_0, krb5_last_req_entry, lr_type, 0, int32); DEFFIELD(last_req_1, krb5_last_req_entry, value, 1, kerberos_time); static const struct atype_info *lr_fields[] = { &k5_atype_last_req_0, &k5_atype_last_req_1 }; -DEFSEQTYPE(last_req_ent, krb5_last_req_entry, lr_fields, NULL); +DEFSEQTYPE(last_req_ent, krb5_last_req_entry, lr_fields); DEFPTRTYPE(last_req_ent_ptr, last_req_ent); DEFNONEMPTYNULLTERMSEQOFTYPE(last_req, last_req_ent_ptr); @@ -173,7 +193,7 @@ static const struct atype_info *ticket_fields[] = { &k5_atype_ticket_0, &k5_atype_ticket_1, &k5_atype_ticket_2, &k5_atype_ticket_3 }; -DEFSEQTYPE(untagged_ticket, krb5_ticket, ticket_fields, NULL); +DEFSEQTYPE(untagged_ticket, krb5_ticket, ticket_fields); DEFAPPTAGGEDTYPE(ticket, 1, untagged_ticket); /* First context tag is 1, not 0. */ @@ -182,35 +202,44 @@ DEFCNFIELD(pa_data_2, krb5_pa_data, contents, length, 2, octetstring); static const struct atype_info *pa_data_fields[] = { &k5_atype_pa_data_1, &k5_atype_pa_data_2 }; -DEFSEQTYPE(pa_data, krb5_pa_data, pa_data_fields, 0); +DEFSEQTYPE(pa_data, krb5_pa_data, pa_data_fields); DEFPTRTYPE(pa_data_ptr, pa_data); DEFNULLTERMSEQOFTYPE(seqof_pa_data, pa_data_ptr); DEFPTRTYPE(ptr_seqof_pa_data, seqof_pa_data); +DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_pa_data, ptr_seqof_pa_data); DEFPTRTYPE(ticket_ptr, ticket); DEFNONEMPTYNULLTERMSEQOFTYPE(seqof_ticket,ticket_ptr); DEFPTRTYPE(ptr_seqof_ticket, seqof_ticket); +DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_ticket, ptr_seqof_ticket); +static int +is_renewable_flag_set(const void *p) +{ + const krb5_enc_kdc_rep_part *val = p; + return (val->flags & TKT_FLG_RENEWABLE); +} DEFFIELD(enc_kdc_rep_0, krb5_enc_kdc_rep_part, session, 0, ptr_encryption_key); DEFFIELD(enc_kdc_rep_1, krb5_enc_kdc_rep_part, last_req, 1, last_req_ptr); DEFFIELD(enc_kdc_rep_2, krb5_enc_kdc_rep_part, nonce, 2, int32); -DEFFIELD(enc_kdc_rep_3, krb5_enc_kdc_rep_part, key_exp, 3, kerberos_time); +DEFFIELD(enc_kdc_rep_3, krb5_enc_kdc_rep_part, key_exp, 3, opt_kerberos_time); DEFFIELD(enc_kdc_rep_4, krb5_enc_kdc_rep_part, flags, 4, krb5_flags); DEFFIELD(enc_kdc_rep_5, krb5_enc_kdc_rep_part, times.authtime, 5, kerberos_time); DEFFIELD(enc_kdc_rep_6, krb5_enc_kdc_rep_part, times.starttime, 6, - kerberos_time); + opt_kerberos_time); DEFFIELD(enc_kdc_rep_7, krb5_enc_kdc_rep_part, times.endtime, 7, kerberos_time); -DEFFIELD(enc_kdc_rep_8, krb5_enc_kdc_rep_part, times.renew_till, 8, +DEFFIELD(enc_kdc_rep_8_def, krb5_enc_kdc_rep_part, times.renew_till, 8, kerberos_time); +DEFOPTIONALTYPE(enc_kdc_rep_8, is_renewable_flag_set, enc_kdc_rep_8_def); DEFFIELD(enc_kdc_rep_9, krb5_enc_kdc_rep_part, server, 9, realm_of_principal); DEFFIELD(enc_kdc_rep_10, krb5_enc_kdc_rep_part, server, 10, principal); DEFFIELD(enc_kdc_rep_11, krb5_enc_kdc_rep_part, caddrs, 11, - ptr_seqof_host_addresses); + opt_ptr_seqof_host_addresses); DEFFIELD(enc_kdc_rep_12, krb5_enc_kdc_rep_part, enc_padata, 12, - ptr_seqof_pa_data); + opt_ptr_seqof_pa_data); static const struct atype_info *enc_kdc_rep_part_fields[] = { &k5_atype_enc_kdc_rep_0, &k5_atype_enc_kdc_rep_1, &k5_atype_enc_kdc_rep_2, &k5_atype_enc_kdc_rep_3, &k5_atype_enc_kdc_rep_4, &k5_atype_enc_kdc_rep_5, @@ -218,25 +247,7 @@ static const struct atype_info *enc_kdc_rep_part_fields[] = { &k5_atype_enc_kdc_rep_9, &k5_atype_enc_kdc_rep_10, &k5_atype_enc_kdc_rep_11, &k5_atype_enc_kdc_rep_12 }; -static unsigned int -optional_enc_kdc_rep_part(const void *p) -{ - const krb5_enc_kdc_rep_part *val = p; - unsigned int not_present = 0; - if (val->key_exp == 0) - not_present |= (1u << 3); - if (val->times.starttime == 0) - not_present |= (1u << 6); - if (!(val->flags & TKT_FLG_RENEWABLE)) - not_present |= (1u << 8); - if (val->caddrs == NULL || val->caddrs[0] == NULL) - not_present |= (1u << 11); - if (val->enc_padata == NULL) - not_present |= (1u << 12); - return not_present; -} -DEFSEQTYPE(enc_kdc_rep_part, krb5_enc_kdc_rep_part, enc_kdc_rep_part_fields, - optional_enc_kdc_rep_part); +DEFSEQTYPE(enc_kdc_rep_part, krb5_enc_kdc_rep_part, enc_kdc_rep_part_fields); /* * Yuck! Eventually push this *up* above the encoder API and make the @@ -249,47 +260,26 @@ typedef struct kdc_req_hack { krb5_data *server_realm; } kdc_req_hack; DEFFIELD(req_body_0, kdc_req_hack, v.kdc_options, 0, krb5_flags); -DEFFIELD(req_body_1, kdc_req_hack, v.client, 1, principal); +DEFFIELD(req_body_1, kdc_req_hack, v.client, 1, opt_principal); DEFFIELD(req_body_2, kdc_req_hack, server_realm, 2, gstring_data_ptr); -DEFFIELD(req_body_3, kdc_req_hack, v.server, 3, principal); -DEFFIELD(req_body_4, kdc_req_hack, v.from, 4, kerberos_time); +DEFFIELD(req_body_3, kdc_req_hack, v.server, 3, opt_principal); +DEFFIELD(req_body_4, kdc_req_hack, v.from, 4, opt_kerberos_time); DEFFIELD(req_body_5, kdc_req_hack, v.till, 5, kerberos_time); -DEFFIELD(req_body_6, kdc_req_hack, v.rtime, 6, kerberos_time); +DEFFIELD(req_body_6, kdc_req_hack, v.rtime, 6, opt_kerberos_time); DEFFIELD(req_body_7, kdc_req_hack, v.nonce, 7, int32); DEFCNFIELD(req_body_8, kdc_req_hack, v.ktype, v.nktypes, 8, cseqof_int32); -DEFFIELD(req_body_9, kdc_req_hack, v.addresses, 9, ptr_seqof_host_addresses); -DEFFIELD(req_body_10, kdc_req_hack, v.authorization_data, 10, encrypted_data); -DEFFIELD(req_body_11, kdc_req_hack, v.second_ticket, 11, ptr_seqof_ticket); +DEFFIELD(req_body_9, kdc_req_hack, v.addresses, 9, + opt_ptr_seqof_host_addresses); +DEFFIELD(req_body_10, kdc_req_hack, v.authorization_data, 10, + opt_encrypted_data); +DEFFIELD(req_body_11, kdc_req_hack, v.second_ticket, 11, opt_ptr_seqof_ticket); static const struct atype_info *kdc_req_hack_fields[] = { &k5_atype_req_body_0, &k5_atype_req_body_1, &k5_atype_req_body_2, &k5_atype_req_body_3, &k5_atype_req_body_4, &k5_atype_req_body_5, &k5_atype_req_body_6, &k5_atype_req_body_7, &k5_atype_req_body_8, &k5_atype_req_body_9, &k5_atype_req_body_10, &k5_atype_req_body_11 }; -static unsigned int -optional_kdc_req_hack(const void *p) -{ - const kdc_req_hack *val2 = p; - const krb5_kdc_req *val = &val2->v; - unsigned int not_present = 0; - if (val->second_ticket == NULL || val->second_ticket[0] == NULL) - not_present |= (1u << 11); - if (val->authorization_data.ciphertext.data == NULL) - not_present |= (1u << 10); - if (val->addresses == NULL || val->addresses[0] == NULL) - not_present |= (1u << 9); - if (val->rtime == 0) - not_present |= (1u << 6); - if (val->from == 0) - not_present |= (1u << 4); - if (val->server == NULL) - not_present |= (1u << 3); - if (val->client == NULL) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(kdc_req_body_hack, kdc_req_hack, kdc_req_hack_fields, - optional_kdc_req_hack); +DEFSEQTYPE(kdc_req_body_hack, kdc_req_hack, kdc_req_hack_fields); static asn1_error_code encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out) { @@ -315,117 +305,75 @@ DEFFIELD(transited_1, krb5_transited, tr_contents, 1, ostring_data); static const struct atype_info *transited_fields[] = { &k5_atype_transited_0, &k5_atype_transited_1 }; -DEFSEQTYPE(transited, krb5_transited, transited_fields, NULL); +DEFSEQTYPE(transited, krb5_transited, transited_fields); +static int +is_safe_timestamp_set(const void *p) +{ + const krb5_safe *val = p; + return (val->timestamp != 0); +} DEFFIELD(safe_body_0, krb5_safe, user_data, 0, ostring_data); -DEFFIELD(safe_body_1, krb5_safe, timestamp, 1, kerberos_time); -DEFFIELD(safe_body_2, krb5_safe, usec, 2, int32); -DEFFIELD(safe_body_3, krb5_safe, seq_number, 3, uint); +DEFFIELD(safe_body_1, krb5_safe, timestamp, 1, opt_kerberos_time); +DEFFIELD(safe_body_2_def, krb5_safe, usec, 2, int32); +DEFOPTIONALTYPE(safe_body_2, is_safe_timestamp_set, safe_body_2_def); +DEFFIELD(safe_body_3, krb5_safe, seq_number, 3, opt_ui_4); DEFFIELD(safe_body_4, krb5_safe, s_address, 4, address_ptr); -DEFFIELD(safe_body_5, krb5_safe, r_address, 5, address_ptr); +DEFFIELD(safe_body_5, krb5_safe, r_address, 5, opt_address_ptr); static const struct atype_info *safe_body_fields[] = { &k5_atype_safe_body_0, &k5_atype_safe_body_1, &k5_atype_safe_body_2, &k5_atype_safe_body_3, &k5_atype_safe_body_4, &k5_atype_safe_body_5 }; -static unsigned int -optional_krb_safe_body(const void *p) -{ - const krb5_safe *val = p; - unsigned int not_present = 0; - if (val->timestamp == 0) - not_present |= (1u << 1) | (1u << 2); - if (val->seq_number == 0) - not_present |= (1u << 3); - if (val->r_address == NULL) - not_present |= (1u << 5); - return not_present; -} -DEFSEQTYPE(safe_body, krb5_safe, safe_body_fields, optional_krb_safe_body); +DEFSEQTYPE(safe_body, krb5_safe, safe_body_fields); DEFFIELD(cred_info_0, krb5_cred_info, session, 0, ptr_encryption_key); -DEFFIELD(cred_info_1, krb5_cred_info, client, 1, realm_of_principal); -DEFFIELD(cred_info_2, krb5_cred_info, client, 2, principal); -DEFFIELD(cred_info_3, krb5_cred_info, flags, 3, krb5_flags); -DEFFIELD(cred_info_4, krb5_cred_info, times.authtime, 4, kerberos_time); -DEFFIELD(cred_info_5, krb5_cred_info, times.starttime, 5, kerberos_time); -DEFFIELD(cred_info_6, krb5_cred_info, times.endtime, 6, kerberos_time); -DEFFIELD(cred_info_7, krb5_cred_info, times.renew_till, 7, kerberos_time); -DEFFIELD(cred_info_8, krb5_cred_info, server, 8, realm_of_principal); -DEFFIELD(cred_info_9, krb5_cred_info, server, 9, principal); -DEFFIELD(cred_info_10, krb5_cred_info, caddrs, 10, ptr_seqof_host_addresses); +DEFFIELD(cred_info_1, krb5_cred_info, client, 1, opt_realm_of_principal); +DEFFIELD(cred_info_2, krb5_cred_info, client, 2, opt_principal); +DEFFIELD(cred_info_3, krb5_cred_info, flags, 3, opt_krb5_flags); +DEFFIELD(cred_info_4, krb5_cred_info, times.authtime, 4, opt_kerberos_time); +DEFFIELD(cred_info_5, krb5_cred_info, times.starttime, 5, opt_kerberos_time); +DEFFIELD(cred_info_6, krb5_cred_info, times.endtime, 6, opt_kerberos_time); +DEFFIELD(cred_info_7, krb5_cred_info, times.renew_till, 7, opt_kerberos_time); +DEFFIELD(cred_info_8, krb5_cred_info, server, 8, opt_realm_of_principal); +DEFFIELD(cred_info_9, krb5_cred_info, server, 9, opt_principal); +DEFFIELD(cred_info_10, krb5_cred_info, caddrs, 10, + opt_ptr_seqof_host_addresses); static const struct atype_info *krb_cred_info_fields[] = { &k5_atype_cred_info_0, &k5_atype_cred_info_1, &k5_atype_cred_info_2, &k5_atype_cred_info_3, &k5_atype_cred_info_4, &k5_atype_cred_info_5, &k5_atype_cred_info_6, &k5_atype_cred_info_7, &k5_atype_cred_info_8, &k5_atype_cred_info_9, &k5_atype_cred_info_10 }; -static unsigned int -optional_krb_cred_info(const void *p) -{ - const krb5_cred_info *val = p; - unsigned int not_present = 0; - if (val->caddrs == NULL || val->caddrs[0] == NULL) - not_present |= (1u << 10); - if (val->server == NULL) - not_present |= (1u << 9) | (1u << 8); - if (val->times.renew_till == 0) - not_present |= (1u << 7); - if (val->times.endtime == 0) - not_present |= (1u << 6); - if (val->times.starttime == 0) - not_present |= (1u << 5); - if (val->times.authtime == 0) - not_present |= (1u << 4); - if (val->flags == 0) - not_present |= (1u << 3); - if (val->client == NULL) - not_present |= (1u << 2) | (1u << 1); - return not_present; -} -DEFSEQTYPE(cred_info, krb5_cred_info, krb_cred_info_fields, - optional_krb_cred_info); +DEFSEQTYPE(cred_info, krb5_cred_info, krb_cred_info_fields); DEFPTRTYPE(cred_info_ptr, cred_info); DEFNULLTERMSEQOFTYPE(seqof_cred_info, cred_info_ptr); DEFPTRTYPE(ptrseqof_cred_info, seqof_cred_info); +static int +is_etype_info_salt_present(const void *p) +{ + const krb5_etype_info_entry *val = p; + return (val->length != KRB5_ETYPE_NO_SALT); +} DEFFIELD(etype_info_0, krb5_etype_info_entry, etype, 0, int32); -DEFCNFIELD(etype_info_1, krb5_etype_info_entry, salt, length, 1, octetstring); +DEFCNFIELD(etype_info_1_def, krb5_etype_info_entry, salt, length, 1, + octetstring); +DEFOPTIONALTYPE(etype_info_1, is_etype_info_salt_present, etype_info_1_def); static const struct atype_info *etype_info_entry_fields[] = { &k5_atype_etype_info_0, &k5_atype_etype_info_1 }; -static unsigned int -optional_etype_info_entry(const void *vptr) -{ - const krb5_etype_info_entry *val = vptr; - unsigned int not_present = 0; - if (val->length == KRB5_ETYPE_NO_SALT) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(etype_info_entry, krb5_etype_info_entry, etype_info_entry_fields, - optional_etype_info_entry); +DEFSEQTYPE(etype_info_entry, krb5_etype_info_entry, etype_info_entry_fields); /* First field is the same as etype-info. */ -DEFCNFIELD(etype_info2_1, krb5_etype_info_entry, salt, length, 1, +DEFCNFIELD(etype_info2_1_def, krb5_etype_info_entry, salt, length, 1, u_generalstring); -DEFFIELD(etype_info2_2, krb5_etype_info_entry, s2kparams, 2, ostring_data); +DEFOPTIONALTYPE(etype_info2_1, is_etype_info_salt_present, etype_info2_1_def); +DEFFIELD(etype_info2_2, krb5_etype_info_entry, s2kparams, 2, opt_ostring_data); static const struct atype_info *etype_info2_entry_fields[] = { &k5_atype_etype_info_0, &k5_atype_etype_info2_1, &k5_atype_etype_info2_2 }; -static unsigned int -optional_etype_info2_entry(const void *vptr) -{ - const krb5_etype_info_entry *val = vptr; - unsigned int not_present = 0; - if (val->length == KRB5_ETYPE_NO_SALT) - not_present |= (1u << 1); - if (val->s2kparams.data == NULL) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(etype_info2_entry, krb5_etype_info_entry, etype_info2_entry_fields, - optional_etype_info2_entry); +DEFSEQTYPE(etype_info2_entry, krb5_etype_info_entry, etype_info2_entry_fields); DEFPTRTYPE(etype_info_entry_ptr, etype_info_entry); DEFNULLTERMSEQOFTYPE(etype_info, etype_info_entry_ptr); @@ -438,19 +386,21 @@ DEFFIELD(sch_1, krb5_sam_challenge_2, sam_cksum, 1, ptr_seqof_checksum); static const struct atype_info *sam_challenge_2_fields[] = { &k5_atype_sch_0, &k5_atype_sch_1 }; -DEFSEQTYPE(sam_challenge_2, krb5_sam_challenge_2, sam_challenge_2_fields, - NULL); +DEFSEQTYPE(sam_challenge_2, krb5_sam_challenge_2, sam_challenge_2_fields); DEFFIELD(schb_0, krb5_sam_challenge_2_body, sam_type, 0, int32); DEFFIELD(schb_1, krb5_sam_challenge_2_body, sam_flags, 1, krb5_flags); -DEFFIELD(schb_2, krb5_sam_challenge_2_body, sam_type_name, 2, ostring_data); -DEFFIELD(schb_3, krb5_sam_challenge_2_body, sam_track_id, 3, ostring_data); +DEFFIELD(schb_2, krb5_sam_challenge_2_body, sam_type_name, 2, + opt_ostring_data); +DEFFIELD(schb_3, krb5_sam_challenge_2_body, sam_track_id, 3, opt_ostring_data); DEFFIELD(schb_4, krb5_sam_challenge_2_body, sam_challenge_label, 4, - ostring_data); -DEFFIELD(schb_5, krb5_sam_challenge_2_body, sam_challenge, 5, ostring_data); + opt_ostring_data); +DEFFIELD(schb_5, krb5_sam_challenge_2_body, sam_challenge, 5, + opt_ostring_data); DEFFIELD(schb_6, krb5_sam_challenge_2_body, sam_response_prompt, 6, - ostring_data); -DEFFIELD(schb_7, krb5_sam_challenge_2_body, sam_pk_for_sad, 7, ostring_data); + opt_ostring_data); +DEFFIELD(schb_7, krb5_sam_challenge_2_body, sam_pk_for_sad, 7, + opt_ostring_data); DEFFIELD(schb_8, krb5_sam_challenge_2_body, sam_nonce, 8, int32); DEFFIELD(schb_9, krb5_sam_challenge_2_body, sam_etype, 9, int32); static const struct atype_info *sam_challenge_2_body_fields[] = { @@ -458,49 +408,20 @@ static const struct atype_info *sam_challenge_2_body_fields[] = { &k5_atype_schb_4, &k5_atype_schb_5, &k5_atype_schb_6, &k5_atype_schb_7, &k5_atype_schb_8, &k5_atype_schb_9 }; -static unsigned int -optional_sam_challenge_2_body(const void *p) -{ - const krb5_sam_challenge_2_body *val = p; - unsigned int not_present = 0; - if (val->sam_pk_for_sad.length == 0) - not_present |= (1u << 7); - if (val->sam_response_prompt.length == 0) - not_present |= (1u << 6); - if (val->sam_challenge.length == 0) - not_present |= (1u << 5); - if (val->sam_challenge_label.length == 0) - not_present |= (1u << 4); - if (val->sam_track_id.length == 0) - not_present |= (1u << 3); - if (val->sam_type_name.length == 0) - not_present |= (1u << 2); - return not_present; -} DEFSEQTYPE(sam_challenge_2_body,krb5_sam_challenge_2_body, - sam_challenge_2_body_fields, - optional_sam_challenge_2_body); + sam_challenge_2_body_fields); DEFFIELD(esre_0, krb5_enc_sam_response_enc_2, sam_nonce, 0, int32); -DEFFIELD(esre_1, krb5_enc_sam_response_enc_2, sam_sad, 1, ostring_data); +DEFFIELD(esre_1, krb5_enc_sam_response_enc_2, sam_sad, 1, opt_ostring_data); static const struct atype_info *enc_sam_response_enc_2_fields[] = { &k5_atype_esre_0, &k5_atype_esre_1 }; -static unsigned int -optional_enc_sam_response_enc_2(const void *p) -{ - const krb5_enc_sam_response_enc_2 *val = p; - unsigned int not_present = 0; - if (val->sam_sad.length == 0) - not_present |= (1u << 1); - return not_present; -} DEFSEQTYPE(enc_sam_response_enc_2, krb5_enc_sam_response_enc_2, - enc_sam_response_enc_2_fields, optional_enc_sam_response_enc_2); + enc_sam_response_enc_2_fields); DEFFIELD(sam_resp_0, krb5_sam_response_2, sam_type, 0, int32); DEFFIELD(sam_resp_1, krb5_sam_response_2, sam_flags, 1, krb5_flags); -DEFFIELD(sam_resp_2, krb5_sam_response_2, sam_track_id, 2, ostring_data); +DEFFIELD(sam_resp_2, krb5_sam_response_2, sam_track_id, 2, opt_ostring_data); DEFFIELD(sam_resp_3, krb5_sam_response_2, sam_enc_nonce_or_sad, 3, encrypted_data); DEFFIELD(sam_resp_4, krb5_sam_response_2, sam_nonce, 4, int32); @@ -508,28 +429,19 @@ static const struct atype_info *sam_response_2_fields[] = { &k5_atype_sam_resp_0, &k5_atype_sam_resp_1, &k5_atype_sam_resp_2, &k5_atype_sam_resp_3, &k5_atype_sam_resp_4 }; -static unsigned int -optional_sam_response_2(const void *p) -{ - const krb5_sam_response_2 *val = p; - unsigned int not_present = 0; - if (val->sam_track_id.length == 0) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(sam_response_2, krb5_sam_response_2, sam_response_2_fields, - optional_sam_response_2); +DEFSEQTYPE(sam_response_2, krb5_sam_response_2, sam_response_2_fields); DEFCTAGGEDTYPE(authenticator_0, 0, krb5_version); DEFFIELD(authenticator_1, krb5_authenticator, client, 1, realm_of_principal); DEFFIELD(authenticator_2, krb5_authenticator, client, 2, principal); -DEFFIELD(authenticator_3, krb5_authenticator, checksum, 3, checksum_ptr); +DEFFIELD(authenticator_3, krb5_authenticator, checksum, 3, opt_checksum_ptr); DEFFIELD(authenticator_4, krb5_authenticator, cusec, 4, int32); DEFFIELD(authenticator_5, krb5_authenticator, ctime, 5, kerberos_time); -DEFFIELD(authenticator_6, krb5_authenticator, subkey, 6, ptr_encryption_key); -DEFFIELD(authenticator_7, krb5_authenticator, seq_number, 7, uint); +DEFFIELD(authenticator_6, krb5_authenticator, subkey, 6, + opt_ptr_encryption_key); +DEFFIELD(authenticator_7, krb5_authenticator, seq_number, 7, opt_ui_4); DEFFIELD(authenticator_8, krb5_authenticator, authorization_data, 8, - auth_data_ptr); + opt_auth_data_ptr); static const struct atype_info *authenticator_fields[] = { &k5_atype_authenticator_0, &k5_atype_authenticator_1, &k5_atype_authenticator_2, &k5_atype_authenticator_3, @@ -537,23 +449,7 @@ static const struct atype_info *authenticator_fields[] = { &k5_atype_authenticator_6, &k5_atype_authenticator_7, &k5_atype_authenticator_8 }; -static unsigned int -optional_authenticator(const void *p) -{ - const krb5_authenticator *val = p; - unsigned int not_present = 0; - if (val->authorization_data == NULL || val->authorization_data[0] == NULL) - not_present |= (1u << 8); - if (val->seq_number == 0) - not_present |= (1u << 7); - if (val->subkey == NULL) - not_present |= (1u << 6); - if (val->checksum == NULL) - not_present |= (1u << 3); - return not_present; -} -DEFSEQTYPE(untagged_authenticator, krb5_authenticator, authenticator_fields, - optional_authenticator); +DEFSEQTYPE(untagged_authenticator, krb5_authenticator, authenticator_fields); DEFAPPTAGGEDTYPE(authenticator, 2, untagged_authenticator); DEFFIELD(enc_tkt_0, krb5_enc_tkt_part, flags, 0, krb5_flags); @@ -562,34 +458,20 @@ DEFFIELD(enc_tkt_2, krb5_enc_tkt_part, client, 2, realm_of_principal); DEFFIELD(enc_tkt_3, krb5_enc_tkt_part, client, 3, principal); DEFFIELD(enc_tkt_4, krb5_enc_tkt_part, transited, 4, transited); DEFFIELD(enc_tkt_5, krb5_enc_tkt_part, times.authtime, 5, kerberos_time); -DEFFIELD(enc_tkt_6, krb5_enc_tkt_part, times.starttime, 6, kerberos_time); +DEFFIELD(enc_tkt_6, krb5_enc_tkt_part, times.starttime, 6, opt_kerberos_time); DEFFIELD(enc_tkt_7, krb5_enc_tkt_part, times.endtime, 7, kerberos_time); -DEFFIELD(enc_tkt_8, krb5_enc_tkt_part, times.renew_till, 8, kerberos_time); -DEFFIELD(enc_tkt_9, krb5_enc_tkt_part, caddrs, 9, ptr_seqof_host_addresses); -DEFFIELD(enc_tkt_10, krb5_enc_tkt_part, authorization_data, 10, auth_data_ptr); +DEFFIELD(enc_tkt_8, krb5_enc_tkt_part, times.renew_till, 8, opt_kerberos_time); +DEFFIELD(enc_tkt_9, krb5_enc_tkt_part, caddrs, 9, + opt_ptr_seqof_host_addresses); +DEFFIELD(enc_tkt_10, krb5_enc_tkt_part, authorization_data, 10, + opt_auth_data_ptr); static const struct atype_info *enc_tkt_part_fields[] = { &k5_atype_enc_tkt_0, &k5_atype_enc_tkt_1, &k5_atype_enc_tkt_2, &k5_atype_enc_tkt_3, &k5_atype_enc_tkt_4, &k5_atype_enc_tkt_5, &k5_atype_enc_tkt_6, &k5_atype_enc_tkt_7, &k5_atype_enc_tkt_8, &k5_atype_enc_tkt_9, &k5_atype_enc_tkt_10 }; -static unsigned int -optional_enc_tkt_part(const void *p) -{ - const krb5_enc_tkt_part *val = p; - unsigned int not_present = 0; - if (val->authorization_data == NULL || val->authorization_data[0] == NULL) - not_present |= (1u << 10); - if (val->caddrs == NULL || val->caddrs[0] == NULL) - not_present |= (1u << 9); - if (val->times.renew_till == 0) - not_present |= (1u << 8); - if (val->times.starttime == 0) - not_present |= (1u << 6); - return not_present; -} -DEFSEQTYPE(untagged_enc_tkt_part, krb5_enc_tkt_part, enc_tkt_part_fields, - optional_enc_tkt_part); +DEFSEQTYPE(untagged_enc_tkt_part, krb5_enc_tkt_part, enc_tkt_part_fields); DEFAPPTAGGEDTYPE(enc_tkt_part, 3, untagged_enc_tkt_part); DEFAPPTAGGEDTYPE(enc_tgs_rep_part, 26, enc_kdc_rep_part); @@ -597,7 +479,7 @@ DEFAPPTAGGEDTYPE(enc_tgs_rep_part, 26, enc_kdc_rep_part); DEFINT_IMMEDIATE(as_rep_msg_type, KRB5_AS_REP); DEFCTAGGEDTYPE(kdc_rep_0, 0, krb5_version); DEFCTAGGEDTYPE(as_rep_1, 1, as_rep_msg_type); -DEFFIELD(kdc_rep_2, krb5_kdc_rep, padata, 2, ptr_seqof_pa_data); +DEFFIELD(kdc_rep_2, krb5_kdc_rep, padata, 2, opt_ptr_seqof_pa_data); DEFFIELD(kdc_rep_3, krb5_kdc_rep, client, 3, realm_of_principal); DEFFIELD(kdc_rep_4, krb5_kdc_rep, client, 4, principal); DEFFIELD(kdc_rep_5, krb5_kdc_rep, ticket, 5, ticket_ptr); @@ -607,16 +489,7 @@ static const struct atype_info *as_rep_fields[] = { &k5_atype_kdc_rep_3, &k5_atype_kdc_rep_4, &k5_atype_kdc_rep_5, &k5_atype_kdc_rep_6 }; -static unsigned int -optional_kdc_rep(const void *p) -{ - const krb5_kdc_rep *val = p; - unsigned int not_present = 0; - if (val->padata == NULL || val->padata[0] == NULL) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(untagged_as_rep, krb5_kdc_rep, as_rep_fields, optional_kdc_rep); +DEFSEQTYPE(untagged_as_rep, krb5_kdc_rep, as_rep_fields); DEFAPPTAGGEDTYPE(as_rep, 11, untagged_as_rep); /* TGS-REP ::= [APPLICATION 13] KDC-REP */ @@ -629,7 +502,7 @@ static const struct atype_info *tgs_rep_fields[] = { &k5_atype_kdc_rep_3, &k5_atype_kdc_rep_4, &k5_atype_kdc_rep_5, &k5_atype_kdc_rep_6 }; -DEFSEQTYPE(untagged_tgs_rep, krb5_kdc_rep, tgs_rep_fields, optional_kdc_rep); +DEFSEQTYPE(untagged_tgs_rep, krb5_kdc_rep, tgs_rep_fields); DEFAPPTAGGEDTYPE(tgs_rep, 13, untagged_tgs_rep); DEFINT_IMMEDIATE(ap_req_msg_type, ASN1_KRB_AP_REQ); @@ -642,7 +515,7 @@ static const struct atype_info *ap_req_fields[] = { &k5_atype_ap_req_0, &k5_atype_ap_req_1, &k5_atype_ap_req_2, &k5_atype_ap_req_3, &k5_atype_ap_req_4 }; -DEFSEQTYPE(untagged_ap_req, krb5_ap_req, ap_req_fields, NULL); +DEFSEQTYPE(untagged_ap_req, krb5_ap_req, ap_req_fields); DEFAPPTAGGEDTYPE(ap_req, 14, untagged_ap_req); DEFINT_IMMEDIATE(ap_rep_msg_type, ASN1_KRB_AP_REP); @@ -652,31 +525,20 @@ DEFFIELD(ap_rep_2, krb5_ap_rep, enc_part, 2, encrypted_data); static const struct atype_info *ap_rep_fields[] = { &k5_atype_ap_rep_0, &k5_atype_ap_rep_1, &k5_atype_ap_rep_2 }; -DEFSEQTYPE(untagged_ap_rep, krb5_ap_rep, ap_rep_fields, NULL); +DEFSEQTYPE(untagged_ap_rep, krb5_ap_rep, ap_rep_fields); DEFAPPTAGGEDTYPE(ap_rep, 15, untagged_ap_rep); DEFFIELD(ap_rep_enc_part_0, krb5_ap_rep_enc_part, ctime, 0, kerberos_time); DEFFIELD(ap_rep_enc_part_1, krb5_ap_rep_enc_part, cusec, 1, int32); DEFFIELD(ap_rep_enc_part_2, krb5_ap_rep_enc_part, subkey, 2, - ptr_encryption_key); -DEFFIELD(ap_rep_enc_part_3, krb5_ap_rep_enc_part, seq_number, 3, uint); + opt_ptr_encryption_key); +DEFFIELD(ap_rep_enc_part_3, krb5_ap_rep_enc_part, seq_number, 3, opt_ui_4); static const struct atype_info *ap_rep_enc_part_fields[] = { &k5_atype_ap_rep_enc_part_0, &k5_atype_ap_rep_enc_part_1, &k5_atype_ap_rep_enc_part_2, &k5_atype_ap_rep_enc_part_3 }; -static unsigned int -optional_ap_rep_enc_part(const void *p) -{ - const krb5_ap_rep_enc_part *val = p; - unsigned int not_present = 0; - if (val->seq_number == 0) - not_present |= (1u << 3); - if (val->subkey == NULL) - not_present |= (1u << 2); - return not_present; -} DEFSEQTYPE(untagged_ap_rep_enc_part, krb5_ap_rep_enc_part, - ap_rep_enc_part_fields, optional_ap_rep_enc_part); + ap_rep_enc_part_fields); DEFAPPTAGGEDTYPE(ap_rep_enc_part, 27, untagged_ap_rep_enc_part); /* First context tag is 1. Fourth field is the encoding of the krb5_kdc_req @@ -684,22 +546,13 @@ DEFAPPTAGGEDTYPE(ap_rep_enc_part, 27, untagged_ap_rep_enc_part); DEFINT_IMMEDIATE(as_req_msg_type, KRB5_AS_REQ); DEFCTAGGEDTYPE(as_req_1, 1, krb5_version); DEFCTAGGEDTYPE(as_req_2, 2, as_req_msg_type); -DEFFIELD(as_req_3, krb5_kdc_req, padata, 3, ptr_seqof_pa_data); +DEFFIELD(as_req_3, krb5_kdc_req, padata, 3, opt_ptr_seqof_pa_data); DEFCTAGGEDTYPE(as_req_4, 4, kdc_req_body); static const struct atype_info *as_req_fields[] = { &k5_atype_as_req_1, &k5_atype_as_req_2, &k5_atype_as_req_3, &k5_atype_as_req_4 }; -static unsigned int -optional_as_req(const void *p) -{ - const krb5_kdc_req *val = p; - unsigned int not_present = 0; - if (val->padata == NULL || val->padata[0] == NULL) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(untagged_as_req, krb5_kdc_req, as_req_fields, optional_as_req); +DEFSEQTYPE(untagged_as_req, krb5_kdc_req, as_req_fields); DEFAPPTAGGEDTYPE(as_req, 10, untagged_as_req); /* Most fields are the same as as_req. */ @@ -709,8 +562,7 @@ static const struct atype_info *tgs_req_fields[] = { &k5_atype_as_req_1, &k5_atype_tgs_req_2, &k5_atype_as_req_3, &k5_atype_as_req_4 }; -DEFSEQTYPE(untagged_tgs_req, krb5_kdc_req, tgs_req_fields, - optional_as_req); +DEFSEQTYPE(untagged_tgs_req, krb5_kdc_req, tgs_req_fields); DEFAPPTAGGEDTYPE(tgs_req, 12, untagged_tgs_req); DEFINT_IMMEDIATE(safe_msg_type, ASN1_KRB_SAFE); @@ -721,7 +573,7 @@ DEFFIELD(safe_3, krb5_safe, checksum, 3, checksum_ptr); static const struct atype_info *safe_fields[] = { &k5_atype_safe_0, &k5_atype_safe_1, &k5_atype_safe_2, &k5_atype_safe_3 }; -DEFSEQTYPE(untagged_safe, krb5_safe, safe_fields, NULL); +DEFSEQTYPE(untagged_safe, krb5_safe, safe_fields); DEFAPPTAGGEDTYPE(safe, 20, untagged_safe); /* Hack to encode a KRB-SAFE with a pre-specified body encoding. The integer- @@ -738,7 +590,7 @@ static const struct atype_info *safe_with_body_fields[] = { &k5_atype_safe_with_body_3 }; DEFSEQTYPE(untagged_safe_with_body, struct krb5_safe_with_body, - safe_with_body_fields, NULL); + safe_with_body_fields); DEFAPPTAGGEDTYPE(safe_with_body, 20, untagged_safe_with_body); /* Third tag is [3] instead of [2]. */ @@ -749,35 +601,28 @@ DEFFIELD(priv_3, krb5_priv, enc_part, 3, encrypted_data); static const struct atype_info *priv_fields[] = { &k5_atype_priv_0, &k5_atype_priv_1, &k5_atype_priv_3 }; -DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields, NULL); +DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields); DEFAPPTAGGEDTYPE(priv, 21, untagged_priv); +static int +is_priv_timestamp_set(const void *p) +{ + const krb5_priv_enc_part *val = p; + return (val->timestamp != 0); +} DEFFIELD(priv_enc_part_0, krb5_priv_enc_part, user_data, 0, ostring_data); -DEFFIELD(priv_enc_part_1, krb5_priv_enc_part, timestamp, 1, kerberos_time); -DEFFIELD(priv_enc_part_2, krb5_priv_enc_part, usec, 2, int32); -DEFFIELD(priv_enc_part_3, krb5_priv_enc_part, seq_number, 3, uint); +DEFFIELD(priv_enc_part_1, krb5_priv_enc_part, timestamp, 1, opt_kerberos_time); +DEFFIELD(priv_enc_part_2_def, krb5_priv_enc_part, usec, 2, int32); +DEFOPTIONALTYPE(priv_enc_part_2, is_priv_timestamp_set, priv_enc_part_2_def); +DEFFIELD(priv_enc_part_3, krb5_priv_enc_part, seq_number, 3, opt_ui_4); DEFFIELD(priv_enc_part_4, krb5_priv_enc_part, s_address, 4, address_ptr); -DEFFIELD(priv_enc_part_5, krb5_priv_enc_part, r_address, 5, address_ptr); +DEFFIELD(priv_enc_part_5, krb5_priv_enc_part, r_address, 5, opt_address_ptr); static const struct atype_info *priv_enc_part_fields[] = { &k5_atype_priv_enc_part_0, &k5_atype_priv_enc_part_1, &k5_atype_priv_enc_part_2, &k5_atype_priv_enc_part_3, &k5_atype_priv_enc_part_4, &k5_atype_priv_enc_part_5 }; -static unsigned int -optional_priv_enc_part(const void *p) -{ - const krb5_priv_enc_part *val = p; - unsigned int not_present = 0; - if (val->timestamp == 0) - not_present |= (1u << 2) | (1u << 1); - if (val->seq_number == 0) - not_present |= (1u << 3); - if (val->r_address == NULL) - not_present |= (1u << 5); - return not_present; -} -DEFSEQTYPE(untagged_priv_enc_part, krb5_priv_enc_part, priv_enc_part_fields, - optional_priv_enc_part); +DEFSEQTYPE(untagged_priv_enc_part, krb5_priv_enc_part, priv_enc_part_fields); DEFAPPTAGGEDTYPE(priv_enc_part, 28, untagged_priv_enc_part); DEFINT_IMMEDIATE(cred_msg_type, ASN1_KRB_CRED); @@ -788,95 +633,60 @@ DEFFIELD(cred_3, krb5_cred, enc_part, 3, encrypted_data); static const struct atype_info *cred_fields[] = { &k5_atype_cred_0, &k5_atype_cred_1, &k5_atype_cred_2, &k5_atype_cred_3 }; -DEFSEQTYPE(untagged_cred, krb5_cred, cred_fields, NULL); +DEFSEQTYPE(untagged_cred, krb5_cred, cred_fields); DEFAPPTAGGEDTYPE(krb5_cred, 22, untagged_cred); +static int +is_cred_timestamp_set(const void *p) +{ + const krb5_cred_enc_part *val = p; + return (val->timestamp != 0); +} DEFFIELD(enc_cred_part_0, krb5_cred_enc_part, ticket_info, 0, ptrseqof_cred_info); -DEFFIELD(enc_cred_part_1, krb5_cred_enc_part, nonce, 1, int32); -DEFFIELD(enc_cred_part_2, krb5_cred_enc_part, timestamp, 2, kerberos_time); -DEFFIELD(enc_cred_part_3, krb5_cred_enc_part, usec, 3, int32); -DEFFIELD(enc_cred_part_4, krb5_cred_enc_part, s_address, 4, address_ptr); -DEFFIELD(enc_cred_part_5, krb5_cred_enc_part, r_address, 5, address_ptr); +DEFFIELD(enc_cred_part_1, krb5_cred_enc_part, nonce, 1, opt_int32); +DEFFIELD(enc_cred_part_2, krb5_cred_enc_part, timestamp, 2, opt_kerberos_time); +DEFFIELD(enc_cred_part_3_def, krb5_cred_enc_part, usec, 3, int32); +DEFOPTIONALTYPE(enc_cred_part_3, is_cred_timestamp_set, enc_cred_part_3_def); +DEFFIELD(enc_cred_part_4, krb5_cred_enc_part, s_address, 4, opt_address_ptr); +DEFFIELD(enc_cred_part_5, krb5_cred_enc_part, r_address, 5, opt_address_ptr); static const struct atype_info *enc_cred_part_fields[] = { &k5_atype_enc_cred_part_0, &k5_atype_enc_cred_part_1, &k5_atype_enc_cred_part_2, &k5_atype_enc_cred_part_3, &k5_atype_enc_cred_part_4, &k5_atype_enc_cred_part_5 }; -static unsigned int -optional_enc_cred_part(const void *p) -{ - const krb5_cred_enc_part *val = p; - unsigned int not_present = 0; - if (val->r_address == NULL) - not_present |= (1u << 5); - if (val->s_address == NULL) - not_present |= (1u << 4); - if (val->timestamp == 0) - not_present |= (1u << 2) | (1u << 3); - if (val->nonce == 0) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(untagged_enc_cred_part, krb5_cred_enc_part, enc_cred_part_fields, - optional_enc_cred_part); +DEFSEQTYPE(untagged_enc_cred_part, krb5_cred_enc_part, enc_cred_part_fields); DEFAPPTAGGEDTYPE(enc_cred_part, 29, untagged_enc_cred_part); DEFINT_IMMEDIATE(error_msg_type, ASN1_KRB_ERROR); DEFCTAGGEDTYPE(error_0, 0, krb5_version); DEFCTAGGEDTYPE(error_1, 1, error_msg_type); -DEFFIELD(error_2, krb5_error, ctime, 2, kerberos_time); -DEFFIELD(error_3, krb5_error, cusec, 3, int32); +DEFFIELD(error_2, krb5_error, ctime, 2, opt_kerberos_time); +DEFFIELD(error_3, krb5_error, cusec, 3, opt_int32); DEFFIELD(error_4, krb5_error, stime, 4, kerberos_time); DEFFIELD(error_5, krb5_error, susec, 5, int32); DEFFIELD(error_6, krb5_error, error, 6, ui_4); -DEFFIELD(error_7, krb5_error, client, 7, realm_of_principal); -DEFFIELD(error_8, krb5_error, client, 8, principal); +DEFFIELD(error_7, krb5_error, client, 7, opt_realm_of_principal); +DEFFIELD(error_8, krb5_error, client, 8, opt_principal); DEFFIELD(error_9, krb5_error, server, 9, realm_of_principal); DEFFIELD(error_10, krb5_error, server, 10, principal); -DEFFIELD(error_11, krb5_error, text, 11, gstring_data); -DEFFIELD(error_12, krb5_error, e_data, 12, ostring_data); +DEFFIELD(error_11, krb5_error, text, 11, opt_gstring_data); +DEFFIELD(error_12, krb5_error, e_data, 12, opt_ostring_data); static const struct atype_info *error_fields[] = { &k5_atype_error_0, &k5_atype_error_1, &k5_atype_error_2, &k5_atype_error_3, &k5_atype_error_4, &k5_atype_error_5, &k5_atype_error_6, &k5_atype_error_7, &k5_atype_error_8, &k5_atype_error_9, &k5_atype_error_10, &k5_atype_error_11, &k5_atype_error_12 }; -static unsigned int -optional_error(const void *p) -{ - const krb5_error *val = p; - unsigned int not_present = 0; - if (val->ctime == 0) - not_present |= (1u << 2); - if (val->cusec == 0) - not_present |= (1u << 3); - if (val->client == NULL) - not_present |= (1u << 7) | (1u << 8); - if (val->text.data == NULL || val->text.length == 0) - not_present |= (1u << 11); - if (val->e_data.data == NULL || val->e_data.length == 0) - not_present |= (1u << 12); - return not_present; -} -DEFSEQTYPE(untagged_krb5_error, krb5_error, error_fields, optional_error); +DEFSEQTYPE(untagged_krb5_error, krb5_error, error_fields); DEFAPPTAGGEDTYPE(krb5_error, 30, untagged_krb5_error); DEFFIELD(pa_enc_ts_0, krb5_pa_enc_ts, patimestamp, 0, kerberos_time); -DEFFIELD(pa_enc_ts_1, krb5_pa_enc_ts, pausec, 1, int32); +DEFFIELD(pa_enc_ts_1, krb5_pa_enc_ts, pausec, 1, opt_int32); static const struct atype_info *pa_enc_ts_fields[] = { &k5_atype_pa_enc_ts_0, &k5_atype_pa_enc_ts_1 }; -static unsigned int -optional_pa_enc_ts(const void *p) -{ - const krb5_pa_enc_ts *val = p; - unsigned int not_present = 0; - if (val->pausec == 0) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(pa_enc_ts, krb5_pa_enc_ts, pa_enc_ts_fields, optional_pa_enc_ts); +DEFSEQTYPE(pa_enc_ts, krb5_pa_enc_ts, pa_enc_ts_fields); DEFFIELD(setpw_0, struct krb5_setpw_req, password, 0, ostring_data); DEFFIELD(setpw_1, struct krb5_setpw_req, target, 1, principal); @@ -884,7 +694,7 @@ DEFFIELD(setpw_2, struct krb5_setpw_req, target, 2, realm_of_principal); static const struct atype_info *setpw_req_fields[] = { &k5_atype_setpw_0, &k5_atype_setpw_1, &k5_atype_setpw_2 }; -DEFSEQTYPE(setpw_req, struct krb5_setpw_req, setpw_req_fields, NULL); +DEFSEQTYPE(setpw_req, struct krb5_setpw_req, setpw_req_fields); /* [MS-SFU] Section 2.2.1. */ DEFFIELD(pa_for_user_0, krb5_pa_for_user, user, 0, principal); @@ -895,41 +705,34 @@ static const struct atype_info *pa_for_user_fields[] = { &k5_atype_pa_for_user_0, &k5_atype_pa_for_user_1, &k5_atype_pa_for_user_2, &k5_atype_pa_for_user_3, }; -DEFSEQTYPE(pa_for_user, krb5_pa_for_user, pa_for_user_fields, NULL); +DEFSEQTYPE(pa_for_user, krb5_pa_for_user, pa_for_user_fields); /* [MS-SFU] Section 2.2.2. */ +/* The user principal name may be absent, but the realm is required. */ +static int +is_s4u_principal_present(const void *p) +{ + krb5_const_principal val = *(krb5_const_principal *)p; + return (val->length != 0); +} +DEFOPTIONALTYPE(opt_s4u_principal, is_s4u_principal_present, principal); DEFFIELD(s4u_userid_0, krb5_s4u_userid, nonce, 0, int32); -DEFFIELD(s4u_userid_1, krb5_s4u_userid, user, 1, principal); +DEFFIELD(s4u_userid_1, krb5_s4u_userid, user, 1, opt_s4u_principal); DEFFIELD(s4u_userid_2, krb5_s4u_userid, user, 2, realm_of_principal); -DEFFIELD(s4u_userid_3, krb5_s4u_userid, subject_cert, 3, ostring_data); -DEFFIELD(s4u_userid_4, krb5_s4u_userid, options, 4, krb5_flags); +DEFFIELD(s4u_userid_3, krb5_s4u_userid, subject_cert, 3, opt_ostring_data); +DEFFIELD(s4u_userid_4, krb5_s4u_userid, options, 4, opt_krb5_flags); static const struct atype_info *s4u_userid_fields[] = { &k5_atype_s4u_userid_0, &k5_atype_s4u_userid_1, &k5_atype_s4u_userid_2, &k5_atype_s4u_userid_3, &k5_atype_s4u_userid_4 }; -static unsigned int -s4u_userid_optional(const void *p) -{ - const krb5_s4u_userid *val = p; - unsigned int not_present = 0; - if (val->user == NULL || val->user->length == 0) - not_present |= (1u << 1); - if (val->subject_cert.length == 0) - not_present |= (1u << 3); - if (val->options == 0) - not_present |= (1u << 4); - return not_present; -} -DEFSEQTYPE(s4u_userid, krb5_s4u_userid, s4u_userid_fields, - s4u_userid_optional); +DEFSEQTYPE(s4u_userid, krb5_s4u_userid, s4u_userid_fields); DEFFIELD(pa_s4u_x509_user_0, krb5_pa_s4u_x509_user, user_id, 0, s4u_userid); DEFFIELD(pa_s4u_x509_user_1, krb5_pa_s4u_x509_user, cksum, 1, checksum); static const struct atype_info *pa_s4u_x509_user_fields[] = { &k5_atype_pa_s4u_x509_user_0, &k5_atype_pa_s4u_x509_user_1 }; -DEFSEQTYPE(pa_s4u_x509_user, krb5_pa_s4u_x509_user, pa_s4u_x509_user_fields, - NULL); +DEFSEQTYPE(pa_s4u_x509_user, krb5_pa_s4u_x509_user, pa_s4u_x509_user_fields); /* RFC 4537 */ DEFCOUNTEDTYPE(etype_list, krb5_etype_list, etypes, length, cseqof_int32); @@ -940,10 +743,12 @@ DEFFIELD(fast_armor_1, krb5_fast_armor, armor_value, 1, ostring_data); static const struct atype_info *fast_armor_fields[] = { &k5_atype_fast_armor_0, &k5_atype_fast_armor_1 }; -DEFSEQTYPE(fast_armor, krb5_fast_armor, fast_armor_fields, NULL); +DEFSEQTYPE(fast_armor, krb5_fast_armor, fast_armor_fields); DEFPTRTYPE(ptr_fast_armor, fast_armor); +DEFOPTIONALZEROTYPE(opt_ptr_fast_armor, ptr_fast_armor); -DEFFIELD(fast_armored_req_0, krb5_fast_armored_req, armor, 0, ptr_fast_armor); +DEFFIELD(fast_armored_req_0, krb5_fast_armored_req, armor, 0, + opt_ptr_fast_armor); DEFFIELD(fast_armored_req_1, krb5_fast_armored_req, req_checksum, 1, checksum); DEFFIELD(fast_armored_req_2, krb5_fast_armored_req, enc_part, 2, encrypted_data); @@ -951,17 +756,7 @@ static const struct atype_info *fast_armored_req_fields[] = { &k5_atype_fast_armored_req_0, &k5_atype_fast_armored_req_1, &k5_atype_fast_armored_req_2 }; -static unsigned int -fast_armored_req_optional(const void *p) -{ - const krb5_fast_armored_req *val = p; - unsigned int not_present = 0; - if (val->armor == NULL) - not_present |= (1u << 0); - return not_present; -} -DEFSEQTYPE(fast_armored_req, krb5_fast_armored_req, fast_armored_req_fields, - fast_armored_req_optional); +DEFSEQTYPE(fast_armored_req, krb5_fast_armored_req, fast_armored_req_fields); /* This is a CHOICE type with only one choice (so far) and we're not using a * distinguisher/union for it. */ @@ -977,7 +772,7 @@ DEFFIELD(fast_req_2, krb5_fast_req, req_body, 2, ptr_kdc_req_body); static const struct atype_info *fast_req_fields[] = { &k5_atype_fast_req_0, &k5_atype_fast_req_1, &k5_atype_fast_req_2 }; -DEFSEQTYPE(fast_req, krb5_fast_req, fast_req_fields, NULL); +DEFSEQTYPE(fast_req, krb5_fast_req, fast_req_fields); DEFFIELD(fast_finished_0, krb5_fast_finished, timestamp, 0, kerberos_time); DEFFIELD(fast_finished_1, krb5_fast_finished, usec, 1, int32); @@ -989,37 +784,27 @@ static const struct atype_info *fast_finished_fields[] = { &k5_atype_fast_finished_2, &k5_atype_fast_finished_3, &k5_atype_fast_finished_4 }; -DEFSEQTYPE(fast_finished, krb5_fast_finished, fast_finished_fields, NULL); +DEFSEQTYPE(fast_finished, krb5_fast_finished, fast_finished_fields); DEFPTRTYPE(ptr_fast_finished, fast_finished); +DEFOPTIONALZEROTYPE(opt_ptr_fast_finished, ptr_fast_finished); DEFFIELD(fast_response_0, krb5_fast_response, padata, 0, ptr_seqof_pa_data); DEFFIELD(fast_response_1, krb5_fast_response, strengthen_key, 1, - ptr_encryption_key); -DEFFIELD(fast_response_2, krb5_fast_response, finished, 2, ptr_fast_finished); + opt_ptr_encryption_key); +DEFFIELD(fast_response_2, krb5_fast_response, finished, 2, + opt_ptr_fast_finished); DEFFIELD(fast_response_3, krb5_fast_response, nonce, 3, int32); static const struct atype_info *fast_response_fields[] = { &k5_atype_fast_response_0, &k5_atype_fast_response_1, &k5_atype_fast_response_2, &k5_atype_fast_response_3 }; -static unsigned int -fast_response_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_fast_response *val = p; - if (val->strengthen_key == NULL) - not_present |= (1u <<1); - if (val->finished == NULL) - not_present |= (1u<<2); - return not_present; -} -DEFSEQTYPE(fast_response, krb5_fast_response, fast_response_fields, - fast_response_optional); +DEFSEQTYPE(fast_response, krb5_fast_response, fast_response_fields); DEFCTAGGEDTYPE(fast_rep_0, 0, encrypted_data); static const struct atype_info *fast_rep_fields[] = { &k5_atype_fast_rep_0 }; -DEFSEQTYPE(fast_rep, krb5_enc_data, fast_rep_fields, NULL); +DEFSEQTYPE(fast_rep, krb5_enc_data, fast_rep_fields); /* This is a CHOICE type with only one choice (so far) and we're not using a * distinguisher/union for it. */ @@ -1028,111 +813,69 @@ DEFTAGGEDTYPE(pa_fx_fast_reply, CONTEXT_SPECIFIC, CONSTRUCTED, 0, 0, DEFFIELD(ad_kdcissued_0, krb5_ad_kdcissued, ad_checksum, 0, checksum); DEFFIELD(ad_kdcissued_1, krb5_ad_kdcissued, i_principal, 1, - realm_of_principal); -DEFFIELD(ad_kdcissued_2, krb5_ad_kdcissued, i_principal, 2, principal); + opt_realm_of_principal); +DEFFIELD(ad_kdcissued_2, krb5_ad_kdcissued, i_principal, 2, opt_principal); DEFFIELD(ad_kdcissued_3, krb5_ad_kdcissued, elements, 3, auth_data_ptr); static const struct atype_info *ad_kdcissued_fields[] = { &k5_atype_ad_kdcissued_0, &k5_atype_ad_kdcissued_1, &k5_atype_ad_kdcissued_2, &k5_atype_ad_kdcissued_3 }; -static unsigned int -ad_kdcissued_optional(const void *p) -{ - unsigned int optional = 0; - const krb5_ad_kdcissued *val = p; - if (val->i_principal == NULL) - optional |= (1u << 1) | (1u << 2); - return optional; -} -DEFSEQTYPE(ad_kdc_issued, krb5_ad_kdcissued, ad_kdcissued_fields, - ad_kdcissued_optional); +DEFSEQTYPE(ad_kdc_issued, krb5_ad_kdcissued, ad_kdcissued_fields); DEFCTAGGEDTYPE(princ_plus_realm_0, 0, principal_data); DEFCTAGGEDTYPE(princ_plus_realm_1, 1, realm_of_principal_data); static const struct atype_info *princ_plus_realm_fields[] = { &k5_atype_princ_plus_realm_0, &k5_atype_princ_plus_realm_1 }; -DEFSEQTYPE(princ_plus_realm_data, krb5_principal_data, princ_plus_realm_fields, - NULL); +DEFSEQTYPE(princ_plus_realm_data, krb5_principal_data, + princ_plus_realm_fields); DEFPTRTYPE(princ_plus_realm, princ_plus_realm_data); DEFNULLTERMSEQOFTYPE(seqof_princ_plus_realm, princ_plus_realm); DEFPTRTYPE(ptr_seqof_princ_plus_realm, seqof_princ_plus_realm); +DEFOPTIONALEMPTYTYPE(opt_ptr_seqof_princ_plus_realm, + ptr_seqof_princ_plus_realm); DEFFIELD(spdata_0, krb5_ad_signedpath_data, client, 0, princ_plus_realm); DEFFIELD(spdata_1, krb5_ad_signedpath_data, authtime, 1, kerberos_time); DEFFIELD(spdata_2, krb5_ad_signedpath_data, delegated, 2, - ptr_seqof_princ_plus_realm); -DEFFIELD(spdata_3, krb5_ad_signedpath_data, method_data, 3, ptr_seqof_pa_data); + opt_ptr_seqof_princ_plus_realm); +DEFFIELD(spdata_3, krb5_ad_signedpath_data, method_data, 3, + opt_ptr_seqof_pa_data); DEFFIELD(spdata_4, krb5_ad_signedpath_data, authorization_data, 4, - auth_data_ptr); + opt_auth_data_ptr); static const struct atype_info *ad_signedpath_data_fields[] = { &k5_atype_spdata_0, &k5_atype_spdata_1, &k5_atype_spdata_2, &k5_atype_spdata_3, &k5_atype_spdata_4 }; -static unsigned int -ad_signedpath_data_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_ad_signedpath_data *val = p; - if (val->delegated == NULL || val->delegated[0] == NULL) - not_present |= (1u << 2); - if (val->method_data == NULL || val->method_data[0] == NULL) - not_present |= (1u << 3); - if (val->authorization_data == NULL || val->authorization_data[0] == NULL) - not_present |= (1u << 4); - return not_present; -} DEFSEQTYPE(ad_signedpath_data, krb5_ad_signedpath_data, - ad_signedpath_data_fields, ad_signedpath_data_optional); + ad_signedpath_data_fields); DEFFIELD(signedpath_0, krb5_ad_signedpath, enctype, 0, int32); DEFFIELD(signedpath_1, krb5_ad_signedpath, checksum, 1, checksum); DEFFIELD(signedpath_2, krb5_ad_signedpath, delegated, 2, - ptr_seqof_princ_plus_realm); -DEFFIELD(signedpath_3, krb5_ad_signedpath, method_data, 3, ptr_seqof_pa_data); + opt_ptr_seqof_princ_plus_realm); +DEFFIELD(signedpath_3, krb5_ad_signedpath, method_data, 3, + opt_ptr_seqof_pa_data); static const struct atype_info *ad_signedpath_fields[] = { &k5_atype_signedpath_0, &k5_atype_signedpath_1, &k5_atype_signedpath_2, &k5_atype_signedpath_3 }; -static unsigned int -ad_signedpath_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_ad_signedpath *val = p; - if (val->delegated == NULL || val->delegated[0] == NULL) - not_present |= (1u << 2); - if (val->method_data == NULL || val->method_data[0] == NULL) - not_present |= (1u << 3); - return not_present; -} -DEFSEQTYPE(ad_signedpath, krb5_ad_signedpath, ad_signedpath_fields, - ad_signedpath_optional); +DEFSEQTYPE(ad_signedpath, krb5_ad_signedpath, ad_signedpath_fields); /* First context tag is 1, not 0. */ DEFFIELD(iakerb_header_1, krb5_iakerb_header, target_realm, 1, ostring_data); -DEFFIELD(iakerb_header_2, krb5_iakerb_header, cookie, 2, ostring_data_ptr); +DEFFIELD(iakerb_header_2, krb5_iakerb_header, cookie, 2, opt_ostring_data_ptr); static const struct atype_info *iakerb_header_fields[] = { &k5_atype_iakerb_header_1, &k5_atype_iakerb_header_2 }; -static unsigned int -iakerb_header_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_iakerb_header *val = p; - if (val->cookie == NULL || val->cookie->data == NULL) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(iakerb_header, krb5_iakerb_header, iakerb_header_fields, - iakerb_header_optional); +DEFSEQTYPE(iakerb_header, krb5_iakerb_header, iakerb_header_fields); /* First context tag is 1, not 0. */ DEFFIELD(iakerb_finished_0, krb5_iakerb_finished, checksum, 1, checksum); static const struct atype_info *iakerb_finished_fields[] = { &k5_atype_iakerb_finished_0 }; -DEFSEQTYPE(iakerb_finished, krb5_iakerb_finished, iakerb_finished_fields, - NULL); +DEFSEQTYPE(iakerb_finished, krb5_iakerb_finished, iakerb_finished_fields); /* Exported complete encoders -- these produce a krb5_data with the encoding in the correct byte order. */ @@ -1210,31 +953,24 @@ DEFPTRTYPE(oid_data_ptr, oid_data); /* RFC 3280. No context tags. */ DEFOFFSETTYPE(algid_0, krb5_algorithm_identifier, algorithm, oid_data); -DEFOFFSETTYPE(algid_1, krb5_algorithm_identifier, parameters, der_data); +DEFOFFSETTYPE(algid_1, krb5_algorithm_identifier, parameters, opt_der_data); static const struct atype_info *algorithm_identifier_fields[] = { &k5_atype_algid_0, &k5_atype_algid_1 }; -static unsigned int -algorithm_identifier_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_algorithm_identifier *val = p; - if (val->parameters.length == 0) - not_present |= (1u << 1); - return not_present; -} DEFSEQTYPE(algorithm_identifier, krb5_algorithm_identifier, - algorithm_identifier_fields, algorithm_identifier_optional); + algorithm_identifier_fields); DEFPTRTYPE(algorithm_identifier_ptr, algorithm_identifier); DEFCTAGGEDTYPE(kdf_alg_id_0, 0, oid_data); static const struct atype_info *kdf_alg_id_fields[] = { &k5_atype_kdf_alg_id_0 }; -DEFSEQTYPE(kdf_alg_id, krb5_data, kdf_alg_id_fields, NULL); -DEFPTRTYPE(kdf_alg_id_ptr, kdf_alg_id); -DEFNONEMPTYNULLTERMSEQOFTYPE(supported_kdfs, kdf_alg_id_ptr); -DEFPTRTYPE(supported_kdfs_ptr, supported_kdfs); +DEFSEQTYPE(kdf_alg_id, krb5_data, kdf_alg_id_fields); +DEFPTRTYPE(ptr_kdf_alg_id, kdf_alg_id); +DEFNONEMPTYNULLTERMSEQOFTYPE(supported_kdfs, ptr_kdf_alg_id); +DEFPTRTYPE(ptr_supported_kdfs, supported_kdfs); +DEFOPTIONALZEROTYPE(opt_ptr_kdf_alg_id, ptr_kdf_alg_id); +DEFOPTIONALZEROTYPE(opt_ptr_supported_kdfs, ptr_supported_kdfs); /* KRB5PrincipalName from RFC 4556 (*not* PrincipalName from RFC 4120) */ DEFCTAGGEDTYPE(pkinit_princ_0, 0, realm_of_principal_data); @@ -1243,7 +979,7 @@ static const struct atype_info *pkinit_krb5_principal_name_fields[] = { &k5_atype_pkinit_princ_0, &k5_atype_pkinit_princ_1 }; DEFSEQTYPE(pkinit_krb5_principal_name_data, krb5_principal_data, - pkinit_krb5_principal_name_fields, NULL); + pkinit_krb5_principal_name_fields); DEFPTRTYPE(pkinit_krb5_principal_name, pkinit_krb5_principal_name_data); /* SP80056A OtherInfo, for pkinit agility. No context tag on first field. */ @@ -1261,7 +997,7 @@ static const struct atype_info *sp80056a_other_info_fields[] = { &k5_atype_oinfo_2 }; DEFSEQTYPE(sp80056a_other_info, krb5_sp80056a_other_info, - sp80056a_other_info_fields, NULL); + sp80056a_other_info_fields); /* For PkinitSuppPubInfo, for pkinit agility */ DEFFIELD(supp_pub_0, krb5_pkinit_supp_pub_info, enctype, 0, int32); @@ -1271,7 +1007,7 @@ static const struct atype_info *pkinit_supp_pub_info_fields[] = { &k5_atype_supp_pub_0, &k5_atype_supp_pub_1, &k5_atype_supp_pub_2 }; DEFSEQTYPE(pkinit_supp_pub_info, krb5_pkinit_supp_pub_info, - pkinit_supp_pub_info_fields, NULL); + pkinit_supp_pub_info_fields); MAKE_ENCODER(encode_krb5_pkinit_supp_pub_info, pkinit_supp_pub_info); MAKE_ENCODER(encode_krb5_sp80056a_other_info, sp80056a_other_info); @@ -1288,8 +1024,7 @@ static const struct atype_info *pk_authenticator_fields[] = { &k5_atype_pk_authenticator_0, &k5_atype_pk_authenticator_1, &k5_atype_pk_authenticator_2, &k5_atype_pk_authenticator_3 }; -DEFSEQTYPE(pk_authenticator, krb5_pk_authenticator, pk_authenticator_fields, - NULL); +DEFSEQTYPE(pk_authenticator, krb5_pk_authenticator, pk_authenticator_fields); DEFFIELD(pkauth9_0, krb5_pk_authenticator_draft9, kdcName, 0, principal); DEFFIELD(pkauth9_1, krb5_pk_authenticator_draft9, kdcName, 1, @@ -1302,7 +1037,7 @@ static const struct atype_info *pk_authenticator_draft9_fields[] = { &k5_atype_pkauth9_3, &k5_atype_pkauth9_4 }; DEFSEQTYPE(pk_authenticator_draft9, krb5_pk_authenticator_draft9, - pk_authenticator_draft9_fields, NULL); + pk_authenticator_draft9_fields); DEFCOUNTEDSTRINGTYPE(s_bitstring, char *, unsigned int, k5_asn1_encode_bitstring, ASN1_BITSTRING); @@ -1314,113 +1049,68 @@ DEFOFFSETTYPE(spki_1, krb5_subject_pk_info, subjectPublicKey, bitstring_data); static const struct atype_info *subject_pk_info_fields[] = { &k5_atype_spki_0, &k5_atype_spki_1 }; -DEFSEQTYPE(subject_pk_info, krb5_subject_pk_info, subject_pk_info_fields, - NULL); +DEFSEQTYPE(subject_pk_info, krb5_subject_pk_info, subject_pk_info_fields); DEFPTRTYPE(subject_pk_info_ptr, subject_pk_info); +DEFOPTIONALZEROTYPE(opt_subject_pk_info_ptr, subject_pk_info_ptr); DEFNULLTERMSEQOFTYPE(seqof_algorithm_identifier, algorithm_identifier_ptr); DEFPTRTYPE(ptr_seqof_algorithm_identifier, seqof_algorithm_identifier); +DEFOPTIONALZEROTYPE(opt_ptr_seqof_algorithm_identifier, + ptr_seqof_algorithm_identifier); DEFFIELD(auth_pack_0, krb5_auth_pack, pkAuthenticator, 0, pk_authenticator); DEFFIELD(auth_pack_1, krb5_auth_pack, clientPublicValue, 1, - subject_pk_info_ptr); + opt_subject_pk_info_ptr); DEFFIELD(auth_pack_2, krb5_auth_pack, supportedCMSTypes, 2, - ptr_seqof_algorithm_identifier); -DEFFIELD(auth_pack_3, krb5_auth_pack, clientDHNonce, 3, ostring_data); -DEFFIELD(auth_pack_4, krb5_auth_pack, supportedKDFs, 4, supported_kdfs_ptr); + opt_ptr_seqof_algorithm_identifier); +DEFFIELD(auth_pack_3, krb5_auth_pack, clientDHNonce, 3, opt_ostring_data); +DEFFIELD(auth_pack_4, krb5_auth_pack, supportedKDFs, 4, + opt_ptr_supported_kdfs); static const struct atype_info *auth_pack_fields[] = { &k5_atype_auth_pack_0, &k5_atype_auth_pack_1, &k5_atype_auth_pack_2, &k5_atype_auth_pack_3, &k5_atype_auth_pack_4 }; -static unsigned int -auth_pack_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_auth_pack *val = p; - if (val->clientPublicValue == NULL) - not_present |= (1u << 1); - if (val->supportedCMSTypes == NULL) - not_present |= (1u << 2); - if (val->clientDHNonce.length == 0) - not_present |= (1u << 3); - if (val->supportedKDFs == NULL) - not_present |= (1u << 4); - return not_present; -} -DEFSEQTYPE(auth_pack, krb5_auth_pack, auth_pack_fields, auth_pack_optional); +DEFSEQTYPE(auth_pack, krb5_auth_pack, auth_pack_fields); DEFFIELD(auth_pack9_0, krb5_auth_pack_draft9, pkAuthenticator, 0, pk_authenticator_draft9); DEFFIELD(auth_pack9_1, krb5_auth_pack_draft9, clientPublicValue, 1, - subject_pk_info_ptr); + opt_subject_pk_info_ptr); static const struct atype_info *auth_pack_draft9_fields[] = { &k5_atype_auth_pack9_0, &k5_atype_auth_pack9_1 }; -static unsigned int -auth_pack_draft9_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_auth_pack_draft9 *val = p; - if (val->clientPublicValue == NULL) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(auth_pack_draft9, krb5_auth_pack_draft9, auth_pack_draft9_fields, - auth_pack_draft9_optional); +DEFSEQTYPE(auth_pack_draft9, krb5_auth_pack_draft9, auth_pack_draft9_fields); DEFFIELD_IMPLICIT(extprinc_0, krb5_external_principal_identifier, - subjectName, 0, ostring_data); + subjectName, 0, opt_ostring_data); DEFFIELD_IMPLICIT(extprinc_1, krb5_external_principal_identifier, - issuerAndSerialNumber, 1, ostring_data); + issuerAndSerialNumber, 1, opt_ostring_data); DEFFIELD_IMPLICIT(extprinc_2, krb5_external_principal_identifier, - subjectKeyIdentifier, 2, ostring_data); + subjectKeyIdentifier, 2, opt_ostring_data); static const struct atype_info *external_principal_identifier_fields[] = { &k5_atype_extprinc_0, &k5_atype_extprinc_1, &k5_atype_extprinc_2 }; -static unsigned int -external_principal_identifier_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_external_principal_identifier *val = p; - if (val->subjectName.length == 0) - not_present |= (1u << 0); - if (val->issuerAndSerialNumber.length == 0) - not_present |= (1u << 1); - if (val->subjectKeyIdentifier.length == 0) - not_present |= (1u << 2); - return not_present; -} DEFSEQTYPE(external_principal_identifier, krb5_external_principal_identifier, - external_principal_identifier_fields, - external_principal_identifier_optional); + external_principal_identifier_fields); DEFPTRTYPE(external_principal_identifier_ptr, external_principal_identifier); DEFNULLTERMSEQOFTYPE(seqof_external_principal_identifier, external_principal_identifier_ptr); DEFPTRTYPE(ptr_seqof_external_principal_identifier, seqof_external_principal_identifier); +DEFOPTIONALZEROTYPE(opt_ptr_seqof_external_principal_identifier, + ptr_seqof_external_principal_identifier); DEFFIELD_IMPLICIT(pa_pk_as_req_0, krb5_pa_pk_as_req, signedAuthPack, 0, ostring_data); DEFFIELD(pa_pk_as_req_1, krb5_pa_pk_as_req, trustedCertifiers, 1, - ptr_seqof_external_principal_identifier); -DEFFIELD_IMPLICIT(pa_pk_as_req_2, krb5_pa_pk_as_req, kdcPkId, 2, ostring_data); + opt_ptr_seqof_external_principal_identifier); +DEFFIELD_IMPLICIT(pa_pk_as_req_2, krb5_pa_pk_as_req, kdcPkId, 2, + opt_ostring_data); static const struct atype_info *pa_pk_as_req_fields[] = { &k5_atype_pa_pk_as_req_0, &k5_atype_pa_pk_as_req_1, &k5_atype_pa_pk_as_req_2 }; -static unsigned int -pa_pk_as_req_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_pa_pk_as_req *val = p; - if (val->trustedCertifiers == NULL) - not_present |= (1u << 1); - if (val->kdcPkId.length == 0) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(pa_pk_as_req, krb5_pa_pk_as_req, pa_pk_as_req_fields, - pa_pk_as_req_optional); +DEFSEQTYPE(pa_pk_as_req, krb5_pa_pk_as_req, pa_pk_as_req_fields); /* * In draft-ietf-cat-kerberos-pk-init-09, this sequence has four fields, but we @@ -1432,67 +1122,37 @@ DEFSEQTYPE(pa_pk_as_req, krb5_pa_pk_as_req, pa_pk_as_req_fields, DEFFIELD_IMPLICIT(pa_pk_as_req9_0, krb5_pa_pk_as_req_draft9, signedAuthPack, 0, ostring_data); DEFFIELD_IMPLICIT(pa_pk_as_req9_2, krb5_pa_pk_as_req_draft9, kdcCert, 2, - ostring_data); + opt_ostring_data); static const struct atype_info *pa_pk_as_req_draft9_fields[] = { &k5_atype_pa_pk_as_req9_0, &k5_atype_pa_pk_as_req9_2 }; -static unsigned int -pa_pk_as_req_draft9_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_pa_pk_as_req_draft9 *val = p; - if (val->kdcCert.length == 0) - not_present |= (1u << 1); - return not_present; -} DEFSEQTYPE(pa_pk_as_req_draft9, krb5_pa_pk_as_req_draft9, - pa_pk_as_req_draft9_fields, pa_pk_as_req_draft9_optional); + pa_pk_as_req_draft9_fields); DEFFIELD_IMPLICIT(dh_rep_info_0, krb5_dh_rep_info, dhSignedData, 0, ostring_data); -DEFFIELD(dh_rep_info_1, krb5_dh_rep_info, serverDHNonce, 1, ostring_data); -DEFFIELD(dh_rep_info_2, krb5_dh_rep_info, kdfID, 2, kdf_alg_id_ptr); +DEFFIELD(dh_rep_info_1, krb5_dh_rep_info, serverDHNonce, 1, opt_ostring_data); +DEFFIELD(dh_rep_info_2, krb5_dh_rep_info, kdfID, 2, opt_ptr_kdf_alg_id); static const struct atype_info *dh_rep_info_fields[] = { &k5_atype_dh_rep_info_0, &k5_atype_dh_rep_info_1, &k5_atype_dh_rep_info_2 }; -static unsigned int -dh_rep_info_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_dh_rep_info *val = p; - if (val->serverDHNonce.length == 0) - not_present |= (1u << 1); - if (val->kdfID == NULL) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(dh_rep_info, krb5_dh_rep_info, dh_rep_info_fields, - dh_rep_info_optional); +DEFSEQTYPE(dh_rep_info, krb5_dh_rep_info, dh_rep_info_fields); DEFFIELD(dh_key_0, krb5_kdc_dh_key_info, subjectPublicKey, 0, bitstring_data); DEFFIELD(dh_key_1, krb5_kdc_dh_key_info, nonce, 1, int32); -DEFFIELD(dh_key_2, krb5_kdc_dh_key_info, dhKeyExpiration, 2, kerberos_time); +DEFFIELD(dh_key_2, krb5_kdc_dh_key_info, dhKeyExpiration, 2, + opt_kerberos_time); static const struct atype_info *kdc_dh_key_info_fields[] = { &k5_atype_dh_key_0, &k5_atype_dh_key_1, &k5_atype_dh_key_2 }; -static unsigned int -kdc_dh_key_info_optional(const void *p) -{ - unsigned int not_present = 0; - const krb5_kdc_dh_key_info *val = p; - if (val->dhKeyExpiration == 0) - not_present |= (1u << 2); - return not_present; -} -DEFSEQTYPE(kdc_dh_key_info, krb5_kdc_dh_key_info, kdc_dh_key_info_fields, - kdc_dh_key_info_optional); +DEFSEQTYPE(kdc_dh_key_info, krb5_kdc_dh_key_info, kdc_dh_key_info_fields); DEFFIELD(reply_key_pack_0, krb5_reply_key_pack, replyKey, 0, encryption_key); DEFFIELD(reply_key_pack_1, krb5_reply_key_pack, asChecksum, 1, checksum); static const struct atype_info *reply_key_pack_fields[] = { &k5_atype_reply_key_pack_0, &k5_atype_reply_key_pack_1 }; -DEFSEQTYPE(reply_key_pack, krb5_reply_key_pack, reply_key_pack_fields, NULL); +DEFSEQTYPE(reply_key_pack, krb5_reply_key_pack, reply_key_pack_fields); DEFFIELD(key_pack9_0, krb5_reply_key_pack_draft9, replyKey, 0, encryption_key); DEFFIELD(key_pack9_1, krb5_reply_key_pack_draft9, nonce, 1, int32); @@ -1500,7 +1160,7 @@ static const struct atype_info *reply_key_pack_draft9_fields[] = { &k5_atype_key_pack9_0, &k5_atype_key_pack9_1 }; DEFSEQTYPE(reply_key_pack_draft9, krb5_reply_key_pack_draft9, - reply_key_pack_draft9_fields, NULL); + reply_key_pack_draft9_fields); DEFCTAGGEDTYPE(pa_pk_as_rep_0, 0, dh_rep_info); DEFCTAGGEDTYPE_IMPLICIT(pa_pk_as_rep_1, 1, ostring_data); @@ -1571,7 +1231,7 @@ DEFCNFIELD(typed_data_1, krb5_pa_data, contents, length, 1, octetstring); static const struct atype_info *typed_data_fields[] = { &k5_atype_typed_data_0, &k5_atype_typed_data_1 }; -DEFSEQTYPE(typed_data, krb5_pa_data, typed_data_fields, NULL); +DEFSEQTYPE(typed_data, krb5_pa_data, typed_data_fields); DEFPTRTYPE(typed_data_ptr, typed_data); DEFNULLTERMSEQOFTYPE(seqof_typed_data, typed_data_ptr); diff --git a/src/lib/krb5/asn.1/ldap_key_seq.c b/src/lib/krb5/asn.1/ldap_key_seq.c index 2c34091e4..f407d9809 100644 --- a/src/lib/krb5/asn.1/ldap_key_seq.c +++ b/src/lib/krb5/asn.1/ldap_key_seq.c @@ -57,22 +57,21 @@ DEFINTTYPE(int16, krb5_int16); DEFCOUNTEDSTRINGTYPE(ui2_octetstring, unsigned char *, krb5_ui_2, k5_asn1_encode_bytestring, ASN1_OCTETSTRING); +static int +is_salt_present(const void *p) +{ + const krb5_key_data *val = p; + return (val->key_data_length[1] != 0); +} +DEFCOUNTEDTYPE(krbsalt_salt, krb5_key_data, key_data_contents[1], + key_data_length[1], ui2_octetstring); +DEFOPTIONALTYPE(krbsalt_salt_if_present, is_salt_present, krbsalt_salt); DEFFIELD(krbsalt_0, krb5_key_data, key_data_type[1], 0, int16); -DEFCNFIELD(krbsalt_1, krb5_key_data, key_data_contents[1], key_data_length[1], - 1, ui2_octetstring); +DEFCTAGGEDTYPE(krbsalt_1, 1, krbsalt_salt_if_present); static const struct atype_info *krbsalt_fields[] = { &k5_atype_krbsalt_0, &k5_atype_krbsalt_1 }; -static unsigned int -optional_krbsalt (const void *p) -{ - const krb5_key_data *k = p; - unsigned int not_present = 0; - if (k->key_data_length[1] == 0) - not_present |= (1u << 1); - return not_present; -} -DEFSEQTYPE(krbsalt, krb5_key_data, krbsalt_fields, optional_krbsalt); +DEFSEQTYPE(krbsalt, krb5_key_data, krbsalt_fields); DEFFIELD(encryptionkey_0, krb5_key_data, key_data_type[0], 0, int16); DEFCNFIELD(encryptionkey_1, krb5_key_data, key_data_contents[0], @@ -80,7 +79,7 @@ DEFCNFIELD(encryptionkey_1, krb5_key_data, key_data_contents[0], static const struct atype_info *encryptionkey_fields[] = { &k5_atype_encryptionkey_0, &k5_atype_encryptionkey_1 }; -DEFSEQTYPE(encryptionkey, krb5_key_data, encryptionkey_fields, NULL); +DEFSEQTYPE(encryptionkey, krb5_key_data, encryptionkey_fields); DEFCTAGGEDTYPE(key_data_0, 0, krbsalt); DEFCTAGGEDTYPE(key_data_1, 1, encryptionkey); @@ -90,7 +89,7 @@ DEFCTAGGEDTYPE(key_data_2, 2, s2kparams), static const struct atype_info *key_data_fields[] = { &k5_atype_key_data_0, &k5_atype_key_data_1 }; -DEFSEQTYPE(key_data, krb5_key_data, key_data_fields, 0); +DEFSEQTYPE(key_data, krb5_key_data, key_data_fields); DEFPTRTYPE(ptr_key_data, key_data); DEFCOUNTEDSEQOFTYPE(cseqof_key_data, krb5_int16, ptr_key_data); @@ -109,7 +108,7 @@ static const struct atype_info *ldap_key_seq_fields[] = { &k5_atype_ldap_key_seq_2, &k5_atype_ldap_key_seq_3, &k5_atype_ldap_key_seq_4 }; -DEFSEQTYPE(ldap_key_seq, ldap_seqof_key_data, ldap_key_seq_fields, NULL); +DEFSEQTYPE(ldap_key_seq, ldap_seqof_key_data, ldap_key_seq_fields); /* Export a function to do the whole encoding. */ MAKE_ENCODER(krb5int_ldap_encode_sequence_of_keys, ldap_key_seq); diff --git a/src/lib/krb5/error_tables/asn1_err.et b/src/lib/krb5/error_tables/asn1_err.et index 06078ffbc..30c435641 100644 --- a/src/lib/krb5/error_tables/asn1_err.et +++ b/src/lib/krb5/error_tables/asn1_err.et @@ -12,4 +12,5 @@ error_code ASN1_PARSE_ERROR, "ASN.1 parse error" error_code ASN1_BAD_GMTIME, "ASN.1 bad return from gmtime" error_code ASN1_MISMATCH_INDEF, "ASN.1 non-constructed indefinite encoding" error_code ASN1_MISSING_EOC, "ASN.1 missing expected EOC" +error_code ASN1_OMITTED, "ASN.1 object omitted in sequence" end -- 2.26.2