1 /**************************************************************************** 2 * * 3 * ASN.1 Constants and Structures * 4 * Copyright Peter Gutmann 1992-2015 * 5 * * 6 ****************************************************************************/ 7 8 #ifndef _ASN1_DEFINED 9 10 #define _ASN1_DEFINED 11 12 #include <time.h> 13 #if defined( INC_ALL ) 14 #include "stream.h" 15 #else 16 #include "io/stream.h" 17 #endif /* Compiler-specific includes */ 18 19 #ifdef USE_INT_ASN1 20 21 /**************************************************************************** 22 * * 23 * BER/DER Constants and Macros * 24 * * 25 ****************************************************************************/ 26 27 /* Definitions for the ISO 8825:1990 Basic Encoding Rules */ 28 29 /* Tag class */ 30 31 #define BER_UNIVERSAL 0x00 32 #define BER_APPLICATION 0x40 33 #define BER_CONTEXT_SPECIFIC 0x80 34 #define BER_PRIVATE 0xC0 35 36 /* Whether the encoding is constructed or primitive */ 37 38 #define BER_CONSTRUCTED 0x20 39 #define BER_PRIMITIVE 0x00 40 41 /* The ID's for universal tag numbers 0-31. Tag number 0 is reserved for 42 encoding the end-of-contents value when an indefinite-length encoding 43 is used */ 44 45 enum { BER_ID_RESERVED, BER_ID_BOOLEAN, BER_ID_INTEGER, BER_ID_BITSTRING, 46 BER_ID_OCTETSTRING, BER_ID_NULL, BER_ID_OBJECT_IDENTIFIER, 47 BER_ID_OBJECT_DESCRIPTOR, BER_ID_EXTERNAL, BER_ID_REAL, 48 BER_ID_ENUMERATED, BER_ID_EMBEDDED_PDV, BER_ID_STRING_UTF8, BER_ID_13, 49 BER_ID_14, BER_ID_15, BER_ID_SEQUENCE, BER_ID_SET, 50 BER_ID_STRING_NUMERIC, BER_ID_STRING_PRINTABLE, BER_ID_STRING_T61, 51 BER_ID_STRING_VIDEOTEX, BER_ID_STRING_IA5, BER_ID_TIME_UTC, 52 BER_ID_TIME_GENERALIZED, BER_ID_STRING_GRAPHIC, BER_ID_STRING_ISO646, 53 BER_ID_STRING_GENERAL, BER_ID_STRING_UNIVERSAL, BER_ID_29, 54 BER_ID_STRING_BMP, BER_ID_LAST }; 55 56 /* The encodings for the universal types */ 57 58 #define BER_EOC 0 /* Pseudo-type for first EOC octet */ 59 #define BER_RESERVED ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_RESERVED ) 60 #define BER_BOOLEAN ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_BOOLEAN ) 61 #define BER_INTEGER ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_INTEGER ) 62 #define BER_BITSTRING ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_BITSTRING ) 63 #define BER_OCTETSTRING ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_OCTETSTRING ) 64 #define BER_NULL ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_NULL ) 65 #define BER_OBJECT_IDENTIFIER ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_OBJECT_IDENTIFIER ) 66 #define BER_OBJECT_DESCRIPTOR ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_OBJECT_DESCRIPTOR ) 67 #define BER_EXTERNAL ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_EXTERNAL ) 68 #define BER_REAL ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_REAL ) 69 #define BER_ENUMERATED ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_ENUMERATED ) 70 #define BER_EMBEDDED_PDV ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_EMBEDDED_PDV ) 71 #define BER_STRING_UTF8 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_UTF8 ) 72 #define BER_13 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_13 ) 73 #define BER_14 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_14 ) 74 #define BER_15 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_15 ) 75 #define BER_SEQUENCE ( BER_UNIVERSAL | BER_CONSTRUCTED | BER_ID_SEQUENCE ) 76 #define BER_SET ( BER_UNIVERSAL | BER_CONSTRUCTED | BER_ID_SET ) 77 #define BER_STRING_NUMERIC ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_NUMERIC ) 78 #define BER_STRING_PRINTABLE ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_PRINTABLE ) 79 #define BER_STRING_T61 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_T61 ) 80 #define BER_STRING_VIDEOTEX ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_VIDEOTEX ) 81 #define BER_STRING_IA5 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_IA5 ) 82 #define BER_TIME_UTC ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_TIME_UTC ) 83 #define BER_TIME_GENERALIZED ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_TIME_GENERALIZED ) 84 #define BER_STRING_GRAPHIC ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_GRAPHIC ) 85 #define BER_STRING_ISO646 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_ISO646 ) 86 #define BER_STRING_GENERAL ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_GENERAL ) 87 #define BER_STRING_UNIVERSAL ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_UNIVERSAL ) 88 #define BER_29 ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_BER29 ) 89 #define BER_STRING_BMP ( BER_UNIVERSAL | BER_PRIMITIVE | BER_ID_STRING_BMP ) 90 91 /* The encodings for constructed, indefinite-length tags and lengths */ 92 93 #define BER_OCTETSTRING_INDEF MKDATA( "\x24\x80" ) 94 #define BER_SEQUENCE_INDEF MKDATA( "\x30\x80" ) 95 #define BER_SET_INDEF MKDATA( "\x31\x80" ) 96 #define BER_CTAG0_INDEF MKDATA( "\xA0\x80" ) 97 #define BER_END_INDEF MKDATA( "\x00\x00" ) 98 99 /* Masks to extract information from a tag number */ 100 101 #define BER_CLASS_MASK 0xC0 102 #define BER_CONSTRUCTED_MASK 0x20 103 #define BER_SHORT_ID_MASK 0x1F 104 105 /* The maximum value for the short tag encoding, and the magic value which 106 indicates that a long encoding of the number is being used */ 107 108 #define MAX_SHORT_BER_ID ( BER_STRING_BMP + 1 ) 109 #define LONG_BER_ID 0x1F 110 111 /* Turn an identifier into a context-specific tag, and extract the value from 112 a tag. Normally these are constructed, but in a few special cases they 113 are primitive */ 114 115 #define MAKE_CTAG( identifier ) \ 116 ( BER_CONTEXT_SPECIFIC | BER_CONSTRUCTED | ( identifier ) ) 117 #define MAKE_CTAG_PRIMITIVE( identifier ) \ 118 ( BER_CONTEXT_SPECIFIC | ( identifier ) ) 119 #define EXTRACT_CTAG( tag ) \ 120 ( ( tag ) & ~( BER_CONTEXT_SPECIFIC | BER_CONSTRUCTED ) ) 121 122 /**************************************************************************** 123 * * 124 * ASN.1 Constants and Macros * 125 * * 126 ****************************************************************************/ 127 128 /* Special-case tags. If DEFAULT_TAG is given the basic type (e.g. INTEGER, 129 ENUMERATED) is used, otherwise the value is used as a context-specific 130 tag. If NO_TAG is given, processing of the tag is skipped. If ANY_TAG 131 is given, the tag is ignored. The parentheses are to catch potential 132 erroneous use in an expression */ 133 134 #define DEFAULT_TAG ( -1 ) 135 #define NO_TAG ( -2 ) 136 #define ANY_TAG ( -3 ) 137 138 /* The highest encoded tag value */ 139 140 #define MAX_TAG ( BER_CONTEXT_SPECIFIC | BER_CONSTRUCTED | \ 141 MAX_SHORT_BER_ID ) 142 143 /* The highest allowed raw tag value before encoding as a primitive or 144 constructed tag or before encoding as a content-specific tag. In 145 addition to the standard MAX_TAG_VALUE we also have a value for universal 146 tags whose basic form is constructed (SETs and SEQUENCES), which would 147 fall outside the normal MAX_TAG_VALUE range. 148 149 Due to CMP's braindamaged use of tag values to communicate message type 150 information we have to be fairly permissive with the context-specific 151 tag range because CMP burns up tag values up to the mid-20s, however we 152 can restrict the range if CMP isn't being used */ 153 154 #define MAX_TAG_VALUE MAX_SHORT_BER_ID 155 #define MAX_CONSTR_TAG_VALUE BER_SET 156 #ifdef USE_CMP 157 #define MAX_CTAG_VALUE 30 158 #else 159 #define MAX_CTAG_VALUE 10 160 #endif /* USE_CMP */ 161 162 /* The minimum and maximum allowed size for an (encoded) object identifier */ 163 164 #define MIN_OID_SIZE 5 165 #define MAX_OID_SIZE 32 166 167 /* When reading an OID selection with readOID() we sometimes need to allow 168 a catch-all default value that's used when nothing else matches. This is 169 typically used for type-and-value data where we want to ignore anything 170 that we don't recognise. The following value is used as a match-all 171 wildcard. It's longer than any normal OID to make it possible to do a 172 quick-reject match based only on the length. The second byte is set to 173 0x0E (= 14) to make the standard sizeofOID() macro work, since this 174 examines the length field of the encoded OID */ 175 176 #define WILDCARD_OID ( const BYTE * ) \ 177 "\xFF\x0E\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00\xFF\x00" 178 #define WILDCARD_OID_SIZE 16 179 180 /* A macro to make make declaring OIDs simpler */ 181 182 #define MKOID( value ) ( ( const BYTE * ) value ) 183 184 /* Macros and functions to work with indefinite-length tags. The only ones 185 used are SEQUENCE and [0] (for the outer encapsulation) and OCTET STRING 186 (for the data itself) */ 187 188 #define writeOctetStringIndef( stream ) swrite( stream, BER_OCTETSTRING_INDEF, 2 ) 189 #define writeSequenceIndef( stream ) swrite( stream, BER_SEQUENCE_INDEF, 2 ) 190 #define writeSetIndef( stream ) swrite( stream, BER_SET_INDEF, 2 ) 191 #define writeCtag0Indef( stream ) swrite( stream, BER_CTAG0_INDEF, 2 ) 192 #define writeEndIndef( stream ) swrite( stream, BER_END_INDEF, 2 ) 193 194 #define sizeofEOC() 2 195 RETVAL_RANGE( FALSE, TRUE ) STDC_NONNULL_ARG( ( 1 ) ) \ 196 int checkEOC( INOUT STREAM *stream ); 197 198 /**************************************************************************** 199 * * 200 * ASN.1 Function Prototypes * 201 * * 202 ****************************************************************************/ 203 204 /* Read/peek at a tag and make sure that it's (approximately) valid, and 205 write a tag. The latter translates directly to sputc(), but we use a 206 macro to make explicit what's going on */ 207 208 RETVAL_RANGE( MAX_ERROR, MAX_TAG - 1 ) STDC_NONNULL_ARG( ( 1 ) ) \ 209 int readTag( INOUT STREAM *stream ); 210 RETVAL_RANGE( MAX_ERROR, MAX_TAG - 1 ) STDC_NONNULL_ARG( ( 1 ) ) \ 211 int peekTag( INOUT STREAM *stream ); 212 #define writeTag( stream, tag ) sputc( stream, tag ) 213 214 /* peekTag() is a somewhat awkward function because it can return an error 215 code alongside the tag, so code like: 216 217 if( peekTag() == tag1 ) 218 status = read1(); 219 if( peekTag() == tag2 ) 220 status = read2(); 221 222 to read a sequence of optional elements can conclude with an OK status 223 but an error on the stream if an earlier peekTag() returns an error (so 224 that all sunsequent peekTags() don't match the tag). To deal with this 225 we define a macro that checks that the status from an earlier read 226 is OK, peeks at the next tag, and checks that the result isn't an error 227 status. The resulting usage is: 228 229 status = read(); 230 if( checkStatusPeekTag( stream, status, tag ) && \ 231 tag == MAKE_CTAG( 0 ) ) 232 status = read(); */ 233 234 #define checkStatusPeekTag( stream, status, tag ) \ 235 ( !cryptStatusError( status ) && \ 236 ( ( status ) = ( tag ) = peekTag( stream ), !cryptStatusError( status ) ) ) 237 238 /* Alongside the standard checkStatusPeekTag() we also provide a version 239 that checks whether we should still be looking for new tags, for use 240 when we're reading a SEQUENCE OF/SET OF. 241 242 Note that this sets status to a non-error/CRYPT_OK value, which means 243 that the status can't be checked using cryptStatusOK() but has to be 244 checked with !cryptStatusError() */ 245 246 #define checkStatusLimitsPeekTag( stream, status, tag, endPos ) \ 247 ( !cryptStatusError( status ) && \ 248 stell( stream ) < ( endPos ) && \ 249 ( ( status ) = ( tag ) = peekTag( stream ), !cryptStatusError( status ) ) ) 250 251 /* Determine the size of an object once it's wrapped up with a tag and 252 length */ 253 254 RETVAL_LENGTH_NOERROR \ 255 long sizeofObject( IN_LENGTH_Z const long length ); 256 257 /* Generalized ASN.1 type manipulation routines. readRawObject() reads a 258 complete object (including tag and length data) while readUniversal() 259 just skips it. Since readRawObject() always requires a tag, we don't 260 have the xxx/xxxData() variants that exist for other functions */ 261 262 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 263 int readUniversalData( INOUT STREAM *stream ); 264 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 265 int readUniversal( INOUT STREAM *stream ); 266 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \ 267 int readRawObject( INOUT STREAM *stream, 268 OUT_BUFFER( bufferMaxLength, *bufferLength ) BYTE *buffer, 269 IN_LENGTH_SHORT_MIN( 3 ) const int bufferMaxLength, 270 OUT_LENGTH_BOUNDED_Z( bufferMaxLength ) \ 271 int *bufferLength, 272 IN_TAG_ENCODED const int tag ); 273 274 #define writeRawObject( stream, object, size ) \ 275 swrite( stream, object, size ) 276 277 /* Routines for handling OBJECT IDENTIFIERS. The sizeof() macro determines 278 the length of an encoded object identifier as tag + length + value. 279 Write OID routines equivalent to the ones for other ASN.1 types don't 280 exist since OIDs are always read and written as a blob with sread()/ 281 swrite(). OIDs are never tagged so we don't need any special-case 282 handling for tags. 283 284 When there's a choice of possible OIDs, the list of OID values and 285 corresponding selection IDs is provided in an OID_INFO structure (we also 286 provide a shortcut readFixedOID() function when there's only a single OID 287 that's valid at that point). The read OID value is checked against each 288 OID in the OID_INFO list, if a match is found the selectionID is returned. 289 290 The OID_INFO includes a pointer to further user-supplied information 291 related to this OID that may be used by the user, set when the OID list 292 is initialised. For example it could point to OID-specific handlers for 293 the data. When the caller needs to work with the extraInfo field, it's 294 necessary to return the complete OID_INFO entry rather than just the 295 selection ID, which is done by the ..Ex() form of the function */ 296 297 typedef struct { 298 const BYTE FAR_BSS *oid;/* OID */ 299 const int selectionID; /* Value to return for this OID */ 300 const void *extraInfo; /* Additional info for this selection */ 301 } OID_INFO; 302 303 #define sizeofOID( oid ) ( 1 + 1 + ( int ) oid[ 1 ] ) 304 RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \ 305 int readOID( INOUT STREAM *stream, 306 IN_ARRAY( noOidSelectionEntries ) \ 307 const OID_INFO *oidSelection, 308 IN_RANGE( 1, 50 ) const int noOidSelectionEntries, 309 OUT_RANGE( CRYPT_ERROR, noOidSelectionEntries ) \ 310 int *selectionID ); 311 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 312 int readOIDEx( INOUT STREAM *stream, 313 IN_ARRAY( noOidSelectionEntries ) \ 314 const OID_INFO *oidSelection, 315 IN_RANGE( 1, 50 ) const int noOidSelectionEntries, 316 OUT_OPT_PTR_COND const OID_INFO **oidSelectionValue ); 317 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 318 int readFixedOID( INOUT STREAM *stream, 319 IN_BUFFER( oidLength ) \ 320 const BYTE *oid, IN_LENGTH_OID const int oidLength ); 321 RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \ 322 int readEncodedOID( INOUT STREAM *stream, 323 OUT_BUFFER( oidMaxLength, *oidLength ) BYTE *oid, 324 IN_LENGTH_SHORT_MIN( 5 ) const int oidMaxLength, 325 OUT_LENGTH_BOUNDED_Z( oidMaxLength ) int *oidLength, 326 IN_TAG_ENCODED const int tag ); 327 #define writeOID( stream, oid ) \ 328 swrite( ( stream ), ( oid ), sizeofOID( oid ) ) 329 330 /* Routines for handling large integers. When we're writing these we can't 331 use sizeofObject() directly because the internal representation is 332 unsigned whereas the encoded form is signed. The following macro performs 333 the appropriate conversion on the data length before passing it on to 334 sizeofObject() */ 335 336 #define sizeofInteger( value, valueLength ) \ 337 ( int ) sizeofObject( ( valueLength ) + \ 338 ( ( *( BYTE * )( value ) & 0x80 ) ? 1 : 0 ) ) 339 340 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 341 int readIntegerTag( INOUT STREAM *stream, 342 OUT_BUFFER_OPT( integerMaxLength, \ 343 *integerLength ) BYTE *integer, 344 IN_LENGTH_SHORT const int integerMaxLength, 345 OUT_OPT_LENGTH_SHORT_Z int *integerLength, 346 IN_TAG_EXT const int tag ); 347 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 348 int writeInteger( INOUT STREAM *stream, 349 IN_BUFFER( integerLength ) const BYTE *integer, 350 IN_LENGTH_SHORT const int integerLength, 351 IN_TAG const int tag ); 352 353 #define readIntegerData( stream, integer, integerLength, maxLength ) \ 354 readIntegerTag( stream, integer, integerLength, maxLength, NO_TAG ) 355 #define readInteger( stream, integer, integerLength, maxLength ) \ 356 readIntegerTag( stream, integer, integerLength, maxLength, DEFAULT_TAG ) 357 358 /* Routines for handling bignums. We use void * rather than BIGNUM * to save 359 having to include the bignum header everywhere where ASN.1 is used */ 360 361 #define sizeofBignum( bignum ) \ 362 ( ( int ) sizeofObject( signedBignumSize( bignum ) ) ) 363 364 RETVAL_RANGE_NOERROR( 0, MAX_INTLENGTH_SHORT ) STDC_NONNULL_ARG( ( 1 ) ) \ 365 int signedBignumSize( IN TYPECAST( BIGNUM * ) const void *bignum ); 366 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 367 int readBignumTag( INOUT STREAM *stream, INOUT void *bignum, 368 IN_LENGTH_PKC const int minLength, 369 IN_LENGTH_PKC const int maxLength, 370 IN_OPT const void *maxRange, 371 IN_TAG_EXT const int tag ); 372 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 373 int writeBignumTag( INOUT STREAM *stream, 374 IN const void *bignum, 375 IN_TAG const int tag ); 376 377 #define readBignum( stream, bignum, minLen, maxLen, maxRange ) \ 378 readBignumTag( stream, bignum, minLen, maxLen, maxRange, DEFAULT_TAG ) 379 #define writeBignum( stream, bignum ) \ 380 writeBignumTag( stream, bignum, DEFAULT_TAG ) 381 382 /* Special-case bignum read routine that explicitly checks for a too-short 383 key and returns CRYPT_ERROR_NOSECURE rather than the CRYPT_ERROR_BADDATA 384 that'd otherwise be returned */ 385 386 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 387 int readBignumChecked( INOUT STREAM *stream, 388 INOUT TYPECAST( BIGNUM * ) void *bignum, 389 IN_LENGTH_PKC const int minLength, 390 IN_LENGTH_PKC const int maxLength, 391 IN_OPT const void *maxRange ); 392 393 /* Generally most integers will be non-bignum values, so we also define 394 routines to handle values that will fit into a machine word */ 395 396 #define sizeofShortInteger( value ) \ 397 ( ( ( value ) < 0x80 ) ? 3 : \ 398 ( ( ( long ) value ) < 0x8000L ) ? 4 : \ 399 ( ( ( long ) value ) < 0x800000L ) ? 5 : \ 400 ( ( ( long ) value ) < 0x80000000UL ) ? 6 : 7 ) 401 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 402 int writeShortInteger( INOUT STREAM *stream, 403 IN_INT_Z const long integer, 404 IN_TAG const int tag ); 405 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 406 int readShortIntegerTag( INOUT STREAM *stream, 407 OUT_OPT_INT_Z long *value, 408 IN_TAG_EXT const int tag ); 409 410 #define readShortIntegerData( stream, integer ) \ 411 readShortIntegerTag( stream, integer, NO_TAG ) 412 #define readShortInteger( stream, integer ) \ 413 readShortIntegerTag( stream, integer, DEFAULT_TAG ) 414 415 /* Routines for handling enumerations */ 416 417 #define sizeofEnumerated( value ) ( ( ( value ) < 128 ) ? 3 : 4 ) 418 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 419 int writeEnumerated( INOUT STREAM *stream, 420 IN_RANGE( 0, 999 ) const int enumerated, 421 IN_TAG const int tag ); 422 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 423 int readEnumeratedTag( INOUT STREAM *stream, 424 OUT_OPT_INT_Z int *enumeration, 425 IN_TAG_EXT const int tag ); 426 427 #define readEnumeratedData( stream, enumeration ) \ 428 readEnumeratedTag( stream, enumeration, NO_TAG ) 429 #define readEnumerated( stream, enumeration ) \ 430 readEnumeratedTag( stream, enumeration, DEFAULT_TAG ) 431 432 /* Routines for handling booleans */ 433 434 #define sizeofBoolean() ( sizeof( BYTE ) + sizeof( BYTE ) + sizeof( BYTE ) ) 435 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 436 int writeBoolean( INOUT STREAM *stream, const BOOLEAN boolean, 437 IN_TAG const int tag ); 438 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 439 int readBooleanTag( INOUT STREAM *stream, 440 OUT_OPT_BOOL BOOLEAN *boolean, 441 IN_TAG_EXT const int tag ); 442 443 #define readBooleanData( stream, boolean ) \ 444 readBooleanTag( stream, boolean, NO_TAG ) 445 #define readBoolean( stream, boolean ) \ 446 readBooleanTag( stream, boolean, DEFAULT_TAG ) 447 448 /* Routines for handling null values */ 449 450 #define sizeofNull() ( sizeof( BYTE ) + sizeof( BYTE ) ) 451 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 452 int writeNull( INOUT STREAM *stream, IN_TAG const int tag ); 453 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 454 int readNullTag( INOUT STREAM *stream, IN_TAG_EXT const int tag ); 455 456 #define readNullData( stream ) readNullTag( stream, NO_TAG ) 457 #define readNull( stream ) readNullTag( stream, DEFAULT_TAG ) 458 459 /* Routines for handling octet strings */ 460 461 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 462 int writeOctetString( INOUT STREAM *stream, 463 IN_BUFFER( length ) \ 464 const BYTE *string, 465 IN_LENGTH_SHORT const int length, 466 IN_TAG const int tag ); 467 RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 468 int readOctetStringTag( INOUT STREAM *stream, 469 OUT_BUFFER( maxLength, *stringLength ) \ 470 BYTE *string, 471 OUT_LENGTH_BOUNDED_Z( maxLength ) \ 472 int *stringLength, 473 IN_LENGTH_SHORT const int minLength, 474 IN_LENGTH_SHORT const int maxLength, 475 IN_TAG_EXT const int tag ); 476 477 #define readOctetStringData( stream, string, stringLength, minLength, maxLength ) \ 478 readOctetStringTag( stream, string, stringLength, minLength, maxLength, NO_TAG ) 479 #define readOctetString( stream, string, stringLength, minLength, maxLength ) \ 480 readOctetStringTag( stream, string, stringLength, minLength, maxLength, DEFAULT_TAG ) 481 482 /* Routines for handling character strings. There are a number of oddball 483 character string types that are all handled through the same functions - 484 it's not worth having a seperate function to handle each of the half-dozen 485 types */ 486 487 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 488 int writeCharacterString( INOUT STREAM *stream, 489 IN_BUFFER( length ) const void *string, 490 IN_LENGTH_SHORT const int length, 491 IN_TAG_ENCODED const int tag ); 492 RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \ 493 int readCharacterString( INOUT STREAM *stream, 494 OUT_BUFFER_OPT( stringMaxLength, *stringLength ) \ 495 void *string, 496 IN_LENGTH_SHORT const int stringMaxLength, 497 OUT_LENGTH_BOUNDED_Z( stringMaxLength ) \ 498 int *stringLength, 499 IN_TAG_EXT const int tag ); 500 501 /* Routines for handling bit strings. The sizeof() values are 3 bytes for 502 the tag, length, and surplus-bits value, and the data itself */ 503 504 #define sizeofBitString( value ) \ 505 ( 3 + ( ( ( ( long ) value ) > 0xFFFFFFL ) ? 4 : \ 506 ( ( ( long ) value ) > 0xFFFFL ) ? 3 : \ 507 ( ( value ) > 0xFF ) ? 2 : ( value ) ? 1 : 0 ) ) 508 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 509 int writeBitString( INOUT STREAM *stream, 510 IN_INT_Z const int bitString, 511 IN_TAG const int tag ); 512 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 513 int readBitStringTag( INOUT STREAM *stream, 514 OUT_OPT_INT_Z int *bitString, 515 IN_TAG_EXT const int tag ); 516 517 #define readBitStringData( stream, bitString ) \ 518 readBitStringTag( stream, bitString, NO_TAG ) 519 #define readBitString( stream, bitString ) \ 520 readBitStringTag( stream, bitString, DEFAULT_TAG ) 521 522 /* Routines for handling UTC and Generalized time */ 523 524 #define sizeofUTCTime() ( 1 + 1 + 13 ) 525 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 526 int writeUTCTime( INOUT STREAM *stream, const time_t timeVal, 527 IN_TAG const int tag ); 528 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 529 int readUTCTimeTag( INOUT STREAM *stream, OUT time_t *timeVal, 530 IN_TAG_EXT const int tag ); 531 532 #define readUTCTimeData( stream, time ) readUTCTimeTag( stream, time, NO_TAG ) 533 #define readUTCTime( stream, time ) readUTCTimeTag( stream, time, DEFAULT_TAG ) 534 535 #define sizeofGeneralizedTime() ( 1 + 1 + 15 ) 536 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 537 int writeGeneralizedTime( INOUT STREAM *stream, const time_t timeVal, 538 IN_TAG const int tag ); 539 RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 540 int readGeneralizedTimeTag( INOUT STREAM *stream, OUT time_t *timeVal, 541 IN_TAG_EXT const int tag ); 542 543 #define readGeneralizedTimeData( stream, time ) \ 544 readGeneralizedTimeTag( stream, time, NO_TAG ) 545 #define readGeneralizedTime( stream, time ) \ 546 readGeneralizedTimeTag( stream, time, DEFAULT_TAG ) 547 548 /* Utilitity routines for reading and writing constructed objects and 549 equivalent holes. As with the other ASN.1-read routines we need 550 variants to check for different permitted conditions: 551 552 Length = 1 ... MAX, most cases. 553 Length = 0 ... MAX, occasional cases where a zero-length SEQUENCE 554 is permitted. 555 Length = 1 ... MAX || INDEF. 556 557 The difference between writeOctet/BitStringHole() and writeGenericHole() 558 is that the octet/bit-string versions create a normal or context- 559 specific-tagged string while the generic version creates a pure hole with 560 no processing of tags. 561 562 Note that readGenericHole() takes a full encoded tag value, since we 563 don't know what form it has to be turned into when reading the tag. 564 In addition it has to be able to read zero-length values in order to 565 deal with broken encodings */ 566 567 typedef enum { 568 LENGTH_CHECK_NONE, /* No length check type */ 569 LENGTH_CHECK_ZERO, /* 0 ... MAX */ 570 LENGTH_CHECK_NONZERO, /* 1 ... MAX */ 571 LENGTH_CHECK_NONZERO_INDEF, /* 1 ... MAX || INDEF */ 572 LENGTH_CHECK_LAST /* Last possible length check type */ 573 } LENGTH_CHECK_TYPE; 574 575 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 576 PARAMCHECK( lengthCheckType == LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT_Z ) \ 577 PARAMCHECK( lengthCheckType != LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT ) \ 578 int readSequenceExt( INOUT STREAM *stream, 579 /* PARAMCHECK */ int *length, 580 IN_ENUM( LENGTH_CHECK ) \ 581 const LENGTH_CHECK_TYPE lengthCheckType ); 582 #define readSequence( stream, length ) \ 583 readSequenceExt( stream, length, LENGTH_CHECK_NONZERO ) 584 #define readSequenceZ( stream, length ) \ 585 readSequenceExt( stream, length, LENGTH_CHECK_ZERO ) 586 #define readSequenceI( stream, length ) \ 587 readSequenceExt( stream, length, LENGTH_CHECK_NONZERO_INDEF ) 588 589 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 590 PARAMCHECK( lengthCheckType == LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT_Z ) \ 591 PARAMCHECK( lengthCheckType != LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT ) \ 592 int readSetExt( INOUT STREAM *stream, 593 /* PARAMCHECK */ int *length, 594 IN_ENUM( LENGTH_CHECK ) \ 595 const LENGTH_CHECK_TYPE lengthCheckType ); 596 #define readSet( stream, length ) \ 597 readSetExt( stream, length, LENGTH_CHECK_NONZERO ) 598 #define readSetZ( stream, length ) \ 599 readSetExt( stream, length, LENGTH_CHECK_ZERO ) 600 #define readSetI( stream, length ) \ 601 readSetExt( stream, length, LENGTH_CHECK_NONZERO_INDEF ) 602 603 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 604 PARAMCHECK( lengthCheckType == LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT_Z ) \ 605 PARAMCHECK( lengthCheckType != LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT ) \ 606 int readConstructedExt( INOUT STREAM *stream, 607 /* PARAMCHECK */ int *length, 608 IN_TAG const int tag, 609 IN_ENUM( LENGTH_CHECK ) \ 610 const LENGTH_CHECK_TYPE lengthCheckType ); 611 #define readConstructed( stream, length, tag ) \ 612 readConstructedExt( stream, length, tag, LENGTH_CHECK_NONZERO ) 613 #define readConstructedZ( stream, length, tag ) \ 614 readConstructedExt( stream, length, tag, LENGTH_CHECK_ZERO ) 615 #define readConstructedI( stream, length, tag ) \ 616 readConstructedExt( stream, length, tag, LENGTH_CHECK_NONZERO_INDEF ) 617 618 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 619 int readOctetStringHole( INOUT STREAM *stream, 620 OUT_OPT_LENGTH_SHORT_MIN( minLength ) int *length, 621 IN_LENGTH_SHORT const int minLength, 622 IN_TAG const int tag ); 623 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 624 int readBitStringHole( INOUT STREAM *stream, 625 OUT_OPT_LENGTH_SHORT_MIN( minLength ) int *length, 626 IN_LENGTH_SHORT const int minLength, 627 IN_TAG const int tag ); 628 629 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 630 PARAMCHECK( lengthCheckType == LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_SHORT_Z ) \ 631 PARAMCHECK( lengthCheckType != LENGTH_CHECK_ZERO, length, OUT_OPT_LENGTH_MIN( minLength ) ) \ 632 int readGenericHoleExt( INOUT STREAM *stream, 633 /* PARAMCHECK */ int *length, 634 IN_LENGTH_SHORT_Z const int minLength, 635 IN_TAG_ENCODED const int tag, 636 IN_ENUM( LENGTH_CHECK ) \ 637 const LENGTH_CHECK_TYPE lengthCheckType ); 638 #define readGenericHole( stream, length, minLength, tag ) \ 639 readGenericHoleExt( stream, length, minLength, tag, LENGTH_CHECK_NONZERO ) 640 #define readGenericHoleZ( stream, length, minLength, tag ) \ 641 readGenericHoleExt( stream, length, minLength, tag, LENGTH_CHECK_ZERO ) 642 #define readGenericHoleI( stream, length, minLength, tag ) \ 643 readGenericHoleExt( stream, length, minLength, tag, LENGTH_CHECK_NONZERO_INDEF ) 644 645 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 646 int writeSequence( INOUT STREAM *stream, 647 IN_LENGTH_Z const int length ); 648 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 649 int writeSet( INOUT STREAM *stream, 650 IN_LENGTH_SHORT_Z const int length ); 651 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 652 int writeConstructed( INOUT STREAM *stream, 653 IN_LENGTH_Z const int length, 654 IN_TAG const int tag ); 655 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 656 int writeOctetStringHole( INOUT STREAM *stream, 657 IN_LENGTH_Z const int length, 658 IN_TAG const int tag ); 659 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 660 int writeBitStringHole( INOUT STREAM *stream, 661 IN_LENGTH_SHORT_Z const int length, 662 IN_TAG const int tag ); 663 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 664 int writeGenericHole( INOUT STREAM *stream, 665 IN_LENGTH_Z const int length, 666 IN_TAG const int tag ); 667 668 /* Read a generic object header, used to find the length of an object being 669 read as a blob */ 670 671 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 672 int readGenericObjectHeader( INOUT STREAM *stream, 673 OUT_LENGTH_INDEF long *length, 674 const BOOLEAN isLongObject ); 675 676 /* Read an arbitrary-length constructed object's data into a memory buffer. 677 This is the arbitrary-length form of readRawObject() */ 678 679 #define OBJECT_HEADER_DATA_SIZE 16 680 681 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 682 int readRawObjectAlloc( INOUT STREAM *stream, 683 OUT_BUFFER_ALLOC_OPT( *objectLengthPtr ) \ 684 void **objectPtrPtr, 685 OUT_LENGTH_BOUNDED_Z( maxLength ) \ 686 int *objectLengthPtr, 687 IN_LENGTH_SHORT_MIN( OBJECT_HEADER_DATA_SIZE ) \ 688 const int minLength, 689 IN_LENGTH_SHORT const int maxLength ); 690 691 /* Determine the length of an ASN.1-encoded object (this just reads the 692 outer length if present, but will burrow down into the object if necessary 693 if the length is indefinite) and check that an object has valid encoding */ 694 695 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 696 int getStreamObjectLength( INOUT STREAM *stream, OUT_DATALENGTH_Z int *length ); 697 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 698 int getObjectLength( IN_BUFFER( objectLength ) \ 699 const void *objectPtr, 700 IN_DATALENGTH const int objectLength, 701 OUT_DATALENGTH_Z int *length ); 702 CHECK_RETVAL_LENGTH STDC_NONNULL_ARG( ( 1 ) ) \ 703 int checkObjectEncoding( IN_BUFFER( objectLength ) const void *objectPtr, 704 IN_DATALENGTH const int objectLength ); 705 706 /* Full-length equivalents of length/encapsulating-object read routines. 707 These are used explicitly in the rare situations where long lengths are 708 valid, all other ASN.1 code only works with short lengths. Because these 709 can be quite long, they allow definite or indefinite lengths. 710 711 Note that readLongGenericHole() takes a full encoded tag value, since we 712 don't know what form it has to be turned into when reading the tag */ 713 714 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 715 int readLongSequence( INOUT STREAM *stream, 716 OUT_OPT_LENGTH_INDEF long *length ); 717 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 718 int readLongSet( INOUT STREAM *stream, OUT_OPT_LENGTH_INDEF long *length ); 719 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 720 int readLongConstructed( INOUT STREAM *stream, 721 OUT_OPT_LENGTH_INDEF long *length, 722 IN_TAG const int tag ); 723 724 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 725 int readLongGenericHoleExt( INOUT STREAM *stream, 726 OUT_OPT_LENGTH_INDEF long *length, 727 IN_TAG_ENCODED const int tag, 728 IN_ENUM( LENGTH_CHECK ) \ 729 const LENGTH_CHECK_TYPE lengthCheckType ); 730 #define readLongGenericHole( stream, length, tag ) \ 731 readLongGenericHoleExt( stream, length, tag, LENGTH_CHECK_NONZERO ) 732 #define readLongGenericHoleZ( stream, length, tag ) \ 733 readLongGenericHoleExt( stream, length, tag, LENGTH_CHECK_ZERO ) 734 735 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 736 int getLongStreamObjectLength( INOUT STREAM *stream, 737 OUT_DATALENGTH_Z long *length ); 738 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 739 int getLongObjectLength( IN_BUFFER( objectLength ) const void *objectPtr, 740 IN_DATALENGTH const long objectLength, 741 OUT_DATALENGTH_Z long *length ); 742 743 #endif /* USE_INT_ASN1 */ 744 #endif /* !_ASN1_DEFINED */ 745