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