1 /* -*- mode: c; indent-tabs-mode: nil -*- */ 2 /* 3 * src/lib/krb5/asn.1/asn1_encode.h 4 * 5 * Copyright 1994, 2008 by the Massachusetts Institute of Technology. 6 * All Rights Reserved. 7 * 8 * Export of this software from the United States of America may 9 * require a specific license from the United States Government. 10 * It is the responsibility of any person or organization contemplating 11 * export to obtain such a license before exporting. 12 * 13 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14 * distribute this software and its documentation for any purpose and 15 * without fee is hereby granted, provided that the above copyright 16 * notice appear in all copies and that both that copyright notice and 17 * this permission notice appear in supporting documentation, and that 18 * the name of M.I.T. not be used in advertising or publicity pertaining 19 * to distribution of the software without specific, written prior 20 * permission. Furthermore if you modify this software you must label 21 * your software as modified software and not distribute it in such a 22 * fashion that it might be confused with the original M.I.T. software. 23 * M.I.T. makes no representations about the suitability of 24 * this software for any purpose. It is provided "as is" without express 25 * or implied warranty. 26 */ 27 28 #ifndef __ASN1_ENCODE_H__ 29 #define __ASN1_ENCODE_H__ 30 31 #include "k5-int.h" 32 #include "krbasn1.h" 33 #include "asn1buf.h" 34 #include <time.h> 35 36 /* 37 Overview 38 39 Each of these procedures inserts the encoding of an ASN.1 40 primitive in a coding buffer. 41 42 Operations 43 44 asn1_encode_boolean 45 asn1_encode_integer 46 asn1_encode_unsigned_integer 47 asn1_encode_octetstring 48 asn1_encode_generaltime 49 asn1_encode_generalstring 50 asn1_encode_bitstring 51 asn1_encode_oid 52 */ 53 54 asn1_error_code asn1_encode_boolean 55 (asn1buf *buf, asn1_intmax val, unsigned int *retlen); 56 asn1_error_code asn1_encode_integer 57 (asn1buf *buf, asn1_intmax val, unsigned int *retlen); 58 /* requires *buf is allocated 59 modifies *buf, *retlen 60 effects Inserts the encoding of val into *buf and returns 61 the length of the encoding in *retlen. 62 Returns ENOMEM to signal an unsuccesful attempt 63 to expand the buffer. */ 64 65 asn1_error_code asn1_encode_enumerated 66 (asn1buf *buf, long val, unsigned int *retlen); 67 68 asn1_error_code asn1_encode_unsigned_integer 69 (asn1buf *buf, asn1_uintmax val, 70 unsigned int *retlen); 71 /* requires *buf is allocated 72 modifies *buf, *retlen 73 effects Inserts the encoding of val into *buf and returns 74 the length of the encoding in *retlen. 75 Returns ENOMEM to signal an unsuccesful attempt 76 to expand the buffer. */ 77 78 asn1_error_code asn1_encode_octetstring 79 (asn1buf *buf, 80 unsigned int len, const void *val, 81 unsigned int *retlen); 82 /* requires *buf is allocated 83 modifies *buf, *retlen 84 effects Inserts the encoding of val into *buf and returns 85 the length of the encoding in *retlen. 86 Returns ENOMEM to signal an unsuccesful attempt 87 to expand the buffer. */ 88 #define asn1_encode_charstring asn1_encode_octetstring 89 90 asn1_error_code asn1_encode_oid 91 (asn1buf *buf, 92 unsigned int len, const asn1_octet *val, 93 unsigned int *retlen); 94 /* requires *buf is allocated 95 modifies *buf, *retlen 96 effects Inserts the encoding of val into *buf and returns 97 the length of the encoding in *retlen. 98 Returns ENOMEM to signal an unsuccesful attempt 99 to expand the buffer. */ 100 101 asn1_error_code asn1_encode_null 102 (asn1buf *buf, int *retlen); 103 /* requires *buf is allocated 104 modifies *buf, *retlen 105 effects Inserts the encoding of NULL into *buf and returns 106 the length of the encoding in *retlen. 107 Returns ENOMEM to signal an unsuccesful attempt 108 to expand the buffer. */ 109 110 asn1_error_code asn1_encode_printablestring 111 (asn1buf *buf, 112 unsigned int len, const char *val, 113 int *retlen); 114 /* requires *buf is allocated 115 modifies *buf, *retlen 116 effects Inserts the encoding of val into *buf and returns 117 the length of the encoding in *retlen. 118 Returns ENOMEM to signal an unsuccesful attempt 119 to expand the buffer. */ 120 121 asn1_error_code asn1_encode_ia5string 122 (asn1buf *buf, 123 unsigned int len, const char *val, 124 int *retlen); 125 /* requires *buf is allocated 126 modifies *buf, *retlen 127 effects Inserts the encoding of val into *buf and returns 128 the length of the encoding in *retlen. 129 Returns ENOMEM to signal an unsuccesful attempt 130 to expand the buffer. */ 131 132 asn1_error_code asn1_encode_generaltime 133 (asn1buf *buf, time_t val, unsigned int *retlen); 134 /* requires *buf is allocated 135 modifies *buf, *retlen 136 effects Inserts the encoding of val into *buf and returns 137 the length of the encoding in *retlen. 138 Returns ENOMEM to signal an unsuccesful attempt 139 to expand the buffer. 140 Note: The encoding of GeneralizedTime is YYYYMMDDhhmmZ */ 141 142 asn1_error_code asn1_encode_generalstring 143 (asn1buf *buf, 144 unsigned int len, const void *val, 145 unsigned int *retlen); 146 /* requires *buf is allocated, val has a length of len characters 147 modifies *buf, *retlen 148 effects Inserts the encoding of val into *buf and returns 149 the length of the encoding in *retlen. 150 Returns ENOMEM to signal an unsuccesful attempt 151 to expand the buffer. */ 152 153 asn1_error_code asn1_encode_bitstring(asn1buf *buf, unsigned int len, 154 const void *val, 155 unsigned int *retlen); 156 /* requires *buf is allocated, val has a length of len characters 157 modifies *buf, *retlen 158 effects Inserts the encoding of val into *buf and returns 159 the length of the encoding in *retlen. 160 Returns ENOMEM to signal an unsuccesful attempt 161 to expand the buffer. */ 162 163 asn1_error_code asn1_encode_opaque(asn1buf *buf, unsigned int len, 164 const void *val, 165 unsigned int *retlen); 166 /* requires *buf is allocated, val has a length of len characters 167 modifies *buf, *retlen 168 effects Inserts the encoding of val into *buf and returns 169 the length of the encoding in *retlen. 170 Returns ENOMEM to signal an unsuccesful attempt 171 to expand the buffer. */ 172 173 /* Type descriptor info. 174 175 In this context, a "type" is a combination of a C data type 176 and an ASN.1 encoding scheme for it. So we would have to define 177 different "types" for: 178 179 * unsigned char* encoded as octet string 180 * char* encoded as octet string 181 * char* encoded as generalstring 182 * krb5_data encoded as octet string 183 * krb5_data encoded as generalstring 184 * int32_t encoded as integer 185 * unsigned char encoded as integer 186 187 Perhaps someday some kind of flags could be defined so that minor 188 variations on the C types could be handled via common routines. 189 190 The handling of strings is pretty messy. Currently, we have a 191 separate kind of encoder function that takes an extra length 192 parameter. Perhaps we should just give up on that, always deal 193 with just a single location, and handle strings by via encoder 194 functions for krb5_data, keyblock, etc. 195 196 We wind up with a lot of load-time relocations being done, which is 197 a bit annoying. Be careful about "fixing" that at the cost of too 198 much run-time performance. It might work to have a master "module" 199 descriptor with pointers to various arrays (type descriptors, 200 strings, field descriptors, functions) most of which don't need 201 relocation themselves, and replace most of the pointers with table 202 indices. 203 204 It's a work in progress. */ 205 206 enum atype_type { 207 /* For bounds checking only. By starting with values above 1, we 208 guarantee that zero-initialized storage will be recognized as 209 invalid. */ 210 atype_min = 1, 211 /* Encoder function to be called with address of <thing>. */ 212 atype_fn, 213 /* Encoder function to be called with address of <thing> and a 214 length (unsigned int). */ 215 atype_fn_len, 216 /* Pointer to actual thing to be encoded. 217 218 Most of the fields are related only to the C type -- size, how 219 to fetch a pointer in a type-safe fashion -- but since the base 220 type descriptor encapsulates the encoding as well, different 221 encodings for the same C type may require different pointer-to 222 types as well. 223 224 Must not refer to atype_fn_len. */ 225 atype_ptr, 226 /* Sequence, with pointer to sequence descriptor header. */ 227 atype_sequence, 228 /* Sequence-of, with pointer to base type descriptor, represented 229 as a null-terminated array of pointers (and thus the "base" 230 type descriptor is actually an atype_ptr node). */ 231 atype_nullterm_sequence_of, 232 atype_nonempty_nullterm_sequence_of, 233 /* Encode this object using a single field descriptor. This may 234 mean the atype/field breakdown needs revision.... 235 236 Main expected uses: Encode realm component of principal as a 237 GENERALSTRING. Pluck data and length fields out of a structure 238 and encode a counted SEQUENCE OF. */ 239 atype_field, 240 /* Tagged version of another type. */ 241 atype_tagged_thing, 242 /* Integer types. */ 243 atype_int, 244 atype_uint, 245 /* Unused except for bounds checking. */ 246 atype_max 247 }; 248 249 /* Initialized structures could be a lot smaller if we could use C99 250 designated initializers, and a union for all the type-specific 251 stuff. Maybe use the hack we use for krb5int_access, where we use 252 a run-time initialize if the compiler doesn't support designated 253 initializers? That's a lot of work here, though, with so many 254 little structures. Maybe if/when these get auto-generated. */ 255 struct atype_info { 256 enum atype_type type; 257 /* used for sequence-of processing */ 258 unsigned int size; 259 /* atype_fn */ 260 asn1_error_code (*enc)(asn1buf *, const void *, unsigned int *); 261 /* atype_fn_len */ 262 asn1_error_code (*enclen)(asn1buf *, unsigned int, const void *, 263 unsigned int *); 264 /* atype_ptr, atype_fn_len */ 265 const void *(*loadptr)(const void *); 266 /* atype_ptr, atype_nullterm_sequence_of */ 267 const struct atype_info *basetype; 268 /* atype_sequence */ 269 const struct seq_info *seq; 270 /* atype_field */ 271 const struct field_info *field; 272 /* atype_tagged_thing */ 273 unsigned int tagval : 8, tagtype : 8; 274 /* atype_[u]int */ 275 asn1_intmax (*loadint)(const void *); 276 asn1_uintmax (*loaduint)(const void *); 277 }; 278 279 /* The various DEF*TYPE macros must: 280 281 + Define a type named aux_typedefname_##DESCNAME, for use in any 282 types derived from the type being defined. 283 284 + Define an atype_info struct named krb5int_asn1type_##DESCNAME. 285 286 + Define any extra stuff needed in the type descriptor, like 287 pointer-load functions. 288 289 + Accept a following semicolon syntactically, to keep Emacs parsing 290 (and indentation calculating) code happy. 291 292 Nothing else should directly define the atype_info structures. */ 293 294 /* Define a type for which we must use an explicit encoder function. 295 The DEFFNTYPE variant uses a function taking a void*, the 296 DEFFNXTYPE form wants a function taking a pointer to the actual C 297 type to be encoded; you should use the latter unless you've already 298 got the void* function supplied elsewhere. 299 300 Of course, we need a single, consistent type for the descriptor 301 structure field, so we use the function pointer type that uses 302 void*, and create a wrapper function in DEFFNXTYPE. However, in 303 all our cases so far, the supplied function is static and not used 304 otherwise, so the compiler can merge it with the wrapper function 305 if the optimizer is good enough. */ 306 #define DEFFNTYPE(DESCNAME, CTYPENAME, ENCFN) \ 307 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 308 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 309 atype_fn, sizeof(CTYPENAME), ENCFN, \ 310 } 311 #define DEFFNXTYPE(DESCNAME, CTYPENAME, ENCFN) \ 312 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 313 static asn1_error_code \ 314 aux_encfn_##DESCNAME(asn1buf *buf, const void *val, \ 315 unsigned int *retlen) \ 316 { \ 317 return ENCFN(buf, \ 318 (const aux_typedefname_##DESCNAME *)val, \ 319 retlen); \ 320 } \ 321 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 322 atype_fn, sizeof(CTYPENAME), aux_encfn_##DESCNAME, \ 323 } 324 /* XXX The handling of data+length fields really needs reworking. 325 A type descriptor probably isn't the right way. 326 327 Also, the C type is likely to be one of char*, unsigned char*, 328 or (maybe) void*. An enumerator or reference to an external 329 function would be more compact. 330 331 The supplied encoder function takes as an argument the data pointer 332 loaded from the indicated location, not the address of the field. 333 This isn't consistent with DEFFN[X]TYPE above, but all of the uses 334 of DEFFNLENTYPE are for string encodings, and that's how our 335 string-encoding primitives work. So be it. */ 336 #ifdef POINTERS_ARE_ALL_THE_SAME 337 #define DEFFNLENTYPE(DESCNAME, CTYPENAME, ENCFN) \ 338 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 339 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 340 atype_fn_len, 0, 0, ENCFN, \ 341 } 342 #else 343 #define DEFFNLENTYPE(DESCNAME, CTYPENAME, ENCFN) \ 344 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 345 static const void *loadptr_for_##DESCNAME(const void *pv) \ 346 { \ 347 const aux_typedefname_##DESCNAME *p = pv; \ 348 return *p; \ 349 } \ 350 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 351 atype_fn_len, 0, 0, ENCFN, \ 352 loadptr_for_##DESCNAME \ 353 } 354 #endif 355 /* A sequence, defined by the indicated series of fields, and an 356 optional function indicating which fields are present. */ 357 #define DEFSEQTYPE(DESCNAME, CTYPENAME, FIELDS, OPT) \ 358 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 359 static const struct seq_info aux_seqinfo_##DESCNAME = { \ 360 OPT, FIELDS, sizeof(FIELDS)/sizeof(FIELDS[0]) \ 361 }; \ 362 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 363 atype_sequence, sizeof(CTYPENAME), 0,0,0,0, \ 364 &aux_seqinfo_##DESCNAME, \ 365 } 366 /* Integer types. */ 367 #define DEFINTTYPE(DESCNAME, CTYPENAME) \ 368 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 369 static asn1_intmax loadint_##DESCNAME(const void *p) \ 370 { \ 371 assert(sizeof(CTYPENAME) <= sizeof(asn1_intmax)); \ 372 return *(const aux_typedefname_##DESCNAME *)p; \ 373 } \ 374 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 375 atype_int, sizeof(CTYPENAME), 0, 0, 0, 0, 0, 0, 0, 0, \ 376 loadint_##DESCNAME, 0, \ 377 } 378 #define DEFUINTTYPE(DESCNAME, CTYPENAME) \ 379 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 380 static asn1_uintmax loaduint_##DESCNAME(const void *p) \ 381 { \ 382 assert(sizeof(CTYPENAME) <= sizeof(asn1_uintmax)); \ 383 return *(const aux_typedefname_##DESCNAME *)p; \ 384 } \ 385 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 386 atype_uint, sizeof(CTYPENAME), 0, 0, 0, 0, 0, 0, 0, 0, \ 387 0, loaduint_##DESCNAME, \ 388 } 389 /* Pointers to other types, to be encoded as those other types. */ 390 #ifdef POINTERS_ARE_ALL_THE_SAME 391 #define DEFPTRTYPE(DESCNAME,BASEDESCNAME) \ 392 typedef aux_typedefname_##BASEDESCNAME * aux_typedefname_##DESCNAME; \ 393 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 394 atype_ptr, sizeof(aux_typedefname_##DESCNAME), 0, 0, 0, \ 395 &krb5int_asn1type_##BASEDESCNAME, 0 \ 396 } 397 #else 398 #define DEFPTRTYPE(DESCNAME,BASEDESCNAME) \ 399 typedef aux_typedefname_##BASEDESCNAME * aux_typedefname_##DESCNAME; \ 400 static const void * \ 401 loadptr_for_##BASEDESCNAME##_from_##DESCNAME(const void *p) \ 402 { \ 403 const aux_typedefname_##DESCNAME *inptr = p; \ 404 const aux_typedefname_##BASEDESCNAME *retptr; \ 405 retptr = *inptr; \ 406 return retptr; \ 407 } \ 408 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 409 atype_ptr, sizeof(aux_typedefname_##DESCNAME), 0, 0, \ 410 loadptr_for_##BASEDESCNAME##_from_##DESCNAME, \ 411 &krb5int_asn1type_##BASEDESCNAME, 0 \ 412 } 413 #endif 414 /* This encodes a pointer-to-pointer-to-thing where the passed-in 415 value points to a null-terminated list of pointers to objects to be 416 encoded, and encodes a (possibly empty) SEQUENCE OF these objects. 417 418 BASEDESCNAME is a descriptor name for the pointer-to-thing 419 type. 420 421 When dealing with a structure containing a 422 pointer-to-pointer-to-thing field, make a DEFPTRTYPE of this type, 423 and use that type for the structure field. */ 424 #define DEFNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME) \ 425 typedef aux_typedefname_##BASEDESCNAME aux_typedefname_##DESCNAME; \ 426 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 427 atype_nullterm_sequence_of, sizeof(aux_typedefname_##DESCNAME), \ 428 0, 0, \ 429 0 /* loadptr */, \ 430 &krb5int_asn1type_##BASEDESCNAME, 0 \ 431 } 432 #define DEFNONEMPTYNULLTERMSEQOFTYPE(DESCNAME,BASEDESCNAME) \ 433 typedef aux_typedefname_##BASEDESCNAME aux_typedefname_##DESCNAME; \ 434 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 435 atype_nonempty_nullterm_sequence_of, \ 436 sizeof(aux_typedefname_##DESCNAME), \ 437 0, 0, \ 438 0 /* loadptr */, \ 439 &krb5int_asn1type_##BASEDESCNAME, 0 \ 440 } 441 /* Encode a thing (probably sub-fields within the structure) as a 442 single object. */ 443 #define DEFFIELDTYPE(DESCNAME, CTYPENAME, FIELDINFO) \ 444 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 445 static const struct field_info aux_fieldinfo_##DESCNAME = FIELDINFO; \ 446 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 447 atype_field, sizeof(CTYPENAME), 0, 0, 0, 0, 0, \ 448 &aux_fieldinfo_##DESCNAME \ 449 } 450 /* Objects with an APPLICATION tag added. */ 451 #define DEFAPPTAGGEDTYPE(DESCNAME, TAG, BASEDESC) \ 452 typedef aux_typedefname_##BASEDESC aux_typedefname_##DESCNAME; \ 453 const struct atype_info krb5int_asn1type_##DESCNAME = { \ 454 atype_tagged_thing, sizeof(aux_typedefname_##DESCNAME), \ 455 0, 0, 0, &krb5int_asn1type_##BASEDESC, 0, 0, TAG, APPLICATION \ 456 } 457 458 /* Declare an externally-defined type. This is a hack we should do 459 away with once we move to generating code from a script. For now, 460 this macro is unfortunately not compatible with the defining macros 461 above, since you can't do the typedefs twice and we need the 462 declarations to produce typedefs. (We could eliminate the typedefs 463 from the DEF* macros, but then every DEF* macro use, even the ones 464 for internal type nodes we only use to build other types, would 465 need an accompanying declaration which explicitly lists the 466 type.) */ 467 #define IMPORT_TYPE(DESCNAME, CTYPENAME) \ 468 typedef CTYPENAME aux_typedefname_##DESCNAME; \ 469 extern const struct atype_info krb5int_asn1type_##DESCNAME 470 471 /* Create a partial-encoding function by the indicated name, for the 472 indicated type. Should only be needed until we've converted all of 473 the encoders, then everything should use descriptor tables. */ 474 extern asn1_error_code 475 krb5int_asn1_encode_a_thing(asn1buf *buf, const void *val, 476 const struct atype_info *a, unsigned int *retlen); 477 #define MAKE_ENCFN(FNAME,DESC) \ 478 static asn1_error_code FNAME (asn1buf *buf, \ 479 const aux_typedefname_##DESC *val, \ 480 unsigned int *retlen) \ 481 { \ 482 return krb5int_asn1_encode_a_thing(buf, val, \ 483 &krb5int_asn1type_##DESC, \ 484 retlen); \ 485 } \ 486 extern int dummy /* gobble semicolon */ 487 488 /* Sequence field descriptor. 489 490 Currently we assume everything is a single object with a type 491 descriptor, and then we bolt on some ugliness on the side for 492 handling strings with length fields. 493 494 Anything with "interesting" encoding handling, like a sequence-of 495 or a pointer to the actual value to encode, is handled via opaque 496 types with their own encoder functions. Most of that should 497 eventually change. */ 498 499 enum field_type { 500 /* Unused except for range checking. */ 501 field_min = 1, 502 /* Field ATYPE describes processing of field at DATAOFF. */ 503 field_normal, 504 /* Encode an "immediate" integer value stored in DATAOFF, with no 505 reference to the data structure. */ 506 field_immediate, 507 /* Encode some kind of string field encoded with pointer and 508 length. (A GENERALSTRING represented as a null-terminated C 509 string would be handled as field_normal.) */ 510 field_string, 511 /* LENOFF indicates a value describing the length of the array at 512 DATAOFF, encoded as a sequence-of with the element type 513 described by ATYPE. */ 514 field_sequenceof_len, 515 /* Unused except for range checking. */ 516 field_max 517 }; 518 /* To do: Consider using bitfields. */ 519 struct field_info { 520 /* Type of the field. */ 521 unsigned int /* enum field_type */ ftype : 3; 522 523 /* Use of DATAOFF and LENOFF are described by the value in FTYPE. 524 Generally DATAOFF will be the offset from the supplied pointer 525 at which we find the object to be encoded. */ 526 unsigned int dataoff : 9, lenoff : 9; 527 528 /* If TAG is non-negative, a context tag with that value is added 529 to the encoding of the thing. (XXX This would encode more 530 compactly as an unsigned bitfield value tagnum+1, with 0=no 531 tag.) The tag is omitted for optional fields that are not 532 present. 533 534 It's a bit illogical to combine the tag and other field info, 535 since really a sequence field could have zero or several 536 context tags, and of course a tag could be used elsewhere. But 537 the normal mode in the Kerberos ASN.1 description is to use one 538 context tag on each sequence field, so for now let's address 539 that case primarily and work around the other cases (thus tag<0 540 means skip tagging). */ 541 signed int tag : 5; 542 543 /* If OPT is non-negative and the sequence header structure has a 544 function pointer describing which fields are present, OPT is 545 the bit position indicating whether the currently-described 546 element is present. (XXX Similar encoding issue.) 547 548 Note: Most of the time, I'm using the same number here as for 549 the context tag. This is just because it's easier for me to 550 keep track while working on the code by hand. The *only* 551 meaningful correlation is of this value and the bits set by the 552 "optional" function when examining the data structure. */ 553 signed int opt : 5; 554 555 /* For some values of FTYPE, this describes the type of the 556 object(s) to be encoded. */ 557 const struct atype_info *atype; 558 559 /* We use different types for "length" fields in different places. 560 So we need a good way to retrieve the various kinds of lengths 561 in a compatible way. This may be a string length, or the 562 length of an array of objects to encode in a SEQUENCE OF. 563 564 In case the field is signed and negative, or larger than 565 size_t, return SIZE_MAX as an error indication. We'll assume 566 for now that we'll never have 4G-1 (or 2**64-1, or on tiny 567 systems, 65535) sized values. On most if not all systems we 568 care about, SIZE_MAX is equivalent to "all of addressable 569 memory" minus one byte. That wouldn't leave enough extra room 570 for the structure we're encoding, so it's pretty safe to assume 571 SIZE_MAX won't legitimately come up on those systems. 572 573 If this code gets ported to a segmented architecture or other 574 system where it might be possible... figure it out then. */ 575 const struct atype_info *lentype; 576 }; 577 578 /* Normal or optional sequence fields at a particular offset, encoded 579 as indicated by the listed DESCRiptor. */ 580 #define FIELDOF_OPT(TYPE,DESCR,FIELDNAME,TAG,OPT) \ 581 { \ 582 field_normal, OFFOF(TYPE, FIELDNAME, aux_typedefname_##DESCR), \ 583 0, TAG, OPT, &krb5int_asn1type_##DESCR \ 584 } 585 #define FIELDOF_NORM(TYPE,DESCR,FIELDNAME,TAG) \ 586 FIELDOF_OPT(TYPE,DESCR,FIELDNAME,TAG,-1) 587 /* If encoding a subset of the fields of the current structure (for 588 example, a flat structure describing data that gets encoded as a 589 sequence containing one or more sequences), use ENCODEAS, no struct 590 field name(s), and the indicated type descriptor must support the 591 current struct type. */ 592 #define FIELDOF_ENCODEAS(TYPE,DESCR,TAG) \ 593 FIELDOF_ENCODEAS_OPT(TYPE,DESCR,TAG,-1) 594 #define FIELDOF_ENCODEAS_OPT(TYPE,DESCR,TAG,OPT) \ 595 { \ 596 field_normal, \ 597 0 * sizeof(0 ? (TYPE *)0 : (aux_typedefname_##DESCR *) 0), \ 598 0, TAG, OPT, &krb5int_asn1type_##DESCR \ 599 } 600 601 /* Reinterpret some subset of the structure itself as something 602 else. */ 603 #define FIELD_SELF(DESCR, TAG) \ 604 { field_normal, 0, 0, TAG, -1, &krb5int_asn1type_##DESCR } 605 606 #define FIELDOF_OPTSTRINGL(STYPE,DESC,PTRFIELD,LENDESC,LENFIELD,TAG,OPT) \ 607 { \ 608 field_string, \ 609 OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC), \ 610 OFFOF(STYPE, LENFIELD, aux_typedefname_##LENDESC), \ 611 TAG, OPT, &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENDESC \ 612 } 613 #define FIELDOF_OPTSTRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG,OPT) \ 614 FIELDOF_OPTSTRINGL(STYPE,DESC,PTRFIELD,uint,LENFIELD,TAG,OPT) 615 #define FIELDOF_STRINGL(STYPE,DESC,PTRFIELD,LENDESC,LENFIELD,TAG) \ 616 FIELDOF_OPTSTRINGL(STYPE,DESC,PTRFIELD,LENDESC,LENFIELD,TAG,-1) 617 #define FIELDOF_STRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG) \ 618 FIELDOF_OPTSTRING(STYPE,DESC,PTRFIELD,LENFIELD,TAG,-1) 619 #define FIELD_INT_IMM(VALUE,TAG) \ 620 { field_immediate, VALUE, 0, TAG, -1, 0, } 621 622 #define FIELDOF_SEQOF_LEN(STYPE,DESC,PTRFIELD,LENFIELD,LENTYPE,TAG) \ 623 { \ 624 field_sequenceof_len, \ 625 OFFOF(STYPE, PTRFIELD, aux_typedefname_##DESC), \ 626 OFFOF(STYPE, LENFIELD, aux_typedefname_##LENTYPE), \ 627 TAG, -1, &krb5int_asn1type_##DESC, &krb5int_asn1type_##LENTYPE \ 628 } 629 #define FIELDOF_SEQOF_INT32(STYPE,DESC,PTRFIELD,LENFIELD,TAG) \ 630 FIELDOF_SEQOF_LEN(STYPE,DESC,PTRFIELD,LENFIELD,int32,TAG) 631 632 struct seq_info { 633 /* If present, returns a bitmask indicating which fields are 634 present. See the "opt" field in struct field_info. */ 635 unsigned int (*optional)(const void *); 636 /* Indicates an array of sequence field descriptors. */ 637 const struct field_info *fields; 638 size_t n_fields; 639 /* Missing: Extensibility handling. (New field type?) */ 640 }; 641 642 extern krb5_error_code 643 krb5int_asn1_do_full_encode(const void *rep, krb5_data **code, 644 const struct atype_info *a); 645 646 #define MAKE_FULL_ENCODER(FNAME, DESC) \ 647 krb5_error_code FNAME(const aux_typedefname_##DESC *rep, \ 648 krb5_data **code) \ 649 { \ 650 return krb5int_asn1_do_full_encode(rep, code, \ 651 &krb5int_asn1type_##DESC); \ 652 } \ 653 extern int dummy /* gobble semicolon */ 654 655 #include <stddef.h> 656 /* Ugly hack! 657 Like "offsetof", but with type checking. */ 658 #define WARN_IF_TYPE_MISMATCH(LVALUE, TYPE) \ 659 (sizeof(0 ? (TYPE *) 0 : &(LVALUE))) 660 #define OFFOF(TYPE,FIELD,FTYPE) \ 661 (offsetof(TYPE, FIELD) \ 662 + 0 * WARN_IF_TYPE_MISMATCH(((TYPE*)0)->FIELD, FTYPE)) 663 664 #endif 665