1 /****************************************************************************
2 * *
3 * Certificate Attribute Checking Routines *
4 * Copyright Peter Gutmann 1996-2008 *
5 * *
6 ****************************************************************************/
7
8 #if defined( INC_ALL )
9 #include "cert.h"
10 #include "certattr.h"
11 #include "asn1_ext.h"
12 #else
13 #include "cert/cert.h"
14 #include "cert/certattr.h"
15 #include "enc_dec/asn1_ext.h"
16 #endif /* Compiler-specific includes */
17
18 /* Define the following to print a trace of the certificate fields being
19 checked */
20
21 #if !defined( NDEBUG ) && 0
22 #define TRACE_FIELDTYPE( attributeInfoPtr ) \
23 { \
24 if( ( attributeInfoPtr ) != NULL && \
25 ( attributeInfoPtr )->description != NULL ) \
26 DEBUG_PRINT(( ( attributeInfoPtr )->description )); \
27 else \
28 DEBUG_PRINT(( "<Unrecognised attribute>" )); \
29 DEBUG_PRINT(( "\n" )); \
30 }
31 #define TRACE_DEBUG( message ) \
32 DEBUG_PRINT( message )
33 #else
34 #define TRACE_FIELDTYPE( attributeInfoPtr )
35 #define TRACE_DEBUG( message )
36 #endif /* NDEBUG */
37
38 #ifdef USE_CERTIFICATES
39
40 /****************************************************************************
41 * *
42 * Attribute Field Type Checking *
43 * *
44 ****************************************************************************/
45
46 /* Validate and preprocess a set of attributes and set up links to the
47 information in the attribute information table in preparation for
48 encoding the attribute. This is a rather complex process that relies on
49 stepping through the list of attribute fields and the attribute
50 information table in sync and making sure that the list of fields is
51 consistent with the attribute information table. In addition we set up
52 synchronisation points between the list and table that are used during
53 the encoding process. For example assume that we have the following
54 attribute:
55
56 attribute ::= SEQUENCE {
57 foo BOOLEAN DEFAULT TRUE,
58 bar SEQUENCE OF OBJECT IDENTIFIER
59 }
60
61 The attribute information table would encode this attribute as:
62
63 t1: OID SEQUENCE
64 t2: BOOLEAN OPTIONAL
65 t3: SEQUENCE
66 t4: OID END
67
68 The first table entry t1 contains the OID, the SEQUENCE wrapper. For the
69 purposes of comparison with the list this is a no-op and can be skipped
70 since it's only used for encoding purposes. The next table entry t2
71 contains the first attribute field, an optional boolean. The next table
72 entry t3 contains another SEQUENCE wrapper that again is only used for
73 encoding and can be skipped for comparing with the list. Finally, the
74 last table entry t4 contains the second attribute field, an OID, and the
75 end-of-attribute flag.
76
77 Assuming that the attribute list contains the following:
78
79 BOOLEAN FALSE -> t1
80 OID xxx -> t3
81
82 The attribute validation process sets the synchronisation point for the
83 first attribute list entry to point to t1 and the second one to point to
84 t3. When we encode the attribute we encode t1 (the OID, critical flag,
85 and SEQUENCE wrapper) and then since the field IDs won't match we step on
86 to t2 and use that to encode the boolean. We then do the same for t3
87 with the SEQUENCE and OID.
88
89 If the attribute list instead contained only:
90
91 OID xxx -> t1
92
93 then this time the attribute validation process sets the synchronisation
94 point to t1. When encoding we encode t1 as before, step to t2, the field
95 IDs won't match but t2 is optional so we skip it, then encode t3 as for
96 t1 and finally encode the OID using t4.
97
98 At this point we also evaluate the encoded size of each attribute. For
99 invidual fields we just store their encoded size. For constructed
100 objects we stack the attribute list entry where the constructed object
101 starts and, until we reach the end of the constructed object, accumulate
102 the total size of the fields that make up the object. When we reach the
103 end of the object we unstack the pointer to the attribute list and store
104 the total size in it.
105
106 To handle nested constructed objects we only update the size of the
107 topmost item on the stack. When this is unstacked we add the size of
108 that entry plus the size of its tag and length information to the next
109 entry on the stack.
110
111 In addition to updating the size we also record the sequence of table
112 entries that are required to encode the constructed item. A worst-case
113 sequence of entries would be:
114
115 SEQUENCE {
116 SEQUENCE OPTIONAL { ... } | Not encoded
117 SEQUENCE {
118 SEQUENCE OPTIONAL { ... } | Not encoded
119 SEQUENCE {
120 value
121 }
122 }
123 }
124
125 which contains an alternating sequence of encoded and non-encoded fields.
126 Because of this the validation check performs the complex task of
127 recording which table entries are used for the encoding by stacking and
128 unstacking them and discarding the ones that evaluate to a zero size
129 during the unstacking process.
130
131 Each entry in the stack contains the list item that it applies to, the
132 table entry which is used to encode the stacked item, and the size of the
133 item */
134
135 #define ATTRIBUTE_STACKSIZE 10
136
137 typedef struct {
138 ATTRIBUTE_LIST *attributeListPtr; /* List entry that this applies to */
139 const ATTRIBUTE_INFO *attributeInfoPtr; /* Encoding point for sequence */
140 int size; /* Size of sequence */
141 } ATTRIBUTE_STACK;
142
143 /* Once we reach the end of the constructed item we need to unwind the stack
144 and update everything that we've gone past. If it's an optional item (so
145 that nothing gets encoded) we don't do anything. The count argument
146 specifies the level of unwinding to perform, this can be relative
147 (isRelative = TRUE, in which case we undo 'count' levels of nesting, which
148 may be more than count stack positions if non-nested data was stacked) or
149 absolute (isRelative = FALSE, in which case we undo 'count' stack
150 positions */
151
152 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
INOUT_ARRAY_C(ATTRIBUTE_STACKSIZE)153 static int updateStackedInfo( INOUT_ARRAY_C( ATTRIBUTE_STACKSIZE ) \
154 ATTRIBUTE_STACK *stack,
155 IN_RANGE( 0, ATTRIBUTE_STACKSIZE - 1 ) \
156 const int stackPos,
157 OUT_RANGE( 0, ATTRIBUTE_STACKSIZE - 1 ) \
158 int *newStackPosPtr,
159 IN_RANGE( 0, ATTRIBUTE_STACKSIZE - 1 ) int count,
160 const BOOLEAN isRelative )
161 {
162 int currentStackPos = stackPos, iterationCount;
163
164 assert( isWritePtr( stack, sizeof( ATTRIBUTE_STACK ) * \
165 ATTRIBUTE_STACKSIZE ) );
166 assert( isWritePtr( newStackPosPtr, sizeof( int ) ) );
167
168 static_assert( ENCODING_FIFO_SIZE >= ATTRIBUTE_STACKSIZE, \
169 "Stack size" );
170
171 REQUIRES( stackPos >= 0 && stackPos < ATTRIBUTE_STACKSIZE );
172 REQUIRES( count >= 0 && count <= stackPos );
173
174 for( iterationCount = 0; \
175 count > 0 && iterationCount < ATTRIBUTE_STACKSIZE; \
176 count--, iterationCount++ )
177 {
178 ATTRIBUTE_LIST *attributeFifoPtr;
179 const ATTRIBUTE_INFO *attributeInfoPtr;
180 int size;
181
182 ENSURES( count > 0 && count <= currentStackPos );
183
184 /* Unstack the current entry */
185 currentStackPos--;
186 ENSURES( currentStackPos >= 0 && \
187 currentStackPos < ATTRIBUTE_STACKSIZE );
188 attributeFifoPtr = stack[ currentStackPos ].attributeListPtr;
189 attributeInfoPtr = stack[ currentStackPos ].attributeInfoPtr;
190 size = stack[ currentStackPos ].size;
191 ENSURES( size >= 0 && size < MAX_INTLENGTH );
192 assert( isReadPtr( attributeInfoPtr, sizeof( ATTRIBUTE_INFO ) ) );
193
194 /* If there's nothing to encode, continue. There are a few special
195 cases here where even if the sequence is of zero length we may
196 have to encode something. Firstly, if there's a member with a
197 default value present (resulting in nothing being encoded) we
198 still have to encode a zero-length sequence. In addition if all
199 of the members have non-encoding values (e.g. OIDs and fixed
200 attributes, none of which are specified by the user) then we have
201 to encode these even though there's no actual value associated
202 with them since their mere presence conveys the necessary
203 information.
204
205 In addition sometimes we can reach the end of the attribute list
206 but there are further actions defined in the encoding table (for
207 example cleanup actions in nested sequences). In this case the
208 stacked attributeFifoPtr is NULL and the size is zero so we
209 perform an additional check to make sure that the pointer is
210 non-null */
211 if( attributeFifoPtr == NULL )
212 {
213 ENSURES( size == 0 );
214 continue;
215 }
216 if( size <= 0 && \
217 !( ( attributeFifoPtr->flags & ATTR_FLAG_DEFAULTVALUE ) || \
218 ( attributeInfoPtr->encodingFlags & FL_NONENCODING ) ) )
219 continue;
220
221 /* Remember the size and table entry used to encode this stack
222 entry */
223 attributeFifoPtr->sizeFifo[ attributeFifoPtr->fifoEnd ] = size;
224 attributeFifoPtr->encodingFifo[ attributeFifoPtr->fifoEnd++ ] = \
225 stack[ currentStackPos ].attributeInfoPtr;
226
227 ENSURES( attributeFifoPtr->fifoEnd > 0 && \
228 attributeFifoPtr->fifoEnd < ENCODING_FIFO_SIZE );
229
230 /* If there are no further items on the stack, continue */
231 if( currentStackPos <= 0 )
232 continue;
233
234 ENSURES( currentStackPos > 0 && \
235 currentStackPos < ATTRIBUTE_STACKSIZE );
236
237 /* If it's a non-constructed field, add the length of the existing and
238 new fields */
239 if( attributeInfoPtr->fieldType != BER_SEQUENCE && \
240 attributeInfoPtr->fieldType != BER_SET )
241 {
242 int newLength;
243
244 /* Calculate the size of the encoded field data. A sequence of
245 identifier fields has a final catch-all entry without an OID
246 which is only used for decoding, we should never see this
247 when encoding but we make the check explicit just in case */
248 if( attributeInfoPtr->fieldType == FIELDTYPE_IDENTIFIER )
249 {
250 ENSURES( attributeInfoPtr->oid );
251 newLength = sizeofOID( attributeInfoPtr->oid );
252 }
253 else
254 newLength = ( int ) attributeInfoPtr->defaultValue;
255
256 /* Add the new length to the existing data size. Since this is a
257 non-constructed field it doesn't count as a reduction in the
258 nesting level so if we're unnesting by a relative amount we
259 adjust the nesting count to give a net change of zero for this
260 item */
261 stack[ currentStackPos - 1 ].size += size + newLength;
262 if( isRelative )
263 count++;
264 }
265 else
266 {
267 /* It's a constructed field, percolate the encapsulated content
268 size up the stack */
269 stack[ currentStackPos - 1 ].size += ( int ) sizeofObject( size );
270 }
271 }
272 ENSURES( iterationCount < ATTRIBUTE_STACKSIZE );
273
274 *newStackPosPtr = currentStackPos;
275
276 return( CRYPT_OK );
277 }
278
279 /* Some attributes contain a sequence of items of the attributeTypeAndValue
280 form (i.e. OID, ANY DEFINED BY OID). To process these we check whether
281 the named value component in the attribute list is present in the current
282 attributeTypeAndValue definition. If it isn't the item is given a zero
283 length, which means that it's never encoded since the field is marked as
284 optional. The following function checks whether a named value component
285 is present in the item */
286
287 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
288 static int checkComponentPresent( IN_RANGE( CRYPT_ATTRIBUTE_NONE + 1,
289 CRYPT_IATTRIBUTE_LAST ) \
290 const CRYPT_ATTRIBUTE_TYPE fieldID,
291 INOUT ATTRIBUTE_INFO **attributeInfoPtrPtr )
292 {
293 const ATTRIBUTE_INFO *attributeInfoPtr = *attributeInfoPtrPtr;
294 int nestLevel = 0, iterationCount;
295
296 assert( isWritePtr( attributeInfoPtrPtr, sizeof( ATTRIBUTE_INFO * ) ) );
297 assert( isReadPtr( *attributeInfoPtrPtr, sizeof( ATTRIBUTE_INFO ) ) );
298
299 REQUIRES( ( fieldID > CRYPT_ATTRIBUTE_NONE && \
300 fieldID < CRYPT_ATTRIBUTE_LAST ) || \
301 ( fieldID == CRYPT_IATTRIBUTE_LAST ) );
302 /* The latter is used when we've run out of values to match
303 and just want to skip to the end of the
304 attributeTypeAndValue */
305
306 /* Check each field that we find until we find the end of the
307 attributeTypeAndValue. Unfortunately we don't know how many
308 attribute table entries are left so we have to use the generic
309 FAILSAFE_ITERATIONS_LARGE for the bounds check */
310 for( iterationCount = 0; iterationCount < FAILSAFE_ITERATIONS_LARGE; \
311 iterationCount++ )
312 {
313 /* Sanity check to make sure that we don't fall off the end of the
314 table */
315 ENSURES( !isAttributeTableEnd( attributeInfoPtr ) );
316
317 /* Adjust the nesting level depending on whether we're entering or
318 leaving a sequence */
319 if( attributeInfoPtr->fieldType == BER_SEQUENCE )
320 nestLevel++;
321 nestLevel -= decodeNestingLevel( attributeInfoPtr->encodingFlags );
322
323 /* If the field is present in this attributeTypeAndValue, return */
324 if( attributeInfoPtr->fieldID == fieldID )
325 return( CRYPT_OK );
326
327 /* If we're at the end of the attribute or the attributeTypeAndValue,
328 exit the loop before adjusting the attributeInfoPtr so that we're
329 still pointing at the end-of-attribute field */
330 if( nestLevel <= 0 || \
331 ( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTREND ) )
332 break;
333
334 attributeInfoPtr++;
335 }
336 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
337
338 /* The field isn't present, update the pointer to the next
339 attributeTypeAndValue or the end of the attribute */
340 *attributeInfoPtrPtr = ( ATTRIBUTE_INFO * ) attributeInfoPtr;
341 return( CRYPT_ERROR_NOTFOUND );
342 }
343
344 /* State machine for checking a CHOICE. When we get to the start of a
345 CHOICE we move from CHOICE_NONE to CHOICE_START. Once we've checked one
346 of the CHOICE options we move to CHOICE_DONE. If a further option is
347 found in the CHOICE_DONE state we record an error. This is a somewhat
348 crude mechanism that works because the only CHOICE fields that can't be
349 handled by rewriting them as alternative representations are complete
350 attributes so that the CHOICE applies over the entire attribute. If a
351 CHOICE is ever present as an attribute subfield then the checking would
352 be handled by recursively checking it as a subtyped field */
353
354 typedef enum { CHOICE_NONE, CHOICE_START, CHOICE_DONE } CHOICE_STATE;
355
356 /* Check an entry in the attribute table. While we're performing the check
357 we need to pass a lot of state information around, this is contained in
358 the following structure */
359
360 typedef struct {
361 /* State information. When we're encoding a subtyped field (using an
362 alternative encoding table) we need to remember the field ID of the
363 parent to both tell the encoding routines that we're using an
364 alternative encoding table and to remember the overall field ID so we
365 don't treat two adjacent field subfields as though they were part of
366 the same parent field. If we're not currently encoding a subtyped
367 field, this field is set to CRYPT_ATTRIBUTE_NONE */
368 ATTRIBUTE_LIST *attributeListPtr; /* Position in attribute list */
369 const ATTRIBUTE_INFO *attributeInfoPtr; /* Position in attribute table */
370 CRYPT_ATTRIBUTE_TYPE subtypeParent; /* Parent of subtype being processed */
371 CHOICE_STATE choiceState; /* State of CHOICE processing */
372
373 /* Encoding stack. When we're encoding subfields the stack contains
374 items from both the subfield and the encapsulating field so we also
375 record the current stack top to make sure that we don't go past this
376 level when popping items after we've finished encoding a subfield */
377 ARRAY( ATTRIBUTE_STACKSIZE, stackPos ) \
378 ATTRIBUTE_STACK stack[ ATTRIBUTE_STACKSIZE + 8 ];
379 int stackPos; /* Encoding stack position */
380 int stackTop;
381
382 /* Error information */
383 CRYPT_ATTRIBUTE_TYPE errorLocus;/* Error locus */
384 int errorType; /* Error type */
385 } ATTRIBUTE_CHECK_INFO;
386
387 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
stackInfo(INOUT ATTRIBUTE_CHECK_INFO * attributeCheckInfo,IN_OPT ATTRIBUTE_LIST * attributeListPtr,const ATTRIBUTE_INFO * attributeInfoPtr)388 static int stackInfo( INOUT ATTRIBUTE_CHECK_INFO *attributeCheckInfo,
389 IN_OPT ATTRIBUTE_LIST *attributeListPtr,
390 const ATTRIBUTE_INFO *attributeInfoPtr )
391 {
392 ATTRIBUTE_STACK *stack = attributeCheckInfo->stack;
393
394 assert( isWritePtr( attributeCheckInfo, \
395 sizeof( ATTRIBUTE_CHECK_INFO ) ) );
396 assert( attributeListPtr == NULL || \
397 isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
398 assert( isReadPtr( attributeInfoPtr, sizeof( ATTRIBUTE_INFO ) ) );
399
400 REQUIRES( attributeCheckInfo->stackPos >= 0 && \
401 attributeCheckInfo->stackPos < ATTRIBUTE_STACKSIZE - 1 );
402
403 stack[ attributeCheckInfo->stackPos ].size = 0;
404 stack[ attributeCheckInfo->stackPos ].attributeListPtr = attributeListPtr;
405 stack[ attributeCheckInfo->stackPos++ ].attributeInfoPtr = attributeInfoPtr;
406
407 return( CRYPT_OK );
408 }
409
410 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
411 static int checkAttribute( INOUT ATTRIBUTE_CHECK_INFO *attributeCheckInfo );
412 /* Forward declaration for function */
413
414 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
checkAttributeEntry(INOUT ATTRIBUTE_CHECK_INFO * attributeCheckInfo)415 static int checkAttributeEntry( INOUT ATTRIBUTE_CHECK_INFO *attributeCheckInfo )
416 {
417 ATTRIBUTE_LIST *attributeListPtr = attributeCheckInfo->attributeListPtr;
418 const ATTRIBUTE_INFO *attributeInfoPtr = attributeCheckInfo->attributeInfoPtr;
419 ATTRIBUTE_STACK *stack = attributeCheckInfo->stack;
420 CRYPT_ATTRIBUTE_TYPE fieldID;
421
422 assert( isWritePtr( attributeCheckInfo, \
423 sizeof( ATTRIBUTE_CHECK_INFO ) ) );
424 assert( attributeListPtr == NULL || \
425 isWritePtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
426 assert( isReadPtr( attributeInfoPtr, sizeof( ATTRIBUTE_INFO ) ) );
427 assert( isWritePtr( stack, \
428 sizeof( ATTRIBUTE_STACK ) * ATTRIBUTE_STACKSIZE ) );
429
430 /* Determine the fieldID for the current attribute field. Once we get
431 to the end of an attribute list entry we may still run through this
432 function multiple times with attributeListPtr set to NULL but
433 attributeInfoPtr advancing on each step, see the comment in
434 updateStackedInfo() for details */
435 if( attributeListPtr == NULL || \
436 attributeListPtr->fieldID == CRYPT_ATTRIBUTE_NONE )
437 {
438 /* If we've reached the end of the list of recognised attributes,
439 use a non-ID that doesn't match any table entry */
440 fieldID = CRYPT_IATTRIBUTE_LAST;
441 }
442 else
443 {
444 /* If we're encoding a subtyped field the fieldID is the field ID
445 within the parent field, or the subFieldID */
446 if( attributeCheckInfo->subtypeParent == attributeListPtr->fieldID )
447 fieldID = attributeListPtr->subFieldID;
448 else
449 {
450 /* It's a standard attribute field */
451 fieldID = attributeListPtr->fieldID;
452 }
453 }
454
455 /* If the field in the attribute list matches the one in the table,
456 process it and move on to the next one */
457 if( attributeListPtr != NULL && attributeInfoPtr->fieldID == fieldID )
458 {
459 /* If it's a subtyped or CHOICE field, check the components using
460 their own encoding table */
461 if( attributeInfoPtr->fieldType == FIELDTYPE_SUBTYPED || \
462 attributeInfoPtr->fieldType == FIELDTYPE_CHOICE )
463 {
464 int status;
465
466 /* Switch to the new encoding table, record the fact that
467 we've done this, and set the new stack top to the level at
468 which we start encoding the subtype */
469 if( attributeInfoPtr->fieldType == FIELDTYPE_CHOICE )
470 {
471 /* Stack the value start position in the attribute list and
472 record the fact that we're processing a CHOICE */
473 status = stackInfo( attributeCheckInfo, attributeListPtr,
474 attributeInfoPtr );
475 if( cryptStatusError( status ) )
476 return( status );
477 attributeCheckInfo->choiceState = CHOICE_START;
478 }
479 attributeCheckInfo->attributeInfoPtr = \
480 ( const ATTRIBUTE_INFO * ) attributeInfoPtr->extraData;
481 attributeCheckInfo->subtypeParent = attributeListPtr->fieldID;
482 attributeCheckInfo->stackTop = attributeCheckInfo->stackPos;
483 status = checkAttribute( attributeCheckInfo );
484 attributeCheckInfo->attributeInfoPtr = attributeInfoPtr;
485 attributeCheckInfo->subtypeParent = CRYPT_ATTRIBUTE_NONE;
486 attributeCheckInfo->stackTop = 0;
487 if( !( attributeInfoPtr->encodingFlags & FL_OPTIONAL ) && \
488 attributeCheckInfo->attributeListPtr == attributeListPtr )
489 {
490 /* The subtyped field was non-optional but we failed to
491 match anything in it against the current attribute list
492 entry (meaning that the atributeListPtr in the check info
493 hasn't been advanced), there's a problem with the
494 encoding table. This check is used to catch situations
495 where a subtyped field is used to encode a CHOICE for
496 which each CHOICE field is optional but at least one
497 component of the CHOICE must be present */
498 retIntError();
499 }
500 return( status );
501 }
502
503 /* If there's an extended validation function attached to this field,
504 call it */
505 if( attributeInfoPtr->extraData != NULL )
506 {
507 VALIDATION_FUNCTION validationFunction = \
508 ( VALIDATION_FUNCTION ) attributeInfoPtr->extraData;
509
510 attributeCheckInfo->errorType = \
511 validationFunction( attributeListPtr );
512 if( attributeCheckInfo->errorType != CRYPT_ERRTYPE_NONE )
513 return( CRYPT_ERROR_INVALID );
514 }
515
516 /* If this is an optional field and the value is the same as the
517 default value remember that it doesn't get encoded */
518 if( ( attributeInfoPtr->encodingFlags & FL_DEFAULT ) && \
519 ( attributeInfoPtr->defaultValue == attributeListPtr->intValue ) )
520 {
521 attributeListPtr->flags |= ATTR_FLAG_DEFAULTVALUE;
522 attributeCheckInfo->attributeListPtr = attributeListPtr->next;
523
524 return( CRYPT_OK );
525 }
526
527 /* Remember the encoded size of this field. writeAttributeField()
528 takes a compliance-level parameter that controls stricter
529 encoding of some string types at higher compliance levels but
530 this doesn't affect the encoded size so we always use
531 CRYPT_COMPLIANCELEVEL_STANDARD for the size calculation */
532 attributeListPtr->attributeInfoPtr = attributeInfoPtr;
533 attributeListPtr->encodedSize = \
534 writeAttributeField( NULL, attributeListPtr,
535 CRYPT_COMPLIANCELEVEL_STANDARD );
536 if( attributeCheckInfo->stackPos > 0 )
537 {
538 stack[ attributeCheckInfo->stackPos - 1 ].size += \
539 attributeListPtr->encodedSize;
540 }
541
542 /* If this is a CHOICE field update the choice state */
543 if( attributeCheckInfo->choiceState != CHOICE_NONE )
544 {
545 if( attributeCheckInfo->choiceState == CHOICE_DONE )
546 {
547 /* If we've already processed one of the CHOICE options
548 there can't be another one present */
549 attributeCheckInfo->errorType = CRYPT_ERRTYPE_ATTR_PRESENT;
550 return( CRYPT_ERROR_INVALID );
551 }
552 if( attributeCheckInfo->choiceState == CHOICE_START )
553 {
554 /* Remember that we've seen a CHOICE option */
555 attributeCheckInfo->choiceState = CHOICE_DONE;
556 }
557 }
558
559 /* Move on to the next attribute field */
560 attributeCheckInfo->attributeListPtr = attributeListPtr->next;
561 return( CRYPT_OK );
562 }
563
564 /* If it's an attributeTypeAndValue sequence check whether it contains
565 the field that we want:
566
567 t0: BER_SEQUENCE IDENTIFIER
568 t1: OID
569 [ t2: params NONENCODING ]
570
571 The initialisation sanity-check has already confirmed the validity of
572 the above format in the encoding table on startup */
573 if( attributeInfoPtr->encodingFlags & FL_IDENTIFIER )
574 {
575 BOOLEAN endOfAttributeField = FALSE;
576 int status;
577
578 status = checkComponentPresent( fieldID,
579 ( ATTRIBUTE_INFO ** ) &attributeInfoPtr );
580 if( status == CRYPT_ERROR_NOTFOUND )
581 {
582 /* Since we've jumped over several items we may be pointing at an
583 end-of-sequence flag for which no sequence start was stacked
584 so we skip the stack update step */
585 attributeCheckInfo->attributeInfoPtr = attributeInfoPtr;
586 return( OK_SPECIAL );
587 }
588 if( cryptStatusError( status ) )
589 return( status );
590
591 /* Stack the position of the sequence start and the following OID */
592 status = stackInfo( attributeCheckInfo, attributeListPtr,
593 attributeInfoPtr++ );
594 if( cryptStatusOK( status ) )
595 status = stackInfo( attributeCheckInfo, attributeListPtr,
596 attributeInfoPtr );
597 if( cryptStatusError( status ) )
598 return( status );
599
600 /* If the OID entry is marked as the end-of-sequence there are no
601 parameters attached so we move on to the next entry */
602 if( attributeInfoPtr->encodingFlags & FL_SEQEND_MASK )
603 endOfAttributeField = TRUE;
604
605 /* Sometimes the OID is followed by a fixed-value blob field that
606 constitutes parameters for the OID, if this is present we stack it
607 as well */
608 if( attributeInfoPtr[ 1 ].encodingFlags & FL_NONENCODING )
609 {
610 attributeInfoPtr++;
611 status = stackInfo( attributeCheckInfo, attributeListPtr,
612 attributeInfoPtr );
613 if( cryptStatusError( status ) )
614 return( status );
615
616 /* If the fields are fixed-value we always move on to the next
617 entry since there are no user-supplied parameters present */
618 endOfAttributeField = TRUE;
619 }
620
621 attributeCheckInfo->attributeInfoPtr = attributeInfoPtr;
622 if( endOfAttributeField )
623 {
624 /* If this is all that needs to be encoded move on to the next
625 attribute field */
626 if( attributeListPtr == NULL )
627 attributeCheckInfo->attributeListPtr = NULL;
628 else
629 attributeCheckInfo->attributeListPtr = attributeListPtr->next;
630 }
631 return( CRYPT_OK );
632 }
633
634 /* If it's a SEQUENCE/SET or a non-encoding value then it's a no-op entry
635 used only for encoding purposes and can be skipped, however we need to
636 remember it for later encoding */
637 if( attributeInfoPtr->fieldType == BER_SEQUENCE || \
638 attributeInfoPtr->fieldType == BER_SET || \
639 attributeInfoPtr->encodingFlags & FL_NONENCODING )
640 {
641 /* Stack the sequence or value start position in the attribute list */
642 return( stackInfo( attributeCheckInfo, attributeListPtr,
643 attributeInfoPtr ) );
644 }
645
646 /* If it's a non-optional field and the attribute field doesn't match,
647 it's an error - attribute attributeID is missing field
648 attributeInfoPtr->fieldID (optional subfield
649 attributeInfoPtr->subFieldID) (set by the error handler in the calling
650 code) */
651 if( !( attributeInfoPtr->encodingFlags & FL_OPTIONAL ) )
652 {
653 attributeCheckInfo->errorType = CRYPT_ERRTYPE_ATTR_ABSENT;
654 return( CRYPT_ERROR_NOTINITED );
655 }
656
657 return( CRYPT_OK );
658 }
659
660 /* Check an individual attribute */
661
662 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
checkAttribute(INOUT ATTRIBUTE_CHECK_INFO * attributeCheckInfo)663 static int checkAttribute( INOUT ATTRIBUTE_CHECK_INFO *attributeCheckInfo )
664 {
665 ATTRIBUTE_LIST *restartEntry = NULL;
666 const ATTRIBUTE_INFO *restartPoint = NULL;
667 int restartStackPos = 0, iterationCount;
668
669 assert( isWritePtr( attributeCheckInfo, \
670 sizeof( ATTRIBUTE_CHECK_INFO ) ) );
671 assert( isReadPtr( attributeCheckInfo->attributeInfoPtr,
672 sizeof( ATTRIBUTE_INFO ) ) );
673
674 TRACE_DEBUG(( "Checking attribute " ));
675 TRACE_FIELDTYPE( attributeCheckInfo->attributeInfoPtr );
676
677 /* Step through the attribute comparing the fields that are present in
678 the attribute list with the fields that should be present according
679 to the table and set encoding synchronisation points as required */
680 for( iterationCount = 0; iterationCount < FAILSAFE_ITERATIONS_LARGE;
681 iterationCount++ )
682 {
683 int typeInfoFlags, status;
684
685 /* Sanity check to make sure that we don't fall off the end of the
686 encoding table */
687 ENSURES( !isAttributeTableEnd( attributeCheckInfo->attributeInfoPtr ) );
688
689 /* Check whether this is a repeated instance of the same attribute
690 and if it is remember the encoding restart point. We have to do
691 this before we check the attribute information because it usually
692 updates the information after the check */
693 if( restartEntry == NULL && \
694 attributeCheckInfo->attributeListPtr != NULL && \
695 attributeCheckInfo->attributeListPtr->next != NULL && \
696 ( attributeCheckInfo->attributeListPtr->fieldID == \
697 attributeCheckInfo->attributeListPtr->next->fieldID ) && \
698 ( attributeCheckInfo->attributeListPtr->subFieldID == \
699 attributeCheckInfo->attributeListPtr->next->subFieldID ) )
700 {
701 restartEntry = attributeCheckInfo->attributeListPtr;
702 restartPoint = attributeCheckInfo->attributeInfoPtr + 1;
703 restartStackPos = attributeCheckInfo->stackPos + 1;
704 }
705
706 /* Check the current encoding table entry */
707 status = checkAttributeEntry( attributeCheckInfo );
708 if( status != OK_SPECIAL )
709 {
710 if( cryptStatusError( status ) )
711 {
712 attributeCheckInfo->errorLocus = \
713 attributeCheckInfo->attributeInfoPtr->fieldID;
714 return( status );
715 }
716
717 /* If this is the end of a constructed item unstack it and
718 update the attribute list entry with the length information.
719 If it's a sequence with all fields optional (so that nothing
720 gets encoded) we don't do anything */
721 status = updateStackedInfo( attributeCheckInfo->stack,
722 attributeCheckInfo->stackPos,
723 &attributeCheckInfo->stackPos,
724 decodeNestingLevel( attributeCheckInfo->attributeInfoPtr->encodingFlags ),
725 TRUE );
726 if( cryptStatusError( status ) )
727 return( status );
728 }
729
730 /* If there's another instance of the same item, don't move on to
731 the next table entry */
732 if( restartEntry != NULL && \
733 restartEntry != attributeCheckInfo->attributeListPtr )
734 {
735 /* Restart at the table entry for the previous instance of the
736 item and adjust the stack to match */
737 attributeCheckInfo->attributeInfoPtr = restartPoint;
738 if( attributeCheckInfo->stackPos > restartStackPos )
739 {
740 status = updateStackedInfo( attributeCheckInfo->stack,
741 attributeCheckInfo->stackPos,
742 &attributeCheckInfo->stackPos,
743 attributeCheckInfo->stackPos - \
744 restartStackPos, TRUE );
745 if( cryptStatusError( status ) )
746 return( status );
747 }
748 restartEntry = NULL;
749 restartPoint = NULL;
750 restartStackPos = 0;
751
752 continue;
753 }
754
755 /* Move on to the next table entry. We have to check the
756 continuation flag before we move to the next table entry in order
757 to include processing of the last field in an attribute */
758 typeInfoFlags = attributeCheckInfo->attributeInfoPtr->typeInfoFlags;
759 attributeCheckInfo->attributeInfoPtr++;
760 if( typeInfoFlags & FL_ATTR_ATTREND )
761 break;
762 }
763 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
764 attributeCheckInfo->choiceState = CHOICE_NONE;
765
766 /* We've reached the end of the attribute, if there are still constructed
767 objects stacked, unstack them and update their length information. If
768 it's a sequence with all fields optional (so that nothing gets
769 encoded) this won't do anything */
770 return( updateStackedInfo( attributeCheckInfo->stack,
771 attributeCheckInfo->stackPos,
772 &attributeCheckInfo->stackPos,
773 attributeCheckInfo->stackPos - \
774 attributeCheckInfo->stackTop, FALSE ) );
775 }
776
777 /* Check the entire list of attributes */
778
779 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3, 4 ) ) \
checkAttributes(IN_ENUM (ATTRIBUTE)const ATTRIBUTE_TYPE attributeType,const ATTRIBUTE_PTR * listHeadPtr,OUT_ENUM_OPT (CRYPT_ATTRIBUTE)CRYPT_ATTRIBUTE_TYPE * errorLocus,OUT_ENUM_OPT (CRYPT_ERRTYPE)CRYPT_ERRTYPE_TYPE * errorType)780 int checkAttributes( IN_ENUM( ATTRIBUTE ) const ATTRIBUTE_TYPE attributeType,
781 const ATTRIBUTE_PTR *listHeadPtr,
782 OUT_ENUM_OPT( CRYPT_ATTRIBUTE ) \
783 CRYPT_ATTRIBUTE_TYPE *errorLocus,
784 OUT_ENUM_OPT( CRYPT_ERRTYPE ) \
785 CRYPT_ERRTYPE_TYPE *errorType )
786 {
787 ATTRIBUTE_CHECK_INFO attributeCheckInfo;
788 const ATTRIBUTE_INFO *attributeInfoStartPtr;
789 ATTRIBUTE_LIST *attributeListPtr;
790 int dummy, iterationCount, status;
791
792 assert( isReadPtr( listHeadPtr, sizeof( ATTRIBUTE_LIST ) ) );
793 assert( isWritePtr( errorLocus, sizeof( CRYPT_ATTRIBUTE_TYPE ) ) );
794 assert( isWritePtr( errorType, sizeof( CRYPT_ERRTYPE_TYPE ) ) );
795
796 REQUIRES( attributeType == ATTRIBUTE_CERTIFICATE || \
797 attributeType == ATTRIBUTE_CMS );
798
799 /* Clear return values */
800 *errorLocus = CRYPT_ATTRIBUTE_NONE;
801 *errorType = CRYPT_ERRTYPE_NONE;
802
803 /* Get the attribute encoding information. We can't use the size value
804 returned from this because of the nested-loop structure below which
805 only ever iterates through a subset of the encoding information so we
806 leave it as a dummy value */
807 status = getAttributeInfo( attributeType, &attributeInfoStartPtr,
808 &dummy );
809 ENSURES( cryptStatusOK( status ) );
810
811 /* If we've already done a validation pass some of the fields will
812 contain values that were previously set so before we begin we walk
813 down the list resetting the fields that are updated by this
814 function */
815 for( attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr, \
816 iterationCount = 0;
817 attributeListPtr != NULL && \
818 isValidAttributeField( attributeListPtr ) && \
819 iterationCount < FAILSAFE_ITERATIONS_LARGE;
820 attributeListPtr = attributeListPtr->next, iterationCount++ )
821 {
822 if( attributeListPtr->next != NULL && \
823 isValidAttributeField( attributeListPtr->next ) && \
824 attributeListPtr->attributeID > \
825 attributeListPtr->next->attributeID )
826 {
827 /* Safety check in case of an invalid attribute list */
828 retIntError();
829 }
830 attributeListPtr->attributeInfoPtr = NULL;
831 attributeListPtr->encodedSize = attributeListPtr->fifoPos = \
832 attributeListPtr->fifoEnd = 0;
833 attributeListPtr->flags &= ~ATTR_FLAG_DEFAULTVALUE;
834 }
835 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
836
837 /* Set up the attribute-checking state information */
838 memset( &attributeCheckInfo, 0, sizeof( ATTRIBUTE_CHECK_INFO ) );
839 attributeCheckInfo.attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr;
840 attributeCheckInfo.attributeInfoPtr = attributeInfoStartPtr;
841
842 /* Walk down the list of known attributes checking each one for
843 consistency */
844 for( iterationCount = 0;
845 attributeCheckInfo.attributeListPtr != NULL && \
846 attributeCheckInfo.attributeListPtr->fieldID != CRYPT_ATTRIBUTE_NONE && \
847 iterationCount < FAILSAFE_ITERATIONS_LARGE;
848 iterationCount++ )
849 {
850 int innerIterationCount;
851
852 /* Find the start of this attribute in the attribute information
853 table and remember it as an encoding synchronisation point.
854 Comparing the field ID with the attribute ID is usually valid
855 because the attribute information table always begins the series
856 of entries for an attribute with the attribute ID. The one
857 exception is where the attribute ID is the same as the field ID
858 but they're separate entries in the table, in which case the
859 first entries will contain a FIELDID_FOLLOWS code to indicate
860 that the following field contains the attribute/fieldID */
861 for( innerIterationCount = 0;
862 !isAttributeTableEnd( attributeCheckInfo.attributeInfoPtr ) && \
863 innerIterationCount < FAILSAFE_ITERATIONS_LARGE;
864 attributeCheckInfo.attributeInfoPtr++, innerIterationCount++ )
865 {
866 if( attributeCheckInfo.attributeInfoPtr->fieldID == FIELDID_FOLLOWS )
867 {
868 if( attributeCheckInfo.attributeInfoPtr[ 1 ].fieldID == \
869 attributeCheckInfo.attributeListPtr->attributeID )
870 break;
871 }
872 else
873 {
874 if( attributeCheckInfo.attributeInfoPtr->fieldID == \
875 attributeCheckInfo.attributeListPtr->attributeID )
876 break;
877 }
878 }
879 ENSURES( innerIterationCount < FAILSAFE_ITERATIONS_LARGE );
880 ENSURES( !isAttributeTableEnd( attributeCheckInfo.attributeInfoPtr ) );
881
882 /* Check this attribute */
883 status = checkAttribute( &attributeCheckInfo );
884 if( cryptStatusError( status ) )
885 {
886 *errorLocus = attributeCheckInfo.errorLocus;
887 *errorType = attributeCheckInfo.errorType;
888 return( status );
889 }
890 }
891 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
892
893 return( CRYPT_OK );
894 }
895 #endif /* USE_CERTIFICATES */
896