Fix autoconf 2.70 compatibility
[platform/upstream/krb5.git] / src / lib / krb5 / asn.1 / asn1_encode.h
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/asn.1/asn1_encode.h */
3 /*
4  * Copyright 1994, 2008 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26
27 #ifndef __ASN1_ENCODE_H__
28 #define __ASN1_ENCODE_H__
29
30 #include "k5-int.h"
31 #include "krbasn1.h"
32 #include <time.h>
33
34 typedef struct asn1buf_st asn1buf;
35
36 typedef struct {
37     asn1_class asn1class;
38     asn1_construction construction;
39     asn1_tagnum tagnum;
40
41     /* When decoding, stores the leading and trailing lengths of a tag.  Used
42      * by store_der(). */
43     size_t tag_len;
44     size_t tag_end_len;
45 } taginfo;
46
47 /* These functions are referenced by encoder structures.  They handle the
48  * encoding of primitive ASN.1 types. */
49 void k5_asn1_encode_bool(asn1buf *buf, intmax_t val);
50 void k5_asn1_encode_int(asn1buf *buf, intmax_t val);
51 void k5_asn1_encode_uint(asn1buf *buf, uintmax_t val);
52 krb5_error_code k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val,
53                                           size_t len);
54 krb5_error_code k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val,
55                                          size_t len);
56 krb5_error_code k5_asn1_encode_generaltime(asn1buf *buf, time_t val);
57
58 /* These functions are referenced by encoder structures.  They handle the
59  * decoding of primitive ASN.1 types. */
60 krb5_error_code k5_asn1_decode_bool(const uint8_t *asn1, size_t len,
61                                     intmax_t *val);
62 krb5_error_code k5_asn1_decode_int(const uint8_t *asn1, size_t len,
63                                    intmax_t *val);
64 krb5_error_code k5_asn1_decode_uint(const uint8_t *asn1, size_t len,
65                                     uintmax_t *val);
66 krb5_error_code k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len,
67                                            time_t *time_out);
68 krb5_error_code k5_asn1_decode_bytestring(const uint8_t *asn1, size_t len,
69                                           uint8_t **str_out, size_t *len_out);
70 krb5_error_code k5_asn1_decode_bitstring(const uint8_t *asn1, size_t len,
71                                          uint8_t **bits_out, size_t *len_out);
72
73 /*
74  * An atype_info structure specifies how to map a C object to an ASN.1 value.
75  *
76  * We wind up with a lot of load-time relocations being done, which is
77  * a bit annoying.  Be careful about "fixing" that at the cost of too
78  * much run-time performance.  It might work to have a master "module"
79  * descriptor with pointers to various arrays (type descriptors,
80  * strings, field descriptors, functions) most of which don't need
81  * relocation themselves, and replace most of the pointers with table
82  * indices.
83  *
84  * It's a work in progress.
85  */
86
87 enum atype_type {
88     /* For bounds checking only.  By starting with 2, we guarantee that
89      * zero-initialized storage will be recognized as invalid. */
90     atype_min = 1,
91     /* Use a function table to handle encoding or decoding.  tinfo is a struct
92      * fn_info *. */
93     atype_fn,
94     /* C object is a pointer to the object to be encoded or decoded.  tinfo is
95      * a struct ptr_info *. */
96     atype_ptr,
97     /* C object to be encoded or decoded is at an offset from the original
98      * pointer.  tinfo is a struct offset_info *. */
99     atype_offset,
100     /*
101      * Indicates a sequence field which may or may not be present in the C
102      * object or ASN.1 sequence.  tinfo is a struct optional_info *.  Must be
103      * used within a sequence, although the optional type may be nested within
104      * offset, ptr, and/or tag types.
105      */
106     atype_optional,
107     /*
108      * C object contains an integer and another C object at specified offsets,
109      * to be combined and encoded or decoded as specified by a cntype_info
110      * structure.  tinfo is a struct counted_info *.
111      */
112     atype_counted,
113     /* Sequence.  tinfo is a struct seq_info *. */
114     atype_sequence,
115     /*
116      * Sequence-of, with pointer to base type descriptor, represented as a
117      * null-terminated array of pointers (and thus the "base" type descriptor
118      * is actually an atype_ptr node).  tinfo is a struct atype_info * giving
119      * the base type.
120      */
121     atype_nullterm_sequence_of,
122     atype_nonempty_nullterm_sequence_of,
123     /* Tagged version of another type.  tinfo is a struct tagged_info *. */
124     atype_tagged_thing,
125     /* Boolean value.  tinfo is NULL (size field determines C type width). */
126     atype_bool,
127     /* Signed or unsigned integer.  tinfo is NULL. */
128     atype_int,
129     atype_uint,
130     /*
131      * Integer value taken from the type info, not from the object being
132      * encoded.  tinfo is a struct immediate_info * giving the integer value
133      * and error code to return if a decoded object doesn't match it (or 0 if
134      * the value shouldn't be checked on decode).
135      */
136     atype_int_immediate,
137     /* Unused except for bounds checking.  */
138     atype_max
139 };
140
141 struct atype_info {
142     enum atype_type type;
143     size_t size;                /* Used for sequence-of processing */
144     const void *tinfo;          /* Points to type-specific structure */
145 };
146
147 struct fn_info {
148     krb5_error_code (*enc)(asn1buf *, const void *, taginfo *);
149     krb5_error_code (*dec)(const taginfo *, const uint8_t *, size_t, void *);
150     int (*check_tag)(const taginfo *);
151     void (*free_func)(void *);
152 };
153
154 struct ptr_info {
155     void *(*loadptr)(const void *);
156     void (*storeptr)(void *, void *);
157     const struct atype_info *basetype;
158 };
159
160 struct offset_info {
161     unsigned int dataoff : 9;
162     const struct atype_info *basetype;
163 };
164
165 struct optional_info {
166     int (*is_present)(const void *);
167     void (*init)(void *);
168     const struct atype_info *basetype;
169 };
170
171 struct counted_info {
172     unsigned int dataoff : 9;
173     unsigned int lenoff : 9;
174     unsigned int lensigned : 1;
175     unsigned int lensize : 5;
176     const struct cntype_info *basetype;
177 };
178
179 struct tagged_info {
180     unsigned int tagval : 16, tagtype : 8, construction : 6, implicit : 1;
181     const struct atype_info *basetype;
182 };
183
184 struct immediate_info {
185     intmax_t val;
186     krb5_error_code err;
187 };
188
189 /* A cntype_info structure specifies how to map a C object and count (length or
190  * union distinguisher) to an ASN.1 value. */
191
192 enum cntype_type {
193     cntype_min = 1,
194
195     /*
196      * Apply an encoder function (contents only) and wrap it in a universal
197      * primitive tag.  The C object must be a char * or uint8_t *.  tinfo
198      * is a struct string_info *.
199      */
200     cntype_string,
201
202     /*
203      * The C object is a DER encoding (with tag), to be simply inserted on
204      * encode or stored on decode.  The C object must be a char * or unsigned
205      * char *.  tinfo is NULL.
206      */
207     cntype_der,
208
209     /* An ASN.1 sequence-of value, represtened in C as a counted array.  struct
210      * atype_info * giving the base type, which must be of type atype_ptr. */
211     cntype_seqof,
212
213     /* An ASN.1 choice, represented in C as a distinguisher and union.  tinfo
214      * is a struct choice_info *. */
215     cntype_choice,
216
217     cntype_max
218 };
219
220 struct cntype_info {
221     enum cntype_type type;
222     const void *tinfo;
223 };
224
225 struct string_info {
226     krb5_error_code (*enc)(asn1buf *, uint8_t *const *, size_t);
227     krb5_error_code (*dec)(const uint8_t *, size_t, uint8_t **, size_t *);
228     unsigned int tagval : 5;
229 };
230
231 struct choice_info {
232     const struct atype_info **options;
233     size_t n_options;
234 };
235
236 struct seq_info {
237     const struct atype_info **fields;
238     size_t n_fields;
239     /* Currently all sequences are assumed to be extensible. */
240 };
241
242 /*
243  * The various DEF*TYPE macros must:
244  *
245  * + Define a type named aux_type_##DESCNAME, for use in any types derived from
246  *   the type being defined.
247  *
248  * + Define an atype_info struct named k5_atype_##DESCNAME
249  *
250  * + Define a type-specific structure, referenced by the tinfo field
251  *   of the atype_info structure.
252  *
253  * + Define any extra stuff needed in the type descriptor, like
254  *   pointer-load functions.
255  *
256  * + Accept a following semicolon syntactically, to keep Emacs parsing
257  *   (and indentation calculating) code happy.
258  *
259  * Nothing else should directly define the atype_info structures.
260  */
261
262 /* Define a type using a function table. */
263 #define DEFFNTYPE(DESCNAME, CTYPENAME, ENCFN, DECFN, CHECKFN, FREEFN)   \
264     typedef CTYPENAME aux_type_##DESCNAME;                              \
265     static const struct fn_info aux_info_##DESCNAME = {                 \
266         ENCFN, DECFN, CHECKFN, FREEFN                                   \
267     };                                                                  \
268     const struct atype_info k5_atype_##DESCNAME = {                     \
269         atype_fn, sizeof(CTYPENAME), &aux_info_##DESCNAME               \
270     }
271 /* A sequence, defined by the indicated series of types, and an optional
272  * function indicating which fields are not present. */
273 #define DEFSEQTYPE(DESCNAME, CTYPENAME, FIELDS)                         \
274     typedef CTYPENAME aux_type_##DESCNAME;                              \
275     static const struct seq_info aux_seqinfo_##DESCNAME = {             \
276         FIELDS, sizeof(FIELDS)/sizeof(FIELDS[0])                        \
277     };                                                                  \
278     const struct atype_info k5_atype_##DESCNAME = {                     \
279         atype_sequence, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME      \
280     }
281 /* A boolean type. */
282 #define DEFBOOLTYPE(DESCNAME, CTYPENAME)                        \
283     typedef CTYPENAME aux_type_##DESCNAME;                      \
284     const struct atype_info k5_atype_##DESCNAME = {             \
285         atype_bool, sizeof(CTYPENAME), NULL                     \
286     }
287 /* Integer types.  */
288 #define DEFINTTYPE(DESCNAME, CTYPENAME)                         \
289     typedef CTYPENAME aux_type_##DESCNAME;                      \
290     const struct atype_info k5_atype_##DESCNAME = {             \
291         atype_int, sizeof(CTYPENAME), NULL                      \
292     }
293 #define DEFUINTTYPE(DESCNAME, CTYPENAME)                        \
294     typedef CTYPENAME aux_type_##DESCNAME;                      \
295     const struct atype_info k5_atype_##DESCNAME = {             \
296         atype_uint, sizeof(CTYPENAME), NULL                     \
297     }
298 #define DEFINT_IMMEDIATE(DESCNAME, VAL, ERR)                    \
299     typedef int aux_type_##DESCNAME;                            \
300     static const struct immediate_info aux_info_##DESCNAME = {  \
301         VAL, ERR                                                \
302     };                                                          \
303     const struct atype_info k5_atype_##DESCNAME = {             \
304         atype_int_immediate, 0, &aux_info_##DESCNAME            \
305     }
306
307 /* Pointers to other types, to be encoded as those other types.  */
308 #ifdef POINTERS_ARE_ALL_THE_SAME
309 #define DEFPTRTYPE(DESCNAME,BASEDESCNAME)                       \
310     typedef aux_type_##BASEDESCNAME *aux_type_##DESCNAME;       \
311     static const struct ptr_info aux_info_##DESCNAME = {        \
312         NULL, NULL, &k5_atype_##BASEDESCNAME                    \
313     };                                                          \
314     const struct atype_info k5_atype_##DESCNAME = {             \
315         atype_ptr, sizeof(aux_type_##DESCNAME),                 \
316         &aux_info_##DESCNAME                                    \
317     }
318 #else
319 #define DEFPTRTYPE(DESCNAME,BASEDESCNAME)                       \
320     typedef aux_type_##BASEDESCNAME *aux_type_##DESCNAME;       \
321     static void *                                               \
322     aux_loadptr_##DESCNAME(const void *p)                       \
323     {                                                           \
324         return *(aux_type_##DESCNAME *)p;                       \
325     }                                                           \
326     static void                                                 \
327     aux_storeptr_##DESCNAME(void *ptr, void *val)               \
328     {                                                           \
329         *(aux_type_##DESCNAME *)val = ptr;                      \
330     }                                                           \
331     static const struct ptr_info aux_info_##DESCNAME = {        \
332         aux_loadptr_##DESCNAME, aux_storeptr_##DESCNAME,        \
333         &k5_atype_##BASEDESCNAME                                \
334     };                                                          \
335     const struct atype_info k5_atype_##DESCNAME = {             \
336         atype_ptr, sizeof(aux_type_##DESCNAME),                 \
337         &aux_info_##DESCNAME                                    \
338     }
339 #endif
340 #define DEFOFFSETTYPE(DESCNAME, STYPE, FIELDNAME, BASEDESC)     \
341     typedef STYPE aux_type_##DESCNAME;                          \
342     static const struct offset_info aux_info_##DESCNAME = {     \
343         OFFOF(STYPE, FIELDNAME, aux_type_##BASEDESC),           \
344         &k5_atype_##BASEDESC                                    \
345     };                                                          \
346     const struct atype_info k5_atype_##DESCNAME = {             \
347         atype_offset, sizeof(aux_type_##DESCNAME),              \
348         &aux_info_##DESCNAME                                    \
349     }
350 #define DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, SIGNED, \
351                             CDESC)                                      \
352     typedef STYPE aux_type_##DESCNAME;                                  \
353     const struct counted_info aux_info_##DESCNAME = {                   \
354         OFFOF(STYPE, DATAFIELD, aux_ptrtype_##CDESC),                   \
355         OFFOF(STYPE, COUNTFIELD, aux_counttype_##CDESC),                \
356         SIGNED, sizeof(((STYPE*)0)->COUNTFIELD),                        \
357         &k5_cntype_##CDESC                                              \
358     };                                                                  \
359     const struct atype_info k5_atype_##DESCNAME = {                     \
360         atype_counted, sizeof(STYPE),                                   \
361         &aux_info_##DESCNAME                                            \
362     }
363 #define DEFCOUNTEDTYPE(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, CDESC) \
364     DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, 0, CDESC)
365 #define DEFCOUNTEDTYPE_SIGNED(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, CDESC) \
366     DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, 1, CDESC)
367
368 /* Optional sequence fields.  The basic form allows arbitrary test and
369  * initializer functions to be used.  INIT may be null. */
370 #define DEFOPTIONALTYPE(DESCNAME, PRESENT, INIT, BASEDESC)       \
371     typedef aux_type_##BASEDESC aux_type_##DESCNAME;             \
372     static const struct optional_info aux_info_##DESCNAME = {   \
373         PRESENT, INIT, &k5_atype_##BASEDESC                     \
374     };                                                          \
375     const struct atype_info k5_atype_##DESCNAME = {             \
376         atype_optional, sizeof(aux_type_##DESCNAME),            \
377         &aux_info_##DESCNAME                                    \
378     }
379 /* This form defines an is_present function for a zero-valued integer or null
380  * pointer of the base type's C type. */
381 #define DEFOPTIONALZEROTYPE(DESCNAME, BASEDESC)                         \
382     static int                                                          \
383     aux_present_##DESCNAME(const void *p)                               \
384     {                                                                   \
385         return *(aux_type_##BASEDESC *)p != 0;                          \
386     }                                                                   \
387     DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, NULL, BASEDESC)
388 /* This form defines an is_present function for a null or empty null-terminated
389  * array of the base type's C type. */
390 #define DEFOPTIONALEMPTYTYPE(DESCNAME, BASEDESC)                        \
391     static int                                                          \
392     aux_present_##DESCNAME(const void *p)                               \
393     {                                                                   \
394         const aux_type_##BASEDESC *val = p;                             \
395         return (*val != NULL && **val != NULL);                         \
396     }                                                                   \
397     DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, NULL, BASEDESC)
398
399 /*
400  * This encodes a pointer-to-pointer-to-thing where the passed-in
401  * value points to a null-terminated list of pointers to objects to be
402  * encoded, and encodes a (possibly empty) SEQUENCE OF these objects.
403  *
404  * BASEDESCNAME is a descriptor name for the pointer-to-thing
405  * type.
406  *
407  * When dealing with a structure containing a
408  * pointer-to-pointer-to-thing field, make a DEFPTRTYPE of this type,
409  * and use that type for the structure field.
410  */
411 #define DEFNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME)                     \
412     typedef aux_type_##BASEDESCNAME aux_type_##DESCNAME;                \
413     const struct atype_info k5_atype_##DESCNAME = {                     \
414         atype_nullterm_sequence_of, sizeof(aux_type_##DESCNAME),        \
415         &k5_atype_##BASEDESCNAME                                        \
416     }
417 #define DEFNONEMPTYNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME)     \
418     typedef aux_type_##BASEDESCNAME aux_type_##DESCNAME;        \
419     const struct atype_info k5_atype_##DESCNAME = {             \
420         atype_nonempty_nullterm_sequence_of,                    \
421         sizeof(aux_type_##DESCNAME),                            \
422         &k5_atype_##BASEDESCNAME                                \
423     }
424
425 /* Objects with an explicit or implicit tag.  (Implicit tags will ignore the
426  * construction field.) */
427 #define DEFTAGGEDTYPE(DESCNAME, CLASS, CONSTRUCTION, TAG, IMPLICIT, BASEDESC) \
428     typedef aux_type_##BASEDESC aux_type_##DESCNAME;                    \
429     static const struct tagged_info aux_info_##DESCNAME = {             \
430         TAG, CLASS, CONSTRUCTION, IMPLICIT, &k5_atype_##BASEDESC        \
431     };                                                                  \
432     const struct atype_info k5_atype_##DESCNAME = {                     \
433         atype_tagged_thing, sizeof(aux_type_##DESCNAME),                \
434         &aux_info_##DESCNAME                                            \
435     }
436 /* Objects with an explicit APPLICATION tag added.  */
437 #define DEFAPPTAGGEDTYPE(DESCNAME, TAG, BASEDESC)                       \
438     DEFTAGGEDTYPE(DESCNAME, APPLICATION, CONSTRUCTED, TAG, 0, BASEDESC)
439 /* Object with a context-specific tag added */
440 #define DEFCTAGGEDTYPE(DESCNAME, TAG, BASEDESC)                         \
441     DEFTAGGEDTYPE(DESCNAME, CONTEXT_SPECIFIC, CONSTRUCTED, TAG, 0, BASEDESC)
442 #define DEFCTAGGEDTYPE_IMPLICIT(DESCNAME, TAG, BASEDESC)                \
443     DEFTAGGEDTYPE(DESCNAME, CONTEXT_SPECIFIC, CONSTRUCTED, TAG, 1, BASEDESC)
444
445 /* Define an offset type with an explicit context tag wrapper (the usual case
446  * for an RFC 4120 sequence field). */
447 #define DEFFIELD(NAME, STYPE, FIELDNAME, TAG, DESC)                     \
448     DEFOFFSETTYPE(NAME##_untagged, STYPE, FIELDNAME, DESC);             \
449     DEFCTAGGEDTYPE(NAME, TAG, NAME##_untagged)
450 /* Define a counted type with an explicit context tag wrapper. */
451 #define DEFCNFIELD(NAME, STYPE, DATAFIELD, LENFIELD, TAG, CDESC)        \
452     DEFCOUNTEDTYPE(NAME##_untagged, STYPE, DATAFIELD, LENFIELD, CDESC); \
453     DEFCTAGGEDTYPE(NAME, TAG, NAME##_untagged)
454 /* Like DEFFIELD but with an implicit context tag. */
455 #define DEFFIELD_IMPLICIT(NAME, STYPE, FIELDNAME, TAG, DESC)            \
456     DEFOFFSETTYPE(NAME##_untagged, STYPE, FIELDNAME, DESC);             \
457     DEFCTAGGEDTYPE_IMPLICIT(NAME, TAG, NAME##_untagged)
458
459 /*
460  * DEFCOUNTED*TYPE macros must:
461  *
462  * + Define types named aux_ptrtype_##DESCNAME and aux_counttype_##DESCNAME, to
463  *   allow type checking when the counted type is referenced with structure
464  *   field offsets in DEFCOUNTEDTYPE.
465  *
466  * + Define a cntype_info struct named k5_cntype_##DESCNAME
467  *
468  * + Define a type-specific structure, referenced by the tinfo field of the
469  *   cntype_info structure.
470  *
471  * + Accept a following semicolon syntactically.
472  */
473
474 #define DEFCOUNTEDSTRINGTYPE(DESCNAME, DTYPE, LTYPE, ENCFN, DECFN, TAGVAL) \
475     typedef DTYPE aux_ptrtype_##DESCNAME;                               \
476     typedef LTYPE aux_counttype_##DESCNAME;                             \
477     static const struct string_info aux_info_##DESCNAME = {             \
478         ENCFN, DECFN, TAGVAL                                            \
479     };                                                                  \
480     const struct cntype_info k5_cntype_##DESCNAME = {                   \
481         cntype_string, &aux_info_##DESCNAME                             \
482     }
483
484 #define DEFCOUNTEDDERTYPE(DESCNAME, DTYPE, LTYPE)               \
485     typedef DTYPE aux_ptrtype_##DESCNAME;                       \
486     typedef LTYPE aux_counttype_##DESCNAME;                     \
487     const struct cntype_info k5_cntype_##DESCNAME = {           \
488         cntype_der, NULL                                        \
489     }
490
491 #define DEFCOUNTEDSEQOFTYPE(DESCNAME, LTYPE, BASEDESC)          \
492     typedef aux_type_##BASEDESC aux_ptrtype_##DESCNAME;         \
493     typedef LTYPE aux_counttype_##DESCNAME;                     \
494     const struct cntype_info k5_cntype_##DESCNAME = {           \
495         cntype_seqof, &k5_atype_##BASEDESC                      \
496     }
497
498 #define DEFCHOICETYPE(DESCNAME, UTYPE, DTYPE, FIELDS)           \
499     typedef UTYPE aux_ptrtype_##DESCNAME;                       \
500     typedef DTYPE aux_counttype_##DESCNAME;                     \
501     static const struct choice_info aux_info_##DESCNAME = {     \
502         FIELDS, sizeof(FIELDS) / sizeof(FIELDS[0])              \
503     };                                                          \
504     const struct cntype_info k5_cntype_##DESCNAME = {           \
505         cntype_choice, &aux_info_##DESCNAME                     \
506     }
507
508 /*
509  * Declare an externally-defined type.  This is a hack we should do
510  * away with once we move to generating code from a script.  For now,
511  * this macro is unfortunately not compatible with the defining macros
512  * above, since you can't do the typedefs twice and we need the
513  * declarations to produce typedefs.  (We could eliminate the typedefs
514  * from the DEF* macros, but then every DEF* macro use, even the ones
515  * for internal type nodes we only use to build other types, would
516  * need an accompanying declaration which explicitly lists the
517  * type.)
518  */
519 #define IMPORT_TYPE(DESCNAME, CTYPENAME)                        \
520     typedef CTYPENAME aux_type_##DESCNAME;                      \
521     extern const struct atype_info k5_atype_##DESCNAME
522
523 /* Partially encode the contents of a type and return its tag information.
524  * Used only by kdc_req_body. */
525 krb5_error_code
526 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
527                      taginfo *tag_out);
528
529 /* Decode the tag and contents of a type, storing the result in the
530  * caller-allocated C object val.  Used only by kdc_req_body. */
531 krb5_error_code
532 k5_asn1_decode_atype(const taginfo *t, const uint8_t *asn1, size_t len,
533                      const struct atype_info *a, void *val);
534
535 /* Returns a completed encoding, with tag and in the correct byte order, in an
536  * allocated krb5_data. */
537 extern krb5_error_code
538 k5_asn1_full_encode(const void *rep, const struct atype_info *a,
539                     krb5_data **code_out);
540 krb5_error_code
541 k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a,
542                     void **rep_out);
543
544 #define MAKE_ENCODER(FNAME, DESC)                                       \
545     krb5_error_code                                                     \
546     FNAME(const aux_type_##DESC *rep, krb5_data **code_out)             \
547     {                                                                   \
548         return k5_asn1_full_encode(rep, &k5_atype_##DESC, code_out);    \
549     }                                                                   \
550     extern int dummy /* gobble semicolon */
551
552 #define MAKE_DECODER(FNAME, DESC)                                       \
553     krb5_error_code                                                     \
554     FNAME(const krb5_data *code, aux_type_##DESC **rep_out)             \
555     {                                                                   \
556         krb5_error_code ret;                                            \
557         void *rep;                                                      \
558         *rep_out = NULL;                                                \
559         ret = k5_asn1_full_decode(code, &k5_atype_##DESC, &rep);        \
560         if (ret)                                                        \
561             return ret;                                                 \
562         *rep_out = rep;                                                 \
563         return 0;                                                       \
564     }                                                                   \
565     extern int dummy /* gobble semicolon */
566
567 #include <stddef.h>
568 /*
569  * Ugly hack!
570  * Like "offsetof", but with type checking.
571  */
572 #define WARN_IF_TYPE_MISMATCH(LVALUE, TYPE)     \
573     (sizeof(0 ? (TYPE *) 0 : &(LVALUE)))
574 #define OFFOF(TYPE,FIELD,FTYPE)                                 \
575     (offsetof(TYPE, FIELD)                                      \
576      + 0 * WARN_IF_TYPE_MISMATCH(((TYPE*)0)->FIELD, FTYPE))
577
578 #endif