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