diff options
author | Tom Yu <tlyu@mit.edu> | 2009-11-16 16:48:37 +0000 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2009-11-16 16:48:37 +0000 |
commit | 409bcfb8f5a21d257e506e8b92bf025522878919 (patch) | |
tree | d43ad40cabe26058f7d2df8217f6a9ee31825e2d /src | |
parent | e1cfc10df16d9319405fd101c21bf328515fa3a3 (diff) | |
download | krb5-409bcfb8f5a21d257e506e8b92bf025522878919.zip krb5-409bcfb8f5a21d257e506e8b92bf025522878919.tar.gz krb5-409bcfb8f5a21d257e506e8b92bf025522878919.tar.bz2 |
Fix coding style in lib/krb5/asn.1, remove from exclusions, and
reindent.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23236 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.in | 6 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_decode.h | 65 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_encode.h | 725 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_k_decode.c | 19 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_k_encode.c | 284 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_make.h | 126 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1buf.c | 58 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1buf.h | 376 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/krb5_decode.c | 336 |
9 files changed, 1080 insertions, 915 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 90be763..639243e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -688,12 +688,6 @@ OTHEREXCLUDES = \ include/iprop.h \ include/k5-platform.h \ include/gssrpc \ - lib/krb5/asn.1/asn1_decode.h \ - lib/krb5/asn.1/asn1_encode.h \ - lib/krb5/asn.1/asn1_k_encode.c \ - lib/krb5/asn.1/asn1_make.h \ - lib/krb5/asn.1/asn1buf.h \ - lib/krb5/asn.1/krb5_decode.c \ lib/krb5/krb/deltat.c \ lib/krb5/unicode diff --git a/src/lib/krb5/asn.1/asn1_decode.h b/src/lib/krb5/asn.1/asn1_decode.h index 016ba2d..09bb641 100644 --- a/src/lib/krb5/asn.1/asn1_decode.h +++ b/src/lib/krb5/asn.1/asn1_decode.h @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * src/lib/krb5/asn.1/asn1_decode.h * @@ -33,32 +33,33 @@ #include "asn1buf.h" /* - Overview - - These procedures take an asn1buf whose current position points - to the beginning of an ASN.1 primitive (<id><length><contents>). - The primitive is removed from the buffer and decoded. - - Operations - - asn1_decode_integer - asn1_decode_unsigned_integer - asn1_decode_octetstring - asn1_decode_charstring - asn1_decode_generalstring - asn1_decode_null - asn1_decode_printablestring - asn1_decode_ia5string - asn1_decode_generaltime -*/ + * Overview + * + * These procedures take an asn1buf whose current position points + * to the beginning of an ASN.1 primitive (<id><length><contents>). + * The primitive is removed from the buffer and decoded. + * + * Operations + * + * asn1_decode_integer + * asn1_decode_unsigned_integer + * asn1_decode_octetstring + * asn1_decode_charstring + * asn1_decode_generalstring + * asn1_decode_null + * asn1_decode_printablestring + * asn1_decode_ia5string + * asn1_decode_generaltime + */ /* asn1_error_code asn1_decode_type(asn1buf *buf, ctype *val); */ -/* requires *buf is allocated - modifies *buf, *len - effects Decodes the octet string in *buf into *val. - Returns ENOMEM if memory is exhausted. - Returns asn1 errors. */ - +/* + * requires *buf is allocated + * modifies *buf, *len + * effects Decodes the octet string in *buf into *val. + * Returns ENOMEM if memory is exhausted. + * Returns asn1 errors. + */ asn1_error_code asn1_decode_boolean(asn1buf *buf, unsigned int *val); asn1_error_code asn1_decode_integer(asn1buf *buf, long *val); @@ -74,12 +75,14 @@ asn1_error_code asn1_decode_generalstring(asn1buf *buf, unsigned int *retlen, char **val); asn1_error_code asn1_decode_charstring(asn1buf *buf, unsigned int *retlen, char **val); -/* Note: A charstring is a special hack to account for the fact that - krb5 structures store some OCTET STRING values in krb5_octet - arrays and others in krb5_data structures - (which use char arrays). - From the ASN.1 point of view, the two string types are the same, - only the receptacles differ. */ +/* + * Note: A charstring is a special hack to account for the fact that + * krb5 structures store some OCTET STRING values in krb5_octet + * arrays and others in krb5_data structures + * (which use char arrays). + * From the ASN.1 point of view, the two string types are the same, + * only the receptacles differ. + */ asn1_error_code asn1_decode_printablestring(asn1buf *buf, int *retlen, char **val); asn1_error_code asn1_decode_ia5string(asn1buf *buf, int *retlen, char **val); diff --git a/src/lib/krb5/asn.1/asn1_encode.h b/src/lib/krb5/asn.1/asn1_encode.h index df971ab..59d53ab 100644 --- a/src/lib/krb5/asn.1/asn1_encode.h +++ b/src/lib/krb5/asn.1/asn1_encode.h @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * src/lib/krb5/asn.1/asn1_encode.h * @@ -34,200 +34,231 @@ #include <time.h> /* - Overview - - Each of these procedures inserts the encoding of an ASN.1 - primitive in a coding buffer. - - Operations - - asn1_encode_boolean - asn1_encode_integer - asn1_encode_unsigned_integer - asn1_encode_octetstring - asn1_encode_generaltime - asn1_encode_generalstring - asn1_encode_bitstring - asn1_encode_oid -*/ + * Overview + * + * Each of these procedures inserts the encoding of an ASN.1 + * primitive in a coding buffer. + * + * Operations + * + * asn1_encode_boolean + * asn1_encode_integer + * asn1_encode_unsigned_integer + * asn1_encode_octetstring + * asn1_encode_generaltime + * asn1_encode_generalstring + * asn1_encode_bitstring + * asn1_encode_oid + */ asn1_error_code asn1_encode_boolean(asn1buf *buf, asn1_intmax val, unsigned int *retlen); asn1_error_code asn1_encode_integer(asn1buf *buf, asn1_intmax val, unsigned int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ asn1_error_code asn1_encode_enumerated(asn1buf *buf, long val, unsigned int *retlen); asn1_error_code asn1_encode_unsigned_integer(asn1buf *buf, asn1_uintmax val, unsigned int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ asn1_error_code asn1_encode_octetstring(asn1buf *buf, unsigned int len, const void *val, unsigned int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ #define asn1_encode_charstring asn1_encode_octetstring asn1_error_code asn1_encode_oid(asn1buf *buf, unsigned int len, const asn1_octet *val, unsigned int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ asn1_error_code asn1_encode_null(asn1buf *buf, int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of NULL into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ - -asn1_error_code asn1_encode_printablestring (asn1buf *buf, unsigned int len, - const char *val, int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ - -asn1_error_code asn1_encode_ia5string - (asn1buf *buf, - unsigned int len, const char *val, - int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ - -asn1_error_code asn1_encode_generaltime - (asn1buf *buf, time_t val, unsigned int *retlen); -/* requires *buf is allocated - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. - Note: The encoding of GeneralizedTime is YYYYMMDDhhmmZ */ - -asn1_error_code asn1_encode_generalstring - (asn1buf *buf, - unsigned int len, const void *val, - unsigned int *retlen); -/* requires *buf is allocated, val has a length of len characters - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of NULL into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ + +asn1_error_code asn1_encode_printablestring(asn1buf *buf, unsigned int len, + const char *val, int *retlen); +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ + +asn1_error_code asn1_encode_ia5string(asn1buf *buf, unsigned int len, + const char *val, int *retlen); +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ + +asn1_error_code asn1_encode_generaltime(asn1buf *buf, time_t val, + unsigned int *retlen); +/* + * requires *buf is allocated + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + * Note: The encoding of GeneralizedTime is YYYYMMDDhhmmZ + */ + +asn1_error_code asn1_encode_generalstring(asn1buf *buf, + unsigned int len, const void *val, + unsigned int *retlen); +/* + * requires *buf is allocated, val has a length of len characters + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ asn1_error_code asn1_encode_bitstring(asn1buf *buf, unsigned int len, const void *val, unsigned int *retlen); -/* requires *buf is allocated, val has a length of len characters - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ +/* + * requires *buf is allocated, val has a length of len characters + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ asn1_error_code asn1_encode_opaque(asn1buf *buf, unsigned int len, const void *val, unsigned int *retlen); -/* requires *buf is allocated, val has a length of len characters - modifies *buf, *retlen - effects Inserts the encoding of val into *buf and returns - the length of the encoding in *retlen. - Returns ENOMEM to signal an unsuccesful attempt - to expand the buffer. */ - -/* Type descriptor info. - - In this context, a "type" is a combination of a C data type - and an ASN.1 encoding scheme for it. So we would have to define - different "types" for: - - * unsigned char* encoded as octet string - * char* encoded as octet string - * char* encoded as generalstring - * krb5_data encoded as octet string - * krb5_data encoded as generalstring - * int32_t encoded as integer - * unsigned char encoded as integer - - Perhaps someday some kind of flags could be defined so that minor - variations on the C types could be handled via common routines. - - The handling of strings is pretty messy. Currently, we have a - separate kind of encoder function that takes an extra length - parameter. Perhaps we should just give up on that, always deal - with just a single location, and handle strings by via encoder - functions for krb5_data, keyblock, etc. - - We wind up with a lot of load-time relocations being done, which is - a bit annoying. Be careful about "fixing" that at the cost of too - much run-time performance. It might work to have a master "module" - descriptor with pointers to various arrays (type descriptors, - strings, field descriptors, functions) most of which don't need - relocation themselves, and replace most of the pointers with table - indices. - - It's a work in progress. */ +/* + * requires *buf is allocated, val has a length of len characters + * modifies *buf, *retlen + * effects Inserts the encoding of val into *buf and returns + * the length of the encoding in *retlen. + * Returns ENOMEM to signal an unsuccesful attempt + * to expand the buffer. + */ + +/* + * Type descriptor info. + * + * In this context, a "type" is a combination of a C data type + * and an ASN.1 encoding scheme for it. So we would have to define + * different "types" for: + * + * * unsigned char* encoded as octet string + * * char* encoded as octet string + * * char* encoded as generalstring + * * krb5_data encoded as octet string + * * krb5_data encoded as generalstring + * * int32_t encoded as integer + * * unsigned char encoded as integer + * + * Perhaps someday some kind of flags could be defined so that minor + * variations on the C types could be handled via common routines. + * + * The handling of strings is pretty messy. Currently, we have a + * separate kind of encoder function that takes an extra length + * parameter. Perhaps we should just give up on that, always deal + * with just a single location, and handle strings by via encoder + * functions for krb5_data, keyblock, etc. + * + * We wind up with a lot of load-time relocations being done, which is + * a bit annoying. Be careful about "fixing" that at the cost of too + * much run-time performance. It might work to have a master "module" + * descriptor with pointers to various arrays (type descriptors, + * strings, field descriptors, functions) most of which don't need + * relocation themselves, and replace most of the pointers with table + * indices. + * + * It's a work in progress. + */ enum atype_type { - /* For bounds checking only. By starting with values above 1, we - guarantee that zero-initialized storage will be recognized as - invalid. */ + /* + * For bounds checking only. By starting with values above 1, we + * guarantee that zero-initialized storage will be recognized as + * invalid. + */ atype_min = 1, /* Encoder function to be called with address of <thing>. */ atype_fn, - /* Encoder function to be called with address of <thing> and a - length (unsigned int). */ + /* + * Encoder function to be called with address of <thing> and a + * length (unsigned int). + */ atype_fn_len, - /* Pointer to actual thing to be encoded. - - Most of the fields are related only to the C type -- size, how - to fetch a pointer in a type-safe fashion -- but since the base - type descriptor encapsulates the encoding as well, different - encodings for the same C type may require different pointer-to - types as well. - - Must not refer to atype_fn_len. */ + /* + * Pointer to actual thing to be encoded. + * + * Most of the fields are related only to the C type -- size, how + * to fetch a pointer in a type-safe fashion -- but since the base + * type descriptor encapsulates the encoding as well, different + * encodings for the same C type may require different pointer-to + * types as well. + * + * Must not refer to atype_fn_len. + */ atype_ptr, /* Sequence, with pointer to sequence descriptor header. */ atype_sequence, - /* Sequence-of, with pointer to base type descriptor, represented - as a null-terminated array of pointers (and thus the "base" - type descriptor is actually an atype_ptr node). */ + /* + * Sequence-of, with pointer to base type descriptor, represented + * as a null-terminated array of pointers (and thus the "base" + * type descriptor is actually an atype_ptr node). + */ atype_nullterm_sequence_of, atype_nonempty_nullterm_sequence_of, - /* Encode this object using a single field descriptor. This may - mean the atype/field breakdown needs revision.... - - Main expected uses: Encode realm component of principal as a - GENERALSTRING. Pluck data and length fields out of a structure - and encode a counted SEQUENCE OF. */ + /* + * Encode this object using a single field descriptor. This may + * mean the atype/field breakdown needs revision.... + * + * Main expected uses: Encode realm component of principal as a + * GENERALSTRING. Pluck data and length fields out of a structure + * and encode a counted SEQUENCE OF. + */ atype_field, /* Tagged version of another type. */ atype_tagged_thing, @@ -238,12 +269,14 @@ enum atype_type { atype_max }; -/* Initialized structures could be a lot smaller if we could use C99 - designated initializers, and a union for all the type-specific - stuff. Maybe use the hack we use for krb5int_access, where we use - a run-time initialize if the compiler doesn't support designated - initializers? That's a lot of work here, though, with so many - little structures. Maybe if/when these get auto-generated. */ +/* + * Initialized structures could be a lot smaller if we could use C99 + * designated initializers, and a union for all the type-specific + * stuff. Maybe use the hack we use for krb5int_access, where we use + * a run-time initialize if the compiler doesn't support designated + * initializers? That's a lot of work here, though, with so many + * little structures. Maybe if/when these get auto-generated. + */ struct atype_info { enum atype_type type; /* used for sequence-of processing */ @@ -268,33 +301,37 @@ struct atype_info { asn1_uintmax (*loaduint)(const void *); }; -/* The various DEF*TYPE macros must: - - + Define a type named aux_typedefname_##DESCNAME, for use in any - types derived from the type being defined. - - + Define an atype_info struct named krb5int_asn1type_##DESCNAME. - - + Define any extra stuff needed in the type descriptor, like - pointer-load functions. - - + Accept a following semicolon syntactically, to keep Emacs parsing - (and indentation calculating) code happy. - - Nothing else should directly define the atype_info structures. */ - -/* Define a type for which we must use an explicit encoder function. - The DEFFNTYPE variant uses a function taking a void*, the - DEFFNXTYPE form wants a function taking a pointer to the actual C - type to be encoded; you should use the latter unless you've already - got the void* function supplied elsewhere. +/* + * The various DEF*TYPE macros must: + * + * + Define a type named aux_typedefname_##DESCNAME, for use in any + * types derived from the type being defined. + * + * + Define an atype_info struct named krb5int_asn1type_##DESCNAME. + * + * + Define any extra stuff needed in the type descriptor, like + * pointer-load functions. + * + * + Accept a following semicolon syntactically, to keep Emacs parsing + * (and indentation calculating) code happy. + * + * Nothing else should directly define the atype_info structures. + */ - Of course, we need a single, consistent type for the descriptor - structure field, so we use the function pointer type that uses - void*, and create a wrapper function in DEFFNXTYPE. However, in - all our cases so far, the supplied function is static and not used - otherwise, so the compiler can merge it with the wrapper function - if the optimizer is good enough. */ +/* + * Define a type for which we must use an explicit encoder function. + * The DEFFNTYPE variant uses a function taking a void*, the + * DEFFNXTYPE form wants a function taking a pointer to the actual C + * type to be encoded; you should use the latter unless you've already + * got the void* function supplied elsewhere. + * + * Of course, we need a single, consistent type for the descriptor + * structure field, so we use the function pointer type that uses + * void*, and create a wrapper function in DEFFNXTYPE. However, in + * all our cases so far, the supplied function is static and not used + * otherwise, so the compiler can merge it with the wrapper function + * if the optimizer is good enough. + */ #define DEFFNTYPE(DESCNAME, CTYPENAME, ENCFN) \ typedef CTYPENAME aux_typedefname_##DESCNAME; \ const struct atype_info krb5int_asn1type_##DESCNAME = { \ @@ -313,18 +350,20 @@ struct atype_info { const struct atype_info krb5int_asn1type_##DESCNAME = { \ atype_fn, sizeof(CTYPENAME), aux_encfn_##DESCNAME, \ } -/* XXX The handling of data+length fields really needs reworking. - A type descriptor probably isn't the right way. - - Also, the C type is likely to be one of char*, unsigned char*, - or (maybe) void*. An enumerator or reference to an external - function would be more compact. - - The supplied encoder function takes as an argument the data pointer - loaded from the indicated location, not the address of the field. - This isn't consistent with DEFFN[X]TYPE above, but all of the uses - of DEFFNLENTYPE are for string encodings, and that's how our - string-encoding primitives work. So be it. */ +/* + * XXX The handling of data+length fields really needs reworking. + * A type descriptor probably isn't the right way. + * + * Also, the C type is likely to be one of char*, unsigned char*, + * or (maybe) void*. An enumerator or reference to an external + * function would be more compact. + * + * The supplied encoder function takes as an argument the data pointer + * loaded from the indicated location, not the address of the field. + * This isn't consistent with DEFFN[X]TYPE above, but all of the uses + * of DEFFNLENTYPE are for string encodings, and that's how our + * string-encoding primitives work. So be it. + */ #ifdef POINTERS_ARE_ALL_THE_SAME #define DEFFNLENTYPE(DESCNAME, CTYPENAME, ENCFN) \ typedef CTYPENAME aux_typedefname_##DESCNAME; \ @@ -344,8 +383,10 @@ struct atype_info { loadptr_for_##DESCNAME \ } #endif -/* A sequence, defined by the indicated series of fields, and an - optional function indicating which fields are present. */ +/* + * A sequence, defined by the indicated series of fields, and an + * optional function indicating which fields are present. + */ #define DEFSEQTYPE(DESCNAME, CTYPENAME, FIELDS, OPT) \ typedef CTYPENAME aux_typedefname_##DESCNAME; \ static const struct seq_info aux_seqinfo_##DESCNAME = { \ @@ -403,16 +444,18 @@ struct atype_info { &krb5int_asn1type_##BASEDESCNAME, 0 \ } #endif -/* 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 - encoded, and encodes a (possibly empty) SEQUENCE OF these objects. - - BASEDESCNAME is a descriptor name for the pointer-to-thing - type. - - When dealing with a structure containing a - pointer-to-pointer-to-thing field, make a DEFPTRTYPE of this type, - and use that type for the structure field. */ +/* + * 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 + * encoded, and encodes a (possibly empty) SEQUENCE OF these objects. + * + * BASEDESCNAME is a descriptor name for the pointer-to-thing + * type. + * + * When dealing with a structure containing a + * pointer-to-pointer-to-thing field, make a DEFPTRTYPE of this type, + * and use that type for the structure field. + */ #define DEFNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME) \ typedef aux_typedefname_##BASEDESCNAME aux_typedefname_##DESCNAME; \ const struct atype_info krb5int_asn1type_##DESCNAME = { \ @@ -430,8 +473,10 @@ struct atype_info { 0 /* loadptr */, \ &krb5int_asn1type_##BASEDESCNAME, 0 \ } -/* Encode a thing (probably sub-fields within the structure) as a - single object. */ +/* + * Encode a thing (probably sub-fields within the structure) as a + * single object. + */ #define DEFFIELDTYPE(DESCNAME, CTYPENAME, FIELDINFO) \ typedef CTYPENAME aux_typedefname_##DESCNAME; \ static const struct field_info aux_fieldinfo_##DESCNAME = FIELDINFO; \ @@ -447,29 +492,33 @@ struct atype_info { 0, 0, 0, &krb5int_asn1type_##BASEDESC, 0, 0, TAG, APPLICATION \ } -/* Declare an externally-defined type. This is a hack we should do - away with once we move to generating code from a script. For now, - this macro is unfortunately not compatible with the defining macros - above, since you can't do the typedefs twice and we need the - declarations to produce typedefs. (We could eliminate the typedefs - from the DEF* macros, but then every DEF* macro use, even the ones - for internal type nodes we only use to build other types, would - need an accompanying declaration which explicitly lists the - type.) */ +/* + * Declare an externally-defined type. This is a hack we should do + * away with once we move to generating code from a script. For now, + * this macro is unfortunately not compatible with the defining macros + * above, since you can't do the typedefs twice and we need the + * declarations to produce typedefs. (We could eliminate the typedefs + * from the DEF* macros, but then every DEF* macro use, even the ones + * for internal type nodes we only use to build other types, would + * need an accompanying declaration which explicitly lists the + * type.) + */ #define IMPORT_TYPE(DESCNAME, CTYPENAME) \ typedef CTYPENAME aux_typedefname_##DESCNAME; \ extern const struct atype_info krb5int_asn1type_##DESCNAME -/* Create a partial-encoding function by the indicated name, for the - indicated type. Should only be needed until we've converted all of - the encoders, then everything should use descriptor tables. */ +/* + * Create a partial-encoding function by the indicated name, for the + * indicated type. Should only be needed until we've converted all of + * the encoders, then everything should use descriptor tables. + */ extern asn1_error_code krb5int_asn1_encode_a_thing(asn1buf *buf, const void *val, const struct atype_info *a, unsigned int *retlen); #define MAKE_ENCFN(FNAME,DESC) \ - static asn1_error_code FNAME (asn1buf *buf, \ - const aux_typedefname_##DESC *val, \ - unsigned int *retlen) \ + static asn1_error_code FNAME(asn1buf *buf, \ + const aux_typedefname_##DESC *val, \ + unsigned int *retlen) \ { \ return krb5int_asn1_encode_a_thing(buf, val, \ &krb5int_asn1type_##DESC, \ @@ -477,32 +526,40 @@ krb5int_asn1_encode_a_thing(asn1buf *buf, const void *val, } \ extern int dummy /* gobble semicolon */ -/* Sequence field descriptor. - - Currently we assume everything is a single object with a type - descriptor, and then we bolt on some ugliness on the side for - handling strings with length fields. - - Anything with "interesting" encoding handling, like a sequence-of - or a pointer to the actual value to encode, is handled via opaque - types with their own encoder functions. Most of that should - eventually change. */ +/* + * Sequence field descriptor. + * + * Currently we assume everything is a single object with a type + * descriptor, and then we bolt on some ugliness on the side for + * handling strings with length fields. + * + * Anything with "interesting" encoding handling, like a sequence-of + * or a pointer to the actual value to encode, is handled via opaque + * types with their own encoder functions. Most of that should + * eventually change. + */ enum field_type { /* Unused except for range checking. */ field_min = 1, /* Field ATYPE describes processing of field at DATAOFF. */ field_normal, - /* Encode an "immediate" integer value stored in DATAOFF, with no - reference to the data structure. */ + /* + * Encode an "immediate" integer value stored in DATAOFF, with no + * reference to the data structure. + */ field_immediate, - /* Encode some kind of string field encoded with pointer and - length. (A GENERALSTRING represented as a null-terminated C - string would be handled as field_normal.) */ + /* + * Encode some kind of string field encoded with pointer and + * length. (A GENERALSTRING represented as a null-terminated C + * string would be handled as field_normal.) + */ field_string, - /* LENOFF indicates a value describing the length of the array at - DATAOFF, encoded as a sequence-of with the element type - described by ATYPE. */ + /* + * LENOFF indicates a value describing the length of the array at + * DATAOFF, encoded as a sequence-of with the element type + * described by ATYPE. + */ field_sequenceof_len, /* Unused except for range checking. */ field_max @@ -512,118 +569,136 @@ struct field_info { /* Type of the field. */ unsigned int /* enum field_type */ ftype : 3; - /* Use of DATAOFF and LENOFF are described by the value in FTYPE. - Generally DATAOFF will be the offset from the supplied pointer - at which we find the object to be encoded. */ + /* + * Use of DATAOFF and LENOFF are described by the value in FTYPE. + * Generally DATAOFF will be the offset from the supplied pointer + * at which we find the object to be encoded. + */ unsigned int dataoff : 9, lenoff : 9; - /* If TAG is non-negative, a context tag with that value is added - to the encoding of the thing. (XXX This would encode more - compactly as an unsigned bitfield value tagnum+1, with 0=no - tag.) The tag is omitted for optional fields that are not - present. - - It's a bit illogical to combine the tag and other field info, - since really a sequence field could have zero or several - context tags, and of course a tag could be used elsewhere. But - the normal mode in the Kerberos ASN.1 description is to use one - context tag on each sequence field, so for now let's address - that case primarily and work around the other cases (thus tag<0 - means skip tagging). */ + /* + * If TAG is non-negative, a context tag with that value is added + * to the encoding of the thing. (XXX This would encode more + * compactly as an unsigned bitfield value tagnum+1, with 0=no + * tag.) The tag is omitted for optional fields that are not + * present. + * + * It's a bit illogical to combine the tag and other field info, + * since really a sequence field could have zero or several + * context tags, and of course a tag could be used elsewhere. But + * the normal mode in the Kerberos ASN.1 description is to use one + * context tag on each sequence field, so for now let's address + * that case primarily and work around the other cases (thus tag<0 + * means skip tagging). + */ signed int tag : 5; - /* If OPT is non-negative and the sequence header structure has a - function pointer describing which fields are present, OPT is - the bit position indicating whether the currently-described - element is present. (XXX Similar encoding issue.) - - Note: Most of the time, I'm using the same number here as for - the context tag. This is just because it's easier for me to - keep track while working on the code by hand. The *only* - meaningful correlation is of this value and the bits set by the - "optional" function when examining the data structure. */ + /* + * If OPT is non-negative and the sequence header structure has a + * function pointer describing which fields are present, OPT is + * the bit position indicating whether the currently-described + * element is present. (XXX Similar encoding issue.) + * + * Note: Most of the time, I'm using the same number here as for + * the context tag. This is just because it's easier for me to + * keep track while working on the code by hand. The *only* + * meaningful correlation is of this value and the bits set by the + * "optional" function when examining the data structure. + */ signed int opt : 5; - /* For some values of FTYPE, this describes the type of the - object(s) to be encoded. */ + /* + * For some values of FTYPE, this describes the type of the + * object(s) to be encoded. + */ const struct atype_info *atype; - /* We use different types for "length" fields in different places. - So we need a good way to retrieve the various kinds of lengths - in a compatible way. This may be a string length, or the - length of an array of objects to encode in a SEQUENCE OF. - - In case the field is signed and negative, or larger than - size_t, return SIZE_MAX as an error indication. We'll assume - for now that we'll never have 4G-1 (or 2**64-1, or on tiny - systems, 65535) sized values. On most if not all systems we - care about, SIZE_MAX is equivalent to "all of addressable - memory" minus one byte. That wouldn't leave enough extra room - for the structure we're encoding, so it's pretty safe to assume - SIZE_MAX won't legitimately come up on those systems. - - If this code gets ported to a segmented architecture or other - system where it might be possible... figure it out then. */ + /* + * We use different types for "length" fields in different places. + * So we need a good way to retrieve the various kinds of lengths + * in a compatible way. This may be a string length, or the + * length of an array of objects to encode in a SEQUENCE OF. + * + * In case the field is signed and negative, or larger than + * size_t, return SIZE_MAX as an error indication. We'll assume + * for now that we'll never have 4G-1 (or 2**64-1, or on tiny + * systems, 65535) sized values. On most if not all systems we + * care about, SIZE_MAX is equivalent to "all of addressable + * memory" minus one byte. That wouldn't leave enough extra room + * for the structure we're encoding, so it's pretty safe to assume + * SIZE_MAX won't legitimately come up on those systems. + * + * If this code gets ported to a segmented architecture or other + * system where it might be possible... figure it out then. + */ const struct atype_info *lentype; }; -/* Normal or optional sequence fields at a particular offset, encoded - as indicated by the listed DESCRiptor. */ +/* + * Normal or optional sequence fields at a particular offset, encoded + * as indicated by the listed DESCRiptor. + */ #define FIELDOF_OPT(TYPE,DESCR,FIELDNAME,TAG,OPT) \ { \ field_normal, OFFOF(TYPE, FIELDNAME, aux_typedefname_##DESCR), \ - 0, TAG, OPT, &krb5int_asn1type_##DESCR \ - } + 0, TAG, OPT, &krb5int_asn1type_##DESCR \ + } #define FIELDOF_NORM(TYPE,DESCR,FIELDNAME,TAG) \ FIELDOF_OPT(TYPE,DESCR,FIELDNAME,TAG,-1) -/* If encoding a subset of the fields of the current structure (for - example, a flat structure describing data that gets encoded as a - sequence containing one or more sequences), use ENCODEAS, no struct - field name(s), and the indicated type descriptor must support the - current struct type. */ -#define FIELDOF_ENCODEAS(TYPE,DESCR,TAG) \ +/* + * If encoding a subset of the fields of the current structure (for + * example, a flat structure describing data that gets encoded as a + * sequence containing one or more sequences), use ENCODEAS, no struct + * field name(s), and the indicated type descriptor must support the + * current struct type. + */ +#define FIELDOF_ENCODEAS(TYPE,DESCR,TAG) \ FIELDOF_ENCODEAS_OPT(TYPE,DESCR,TAG,-1) #define FIELDOF_ENCODEAS_OPT(TYPE,DESCR,TAG,OPT) \ { \ field_normal, \ - 0 * sizeof(0 ? (TYPE *)0 : (aux_typedefname_##DESCR *) 0), \ - 0, TAG, OPT, &krb5int_asn1type_##DESCR \ - } + 0 * sizeof(0 ? (TYPE *)0 : (aux_typedefname_##DESCR *) 0), \ + 0, TAG, OPT, &krb5int_asn1type_##DESCR \ + } -/* Reinterpret some subset of the structure itself as something - else. */ -#define FIELD_SELF(DESCR, TAG) \ +/* + * Reinterpret some subset of the structure itself as something + * else. + */ +#define FIELD_SELF(DESCR, TAG) \ { field_normal, 0, 0, TAG, -1, &krb5int_asn1type_##DESCR } #define FIELDOF_OPTSTRINGL(STYPE,DESC,PTRFIELD,LENDESC,LENFIELD,TAG,OPT) \ - { \ - field_string, \ - OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC), \ - OFFOF(STYPE, LENFIELD, aux_typedefname_##LENDESC), \ - TAG, OPT, &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENDESC \ - } + { \ + field_string, \ + OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC), \ + OFFOF(STYPE, LENFIELD, aux_typedefname_##LENDESC), \ + TAG, OPT, &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENDESC \ + } #define FIELDOF_OPTSTRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG,OPT) \ FIELDOF_OPTSTRINGL(STYPE,DESC,PTRFIELD,uint,LENFIELD,TAG,OPT) #define FIELDOF_STRINGL(STYPE,DESC,PTRFIELD,LENDESC,LENFIELD,TAG) \ FIELDOF_OPTSTRINGL(STYPE,DESC,PTRFIELD,LENDESC,LENFIELD,TAG,-1) -#define FIELDOF_STRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG) \ +#define FIELDOF_STRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG) \ FIELDOF_OPTSTRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG,-1) -#define FIELD_INT_IMM(VALUE,TAG) \ +#define FIELD_INT_IMM(VALUE,TAG) \ { field_immediate, VALUE, 0, TAG, -1, 0, } #define FIELDOF_SEQOF_LEN(STYPE,DESC,PTRFIELD,LENFIELD,LENTYPE,TAG) \ { \ field_sequenceof_len, \ - OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC), \ - OFFOF(STYPE, LENFIELD, aux_typedefname_##LENTYPE), \ - TAG, -1, &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENTYPE \ - } + OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC), \ + OFFOF(STYPE, LENFIELD, aux_typedefname_##LENTYPE), \ + TAG, -1, &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENTYPE \ + } #define FIELDOF_SEQOF_INT32(STYPE,DESC,PTRFIELD,LENFIELD,TAG) \ FIELDOF_SEQOF_LEN(STYPE,DESC,PTRFIELD,LENFIELD,int32,TAG) struct seq_info { - /* If present, returns a bitmask indicating which fields are - present. See the "opt" field in struct field_info. */ + /* + * If present, returns a bitmask indicating which fields are + * present. See the "opt" field in struct field_info. + */ unsigned int (*optional)(const void *); /* Indicates an array of sequence field descriptors. */ const struct field_info *fields; @@ -645,9 +720,11 @@ krb5int_asn1_do_full_encode(const void *rep, krb5_data **code, extern int dummy /* gobble semicolon */ #include <stddef.h> -/* Ugly hack! - Like "offsetof", but with type checking. */ -#define WARN_IF_TYPE_MISMATCH(LVALUE, TYPE) \ +/* + * Ugly hack! + * Like "offsetof", but with type checking. + */ +#define WARN_IF_TYPE_MISMATCH(LVALUE, TYPE) \ (sizeof(0 ? (TYPE *) 0 : &(LVALUE))) #define OFFOF(TYPE,FIELD,FTYPE) \ (offsetof(TYPE, FIELD) \ diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index dd1a2ae..0257a8b 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -1007,7 +1007,8 @@ error_out: return retval; } -static asn1_error_code asn1_peek_authdata_elt(asn1buf *buf, krb5_authdatatype *val) +static asn1_error_code +asn1_peek_authdata_elt(asn1buf *buf, krb5_authdatatype *val) { setup(); *val = 0; @@ -1020,8 +1021,9 @@ error_out: return retval; } -asn1_error_code asn1_peek_authorization_data -(asn1buf *buf, unsigned int *num, krb5_authdatatype **val) +asn1_error_code +asn1_peek_authorization_data(asn1buf *buf, unsigned int *num, + krb5_authdatatype **val) { int size = 0; krb5_authdatatype *array = NULL, *new_array; @@ -1868,14 +1870,14 @@ error_out: return retval; } -static asn1_error_code asn1_decode_sequence_of_princ_plus_realm -(asn1buf *buf, krb5_principal **val) +static asn1_error_code +asn1_decode_sequence_of_princ_plus_realm(asn1buf *buf, krb5_principal **val) { decode_array_body(krb5_principal_data,asn1_decode_princ_plus_realm,krb5_free_principal); } -asn1_error_code asn1_decode_ad_signedpath -(asn1buf *buf, krb5_ad_signedpath *val) +asn1_error_code +asn1_decode_ad_signedpath(asn1buf *buf, krb5_ad_signedpath *val) { setup(); val->enctype = ENCTYPE_NULL; @@ -1926,7 +1928,8 @@ error_out: return retval; } -asn1_error_code asn1_decode_external_principal_identifier_ptr( +asn1_error_code +asn1_decode_external_principal_identifier_ptr( asn1buf *buf, krb5_external_principal_identifier **valptr) { diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c index 22ebae3..1cd6c8c 100644 --- a/src/lib/krb5/asn.1/asn1_k_encode.c +++ b/src/lib/krb5/asn.1/asn1_k_encode.c @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * src/lib/krb5/asn.1/asn1_k_encode.c * @@ -30,43 +30,47 @@ #include "asn1_encode.h" #include <assert.h> -/* helper macros - - These are mostly only needed for PKINIT, but there are three - basic-krb5 encoders not converted yet. */ +/* + * helper macros + * + * These are mostly only needed for PKINIT, but there are three + * basic-krb5 encoders not converted yet. + */ -/* setup() -- create and initialize bookkeeping variables - retval: stores error codes returned from subroutines - length: length of the most-recently produced encoding - sum: cumulative length of the entire encoding */ -#define asn1_setup()\ - asn1_error_code retval;\ - unsigned int sum=0 +/* + * setup() -- create and initialize bookkeeping variables + * retval: stores error codes returned from subroutines + * length: length of the most-recently produced encoding + * sum: cumulative length of the entire encoding + */ +#define asn1_setup() \ + asn1_error_code retval; \ + unsigned int sum=0 /* form a sequence (by adding a sequence header to the current encoding) */ -#define asn1_makeseq()\ -{ unsigned int length;\ - retval = asn1_make_sequence(buf,sum,&length);\ - if (retval) {\ - return retval; }\ - sum += length; } +#define asn1_makeseq() \ + { unsigned int length; \ + retval = asn1_make_sequence(buf,sum,&length); \ + if (retval) { \ + return retval; } \ + sum += length; } /* produce the final output and clean up the workspace */ -#define asn1_cleanup()\ - *retlen = sum;\ - return 0 +#define asn1_cleanup() \ + *retlen = sum; \ + return 0 /* asn1_addfield -- add a field, or component, to the encoding */ -#define asn1_addfield(value,tag,encoder)\ -{ unsigned int length; \ - retval = encoder(buf,value,&length); \ - if (retval) {\ - return retval; }\ - sum += length;\ - retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\ - if (retval) {\ - return retval; }\ - sum += length; } +#define asn1_addfield(value,tag,encoder) \ + { unsigned int length; \ + retval = encoder(buf,value,&length); \ + if (retval) { \ + return retval; } \ + sum += length; \ + retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length); \ + if (retval) { \ + return retval; } \ + sum += length; } DEFINTTYPE(int32, krb5_int32); DEFPTRTYPE(int32_ptr, int32); @@ -101,8 +105,10 @@ static const struct field_info princname_fields[] = { FIELDOF_NORM(krb5_principal_data, int32, type, 0), FIELDOF_SEQOF_INT32(krb5_principal_data, gstring_data_ptr, data, length, 1), }; -/* krb5_principal is a typedef for krb5_principal_data*, so this is - effectively "encode_principal_data_at" with an address arg. */ +/* + * krb5_principal is a typedef for krb5_principal_data*, so this is + * effectively "encode_principal_data_at" with an address arg. + */ DEFSEQTYPE(principal_data, krb5_principal_data, princname_fields, 0); DEFPTRTYPE(principal, principal_data); @@ -146,9 +152,11 @@ static const struct field_info encrypted_data_fields[] = { DEFSEQTYPE(encrypted_data, krb5_enc_data, encrypted_data_fields, optional_encrypted_data); -/* The encode_bitstring function wants an array of bytes (since PKINIT - may provide something that isn't 32 bits), but krb5_flags is stored - as a 32-bit integer in host order. */ +/* + * The encode_bitstring function wants an array of bytes (since PKINIT + * may provide something that isn't 32 bits), but krb5_flags is stored + * as a 32-bit integer in host order. + */ static asn1_error_code asn1_encode_krb5_flags_at(asn1buf *buf, const krb5_flags *val, unsigned int *retlen) @@ -271,10 +279,12 @@ optional_enc_kdc_rep_part(const void *p) DEFSEQTYPE(enc_kdc_rep_part, krb5_enc_kdc_rep_part, enc_kdc_rep_part_fields, optional_enc_kdc_rep_part); -/* Yuck! Eventually push this *up* above the encoder API and make the - rest of the library put the realm name in one consistent place. At - the same time, might as well add the msg-type field and encode both - AS-REQ and TGS-REQ through the same descriptor. */ +/* + * Yuck! Eventually push this *up* above the encoder API and make the + * rest of the library put the realm name in one consistent place. At + * the same time, might as well add the msg-type field and encode both + * AS-REQ and TGS-REQ through the same descriptor. + */ struct kdc_req_hack { krb5_kdc_req v; krb5_data *server_realm; @@ -1304,7 +1314,7 @@ fast_response_optional (const void *p) DEFSEQTYPE( fast_response, krb5_fast_response, fast_response_fields, fast_response_optional); static const struct field_info fast_rep_fields[] = { - FIELDOF_ENCODEAS(krb5_enc_data, encrypted_data, 0), + FIELDOF_ENCODEAS(krb5_enc_data, encrypted_data, 0), }; DEFSEQTYPE(fast_rep, krb5_enc_data, fast_rep_fields, 0); @@ -1468,102 +1478,120 @@ MAKE_FULL_ENCODER(encode_krb5_ad_signedpath, ad_signedpath); * PKINIT */ -/* This code hasn't been converted to use the above framework yet, - because we currently have no test cases to validate the new - version. It *also* appears that some of the encodings may disagree - with the specifications, but that's a separate problem. */ +/* + * This code hasn't been converted to use the above framework yet, + * because we currently have no test cases to validate the new + * version. It *also* appears that some of the encodings may disagree + * with the specifications, but that's a separate problem. + */ /**** asn1 macros ****/ #if 0 - How to write an asn1 encoder function using these macros: - - asn1_error_code asn1_encode_krb5_substructure(asn1buf *buf, - const krb5_type *val, - int *retlen) - { - asn1_setup(); - - asn1_addfield(val->last_field, n, asn1_type); - asn1_addfield(rep->next_to_last_field, n-1, asn1_type); - ... - - /* for OPTIONAL fields */ - if (rep->field_i == should_not_be_omitted) - asn1_addfield(rep->field_i, i, asn1_type); - - /* for string fields (these encoders take an additional argument, - the length of the string) */ - addlenfield(rep->field_length, rep->field, i-1, asn1_type); - - /* if you really have to do things yourself... */ - retval = asn1_encode_asn1_type(buf,rep->field,&length); - if (retval) return retval; - sum += length; - retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, tag_number, length, - &length); - if (retval) return retval; - sum += length; - - ... - asn1_addfield(rep->second_field, 1, asn1_type); - asn1_addfield(rep->first_field, 0, asn1_type); - asn1_makeseq(); - - asn1_cleanup(); - } +How to write an asn1 encoder function using these macros: + +asn1_error_code asn1_encode_krb5_substructure(asn1buf *buf, + const krb5_type *val, + int *retlen) +{ + asn1_setup(); + + asn1_addfield(val->last_field, n, asn1_type); + asn1_addfield(rep->next_to_last_field, n-1, asn1_type); + ... + + /* for OPTIONAL fields */ + if (rep->field_i == should_not_be_omitted) + asn1_addfield(rep->field_i, i, asn1_type); + + /* + * for string fields (these encoders take an additional argument, + * the length of the string) + */ + addlenfield(rep->field_length, rep->field, i-1, asn1_type); + + /* if you really have to do things yourself... */ + retval = asn1_encode_asn1_type(buf,rep->field,&length); + if (retval) return retval; + sum += length; + retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, tag_number, length, + &length); + if (retval) return retval; + sum += length; + + ... + asn1_addfield(rep->second_field, 1, asn1_type); + asn1_addfield(rep->first_field, 0, asn1_type); + asn1_makeseq(); + + asn1_cleanup(); +} #endif /* asn1_addlenfield -- add a field whose length must be separately specified */ -#define asn1_addlenfield(len,value,tag,encoder)\ -{ unsigned int length; \ - retval = encoder(buf,len,value,&length); \ - if (retval) {\ - return retval; }\ - sum += length;\ - retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\ - if (retval) {\ - return retval; }\ - sum += length; } - -/* asn1_addfield_implicit -- add an implicitly tagged field, or component, to the encoding */ -#define asn1_addfield_implicit(value,tag,encoder)\ -{ unsigned int length;\ - retval = encoder(buf,value,&length);\ - if (retval) {\ - return retval; }\ - sum += length;\ - retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,length,&length); \ - if (retval) {\ - return retval; }\ - sum += length; } - -/* asn1_insert_implicit_octetstring -- add an octet string with implicit tagging */ -#define asn1_insert_implicit_octetstring(len,value,tag)\ -{ unsigned int length;\ - retval = asn1buf_insert_octetstring(buf,len,value);\ - if (retval) {\ - return retval; }\ - sum += len;\ - retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,len,&length); \ - if (retval) {\ - return retval; }\ - sum += length; } +#define asn1_addlenfield(len, value, tag, encoder) \ + { \ + unsigned int length; \ + retval = encoder(buf, len, value, &length); \ + if (retval) { \ + return retval; } \ + sum += length; \ + retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, \ + tag, length, &length); \ + if (retval) { \ + return retval; } \ + sum += length; \ + } + +/* + * asn1_addfield_implicit -- add an implicitly tagged field, or component, + * to the encoding + */ +#define asn1_addfield_implicit(value,tag,encoder) \ + { unsigned int length; \ + retval = encoder(buf,value,&length); \ + if (retval) { \ + return retval; } \ + sum += length; \ + retval = asn1_make_tag(buf, CONTEXT_SPECIFIC,PRIMITIVE, \ + tag, length, &length); \ + if (retval) { \ + return retval; } \ + sum += length; } + +/* + * asn1_insert_implicit_octetstring -- add an octet string with implicit + * tagging + */ +#define asn1_insert_implicit_octetstring(len,value,tag) \ + { unsigned int length; \ + retval = asn1buf_insert_octetstring(buf,len,value); \ + if (retval) { \ + return retval; } \ + sum += len; \ + retval = asn1_make_tag(buf, CONTEXT_SPECIFIC, PRIMITIVE, \ + tag, len, &length); \ + if (retval) { \ + return retval; } \ + sum += length; } /* asn1_insert_implicit_bitstring -- add a bitstring with implicit tagging */ /* needs "length" declared in enclosing context */ -#define asn1_insert_implicit_bitstring(len,value,tag)\ -{ retval = asn1buf_insert_octetstring(buf,len,value); \ - if (retval) {\ - return retval; }\ - sum += len;\ - retval = asn1buf_insert_octet(buf, 0);\ - if (retval) {\ - return retval; }\ - sum++;\ - retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,tag,len+1,&length); \ - if (retval) {\ - return retval; }\ - sum += length; } +#define asn1_insert_implicit_bitstring(len, value, tag) \ + { \ + retval = asn1buf_insert_octetstring(buf, len, value); \ + if (retval) { \ + return retval; } \ + sum += len; \ + retval = asn1buf_insert_octet(buf, 0); \ + if (retval) { \ + return retval; } \ + sum++; \ + retval = asn1_make_tag(buf, UNIVERSAL, PRIMITIVE, \ + tag, len + 1, &length); \ + if (retval) { \ + return retval; } \ + sum += length; \ + } #ifndef DISABLE_PKINIT diff --git a/src/lib/krb5/asn.1/asn1_make.h b/src/lib/krb5/asn.1/asn1_make.h index 4279fa7..dcbaa16 100644 --- a/src/lib/krb5/asn.1/asn1_make.h +++ b/src/lib/krb5/asn.1/asn1_make.h @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * src/lib/krb5/asn.1/asn1_make.h * @@ -33,70 +33,80 @@ #include "asn1buf.h" /* - Overview - - Each of these procedures constructs a subpart of an ASN.1 - primitive in a coding buffer. - - Operations - - asn1_make_etag - asn1_make_sequence - asn1_make_set - asn1_make_tag - asn1_make_string -*/ + * Overview + * + * Each of these procedures constructs a subpart of an ASN.1 + * primitive in a coding buffer. + * + * Operations + * + * asn1_make_etag + * asn1_make_sequence + * asn1_make_set + * asn1_make_tag + * asn1_make_string + */ asn1_error_code asn1_make_etag(asn1buf *buf, asn1_class asn1class, asn1_tagnum tagnum, unsigned int in_len, unsigned int *retlen); -/* requires *buf is allocated, in_len is the length of an ASN.1 encoding - which has just been inserted in *buf - modifies *buf, *retlen - effects Inserts an explicit tag with class = asn1class, id# = tag - length = in_len into *buf. - Returns the length of this encoding in *retlen. - Returns ENOMEM if memory runs out. */ +/* + * requires *buf is allocated, in_len is the length of an ASN.1 encoding + * which has just been inserted in *buf + * modifies *buf, *retlen + * effects Inserts an explicit tag with class = asn1class, id# = tag + * length = in_len into *buf. + * Returns the length of this encoding in *retlen. + * Returns ENOMEM if memory runs out. + */ asn1_error_code asn1_make_tag(asn1buf *buf, asn1_class asn1class, asn1_construction construction, asn1_tagnum tagnum, unsigned int in_len, unsigned int *retlen); -/* requires *buf is allocated, in_len is the length of an ASN.1 encoding - which has just been inserted in *buf - modifies *buf, *retlen - effects Inserts the encoding of a tag with class = asn1class, - primitive/constructed staus = construction, - id# = tag and length = in_len into *buf. - Returns the length of this encoding in *retlen. - Returns ENOMEM if memory runs out. - Returns ASN1_OVERFLOW if tagnum exceeds the limits of - the implementation. */ +/* + * requires *buf is allocated, in_len is the length of an ASN.1 encoding + * which has just been inserted in *buf + * modifies *buf, *retlen + * effects Inserts the encoding of a tag with class = asn1class, + * primitive/constructed staus = construction, + * id# = tag and length = in_len into *buf. + * Returns the length of this encoding in *retlen. + * Returns ENOMEM if memory runs out. + * Returns ASN1_OVERFLOW if tagnum exceeds the limits of + * the implementation. + */ asn1_error_code asn1_make_sequence(asn1buf *buf, const unsigned int seq_len, unsigned int *len); -/* requires *buf is allocated, seq_len is the length of a series of - sequence components which have just been inserted in *buf - modifies *buf, *retlen - effects Inserts the sequence header for a sequence of length seq_len - in *buf. Returns the length of this encoding in *retlen. - Returns ENOMEM if memory runs out. */ +/* + * requires *buf is allocated, seq_len is the length of a series of + * sequence components which have just been inserted in *buf + * modifies *buf, *retlen + * effects Inserts the sequence header for a sequence of length seq_len + * in *buf. Returns the length of this encoding in *retlen. + * Returns ENOMEM if memory runs out. + */ asn1_error_code asn1_make_set(asn1buf *buf, const unsigned int set_len, unsigned int *retlen); -/* requires *buf is allocated, seq_len is the length of a series of - sequence components which have just been inserted in *buf - modifies *buf, *retlen - effects Inserts the set header for a set of length set_len in *buf. - Returns the length of this encoding in *retlen. - Returns ENOMEM if memory runs out. */ +/* + * requires *buf is allocated, seq_len is the length of a series of + * sequence components which have just been inserted in *buf + * modifies *buf, *retlen + * effects Inserts the set header for a set of length set_len in *buf. + * Returns the length of this encoding in *retlen. + * Returns ENOMEM if memory runs out. + */ asn1_error_code asn1_make_string(asn1buf *buf, const unsigned int len, const char *string, int *retlen); -/* requires *buf is allocated, len is the length of *string - effects Inserts the encoding of *string (a series of octets) in *buf. - Returns the length of this encoding in *retlen. - Returns ENOMEM if memory runs out. */ +/* + * requires *buf is allocated, len is the length of *string + * effects Inserts the encoding of *string (a series of octets) in *buf. + * Returns the length of this encoding in *retlen. + * Returns ENOMEM if memory runs out. + */ /****************************************************************/ @@ -105,19 +115,23 @@ asn1_error_code asn1_make_string(asn1buf *buf, const unsigned int len, /* "helper" procedure for asn1_make_tag */ asn1_error_code asn1_make_length(asn1buf *buf, const unsigned int in_len, unsigned int *retlen); -/* requires *buf is allocated, in_len is the length of an ASN.1 encoding - which has just been inserted in *buf - modifies *buf, *retlen - effects inserts length octet(s) for in_len into *buf */ +/* + * requires *buf is allocated, in_len is the length of an ASN.1 encoding + * which has just been inserted in *buf + * modifies *buf, *retlen + * effects inserts length octet(s) for in_len into *buf + */ /* "helper" procedure for asn1_make_tag */ asn1_error_code asn1_make_id(asn1buf *buf, asn1_class asn1class, asn1_construction construction, asn1_tagnum tagnum, unsigned int *retlen); -/* requires *buf is allocated, asn1class and tagnum are appropriate for - the ASN.1 encoding which has just been inserted in *buf - modifies *buf, *retlen - effects Inserts id octet(s) of class asn1class and tag number tagnum - into *buf */ +/* + * requires *buf is allocated, asn1class and tagnum are appropriate for + * the ASN.1 encoding which has just been inserted in *buf + * modifies *buf, *retlen + * effects Inserts id octet(s) of class asn1class and tag number tagnum + * into *buf + */ #endif diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c index 5e0d4e7..f73458e 100644 --- a/src/lib/krb5/asn.1/asn1buf.c +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -78,7 +78,8 @@ static asn1_error_code asn1buf_expand(asn1buf *, unsigned int); #define asn1_is_eoc(class, num, indef) \ ((class) == UNIVERSAL && !(num) && !(indef)) -asn1_error_code asn1buf_create(asn1buf **buf) +asn1_error_code +asn1buf_create(asn1buf **buf) { *buf = (asn1buf*)malloc(sizeof(asn1buf)); if (*buf == NULL) return ENOMEM; @@ -88,7 +89,8 @@ asn1_error_code asn1buf_create(asn1buf **buf) return 0; } -asn1_error_code asn1buf_wrap_data(asn1buf *buf, const krb5_data *code) +asn1_error_code +asn1buf_wrap_data(asn1buf *buf, const krb5_data *code) { if (code == NULL || code->data == NULL) return ASN1_MISSING_FIELD; buf->next = buf->base = code->data; @@ -96,7 +98,8 @@ asn1_error_code asn1buf_wrap_data(asn1buf *buf, const krb5_data *code) return 0; } -asn1_error_code asn1buf_imbed(asn1buf *subbuf, const asn1buf *buf, const unsigned int length, const int indef) +asn1_error_code +asn1buf_imbed(asn1buf *subbuf, const asn1buf *buf, const unsigned int length, const int indef) { if (buf->next > buf->bound + 1) return ASN1_OVERRUN; subbuf->base = subbuf->next = buf->next; @@ -108,9 +111,10 @@ asn1_error_code asn1buf_imbed(asn1buf *subbuf, const asn1buf *buf, const unsigne return 0; } -asn1_error_code asn1buf_sync(asn1buf *buf, asn1buf *subbuf, - asn1_class asn1class, asn1_tagnum lasttag, - unsigned int length, int indef, int seqindef) +asn1_error_code +asn1buf_sync(asn1buf *buf, asn1buf *subbuf, + asn1_class asn1class, asn1_tagnum lasttag, + unsigned int length, int indef, int seqindef) { asn1_error_code retval; @@ -128,7 +132,8 @@ asn1_error_code asn1buf_sync(asn1buf *buf, asn1buf *subbuf, return 0; } -asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const int indef) +asn1_error_code +asn1buf_skiptail(asn1buf *buf, const unsigned int length, const int indef) { asn1_error_code retval; taginfo t; @@ -160,7 +165,8 @@ asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const return 0; } -void asn1buf_destroy(asn1buf **buf) +void +asn1buf_destroy(asn1buf **buf) { if (*buf != NULL) { free((*buf)->base); @@ -172,7 +178,8 @@ void asn1buf_destroy(asn1buf **buf) #ifdef asn1buf_insert_octet #undef asn1buf_insert_octet #endif -asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o) +asn1_error_code +asn1buf_insert_octet(asn1buf *buf, const int o) { asn1_error_code retval; @@ -207,7 +214,8 @@ asn1_error_code asn1buf_remove_octet(asn1buf *buf, asn1_octet *o) return 0; } -asn1_error_code asn1buf_remove_octetstring(asn1buf *buf, const unsigned int len, asn1_octet **s) +asn1_error_code +asn1buf_remove_octetstring(asn1buf *buf, const unsigned int len, asn1_octet **s) { unsigned int i; @@ -226,7 +234,8 @@ asn1_error_code asn1buf_remove_octetstring(asn1buf *buf, const unsigned int len, return 0; } -asn1_error_code asn1buf_remove_charstring(asn1buf *buf, const unsigned int len, char **s) +asn1_error_code +asn1buf_remove_charstring(asn1buf *buf, const unsigned int len, char **s) { unsigned int i; @@ -244,7 +253,8 @@ asn1_error_code asn1buf_remove_charstring(asn1buf *buf, const unsigned int len, return 0; } -int asn1buf_remains(asn1buf *buf, int indef) +int +asn1buf_remains(asn1buf *buf, int indef) { int remain; if (buf == NULL || buf->base == NULL) return 0; @@ -258,7 +268,8 @@ int asn1buf_remains(asn1buf *buf, int indef) else return remain; } -asn1_error_code asn12krb5_buf(const asn1buf *buf, krb5_data **code) +asn1_error_code +asn12krb5_buf(const asn1buf *buf, krb5_data **code) { unsigned int i; krb5_data *d; @@ -290,7 +301,8 @@ asn1_error_code asn12krb5_buf(const asn1buf *buf, krb5_data **code) * version. */ -asn1_error_code asn1buf_unparse(const asn1buf *buf, char **s) +asn1_error_code +asn1buf_unparse(const asn1buf *buf, char **s) { free(*s); if (buf == NULL) { @@ -312,7 +324,8 @@ asn1_error_code asn1buf_unparse(const asn1buf *buf, char **s) return 0; } -asn1_error_code asn1buf_hex_unparse(const asn1buf *buf, char **s) +asn1_error_code +asn1buf_hex_unparse(const asn1buf *buf, char **s) { #define hexchar(d) ((d)<=9 ? ('0'+(d)) : \ ((d)<=15 ? ('A'+(d)-10) : \ @@ -345,21 +358,24 @@ asn1_error_code asn1buf_hex_unparse(const asn1buf *buf, char **s) /****************************************************************/ /* Private Procedures */ -static int asn1buf_size(const asn1buf *buf) +static int +asn1buf_size(const asn1buf *buf) { if (buf == NULL || buf->base == NULL) return 0; return buf->bound - buf->base + 1; } #undef asn1buf_free -unsigned int asn1buf_free(const asn1buf *buf) +unsigned int +asn1buf_free(const asn1buf *buf) { if (buf == NULL || buf->base == NULL) return 0; else return buf->bound - buf->next + 1; } #undef asn1buf_ensure_space -asn1_error_code asn1buf_ensure_space(asn1buf *buf, const unsigned int amount) +asn1_error_code +asn1buf_ensure_space(asn1buf *buf, const unsigned int amount) { unsigned int avail = asn1buf_free(buf); if (avail >= amount) @@ -367,7 +383,8 @@ asn1_error_code asn1buf_ensure_space(asn1buf *buf, const unsigned int amount) return asn1buf_expand(buf, amount-avail); } -asn1_error_code asn1buf_expand(asn1buf *buf, unsigned int inc) +asn1_error_code +asn1buf_expand(asn1buf *buf, unsigned int inc) { #define STANDARD_INCREMENT 200 int next_offset = buf->next - buf->base; @@ -387,7 +404,8 @@ asn1_error_code asn1buf_expand(asn1buf *buf, unsigned int inc) } #undef asn1buf_len -int asn1buf_len(const asn1buf *buf) +int +asn1buf_len(const asn1buf *buf) { return buf->next - buf->base; } diff --git a/src/lib/krb5/asn.1/asn1buf.h b/src/lib/krb5/asn.1/asn1buf.h index 33affbb..900b14a 100644 --- a/src/lib/krb5/asn.1/asn1buf.h +++ b/src/lib/krb5/asn.1/asn1buf.h @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* Coding Buffer Specifications */ #ifndef __ASN1BUF_H__ #define __ASN1BUF_H__ @@ -7,137 +7,146 @@ #include "krbasn1.h" typedef struct code_buffer_rep { - char *base, *bound, *next; + char *base, *bound, *next; } asn1buf; /**************** Private Procedures ****************/ #if (__GNUC__ >= 2) && !defined(CONFIG_SMALL) -unsigned int asn1buf_free - (const asn1buf *buf); -/* requires *buf is allocated - effects Returns the number of unused, allocated octets in *buf. */ -#define asn1buf_free(buf) \ - (((buf) == NULL || (buf)->base == NULL) \ - ? 0U \ - : (unsigned int)((buf)->bound - (buf)->next + 1)) - - -asn1_error_code asn1buf_ensure_space - (asn1buf *buf, const unsigned int amount); -/* requires *buf is allocated - modifies *buf - effects If buf has less than amount octets of free space, then it is - expanded to have at least amount octets of free space. - Returns ENOMEM memory is exhausted. */ -#define asn1buf_ensure_space(buf,amount) \ - ((asn1buf_free(buf) < (amount)) \ - ? (asn1buf_expand((buf), (amount)-asn1buf_free(buf))) \ - : 0) - -asn1_error_code asn1buf_expand - (asn1buf *buf, unsigned int inc); -/* requires *buf is allocated - modifies *buf - effects Expands *buf by allocating space for inc more octets. - Returns ENOMEM if memory is exhausted. */ +unsigned int asn1buf_free(const asn1buf *buf); +/* + * requires *buf is allocated + * effects Returns the number of unused, allocated octets in *buf. + */ +#define asn1buf_free(buf) \ + (((buf) == NULL || (buf)->base == NULL) \ + ? 0U \ + : (unsigned int)((buf)->bound - (buf)->next + 1)) + + +asn1_error_code asn1buf_ensure_space(asn1buf *buf, const unsigned int amount); +/* + * requires *buf is allocated + * modifies *buf + * effects If buf has less than amount octets of free space, then it is + * expanded to have at least amount octets of free space. + * Returns ENOMEM memory is exhausted. + */ +#define asn1buf_ensure_space(buf,amount) \ + ((asn1buf_free(buf) < (amount)) \ + ? (asn1buf_expand((buf), (amount)-asn1buf_free(buf))) \ + : 0) + +asn1_error_code asn1buf_expand(asn1buf *buf, unsigned int inc); +/* + * requires *buf is allocated + * modifies *buf + * effects Expands *buf by allocating space for inc more octets. + * Returns ENOMEM if memory is exhausted. + */ #endif -int asn1buf_len - (const asn1buf *buf); -/* requires *buf is allocated - effects Returns the length of the encoding in *buf. */ +int asn1buf_len(const asn1buf *buf); +/* + * requires *buf is allocated + * effects Returns the length of the encoding in *buf. + */ #define asn1buf_len(buf) ((buf)->next - (buf)->base) /****** End of private procedures *****/ /* - Overview - - The coding buffer is an array of char (to match a krb5_data structure) - with 3 reference pointers: - 1) base - The bottom of the octet array. Used for memory management - operations on the array (e.g. alloc, realloc, free). - 2) next - Points to the next available octet position in the array. - During encoding, this is the next free position, and it - advances as octets are added to the array. - During decoding, this is the next unread position, and it - advances as octets are read from the array. - 3) bound - Points to the top of the array. Used for bounds-checking. - - All pointers to encoding buffers should be initalized to NULL. - - Operations - - asn1buf_create - asn1buf_wrap_data - asn1buf_destroy - asn1buf_insert_octet - asn1buf_insert_charstring - asn1buf_remove_octet - asn1buf_remove_charstring - asn1buf_unparse - asn1buf_hex_unparse - asn12krb5_buf - asn1buf_remains - - (asn1buf_size) - (asn1buf_free) - (asn1buf_ensure_space) - (asn1buf_expand) - (asn1buf_len) -*/ - -asn1_error_code asn1buf_create - (asn1buf **buf); -/* effects Creates a new encoding buffer pointed to by *buf. - Returns ENOMEM if the buffer can't be created. */ - -asn1_error_code asn1buf_wrap_data - (asn1buf *buf, const krb5_data *code); -/* requires *buf has already been allocated - effects Turns *buf into a "wrapper" for *code. i.e. *buf is set up - such that its bottom is the beginning of *code, and its top - is the top of *code. - Returns ASN1_MISSING_FIELD if code is empty. */ - -asn1_error_code asn1buf_imbed - (asn1buf *subbuf, const asn1buf *buf, - const unsigned int length, - const int indef); -/* requires *subbuf and *buf are allocated - effects *subbuf becomes a sub-buffer of *buf. *subbuf begins - at *buf's current position and is length octets long. - (Unless this would exceed the bounds of *buf -- in - that case, ASN1_OVERRUN is returned) *subbuf's current - position starts at the beginning of *subbuf. */ - -asn1_error_code asn1buf_sync - (asn1buf *buf, asn1buf *subbuf, asn1_class Class, - asn1_tagnum lasttag, - unsigned int length, int indef, - int seqindef); -/* requires *subbuf is a sub-buffer of *buf, as created by asn1buf_imbed. - lasttag is the last tagnumber read. - effects Synchronizes *buf's current position to match that of *subbuf. */ - -asn1_error_code asn1buf_skiptail - (asn1buf *buf, const unsigned int length, - const int indef); -/* requires *buf is a subbuffer used in a decoding of a - constructed indefinite sequence. - effects skips trailing fields. */ - -void asn1buf_destroy - (asn1buf **buf); + * Overview + * + * The coding buffer is an array of char (to match a krb5_data structure) + * with 3 reference pointers: + * 1) base - The bottom of the octet array. Used for memory management + * operations on the array (e.g. alloc, realloc, free). + * 2) next - Points to the next available octet position in the array. + * During encoding, this is the next free position, and it + * advances as octets are added to the array. + * During decoding, this is the next unread position, and it + * advances as octets are read from the array. + * 3) bound - Points to the top of the array. Used for bounds-checking. + * + * All pointers to encoding buffers should be initalized to NULL. + * + * Operations + * + * asn1buf_create + * asn1buf_wrap_data + * asn1buf_destroy + * asn1buf_insert_octet + * asn1buf_insert_charstring + * asn1buf_remove_octet + * asn1buf_remove_charstring + * asn1buf_unparse + * asn1buf_hex_unparse + * asn12krb5_buf + * asn1buf_remains + * + * (asn1buf_size) + * (asn1buf_free) + * (asn1buf_ensure_space) + * (asn1buf_expand) + * (asn1buf_len) + */ + +asn1_error_code asn1buf_create(asn1buf **buf); +/* + * effects Creates a new encoding buffer pointed to by *buf. + * Returns ENOMEM if the buffer can't be created. + */ + +asn1_error_code asn1buf_wrap_data(asn1buf *buf, const krb5_data *code); +/* + * requires *buf has already been allocated + * effects Turns *buf into a "wrapper" for *code. i.e. *buf is set up + * such that its bottom is the beginning of *code, and its top + * is the top of *code. + * Returns ASN1_MISSING_FIELD if code is empty. + */ + +asn1_error_code asn1buf_imbed(asn1buf *subbuf, const asn1buf *buf, + const unsigned int length, + const int indef); +/* + * requires *subbuf and *buf are allocated + * effects *subbuf becomes a sub-buffer of *buf. *subbuf begins + * at *buf's current position and is length octets long. + * (Unless this would exceed the bounds of *buf -- in + * that case, ASN1_OVERRUN is returned) *subbuf's current + * position starts at the beginning of *subbuf. + */ + +asn1_error_code asn1buf_sync(asn1buf *buf, asn1buf *subbuf, asn1_class Class, + asn1_tagnum lasttag, + unsigned int length, int indef, + int seqindef); +/* + * requires *subbuf is a sub-buffer of *buf, as created by asn1buf_imbed. + * lasttag is the last tagnumber read. + * effects Synchronizes *buf's current position to match that of *subbuf. + */ + +asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, + const int indef); +/* + * requires *buf is a subbuffer used in a decoding of a + * constructed indefinite sequence. + * effects skips trailing fields. + */ + +void asn1buf_destroy(asn1buf **buf); /* effects Deallocates **buf, sets *buf to NULL. */ -asn1_error_code asn1buf_insert_octet - (asn1buf *buf, const int o); -/* requires *buf is allocated - effects Inserts o into the buffer *buf, expanding the buffer if - necessary. Returns ENOMEM memory is exhausted. */ +asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o); +/* + * requires *buf is allocated + * effects Inserts o into the buffer *buf, expanding the buffer if + * necessary. Returns ENOMEM memory is exhausted. + */ #if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS)) && !defined(CONFIG_SMALL) extern __inline__ asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o) { @@ -151,68 +160,83 @@ extern __inline__ asn1_error_code asn1buf_insert_octet(asn1buf *buf, const int o } #endif -asn1_error_code asn1buf_insert_bytestring - (asn1buf *buf, const unsigned int len, const void *s); -/* requires *buf is allocated - modifies *buf - effects Inserts the contents of s (an array of length len) - into the buffer *buf, expanding the buffer if necessary. - Returns ENOMEM if memory is exhausted. */ +asn1_error_code +asn1buf_insert_bytestring( + asn1buf *buf, + const unsigned int len, + const void *s); +/* + * requires *buf is allocated + * modifies *buf + * effects Inserts the contents of s (an array of length len) + * into the buffer *buf, expanding the buffer if necessary. + * Returns ENOMEM if memory is exhausted. + */ #define asn1buf_insert_octetstring asn1buf_insert_bytestring #define asn1buf_insert_charstring asn1buf_insert_bytestring -asn1_error_code asn1buf_remove_octet - (asn1buf *buf, asn1_octet *o); -/* requires *buf is allocated - effects Returns *buf's current octet in *o and advances to - the next octet. - Returns ASN1_OVERRUN if *buf has already been exhausted. */ -#define asn1buf_remove_octet(buf,o) \ - (((buf)->next > (buf)->bound) \ - ? ASN1_OVERRUN \ - : ((*(o) = (asn1_octet)(*(((buf)->next)++))),0)) - -asn1_error_code asn1buf_remove_octetstring - (asn1buf *buf, const unsigned int len, asn1_octet **s); -/* requires *buf is allocated - effects Removes the next len octets of *buf and returns them in **s. - Returns ASN1_OVERRUN if there are fewer than len unread octets - left in *buf. - Returns ENOMEM if *s could not be allocated. */ - -asn1_error_code asn1buf_remove_charstring - (asn1buf *buf, const unsigned int len, - char **s); -/* requires *buf is allocated - effects Removes the next len octets of *buf and returns them in **s. - Returns ASN1_OVERRUN if there are fewer than len unread octets - left in *buf. - Returns ENOMEM if *s could not be allocated. */ - -asn1_error_code asn1buf_unparse - (const asn1buf *buf, char **s); -/* modifies *s - effects Returns a human-readable representation of *buf in *s, - where each octet in *buf is represented by a character in *s. */ - -asn1_error_code asn1buf_hex_unparse - (const asn1buf *buf, char **s); -/* modifies *s - effects Returns a human-readable representation of *buf in *s, - where each octet in *buf is represented by a 2-digit - hexadecimal number in *s. */ - -asn1_error_code asn12krb5_buf - (const asn1buf *buf, krb5_data **code); -/* modifies *code - effects Instantiates **code with the krb5_data representation of **buf. */ - - -int asn1buf_remains - (asn1buf *buf, int indef); -/* requires *buf is a buffer containing an asn.1 structure or array - modifies *buf - effects Returns the number of unprocessed octets remaining in *buf. */ +asn1_error_code asn1buf_remove_octet(asn1buf *buf, asn1_octet *o); +/* + * requires *buf is allocated + * effects Returns *buf's current octet in *o and advances to + * the next octet. + * Returns ASN1_OVERRUN if *buf has already been exhausted. + */ +#define asn1buf_remove_octet(buf,o) \ + (((buf)->next > (buf)->bound) \ + ? ASN1_OVERRUN \ + : ((*(o) = (asn1_octet)(*(((buf)->next)++))),0)) + +asn1_error_code +asn1buf_remove_octetstring( + asn1buf *buf, + const unsigned int len, + asn1_octet **s); +/* + * requires *buf is allocated + * effects Removes the next len octets of *buf and returns them in **s. + * Returns ASN1_OVERRUN if there are fewer than len unread octets + * left in *buf. + * Returns ENOMEM if *s could not be allocated. + */ + +asn1_error_code +asn1buf_remove_charstring(asn1buf *buf, const unsigned int len, char **s); +/* + * requires *buf is allocated + * effects Removes the next len octets of *buf and returns them in **s. + * Returns ASN1_OVERRUN if there are fewer than len unread octets + * left in *buf. + * Returns ENOMEM if *s could not be allocated. + */ + +asn1_error_code asn1buf_unparse(const asn1buf *buf, char **s); +/* + * modifies *s + * effects Returns a human-readable representation of *buf in *s, + * where each octet in *buf is represented by a character in *s. + */ + +asn1_error_code asn1buf_hex_unparse(const asn1buf *buf, char **s); +/* + * modifies *s + * effects Returns a human-readable representation of *buf in *s, + * where each octet in *buf is represented by a 2-digit + * hexadecimal number in *s. + */ + +asn1_error_code asn12krb5_buf(const asn1buf *buf, krb5_data **code); +/* + * modifies *code + * effects Instantiates **code with the krb5_data representation of **buf. + */ + +int asn1buf_remains(asn1buf *buf, int indef); +/* + * requires *buf is a buffer containing an asn.1 structure or array + * modifies *buf + * effects Returns the number of unprocessed octets remaining in *buf. + */ #endif diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c index 0daa32e..e255551 100644 --- a/src/lib/krb5/asn.1/krb5_decode.c +++ b/src/lib/krb5/asn.1/krb5_decode.c @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * src/lib/krb5/asn.1/krb5_decode.c * @@ -33,77 +33,79 @@ /* setup *********************************************************/ /* set up variables */ -/* the setup* macros can return, but are always used at function start - and thus need no malloc cleanup */ -#define setup_buf_only(type)\ -asn1_error_code retval;\ -asn1buf buf;\ -type rep = NULL;\ -\ -*repptr = NULL;\ -retval = asn1buf_wrap_data(&buf,code);\ -if (retval) return retval - -#define setup_no_tagnum(type)\ -asn1_class asn1class;\ -asn1_construction construction;\ -setup_buf_only(type) - -#define setup_no_length(type)\ -asn1_tagnum tagnum;\ -setup_no_tagnum(type) - -#define setup(type)\ -unsigned int length;\ -setup_no_length(type) +/* + * the setup* macros can return, but are always used at function start + * and thus need no malloc cleanup + */ +#define setup_buf_only(type) \ + asn1_error_code retval; \ + asn1buf buf; \ + type rep = NULL; \ + \ + *repptr = NULL; \ + retval = asn1buf_wrap_data(&buf,code); \ + if (retval) return retval + +#define setup_no_tagnum(type) \ + asn1_class asn1class; \ + asn1_construction construction; \ + setup_buf_only(type) + +#define setup_no_length(type) \ + asn1_tagnum tagnum; \ + setup_no_tagnum(type) + +#define setup(type) \ + unsigned int length; \ + setup_no_length(type) /* helper macros for cleanup */ #define clean_return(val) { retval = val; goto error_out; } /* alloc_field is the first thing to allocate storage that may need cleanup */ -#define alloc_field(var)\ -var = calloc(1,sizeof(*var));\ -if ((var) == NULL) clean_return(ENOMEM) +#define alloc_field(var) \ + var = calloc(1,sizeof(*var)); \ + if ((var) == NULL) clean_return(ENOMEM) /* * Allocate a principal and initialize enough fields for * krb5_free_principal to have defined behavior. */ #define alloc_principal(var) \ - alloc_field(var); \ - var->realm.data = NULL; \ - var->data = NULL + alloc_field(var); \ + var->realm.data = NULL; \ + var->data = NULL /* process encoding header ***************************************/ /* decode tag and check that it == [APPLICATION tagnum] */ #define check_apptag(tagexpect) \ -{ \ - taginfo t1; \ - retval = asn1_get_tag_2(&buf, &t1); \ - if (retval) clean_return (retval); \ - if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID); \ - if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE); \ - asn1class = t1.asn1class; \ - construction = t1.construction; \ - tagnum = t1.tagnum; \ -} + { \ + taginfo t1; \ + retval = asn1_get_tag_2(&buf, &t1); \ + if (retval) clean_return (retval); \ + if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE); \ + asn1class = t1.asn1class; \ + construction = t1.construction; \ + tagnum = t1.tagnum; \ + } /* process a structure *******************************************/ /* decode an explicit tag and place the number in tagnum */ -#define next_tag_from_buf(buf) \ -{ taginfo t2; \ - retval = asn1_get_tag_2(&(buf), &t2); \ - if (retval) clean_return(retval); \ - asn1class = t2.asn1class; \ - construction = t2.construction; \ - tagnum = t2.tagnum; \ - indef = t2.indef; \ - taglen = t2.length; \ -} +#define next_tag_from_buf(buf) \ + { taginfo t2; \ + retval = asn1_get_tag_2(&(buf), &t2); \ + if (retval) clean_return(retval); \ + asn1class = t2.asn1class; \ + construction = t2.construction; \ + tagnum = t2.tagnum; \ + indef = t2.indef; \ + taglen = t2.length; \ + } #define next_tag() next_tag_from_buf(subbuf) @@ -121,35 +123,36 @@ asn1_get_eoc_tag (asn1buf *buf) return 0; } -#define get_eoc() \ -{ \ - retval = asn1_get_eoc_tag(&subbuf); \ - if (retval) clean_return(retval); \ -} +#define get_eoc() \ + { \ + retval = asn1_get_eoc_tag(&subbuf); \ + if (retval) clean_return(retval); \ + } /* decode sequence header and initialize tagnum with the first field */ -#define begin_structure()\ -unsigned int taglen;\ -asn1buf subbuf;\ -int seqindef;\ -int indef;\ -retval = asn1_get_sequence(&buf,&length,&seqindef);\ -if (retval) clean_return(retval);\ -retval = asn1buf_imbed(&subbuf,&buf,length,seqindef);\ -if (retval) clean_return(retval);\ -next_tag() - -#define end_structure()\ -retval = asn1buf_sync(&buf,&subbuf,asn1class,tagnum,length,indef,seqindef);\ -if (retval) clean_return(retval) +#define begin_structure() \ + unsigned int taglen; \ + asn1buf subbuf; \ + int seqindef; \ + int indef; \ + retval = asn1_get_sequence(&buf,&length,&seqindef); \ + if (retval) clean_return(retval); \ + retval = asn1buf_imbed(&subbuf,&buf,length,seqindef); \ + if (retval) clean_return(retval); \ + next_tag() + +#define end_structure() \ + retval = asn1buf_sync(&buf,&subbuf,asn1class, \ + tagnum,length,indef,seqindef); \ + if (retval) clean_return(retval) /* process fields *******************************************/ /* normal fields ************************/ -#define get_field_body(var,decoder)\ -retval = decoder(&subbuf,&(var));\ -if (retval) clean_return(retval);\ -if (indef) { get_eoc(); }\ -next_tag() +#define get_field_body(var,decoder) \ + retval = decoder(&subbuf,&(var)); \ + if (retval) clean_return(retval); \ + if (indef) { get_eoc(); } \ + next_tag() /* * error_if_bad_tag @@ -157,74 +160,76 @@ next_tag() * Checks that the next tag is the expected one; returns with an error * if not. */ -#define error_if_bad_tag(tagexpect) \ - if (tagnum != (tagexpect)) { clean_return ((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); } - -/* decode a field (<[UNIVERSAL id]> <length> <contents>) - check that the id number == tagexpect then - decode into var - get the next tag */ -#define get_field(var,tagexpect,decoder)\ -error_if_bad_tag(tagexpect);\ -if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ - clean_return(ASN1_BAD_ID);\ -get_field_body(var,decoder) +#define error_if_bad_tag(tagexpect) \ + if (tagnum != (tagexpect)) { clean_return ((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); } + +/* + * decode a field (<[UNIVERSAL id]> <length> <contents>) + * check that the id number == tagexpect then + * decode into var + * get the next tag + */ +#define get_field(var,tagexpect,decoder) \ + error_if_bad_tag(tagexpect); \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + get_field_body(var,decoder) /* decode (or skip, if not present) an optional field */ #define opt_field(var,tagexpect,decoder) \ - if (asn1buf_remains(&subbuf, seqindef)) { \ - if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID); \ - if (tagnum == (tagexpect)) { \ - get_field_body(var,decoder); \ - } \ - } + if (asn1buf_remains(&subbuf, seqindef)) { \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + if (tagnum == (tagexpect)) { \ + get_field_body(var,decoder); \ + } \ + } /* field w/ accompanying length *********/ -#define get_lenfield_body(len,var,decoder)\ -retval = decoder(&subbuf,&(len),&(var));\ -if (retval) clean_return(retval);\ -if (indef) { get_eoc(); }\ -next_tag() +#define get_lenfield_body(len,var,decoder) \ + retval = decoder(&subbuf,&(len),&(var)); \ + if (retval) clean_return(retval); \ + if (indef) { get_eoc(); } \ + next_tag() /* decode a field w/ its length (for string types) */ -#define get_lenfield(len,var,tagexpect,decoder)\ -error_if_bad_tag(tagexpect);\ -if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ - clean_return(ASN1_BAD_ID);\ -get_lenfield_body(len,var,decoder) +#define get_lenfield(len,var,tagexpect,decoder) \ + error_if_bad_tag(tagexpect); \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + get_lenfield_body(len,var,decoder) /* decode an optional field w/ length */ #define opt_lenfield(len,var,tagexpect,decoder) \ - if (asn1buf_remains(&subbuf, seqindef)) { \ - if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID); \ - if (tagnum == (tagexpect)) { \ - get_lenfield_body(len,var,decoder); \ - } \ - } + if (asn1buf_remains(&subbuf, seqindef)) { \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + if (tagnum == (tagexpect)) { \ + get_lenfield_body(len,var,decoder); \ + } \ + } /* clean up ******************************************************/ /* finish up */ /* to make things less painful, assume the cleanup is passed rep */ -#define cleanup(cleanup_routine)\ - *repptr = rep; \ - return 0; \ -error_out: \ - if (rep) \ - cleanup_routine(rep); \ - return retval; - -#define cleanup_none()\ - *repptr = rep; \ - return 0; \ -error_out: \ - return retval; - -#define cleanup_manual()\ - *repptr = rep; \ - return 0; +#define cleanup(cleanup_routine) \ + *repptr = rep; \ + return 0; \ +error_out: \ +if (rep) \ + cleanup_routine(rep); \ +return retval; + +#define cleanup_none() \ + *repptr = rep; \ + return 0; \ +error_out: \ +return retval; + +#define cleanup_manual() \ + *repptr = rep; \ + return 0; #define free_field(rep,f) free((rep)->f) #define clear_field(rep,f) (rep)->f = 0 @@ -264,8 +269,7 @@ error_out: } #endif -krb5_error_code -KRB5_CALLCONV +krb5_error_code KRB5_CALLCONV krb5_decode_ticket(const krb5_data *code, krb5_ticket **repptr) { return decode_krb5_ticket(code, repptr); @@ -1099,23 +1103,23 @@ decode_krb5_etype_list(const krb5_data *code, krb5_etype_list **repptr) 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); + 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 @@ -1126,13 +1130,13 @@ krb5_error_code decode_krb5_fast_req alloc_field(rep->req_body); clear_field(rep, req_body->padata); {begin_structure(); - get_field(rep->fast_options, 0, asn1_decode_krb5_flags); - 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(); } + get_field(rep->fast_options, 0, asn1_decode_krb5_flags); + 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_manual(); - error_out: +error_out: if (rep) { if (rep->req_body) krb5_free_kdc_req(0, rep->req_body); @@ -1151,10 +1155,10 @@ krb5_error_code decode_krb5_fast_response clear_field(rep, padata); clear_field(rep,strengthen_key); {begin_structure(); - get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data); - opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr); - opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr); - get_field(rep->nonce, 3, asn1_decode_int32); + get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data); + opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr); + opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr); + get_field(rep->nonce, 3, asn1_decode_int32); end_structure(); } rep->magic = KV5M_FAST_RESPONSE; cleanup(free); @@ -1173,15 +1177,15 @@ krb5_error_code decode_krb5_pa_fx_fast_reply clean_return(ASN1_BAD_ID); } {begin_structure(); - get_field(*rep, 0, asn1_decode_encrypted_data); - end_structure(); + get_field(*rep, 0, asn1_decode_encrypted_data); + end_structure(); } cleanup(free); } -krb5_error_code decode_krb5_ad_kdcissued -(const krb5_data *code, krb5_ad_kdcissued **repptr) +krb5_error_code +decode_krb5_ad_kdcissued(const krb5_data *code, krb5_ad_kdcissued **repptr) { setup_buf_only(krb5_ad_kdcissued *); alloc_field(rep); @@ -1192,8 +1196,8 @@ krb5_error_code decode_krb5_ad_kdcissued cleanup(free); } -krb5_error_code decode_krb5_ad_signedpath -(const krb5_data *code, krb5_ad_signedpath **repptr) +krb5_error_code +decode_krb5_ad_signedpath(const krb5_data *code, krb5_ad_signedpath **repptr) { setup_buf_only(krb5_ad_signedpath *); alloc_field(rep); @@ -1218,12 +1222,12 @@ krb5int_get_authdata_containee_types(krb5_context context, *num = 0; { - setup_buf_only(krb5_authdatatype *); + setup_buf_only(krb5_authdatatype *); - retval = asn1_peek_authorization_data(&buf, num, &rep); - if (retval) clean_return(retval); + retval = asn1_peek_authorization_data(&buf, num, &rep); + if (retval) clean_return(retval); - cleanup_none(); + cleanup_none(); } assert(0); /* NOTREACHED */ } |