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__
34 typedef struct asn1buf_st asn1buf;
38 asn1_construction construction;
41 /* When decoding, stores the leading and trailing lengths of a tag. Used
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,
54 krb5_error_code k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val,
56 krb5_error_code k5_asn1_encode_generaltime(asn1buf *buf, time_t val);
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,
62 krb5_error_code k5_asn1_decode_int(const uint8_t *asn1, size_t len,
64 krb5_error_code k5_asn1_decode_uint(const uint8_t *asn1, size_t len,
66 krb5_error_code k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len,
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);
74 * An atype_info structure specifies how to map a C object to an ASN.1 value.
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
84 * It's a work in progress.
88 /* For bounds checking only. By starting with 2, we guarantee that
89 * zero-initialized storage will be recognized as invalid. */
91 /* Use a function table to handle encoding or decoding. tinfo is a struct
94 /* C object is a pointer to the object to be encoded or decoded. tinfo is
95 * a struct ptr_info *. */
97 /* C object to be encoded or decoded is at an offset from the original
98 * pointer. tinfo is a struct offset_info *. */
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.
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 *.
113 /* Sequence. tinfo is a struct seq_info *. */
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
121 atype_nullterm_sequence_of,
122 atype_nonempty_nullterm_sequence_of,
123 /* Tagged version of another type. tinfo is a struct tagged_info *. */
125 /* Boolean value. tinfo is NULL (size field determines C type width). */
127 /* Signed or unsigned integer. tinfo is NULL. */
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).
137 /* Unused except for bounds checking. */
142 enum atype_type type;
143 size_t size; /* Used for sequence-of processing */
144 const void *tinfo; /* Points to type-specific structure */
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 *);
155 void *(*loadptr)(const void *);
156 void (*storeptr)(void *, void *);
157 const struct atype_info *basetype;
161 unsigned int dataoff : 9;
162 const struct atype_info *basetype;
165 struct optional_info {
166 int (*is_present)(const void *);
167 void (*init)(void *);
168 const struct atype_info *basetype;
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;
180 unsigned int tagval : 16, tagtype : 8, construction : 6, implicit : 1;
181 const struct atype_info *basetype;
184 struct immediate_info {
189 /* A cntype_info structure specifies how to map a C object and count (length or
190 * union distinguisher) to an ASN.1 value. */
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 *.
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.
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. */
213 /* An ASN.1 choice, represented in C as a distinguisher and union. tinfo
214 * is a struct choice_info *. */
221 enum cntype_type type;
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;
232 const struct atype_info **options;
237 const struct atype_info **fields;
239 /* Currently all sequences are assumed to be extensible. */
243 * The various DEF*TYPE macros must:
245 * + Define a type named aux_type_##DESCNAME, for use in any types derived from
246 * the type being defined.
248 * + Define an atype_info struct named k5_atype_##DESCNAME
250 * + Define a type-specific structure, referenced by the tinfo field
251 * of the atype_info structure.
253 * + Define any extra stuff needed in the type descriptor, like
254 * pointer-load functions.
256 * + Accept a following semicolon syntactically, to keep Emacs parsing
257 * (and indentation calculating) code happy.
259 * Nothing else should directly define the atype_info structures.
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 \
268 const struct atype_info k5_atype_##DESCNAME = { \
269 atype_fn, sizeof(CTYPENAME), &aux_info_##DESCNAME \
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]) \
278 const struct atype_info k5_atype_##DESCNAME = { \
279 atype_sequence, sizeof(CTYPENAME), &aux_seqinfo_##DESCNAME \
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 \
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 \
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 \
298 #define DEFINT_IMMEDIATE(DESCNAME, VAL, ERR) \
299 typedef int aux_type_##DESCNAME; \
300 static const struct immediate_info aux_info_##DESCNAME = { \
303 const struct atype_info k5_atype_##DESCNAME = { \
304 atype_int_immediate, 0, &aux_info_##DESCNAME \
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 \
314 const struct atype_info k5_atype_##DESCNAME = { \
315 atype_ptr, sizeof(aux_type_##DESCNAME), \
316 &aux_info_##DESCNAME \
319 #define DEFPTRTYPE(DESCNAME,BASEDESCNAME) \
320 typedef aux_type_##BASEDESCNAME *aux_type_##DESCNAME; \
322 aux_loadptr_##DESCNAME(const void *p) \
324 return *(aux_type_##DESCNAME *)p; \
327 aux_storeptr_##DESCNAME(void *ptr, void *val) \
329 *(aux_type_##DESCNAME *)val = ptr; \
331 static const struct ptr_info aux_info_##DESCNAME = { \
332 aux_loadptr_##DESCNAME, aux_storeptr_##DESCNAME, \
333 &k5_atype_##BASEDESCNAME \
335 const struct atype_info k5_atype_##DESCNAME = { \
336 atype_ptr, sizeof(aux_type_##DESCNAME), \
337 &aux_info_##DESCNAME \
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 \
346 const struct atype_info k5_atype_##DESCNAME = { \
347 atype_offset, sizeof(aux_type_##DESCNAME), \
348 &aux_info_##DESCNAME \
350 #define DEFCOUNTEDTYPE_base(DESCNAME, STYPE, DATAFIELD, COUNTFIELD, SIGNED, \
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), \
359 const struct atype_info k5_atype_##DESCNAME = { \
360 atype_counted, sizeof(STYPE), \
361 &aux_info_##DESCNAME \
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)
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 \
375 const struct atype_info k5_atype_##DESCNAME = { \
376 atype_optional, sizeof(aux_type_##DESCNAME), \
377 &aux_info_##DESCNAME \
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) \
383 aux_present_##DESCNAME(const void *p) \
385 return *(aux_type_##BASEDESC *)p != 0; \
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) \
392 aux_present_##DESCNAME(const void *p) \
394 const aux_type_##BASEDESC *val = p; \
395 return (*val != NULL && **val != NULL); \
397 DEFOPTIONALTYPE(DESCNAME, aux_present_##DESCNAME, NULL, BASEDESC)
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.
404 * BASEDESCNAME is a descriptor name for the pointer-to-thing
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.
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 \
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 \
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 \
432 const struct atype_info k5_atype_##DESCNAME = { \
433 atype_tagged_thing, sizeof(aux_type_##DESCNAME), \
434 &aux_info_##DESCNAME \
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)
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)
460 * DEFCOUNTED*TYPE macros must:
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.
466 * + Define a cntype_info struct named k5_cntype_##DESCNAME
468 * + Define a type-specific structure, referenced by the tinfo field of the
469 * cntype_info structure.
471 * + Accept a following semicolon syntactically.
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 \
480 const struct cntype_info k5_cntype_##DESCNAME = { \
481 cntype_string, &aux_info_##DESCNAME \
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 = { \
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 \
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]) \
504 const struct cntype_info k5_cntype_##DESCNAME = { \
505 cntype_choice, &aux_info_##DESCNAME \
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
519 #define IMPORT_TYPE(DESCNAME, CTYPENAME) \
520 typedef CTYPENAME aux_type_##DESCNAME; \
521 extern const struct atype_info k5_atype_##DESCNAME
523 /* Partially encode the contents of a type and return its tag information.
524 * Used only by kdc_req_body. */
526 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
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. */
532 k5_asn1_decode_atype(const taginfo *t, const uint8_t *asn1, size_t len,
533 const struct atype_info *a, void *val);
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);
541 k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a,
544 #define MAKE_ENCODER(FNAME, DESC) \
546 FNAME(const aux_type_##DESC *rep, krb5_data **code_out) \
548 return k5_asn1_full_encode(rep, &k5_atype_##DESC, code_out); \
550 extern int dummy /* gobble semicolon */
552 #define MAKE_DECODER(FNAME, DESC) \
554 FNAME(const krb5_data *code, aux_type_##DESC **rep_out) \
556 krb5_error_code ret; \
559 ret = k5_asn1_full_decode(code, &k5_atype_##DESC, &rep); \
565 extern int dummy /* gobble semicolon */
570 * Like "offsetof", but with type checking.
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))