1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/asn.1/asn1_encode.h */
4 * Copyright 1994, 2008 by the Massachusetts Institute of Technology.
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.
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.
27 #ifndef __ASN1_ENCODE_H__
28 #define __ASN1_ENCODE_H__
37 asn1_construction construction;
40 /* When decoding, stores the leading and trailing lengths of a tag. Used
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,
50 asn1_error_code k5_asn1_encode_int(asn1buf *buf, intmax_t val,
52 asn1_error_code k5_asn1_encode_uint(asn1buf *buf, uintmax_t val,
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,
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,
67 asn1_error_code k5_asn1_decode_int(const unsigned char *asn1, size_t len,
69 asn1_error_code k5_asn1_decode_uint(const unsigned char *asn1, size_t len,
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,
76 asn1_error_code k5_asn1_decode_bitstring(const unsigned char *asn1, size_t len,
77 unsigned char **bits_out,
81 * An atype_info structure specifies how to map a C object to an ASN.1 value.
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
91 * It's a work in progress.
95 /* For bounds checking only. By starting with 2, we guarantee that
96 * zero-initialized storage will be recognized as invalid. */
98 /* Use a function table to handle encoding or decoding. tinfo is a struct
101 /* C object is a pointer to the object to be encoded or decoded. tinfo is
102 * a struct ptr_info *. */
104 /* C object to be encoded or decoded is at an offset from the original
105 * pointer. tinfo is a struct offset_info *. */
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.
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 *.
120 /* Sequence. tinfo is a struct seq_info *. */
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
128 atype_nullterm_sequence_of,
129 atype_nonempty_nullterm_sequence_of,
130 /* Tagged version of another type. tinfo is a struct tagged_info *. */
132 /* Boolean value. tinfo is NULL (size field determines C type width). */
134 /* Signed or unsigned integer. tinfo is NULL. */
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).
144 /* Unused except for bounds checking. */
149 enum atype_type type;
150 size_t size; /* Used for sequence-of processing */
151 const void *tinfo; /* Points to type-specific structure */
155 asn1_error_code (*enc)(asn1buf *, const void *, taginfo *, size_t *);
156 asn1_error_code (*dec)(const taginfo *, const unsigned char *, size_t,
158 int (*check_tag)(const taginfo *);
159 void (*free_func)(void *);
163 void *(*loadptr)(const void *);
164 void (*storeptr)(void *, void *);
165 const struct atype_info *basetype;
169 unsigned int dataoff : 9;
170 const struct atype_info *basetype;
173 struct optional_info {
174 int (*is_present)(const void *);
175 void (*init)(void *);
176 const struct atype_info *basetype;
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;
188 unsigned int tagval : 16, tagtype : 8, construction : 6, implicit : 1;
189 const struct atype_info *basetype;
192 struct immediate_info {
197 /* A cntype_info structure specifies how to map a C object and count (length or
198 * union distinguisher) to an ASN.1 value. */
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 *.
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.
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. */
221 /* An ASN.1 choice, represented in C as a distinguisher and union. tinfo
222 * is a struct choice_info *. */
229 enum cntype_type type;
234 asn1_error_code (*enc)(asn1buf *, unsigned char *const *, size_t,
236 asn1_error_code (*dec)(const unsigned char *, size_t, unsigned char **,
238 unsigned int tagval : 5;
242 const struct atype_info **options;
247 const struct atype_info **fields;
249 /* Currently all sequences are assumed to be extensible. */
253 * The various DEF*TYPE macros must:
255 * + Define a type named aux_type_##DESCNAME, for use in any types derived from
256 * the type being defined.
258 * + Define an atype_info struct named k5_atype_##DESCNAME
260 * + Define a type-specific structure, referenced by the tinfo field
261 * of the atype_info structure.
263 * + Define any extra stuff needed in the type descriptor, like
264 * pointer-load functions.
266 * + Accept a following semicolon syntactically, to keep Emacs parsing
267 * (and indentation calculating) code happy.
269 * Nothing else should directly define the atype_info structures.
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 \
278 const struct atype_info k5_atype_##DESCNAME = { \
279 atype_fn, sizeof(CTYPENAME), &aux_info_##DESCNAME \
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]) \
288 const struct atype_info k5_atype_##DESCNAME = { \
289 atype_sequence, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME \
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 \
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 \
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 \
308 #define DEFINT_IMMEDIATE(DESCNAME, VAL, ERR) \
309 typedef int aux_type_##DESCNAME; \
310 static const struct immediate_info aux_info_##DESCNAME = { \
313 const struct atype_info k5_atype_##DESCNAME = { \
314 atype_int_immediate, 0, &aux_info_##DESCNAME \
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 \
324 const struct atype_info k5_atype_##DESCNAME = { \
325 atype_ptr, sizeof(aux_type_##DESCNAME), \
326 &aux_info_##DESCNAME \
329 #define DEFPTRTYPE(DESCNAME,BASEDESCNAME) \
330 typedef aux_type_##BASEDESCNAME *aux_type_##DESCNAME; \
332 aux_loadptr_##DESCNAME(const void *p) \
334 return *(aux_type_##DESCNAME *)p; \
337 aux_storeptr_##DESCNAME(void *ptr, void *val) \
339 *(aux_type_##DESCNAME *)val = ptr; \
341 static const struct ptr_info aux_info_##DESCNAME = { \
342 aux_loadptr_##DESCNAME, aux_storeptr_##DESCNAME, \
343 &k5_atype_##BASEDESCNAME \
345 const struct atype_info k5_atype_##DESCNAME = { \
346 atype_ptr, sizeof(aux_type_##DESCNAME), \
347 &aux_info_##DESCNAME \
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 \
356 const struct atype_info k5_atype_##DESCNAME = { \
357 atype_offset, sizeof(aux_type_##DESCNAME), \
358 &aux_info_##DESCNAME \
360 #define DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, SIGNED, \
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), \
369 const struct atype_info k5_atype_##DESCNAME = { \
370 atype_counted, sizeof(STYPE), \
371 &aux_info_##DESCNAME \
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)
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 \
385 const struct atype_info k5_atype_##DESCNAME = { \
386 atype_optional, sizeof(aux_type_##DESCNAME), \
387 &aux_info_##DESCNAME \
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) \
393 aux_present_##DESCNAME(const void *p) \
395 return *(aux_type_##BASEDESC *)p != 0; \
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) \
402 aux_present_##DESCNAME(const void *p) \
404 const aux_type_##BASEDESC *val = p; \
405 return (*val != NULL && **val != NULL); \
407 DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, NULL, BASEDESC)
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.
414 * BASEDESCNAME is a descriptor name for the pointer-to-thing
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.
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 \
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 \
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 \
442 const struct atype_info k5_atype_##DESCNAME = { \
443 atype_tagged_thing, sizeof(aux_type_##DESCNAME), \
444 &aux_info_##DESCNAME \
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)
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)
470 * DEFCOUNTED*TYPE macros must:
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.
476 * + Define a cntype_info struct named k5_cntype_##DESCNAME
478 * + Define a type-specific structure, referenced by the tinfo field of the
479 * cntype_info structure.
481 * + Accept a following semicolon syntactically.
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 \
490 const struct cntype_info k5_cntype_##DESCNAME = { \
491 cntype_string, &aux_info_##DESCNAME \
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 = { \
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 \
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]) \
514 const struct cntype_info k5_cntype_##DESCNAME = { \
515 cntype_choice, &aux_info_##DESCNAME \
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
529 #define IMPORT_TYPE(DESCNAME, CTYPENAME) \
530 typedef CTYPENAME aux_type_##DESCNAME; \
531 extern const struct atype_info k5_atype_##DESCNAME
533 /* Partially encode the contents of a type and return its tag information.
534 * Used only by kdc_req_body. */
536 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
537 taginfo *tag_out, size_t *len_out);
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. */
542 k5_asn1_decode_atype(const taginfo *t, const unsigned char *asn1,
543 size_t len, const struct atype_info *a, void *val);
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);
551 k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a,
554 #define MAKE_ENCODER(FNAME, DESC) \
556 FNAME(const aux_type_##DESC *rep, krb5_data **code_out) \
558 return k5_asn1_full_encode(rep, &k5_atype_##DESC, code_out); \
560 extern int dummy /* gobble semicolon */
562 #define MAKE_DECODER(FNAME, DESC) \
564 FNAME(const krb5_data *code, aux_type_##DESC **rep_out) \
566 asn1_error_code ret; \
569 ret = k5_asn1_full_decode(code, &k5_atype_##DESC, &rep); \
575 extern int dummy /* gobble semicolon */
580 * Like "offsetof", but with type checking.
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))