cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ext_chk.c
Go to the documentation of this file.
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.h"
12  #include "asn1_ext.h"
13 #else
14  #include "cert/cert.h"
15  #include "cert/certattr.h"
16  #include "enc_dec/asn1.h"
17  #include "enc_dec/asn1_ext.h"
18 #endif /* Compiler-specific includes */
19 
20 /* Define the following to print a trace of the certificate fields being
21  checked */
22 
23 #if !defined( NDEBUG ) && 0
24  #define TRACE_FIELDTYPE( attributeInfoPtr ) \
25  { \
26  if( ( attributeInfoPtr ) != NULL && \
27  ( attributeInfoPtr )->description != NULL ) \
28  DEBUG_PRINT(( ( attributeInfoPtr )->description )); \
29  else \
30  DEBUG_PRINT(( "<Unrecognised attribute>" )); \
31  DEBUG_PRINT(( "\n" )); \
32  }
33  #define TRACE_DEBUG( message ) \
34  DEBUG_PRINT( message )
35 #else
36  #define TRACE_FIELDTYPE( attributeInfoPtr )
37  #define TRACE_DEBUG( message )
38 #endif /* NDEBUG */
39 
40 #ifdef USE_CERTIFICATES
41 
42 /****************************************************************************
43 * *
44 * Attribute Field Type Checking *
45 * *
46 ****************************************************************************/
47 
48 /* Validate and preprocess a set of attributes and set up links to the
49  information in the attribute information table in preparation for
50  encoding the attribute. This is a rather complex process that relies on
51  stepping through the list of attribute fields and the attribute
52  information table in sync and making sure that the list of fields is
53  consistent with the attribute information table. In addition we set up
54  synchronisation points between the list and table that are used during
55  the encoding process. For example assume that we have the following
56  attribute:
57 
58  attribute ::= SEQUENCE {
59  foo BOOLEAN DEFAULT TRUE,
60  bar SEQUENCE OF OBJECT IDENTIFIER
61  }
62 
63  The attribute information table would encode this attribute as:
64 
65  t1: OID SEQUENCE
66  t2: BOOLEAN OPTIONAL
67  t3: SEQUENCE
68  t4: OID END
69 
70  The first table entry t1 contains the OID, the SEQUENCE wrapper. For the
71  purposes of comparison with the list this is a no-op and can be skipped
72  since it's only used for encoding purposes. The next table entry t2
73  contains the first attribute field, an optional boolean. The next table
74  entry t3 contains another SEQUENCE wrapper that again is only used for
75  encoding and can be skipped for comparing with the list. Finally, the
76  last table entry t4 contains the second attribute field, an OID, and the
77  end-of-attribute flag.
78 
79  Assuming that the attribute list contains the following:
80 
81  BOOLEAN FALSE -> t1
82  OID xxx -> t3
83 
84  The attribute validation process sets the synchronisation point for the
85  first attribute list entry to point to t1 and the second one to point to
86  t3. When we encode the attribute we encode t1 (the OID, critical flag,
87  and SEQUENCE wrapper) and then since the field IDs won't match we step on
88  to t2 and use that to encode the boolean. We then do the same for t3
89  with the SEQUENCE and OID.
90 
91  If the attribute list instead contained only:
92 
93  OID xxx -> t1
94 
95  then this time the attribute validation process sets the synchronisation
96  point to t1. When encoding we encode t1 as before, step to t2, the field
97  IDs won't match but t2 is optional so we skip it, then encode t3 as for
98  t1 and finally encode the OID using t4.
99 
100  At this point we also evaluate the encoded size of each attribute. For
101  invidual fields we just store their encoded size. For constructed
102  objects we stack the attribute list entry where the constructed object
103  starts and, until we reach the end of the constructed object, accumulate
104  the total size of the fields that make up the object. When we reach the
105  end of the object we unstack the pointer to the attribute list and store
106  the total size in it.
107 
108  To handle nested constructed objects we only update the size of the
109  topmost item on the stack. When this is unstacked we add the size of
110  that entry plus the size of its tag and length information to the next
111  entry on the stack.
112 
113  In addition to updating the size we also record the sequence of table
114  entries that are required to encode the constructed item. A worst-case
115  sequence of entries would be:
116 
117  SEQUENCE {
118  SEQUENCE OPTIONAL { ... } | Not encoded
119  SEQUENCE {
120  SEQUENCE OPTIONAL { ... } | Not encoded
121  SEQUENCE {
122  value
123  }
124  }
125  }
126 
127  which contains an alternating sequence of encoded and non-encoded fields.
128  Because of this the validation check performs the complex task of
129  recording which table entries are used for the encoding by stacking and
130  unstacking them and discarding the ones that evaluate to a zero size
131  during the unstacking process.
132 
133  Each entry in the stack contains the list item that it applies to, the
134  table entry which is used to encode the stacked item, and the size of the
135  item */
136 
137 #define ATTRIBUTE_STACKSIZE 10
138 
139 typedef struct {
140  ATTRIBUTE_LIST *attributeListPtr; /* List entry that this applies to */
141  const ATTRIBUTE_INFO *attributeInfoPtr; /* Encoding point for sequence */
142  int size; /* Size of sequence */
143  } ATTRIBUTE_STACK;
144 
145 /* Once we reach the end of the constructed item we need to unwind the stack
146  and update everything that we've gone past. If it's an optional item (so
147  that nothing gets encoded) we don't do anything. The count argument
148  specifies the level of unwinding to perform, this can be relative
149  (isRelative = TRUE, in which case we undo 'count' levels of nesting, which
150  may be more than count stack positions if non-nested data was stacked) or
151  absolute (isRelative = FALSE, in which case we undo 'count' stack
152  positions */
153 
154 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
155 static int updateStackedInfo( INOUT_ARRAY_C( ATTRIBUTE_STACKSIZE ) \
156  ATTRIBUTE_STACK *stack,
157  IN_RANGE( 0, ATTRIBUTE_STACKSIZE - 1 ) \
158  const int stackPos,
159  OUT_RANGE( 0, ATTRIBUTE_STACKSIZE - 1 ) \
160  int *newStackPosPtr,
161  IN_RANGE( 0, ATTRIBUTE_STACKSIZE - 1 ) int count,
162  const BOOLEAN isRelative )
163  {
164  int currentStackPos = stackPos, iterationCount;
165 
166  assert( isWritePtr( stack, sizeof( ATTRIBUTE_STACK ) * \
167  ATTRIBUTE_STACKSIZE ) );
168  assert( isWritePtr( newStackPosPtr, sizeof( int ) ) );
169 
170  static_assert( ENCODING_FIFO_SIZE >= ATTRIBUTE_STACKSIZE, \
171  "Stack size" );
172 
173  REQUIRES( stackPos >= 0 && stackPos < ATTRIBUTE_STACKSIZE );
174  REQUIRES( count >= 0 && count <= stackPos );
175 
176  for( iterationCount = 0; \
177  count > 0 && iterationCount < ATTRIBUTE_STACKSIZE; \
178  count--, iterationCount++ )
179  {
180  ATTRIBUTE_LIST *attributeFifoPtr;
181  const ATTRIBUTE_INFO *attributeInfoPtr;
182  int size;
183 
184  ENSURES( count > 0 && count <= currentStackPos );
185 
186  /* Unstack the current entry */
187  currentStackPos--;
188  ENSURES( currentStackPos >= 0 && \
189  currentStackPos < ATTRIBUTE_STACKSIZE );
190  attributeFifoPtr = stack[ currentStackPos ].attributeListPtr;
191  attributeInfoPtr = stack[ currentStackPos ].attributeInfoPtr;
192  size = stack[ currentStackPos ].size;
193  ENSURES( size >= 0 && size < MAX_INTLENGTH );
194  assert( isReadPtr( attributeInfoPtr, sizeof( ATTRIBUTE_INFO ) ) );
195 
196  /* If there's nothing to encode, continue. There are a few special
197  cases here where even if the sequence is of zero length we may
198  have to encode something. Firstly, if there's a member with a
199  default value present (resulting in nothing being encoded) we
200  still have to encode a zero-length sequence. In addition if all
201  of the members have non-encoding values (e.g. OIDs and fixed
202  attributes, none of which are specified by the user) then we have
203  to encode these even though there's no actual value associated
204  with them since their mere presence conveys the necessary
205  information.
206 
207  In addition sometimes we can reach the end of the attribute list
208  but there are further actions defined in the encoding table (for
209  example cleanup actions in nested sequences). In this case the
210  stacked attributeFifoPtr is NULL and the size is zero so we
211  perform an additional check to make sure that the pointer is
212  non-null */
213  if( attributeFifoPtr == NULL )
214  {
215  ENSURES( size == 0 );
216  continue;
217  }
218  if( size <= 0 && \
219  !( ( attributeFifoPtr->flags & ATTR_FLAG_DEFAULTVALUE ) || \
220  ( attributeInfoPtr->encodingFlags & FL_NONENCODING ) ) )
221  continue;
222 
223  /* Remember the size and table entry used to encode this stack
224  entry */
225  attributeFifoPtr->sizeFifo[ attributeFifoPtr->fifoEnd ] = size;
226  attributeFifoPtr->encodingFifo[ attributeFifoPtr->fifoEnd++ ] = \
227  stack[ currentStackPos ].attributeInfoPtr;
228 
229  ENSURES( attributeFifoPtr->fifoEnd > 0 && \
230  attributeFifoPtr->fifoEnd < ENCODING_FIFO_SIZE );
231 
232  /* If there are no further items on the stack, continue */
233  if( currentStackPos <= 0 )
234  continue;
235 
236  ENSURES( currentStackPos > 0 && \
237  currentStackPos < ATTRIBUTE_STACKSIZE );
238 
239  /* If it's a non-constructed field, add the length of the existing and
240  new fields */
241  if( attributeInfoPtr->fieldType != BER_SEQUENCE && \
242  attributeInfoPtr->fieldType != BER_SET )
243  {
244  int newLength;
245 
246  /* Calculate the size of the encoded field data. A sequence of
247  identifier fields has a final catch-all entry without an OID
248  which is only used for decoding, we should never see this
249  when encoding but we make the check explicit just in case */
250  if( attributeInfoPtr->fieldType == FIELDTYPE_IDENTIFIER )
251  {
252  ENSURES( attributeInfoPtr->oid );
253  newLength = sizeofOID( attributeInfoPtr->oid );
254  }
255  else
256  newLength = ( int ) attributeInfoPtr->defaultValue;
257 
258  /* Add the new length to the existing data size. Since this is a
259  non-constructed field it doesn't count as a reduction in the
260  nesting level so if we're unnesting by a relative amount we
261  adjust the nesting count to give a net change of zero for this
262  item */
263  stack[ currentStackPos - 1 ].size += size + newLength;
264  if( isRelative )
265  count++;
266  }
267  else
268  {
269  /* It's a constructed field, percolate the encapsulated content
270  size up the stack */
271  stack[ currentStackPos - 1 ].size += ( int ) sizeofObject( size );
272  }
273  }
274  ENSURES( iterationCount < ATTRIBUTE_STACKSIZE );
275 
276  *newStackPosPtr = currentStackPos;
277 
278  return( CRYPT_OK );
279  }
280 
281 /* Some attributes contain a sequence of items of the attributeTypeAndValue
282  form (i.e. OID, ANY DEFINED BY OID). To process these we check whether
283  the named value component in the attribute list is present in the current
284  attributeTypeAndValue definition. If it isn't the item is given a zero
285  length, which means that it's never encoded since the field is marked as
286  optional. The following function checks whether a named value component
287  is present in the item */
288 
290 static int checkComponentPresent( IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE fieldID,
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( attributeInfoPtr->fieldID != CRYPT_ERROR );
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 ) ) \
388 static int stackInfo( INOUT ATTRIBUTE_CHECK_INFO *attributeCheckInfo,
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 
411 static int checkAttribute( INOUT ATTRIBUTE_CHECK_INFO *attributeCheckInfo );
412  /* Forward declaration for function */
413 
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;
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,
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 
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( attributeCheckInfo->attributeInfoPtr->fieldID != CRYPT_ERROR );
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 ) ) \
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;
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  /* Get the attribute encoding information. We can't use the size value
800  returned from this because of the nested-loop structure below which
801  only ever iterates through a subset of the encoding information so we
802  leave it as a dummy value */
803  status = getAttributeInfo( attributeType, &attributeInfoStartPtr,
804  &dummy );
805  ENSURES( cryptStatusOK( status ) );
806 
807  /* If we've already done a validation pass some of the fields will
808  contain values that were previously set so before we begin we walk
809  down the list resetting the fields that are updated by this
810  function */
811  for( attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr, \
812  iterationCount = 0;
813  attributeListPtr != NULL && \
814  isValidAttributeField( attributeListPtr ) && \
815  iterationCount < FAILSAFE_ITERATIONS_LARGE;
816  attributeListPtr = attributeListPtr->next, iterationCount++ )
817  {
818  if( attributeListPtr->next != NULL && \
819  isValidAttributeField( attributeListPtr->next ) && \
820  attributeListPtr->attributeID > \
821  attributeListPtr->next->attributeID )
822  {
823  /* Safety check in case of an invalid attribute list */
824  retIntError();
825  }
826  attributeListPtr->attributeInfoPtr = NULL;
827  attributeListPtr->encodedSize = attributeListPtr->fifoPos = \
828  attributeListPtr->fifoEnd = 0;
829  attributeListPtr->flags &= ~ATTR_FLAG_DEFAULTVALUE;
830  }
831  ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
832 
833  /* Set up the attribute-checking state information */
834  memset( &attributeCheckInfo, 0, sizeof( ATTRIBUTE_CHECK_INFO ) );
835  attributeCheckInfo.attributeListPtr = ( ATTRIBUTE_LIST * ) listHeadPtr;
836  attributeCheckInfo.attributeInfoPtr = attributeInfoStartPtr;
837 
838  /* Walk down the list of known attributes checking each one for
839  consistency */
840  for( iterationCount = 0;
841  attributeCheckInfo.attributeListPtr != NULL && \
842  attributeCheckInfo.attributeListPtr->fieldID != CRYPT_ATTRIBUTE_NONE && \
843  iterationCount < FAILSAFE_ITERATIONS_LARGE;
844  iterationCount++ )
845  {
846  int innerIterationCount;
847 
848  /* Find the start of this attribute in the attribute information
849  table and remember it as an encoding synchronisation point.
850  Comparing the field ID with the attribute ID is usually valid
851  because the attribute information table always begins the series
852  of entries for an attribute with the attribute ID. The one
853  exception is where the attribute ID is the same as the field ID
854  but they're separate entries in the table, in which case the
855  first entries will contain a FIELDID_FOLLOWS code to indicate
856  that the following field contains the attribute/fieldID */
857  for( innerIterationCount = 0;
858  attributeCheckInfo.attributeInfoPtr->fieldID != CRYPT_ERROR && \
859  innerIterationCount < FAILSAFE_ITERATIONS_LARGE;
860  attributeCheckInfo.attributeInfoPtr++, innerIterationCount++ )
861  {
862  if( attributeCheckInfo.attributeInfoPtr->fieldID == FIELDID_FOLLOWS )
863  {
864  if( attributeCheckInfo.attributeInfoPtr[ 1 ].fieldID == \
865  attributeCheckInfo.attributeListPtr->attributeID )
866  break;
867  }
868  else
869  {
870  if( attributeCheckInfo.attributeInfoPtr->fieldID == \
871  attributeCheckInfo.attributeListPtr->attributeID )
872  break;
873  }
874  }
875  ENSURES( innerIterationCount < FAILSAFE_ITERATIONS_LARGE );
876  ENSURES( attributeCheckInfo.attributeInfoPtr->fieldID != CRYPT_ERROR );
877 
878  /* Check this attribute */
879  status = checkAttribute( &attributeCheckInfo );
880  if( cryptStatusError( status ) )
881  {
882  *errorLocus = attributeCheckInfo.errorLocus;
883  *errorType = attributeCheckInfo.errorType;
884  return( status );
885  }
886  }
887  ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
888 
889  return( CRYPT_OK );
890  }
891 #endif /* USE_CERTIFICATES */