cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ext_def.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Certificate Attribute Definitions *
4 * Copyright Peter Gutmann 1996-2010 *
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 /* The following certificate extensions are currently supported. If
21  'Enforced' is set to 'Yes' then they're constraint extensions that are
22  enforced by the certificate checking code; if set to '-' then they're
23  informational extensions for which enforcement doesn't apply; if set to
24  'No' they need to be handled by the user (this only applies for
25  certificate policies for which the user has to decide whether a given
26  policy is acceptable or not). The Yes/No in policyConstraints means
27  that everything except the policy mapping constraint is enforced
28  (because policyMappings itself isn't enforced). The 'level' value
29  indicates the compliance level at which the extension is decoded and
30  enforced. The 'conditions' value indicates any further conditions under
31  which the extension may be applied or skipped. PKIX = 'Full' overrides
32  Conditions = 'Obscure', so that setting PKIX compliance to Full enables
33  handling of all PKIX/X.509 extensions no matter how obscure and strange
34  they are.
35 
36  Enforced Level Conditions
37  -------- ----- ----------
38  aaIssuingDistributionPoint - Full Rev
39  additionalInformation (SigG) - Partial Obscure
40  admissions (SigG) - Partial Obscure
41  authorityInfoAccess - - -
42  authorityKeyIdentifier - Partial -
43  autonomousSysIds (RPKI) - - -
44  basicConstraints Yes - -
45  biometricInfo (QualifiedCert) - Full -
46  certCardRequired (SET) - Partial Obsolete
47  certHash (SigG, OCSP) - Partial Obscure, Rev
48  certificateIssuer - Full Rev
49  certificatePolicies Yes - -
50  certificateType (SET) - Partial Obsolete
51  challengePassword (SCEP) - - Req
52  cRLDistributionPoints - - -
53  cRLNumber - Partial Rev
54  cRLReason - - Rev | Req
55  cRLExtReason - - Rev
56  crlStreamIdentifier - Full Rev
57  dateOfCertGen (SigG) - Partial Obscure
58  declarationOfMajority (SigG) - Partial Obscure
59  deltaCRLIndicator - Partial Rev
60  deltaInfo - Full Rev
61  expiredCertsOnCRL - Full Rev
62  extKeyUsage Yes - -
63  freshestCRL - Full Rev
64  hashedRootKey (SET) - Partial Obsolete
65  holdInstructionCode - Partial Rev | Req
66  inhibitAnyPolicy Yes Full -
67  invalidityDate - - Rev | Req
68  ipAddrBlocks (RPKI) - - -
69  issuerAltName - - -
70  issuingDistributionPoint - Partial Rev
71  keyFeatures - - -
72  keyUsage Yes - -
73  monetaryLimit (SigG) - Partial Obscure
74  nameConstraints Yes Full -
75  netscape-cert-type Yes - Obsolete
76  netscape-base-url - - Obsolete
77  netscape-revocation-url - - Obsolete
78  netscape-ca-revocation-url - - Obsolete
79  netscape-cert-renewal-url - - Obsolete
80  netscape-ca-policy-url - - Obsolete
81  netscape-ssl-server-name - - Obsolete
82  netscape-comment - - Obsolete
83  merchantData (SET) - Partial Obsolete
84  ocspAcceptableResponse (OCSP) - Partial Rev
85  ocspArchiveCutoff (OCSP) - Partial Rev
86  ocspNoCheck (OCSP) - Partial Rev
87  ocspNonce (OCSP) - - Rev
88  orderedList - Full Rev
89  policyConstraints Yes/No Full -
90  policyMappings No Full -
91  privateKeyUsagePeriod Yes Partial -
92  procuration (SigG) - Partial Obscure
93  qcStatements (QualifiedCert) - Full -
94  restriction (SigG) - Partial Obscure
95  revokedGroups - Full Rev
96  [ signingCertificate - - Rev ]
97  strongExtranet (Thawte) - Partial Obsolete
98  subjectAltName - - -
99  subjectDirectoryAttributes - Partial -
100  subjectInfoAccess - - -
101  subjectKeyIdentifier - - -
102  toBeRevoked - Full Rev
103  tunneling (SET) - Partial Obsolete
104 
105  Of these extensions, only a very small number are permitted in certificate
106  requests for security reasons, see the code comment for
107  sanitiseCertAttributes() in comp_set.c before changing any of these
108  values.
109 
110  Since some extensions fields are tagged the fields as encoded differ from
111  the fields as defined by the tagging, the following macro is used to turn
112  a small integer into a context-specific tag. By default the tag is
113  implicit as per X.509v3, to make it an explicit tag we need to set the
114  FL_EXPLICIT flag for the field */
115 
116 #define CTAG( x ) ( x | BER_CONTEXT_SPECIFIC )
117 
118 /* Symbolic defines to make the encoded forms more legible */
119 
120 #define ENCODING( tag ) BER_##tag, CRYPT_UNUSED
121 #define ENCODING_SPECIAL( value ) \
122  FIELDTYPE_##value, CRYPT_UNUSED
123 #define ENCODING_ALIAS( tag, aliasTag ) \
124  BER_##tag, aliasTag
125 #define ENCODING_TAGGED( tag, outerTag ) \
126  BER_##tag, outerTag
127 #define ENCODING_SPECIAL_TAGGED( tag, outerTag ) \
128  FIELDTYPE_##tag, outerTag
129 #define RANGE( min, max ) min, max, 0, NULL
130 #define RANGE_ATTRIBUTEBLOB 1, MAX_ATTRIBUTE_SIZE, 0, NULL
131 #define RANGE_BLOB 32, MAX_ATTRIBUTE_SIZE, 0, NULL
132 #define RANGE_BOOLEAN FALSE, TRUE, FALSE, NULL
133 #define RANGE_NONE 0, 0, 0, NULL
134 #define RANGE_OID MIN_OID_SIZE, MAX_OID_SIZE, 0, NULL
135 #define RANGE_TEXTSTRING 1, CRYPT_MAX_TEXTSIZE, 0, NULL
136 #define RANGE_TIME sizeof( time_t ), sizeof( time_t ), 0, NULL
137 #define RANGE_UNUSED CRYPT_UNUSED, CRYPT_UNUSED, 0, NULL
138 #define ENCODED_OBJECT( altEncodingTable ) \
139  0, 0, 0, ( void * ) altEncodingTable
140 #define CHECK_DNS MIN_DNS_SIZE, MAX_DNS_SIZE, 0, ( void * ) checkDNS
141 #define CHECK_HTTP MIN_URL_SIZE, MAX_URL_SIZE, 0, ( void * ) checkHTTP
142 #define CHECK_RFC822 MIN_RFC822_SIZE, MAX_RFC822_SIZE, 0, ( void * ) checkRFC822
143 #define CHECK_URL MIN_URL_SIZE, MAX_URL_SIZE, 0, ( void * ) checkURL
144 #define CHECK_X500 0, 0, 0, ( void * ) checkDirectoryName
145 
146 /* Symbolic defines for attribute type information */
147 
148 #define ATTR_TYPEINFO( type, level ) \
149  ( FL_LEVEL_##level | FL_VALID_##type | \
150  FL_ATTR_ATTRSTART )
151 #define ATTR_TYPEINFO2( type1, type2, level ) \
152  ( FL_LEVEL_##level | FL_VALID_##type1 | \
153  FL_VALID_##type2 | FL_ATTR_ATTRSTART )
154 #define ATTR_TYPEINFO3( type1, type2, type3, level ) \
155  ( FL_LEVEL_##level | FL_VALID_##type1 | \
156  FL_VALID_##type2 | FL_VALID_##type3 | \
157  FL_ATTR_ATTRSTART )
158 #define ATTR_TYPEINFO_CRITICAL( type, level ) \
159  ( FL_LEVEL_##level | FL_VALID_##type | \
160  FL_ATTR_CRITICAL | FL_ATTR_ATTRSTART )
161 #define ATTR_TYPEINFO2_CRITICAL( type1, type2, level ) \
162  ( FL_LEVEL_##level | FL_VALID_##type1 | \
163  FL_VALID_##type2 | FL_ATTR_CRITICAL | \
164  FL_ATTR_ATTRSTART )
165 #define ATTR_TYPEINFO3_CRITICAL( type1, type2, type3, level ) \
166  ( FL_LEVEL_##level | FL_VALID_##type1 | \
167  FL_VALID_##type2 | FL_VALID_##type3 | \
168  FL_ATTR_CRITICAL | FL_ATTR_ATTRSTART )
169 #define ATTR_TYPEINFO_CMS ( FL_ATTR_ATTRSTART )
170 
171 /* Extended checking functions */
172 
173 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
174 static int checkRFC822( const ATTRIBUTE_LIST *attributeListPtr );
175 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
176 static int checkDNS( const ATTRIBUTE_LIST *attributeListPtr );
177 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
178 static int checkURL( const ATTRIBUTE_LIST *attributeListPtr );
179 #ifdef USE_CERT_OBSOLETE
180 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
181 static int checkHTTP( const ATTRIBUTE_LIST *attributeListPtr );
182 #endif /* USE_CERT_OBSOLETE */
183 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
184 static int checkDirectoryName( const ATTRIBUTE_LIST *attributeListPtr );
185 
186 /* Forward declarations for alternative encoding tables used by the main
187  tables. These are declared in a somewhat peculiar manner because there's
188  no clean way in C to forward declare a static array. Under VC++ with the
189  highest warning level enabled this produces a compiler warning, so we
190  turn the warning off for this module. In addition there the usual
191  problems that crop up with gcc 4.x */
192 
193 #if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
194  static const ATTRIBUTE_INFO FAR_BSS generalNameInfo[];
195  static const ATTRIBUTE_INFO FAR_BSS holdInstructionInfo[];
196  static const ATTRIBUTE_INFO FAR_BSS contentTypeInfo[];
197 #else
198  extern const ATTRIBUTE_INFO FAR_BSS generalNameInfo[];
199  extern const ATTRIBUTE_INFO FAR_BSS holdInstructionInfo[];
200  extern const ATTRIBUTE_INFO FAR_BSS contentTypeInfo[];
201 #endif /* gcc 4.x */
202 
203 #if defined( _MSC_VER )
204  #pragma warning( disable: 4211 )
205 #endif /* VC++ */
206 
207 #ifdef USE_CERTIFICATES
208 
209 /****************************************************************************
210 * *
211 * Certificate Extension Definitions *
212 * *
213 ****************************************************************************/
214 
215 /* Certificate extensions are encoded using the following table */
216 
217 static const ATTRIBUTE_INFO FAR_BSS extensionInfo[] = {
218 #ifdef USE_CERTREQ
219  /* challengePassword:
220 
221  OID = 1 2 840 113549 1 9 7
222  DirectoryString.
223 
224  This is here even though it's a CMS attribute because SCEP stuffs it
225  into PKCS #10 requests */
226  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x07" ), CRYPT_CERTINFO_CHALLENGEPASSWORD,
227  DESCRIPTION( "challengePassword" )
228  ENCODING_SPECIAL( TEXTSTRING ),
229  ATTR_TYPEINFO( CERTREQ, STANDARD ) | FL_ATTR_ATTREND | FL_ATTR_NOCOPY,
230  0, RANGE_TEXTSTRING },
231 #endif /* USE_CERTREQ */
232 
233 #if defined( USE_CERTREV )
234  /* signingCertificate:
235 
236  OID = 1 2 840 113549 1 9 16 2 12
237  SEQUENCE {
238  SEQUENCE OF ESSCertID {
239  certHash OCTET STRING
240  }, -- SIZE(1)
241  SEQUENCE OF { ... } OPTIONAL -- ABSENT
242  }
243 
244  This is here even though it's a CMS attribute because it's required
245  in order to make OCSP work (a second copy is present with the CMS
246  attributes, see the remainder of this comment below). Since OCSP
247  breaks up the certificate identification information into bits and
248  pieces and hashes some while leaving others intact, there's no way to
249  map what arrives at the responder back into a certificate without an
250  ability to reverse the cryptographic hash function. To work around
251  this we include an ESSCertID in the request that properly identifies
252  the certificate being queried. Since it's a limited-use version that
253  only identifies the certificate we don't allow a full
254  signingCertificate extension but only a single ESSCertID.
255 
256  Note that having this attribute here is somewhat odd in that type-
257  checking is done via the equivalent entry in the CMS attributes
258  because the fieldID identifies it as a CMS attribute but decoding is
259  done via this entry because the decoder loops through the certificate
260  attribute entries to find the decoding information. For this reason
261  if OCSP use is enabled then both this entry and the one in the CMS
262  attributes must be enabled */
263  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x0C" ), CRYPT_CERTINFO_CMS_SIGNINGCERTIFICATE,
264  DESCRIPTION( "signingCertificate" )
265  ENCODING( SEQUENCE ),
266  ATTR_TYPEINFO( OCSPREQ /*Per-entry*/, STANDARD ),
267  0, RANGE_NONE },
268  { NULL, 0,
269  DESCRIPTION( "signingCertificate.certs" )
270  ENCODING( SEQUENCE ),
271  0, 0, RANGE_NONE },
273  DESCRIPTION( "signingCertificate.certs.essCertID" )
274  ENCODING_SPECIAL( BLOB_SEQUENCE ),
275  FL_ATTR_ATTREND, FL_SEQEND_2 /*FL_SEQEND*/, RANGE_BLOB },
276 
277  /* cRLExtReason:
278 
279  OID = 1 3 6 1 4 1 3029 3 1 4
280  ENUMERATED */
281  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x03\x01\x04" ), CRYPT_CERTINFO_CRLEXTREASON,
282  DESCRIPTION( "cRLExtReason" )
283  ENCODING( ENUMERATED ),
284  ATTR_TYPEINFO2( REVREQ /*Per-entry*/, CRL, STANDARD ) | FL_ATTR_ATTREND,
285  0, RANGE( 0, CRYPT_CRLEXTREASON_LAST ) },
286 #endif /* USE_CERTREV */
287 
288  /* keyFeatures:
289 
290  OID = 1 3 6 1 4 1 3029 3 1 5
291  BITSTRING */
292  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x03\x01\x05" ), CRYPT_CERTINFO_KEYFEATURES,
293  DESCRIPTION( "keyFeatures" )
294  ENCODING( BITSTRING ),
295  ATTR_TYPEINFO2( CERT, CERTREQ, STANDARD ) | FL_ATTR_ATTREND,
296  0, RANGE( 0, 7 ) },
297 
298  /* authorityInfoAccess:
299 
300  OID = 1 3 6 1 5 5 7 1 1
301  SEQUENCE SIZE (1...MAX) OF {
302  SEQUENCE {
303  accessMethod OBJECT IDENTIFIER,
304  accessLocation GeneralName
305  }
306  } */
307  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x01" ), CRYPT_CERTINFO_AUTHORITYINFOACCESS,
308  DESCRIPTION( "authorityInfoAccess" )
309  ENCODING( SEQUENCE ),
310  ATTR_TYPEINFO( CERT, STANDARD ),
311  FL_SETOF, RANGE_NONE },
312  { NULL, 0,
313  DESCRIPTION( "authorityInfoAccess.accessDescription (rtcs)" )
314  ENCODING( SEQUENCE ),
316  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x97\x55\x03\x01\x07" ), 0,
317  DESCRIPTION( "authorityInfoAccess.rtcs (1 3 6 1 4 1 3029 3 1 7)" )
318  ENCODING_SPECIAL( IDENTIFIER ),
319  0, 0, RANGE_NONE },
321  DESCRIPTION( "authorityInfoAccess.accessDescription.accessLocation (rtcs)" )
322  ENCODING_SPECIAL( SUBTYPED ),
323  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
324  { NULL, 0,
325  DESCRIPTION( "authorityInfoAccess.accessDescription (ocsp)" )
326  ENCODING( SEQUENCE ),
328  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x01" ), 0,
329  DESCRIPTION( "authorityInfoAccess.ocsp (1 3 6 1 5 5 7 48 1)" )
330  ENCODING_SPECIAL( IDENTIFIER ),
331  0, 0, RANGE_NONE },
333  DESCRIPTION( "authorityInfoAccess.accessDescription.accessLocation (ocsp)" )
334  ENCODING_SPECIAL( SUBTYPED ),
335  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
336  { NULL, 0,
337  DESCRIPTION( "authorityInfoAccess.accessDescription (caIssuers)" )
338  ENCODING( SEQUENCE ),
340  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x02" ), 0,
341  DESCRIPTION( "authorityInfoAccess.caIssuers (1 3 6 1 5 5 7 48 2)" )
342  ENCODING_SPECIAL( IDENTIFIER ),
343  0, 0, RANGE_NONE },
345  DESCRIPTION( "authorityInfoAccess.accessDescription.accessLocation (caIssuers)" )
346  ENCODING_SPECIAL( SUBTYPED ),
347  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
348  { NULL, 0,
349  DESCRIPTION( "authorityInfoAccess.accessDescription (httpCerts)" )
350  ENCODING( SEQUENCE ),
352  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x06" ), 0,
353  DESCRIPTION( "authorityInfoAccess.httpCerts (1 3 6 1 5 5 7 48 6)" )
354  ENCODING_SPECIAL( IDENTIFIER ),
355  0, 0, RANGE_NONE },
357  DESCRIPTION( "authorityInfoAccess.accessDescription.accessLocation (httpCerts)" )
358  ENCODING_SPECIAL( SUBTYPED ),
359  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
360  { NULL, 0,
361  DESCRIPTION( "authorityInfoAccess.accessDescription (httpCRLs)" )
362  ENCODING( SEQUENCE ),
364  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x07" ), 0,
365  DESCRIPTION( "authorityInfoAccess.httpCRLs (1 3 6 1 5 5 7 48 7)" )
366  ENCODING_SPECIAL( IDENTIFIER ),
367  0, 0, RANGE_NONE },
369  DESCRIPTION( "authorityInfoAccess.accessDescription.accessLocation (httpCRLs)" )
370  ENCODING_SPECIAL( SUBTYPED ),
371  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
372  { NULL, 0,
373  DESCRIPTION( "authorityInfoAccess.accessDescription (catchAll)" )
374  ENCODING( SEQUENCE ),
376  { NULL, 0,
377  DESCRIPTION( "authorityInfoAccess.catchAll" )
378  ENCODING_SPECIAL( BLOB_ANY ), /* Match anything and ignore it */
380 
381 #ifdef USE_CERTLEVEL_PKIX_FULL
382  /* biometricInfo (QualifiedCert):
383 
384  OID = 1 3 6 1 5 5 7 1 2
385  SEQUENCE OF {
386  SEQUENCE {
387  typeOfData INTEGER,
388  hashAlgorithm OBJECT IDENTIFIER,
389  dataHash OCTET STRING,
390  sourceDataUri IA5String OPTIONAL
391  }
392  } */
393  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x02" ), CRYPT_CERTINFO_BIOMETRICINFO,
394  DESCRIPTION( "biometricInfo" )
395  ENCODING( SEQUENCE ),
396  ATTR_TYPEINFO( CERT, PKIX_FULL ),
397  FL_SETOF, RANGE_NONE },
398  { NULL, 0,
399  DESCRIPTION( "biometricInfo.biometricData" )
400  ENCODING( SEQUENCE ),
401  0, 0, RANGE_NONE },
403  DESCRIPTION( "biometricInfo.biometricData.typeOfData" )
404  ENCODING( INTEGER ),
405  0, FL_MULTIVALUED, RANGE( 0, 1 ) },
407  DESCRIPTION( "biometricInfo.biometricData.hashAlgorithm" )
408  ENCODING( OBJECT_IDENTIFIER ),
411  DESCRIPTION( "biometricInfo.biometricData.dataHash" )
415  DESCRIPTION( "biometricInfo.biometricData.sourceDataUri" )
416  ENCODING( STRING_IA5 ),
418 
419  /* qcStatements (QualifiedCert):
420 
421  OID = 1 3 6 1 5 5 7 1 3
422  critical = TRUE
423  SEQUENCE OF {
424  SEQUENCE {
425  statementID OBJECT IDENTIFIER,
426  statementInfo SEQUENCE {
427  semanticsIdentifier OBJECT IDENTIFIER OPTIONAL,
428  nameRegistrationAuthorities SEQUENCE OF GeneralName
429  }
430  }
431 
432  There are two versions of the statementID OID, one for RFC 3039 and
433  the other for RFC 3739 (which are actually identical except where
434  they're not). To handle this we preferentially encode the RFC 3739
435  (v2) OID but allow the v1 OID as a fallback by marking both as
436  optional */
437  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x03" ), CRYPT_CERTINFO_QCSTATEMENT,
438  DESCRIPTION( "qcStatements" )
439  ENCODING( SEQUENCE ),
440  ATTR_TYPEINFO_CRITICAL( CERT, PKIX_FULL ),
441  FL_SETOF, RANGE_NONE },
442  { NULL, 0,
443  DESCRIPTION( "qcStatements.qcStatement (statementID)" )
444  ENCODING( SEQUENCE ),
446  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x0B\x02" ), 0,
447  DESCRIPTION( "qcStatements.qcStatement.statementID (1 3 6 1 5 5 7 11 2)" )
448  ENCODING_SPECIAL( IDENTIFIER ),
449  0, FL_OPTIONAL, RANGE_NONE },
450  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x0B\x01" ), 0,
451  DESCRIPTION( "qcStatements.qcStatement.statementID (Backwards-compat.) (1 3 6 1 5 5 7 11 1)" )
452  ENCODING_SPECIAL( IDENTIFIER ),
453  0, FL_OPTIONAL, RANGE_NONE },
454  { NULL, 0,
455  DESCRIPTION( "qcStatements.qcStatement.statementInfo (statementID)" )
456  ENCODING( SEQUENCE ),
457  0, 0, RANGE_NONE },
459  DESCRIPTION( "qcStatements.qcStatement.statementInfo.semanticsIdentifier (statementID)" )
460  ENCODING( OBJECT_IDENTIFIER ),
462  { NULL, 0,
463  DESCRIPTION( "qcStatements.qcStatement.statementInfo.nameRegistrationAuthorities (statementID)" )
464  ENCODING( SEQUENCE ),
465  0, FL_SETOF, RANGE_NONE },
467  DESCRIPTION( "qcStatements.qcStatement.statementInfo.nameRegistrationAuthorities.generalNames" )
468  ENCODING_SPECIAL( SUBTYPED ),
469  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_SEQEND_3 /* Really _4*/, ENCODED_OBJECT( generalNameInfo ) },
470 #endif /* USE_CERTLEVEL_PKIX_FULL */
471 
472  /* ipAddrBlocks (RPKI):
473 
474  OID = 1 3 6 1 5 5 7 1 7
475  critical = TRUE
476  SEQUENCE OF {
477  SEQUENCE {
478  addressFamily OCTET STRING (SIZE(2)),
479  addressesOrRanges SEQUENCE OF {
480  CHOICE {
481  addressPrefix
482  BITSTRING, -- Treated as blob, see below
483  addressRange SEQUENCE {
484  min BITSTRING, -- Treated as blob, see below
485  max BITSTRING -- Treated as blob, see below
486  }
487  }
488  }
489  }
490  }
491 
492  The length range for the BIT STRING is 3 bytes (zero-length string
493  for all IP address blocks) up to 19 bytes (16-byte IPv6 address plus
494  3-byte BIT STRING header) */
495  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x07" ), CRYPT_CERTINFO_IPADDRESSBLOCKS,
496  DESCRIPTION( "ipAddrBlocks" )
497  ENCODING( SEQUENCE ),
498  ATTR_TYPEINFO( CERT, STANDARD ),
499  FL_SETOF, RANGE_NONE },
500  { NULL, 0,
501  DESCRIPTION( "ipAddrBlocks.ipAddressFamily" )
502  ENCODING( SEQUENCE ),
503  0, 0, RANGE_NONE },
505  DESCRIPTION( "ipAddrBlocks.ipAddressFamily.addressFamily" )
507  0, FL_MULTIVALUED, RANGE( 2, 2 ) },
508  { NULL, 0,
509  DESCRIPTION( "ipAddrBlocks.ipAddressFamily.addressesOrRanges" )
510  ENCODING( SEQUENCE ),
511  0, FL_SETOF, RANGE_NONE },
513  DESCRIPTION( "ipAddrBlocks.ipAddressFamily.addressesOrRanges.addressPrefix" )
514  ENCODING_SPECIAL( BLOB_BITSTRING ),
515  0, FL_MULTIVALUED | FL_OPTIONAL, 3, 19 },
516  { NULL, 0,
517  DESCRIPTION( "ipAddrBlocks.ipAddressFamily.addressesOrRanges.addressRange" )
518  ENCODING( SEQUENCE ),
519  0, FL_OPTIONAL, RANGE_NONE },
521  DESCRIPTION( "ipAddrBlocks.ipAddressFamily.addressesOrRanges.addressRange.min" )
522  ENCODING_SPECIAL( BLOB_BITSTRING ),
523  0, FL_MULTIVALUED, 3, 19 },
525  DESCRIPTION( "ipAddrBlocks.ipAddressFamily.addressesOrRanges.addressRange.max" )
526  ENCODING_SPECIAL( BLOB_BITSTRING ),
528 
529  /* autonomousSysIds (RPKI):
530 
531  OID = 1 3 6 1 5 5 7 1 8
532  critical = TRUE
533  SEQUENCE {
534  [ 0 ] EXPLICIT SEQUENCE OF {
535  CHOICE {
536  asId INTEGER,
537  asRange SEQUENCE {
538  min INTEGER,
539  max INTEGER
540  }
541  }
542  }
543  }
544 
545  The AS ranges are a bit difficult to provide sensible restrictions
546  for, traditionally they were 16-bit numbers but then RFC 4893
547  extended them to 32-bits, of which subranges up to about 400K have
548  been allocated (with wierd huge gaps in between the small set of
549  subranges in use), see http://www.iana.org/assignments/as-numbers/
550  for current assignments. We set a limit of 500K to allow some
551  sanity-checking while also allowing room for future expansion */
552  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x08" ), CRYPT_CERTINFO_AUTONOMOUSSYSIDS,
553  DESCRIPTION( "autonomousSysIds" )
554  ENCODING( SEQUENCE ),
555  ATTR_TYPEINFO( CERT, STANDARD ),
556  0, RANGE_NONE },
557  { NULL, 0,
558  DESCRIPTION( "autonomousSysIds.asnum" )
562  DESCRIPTION( "autonomousSysIds.asnum.asIdsOrRanges.asId" )
563  ENCODING( INTEGER ),
564  0, FL_MULTIVALUED | FL_OPTIONAL, 1, 500000 },
565  { NULL, 0,
566  DESCRIPTION( "autonomousSysIds.asnum.asIdsOrRanges.asRange" )
567  ENCODING( SEQUENCE ),
568  0, FL_OPTIONAL, RANGE_NONE },
570  DESCRIPTION( "autonomousSysIds.asnum.asIdsOrRanges.asRange.min" )
571  ENCODING( INTEGER ),
572  0, FL_MULTIVALUED, 1, 500000 },
574  DESCRIPTION( "autonomousSysIds.asnum.asIdsOrRanges.asRange.max" )
575  ENCODING( INTEGER ),
577 
578 #ifdef USE_CERTREV
579  /* ocspNonce:
580 
581  OID = 1 3 6 1 5 5 7 48 1 2
582  nonce OCTET STRING
583 
584  This value was apparently supposed to be an OCTET STRING (although it
585  may also have been a cargo-cult design version of TSP's INTEGER),
586  however while specifying a million pieces of uneecessary braindamage
587  OCSP forgot to actually define this anywhere in the spec. Because of
588  this it's possible to get other stuff here as well, the worst-case
589  being OpenSSL 0.9.6/0.9.7a-c which just dumps a raw blob (not even
590  valid ASN.1 data) in here. We can't do anything with this since we
591  need at least something DER-encoded to be able to read it. OpenSSL
592  0.9.7d and later used an OCTET STRING.
593 
594  We set the en/decoding level to FL_LEVEL_OBLIVIOUS to make sure that
595  it's still encoded even in oblivious mode, if we don't do this then a
596  nonce in a request won't be returned in the response if the user is
597  running at a reduced compliance level */
598  { MKOID( "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x02" ), CRYPT_CERTINFO_OCSP_NONCE,
599  DESCRIPTION( "ocspNonce" )
601  ATTR_TYPEINFO2( OCSPREQ, OCSPRESP, OBLIVIOUS ) | FL_ATTR_ATTREND,
602  0, RANGE( 1, 64 ) },
603 
604 #ifdef USE_CERTLEVEL_PKIX_PARTIAL
605  /* ocspAcceptableResponses:
606 
607  OID = 1 3 6 1 5 5 7 48 1 4
608  SEQUENCE {
609  oidInstance1 OPTIONAL,
610  oidInstance2 OPTIONAL,
611  ...
612  oidInstanceN OPTIONAL
613  } */
614  { MKOID( "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x04" ), CRYPT_CERTINFO_OCSP_RESPONSE,
615  DESCRIPTION( "ocspAcceptableResponses" )
616  ENCODING( SEQUENCE ),
617  ATTR_TYPEINFO( OCSPREQ, PKIX_PARTIAL ),
618  0, RANGE_NONE },
619  { MKOID( "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x01" ), CRYPT_CERTINFO_OCSP_RESPONSE_OCSP,
620  DESCRIPTION( "ocspAcceptableResponses.ocsp (1 3 6 1 5 5 7 48 1 1)" )
621  ENCODING_SPECIAL( IDENTIFIER ),
623 
624  /* ocspNoCheck:
625 
626  OID = 1 3 6 1 5 5 7 48 1 5
627  critical = FALSE
628  NULL
629 
630  ocspNoCheck is a certificate extension rather than an OCSP request
631  extension, it's used by the CA in yet another of OCSP's schizophrenic
632  trust models to indicate that an OCSP responder certificate shouldn't
633  be checked until it expires naturally. The value is treated as a
634  pseudo-numeric value that must be CRYPT_UNUSED when written and is
635  explicitly set to CRYPT_UNUSED when read */
636  { MKOID( "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x05" ), CRYPT_CERTINFO_OCSP_NOCHECK,
637  DESCRIPTION( "ocspNoCheck" )
638  ENCODING( NULL ),
639  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
641 
642  /* ocspArchiveCutoff:
643 
644  OID = 1 3 6 1 5 5 7 48 1 6
645  archiveCutoff GeneralizedTime */
646  { MKOID( "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x06" ), CRYPT_CERTINFO_OCSP_ARCHIVECUTOFF,
647  DESCRIPTION( "ocspArchiveCutoff" )
648  ENCODING( TIME_GENERALIZED ),
649  ATTR_TYPEINFO( OCSPRESP, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
650  0, RANGE_TIME },
651 #endif /* USE_CERTLEVEL_PKIX_PARTIAL */
652 #endif /* USE_CERTREV */
653 
654  /* subjectInfoAccess:
655 
656  OID = 1 3 6 1 5 5 7 1 11
657  SEQUENCE SIZE (1...MAX) OF {
658  SEQUENCE {
659  accessMethod OBJECT IDENTIFIER,
660  accessLocation GeneralName
661  }
662  } */
663  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x0B" ), CRYPT_CERTINFO_SUBJECTINFOACCESS,
664  DESCRIPTION( "subjectInfoAccess" )
665  ENCODING( SEQUENCE ),
666  ATTR_TYPEINFO( CERT, STANDARD ),
667  FL_SETOF, RANGE_NONE },
668  { NULL, 0,
669  DESCRIPTION( "subjectInfoAccess.accessDescription (timeStamping)" )
670  ENCODING( SEQUENCE ),
672  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x03" ), 0,
673  DESCRIPTION( "subjectInfoAccess.timeStamping (1 3 6 1 5 5 7 48 3)" )
674  ENCODING_SPECIAL( IDENTIFIER ),
675  0, 0, RANGE_NONE },
677  DESCRIPTION( "subjectInfoAccess.accessDescription.accessLocation (timeStamping)" )
678  ENCODING_SPECIAL( SUBTYPED ),
679  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
680  { NULL, 0,
681  DESCRIPTION( "subjectInfoAccess.accessDescription (caRepository)" )
682  ENCODING( SEQUENCE ),
684  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x05" ), 0,
685  DESCRIPTION( "subjectInfoAccess.caRepository (1 3 6 1 5 5 7 48 5)" )
686  ENCODING_SPECIAL( IDENTIFIER ),
687  0, 0, RANGE_NONE },
689  DESCRIPTION( "subjectInfoAccess.accessDescription.accessLocation (caRepository)" )
690  ENCODING_SPECIAL( SUBTYPED ),
691  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
692  { NULL, 0,
693  DESCRIPTION( "subjectInfoAccess.accessDescription (signedObjectRepository)" )
694  ENCODING( SEQUENCE ),
696  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x09" ), 0,
697  DESCRIPTION( "subjectInfoAccess.signedObjectRepository (1 3 6 1 5 5 7 48 9)" )
698  ENCODING_SPECIAL( IDENTIFIER ),
699  0, 0, RANGE_NONE },
701  DESCRIPTION( "subjectInfoAccess.accessDescription.accessLocation (signedObjectRepository)" )
702  ENCODING_SPECIAL( SUBTYPED ),
703  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
704  { NULL, 0,
705  DESCRIPTION( "subjectInfoAccess.accessDescription (rpkiManifest)" )
706  ENCODING( SEQUENCE ),
708  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x0A" ), 0,
709  DESCRIPTION( "subjectInfoAccess.rpkiManifest (1 3 6 1 5 5 7 48 10)" )
710  ENCODING_SPECIAL( IDENTIFIER ),
711  0, 0, RANGE_NONE },
713  DESCRIPTION( "subjectInfoAccess.accessDescription.accessLocation (rpkiManifest)" )
714  ENCODING_SPECIAL( SUBTYPED ),
715  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
716  { NULL, 0,
717  DESCRIPTION( "subjectInfoAccess.accessDescription (signedObject)" )
718  ENCODING( SEQUENCE ),
720  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x0B" ), 0,
721  DESCRIPTION( "subjectInfoAccess.signedObject (1 3 6 1 5 5 7 48 11)" )
722  ENCODING_SPECIAL( IDENTIFIER ),
723  0, 0, RANGE_NONE },
725  DESCRIPTION( "subjectInfoAccess.accessDescription.accessLocation (signedObject)" )
726  ENCODING_SPECIAL( SUBTYPED ),
727  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
728  { NULL, 0,
729  DESCRIPTION( "subjectInfoAccess.accessDescription (catchAll)" )
730  ENCODING( SEQUENCE ),
732  { NULL, 0,
733  DESCRIPTION( "subjectInfoAccess.catchAll" )
734  ENCODING_SPECIAL( BLOB_ANY ), /* Match anything and ignore it */
736 
737 #if defined( USE_CERT_OBSCURE ) && defined( USE_CERTLEVEL_PKIX_PARTIAL )
738  /* dateOfCertGen (SigG)
739 
740  OID = 1 3 36 8 3 1
741  dateOfCertGen GeneralizedTime */
742  { MKOID( "\x06\x05\x2B\x24\x08\x03\x01" ), CRYPT_CERTINFO_SIGG_DATEOFCERTGEN,
743  DESCRIPTION( "dateOfCertGen" )
744  ENCODING( TIME_GENERALIZED ),
745  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
746  0, RANGE_TIME },
747 
748  /* procuration (SigG)
749 
750  OID = 1 3 36 8 3 2
751  SEQUENCE OF {
752  country [ 1 ] EXPLICIT PrintableString SIZE(2) OPTIONAL,
753  typeOfSubstitution[ 2 ] EXPLICIT PrintableString OPTIONAL,
754  signingFor [ 3 ] EXPLICIT GeneralName
755  } */
756  { MKOID( "\x06\x05\x2B\x24\x08\x03\x02" ), CRYPT_CERTINFO_SIGG_PROCURATION,
757  DESCRIPTION( "procuration" )
758  ENCODING( SEQUENCE ),
759  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
760  FL_SETOF, RANGE_NONE },
762  DESCRIPTION( "procuration.country" )
763  ENCODING_TAGGED( STRING_PRINTABLE, 1 ),
764  0, FL_MULTIVALUED | FL_EXPLICIT | FL_OPTIONAL, RANGE( 2, 2 ) },
766  DESCRIPTION( "procuration.typeOfSubstitution" )
767  ENCODING_TAGGED( STRING_PRINTABLE, 2 ),
768  0, FL_MULTIVALUED | FL_EXPLICIT | FL_OPTIONAL, RANGE( 1, 128 ) },
770  DESCRIPTION( "procuration.signingFor.thirdPerson" )
771  ENCODING_SPECIAL_TAGGED( SUBTYPED, 3 ),
772  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_EXPLICIT | FL_SEQEND /*NONE*/, ENCODED_OBJECT( generalNameInfo ) },
773 
774  /* admissions (SigG)
775 
776  OID = 1 3 36 8 3 3
777  SEQUENCE {
778  authority GeneralName OPTIONAL,
779  content SEQUENCE OF {
780  namingAuthority [ 1 ] EXPLICIT SEQUENCE {
781  namingAuthID OBJECT IDENTIFIER OPTIONAL,
782  namingAuthURL IA5String OPTIONAL,
783  namingAuthText PrintableString OPTIONAL
784  } OPTIONAL,
785  professionInfo SEQUENCE OF {
786  professionItems SEQUENCE OF {
787  professionItem PrintableString
788  },
789  professionOIDs SEQUENCE OF {
790  professionOID OBJECT IDENTIFIER
791  } OPTIONAL,
792  registrationNumber PrintableString OPTIONAL
793  }
794  }
795  }
796 
797  This is a weird extension with several fields (admissionAuthority, namingAuthority)
798  duplicated in two places and only a vague indication in the spec as to which one
799  is used under which conditions, the above is an attempt to create a meaningful
800  interpretation of the definition */
801  { MKOID( "\x06\x05\x2B\x24\x08\x03\x03" ), CRYPT_CERTINFO_SIGG_ADMISSIONS,
802  DESCRIPTION( "admissions" )
803  ENCODING( SEQUENCE ),
804  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
805  0, RANGE_NONE },
807  DESCRIPTION( "admissions.authority" )
808  ENCODING_SPECIAL( SUBTYPED ),
809  0, FL_OPTIONAL, ENCODED_OBJECT( generalNameInfo ) },
810  { NULL, 0,
811  DESCRIPTION( "admissions.content" )
812  ENCODING( SEQUENCE ),
813  0, 0, RANGE_NONE },
814  { NULL, 0,
815  DESCRIPTION( "admissions.content.namingAuthority" )
819  DESCRIPTION( "admissions.content.namingAuthority.namingAuthID" )
820  ENCODING( OBJECT_IDENTIFIER ),
823  DESCRIPTION( "admissions.content.namingAuthority.namingAuthURL" )
824  ENCODING( STRING_IA5 ),
827  DESCRIPTION( "admissions.content.namingAuthority.namingAuthText" )
828  ENCODING( STRING_PRINTABLE ),
830  { NULL, 0,
831  DESCRIPTION( "admissions.professionInfo" )
832  ENCODING( SEQUENCE ),
833  0, 0, RANGE_NONE },
834  { NULL, 0,
835  DESCRIPTION( "admissions.professionInfo.professionItems" )
836  ENCODING( SEQUENCE ),
837  0, 0, RANGE_NONE },
839  DESCRIPTION( "admissions.professionInfo.professionItems.professionItem" )
840  ENCODING( STRING_PRINTABLE ),
842  { NULL, 0,
843  DESCRIPTION( "admissions.professionInfo.professionOIDs" )
844  ENCODING( SEQUENCE ),
845  0, 0, RANGE_NONE },
847  DESCRIPTION( "admissions.professionInfo.professionOIDs.professionOID" )
848  ENCODING( OBJECT_IDENTIFIER ),
851  DESCRIPTION( "admissions.professionInfo.professionItems.registrationNumber" )
852  ENCODING( STRING_PRINTABLE ),
854 
855  /* monetaryLimit (SigG)
856 
857  OID = 1 3 36 8 3 4
858  SEQUENCE {
859  currency PrintableString SIZE(3),
860  amount INTEGER,
861  exponent INTEGER
862  } */
863  { MKOID( "\x06\x05\x2B\x24\x08\x03\x04" ), CRYPT_CERTINFO_SIGG_MONETARYLIMIT,
864  DESCRIPTION( "monetaryLimit" )
865  ENCODING( SEQUENCE ),
866  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
867  0, RANGE_NONE },
869  DESCRIPTION( "monetaryLimit.currency" )
870  ENCODING( STRING_PRINTABLE ),
871  0, 0, RANGE( 3, 3 ) },
873  DESCRIPTION( "monetaryLimit.amount" )
874  ENCODING( INTEGER ),
875  0, 0, RANGE( 1, 255 ) }, /* That's what the spec says */
877  DESCRIPTION( "monetaryLimit.exponent" )
878  ENCODING( INTEGER ),
879  FL_ATTR_ATTREND, FL_SEQEND /*NONE*/, RANGE( 0, 255 ) },
880 
881  /* declarationOfMajority (SigG)
882 
883  OID = 1 3 36 8 3 5
884  CHOICE {
885  fullAgeAtCountry [ 1 ] SEQUENCE {
886  fullAge DEFAULT TRUE,
887  country PrintableString (SIZE(2))
888  },
889  dateOfBirth [ 2 ] GeneralizedTime
890  }
891 
892  This is a rather problematic extension because it uses a CHOICE at
893  the top level so there's no easy way to work with it because,
894  depending on whether the fullAgeAtCountry or dateOfBirth is used,
895  the extension has a different name. To deal with this we rely on
896  the fact that in privacy-conscious Europe where this is unlikely
897  to be used (as opposed to everywhere else, where it definitely
898  won't be used) it's unlikely that people will want personally
899  identifiable information like birth dates in certificates and so
900  what'll be used in practice is the fullAgeAtCountry.
901 
902  The fullAgeAtCountry has an additional complication in that in
903  theory there's a fullAge field that precedes the country field but
904  since it's declared as DEFAULT TRUE and a declaration of majority
905  can't be false it can never occur in any (sane) implementation.
906 
907  The resulting extension is therefore:
908 
909  declarationOfMajority [ 1 ] EXPLICIT SEQUENCE {
910  country PrintableString (SIZE(2))
911  } */
912  { MKOID( "\x06\x05\x2B\x24\x08\x03\x05" ), CRYPT_CERTINFO_SIGG_DECLARATIONOFMAJORITY,
913  DESCRIPTION( "declarationOfMajority" )
915  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
918  DESCRIPTION( "declarationOfMajority.fullAgeAtCountry.country" )
919  ENCODING( STRING_PRINTABLE ),
920  FL_ATTR_ATTREND, FL_SEQEND, RANGE( 2, 2 ) },
921 
922  /* restriction (SigG)
923 
924  OID = 1 3 36 8 3 8
925  restriction PrintableString */
926  { MKOID( "\x06\x05\x2B\x24\x08\x03\x08" ), CRYPT_CERTINFO_SIGG_RESTRICTION,
927  DESCRIPTION( "restriction" )
928  ENCODING( STRING_PRINTABLE ),
929  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
930  0, RANGE( 1, 128 ) },
931 
932 #ifdef USE_CERTREV
933  /* certHash (SigG, OCSP)
934 
935  OID = 1 3 36 8 3 13
936  SEQUENCE {
937  hashAlgo AlgorithmIdentifier,
938  certHash OCTET STRING
939  } */
941  DESCRIPTION( "certhash" )
942  ENCODING_SPECIAL( BLOB_SEQUENCE ),
943  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
944  0, RANGE_BLOB },
945 #endif /* USE_CERTREV */
946 
947  /* additionalInformation (SigG)
948 
949  OID = 1 3 36 8 3 15
950  additionalInformation PrintableString */
951  { MKOID( "\x06\x05\x2B\x24\x08\x03\x0F" ), CRYPT_CERTINFO_SIGG_ADDITIONALINFORMATION,
952  DESCRIPTION( "additionalInformation" )
953  ENCODING( STRING_PRINTABLE ),
954  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
955  0, RANGE( 1, 128 ) },
956 #endif /* USE_CERT_OBSCURE && USE_CERTLEVEL_PKIX_PARTIAL */
957 
958 #ifdef USE_CERT_OBSOLETE
959  /* strongExtranet:
960 
961  OID = 1 3 101 1 4 1
962  SEQUENCE {
963  version INTEGER (0),
964  SEQUENCE OF {
965  SEQUENCE {
966  zone INTEGER,
967  id OCTET STRING (SIZE(1..64))
968  }
969  }
970  } */
971  { MKOID( "\x06\x05\x2B\x65\x01\x04\x01" ), CRYPT_CERTINFO_STRONGEXTRANET,
972  DESCRIPTION( "strongExtranet" )
973  ENCODING( SEQUENCE ),
974  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
975  0, RANGE_NONE },
976  { NULL, 0,
977  DESCRIPTION( "strongExtranet.version" )
978  ENCODING_SPECIAL( BLOB_ANY ), /* INTEGER 0 */
979  0, FL_NONENCODING, 0, 0, 3, "\x02\x01\x00" },
980  { NULL, 0,
981  DESCRIPTION( "strongExtranet.sxNetIDList" )
982  ENCODING( SEQUENCE ),
983  0, FL_SETOF, RANGE_NONE },
984  { NULL, 0,
985  DESCRIPTION( "strongExtranet.sxNetIDList.sxNetID" )
986  ENCODING( SEQUENCE ),
987  0, 0, RANGE_NONE },
989  DESCRIPTION( "strongExtranet.sxNetIDList.sxNetID.zone" )
990  ENCODING( INTEGER ),
991  0, 0, RANGE( 0, MAX_INTLENGTH ) },
993  DESCRIPTION( "strongExtranet.sxNetIDList.sxnetID.id" )
995  FL_ATTR_ATTREND, FL_SEQEND_3 /*FL_SEQEND_2*/, RANGE( 1, 64 ) },
996 #endif /* USE_CERT_OBSOLETE */
997 
998 #ifdef USE_CERTLEVEL_PKIX_PARTIAL
999  /* subjectDirectoryAttributes:
1000 
1001  OID = 2 5 29 9
1002  SEQUENCE SIZE (1..MAX) OF {
1003  SEQUENCE {
1004  type OBJECT IDENTIFIER,
1005  values SET OF ANY -- SIZE (1)
1006  } */
1007  { MKOID( "\x06\x03\x55\x1D\x09" ), CRYPT_CERTINFO_SUBJECTDIRECTORYATTRIBUTES,
1008  DESCRIPTION( "subjectDirectoryAttributes" )
1009  ENCODING( SEQUENCE ),
1010  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
1011  FL_SETOF, RANGE_NONE },
1012  { NULL, 0,
1013  DESCRIPTION( "subjectDirectoryAttributes.attribute" )
1014  ENCODING( SEQUENCE ),
1015  0, 0, RANGE_NONE },
1017  DESCRIPTION( "subjectDirectoryAttributes.attribute.type" )
1018  ENCODING( OBJECT_IDENTIFIER ),
1019  0, FL_MULTIVALUED, RANGE_OID },
1020  { NULL, 0,
1021  DESCRIPTION( "subjectDirectoryAttributes.attribute.values" )
1022  ENCODING( SET ),
1023  0, 0, RANGE_NONE },
1025  DESCRIPTION( "subjectDirectoryAttributes.attribute.values.value" )
1026  ENCODING_SPECIAL( BLOB_ANY ),
1028 #endif /* USE_CERTLEVEL_PKIX_PARTIAL */
1029 
1030  /* subjectKeyIdentifier:
1031 
1032  OID = 2 5 29 14
1033  OCTET STRING
1034 
1035  In theory this should only be processed at level
1036  CRYPT_COMPLIANCELEVEL_PKIX_PARTIAL but the sKID is a universal
1037  identifier that's often used in place of the DN to identify a
1038  certificate so unlike the authorityKeyIdentifier we process it even
1039  in standard mode */
1040  { MKOID( "\x06\x03\x55\x1D\x0E" ), CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
1041  DESCRIPTION( "subjectKeyIdentifier" )
1042  ENCODING( OCTETSTRING ),
1043  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
1044  0, RANGE( 1, 64 ) },
1045 
1046  /* keyUsage:
1047 
1048  OID = 2 5 29 15
1049  critical = TRUE
1050  BITSTRING */
1051  { MKOID( "\x06\x03\x55\x1D\x0F" ), CRYPT_CERTINFO_KEYUSAGE,
1052  DESCRIPTION( "keyUsage" )
1053  ENCODING( BITSTRING ),
1054  ATTR_TYPEINFO2_CRITICAL( CERTREQ, CERT, REDUCED ) | FL_ATTR_ATTREND,
1055  0, 0, CRYPT_KEYUSAGE_LAST, 0, NULL },
1056 
1057 #ifdef USE_CERTLEVEL_PKIX_PARTIAL
1058  /* privateKeyUsagePeriod:
1059 
1060  OID = 2 5 29 16
1061  SEQUENCE {
1062  notBefore [ 0 ] GeneralizedTime OPTIONAL,
1063  notAfter [ 1 ] GeneralizedTime OPTIONAL
1064  } */
1065  { MKOID( "\x06\x03\x55\x1D\x10" ), CRYPT_CERTINFO_PRIVATEKEYUSAGEPERIOD,
1066  DESCRIPTION( "privateKeyUsagePeriod" )
1067  ENCODING( SEQUENCE ),
1068  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
1069  0, RANGE_NONE },
1071  DESCRIPTION( "privateKeyUsagePeriod.notBefore" )
1072  ENCODING_TAGGED( TIME_GENERALIZED, 0 ),
1073  0, FL_OPTIONAL, RANGE_TIME },
1075  DESCRIPTION( "privateKeyUsagePeriod.notAfter" )
1076  ENCODING_TAGGED( TIME_GENERALIZED, 1 ),
1078 #endif /* USE_CERTLEVEL_PKIX_PARTIAL */
1079 
1080  /* subjectAltName:
1081 
1082  OID = 2 5 29 17
1083  SEQUENCE OF GeneralName */
1084  { MKOID( "\x06\x03\x55\x1D\x11" ), FIELDID_FOLLOWS,
1085  DESCRIPTION( "subjectAltName" )
1086  ENCODING( SEQUENCE ),
1087  ATTR_TYPEINFO2( CERTREQ, CERT, STANDARD ),
1088  FL_SETOF, RANGE_NONE },
1090  DESCRIPTION( "subjectAltName.generalName" )
1091  ENCODING_SPECIAL( SUBTYPED ),
1092  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_SEQEND /*NONE*/, ENCODED_OBJECT( generalNameInfo ) },
1093 
1094  /* issuerAltName:
1095 
1096  OID = 2 5 29 18
1097  SEQUENCE OF GeneralName */
1098  { MKOID( "\x06\x03\x55\x1D\x12" ), FIELDID_FOLLOWS,
1099  DESCRIPTION( "issuerAltName" )
1100  ENCODING( SEQUENCE ),
1101  ATTR_TYPEINFO2( CERT, CRL, STANDARD ),
1102  FL_SETOF, RANGE_NONE },
1104  DESCRIPTION( "issuerAltName.generalName" )
1105  ENCODING_SPECIAL( SUBTYPED ),
1106  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_SEQEND /*NONE*/, ENCODED_OBJECT( generalNameInfo ) },
1107 
1108  /* basicConstraints:
1109 
1110  OID = 2 5 29 19
1111  critical = TRUE
1112  SEQUENCE {
1113  cA BOOLEAN DEFAULT FALSE,
1114  pathLenConstraint INTEGER (0..64) OPTIONAL
1115  } */
1116  { MKOID( "\x06\x03\x55\x1D\x13" ), CRYPT_CERTINFO_BASICCONSTRAINTS,
1117  DESCRIPTION( "basicConstraints" )
1118  ENCODING( SEQUENCE ),
1119  ATTR_TYPEINFO2_CRITICAL( CERT, ATTRCERT, REDUCED ),
1121  { NULL, CRYPT_CERTINFO_CA,
1122  DESCRIPTION( "basicConstraints.cA" )
1123  ENCODING( BOOLEAN ),
1126  DESCRIPTION( "basicConstraints.pathLenConstraint" )
1127  ENCODING( INTEGER ),
1128  FL_ATTR_ATTREND, FL_OPTIONAL | FL_SEQEND /*NONE*/, RANGE( 0, 64 ) },
1129 
1130 #if defined( USE_CERTREV ) && defined( USE_CERTLEVEL_PKIX_PARTIAL )
1131  /* cRLNumber:
1132 
1133  OID = 2 5 29 20
1134  INTEGER */
1135  { MKOID( "\x06\x03\x55\x1D\x14" ), CRYPT_CERTINFO_CRLNUMBER,
1136  DESCRIPTION( "cRLNumber" )
1137  ENCODING( INTEGER ),
1138  ATTR_TYPEINFO( CRL, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
1139  0, RANGE( 0, MAX_INTLENGTH ) },
1140 #endif /* USE_CERTREV && USE_CERTLEVEL_PKIX_PARTIAL */
1141 
1142 #if defined( USE_CERTREV ) || defined( USE_CERTREQ )
1143  /* cRLReason:
1144 
1145  OID = 2 5 29 21
1146  ENUMERATED */
1147  { MKOID( "\x06\x03\x55\x1D\x15" ), CRYPT_CERTINFO_CRLREASON,
1148  DESCRIPTION( "cRLReason" )
1149  ENCODING( ENUMERATED ),
1150  ATTR_TYPEINFO2( CRL, REVREQ /*Per-entry*/, REDUCED ) | FL_ATTR_ATTREND,
1151  0, RANGE( 0, CRYPT_CRLREASON_LAST ) },
1152 #endif /* USE_CERTREV || USE_CERTREQ */
1153 
1154 #if ( defined( USE_CERTREV ) || defined( USE_CERTREQ ) ) && \
1155  defined( USE_CERTLEVEL_PKIX_FULL )
1156  /* holdInstructionCode:
1157 
1158  OID = 2 5 29 23
1159  OBJECT IDENTIFIER */
1160  { MKOID( "\x06\x03\x55\x1D\x17" ), CRYPT_CERTINFO_HOLDINSTRUCTIONCODE,
1161  DESCRIPTION( "holdInstructionCode" )
1162  ENCODING_SPECIAL( CHOICE ),
1163  ATTR_TYPEINFO2( CRL, REVREQ /*Per-entry*/, PKIX_FULL ) | FL_ATTR_ATTREND,
1164  0, CRYPT_HOLDINSTRUCTION_NONE, CRYPT_HOLDINSTRUCTION_LAST, 0, ( void * ) holdInstructionInfo },
1165 #endif /* ( USE_CERTREV || USE_CERTREQ ) && USE_CERTLEVEL_PKIX_FULL */
1166 
1167 #if defined( USE_CERTREV ) || defined( USE_CERTREQ )
1168  /* invalidityDate:
1169 
1170  OID = 2 5 29 24
1171  GeneralizedTime */
1172  { MKOID( "\x06\x03\x55\x1D\x18" ), CRYPT_CERTINFO_INVALIDITYDATE,
1173  DESCRIPTION( "invalidityDate" )
1174  ENCODING( TIME_GENERALIZED ),
1175  ATTR_TYPEINFO2( CRL, REVREQ /*Per-entry*/, STANDARD ) | FL_ATTR_ATTREND,
1176  0, RANGE_TIME },
1177 #endif /* USE_CERTREV || USE_CERTREQ */
1178 
1179 #if defined( USE_CERTREV ) && defined( USE_CERTLEVEL_PKIX_PARTIAL )
1180  /* deltaCRLIndicator:
1181 
1182  OID = 2 5 29 27
1183  critical = TRUE
1184  INTEGER */
1185  { MKOID( "\x06\x03\x55\x1D\x1B" ), CRYPT_CERTINFO_DELTACRLINDICATOR,
1186  DESCRIPTION( "deltaCRLIndicator" )
1187  ENCODING( INTEGER ),
1188  ATTR_TYPEINFO_CRITICAL( CRL, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
1189  0, RANGE( 0, MAX_INTLENGTH ) },
1190 
1191  /* issuingDistributionPoint:
1192 
1193  OID = 2 5 29 28
1194  critical = TRUE
1195  SEQUENCE {
1196  distributionPoint [ 0 ] {
1197  fullName [ 0 ] { -- CHOICE { ... }
1198  SEQUENCE OF GeneralName -- GeneralNames
1199  }
1200  } OPTIONAL,
1201  onlyContainsUserCerts
1202  [ 1 ] BOOLEAN DEFAULT FALSE,
1203  onlyContainsCACerts
1204  [ 2 ] BOOLEAN DEFAULT FALSE,
1205  onlySomeReasons [ 3 ] BITSTRING OPTIONAL,
1206  indirectCRL [ 4 ] BOOLEAN DEFAULT FALSE
1207  } */
1208  { MKOID( "\x06\x03\x55\x1D\x1C" ), CRYPT_CERTINFO_ISSUINGDISTRIBUTIONPOINT,
1209  DESCRIPTION( "issuingDistributionPoint" )
1210  ENCODING( SEQUENCE ),
1211  ATTR_TYPEINFO_CRITICAL( CRL, PKIX_PARTIAL ),
1212  0, RANGE_NONE },
1213  { NULL, 0,
1214  DESCRIPTION( "issuingDistributionPoint.distributionPoint" )
1215  ENCODING_TAGGED( SEQUENCE, 0 ),
1216  0, FL_OPTIONAL, RANGE_NONE },
1217  { NULL, 0,
1218  DESCRIPTION( "issuingDistributionPoint.distributionPoint.fullName" )
1219  ENCODING_TAGGED( SEQUENCE, 0 ),
1220  0, 0, RANGE_NONE },
1221  { NULL, 0,
1222  DESCRIPTION( "issuingDistributionPoint.distributionPoint.fullName.generalNames" )
1223  ENCODING( SEQUENCE ),
1224  0, 0, RANGE_NONE },
1226  DESCRIPTION( "issuingDistributionPoint.distributionPoint.fullName.generalNames.generalName" )
1227  ENCODING_SPECIAL( SUBTYPED ),
1228  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_3, ENCODED_OBJECT( generalNameInfo ) },
1230  DESCRIPTION( "issuingDistributionPoint.onlyContainsUserCerts" )
1231  ENCODING_TAGGED( BOOLEAN, 1 ),
1234  DESCRIPTION( "issuingDistributionPoint.onlyContainsCACerts" )
1235  ENCODING_TAGGED( BOOLEAN, 2 ),
1238  DESCRIPTION( "issuingDistributionPoint.onlySomeReasons" )
1239  ENCODING_TAGGED( BITSTRING, 3 ),
1242  DESCRIPTION( "issuingDistributionPoint.indirectCRL" )
1243  ENCODING_TAGGED( BOOLEAN, 4 ),
1245 #endif /* USER_CERTREV && USE_CERTLEVEL_PKIX_PARTIAL */
1246 
1247 #if defined( USE_CERTREV ) && defined( USE_CERTLEVEL_PKIX_FULL )
1248  /* certificateIssuer:
1249 
1250  OID = 2 5 29 29
1251  critical = TRUE
1252  certificateIssuer SEQUENCE OF GeneralName */
1253  { MKOID( "\x06\x03\x55\x1D\x1D" ), FIELDID_FOLLOWS,
1254  DESCRIPTION( "certificateIssuer" )
1255  ENCODING( SEQUENCE ),
1256  ATTR_TYPEINFO_CRITICAL( CRL, PKIX_FULL ),
1257  0, RANGE_NONE },
1259  DESCRIPTION( "certificateIssuer.generalNames" )
1260  ENCODING_SPECIAL( SUBTYPED ),
1261  FL_ATTR_ATTREND, FL_MULTIVALUED, ENCODED_OBJECT( generalNameInfo ) },
1262 #endif /* USE_CERTREV && USE_CERTLEVEL_PKIX_FULL */
1263 
1264 #ifdef USE_CERTLEVEL_PKIX_FULL
1265  /* nameConstraints
1266 
1267  OID = 2 5 29 30
1268  critical = TRUE
1269  SEQUENCE {
1270  permittedSubtrees [ 0 ] SEQUENCE OF {
1271  SEQUENCE { GeneralName }
1272  } OPTIONAL,
1273  excludedSubtrees [ 1 ] SEQUENCE OF {
1274  SEQUENCE { GeneralName }
1275  } OPTIONAL,
1276  }
1277 
1278  RFC 3280 extended this by adding two additional fields after the
1279  GeneralName (probably from X.509v4) but mitigated it by requiring
1280  that they never be used so we leave the definition as is */
1281  { MKOID( "\x06\x03\x55\x1D\x1E" ), CRYPT_CERTINFO_NAMECONSTRAINTS,
1282  DESCRIPTION( "nameConstraints" )
1283  ENCODING( SEQUENCE ),
1284  ATTR_TYPEINFO2( CERT, ATTRCERT, PKIX_FULL ),
1285  0, RANGE_NONE },
1286  { NULL, 0,
1287  DESCRIPTION( "nameConstraints.permittedSubtrees" )
1288  ENCODING_TAGGED( SEQUENCE, 0 ),
1290  { NULL, 0,
1291  DESCRIPTION( "nameConstraints.permittedSubtrees.sequenceOf" )
1292  ENCODING( SEQUENCE ),
1293  0, 0, RANGE_NONE },
1295  DESCRIPTION( "nameConstraints.permittedSubtrees.sequenceOf.generalName" )
1296  ENCODING_SPECIAL( SUBTYPED ),
1297  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_2, ENCODED_OBJECT( generalNameInfo ) },
1298  { NULL, 0,
1299  DESCRIPTION( "nameConstraints.excludedSubtrees" )
1300  ENCODING_TAGGED( SEQUENCE, 1 ),
1302  { NULL, 0,
1303  DESCRIPTION( "nameConstraints.excludedSubtrees.sequenceOf" )
1304  ENCODING( SEQUENCE ),
1305  0, 0, RANGE_NONE },
1307  DESCRIPTION( "nameConstraints.excludedSubtrees.sequenceOf.generalName" )
1308  ENCODING_SPECIAL( SUBTYPED ),
1309  FL_ATTR_ATTREND, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_2 /*or _3*/, ENCODED_OBJECT( generalNameInfo ) },
1310 #endif /* USE_CERTLEVEL_PKIX_FULL */
1311 
1312  /* cRLDistributionPoints:
1313 
1314  OID = 2 5 29 31
1315  SEQUENCE OF {
1316  SEQUENCE {
1317  distributionPoint
1318  [ 0 ] { -- CHOICE { ... }
1319  fullName [ 0 ] SEQUENCE OF GeneralName
1320  } OPTIONAL,
1321  reasons [ 1 ] BIT STRING OPTIONAL,
1322  cRLIssuer [ 2 ] SEQUENCE OF GeneralName OPTIONAL
1323  }
1324  } */
1325  { MKOID( "\x06\x03\x55\x1D\x1F" ), CRYPT_CERTINFO_CRLDISTRIBUTIONPOINT,
1326  DESCRIPTION( "cRLDistributionPoints" )
1327  ENCODING( SEQUENCE ),
1328  ATTR_TYPEINFO2( CERT, ATTRCERT, STANDARD ),
1329  FL_SETOF, RANGE_NONE },
1330  { NULL, 0,
1331  DESCRIPTION( "cRLDistributionPoints.distPoint" )
1332  ENCODING( SEQUENCE ),
1333  0, 0, RANGE_NONE },
1334  { NULL, 0,
1335  DESCRIPTION( "cRLDistributionPoints.distPoint.distPoint" )
1336  ENCODING_TAGGED( SEQUENCE, 0 ),
1337  0, FL_OPTIONAL, RANGE_NONE },
1338  { NULL, 0,
1339  DESCRIPTION( "cRLDistributionPoints.distPoint.distPoint.fullName" )
1340  ENCODING_TAGGED( SEQUENCE, 0 ),
1341  0, FL_SETOF, RANGE_NONE },
1343  DESCRIPTION( "cRLDistributionPoints.distPoint.distPoint.fullName.generalName" )
1344  ENCODING_SPECIAL( SUBTYPED ),
1345  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_2, ENCODED_OBJECT( generalNameInfo ) },
1347  DESCRIPTION( "cRLDistributionPoints.distPoint.reasons" )
1348  ENCODING_TAGGED( BITSTRING, 1 ),
1350  { NULL, 0,
1351  DESCRIPTION( "cRLDistributionPoints.distPoint.cRLIssuer" )
1352  ENCODING_TAGGED( SEQUENCE, 2 ),
1355  DESCRIPTION( "cRLDistributionPoints.distPoint.cRLIssuer.generalName" )
1356  ENCODING_SPECIAL( SUBTYPED ),
1357  FL_ATTR_ATTREND, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_2 /*or _3*/, ENCODED_OBJECT( generalNameInfo ) },
1358 
1359  /* certificatePolicies:
1360 
1361  OID = 2 5 29 32
1362  SEQUENCE SIZE (1..64) OF {
1363  SEQUENCE {
1364  policyIdentifier OBJECT IDENTIFIER,
1365  policyQualifiers SEQUENCE SIZE (1..64) OF {
1366  SEQUENCE {
1367  policyQualifierId
1368  OBJECT IDENTIFIER,
1369  qualifier ANY DEFINED BY policyQualifierID
1370  } OPTIONAL
1371  }
1372  }
1373  }
1374 
1375  CPSuri ::= IA5String -- OID = cps
1376 
1377  UserNotice ::= SEQUENCE { -- OID = unotice
1378  noticeRef SEQUENCE {
1379  organization DisplayText,
1380  noticeNumbers SEQUENCE OF INTEGER -- SIZE (1)
1381  } OPTIONAL,
1382  explicitText DisplayText OPTIONAL
1383  }
1384 
1385  Note that although this extension is decoded at
1386  CRYPT_COMPLIANCELEVEL_STANDARD policy constraints are only enforced
1387  at CRYPT_COMPLIANCELEVEL_PKIX_FULL due to the totally bizarre
1388  requirements that some of them have (see comments in chk_*.c for more
1389  on this) */
1390  { MKOID( "\x06\x03\x55\x1D\x20" ), CRYPT_CERTINFO_CERTIFICATEPOLICIES,
1391  DESCRIPTION( "certPolicies" )
1392  ENCODING( SEQUENCE ),
1393  ATTR_TYPEINFO( CERT, STANDARD ),
1394  FL_SETOF, RANGE_NONE },
1395  { NULL, 0,
1396  DESCRIPTION( "certPolicies.policyInfo" )
1397  ENCODING( SEQUENCE ),
1398  0, 0, RANGE_NONE },
1400  DESCRIPTION( "certPolicies.policyInfo.policyIdentifier" )
1401  ENCODING( OBJECT_IDENTIFIER ),
1402  0, FL_MULTIVALUED, RANGE_OID },
1403  { NULL, 0,
1404  DESCRIPTION( "certPolicies.policyInfo.policyQualifiers" )
1405  ENCODING( SEQUENCE ),
1407  { NULL, 0,
1408  DESCRIPTION( "certPolicies.policyInfo.policyQual" )
1409  ENCODING( SEQUENCE ),
1410  0, FL_IDENTIFIER, RANGE_NONE },
1411  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x01" ), 0,
1412  DESCRIPTION( "certPolicies.policyInfo.policyQual.cps (1 3 6 1 5 5 7 2 1)" )
1413  ENCODING_SPECIAL( IDENTIFIER ),
1414  0, 0, RANGE_NONE },
1416  DESCRIPTION( "certPolicies.policyInfo.policyQuals.qualifier.cPSuri" )
1417  ENCODING( STRING_IA5 ),
1418  0, FL_MULTIVALUED | FL_SEQEND /*FL_SEQEND_2*/, CHECK_URL },
1419  { NULL, 0,
1420  DESCRIPTION( "certPolicies.policyInfo.policyQual" )
1421  ENCODING( SEQUENCE ),
1422  0, FL_IDENTIFIER, RANGE_NONE },
1423  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x02\x02" ), 0,
1424  DESCRIPTION( "certPolicies.policyInfo.policyQual.unotice (1 3 6 1 5 5 7 2 2)" )
1425  ENCODING_SPECIAL( IDENTIFIER ),
1426  0, 0, RANGE_NONE },
1427  { NULL, 0,
1428  DESCRIPTION( "certPolicies.policyInfo.policyQual.userNotice" )
1429  ENCODING( SEQUENCE ),
1430  0, FL_OPTIONAL, RANGE_NONE },
1431  { NULL, 0,
1432  DESCRIPTION( "certPolicies.policyInfo.policyQual.userNotice.noticeRef" )
1433  ENCODING( SEQUENCE ),
1436  DESCRIPTION( "certPolicies.policyInfo.policyQual.userNotice.noticeRef.organization" )
1437  ENCODING_SPECIAL( TEXTSTRING ),
1438  0, FL_MULTIVALUED, RANGE( 1, 200 ) },
1439  { NULL, 0,
1440  DESCRIPTION( "certPolicies.policyInfo.policyQual.userNotice.noticeRef.noticeNumbers" )
1441  ENCODING( SEQUENCE ),
1442  0, FL_OPTIONAL, RANGE_NONE },
1444  DESCRIPTION( "certPolicies.policyInfo.policyQual.userNotice.noticeRef.noticeNumbers" )
1445  ENCODING( INTEGER ),
1446  0, FL_MULTIVALUED | FL_SEQEND_2, RANGE( 1, 1000 ) },
1448  DESCRIPTION( "certPolicies.policyInfo.policyQual.userNotice.explicitText" )
1449  ENCODING_SPECIAL( TEXTSTRING ),
1450  FL_ATTR_ATTREND, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_3 /*FL_SEQEND, or _4 (CPS) or _5 or _7 (uNotice), */, RANGE( 1, 200 ) },
1451 
1452 #ifdef USE_CERTLEVEL_PKIX_FULL
1453  /* policyMappings:
1454 
1455  OID = 2 5 29 33
1456  SEQUENCE SIZE (1..MAX) OF {
1457  SEQUENCE {
1458  issuerDomainPolicy OBJECT IDENTIFIER,
1459  subjectDomainPolicy OBJECT IDENTIFIER
1460  }
1461  } */
1462  { MKOID( "\x06\x03\x55\x1D\x21" ), CRYPT_CERTINFO_POLICYMAPPINGS,
1463  DESCRIPTION( "policyMappings" )
1464  ENCODING( SEQUENCE ),
1465  ATTR_TYPEINFO( CERT, PKIX_FULL ),
1466  FL_SETOF, RANGE_NONE },
1467  { NULL, 0,
1468  DESCRIPTION( "policyMappings.sequenceOf" )
1469  ENCODING( SEQUENCE ),
1470  0, 0, RANGE_NONE },
1472  DESCRIPTION( "policyMappings.sequenceOf.issuerDomainPolicy" )
1473  ENCODING( OBJECT_IDENTIFIER ),
1474  0, FL_MULTIVALUED, RANGE_OID },
1476  DESCRIPTION( "policyMappings.sequenceOf.subjectDomainPolicy" )
1477  ENCODING( OBJECT_IDENTIFIER ),
1478  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_SEQEND_2 /*FL_SEQEND_3*/, RANGE_OID },
1479 #endif /* USE_CERTLEVEL_PKIX_FULL */
1480 
1481 #ifdef USE_CERTLEVEL_PKIX_PARTIAL
1482  /* authorityKeyIdentifier:
1483 
1484  OID = 2 5 29 35
1485  SEQUENCE {
1486  keyIdentifier [ 0 ] OCTET STRING OPTIONAL,
1487  authorityCertIssuer -- Neither or both
1488  [ 1 ] SEQUENCE OF GeneralName OPTIONAL
1489  authorityCertSerialNumber -- of these must
1490  [ 2 ] INTEGER OPTIONAL -- be present
1491  }
1492 
1493  Although the serialNumber should be an INTEGER it's really an INTEGER
1494  equivalent of an OCTET STRING hole so we call it an OCTET STRING to
1495  make sure that it gets handled appropriately */
1496  { MKOID( "\x06\x03\x55\x1D\x23" ), CRYPT_CERTINFO_AUTHORITYKEYIDENTIFIER,
1497  DESCRIPTION( "authorityKeyIdentifier" )
1498  ENCODING( SEQUENCE ),
1499  ATTR_TYPEINFO2( CERT, CRL, PKIX_PARTIAL ),
1500  0, RANGE_NONE },
1502  DESCRIPTION( "authorityKeyIdentifier.keyIdentifier" )
1504  0, FL_OPTIONAL, RANGE( 1, 64 ) },
1505  { NULL, 0,
1506  DESCRIPTION( "authorityKeyIdentifier.authorityCertIssuer" )
1507  ENCODING_TAGGED( SEQUENCE, 1 ),
1510  DESCRIPTION( "authorityKeyIdentifier.authorityCertIssuer.generalName" )
1511  ENCODING_SPECIAL( SUBTYPED ),
1512  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, ENCODED_OBJECT( generalNameInfo ) },
1514  DESCRIPTION( "authorityKeyIdentifier.authorityCertSerialNumber" )
1515  ENCODING_TAGGED( OCTETSTRING, 2 ), /* Actually an INTEGER hole */
1516  FL_ATTR_ATTREND, FL_OPTIONAL | FL_SEQEND /*NONE*/, RANGE( 1, 64 ) },
1517 #endif /* USE_CERTLEVEL_PKIX_PARTIAL */
1518 
1519 #ifdef USE_CERTLEVEL_PKIX_FULL
1520  /* policyConstraints:
1521 
1522  OID = 2 5 29 36
1523  SEQUENCE {
1524  requireExplicitPolicy [ 0 ] INTEGER OPTIONAL,
1525  inhibitPolicyMapping [ 1 ] INTEGER OPTIONAL
1526  } */
1527  { MKOID( "\x06\x03\x55\x1D\x24" ), CRYPT_CERTINFO_POLICYCONSTRAINTS,
1528  DESCRIPTION( "policyConstraints" )
1529  ENCODING( SEQUENCE ),
1530  ATTR_TYPEINFO( CERT, PKIX_FULL ),
1531  0, RANGE_NONE },
1533  DESCRIPTION( "policyConstraints.requireExplicitPolicy" )
1534  ENCODING_TAGGED( INTEGER, 0 ),
1535  0, FL_OPTIONAL, RANGE( 0, 64 ) },
1537  DESCRIPTION( "policyConstraints.inhibitPolicyMapping" )
1538  ENCODING_TAGGED( INTEGER, 1 ),
1539  FL_ATTR_ATTREND, FL_OPTIONAL | FL_SEQEND /*NONE*/, RANGE( 0, 64 ) },
1540 #endif /* USE_CERTLEVEL_PKIX_FULL */
1541 
1542  /* extKeyUsage:
1543 
1544  OID = 2 5 29 37
1545  SEQUENCE {
1546  oidInstance1 OPTIONAL,
1547  oidInstance2 OPTIONAL,
1548  ...
1549  oidInstanceN OPTIONAL
1550  } */
1551  { MKOID( "\x06\x03\x55\x1D\x25" ), CRYPT_CERTINFO_EXTKEYUSAGE,
1552  DESCRIPTION( "extKeyUsage" )
1553  ENCODING( SEQUENCE ),
1554  ATTR_TYPEINFO2( CERTREQ, CERT, STANDARD ),
1555  0, RANGE_NONE },
1556  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x15" ), CRYPT_CERTINFO_EXTKEY_MS_INDIVIDUALCODESIGNING,
1557  DESCRIPTION( "extKeyUsage.individualCodeSigning (1 3 6 1 4 1 311 2 1 21)" )
1558  ENCODING_SPECIAL( IDENTIFIER ),
1559  0, FL_OPTIONAL, RANGE_NONE },
1560  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x16" ), CRYPT_CERTINFO_EXTKEY_MS_COMMERCIALCODESIGNING,
1561  DESCRIPTION( "extKeyUsage.commercialCodeSigning (1 3 6 1 4 1 311 2 1 22)" )
1562  ENCODING_SPECIAL( IDENTIFIER ),
1563  0, FL_OPTIONAL, RANGE_NONE },
1564  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x0A\x03\x01" ), CRYPT_CERTINFO_EXTKEY_MS_CERTTRUSTLISTSIGNING,
1565  DESCRIPTION( "extKeyUsage.certTrustListSigning (1 3 6 1 4 1 311 10 3 1)" )
1566  ENCODING_SPECIAL( IDENTIFIER ),
1567  0, FL_OPTIONAL, RANGE_NONE },
1568  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x0A\x03\x02" ), CRYPT_CERTINFO_EXTKEY_MS_TIMESTAMPSIGNING,
1569  DESCRIPTION( "extKeyUsage.timeStampSigning (1 3 6 1 4 1 311 10 3 2)" )
1570  ENCODING_SPECIAL( IDENTIFIER ),
1571  0, FL_OPTIONAL, RANGE_NONE },
1572  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x0A\x03\x03" ), CRYPT_CERTINFO_EXTKEY_MS_SERVERGATEDCRYPTO,
1573  DESCRIPTION( "extKeyUsage.serverGatedCrypto (1 3 6 1 4 1 311 10 3 3)" )
1574  ENCODING_SPECIAL( IDENTIFIER ),
1575  0, FL_OPTIONAL, RANGE_NONE },
1576  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x0A\x03\x04" ), CRYPT_CERTINFO_EXTKEY_MS_ENCRYPTEDFILESYSTEM,
1577  DESCRIPTION( "extKeyUsage.encrypedFileSystem (1 3 6 1 4 1 311 10 3 4)" )
1578  ENCODING_SPECIAL( IDENTIFIER ),
1579  0, FL_OPTIONAL, RANGE_NONE },
1580  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x01" ), CRYPT_CERTINFO_EXTKEY_SERVERAUTH,
1581  DESCRIPTION( "extKeyUsage.serverAuth (1 3 6 1 5 5 7 3 1)" )
1582  ENCODING_SPECIAL( IDENTIFIER ),
1583  0, FL_OPTIONAL, RANGE_NONE },
1584  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x02" ), CRYPT_CERTINFO_EXTKEY_CLIENTAUTH,
1585  DESCRIPTION( "extKeyUsage.clientAuth (1 3 6 1 5 5 7 3 2)" )
1586  ENCODING_SPECIAL( IDENTIFIER ),
1587  0, FL_OPTIONAL, RANGE_NONE },
1588  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x03" ), CRYPT_CERTINFO_EXTKEY_CODESIGNING,
1589  DESCRIPTION( "extKeyUsage.codeSigning (1 3 6 1 5 5 7 3 3)" )
1590  ENCODING_SPECIAL( IDENTIFIER ),
1591  0, FL_OPTIONAL, RANGE_NONE },
1592  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x04" ), CRYPT_CERTINFO_EXTKEY_EMAILPROTECTION,
1593  DESCRIPTION( "extKeyUsage.emailProtection (1 3 6 1 5 5 7 3 4)" )
1594  ENCODING_SPECIAL( IDENTIFIER ),
1595  0, FL_OPTIONAL, RANGE_NONE },
1596  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x05" ), CRYPT_CERTINFO_EXTKEY_IPSECENDSYSTEM,
1597  DESCRIPTION( "extKeyUsage.ipsecEndSystem (1 3 6 1 5 5 7 3 5)" )
1598  ENCODING_SPECIAL( IDENTIFIER ),
1599  0, FL_OPTIONAL, RANGE_NONE },
1600  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x06" ), CRYPT_CERTINFO_EXTKEY_IPSECTUNNEL,
1601  DESCRIPTION( "extKeyUsage.ipsecTunnel (1 3 6 1 5 5 7 3 6)" )
1602  ENCODING_SPECIAL( IDENTIFIER ),
1603  0, FL_OPTIONAL, RANGE_NONE },
1604  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x07" ), CRYPT_CERTINFO_EXTKEY_IPSECUSER,
1605  DESCRIPTION( "extKeyUsage.ipsecUser (1 3 6 1 5 5 7 3 7)" )
1606  ENCODING_SPECIAL( IDENTIFIER ),
1607  0, FL_OPTIONAL, RANGE_NONE },
1608  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x08" ), CRYPT_CERTINFO_EXTKEY_TIMESTAMPING,
1609  DESCRIPTION( "extKeyUsage.timeStamping (1 3 6 1 5 5 7 3 8)" )
1610  ENCODING_SPECIAL( IDENTIFIER ),
1611  0, FL_OPTIONAL, RANGE_NONE },
1612  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x03\x09" ), CRYPT_CERTINFO_EXTKEY_OCSPSIGNING,
1613  DESCRIPTION( "extKeyUsage.ocspSigning (1 3 6 1 5 5 7 3 9)" )
1614  ENCODING_SPECIAL( IDENTIFIER ),
1615  0, FL_OPTIONAL, RANGE_NONE },
1616  { MKOID( "\x06\x05\x2B\x24\x08\x02\x01" ), CRYPT_CERTINFO_EXTKEY_DIRECTORYSERVICE,
1617  DESCRIPTION( "extKeyUsage.directoryService (1 3 36 8 2 1)" )
1618  ENCODING_SPECIAL( IDENTIFIER ),
1619  0, FL_OPTIONAL, RANGE_NONE },
1620  { MKOID( "\x06\x04\x55\x1D\x25\x00" ), CRYPT_CERTINFO_EXTKEY_ANYKEYUSAGE,
1621  DESCRIPTION( "extKeyUsage.anyExtendedKeyUsage(2 5 29 37 0)" )
1622  ENCODING_SPECIAL( IDENTIFIER ),
1623  0, FL_OPTIONAL, RANGE_NONE },
1624  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x04\x01" ), CRYPT_CERTINFO_EXTKEY_NS_SERVERGATEDCRYPTO,
1625  DESCRIPTION( "extKeyUsage.serverGatedCrypto (2 16 840 1 113730 4 1)" )
1626  ENCODING_SPECIAL( IDENTIFIER ),
1627  0, FL_OPTIONAL, RANGE_NONE },
1628  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x08\x01" ), CRYPT_CERTINFO_EXTKEY_VS_SERVERGATEDCRYPTO_CA,
1629  DESCRIPTION( "extKeyUsage.serverGatedCryptoCA (2 16 840 1 113733 1 8 1)" )
1630  ENCODING_SPECIAL( IDENTIFIER ),
1631  0, FL_OPTIONAL, RANGE_NONE },
1632  { NULL, 0,
1633  DESCRIPTION( "extKeyUsage.catchAll" )
1634  ENCODING_SPECIAL( BLOB_ANY ), /* Match anything and ignore it */
1636 
1637 #ifdef USE_CERTLEVEL_PKIX_FULL
1638 #ifdef USE_REV
1639  /* crlStreamIdentifier:
1640 
1641  OID = 2 5 29 40
1642  INTEGER */
1643  { MKOID( "\x06\x03\x55\x1D\x28" ), CRYPT_CERTINFO_CRLSTREAMIDENTIFIER,
1644  DESCRIPTION( "crlStreamIdentifier" )
1645  ENCODING( INTEGER ),
1646  ATTR_TYPEINFO( CRL, PKIX_FULL ) | FL_ATTR_ATTREND,
1647  0, RANGE( 0, 64 ) },
1648 #endif /* USE_REV */
1649 
1650  /* statusReferrals:
1651 
1652  OID = 2 5 29 46
1653  critical = TRUE
1654  SEQUENCE OF {
1655  cRLReferral [ 0 ] EXPLICIT SEQUENCE {
1656  issuer [ 0 ] GeneralName OPTIONAL,
1657  location [ 1 ] GeneralName OPTIONAL,
1658  deltaRefInfo [ 2 ] SEQUENCE {
1659  deltaLocation GeneralName,
1660  lastDelta GeneralizedTime OPTIONAL
1661  } OPTIONAL,
1662  cRLScope SEQUENCE OF {
1663  SEQUENCE {
1664  authorityName [ 0 ] GeneralName OPTIONAL,
1665  distributionPoint [ 1 ][ 0 ] EXPLICIT GeneralName OPTIONAL,
1666  onlyContains [ 2 ] BIT STRING OPTIONAL, -- 3 bits
1667  onlySomeReasons [ 4 ] BIT STRING OPTIONAL, -- 9 bits
1668  serialNumberRange [ 5 ] SEQUENCE {
1669  startingNumber[ 0 ] INTEGER OPTIONAL,
1670  endingNumber [ 1 ] INTEGER OPTIONAL
1671  } OPTIONAL,
1672  subjectKeyIdRange [ 6 ] SEQUENCE {
1673  startingKeyId [ 0 ] INTEGER OPTIONAL,
1674  endingKeyId [ 1 ] INTEGER OPTIONAL
1675  } OPTIONAL,
1676  nameSubtrees [ 7 ] SEQUENCE OF GeneralName OPTIONAL,
1677  baseRevocationInfo [ 9 ] SEQUENCE {
1678  cRLStatusIndicator [ 0 ] INTEGER OPTIONAL,
1679  cRLNumber [ 1 ] INTEGER,
1680  baseThisUpdate [ 2 ] GeneralizedTime
1681  }
1682  }
1683  }
1684  lastUpdate [ 3 ] GeneralizedTime OPTIONAL,
1685  lastChangedCRL [ 4 ] GeneralizedTime OPTIONAL
1686  }
1687  }
1688 
1689  To think that someone actually did this on purpose!
1690 
1691  This is a crazy extension that, in effect, says that the CRL that
1692  you're holding in your hands isn't really a CRL at all but a pointer
1693  to locations where actual CRL information may be found, assuming that
1694  the processing application knows about this bizarre interpretation.
1695  Since the likelihood of this happening is essentially zero (there are
1696  no known implementations of this at present), we don't use it */
1697 
1698  /* freshestCRL:
1699 
1700  OID = 2 5 29 46
1701  SEQUENCE OF {
1702  SEQUENCE {
1703  distributionPoint
1704  [ 0 ] { -- CHOICE { ... }
1705  fullName [ 0 ] SEQUENCE OF GeneralName
1706  } OPTIONAL,
1707  reasons [ 1 ] BIT STRING OPTIONAL,
1708  cRLIssuer [ 2 ] SEQUENCE OF GeneralName OPTIONAL
1709  }
1710  } */
1711  { MKOID( "\x06\x03\x55\x1D\x2E" ), CRYPT_CERTINFO_FRESHESTCRL,
1712  DESCRIPTION( "freshestCRL" )
1713  ENCODING( SEQUENCE ),
1714  ATTR_TYPEINFO2( CERT, ATTRCERT, PKIX_FULL ),
1715  FL_SETOF, RANGE_NONE },
1716  { NULL, 0,
1717  DESCRIPTION( "freshestCRL.distributionPoint" )
1718  ENCODING( SEQUENCE ),
1719  0, 0, RANGE_NONE },
1720  { NULL, 0,
1721  DESCRIPTION( "freshestCRL.distributionPoint.distributionPoint" )
1722  ENCODING_TAGGED( SEQUENCE, 0 ),
1723  0, FL_OPTIONAL, RANGE_NONE },
1724  { NULL, 0,
1725  DESCRIPTION( "freshestCRL.distributionPoint.distributionPoint.fullName" )
1726  ENCODING_TAGGED( SEQUENCE, 0 ),
1727  0, FL_SETOF, RANGE_NONE },
1729  DESCRIPTION( "freshestCRL.distributionPoint.distributionPoint.fullName.generalName" )
1730  ENCODING_SPECIAL( SUBTYPED ),
1731  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_2, ENCODED_OBJECT( generalNameInfo ) },
1733  DESCRIPTION( "freshestCRL.distributionPoint.reasons" )
1734  ENCODING_TAGGED( BITSTRING, 1 ),
1736  { NULL, 0,
1737  DESCRIPTION( "freshestCRL.distributionPoint.cRLIssuer" )
1738  ENCODING_TAGGED( SEQUENCE, 2 ),
1741  DESCRIPTION( "freshestCRL.distributionPoint.cRLIssuer.generalName" )
1742  ENCODING_SPECIAL( SUBTYPED ),
1743  FL_ATTR_ATTREND, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_2 /*or _3*/, ENCODED_OBJECT( generalNameInfo ) },
1744 
1745 #ifdef USE_REV
1746  /* orderedList:
1747 
1748  OID = 2 5 29 47
1749  ENUMERATED */
1750  { MKOID( "\x06\x03\x55\x1D\x2F" ), CRYPT_CERTINFO_ORDEREDLIST,
1751  DESCRIPTION( "orderedList" )
1752  ENCODING( ENUMERATED ),
1753  ATTR_TYPEINFO( CRL, PKIX_FULL ) | FL_ATTR_ATTREND,
1754  0, RANGE( 0, 1 ) },
1755 
1756  /* baseUpdateTime:
1757 
1758  OID = 2 5 29 51
1759  GeneralizedTime */
1760  { MKOID( "\x06\x03\x55\x1D\x33" ), CRYPT_CERTINFO_BASEUPDATETIME,
1761  DESCRIPTION( "baseUpdateTime" )
1762  ENCODING( TIME_GENERALIZED ),
1763  ATTR_TYPEINFO( CRL, PKIX_FULL ),
1765 
1766  /* deltaInfo:
1767 
1768  OID = 2 5 29 53
1769  SEQUENCE {
1770  deltaLocation GeneralName,
1771  nextDelta GeneralizedTime OPTIONAL
1772  } */
1773  { MKOID( "\x06\x03\x55\x1D\x35" ), CRYPT_CERTINFO_DELTAINFO,
1774  DESCRIPTION( "deltaInfo" )
1775  ENCODING( SEQUENCE ),
1776  ATTR_TYPEINFO( CRL, PKIX_FULL ),
1777  0, RANGE_NONE },
1779  DESCRIPTION( "deltaInfo.deltaLocation" )
1780  ENCODING_SPECIAL( SUBTYPED ),
1781  0, 0, ENCODED_OBJECT( generalNameInfo ) },
1783  DESCRIPTION( "deltaInfo.nextDelta" )
1784  ENCODING( TIME_GENERALIZED ),
1786 #endif /* USE_REV */
1787 
1788  /* inhibitAnyPolicy:
1789 
1790  OID = 2 5 29 54
1791  INTEGER */
1792  { MKOID( "\x06\x03\x55\x1D\x36" ), CRYPT_CERTINFO_INHIBITANYPOLICY,
1793  DESCRIPTION( "inhibitAnyPolicy" )
1794  ENCODING( INTEGER ),
1795  ATTR_TYPEINFO( CERT, PKIX_FULL ) | FL_ATTR_ATTREND,
1796  0, RANGE( 0, 64 ) },
1797 
1798 #ifdef USE_REV
1799  /* toBeRevoked:
1800 
1801  OID = 2 5 29 58
1802  SEQUENCE OF SEQUENCE {
1803  certificateIssuer [ 0 ] GeneralName OPTIONAL,
1804  reasonInfo [ 1 ] SEQUENCE {
1805  reasonCode ENUMERATED
1806  } OPTIONAL,
1807  revocationTime GeneralizedTime,
1808  certificateGroup [ 0 ] EXPLICIT SEQUENCE OF {
1809  certificateSerialNumber
1810  INTEGER
1811  }
1812  }
1813 
1814  Although the certificateSerialNumber should be an INTEGER it's really
1815  an INTEGER equivalent of an OCTET STRING hole so we call it an OCTET
1816  STRING to make sure that it gets handled appropriately */
1817  { MKOID( "\x06\x03\x55\x1D\x3A" ), CRYPT_CERTINFO_TOBEREVOKED,
1818  DESCRIPTION( "toBeRevoked" )
1819  ENCODING( SEQUENCE ),
1820  ATTR_TYPEINFO( CRL, PKIX_FULL ),
1821  0, RANGE_NONE },
1822  { NULL, 0,
1823  DESCRIPTION( "toBeRevoked.group" )
1824  ENCODING( SEQUENCE ),
1827  DESCRIPTION( "toBeRevoked.group.certificateIssuer" )
1828  ENCODING_SPECIAL( SUBTYPED ),
1829  0, FL_OPTIONAL | FL_MULTIVALUED, ENCODED_OBJECT( generalNameInfo ) },
1830  { NULL, 0,
1831  DESCRIPTION( "toBeRevoked.group.reasonInfo" )
1832  ENCODING_TAGGED( SEQUENCE, 1 ),
1835  DESCRIPTION( "toBeRevoked.group.reasonInfo.reasonCode" )
1836  ENCODING( ENUMERATED ),
1839  DESCRIPTION( "toBeRevoked.group.revocationTime" )
1840  ENCODING( TIME_UTC ),
1841  0, FL_MULTIVALUED, RANGE_TIME },
1842  { NULL, 0,
1843  DESCRIPTION( "toBeRevoked.group.certificateGroup" )
1844  ENCODING_TAGGED( SEQUENCE, 0 ),
1847  DESCRIPTION( "toBeRevoked.group.certificateGroup.certificateSerialNumber" )
1848  ENCODING_TAGGED( OCTETSTRING, BER_INTEGER ), /* Actually an INTEGER hole */
1850 
1851  /* revokedGroups:
1852 
1853  OID = 2 5 29 59
1854  SEQUENCE {
1855  certificateIssuer [ 0 ] GeneralName OPTIONAL,
1856  reasonInfo [ 1 ] SEQUENCE {
1857  reasonCode ENUMERATED
1858  } OPTIONAL,
1859  invalidityDate [ 2 ] GeneralizedTime OPTIONAL,
1860  revokedCertificateGroup [ 3 ] EXPLICIT SEQUENCE {
1861  startingNumber[ 0 ] INTEGER,
1862  endingNumber [ 1 ] INTEGER
1863  }
1864  }
1865 
1866  Although the revokedCertificateGroup serial numbers should INTEGERs
1867  they're really the INTEGER equivalent of OCTET STRING holes so we
1868  call them OCTET STRINGs to make sure that they get handled
1869  appropriately */
1870  { MKOID( "\x06\x03\x55\x1D\x3B" ), CRYPT_CERTINFO_REVOKEDGROUPS,
1871  DESCRIPTION( "revokedGroups" )
1872  ENCODING( SEQUENCE ),
1873  ATTR_TYPEINFO( CRL, PKIX_FULL ),
1874  0, RANGE_NONE },
1876  DESCRIPTION( "revokedGroups.certificateIssuer" )
1877  ENCODING_SPECIAL( SUBTYPED ),
1878  0, FL_OPTIONAL | FL_MULTIVALUED, ENCODED_OBJECT( generalNameInfo ) },
1879  { NULL, 0,
1880  DESCRIPTION( "revokedGroups.reasonInfo" )
1881  ENCODING_TAGGED( SEQUENCE, 1 ),
1882  0, FL_OPTIONAL, RANGE_NONE }
1884  DESCRIPTION( "revokedGroups.reasonCode" )
1885  ENCODING( ENUMERATED ),
1888  DESCRIPTION( "revokedGroups.revocationTime" )
1889  ENCODING_TAGGED( TIME_GENERALIZED, 2 ),
1890  0, FL_OPTIONAL, RANGE_TIME },
1891  { NULL, 0,
1892  DESCRIPTION( "revokedGroups.revokedCertificateGroup" )
1893  ENCODING_TAGGED( SEQUENCE, 3 ),
1894  0, FL_EXPLICIT, RANGE_NONE }
1896  DESCRIPTION( "revokedGroups.revokedCertificateGroup.startingNumber" )
1897  ENCODING_TAGGED( OCTETSTRING, BER_INTEGER ), /* Actually an INTEGER hole */
1898  0, 0, RANGE( 1, 64 ) },
1900  DESCRIPTION( "revokedGroups.revokedCertificateGroup.endingNumber" )
1901  ENCODING_TAGGED( OCTETSTRING, BER_INTEGER ), /* Actually an INTEGER hole */
1902  FL_ATTR_ATTREND, FL_SEQEND_2, RANGE( 1, 64 ) },
1903 
1904  /* expiredCertsOnCRL:
1905 
1906  OID = 2 5 29 60
1907  GeneralizedTime */
1908  { MKOID( "\x06\x03\x55\x1D\x3C" ), CRYPT_CERTINFO_EXPIREDCERTSONCRL,
1909  DESCRIPTION( "expiredCertsOnCRL" )
1910  ENCODING( TIME_GENERALIZED ),
1911  ATTR_TYPEINFO( CRL, PKIX_FULL ),
1913 
1914  /* aaIssuingDistributionPoint:
1915 
1916  OID = 2 5 29 63
1917  critical = TRUE
1918  SEQUENCE {
1919  distributionPoint [ 0 ] {
1920  fullName [ 0 ] EXPLICIT GeneralName -- CHOICE ...
1921  } OPTIONAL,
1922  onlySomeReasons [ 1 ] BITSTRING OPTIONAL,
1923  indirectCRL [ 2 ] BOOLEAN DEFAULT FALSE
1924  containsUserAttributeCerts
1925  [ 3 ] BOOLEAN DEFAULT TRUE,
1926  containsAACerts [ 4 ] BOOLEAN DEFAULT TRUE,
1927  containsSOAPublicKeyCerts
1928  [ 5 ] BOOLEAN DEFAULT TRUE
1929  } */
1930  { MKOID( "\x06\x03\x55\x1D\x3F" ), CRYPT_CERTINFO_AAISSUINGDISTRIBUTIONPOINT,
1931  DESCRIPTION( "aaIssuingDistributionPoint" )
1932  ENCODING( SEQUENCE ),
1933  ATTR_TYPEINFO_CRITICAL( CRL, PKIX_PARTIAL ),
1934  0, RANGE_NONE },
1935  { NULL, 0,
1936  DESCRIPTION( "aaIssuingDistributionPoint.distributionPoint" )
1937  ENCODING_TAGGED( SEQUENCE, 0 ),
1938  0, FL_OPTIONAL, RANGE_NONE },
1939  { NULL, 0,
1940  DESCRIPTION( "aaIssuingDistributionPoint.distributionPoint.fullName" )
1941  ENCODING_TAGGED( SEQUENCE, 0 ),
1942  0, 0, RANGE_NONE },
1944  DESCRIPTION( "aaIssuingDistributionPoint.distributionPoint.fullName.generalName" )
1945  ENCODING_SPECIAL( SUBTYPED ),
1946  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND_3, ENCODED_OBJECT( generalNameInfo ) },
1948  DESCRIPTION( "aaIssuingDistributionPoint.onlySomeReasons" )
1949  ENCODING_TAGGED( BITSTRING, 1 ),
1952  DESCRIPTION( "aaIssuingDistributionPoint.indirectCRL" )
1953  ENCODING_TAGGED( BOOLEAN, 2 ),
1956  DESCRIPTION( "aaIssuingDistributionPoint.containsUserAttributeCerts" )
1957  ENCODING_TAGGED( BOOLEAN, 3 ),
1960  DESCRIPTION( "aaIssuingDistributionPoint.containsAACerts" )
1961  ENCODING_TAGGED( BOOLEAN, 4 ),
1964  DESCRIPTION( "aaIssuingDistributionPoint.containsSOAPublicKeyCerts" )
1965  ENCODING_TAGGED( BOOLEAN, 5 ),
1967 #endif /* USE_REV */
1968 #endif /* USE_CERTLEVEL_PKIX_FULL */
1969 
1970 #ifdef USE_CERT_OBSOLETE
1971  /* netscape-cert-type:
1972 
1973  OID = 2 16 840 1 113730 1 1
1974  BITSTRING */
1975  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x01" ), CRYPT_CERTINFO_NS_CERTTYPE,
1976  DESCRIPTION( "netscape-cert-type" )
1977  ENCODING( BITSTRING ),
1978  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
1979  0, RANGE( 0, CRYPT_NS_CERTTYPE_LAST ) },
1980 
1981  /* netscape-base-url:
1982 
1983  OID = 2 16 840 1 113730 1 2
1984  IA5String */
1985  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x02" ), CRYPT_CERTINFO_NS_BASEURL,
1986  DESCRIPTION( "netscape-base-url" )
1987  ENCODING( STRING_IA5 ),
1988  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
1989  0, CHECK_HTTP },
1990 
1991  /* netscape-revocation-url:
1992 
1993  OID = 2 16 840 1 113730 1 3
1994  IA5String */
1995  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x03" ), CRYPT_CERTINFO_NS_REVOCATIONURL,
1996  DESCRIPTION( "netscape-revocation-url" )
1997  ENCODING( STRING_IA5 ),
1998  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
1999  0, CHECK_HTTP },
2000 
2001  /* netscape-ca-revocation-url:
2002 
2003  OID = 2 16 840 1 113730 1 3
2004  IA5String */
2005  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x04" ), CRYPT_CERTINFO_NS_CAREVOCATIONURL,
2006  DESCRIPTION( "netscape-ca-revocation-url" )
2007  ENCODING( STRING_IA5 ),
2008  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
2009  0, CHECK_HTTP },
2010 
2011  /* netscape-ca-revocation-url:
2012 
2013  OID = 2 16 840 1 113730 11 7
2014  IA5String */
2015  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x07" ), CRYPT_CERTINFO_NS_CERTRENEWALURL,
2016  DESCRIPTION( "netscape-ca-revocation-url" )
2017  ENCODING( STRING_IA5 ),
2018  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
2019  0, CHECK_HTTP },
2020 
2021  /* netscape-ca-policy-url:
2022 
2023  OID = 2 16 840 1 113730 1 8
2024  IA5String */
2025  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x08" ), CRYPT_CERTINFO_NS_CAPOLICYURL,
2026  DESCRIPTION( "netscape-ca-policy-url" )
2027  ENCODING( STRING_IA5 ),
2028  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
2029  0, CHECK_HTTP },
2030 
2031  /* netscape-ssl-server-name:
2032 
2033  OID = 2 16 840 1 113730 1 12
2034  IA5String */
2035  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x0C" ), CRYPT_CERTINFO_NS_SSLSERVERNAME,
2036  DESCRIPTION( "netscape-ssl-server-name" )
2037  ENCODING( STRING_IA5 ),
2038  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
2039  0, CHECK_DNS },
2040 
2041  /* netscape-comment:
2042 
2043  OID = 2 16 840 1 113730 1 13
2044  IA5String */
2045  { MKOID( "\x06\x09\x60\x86\x48\x01\x86\xF8\x42\x01\x0D" ), CRYPT_CERTINFO_NS_COMMENT,
2046  DESCRIPTION( "netscape-comment" )
2047  ENCODING( STRING_IA5 ),
2048  ATTR_TYPEINFO( CERT, STANDARD ) | FL_ATTR_ATTREND,
2049  0, RANGE_ATTRIBUTEBLOB },
2050 #endif /* USE_CERT_OBSOLETE */
2051 
2052 #ifdef USE_CERT_OBSOLETE
2053  /* hashedRootKey (SET):
2054 
2055  OID = 2 23 42 7 0
2056  critical = TRUE
2057  SEQUENCE {
2058  rootKeyThumbprint DigestedData -- PKCS #7-type wrapper
2059  } */
2060  { MKOID( "\x06\x04\x67\x2A\x07\x00" ), CRYPT_CERTINFO_SET_HASHEDROOTKEY,
2061  DESCRIPTION( "hashedRootKey" )
2062  ENCODING( SEQUENCE ),
2063  ATTR_TYPEINFO_CRITICAL( CERT, PKIX_PARTIAL ),
2064  0, RANGE_NONE },
2065  { NULL, 0,
2066  DESCRIPTION( "hashedRootKey.rootKeyThumbprint" )
2067  ENCODING_SPECIAL( BLOB_SEQUENCE ), /* PKCS #7-type wrapper */
2068  0, FL_NONENCODING, 0, 0, 25,
2069  "\x30\x2D\x02\x01\x00\x30\x09\x06\x05\x2B\x0E\x03\x02\x1A\x05\x00\x30\x07\x06\x05\x67\x2A\x03\x00\x00" },
2071  DESCRIPTION( "hashedRootKey.rootKeyThumbprint.hashData" )
2072  ENCODING( OCTETSTRING ),
2073  FL_ATTR_ATTREND, FL_SEQEND /*NONE*/, RANGE( 20, 20 ) },
2074 
2075  /* certificateType (SET):
2076 
2077  OID = 2 23 42 7 1
2078  critical = TRUE
2079  BIT STRING */
2080  { MKOID( "\x06\x04\x67\x2A\x07\x01" ), CRYPT_CERTINFO_SET_CERTIFICATETYPE,
2081  DESCRIPTION( "certificateType" )
2082  ENCODING( BITSTRING ),
2083  ATTR_TYPEINFO_CRITICAL( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
2084  0, RANGE( 0, CRYPT_SET_CERTTYPE_LAST ) },
2085 
2086  /* merchantData (SET):
2087 
2088  OID = 2 23 42 7 2
2089  SEQUENCE {
2090  merID SETString SIZE(1..30),
2091  merAcquirerBIN NumericString SIZE(6),
2092  merNameSeq SEQUENCE OF MerNames,
2093  merCountry INTEGER (1..999),
2094  merAuthFlag BOOLEAN DEFAULT TRUE
2095  }
2096 
2097  MerNames ::= SEQUENCE {
2098  language [ 0 ] VisibleString SIZE(1..35),
2099  name [ 1 ] EXPLICIT SETString SIZE(1..50),
2100  city [ 2 ] EXPLICIT SETString SIZE(1..50),
2101  stateProvince [ 3 ] EXPLICIT SETString SIZE(1..50) OPTIONAL,
2102  postalCode [ 4 ] EXPLICIT SETString SIZE(1..14) OPTIONAL,
2103  countryName [ 5 ] EXPLICIT SETString SIZE(1..50)
2104  } */
2105  { MKOID( "\x06\x04\x67\x2A\x07\x02" ), CRYPT_CERTINFO_SET_MERCHANTDATA,
2106  DESCRIPTION( "merchantData" )
2107  ENCODING( SEQUENCE ),
2108  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
2109  0, RANGE_NONE },
2110  { NULL, CRYPT_CERTINFO_SET_MERID,
2111  DESCRIPTION( "merchantData.merID" )
2112  ENCODING( STRING_ISO646 ),
2113  0, 0, RANGE( 1, 30 ) },
2115  DESCRIPTION( "merchantData.merAcquirerBIN" )
2116  ENCODING( STRING_NUMERIC ),
2117  0, 0, RANGE( 6, 6 ) },
2118  { NULL, 0,
2119  DESCRIPTION( "merchantData.merNameSeq" )
2120  ENCODING( SEQUENCE ),
2121  0, FL_SETOF, RANGE_NONE },
2122  { NULL, 0,
2123  DESCRIPTION( "merchantData.merNameSeq.merNames" )
2124  ENCODING( SEQUENCE ),
2125  0, 0, RANGE_NONE },
2127  DESCRIPTION( "merchantData.merNameSeq.merNames.language" )
2128  ENCODING_TAGGED( STRING_ISO646, 0 ),
2129  0, FL_MULTIVALUED, RANGE( 1, 35 ) },
2131  DESCRIPTION( "merchantData.merNameSeq.merNames.name" )
2132  ENCODING_TAGGED( STRING_ISO646, 1 ),
2133  0, FL_MULTIVALUED | FL_EXPLICIT, RANGE( 1, 50 ) },
2135  DESCRIPTION( "merchantData.merNameSeq.merNames.city" )
2136  ENCODING_TAGGED( STRING_ISO646, 2 ),
2137  0, FL_MULTIVALUED | FL_EXPLICIT, RANGE( 1, 50 ) },
2139  DESCRIPTION( "merchantData.merNameSeq.merNames.stateProvince" )
2140  ENCODING_TAGGED( STRING_ISO646, 3 ),
2141  0, FL_MULTIVALUED | FL_EXPLICIT | FL_OPTIONAL, RANGE( 1, 50 ) },
2143  DESCRIPTION( "merchantData.merNameSeq.merNames.postalCode" )
2144  ENCODING_TAGGED( STRING_ISO646, 4 ),
2145  0, FL_MULTIVALUED | FL_EXPLICIT | FL_OPTIONAL, RANGE( 1, 50 ) },
2147  DESCRIPTION( "merchantData.merNameSeq.merNames.countryName" )
2148  ENCODING_TAGGED( STRING_ISO646, 5 ),
2149  0, FL_MULTIVALUED | FL_EXPLICIT | FL_SEQEND_2, RANGE( 1, 50 ) },
2151  DESCRIPTION( "merchantData.merCountry" )
2152  ENCODING( INTEGER ),
2153  0, 0, RANGE( 1, 999 ) },
2155  DESCRIPTION( "merchantData.merAuthFlag" )
2156  ENCODING( BOOLEAN ),
2158 
2159  /* certCardRequired (SET):
2160 
2161  OID = 2 23 42 7 3
2162  BOOLEAN */
2163  { MKOID( "\x06\x04\x67\x2A\x07\x03" ), CRYPT_CERTINFO_SET_CERTCARDREQUIRED,
2164  DESCRIPTION( "certCardRequired" )
2165  ENCODING( BOOLEAN ),
2166  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ) | FL_ATTR_ATTREND,
2167  0, RANGE_BOOLEAN },
2168 
2169  /* tunneling (SET):
2170 
2171  OID = 2 23 42 7 4
2172  SEQUENCE {
2173  tunneling DEFAULT TRUE,
2174  tunnelAlgIDs SEQUENCE OF OBJECT IDENTIFIER
2175  } */
2176  { MKOID( "\x06\x04\x67\x2A\x07\x04" ), CRYPT_CERTINFO_SET_TUNNELING,
2177  DESCRIPTION( "tunneling" )
2178  ENCODING( SEQUENCE ),
2179  ATTR_TYPEINFO( CERT, PKIX_PARTIAL ),
2180  0, RANGE_NONE },
2182  DESCRIPTION( "tunneling.tunneling" )
2183  ENCODING( BOOLEAN ),
2184  0, FL_OPTIONAL | FL_DEFAULT, FALSE, TRUE, TRUE },
2185  { NULL, 0,
2186  DESCRIPTION( "tunneling.tunnelingAlgIDs" )
2187  ENCODING( SEQUENCE ),
2188  0, FL_SETOF, RANGE_NONE },
2190  DESCRIPTION( "tunneling.tunnelingAlgIDs.tunnelingAlgID" )
2191  ENCODING( OBJECT_IDENTIFIER ),
2193 #endif /* USE_CERT_OBSOLETE */
2194 
2195  { NULL, CRYPT_ERROR }, { NULL, CRYPT_ERROR }
2196  };
2197 
2198 #if ( defined( USE_CERTREV ) || defined( USE_CERTREQ ) ) && \
2199  defined( USE_CERTLEVEL_PKIX_FULL )
2200 
2201 /* Subtable for encoding the holdInstructionCode */
2202 
2203 STATIC_DATA const ATTRIBUTE_INFO FAR_BSS holdInstructionInfo[] = {
2204  { MKOID( "\x06\x07\x2A\x86\x48\xCE\x38\x02\x01" ), CRYPT_HOLDINSTRUCTION_NONE,
2205  DESCRIPTION( "holdInstructionCode.holdinstruction-none (1 2 840 10040 2 1)" )
2206  ENCODING_SPECIAL( IDENTIFIER ),
2208  { MKOID( "\x06\x07\x2A\x86\x48\xCE\x38\x02\x02" ), CRYPT_HOLDINSTRUCTION_CALLISSUER,
2209  DESCRIPTION( "holdInstructionCode.holdinstruction-callissuer (1 2 840 10040 2 2)" )
2210  ENCODING_SPECIAL( IDENTIFIER ),
2211  0, FL_OPTIONAL, RANGE_NONE },
2212  { MKOID( "\x06\x07\x2A\x86\x48\xCE\x38\x02\x03" ), CRYPT_HOLDINSTRUCTION_REJECT,
2213  DESCRIPTION( "holdInstructionCode.holdinstruction-reject (1 2 840 10040 2 3)" )
2214  ENCODING_SPECIAL( IDENTIFIER ),
2215  0, FL_OPTIONAL, RANGE_NONE },
2216  { MKOID( "\x06\x07\x2A\x86\x48\xCE\x38\x02\x04" ), CRYPT_HOLDINSTRUCTION_PICKUPTOKEN,
2217  DESCRIPTION( "holdInstructionCode.holdinstruction-pickupToken (1 2 840 10040 2 4)" )
2218  ENCODING_SPECIAL( IDENTIFIER ),
2220 
2221  { NULL, CRYPT_ERROR }, { NULL, CRYPT_ERROR }
2222  };
2223 #endif /* ( USE_CERTREV || USE_CERTREQ ) && USE_CERTLEVEL_PKIX_FULL */
2224 
2225 /****************************************************************************
2226 * *
2227 * GeneralName Definition *
2228 * *
2229 ****************************************************************************/
2230 
2231 /* Encoding and decoding of GeneralNames is performed with the following
2232  subtable:
2233 
2234  otherName [ 0 ] SEQUENCE {
2235  type-id OBJECT IDENTIFIER,
2236  value [ 0 ] EXPLICIT ANY DEFINED BY type-id
2237  } OPTIONAL,
2238  rfc822Name [ 1 ] IA5String OPTIONAL,
2239  dNSName [ 2 ] IA5String OPTIONAL,
2240  x400Address [ 3 ] ITU-BrainDamage OPTIONAL
2241  directoryName [ 4 ] EXPLICIT Name OPTIONAL,
2242  ediPartyName [ 5 ] SEQUENCE {
2243  nameAssigner [ 0 ] EXPLICIT DirectoryString OPTIONAL,
2244  partyName [ 1 ] EXPLICIT DirectoryString
2245  } OPTIONAL,
2246  uniformResourceIdentifier
2247  [ 6 ] IA5String OPTIONAL,
2248  iPAddress [ 7 ] OCTET STRING OPTIONAL,
2249  registeredID [ 8 ] OBJECT IDENTIFIER OPTIONAL
2250 
2251  ITU-Braindamge ::= SEQUENCE {
2252  built-in-standard-attributes SEQUENCE {
2253  country-name [ APPLICATION 1 ] CHOICE {
2254  x121-dcc-code NumericString,
2255  iso-3166-alpha2-code PrintableString
2256  },
2257  administration-domain-name
2258  [ APPLICATION 2 ] CHOICE {
2259  numeric NumericString,
2260  printable PrintableString
2261  },
2262  network-address [ 0 ] NumericString OPTIONAL,
2263  terminal-identifier [ 1 ] PrintableString OPTIONAL,
2264  private-domain-name [ 2 ] CHOICE {
2265  numeric NumericString,
2266  printable PrintableString
2267  } OPTIONAL,
2268  organization-name [ 3 ] PrintableString OPTIONAL,
2269  numeric-use-identifier [ 4 ] NumericString OPTIONAL,
2270  personal-name [ 5 ] SET {
2271  surname [ 0 ] PrintableString,
2272  given-name [ 1 ] PrintableString,
2273  initials [ 2 ] PrintableString,
2274  generation-qualifier [ 3 ] PrintableString
2275  } OPTIONAL,
2276  organizational-unit-name [ 6 ] PrintableString OPTIONAL,
2277  }
2278  built-in-domain-defined-attributes SEQUENCE OF {
2279  type PrintableString SIZE(1..64),
2280  value PrintableString SIZE(1..64)
2281  } OPTIONAL
2282  extensionAttributes SET OF SEQUENCE {
2283  extension-attribute-type [ 0 ] INTEGER,
2284  extension-attribute-value [ 1 ] ANY DEFINED BY extension-attribute-type
2285  } OPTIONAL
2286  }
2287 
2288  Needless to say X.400 addresses aren't supported (for readers who've
2289  never seen one before you now know why they've been so enormously
2290  successful).
2291 
2292  Note the special-case encoding of the DirectoryName and EDIPartyName.
2293  This is required because (for the DirectoryName) a Name is actually a
2294  CHOICE { RDNSequence } and if the tagging were implicit then there'd be
2295  no way to tell which of the CHOICE options was being used:
2296 
2297  directoryName [ 4 ] Name OPTIONAL
2298 
2299  becomes:
2300 
2301  directoryName [ 4 ] CHOICE { RDNSequence } OPTIONAL
2302 
2303  which, if implicit tagging is used, would replace the RDNSequence tag with
2304  the [4] tag, making it impossible to determine which of the Name choices
2305  was used (actually there's only one possibility and it's unlikely that
2306  there'll ever be more but that's what the encoding rules require - X.208,
2307  section 26.7c).
2308 
2309  The same applies to the EDIPartyName, this is a DirectoryString which is
2310  a CHOICE of several possible string types. The end result is that:
2311 
2312  [ 0 ] DirectoryString
2313 
2314  ends up looking like:
2315 
2316  [ 0 ] SEQUENCE {
2317  option1 PrintableString OPTIONAL,
2318  option2 T61String OPTIONAL,
2319  option3 UTF8String OPTIONAL,
2320  option4 BMPString OPTIONAL
2321  }
2322 
2323  Newer versions of the PKIX core RFC allow the use of 8- and 32-byte CIDR
2324  forms for 4- and 16-byte IP addresses in some instances when they're
2325  being used as constraints. We'll add support for this if anyone ever
2326  asks for it */
2327 
2328 STATIC_DATA const ATTRIBUTE_INFO FAR_BSS generalNameInfo[] = {
2329  /* otherName */
2330  { NULL, FIELDID_FOLLOWS,
2331  DESCRIPTION( "generalName.otherName" )
2332  ENCODING_TAGGED( SEQUENCE, 0 ),
2335  DESCRIPTION( "generalName.otherName.type-id" )
2336  ENCODING( OBJECT_IDENTIFIER ),
2337  0, FL_OPTIONAL, RANGE_OID },
2339  DESCRIPTION( "generalName.otherName.value" )
2340  ENCODING_SPECIAL_TAGGED( BLOB_ANY, 0 ),
2342 
2343  /* rfc822Name */
2344  { NULL, CRYPT_CERTINFO_RFC822NAME,
2345  DESCRIPTION( "generalName.rfc822Name" )
2346  ENCODING_TAGGED( STRING_IA5, 1 ),
2347  0, FL_OPTIONAL, CHECK_RFC822 },
2348 
2349  /* dNSName */
2350  { NULL, CRYPT_CERTINFO_DNSNAME,
2351  DESCRIPTION( "generalName.dNSName" )
2352  ENCODING_TAGGED( STRING_IA5, 2 ),
2353  0, FL_OPTIONAL, CHECK_DNS },
2354 
2355  /* directoryName */
2356 #if 0 /* 28/4/08 This form seems to have worked purely by coincidence... */
2357  { NULL, 0,
2358  DESCRIPTION( "generalName.directoryName" )
2359  ENCODING_TAGGED( SEQUENCE, 4 ),
2360  0, FL_OPTIONAL, RANGE_NONE },
2362  DESCRIPTION( "generalName.directoryName.name" )
2364  0, FL_OPTIONAL | FL_ALIAS | FL_SEQEND, CHECK_X500 },
2365 #else
2367  DESCRIPTION( "generalName.directoryName" )
2368  ENCODING_SPECIAL_TAGGED( DN, 4 ),
2370 #endif /* 0 */
2371 
2372  /* ediPartyName */
2373  { NULL, 0,
2374  DESCRIPTION( "generalName.ediPartyName" )
2375  ENCODING_TAGGED( SEQUENCE, 5 ),
2376  0, FL_OPTIONAL, RANGE_NONE },
2377  { NULL, 0,
2378  DESCRIPTION( "generalName.ediPartyName.nameAssigner" )
2379  ENCODING_TAGGED( SEQUENCE, 0 ),
2381  /* See note above on why the extra SEQUENCE is present */
2383  DESCRIPTION( "generalName.ediPartyName.nameAssigner.directoryName" )
2384  ENCODING_SPECIAL( TEXTSTRING ),
2386  { NULL, 0,
2387  DESCRIPTION( "generalName.ediPartyName.partyName" )
2388  ENCODING_TAGGED( SEQUENCE, 1 ),
2391  DESCRIPTION( "generalName.ediPartyName.partyName.directoryName" )
2392  ENCODING_SPECIAL( TEXTSTRING ),
2394 
2395  /* uniformResourceIdentifier */
2397  DESCRIPTION( "generalName.uniformResourceIdentifier" )
2398  ENCODING_TAGGED( STRING_IA5, 6 ),
2399  0, FL_OPTIONAL, CHECK_URL },
2400 
2401  /* iPAddress */
2402  { NULL, CRYPT_CERTINFO_IPADDRESS,
2403  DESCRIPTION( "generalName.iPAddress" )
2405  0, FL_OPTIONAL, RANGE( 4, 16 ) },
2406 
2407  /* registeredID */
2409  DESCRIPTION( "generalName.registeredID" )
2410  ENCODING_TAGGED( OBJECT_IDENTIFIER, 8 ),
2412 
2413  { NULL, CRYPT_ERROR }, { NULL, CRYPT_ERROR }
2414  };
2415 
2416 /****************************************************************************
2417 * *
2418 * CMS Attribute Definitions *
2419 * *
2420 ****************************************************************************/
2421 
2422 /* CMS attributes are encoded using the following table */
2423 
2424 static const ATTRIBUTE_INFO FAR_BSS cmsAttributeInfo[] = {
2425  /* contentType:
2426 
2427  OID = 1 2 840 113549 1 9 3
2428  OBJECT IDENTIFIER */
2429  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03" ), CRYPT_CERTINFO_CMS_CONTENTTYPE,
2430  DESCRIPTION( "contentType" )
2431  ENCODING_SPECIAL( CHOICE ),
2433  0, CRYPT_CONTENT_DATA, CRYPT_CONTENT_LAST, 0, ( void * ) contentTypeInfo },
2434 
2435  /* messageDigest:
2436 
2437  OID = 1 2 840 113549 1 9 4
2438  OCTET STRING */
2439  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04" ), CRYPT_CERTINFO_CMS_MESSAGEDIGEST,
2440  DESCRIPTION( "messageDigest" )
2441  ENCODING( OCTETSTRING ),
2443  0, RANGE( 16, CRYPT_MAX_HASHSIZE ) },
2444 
2445  /* signingTime:
2446 
2447  OID = 1 2 840 113549 1 9 5
2448  CHOICE {
2449  utcTime UTCTime, -- Up to 2049
2450  generalizedTime GeneralizedTime
2451  } */
2452  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x05" ), CRYPT_CERTINFO_CMS_SIGNINGTIME,
2453  DESCRIPTION( "signingTime" )
2454  ENCODING( TIME_UTC ),
2456  0, RANGE_TIME },
2457 
2458 #ifdef USE_CMSATTR_OBSCURE
2459  /* counterSignature:
2460 
2461  OID = 1 2 840 113549 1 9 6
2462  CHOICE {
2463  utcTime UTCTime, -- Up to 2049
2464  generalizedTime GeneralizedTime
2465  }
2466 
2467  This field isn't an authenticated attribute so it isn't used */
2468  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x06" ), CRYPT_CERTINFO_CMS_COUNTERSIGNATURE,
2469  DESCRIPTION( "counterSignature" )
2470  ENCODING( NULL ), /* Dummy value */
2472  0, RANGE_NONE },
2473 
2474  /* signingDescription:
2475 
2476  OID = 1 2 840 113549 1 9 13
2477  UTF8String */
2478  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0D" ), CRYPT_CERTINFO_CMS_SIGNINGDESCRIPTION,
2479  DESCRIPTION( "signingDescription" )
2480  ENCODING( STRING_UTF8 ),
2482  0, RANGE_ATTRIBUTEBLOB },
2483 #endif /* USE_CMSATTR_OBSCURE */
2484 
2485  /* sMIMECapabilities:
2486 
2487  OID = 1 2 840 113549 1 9 15
2488  SEQUENCE OF {
2489  SEQUENCE {
2490  capabilityID OBJECT IDENTIFIER,
2491  parameters ANY DEFINED BY capabilityID
2492  }
2493  } */
2494  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0F" ), CRYPT_CERTINFO_CMS_SMIMECAPABILITIES,
2495  DESCRIPTION( "sMIMECapabilities" )
2496  ENCODING( SEQUENCE ),
2498  FL_SETOF, RANGE_NONE },
2499  { NULL, 0,
2500  DESCRIPTION( "sMIMECapabilities.capability (des-EDE3-CBC)" )
2501  ENCODING( SEQUENCE ),
2502  0, FL_IDENTIFIER, RANGE_NONE },
2503  { MKOID( "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x03\x07" ), CRYPT_CERTINFO_CMS_SMIMECAP_3DES,
2504  DESCRIPTION( "sMIMECapabilities.capability.des-EDE3-CBC" )
2505  ENCODING_SPECIAL( IDENTIFIER ),
2507  { NULL, 0,
2508  DESCRIPTION( "sMIMECapabilities.capability (aes128-CBC)" )
2509  ENCODING( SEQUENCE ),
2510  0, FL_IDENTIFIER, RANGE_NONE },
2511  { MKOID( "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x02" ), CRYPT_CERTINFO_CMS_SMIMECAP_AES,
2512  DESCRIPTION( "sMIMECapabilities.capability.aes128-CBC" )
2513  ENCODING_SPECIAL( IDENTIFIER ),
2515  { NULL, 0,
2516  DESCRIPTION( "sMIMECapabilities.capability (cast5CBC)" )
2517  ENCODING( SEQUENCE ),
2518  0, FL_IDENTIFIER, RANGE_NONE },
2519  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A" ), CRYPT_CERTINFO_CMS_SMIMECAP_CAST128,
2520  DESCRIPTION( "sMIMECapabilities.capability.cast5CBC" )
2521  ENCODING_SPECIAL( IDENTIFIER ),
2522  0, FL_NONENCODING, RANGE_NONE },
2523  { NULL, 0,
2524  DESCRIPTION( "sMIMECapabilities.capability.cast5CBC.parameter" )
2525  ENCODING_SPECIAL( BLOB_ANY ), /* 128-bit key */
2526  0, FL_NONENCODING | FL_SEQEND, 0, 0, 4, "\x02\x02\x00\x80" },
2527  { NULL, 0,
2528  DESCRIPTION( "sMIMECapabilities.capability (ideaCBC)" )
2529  ENCODING( SEQUENCE ),
2530  0, FL_IDENTIFIER, RANGE_NONE },
2531  { MKOID( "\x06\x0B\x2B\x06\x01\x04\x01\x81\x3C\x07\x01\x01\x02" ), CRYPT_CERTINFO_CMS_SMIMECAP_IDEA,
2532  DESCRIPTION( "sMIMECapabilities.capability.ideaCBC (Ascom Tech variant)" )
2533  ENCODING_SPECIAL( IDENTIFIER ),
2535  { NULL, 0,
2536  DESCRIPTION( "sMIMECapabilities.capability (rc2CBC)" )
2537  ENCODING( SEQUENCE ),
2538  0, FL_IDENTIFIER, RANGE_NONE },
2539  { MKOID( "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x03\x02" ), CRYPT_CERTINFO_CMS_SMIMECAP_RC2,
2540  DESCRIPTION( "sMIMECapabilities.capability.rc2CBC" )
2541  ENCODING_SPECIAL( IDENTIFIER ),
2542  0, FL_NONENCODING, RANGE_NONE },
2543  { NULL, 0,
2544  DESCRIPTION( "sMIMECapabilities.capability.rc2CBC.parameters" )
2545  ENCODING_SPECIAL( BLOB_ANY ), /* 128-bit key */
2546  0, FL_NONENCODING | FL_SEQEND, 0, 0, 4, "\x02\x02\x00\x80" },
2547  { NULL, 0,
2548  DESCRIPTION( "sMIMECapabilities.capability (rC5-CBCPad)" )
2549  ENCODING( SEQUENCE ),
2550  0, FL_IDENTIFIER, RANGE_NONE },
2551  { MKOID( "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x03\x09" ), CRYPT_CERTINFO_CMS_SMIMECAP_RC5,
2552  DESCRIPTION( "sMIMECapabilities.capability.rC5-CBCPad" )
2553  ENCODING_SPECIAL( IDENTIFIER ),
2554  0, FL_NONENCODING, RANGE_NONE },
2555  { NULL, 0,
2556  DESCRIPTION( "sMIMECapabilities.capability.rC5-CBCPad.parameters" )
2557  ENCODING_SPECIAL( BLOB_SEQUENCE ),/* 16-byte key, 12 rounds, 64-bit blocks */
2558  0, FL_NONENCODING | FL_SEQEND, 0, 0, 11, "\x30\x09\x02\x01\x10\x02\x01\x0C\x02\x01\x40" },
2559  { NULL, 0,
2560  DESCRIPTION( "sMIMECapabilities.capability (fortezzaConfidentialityAlgorithm)" )
2561  ENCODING( SEQUENCE ),
2562  0, FL_IDENTIFIER, RANGE_NONE },
2563  { MKOID( "\x06\x09\x60\x86\x48\x01\x65\x02\x01\x01\x04" ), CRYPT_CERTINFO_CMS_SMIMECAP_SKIPJACK,
2564  DESCRIPTION( "sMIMECapabilities.capability.fortezzaConfidentialityAlgorithm" )
2565  ENCODING_SPECIAL( IDENTIFIER ),
2567  { NULL, 0,
2568  DESCRIPTION( "sMIMECapabilities.capability (desCBC)" )
2569  ENCODING( SEQUENCE ),
2570  0, FL_IDENTIFIER, RANGE_NONE },
2571  { MKOID( "\x06\x05\x2B\x0E\x03\x02\x07" ), CRYPT_CERTINFO_CMS_SMIMECAP_DES,
2572  DESCRIPTION( "sMIMECapabilities.capability.desCBC" )
2573  ENCODING_SPECIAL( IDENTIFIER ),
2575  { NULL, 0,
2576  DESCRIPTION( "sMIMECapabilities.capability (sha-ng)" )
2577  ENCODING( SEQUENCE ),
2578  0, FL_IDENTIFIER, RANGE_NONE },
2579  { MKOID( "Unknown" ), CRYPT_CERTINFO_CMS_SMIMECAP_SHAng,
2580  DESCRIPTION( "sMIMECapabilities.capability.sha-ng" )
2581  ENCODING_SPECIAL( IDENTIFIER ),
2583  { NULL, 0,
2584  DESCRIPTION( "sMIMECapabilities.capability (sha2-256)" )
2585  ENCODING( SEQUENCE ),
2586  0, FL_IDENTIFIER, RANGE_NONE },
2587  { MKOID( "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01" ), CRYPT_CERTINFO_CMS_SMIMECAP_SHA2,
2588  DESCRIPTION( "sMIMECapabilities.capability.sha2-256" )
2589  ENCODING_SPECIAL( IDENTIFIER ),
2591  { NULL, 0,
2592  DESCRIPTION( "sMIMECapabilities.capability (sha1)" )
2593  ENCODING( SEQUENCE ),
2594  0, FL_IDENTIFIER, RANGE_NONE },
2595  { MKOID( "\x06\x05\x2B\x0E\x03\x02\x1A" ), CRYPT_CERTINFO_CMS_SMIMECAP_SHA1,
2596  DESCRIPTION( "sMIMECapabilities.capability.sha1" )
2597  ENCODING_SPECIAL( IDENTIFIER ),
2599  { NULL, 0,
2600  DESCRIPTION( "sMIMECapabilities.capability (hmac-sha-ng)" )
2601  ENCODING( SEQUENCE ),
2602  0, FL_IDENTIFIER, RANGE_NONE },
2604  DESCRIPTION( "sMIMECapabilities.capability.hmac-sha-ng" )
2605  ENCODING_SPECIAL( IDENTIFIER ),
2607  { NULL, 0,
2608  DESCRIPTION( "sMIMECapabilities.capability (hmac-sha2-256)" )
2609  ENCODING( SEQUENCE ),
2610  0, FL_IDENTIFIER, RANGE_NONE },
2611  { MKOID( "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x09" ), CRYPT_CERTINFO_CMS_SMIMECAP_HMAC_SHA2,
2612  DESCRIPTION( "sMIMECapabilities.capability.hmac-sha2-256" )
2613  ENCODING_SPECIAL( IDENTIFIER ),
2615  { NULL, 0,
2616  DESCRIPTION( "sMIMECapabilities.capability (hmac-sha1)" )
2617  ENCODING( SEQUENCE ),
2618  0, FL_IDENTIFIER, RANGE_NONE },
2619  { MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x08\x01\x02" ), CRYPT_CERTINFO_CMS_SMIMECAP_HMAC_SHA1,
2620  DESCRIPTION( "sMIMECapabilities.capability.hmac-sha1" )
2621  ENCODING_SPECIAL( IDENTIFIER ),
2623  { NULL, 0,
2624  DESCRIPTION( "sMIMECapabilities.capability (authEnc256)" )
2625  ENCODING( SEQUENCE ),
2626  0, FL_IDENTIFIER, RANGE_NONE },
2627  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x10" ), CRYPT_CERTINFO_CMS_SMIMECAP_AUTHENC256,
2628  DESCRIPTION( "sMIMECapabilities.capability.authEnc256" )
2629  ENCODING_SPECIAL( IDENTIFIER ),
2631  { NULL, 0,
2632  DESCRIPTION( "sMIMECapabilities.capability (authEnc128)" )
2633  ENCODING( SEQUENCE ),
2634  0, FL_IDENTIFIER, RANGE_NONE },
2635  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x0F" ), CRYPT_CERTINFO_CMS_SMIMECAP_AUTHENC128,
2636  DESCRIPTION( "sMIMECapabilities.capability.authEnc128" )
2637  ENCODING_SPECIAL( IDENTIFIER ),
2639  { NULL, 0,
2640  DESCRIPTION( "sMIMECapabilities.capability (rsaWithSHAng)" )
2641  ENCODING( SEQUENCE ),
2642  0, FL_IDENTIFIER, RANGE_NONE },
2644  DESCRIPTION( "sMIMECapabilities.capability.rsaWithSHAng" )
2645  ENCODING_SPECIAL( IDENTIFIER ),
2647  { NULL, 0,
2648  DESCRIPTION( "sMIMECapabilities.capability (rsaWithSHA2-256)" )
2649  ENCODING( SEQUENCE ),
2650  0, FL_IDENTIFIER, RANGE_NONE },
2651  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B" ), CRYPT_CERTINFO_CMS_SMIMECAP_RSA_SHA2,
2652  DESCRIPTION( "sMIMECapabilities.capability.rsaWithSHA2-256" )
2653  ENCODING_SPECIAL( IDENTIFIER ),
2655  { NULL, 0,
2656  DESCRIPTION( "sMIMECapabilities.capability (rsaWithSHA1)" )
2657  ENCODING( SEQUENCE ),
2658  0, FL_IDENTIFIER, RANGE_NONE },
2659  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05" ), CRYPT_CERTINFO_CMS_SMIMECAP_RSA_SHA1,
2660  DESCRIPTION( "sMIMECapabilities.capability.rsaWithSHA1" )
2661  ENCODING_SPECIAL( IDENTIFIER ),
2663  { NULL, 0,
2664  DESCRIPTION( "sMIMECapabilities.capability (dsaWithSHA1)" )
2665  ENCODING( SEQUENCE ),
2666  0, FL_IDENTIFIER, RANGE_NONE },
2667  { MKOID( "\x06\x07\x2A\x86\x48\xCE\x38\x04\x03" ), CRYPT_CERTINFO_CMS_SMIMECAP_DSA_SHA1,
2668  DESCRIPTION( "sMIMECapabilities.capability.dsaWithSHA1" )
2669  ENCODING_SPECIAL( IDENTIFIER ),
2671  { NULL, 0,
2672  DESCRIPTION( "sMIMECapabilities.capability (ecdsaWithSHA-ng)" )
2673  ENCODING( SEQUENCE ),
2674  0, FL_IDENTIFIER, RANGE_NONE },
2676  DESCRIPTION( "sMIMECapabilities.capability.ecdsaWithSHA-ng" )
2677  ENCODING_SPECIAL( IDENTIFIER ),
2679  { NULL, 0,
2680  DESCRIPTION( "sMIMECapabilities.capability (ecdsaWithSHA2-256)" )
2681  ENCODING( SEQUENCE ),
2682  0, FL_IDENTIFIER, RANGE_NONE },
2683  { MKOID( "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02" ), CRYPT_CERTINFO_CMS_SMIMECAP_ECDSA_SHA2,
2684  DESCRIPTION( "sMIMECapabilities.capability.ecdsaWithSHA2-256" )
2685  ENCODING_SPECIAL( IDENTIFIER ),
2687  { NULL, 0,
2688  DESCRIPTION( "sMIMECapabilities.capability (ecdsaWithSHA1)" )
2689  ENCODING( SEQUENCE ),
2690  0, FL_IDENTIFIER, RANGE_NONE },
2691  { MKOID( "\x06\x07\x2A\x86\x48\xCE\x3D\x04\x01" ), CRYPT_CERTINFO_CMS_SMIMECAP_ECDSA_SHA1,
2692  DESCRIPTION( "sMIMECapabilities.capability.ecdsaWithSHA1" )
2693  ENCODING_SPECIAL( IDENTIFIER ),
2695  { NULL, 0,
2696  DESCRIPTION( "sMIMECapabilities.capability (preferSignedData)" )
2697  ENCODING( SEQUENCE ),
2698  0, FL_IDENTIFIER, RANGE_NONE },
2699  { MKOID( "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0F\x01" ), CRYPT_CERTINFO_CMS_SMIMECAP_PREFERSIGNEDDATA,
2700  DESCRIPTION( "sMIMECapabilities.capability.preferSignedData" )
2701  ENCODING_SPECIAL( IDENTIFIER ),
2703  { NULL, 0,
2704  DESCRIPTION( "sMIMECapabilities.capability (canNotDecryptAny)" )
2705  ENCODING( SEQUENCE ),
2706  0, FL_IDENTIFIER, RANGE_NONE },
2707  { MKOID( "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x0F\x02" ), CRYPT_CERTINFO_CMS_SMIMECAP_CANNOTDECRYPTANY,
2708  DESCRIPTION( "sMIMECapabilities.capability.canNotDecryptAny" )
2709  ENCODING_SPECIAL( IDENTIFIER ),
2711  { NULL, 0,
2712  DESCRIPTION( "sMIMECapabilities.capability (preferBinaryInside)" )
2713  ENCODING( SEQUENCE ),
2714  0, FL_IDENTIFIER, RANGE_NONE },
2715  { MKOID( "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x01" ), CRYPT_CERTINFO_CMS_SMIMECAP_PREFERBINARYINSIDE,
2716  DESCRIPTION( "sMIMECapabilities.capability.preferBinaryInside" )
2717  ENCODING_SPECIAL( IDENTIFIER ),
2719  { NULL, 0,
2720  DESCRIPTION( "sMIMECapabilities.capability (catchAll)" )
2721  ENCODING( SEQUENCE ),
2722  0, FL_IDENTIFIER, RANGE_NONE },
2723  { NULL, 10000,
2724  DESCRIPTION( "sMIMECapabilities.capability.catchAll" )
2725  ENCODING_SPECIAL( BLOB_ANY ), /* Match anything and ignore it */
2727 
2728 #ifdef USE_CMSATTR_OBSCURE
2729  /* receiptRequest:
2730 
2731  OID = 1 2 840 113549 1 9 16 2 1
2732  SEQUENCE {
2733  contentIdentifier OCTET STRING,
2734  receiptsFrom [ 0 ] INTEGER (0..1),
2735  receiptsTo SEQUENCE {
2736  SEQUENCE OF GeneralName
2737  }
2738  } */
2739  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x01" ), CRYPT_CERTINFO_CMS_RECEIPTREQUEST,
2740  DESCRIPTION( "receiptRequest" )
2741  ENCODING( SEQUENCE ),
2743  0, RANGE_NONE },
2745  DESCRIPTION( "receiptRequest.contentIdentifier" )
2746  ENCODING( OCTETSTRING ),
2747  0, 0, RANGE( 16, 64 ) },
2749  DESCRIPTION( "receiptRequest.receiptsFrom" )
2750  ENCODING_TAGGED( INTEGER, 0 ),
2751  0, 0, RANGE( 0, 1 ) },
2752  { NULL, 0,
2753  DESCRIPTION( "receiptRequest.receiptsTo" )
2754  ENCODING( SEQUENCE ),
2755  0, 0, RANGE_NONE },
2756  { NULL, 0,
2757  DESCRIPTION( "receiptRequest.receiptsTo.generalNames" )
2758  ENCODING( SEQUENCE ),
2759  0, 0, RANGE_NONE },
2761  DESCRIPTION( "receiptRequest.receiptsTo.generalNames.generalName" )
2762  ENCODING_SPECIAL( SUBTYPED ),
2763  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_SEQEND_3 /*FL_SEQEND_2*/, ENCODED_OBJECT( generalNameInfo ) },
2764 
2765  /* essSecurityLabel:
2766 
2767  OID = 1 2 840 113549 1 9 16 2 2
2768  SET {
2769  policyIdentifier OBJECT IDENTIFIER,
2770  classification INTEGER (0..5+6..255) OPTIONAL,
2771  privacyMark PrintableString OPTIONAL,
2772  categories SET OF {
2773  SEQUENCE {
2774  type [ 0 ] OBJECT IDENTIFIER,
2775  value [ 1 ] ANY DEFINED BY type
2776  }
2777  } OPTIONAL
2778  }
2779 
2780  Because this is a SET we don't order the fields in the sequence
2781  given in the above ASN.1 but in the order of encoded size to follow
2782  the DER SET encoding rules */
2783  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x02" ), CRYPT_CERTINFO_CMS_SECURITYLABEL,
2784  DESCRIPTION( "essSecurityLabel" )
2785  ENCODING( SET ),
2787  0, RANGE_NONE },
2789  DESCRIPTION( "essSecurityLabel.securityPolicyIdentifier" )
2790  ENCODING( OBJECT_IDENTIFIER ),
2791  0, 0, RANGE_OID },
2793  DESCRIPTION( "essSecurityLabel.securityClassification" )
2794  ENCODING( INTEGER ),
2797  DESCRIPTION( "essSecurityLabel.privacyMark" )
2798  ENCODING( STRING_PRINTABLE ),
2799  0, FL_OPTIONAL, RANGE( 1, 64 ) },
2800  { NULL, 0,
2801  DESCRIPTION( "essSecurityLabel.securityCategories" )
2802  ENCODING( SET ),
2804  { NULL, 0,
2805  DESCRIPTION( "essSecurityLabel.securityCategories.securityCategory" )
2806  ENCODING( SEQUENCE ),
2807  0, 0, RANGE_NONE },
2809  DESCRIPTION( "essSecurityLabel.securityCategories.securityCategory.type" )
2810  ENCODING_TAGGED( OBJECT_IDENTIFIER, 0 ),
2813  DESCRIPTION( "essSecurityLabel.securityCategories.securityCategory.value" )
2814  ENCODING_SPECIAL_TAGGED( BLOB_ANY, 1 ),
2816 
2817  /* mlExpansionHistory:
2818 
2819  OID = 1 2 840 113549 1 9 16 2 3
2820  SEQUENCE OF {
2821  SEQUENCE {
2822  entityIdentifier IssuerAndSerialNumber, -- Treated as blob
2823  expansionTime GeneralizedTime,
2824  mlReceiptPolicy CHOICE {
2825  none [ 0 ] NULL,
2826  insteadOf [ 1 ] SEQUENCE OF {
2827  SEQUENCE OF GeneralName -- GeneralNames
2828  }
2829  inAdditionTo [ 2 ] SEQUENCE OF {
2830  SEQUENCE OF GeneralName -- GeneralNames
2831  }
2832  }
2833  }
2834  } */
2835  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x03" ), CRYPT_CERTINFO_CMS_MLEXPANSIONHISTORY,
2836  DESCRIPTION( "mlExpansionHistory" )
2837  ENCODING( SEQUENCE ),
2839  FL_SETOF, RANGE_NONE },
2840  { NULL, 0,
2841  DESCRIPTION( "mlExpansionHistory.mlData" )
2842  ENCODING( SEQUENCE ),
2843  0, 0, RANGE_NONE },
2845  DESCRIPTION( "mlExpansionHistory.mlData.mailListIdentifier.issuerAndSerialNumber" )
2846  ENCODING_SPECIAL( BLOB_SEQUENCE ),
2849  DESCRIPTION( "mlExpansionHistory.mlData.expansionTime" )
2850  ENCODING( TIME_GENERALIZED ),
2851  0, FL_MULTIVALUED, RANGE_TIME },
2853  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.none" )
2854  ENCODING_TAGGED( NULL, 0 ),
2855  0, FL_MULTIVALUED, RANGE_NONE },
2856  { NULL, 0,
2857  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.insteadOf" )
2858  ENCODING_TAGGED( SEQUENCE, 1 ),
2859  0, FL_OPTIONAL, RANGE_NONE },
2860  { NULL, 0,
2861  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.insteadOf.generalNames" )
2862  ENCODING( SEQUENCE ),
2863  0, 0, RANGE_NONE },
2865  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.insteadOf.generalNames.generalName" )
2866  ENCODING_SPECIAL( SUBTYPED ),
2867  0, FL_SEQEND_2 | FL_MULTIVALUED | FL_OPTIONAL, ENCODED_OBJECT( generalNameInfo ) },
2868  { NULL, 0,
2869  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.inAdditionTo" )
2870  ENCODING_TAGGED( SEQUENCE, 2 ),
2871  0, FL_OPTIONAL, RANGE_NONE },
2872  { NULL, 0,
2873  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.inAdditionTo.generalNames" )
2874  ENCODING( SEQUENCE ),
2875  0, 0, RANGE_NONE },
2877  DESCRIPTION( "mlExpansionHistory.mlData.mlReceiptPolicy.inAdditionTo.generalNames.generalName" )
2878  ENCODING_SPECIAL( SUBTYPED ),
2879  FL_ATTR_ATTREND, FL_SEQEND_2 /*FL_SEQEND_3, or _4*/ | FL_MULTIVALUED | FL_OPTIONAL, ENCODED_OBJECT( generalNameInfo ) },
2880 
2881  /* contentHints:
2882 
2883  OID = 1 2 840 113549 1 9 16 2 4
2884  SEQUENCE {
2885  contentDescription UTF8String,
2886  contentType OBJECT IDENTIFIER
2887  } */
2888  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x04" ), CRYPT_CERTINFO_CMS_CONTENTHINTS,
2889  DESCRIPTION( "contentHints" )
2890  ENCODING( SEQUENCE ),
2892  0, RANGE_NONE },
2894  DESCRIPTION( "contentHints.contentDescription" )
2895  ENCODING( STRING_UTF8 ),
2898  DESCRIPTION( "contentHints.contentType" )
2899  ENCODING_SPECIAL( CHOICE ),
2900  FL_ATTR_ATTREND, FL_SEQEND /*NONE*/, CRYPT_CONTENT_DATA, CRYPT_CONTENT_LAST, 0, ( void * ) contentTypeInfo },
2901 
2902  /* equivalentLabels:
2903 
2904  OID = 1 2 840 113549 1 9 16 2 9
2905  SEQUENCE OF {
2906  SET {
2907  policyIdentifier OBJECT IDENTIFIER,
2908  classification INTEGER (0..5) OPTIONAL,
2909  privacyMark PrintableString OPTIONAL,
2910  categories SET OF {
2911  SEQUENCE {
2912  type [ 0 ] OBJECT IDENTIFIER,
2913  value [ 1 ] ANY DEFINED BY type
2914  }
2915  } OPTIONAL
2916  }
2917  }
2918 
2919  Because this is a SET we don't order the fields in the sequence
2920  given in the above ASN.1 but in the order of encoded size to follow
2921  the DER SET encoding rules */
2922  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x09" ), CRYPT_CERTINFO_CMS_EQUIVALENTLABEL,
2923  DESCRIPTION( "equivalentLabels" )
2924  ENCODING( SEQUENCE ),
2926  FL_SETOF, RANGE_NONE },
2927  { NULL, 0,
2928  DESCRIPTION( "equivalentLabels.set" )
2929  ENCODING( SET ),
2930  0, 0, RANGE_NONE },
2932  DESCRIPTION( "equivalentLabels.set.securityClassification" )
2933  ENCODING( INTEGER ),
2936  DESCRIPTION( "equivalentLabels.set.securityPolicyIdentifier" )
2937  ENCODING( OBJECT_IDENTIFIER ),
2938  0, FL_MULTIVALUED, RANGE_OID },
2940  DESCRIPTION( "equivalentLabels.set.privacyMark" )
2941  ENCODING( STRING_PRINTABLE ),
2943  { NULL, 0,
2944  DESCRIPTION( "equivalentLabels.set.securityCategories" )
2945  ENCODING( SET ),
2947  { NULL, 0,
2948  DESCRIPTION( "equivalentLabels.set.securityCategories.securityCategory" )
2949  ENCODING( SEQUENCE ),
2950  0, 0, RANGE_NONE },
2952  DESCRIPTION( "equivalentLabels.set.securityCategories.securityCategory.type" )
2953  ENCODING_TAGGED( OBJECT_IDENTIFIER, 0 ),
2956  DESCRIPTION( "equivalentLabels.set.securityCategories.securityCategory.value" )
2957  ENCODING_SPECIAL_TAGGED( BLOB_ANY, 1 ),
2959 #endif /* USE_CMSATTR_OBSCURE */
2960 
2961 #if defined( USE_CMSATTR_OBSCURE ) || defined( USE_CERTREV ) || defined( USE_TSP )
2962  /* signingCertificate:
2963 
2964  OID = 1 2 840 113549 1 9 16 2 12
2965  SEQUENCE {
2966  SEQUENCE OF ESSCertID {
2967  certHash OCTET STRING
2968  },
2969  SEQUENCE OF {
2970  SEQUENCE {
2971  policyIdentifier OBJECT IDENTIFIER
2972  }
2973  } OPTIONAL
2974  }
2975 
2976  See the long comment in the certificate attributes for why this
2977  attribute has to be enabled if USE_CERTREV is defined */
2978  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x0C" ), CRYPT_CERTINFO_CMS_SIGNINGCERTIFICATE,
2979  DESCRIPTION( "signingCertificate" )
2980  ENCODING( SEQUENCE ),
2982  0, RANGE_NONE },
2983  { NULL, 0,
2984  DESCRIPTION( "signingCertificate.certs" )
2985  ENCODING( SEQUENCE ),
2986  0, FL_SETOF, RANGE_NONE },
2988  DESCRIPTION( "signingCertificate.certs.essCertID" )
2989  ENCODING_SPECIAL( BLOB_SEQUENCE ),
2991  { NULL, 0,
2992  DESCRIPTION( "signingCertificate.policies" )
2993  ENCODING( SEQUENCE ),
2995  { NULL, 0,
2996  DESCRIPTION( "signingCertificate.policies.policyInfo" )
2997  ENCODING( SEQUENCE ),
2998  0, 0, RANGE_NONE },
3000  DESCRIPTION( "signingCertificate.policies.policyInfo.policyIdentifier" )
3001  ENCODING( OBJECT_IDENTIFIER ),
3002  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND /*or _3*/, RANGE_OID },
3003 #endif /* USE_CMSATTR_OBSCURE || USE_CERTREV || USE_TSP */
3004 
3005 #ifdef USE_CMSATTR_OBSCURE
3006  /* signingCertificateV2:
3007 
3008  OID = 1 2 840 113549 1 9 16 2 47
3009  SEQUENCE {
3010  SEQUENCE OF ESSCertIDv2 {
3011  hashAlgorithm AlgorithmIdentifier DEFAULT {SHA-256},
3012  certHash OCTET STRING
3013  },
3014  SEQUENCE OF {
3015  SEQUENCE {
3016  policyIdentifier OBJECT IDENTIFIER
3017  }
3018  } OPTIONAL
3019  } */
3020  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x2F" ), CRYPT_CERTINFO_CMS_SIGNINGCERTIFICATEV2,
3021  DESCRIPTION( "signingCertificate" )
3022  ENCODING( SEQUENCE ),
3024  0, RANGE_NONE },
3025  { NULL, 0,
3026  DESCRIPTION( "signingCertificate.certs" )
3027  ENCODING( SEQUENCE ),
3028  0, FL_SETOF, RANGE_NONE },
3030  DESCRIPTION( "signingCertificate.certs.essCertID" )
3031  ENCODING_SPECIAL( BLOB_SEQUENCE ),
3033  { NULL, 0,
3034  DESCRIPTION( "signingCertificate.policies" )
3035  ENCODING( SEQUENCE ),
3037  { NULL, 0,
3038  DESCRIPTION( "signingCertificate.policies.policyInfo" )
3039  ENCODING( SEQUENCE ),
3040  0, 0, RANGE_NONE },
3042  DESCRIPTION( "signingCertificate.policies.policyInfo.policyIdentifier" )
3043  ENCODING( OBJECT_IDENTIFIER ),
3044  FL_ATTR_ATTREND, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND /*or _3*/, RANGE_OID },
3045 
3046  /* signaturePolicyID:
3047 
3048  OID = 1 2 840 113549 1 9 16 2 15
3049  SEQUENCE {
3050  sigPolicyID OBJECT IDENTIFIER,
3051  sigPolicyHash OtherHashAlgAndValue,
3052  sigPolicyQualifiers SEQUENCE OF {
3053  SEQUENCE {
3054  sigPolicyQualifierID OBJECT IDENTIFIER,
3055  sigPolicyQualifier ANY DEFINED BY sigPolicyQualifierID
3056  }
3057  } OPTIONAL
3058  }
3059 
3060  CPSuri ::= IA5String -- OID = cps
3061 
3062  UserNotice ::= SEQUENCE { -- OID = unotice
3063  noticeRef SEQUENCE {
3064  organization UTF8String,
3065  noticeNumbers SEQUENCE OF INTEGER -- SIZE (1)
3066  } OPTIONAL,
3067  explicitText UTF8String OPTIONAL
3068  } */
3069  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x02\x0F" ), CRYPT_CERTINFO_CMS_SIGNATUREPOLICYID,
3070  DESCRIPTION( "signaturePolicyID" )
3071  ENCODING( SEQUENCE ),
3073  0, RANGE_NONE },
3075  DESCRIPTION( "signaturePolicyID.sigPolicyID" )
3076  ENCODING( OBJECT_IDENTIFIER ),
3077  0, 0, RANGE_OID },
3079  DESCRIPTION( "signaturePolicyID.sigPolicyHash" )
3080  ENCODING_SPECIAL( BLOB_SEQUENCE ),
3081  0, 0, RANGE_BLOB },
3082  { NULL, 0,
3083  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers" )
3084  ENCODING( SEQUENCE ),
3086  { NULL, 0,
3087  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier" )
3088  ENCODING( SEQUENCE ),
3089  0, FL_IDENTIFIER, RANGE_NONE },
3090  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x05\x01" ), 0,
3091  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.cps (1 2 840 113549 1 9 16 5 1)" )
3092  ENCODING_SPECIAL( IDENTIFIER ),
3093  0, 0, RANGE_NONE },
3095  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.cPSuri" )
3096  ENCODING( STRING_IA5 ),
3098  { NULL, 0,
3099  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier" )
3100  ENCODING( SEQUENCE ),
3101  0, FL_IDENTIFIER, RANGE_NONE },
3102  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x05\x02" ), 0,
3103  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.unotice (1 2 840 113549 1 9 16 5 2)" )
3104  ENCODING_SPECIAL( IDENTIFIER ),
3105  0, 0, RANGE_NONE },
3106  { NULL, 0,
3107  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice" )
3108  ENCODING( SEQUENCE ),
3109  0, FL_OPTIONAL, RANGE_NONE },
3110  { NULL, 0,
3111  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.noticeRef" )
3112  ENCODING( SEQUENCE ),
3115  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.noticeRef.organization" )
3116  ENCODING( STRING_UTF8 ),
3117  0, FL_MULTIVALUED | FL_OPTIONAL, RANGE( 1, 200 ) },
3118  { NULL, CRYPT_CERTINFO_CMS_SIGPOLICY_ORGANIZATION, /* Backwards-compat.handling for VisibleString */
3119  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.noticeRef.organization" )
3120  ENCODING( STRING_ISO646 ),
3121  0, FL_MULTIVALUED | FL_OPTIONAL, RANGE( 1, 200 ) },
3122  { NULL, 0,
3123  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.noticeRef.noticeNumbers" )
3124  ENCODING( SEQUENCE ),
3125  0, FL_OPTIONAL, RANGE_NONE },
3127  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.noticeRef.noticeNumbers" )
3128  ENCODING( INTEGER ),
3129  0, FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND_2, RANGE( 1, 1000 ) },
3131  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.explicitText" )
3132  ENCODING( STRING_UTF8 ),
3133  0, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, RANGE( 1, 200 ) },
3134  { NULL, CRYPT_CERTINFO_CMS_SIGPOLICY_EXPLICITTEXT, /* Backwards-compat.handling for VisibleString */
3135  DESCRIPTION( "signaturePolicyID.sigPolicyQualifiers.sigPolicyQualifier.userNotice.explicitText" )
3136  ENCODING( STRING_ISO646 ),
3137  FL_ATTR_ATTREND, FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND /* or ... _5 */, RANGE( 1, 200 ) },
3138 
3139  /* signatureTypeIdentifier:
3140 
3141  OID = 1 2 840 113549 1 9 16 9
3142  SEQUENCE {
3143  oidInstance1 OPTIONAL,
3144  oidInstance2 OPTIONAL,
3145  ...
3146  oidInstanceN OPTIONAL
3147  } */
3148  { MKOID( "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x09" ), CRYPT_CERTINFO_CMS_SIGTYPEIDENTIFIER,
3149  DESCRIPTION( "signatureTypeIdentifier" )
3150  ENCODING( SEQUENCE ),
3152  0, RANGE_NONE },
3153  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x09\x01" ), CRYPT_CERTINFO_CMS_SIGTYPEID_ORIGINATORSIG,
3154  DESCRIPTION( "signatureTypeIdentifier.originatorSig (1 2 840 113549 1 9 16 9 1)" )
3155  ENCODING_SPECIAL( IDENTIFIER ),
3156  0, FL_OPTIONAL, RANGE_NONE },
3157  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x09\x02" ), CRYPT_CERTINFO_CMS_SIGTYPEID_DOMAINSIG,
3158  DESCRIPTION( "signatureTypeIdentifier.domainSig (1 2 840 113549 1 9 16 9 2)" )
3159  ENCODING_SPECIAL( IDENTIFIER ),
3160  0, FL_OPTIONAL, RANGE_NONE },
3161  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x09\x03" ), CRYPT_CERTINFO_CMS_SIGTYPEID_ADDITIONALATTRIBUTES,
3162  DESCRIPTION( "signatureTypeIdentifier.additionalAttributesSig (1 2 840 113549 1 9 16 9 3)" )
3163  ENCODING_SPECIAL( IDENTIFIER ),
3164  0, FL_OPTIONAL, RANGE_NONE },
3165  { MKOID( "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x09\x04" ), CRYPT_CERTINFO_CMS_SIGTYPEID_REVIEWSIG,
3166  DESCRIPTION( "signatureTypeIdentifier.reviewSig (1 2 840 113549 1 9 16 9 4)" )
3167  ENCODING_SPECIAL( IDENTIFIER ),
3168  FL_ATTR_ATTREND, FL_OPTIONAL | FL_SEQEND /*NONE*/, RANGE_NONE },
3169 #endif /* USE_CMSATTR_OBSCURE */
3170 
3171 #ifdef USE_CERTVAL
3172  /* randomNonce:
3173 
3174  OID = 1 2 840 113549 1 9 25 3
3175  OCTET STRING
3176 
3177  This is used by RTCS for its message nonce */
3178  { MKOID( "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x19\x03" ), CRYPT_CERTINFO_CMS_NONCE,
3179  DESCRIPTION( "randomNonce" )
3180  ENCODING( OCTETSTRING ),
3182  0, RANGE( 4, CRYPT_MAX_HASHSIZE ) },
3183 #endif /* USE_CERTVAL */
3184 
3185 #ifdef USE_SCEP
3186  /* SCEP attributes:
3187 
3188  messageType:
3189  OID = 2 16 840 1 113733 1 9 2
3190  PrintableString
3191  pkiStatus
3192  OID = 2 16 840 1 113733 1 9 3
3193  PrintableString
3194  failInfo
3195  OID = 2 16 840 1 113733 1 9 4
3196  PrintableString
3197  senderNonce
3198  OID = 2 16 840 1 113733 1 9 5
3199  OCTET STRING
3200  recipientNonce
3201  OID = 2 16 840 1 113733 1 9 6
3202  OCTET STRING
3203  transID
3204  OID = 2 16 840 1 113733 1 9 7
3205  PrintableString */
3206  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x09\x02" ), CRYPT_CERTINFO_SCEP_MESSAGETYPE,
3207  DESCRIPTION( "messageType" )
3208  ENCODING( STRING_PRINTABLE ),
3210  0, RANGE( 1, 2 ) },
3211  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x09\x03" ), CRYPT_CERTINFO_SCEP_PKISTATUS,
3212  DESCRIPTION( "pkiStatus" )
3213  ENCODING( STRING_PRINTABLE ),
3215  0, RANGE( 1, 1 ) },
3216  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x09\x04" ), CRYPT_CERTINFO_SCEP_FAILINFO,
3217  DESCRIPTION( "failInfo" )
3218  ENCODING( STRING_PRINTABLE ),
3220  0, RANGE( 1, 1 ) },
3221  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x09\x05" ), CRYPT_CERTINFO_SCEP_SENDERNONCE,
3222  DESCRIPTION( "senderNonce" )
3223  ENCODING( OCTETSTRING ),
3225  0, RANGE( 8, CRYPT_MAX_HASHSIZE ) },
3226  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x09\x06" ), CRYPT_CERTINFO_SCEP_RECIPIENTNONCE,
3227  DESCRIPTION( "recipientNonce" )
3228  ENCODING( OCTETSTRING ),
3230  0, RANGE( 8, CRYPT_MAX_HASHSIZE ) },
3231  { MKOID( "\x06\x0A\x60\x86\x48\x01\x86\xF8\x45\x01\x09\x07" ), CRYPT_CERTINFO_SCEP_TRANSACTIONID,
3232  DESCRIPTION( "transID" )
3233  ENCODING( STRING_PRINTABLE ),
3235  0, RANGE( 2, CRYPT_MAX_TEXTSIZE ) },
3236 #endif /* USE_SCEP */
3237 
3238 #ifdef USE_CMSATTR_OBSCURE
3239  /* spcAgencyInfo:
3240 
3241  OID = 1 3 6 1 4 1 311 2 1 10
3242  SEQUENCE {
3243  [ 0 ] {
3244  ??? (= [ 0 ] IA5String )
3245  }
3246  }
3247 
3248  The format for this attribute is unknown but it seems to be an
3249  unnecessarily nested URL which is probably an IA5String */
3250  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x0A" ), CRYPT_CERTINFO_CMS_SPCAGENCYINFO,
3251  DESCRIPTION( "spcAgencyInfo" )
3252  ENCODING( SEQUENCE ),
3254  0, RANGE_NONE },
3255  { NULL, 0,
3256  DESCRIPTION( "spcAgencyInfo.vendorInfo" )
3257  ENCODING_TAGGED( SEQUENCE, 0 ),
3258  0, 0, RANGE_NONE },
3260  DESCRIPTION( "spcAgencyInfo..vendorInfo.url" )
3261  ENCODING_TAGGED( STRING_IA5, 0 ),
3262  FL_ATTR_ATTREND, FL_SEQEND /*NONE*/, CHECK_HTTP },
3263 
3264  /* spcStatementType:
3265 
3266  OID = 1 3 6 1 4 1 311 2 1 11
3267  SEQUENCE {
3268  oidInstance1 OPTIONAL,
3269  oidInstance2 OPTIONAL,
3270  ...
3271  oidInstanceN OPTIONAL
3272  } */
3273  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x0B" ), CRYPT_CERTINFO_CMS_SPCSTATEMENTTYPE,
3274  DESCRIPTION( "spcStatementType" )
3275  ENCODING( SEQUENCE ),
3277  FL_SETOF, RANGE_NONE },
3278  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x15" ), CRYPT_CERTINFO_CMS_SPCSTMT_INDIVIDUALCODESIGNING,
3279  DESCRIPTION( "spcStatementType.individualCodeSigning (1 3 6 1 4 1 311 2 1 21)" )
3280  ENCODING_SPECIAL( IDENTIFIER ),
3281  0, FL_OPTIONAL, RANGE_NONE },
3282  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x16" ), CRYPT_CERTINFO_CMS_SPCSTMT_COMMERCIALCODESIGNING,
3283  DESCRIPTION( "spcStatementType.commercialCodeSigning (1 3 6 1 4 1 311 2 1 22)" )
3284  ENCODING_SPECIAL( IDENTIFIER ),
3285  FL_ATTR_ATTREND, FL_OPTIONAL | FL_SEQEND /*NONE*/, RANGE_NONE },
3286 
3287  /* spcOpusInfo:
3288 
3289  OID = 1 3 6 1 4 1 311 2 1 12
3290  SEQUENCE {
3291  [ 0 ] {
3292  ??? (= [ 0 ] BMPString )
3293  }
3294  [ 1 ] {
3295  ??? (= [ 0 ] IA5String )
3296  }
3297  }
3298 
3299  The format for this attribute is unknown but it seems to be either an
3300  empty sequence or some nested set of tagged fields that eventually
3301  end up as text strings */
3302  { MKOID( "\x06\x0A\x2B\x06\x01\x04\x01\x82\x37\x02\x01\x0C" ), CRYPT_CERTINFO_CMS_SPCOPUSINFO,
3303  DESCRIPTION( "spcOpusInfo" )
3304  ENCODING( SEQUENCE ),
3306  0, RANGE_NONE },
3307  { NULL, 0,
3308  DESCRIPTION( "spcOpusInfo.programInfo" )
3309  ENCODING_TAGGED( SEQUENCE, 0 ),
3310  0, FL_OPTIONAL, RANGE_NONE },
3312  DESCRIPTION( "spcOpusInfo.programInfo.name" )
3313  ENCODING_TAGGED( STRING_BMP, 0 ),
3314  0, FL_OPTIONAL | FL_SEQEND, RANGE( 2, 128 ) },
3315  { NULL, 0,
3316  DESCRIPTION( "spcOpusInfo.vendorInfo" )
3317  ENCODING_TAGGED( SEQUENCE, 1 ),
3318  0, FL_OPTIONAL, RANGE_NONE },
3320  DESCRIPTION( "spcOpusInfo.vendorInfo.url" )
3321  ENCODING_TAGGED( STRING_IA5, 0 ),
3323 #endif /* USE_CMSATTR_OBSCURE */
3324 
3325  { NULL, CRYPT_ERROR }, { NULL, CRYPT_ERROR }
3326  };
3327 
3328 /* Subtable for encoding the contentType */
3329 
3330 STATIC_DATA const ATTRIBUTE_INFO FAR_BSS contentTypeInfo[] = {
3332  DESCRIPTION( "contentType.data (1 2 840 113549 1 7 1)" )
3333  ENCODING_SPECIAL( IDENTIFIER ),
3336  DESCRIPTION( "contentType.signedData (1 2 840 113549 1 7 2)" )
3337  ENCODING_SPECIAL( IDENTIFIER ),
3338  0, FL_OPTIONAL, RANGE_NONE },
3340  DESCRIPTION( "contentType.envelopedData (1 2 840 113549 1 7 3)" )
3341  ENCODING_SPECIAL( IDENTIFIER ),
3342  0, FL_OPTIONAL, RANGE_NONE },
3343 #ifdef USE_CMSATTR_OBSCURE
3344  { MKOID( "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x04" ), CRYPT_CONTENT_SIGNEDANDENVELOPEDDATA,
3345  DESCRIPTION( "contentType.signedAndEnvelopedData (1 2 840 113549 1 7 4)" )
3346  ENCODING_SPECIAL( IDENTIFIER ),
3347  0, FL_OPTIONAL, RANGE_NONE },
3348 #endif /* USE_CMSATTR_OBSCURE */
3350  DESCRIPTION( "contentType.digestedData (1 2 840 113549 1 7 5)" )
3351  ENCODING_SPECIAL( IDENTIFIER ),
3352  0, FL_OPTIONAL, RANGE_NONE },
3354  DESCRIPTION( "contentType.encryptedData (1 2 840 113549 1 7 6)" )
3355  ENCODING_SPECIAL( IDENTIFIER ),
3356  0, FL_OPTIONAL, RANGE_NONE },
3357 #ifdef USE_COMPRESSION
3359  DESCRIPTION( "contentType.compressedData (1 2 840 113549 1 9 16 1 9)" )
3360  ENCODING_SPECIAL( IDENTIFIER ),
3361  0, FL_OPTIONAL, RANGE_NONE },
3362 #endif /* USE_COMPRESSION */
3363 #ifdef USE_TSP
3365  DESCRIPTION( "contentType.tstInfo (1 2 840 113549 1 9 16 1 4)" )
3366  ENCODING_SPECIAL( IDENTIFIER ),
3367  0, FL_OPTIONAL, RANGE_NONE },
3368 #endif /* USE_TSP */
3369 #ifdef USE_CMSATTR_OBSCURE
3371  DESCRIPTION( "contentType.spcIndirectDataContext (1 3 6 1 4 1 311 2 1 4)" )
3372  ENCODING_SPECIAL( IDENTIFIER ),
3373  0, FL_OPTIONAL, RANGE_NONE },
3374 #endif /* USE_CMSATTR_OBSCURE */
3375 #ifdef USE_CERTVAL
3377  DESCRIPTION( "contentType.rtcsRequest (1 3 6 1 4 1 3029 4 1 4)" )
3378  ENCODING_SPECIAL( IDENTIFIER ),
3379  0, FL_OPTIONAL, RANGE_NONE },
3381  DESCRIPTION( "contentType.rtcsResponse (1 3 6 1 4 1 3029 4 1 5)" )
3382  ENCODING_SPECIAL( IDENTIFIER ),
3383  0, FL_OPTIONAL, RANGE_NONE },
3385  DESCRIPTION( "contentType.rtcsResponseExt (1 3 6 1 4 1 3029 4 1 6)" )
3386  ENCODING_SPECIAL( IDENTIFIER ),
3387  0, FL_OPTIONAL, RANGE_NONE },
3388 #endif /* USE_CERTVAL */
3389  { MKOID( "\x06\x06\x67\x81\x08\x01\x01\x01" ), CRYPT_CONTENT_MRTD,
3390  DESCRIPTION( "contentType.mRTD (2 23 136 1 1 1)" )
3391  ENCODING_SPECIAL( IDENTIFIER ),
3393  { NULL, CRYPT_ERROR }, { NULL, CRYPT_ERROR }
3394  };
3395 
3396 /* Select the appropriate attribute information table for encoding/type
3397  checking */
3398 
3399 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
3400 int getAttributeInfo( IN_ENUM( ATTRIBUTE ) const ATTRIBUTE_TYPE attributeType,
3403  {
3404  assert( isReadPtr( attributeInfoPtrPtr, sizeof( ATTRIBUTE_INFO * ) ) );
3405  assert( isWritePtr( noAttributeEntries, sizeof( int ) ) );
3406 
3407  REQUIRES( attributeType == ATTRIBUTE_CERTIFICATE || \
3408  attributeType == ATTRIBUTE_CMS );
3409 
3410  if( attributeType == ATTRIBUTE_CMS )
3411  {
3412  *attributeInfoPtrPtr = cmsAttributeInfo;
3413  *noAttributeEntries = FAILSAFE_ARRAYSIZE( cmsAttributeInfo, \
3414  ATTRIBUTE_INFO );
3415  }
3416  else
3417  {
3418  *attributeInfoPtrPtr = extensionInfo;
3419  *noAttributeEntries = FAILSAFE_ARRAYSIZE( extensionInfo, \
3420  ATTRIBUTE_INFO );
3421  }
3422 
3423  return( CRYPT_OK );
3424  }
3425 
3426 /****************************************************************************
3427 * *
3428 * Init/Shutdown Functions *
3429 * *
3430 ****************************************************************************/
3431 
3432 /* Check the validity of the encoding information for an individual
3433  extension */
3434 
3436 static BOOLEAN checkExtension( IN_ARRAY( noAttributeInfoEntries ) \
3437  const ATTRIBUTE_INFO *attributeInfoPtr,
3438  IN_LENGTH_SHORT const int noAttributeInfoEntries,
3439  IN_ATTRIBUTE CRYPT_ATTRIBUTE_TYPE firstAttributeID,
3440  const BOOLEAN isSubTable )
3441  {
3443  BOOLEAN seenFirstField = FALSE;
3444  int nestingLevel = 0, iterationCount;
3445 
3446  assert( isReadPtr( attributeInfoPtr, \
3447  noAttributeInfoEntries * sizeof( ATTRIBUTE_INFO ) ) );
3448 
3449  REQUIRES_B( noAttributeInfoEntries > 0 && \
3450  noAttributeInfoEntries < MAX_INTLENGTH_SHORT );
3451  REQUIRES_B( ( !isSubTable && \
3452  firstAttributeID >= CRYPT_CERTINFO_FIRST && \
3453  firstAttributeID < CRYPT_CERTINFO_LAST ) || \
3454  ( isSubTable && \
3455  firstAttributeID >= 0 && firstAttributeID < 50 ) );
3456  /* Subtables are indexed by small integer values
3457  (CRYPT_CONTENT_TYPE, CRYPT_HOLDINSTRUCTION_TYPE) rather
3458  than CRYPT_ATTRIBUTE_TYPE so the values are outside the
3459  usual CRYPT_CERTINFO_xxx range */
3460 
3461  /* The first entry must be marked as the attribute start */
3462  if( !( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTRSTART ) )
3463  return( FALSE );
3464 
3465  /* The overall attribute can't have a lower attribute ID than any
3466  preceding attribute */
3467  if( attributeInfoPtr->fieldID == FIELDID_FOLLOWS )
3468  {
3469  if( attributeInfoPtr[ 1 ].fieldID < firstAttributeID )
3470  return( FALSE );
3471  }
3472  else
3473  {
3474  if( attributeInfoPtr->fieldID < firstAttributeID )
3475  return( FALSE );
3476  }
3477 
3478  for( iterationCount = 0;
3479  attributeInfoPtr->fieldID != CRYPT_ERROR && \
3480  iterationCount < noAttributeInfoEntries;
3481  attributeInfoPtr++, iterationCount++ )
3482  {
3483  const int nestingLevelDelta = \
3484  decodeNestingLevel( attributeInfoPtr->encodingFlags );
3485 
3486  /* Make sure that various ranges are valid */
3487  if( nestingLevelDelta < 0 || nestingLevelDelta > 5 )
3488  return( FALSE );
3489  if( decodeComplianceLevel( attributeInfoPtr->typeInfoFlags ) < \
3491  decodeComplianceLevel( attributeInfoPtr->typeInfoFlags ) >= \
3493  return( FALSE );
3494 
3495  /* Make sure that the fieldIDs (if present for this entry) are
3496  sorted. We can't require that they be monotone increasing
3497  because handling of some extensions may have been disabled
3498  through the use of configuration options */
3499  if( attributeInfoPtr->fieldID != CRYPT_ATTRIBUTE_NONE && \
3500  attributeInfoPtr->fieldID != FIELDID_FOLLOWS && \
3501  attributeInfoPtr->fieldID <= prevFieldID )
3502  {
3503  /* There are a few special-case situations in which the fields
3504  don't appear sorted:
3505 
3506  equivalentLabels is for some unknown reason it's defined as
3507  a SET rather than a SEQUENCE, so the fields are given in
3508  their encoding order rather than their sorting order. This
3509  means in practice that the two fields
3510  CRYPT_CERTINFO_CMS_EQVLABEL_CLASSIFICATION and
3511  CRYPT_CERTINFO_CMS_EQVLABEL_POLICY are reversed.
3512 
3513  signaturePolicyID has changed over time to use a different
3514  encoding form for its text strings, which is handled in a
3515  transparent manner by having the
3516  CRYPT_CERTINFO_CMS_SIGPOLICY_ORGANIZATION and
3517  CRYPT_CERTINFO_CMS_SIGPOLICY_EXPLICITTEXT entries present
3518  twice, first with the current (preferred) format and then
3519  again with the legacy one */
3520  if( !( ( prevFieldID == CRYPT_CERTINFO_CMS_EQVLABEL_CLASSIFICATION && \
3521  attributeInfoPtr->fieldID == CRYPT_CERTINFO_CMS_EQVLABEL_POLICY ) || \
3522  ( prevFieldID == CRYPT_CERTINFO_CMS_SIGPOLICY_ORGANIZATION && \
3523  attributeInfoPtr->fieldID == CRYPT_CERTINFO_CMS_SIGPOLICY_ORGANIZATION ) || \
3524  ( prevFieldID == CRYPT_CERTINFO_CMS_SIGPOLICY_EXPLICITTEXT && \
3525  attributeInfoPtr->fieldID == CRYPT_CERTINFO_CMS_SIGPOLICY_EXPLICITTEXT ) ) )
3526  return( FALSE );
3527  }
3528  if( attributeInfoPtr->fieldID > CRYPT_ATTRIBUTE_NONE && \
3529  attributeInfoPtr->fieldID < CRYPT_ATTRIBUTE_LAST )
3530  {
3531  /* This may be a field code or unused, so we only update it if
3532  it's an attribute value */
3533  prevFieldID = attributeInfoPtr->fieldID;
3534  }
3535 
3536  /* Make sure that the field entries are consistent with the field
3537  type */
3538  if( attributeInfoPtr->fieldType == FIELDTYPE_CHOICE && \
3539  attributeInfoPtr->extraData == NULL )
3540  {
3541  /* CHOICE must have a CHOICE encoding table */
3542  return( FALSE );
3543  }
3544  if( attributeInfoPtr->fieldType == FIELDTYPE_DN && \
3545  attributeInfoPtr->extraData == NULL )
3546  {
3547  /* DN must have a DN entry checking function */
3548  return( FALSE );
3549  }
3550  if( attributeInfoPtr->fieldType == FIELDTYPE_SUBTYPED )
3551  {
3552  /* Subtyped field must have a subtype encoding table, currently
3553  this can only be the GeneralName table */
3554  if( attributeInfoPtr->extraData != generalNameInfo )
3555  return( FALSE );
3556 
3557  /* Make sure that the field really is a GeneralName */
3558  if( !isGeneralNameSelectionComponent( attributeInfoPtr->fieldID ) )
3559  return( FALSE );
3560  }
3561  if( attributeInfoPtr->fieldType == FIELDID_FOLLOWS )
3562  {
3563  const ATTRIBUTE_INFO *nextAttributeInfoPtr = attributeInfoPtr + 1;
3564 
3565  /* FIELDID_FOLLOWS entry must be at the start of the attribute
3566  and must followed by the one that contains the actual field ID */
3567  if( !( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTRSTART ) )
3568  return( FALSE );
3569  if( nextAttributeInfoPtr->fieldID < CRYPT_CERTINFO_FIRST_EXTENSION || \
3570  nextAttributeInfoPtr->fieldID > CRYPT_CERTINFO_LAST_EXTENSION )
3571  return( FALSE );
3572  }
3573 
3574  /* We shouldn't be finding another attribute-start flag in the
3575  middle of the current attribute */
3576  if( seenFirstField && \
3577  ( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTRSTART ) )
3578  return( FALSE );
3579 
3580  /* Make sure that identifier fields are set up correctly */
3581  if( attributeInfoPtr->encodingFlags & FL_IDENTIFIER )
3582  {
3583  /* Each identifier field must be followed by the OID that
3584  identifies it (required in ext_chk.c and ext_rd.c) unless
3585  it's the final catch-all blob entry */
3586  if( attributeInfoPtr[ 1 ].fieldType == FIELDTYPE_BLOB_ANY )
3587  {
3588  if( attributeInfoPtr[ 1 ].oid != NULL )
3589  return( FALSE );
3590  }
3591  else
3592  {
3593  if( attributeInfoPtr[ 1 ].oid == NULL )
3594  return( FALSE );
3595  }
3596 
3597  /* If there's optional parameters following the OID then they
3598  have to be part of the current extension (required in
3599  ext_chk.c) */
3600  if( ( attributeInfoPtr[ 1 ].encodingFlags & FL_NONENCODING ) && \
3601  ( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTREND ) )
3602  return( FALSE );
3603  }
3604 
3605  /* Make sure that fields with default values are booleans. This
3606  isn't technically required (ext.c simply users the value stored
3607  in the 'defaultValue' field) but currently all default-value
3608  fields are booleans so we add it as a safety check */
3609  if( ( attributeInfoPtr->encodingFlags & FL_DEFAULT ) && \
3610  attributeInfoPtr->fieldType != BER_BOOLEAN )
3611  return( FALSE );
3612 
3613  /* At the moment only complete-attribute SET/SEQUENCEs can be marked
3614  with FL_EMPTYOK, see the comment in certattr.h for details */
3615  if( ( attributeInfoPtr->encodingFlags & FL_EMPTYOK ) && \
3616  attributeInfoPtr->fieldID != CRYPT_CERTINFO_BASICCONSTRAINTS )
3617  return( FALSE );
3618 
3619  /* If it's a CHOICE field then it must be associated with an
3620  encoding subtable for which each entry has the type
3621  FIELDTYPE_IDENTIFIER. The presence of the subtable has already
3622  been checked in the general field-entry checks above */
3623  if( attributeInfoPtr->fieldType == FIELDTYPE_CHOICE )
3624  {
3625  const ATTRIBUTE_INFO *subTableInfoPtr;
3626  int innerIterationCount;
3627 
3628  for( subTableInfoPtr = attributeInfoPtr->extraData, \
3629  innerIterationCount = 0;
3630  subTableInfoPtr->fieldID != CRYPT_ERROR && \
3631  innerIterationCount < FAILSAFE_ITERATIONS_MED;
3632  subTableInfoPtr++, innerIterationCount++ )
3633  {
3634  if( subTableInfoPtr->fieldType != FIELDTYPE_IDENTIFIER )
3635  return( FALSE );
3636  }
3637  ENSURES_B( innerIterationCount < FAILSAFE_ITERATIONS_MED );
3638  }
3639 
3640  /* If it's a sequence/set, increment the nesting level; if it's an
3641  end-of-constructed-item marker, decrement it by the appropriate
3642  amount */
3643  if( attributeInfoPtr->fieldType == BER_SEQUENCE || \
3644  attributeInfoPtr->fieldType == BER_SET )
3645  nestingLevel++;
3646  nestingLevel -= nestingLevelDelta;
3647 
3648  /* Make sure that the encoding information is valid */
3649  if( !( attributeInfoPtr->fieldEncodedType == CRYPT_UNUSED || \
3650  ( attributeInfoPtr->fieldEncodedType >= 0 && \
3651  attributeInfoPtr->fieldEncodedType < MAX_TAG_VALUE ) ) )
3652  return( FALSE );
3653 
3654  /* If it's explicitly tagged make sure that it's a constructed tag
3655  in the correct range */
3656  if( attributeInfoPtr->encodingFlags & FL_EXPLICIT )
3657  {
3658  if( ( attributeInfoPtr->fieldEncodedType < 0 ) || \
3659  ( attributeInfoPtr->fieldEncodedType >= MAX_TAG ) )
3660  return( FALSE );
3661  }
3662 
3663  /* If we've reached the end of the extension, we're done */
3664  if( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTREND )
3665  break;
3666 
3667  /* Remember that we've seen the first field, from now on we
3668  shouldn't be seeing any start-of-attribute fields */
3669  seenFirstField = TRUE;
3670  }
3671  REQUIRES_B( iterationCount < noAttributeInfoEntries );
3672 
3673  /* The last entry must be marked as the attribute end */
3674  if( !( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTREND ) )
3675  return( FALSE );
3676 
3677  /* Make sure that the nesting is correct. Unfortunately this isn't a
3678  very good check because we can exit with a nesting level between zero
3679  and four, see the long comment in cert/certattr.h on the complexities
3680  of deeply nested SEQUENCEs with optional components */
3681  if( nestingLevel < 0 || nestingLevel > 4 )
3682  return( FALSE );
3683 
3684  return( TRUE );
3685  }
3686 
3687 /* Check the validity of each extension in an encoding table */
3688 
3690 static BOOLEAN checkExtensionTable( IN_ARRAY( noAttributeInfoEntries ) \
3691  const ATTRIBUTE_INFO *attributeInfoPtr,
3692  IN_LENGTH_SHORT const int noAttributeInfoEntries,
3693  const BOOLEAN isSubTable )
3694  {
3695  CRYPT_ATTRIBUTE_TYPE baseAttributeID;
3696  int index;
3697 
3698  assert( isReadPtr( attributeInfoPtr, \
3699  noAttributeInfoEntries * sizeof( ATTRIBUTE_INFO ) ) );
3700 
3701  REQUIRES_B( noAttributeInfoEntries > 0 && \
3702  noAttributeInfoEntries < MAX_INTLENGTH_SHORT );
3703 
3704  baseAttributeID = ( attributeInfoPtr->fieldID == FIELDID_FOLLOWS ) ? \
3705  attributeInfoPtr[ 1 ].fieldID : attributeInfoPtr->fieldID;
3706  for( index = 0;
3707  attributeInfoPtr->fieldID != CRYPT_ERROR && \
3708  index < noAttributeInfoEntries;
3709  attributeInfoPtr++, index++ )
3710  {
3711  int iterationCount;
3712 
3713  if( !checkExtension( attributeInfoPtr, \
3714  noAttributeInfoEntries - index,
3715  baseAttributeID, isSubTable ) )
3716  {
3717  DEBUG_DIAG(( "Extension '%s' definition consistency check failed",
3718  ( attributeInfoPtr->description != NULL ) ? \
3719  attributeInfoPtr->description : "<Unknown>" ));
3720  return( FALSE );
3721  }
3722 
3723  /* Remember the base attribute ID, which all subsequent IDs have to
3724  be equal to or higher. The only exception to this is the ID for
3725  the ESSCertID attribute, which also applies to certificates and
3726  so appears in a out-of-place location in the certificate
3727  extensions */
3728  if( attributeInfoPtr->fieldID != CRYPT_CERTINFO_CMS_SIGNINGCERTIFICATE && \
3729  attributeInfoPtr->fieldID != CRYPT_CERTINFO_CMS_SIGNINGCERT_ESSCERTID )
3730  {
3731  baseAttributeID = ( attributeInfoPtr->fieldID == FIELDID_FOLLOWS ) ? \
3732  attributeInfoPtr[ 1 ].fieldID + 1 : \
3733  attributeInfoPtr->fieldID + 1;
3734  }
3735 
3736  /* Skip the remainder of this attribute */
3737  for( iterationCount = 0;
3738  attributeInfoPtr->fieldID != CRYPT_ERROR && \
3739  !( attributeInfoPtr->typeInfoFlags & FL_ATTR_ATTREND ) && \
3740  iterationCount < noAttributeInfoEntries;
3741  attributeInfoPtr++, iterationCount++ );
3742  ENSURES_B( iterationCount < noAttributeInfoEntries );
3743  }
3744  ENSURES_B( index < noAttributeInfoEntries );
3745 
3746  return( TRUE );
3747  }
3748 
3749 /* Check the validity of the encoding tables */
3750 
3751 CHECK_RETVAL_BOOL \
3752 BOOLEAN checkExtensionTables( void )
3753  {
3754  static const MAP_TABLE checkNestingTbl[] = {
3755  { FL_SEQEND, 1 },
3756  { FL_SEQEND_2, 2 },
3757  { FL_SEQEND_3, 3 },
3758  { CRYPT_ERROR, 0 }, { CRYPT_ERROR, 0 }
3759  };
3760  static const MAP_TABLE checkComplianceTbl[] = {
3766  { CRYPT_ERROR, 0 }, { CRYPT_ERROR, 0 }
3767  };
3768  int i;
3769 
3770  /* Sanity checks on various encoded attribute information flags. These
3771  evaluate to constant expressions at compile-time, which both (at
3772  least somewhat) defeats the point of the check and can also lead to
3773  compiler warnings with some compilers due to the expressions being
3774  constant, so we evaluate them from a table in order to ensure that
3775  they're actually evaluated and to get rid of compiler warnings */
3776  for( i = 0; checkNestingTbl[ i ].source != CRYPT_ERROR && \
3777  i < FAILSAFE_ARRAYSIZE( checkNestingTbl, \
3778  sizeof( MAP_TABLE ) ); i++ )
3779  {
3780  ENSURES_B( decodeNestingLevel( checkNestingTbl[ i ].source ) == \
3781  checkNestingTbl[ i ].destination );
3782  }
3783  ENSURES_B( i < FAILSAFE_ARRAYSIZE( checkNestingTbl, \
3784  sizeof( MAP_TABLE ) ) );
3785  for( i = 0; checkComplianceTbl[ i ].source != CRYPT_ERROR && \
3786  i < FAILSAFE_ARRAYSIZE( checkComplianceTbl, \
3787  sizeof( MAP_TABLE ) ); i++ )
3788  {
3789  ENSURES_B( decodeComplianceLevel( checkComplianceTbl[ i ].source ) == \
3790  checkComplianceTbl[ i ].destination );
3791  }
3792  ENSURES_B( i < FAILSAFE_ARRAYSIZE( checkComplianceTbl, \
3793  sizeof( MAP_TABLE ) ) );
3794 
3795  /* Check each encoding table */
3796  if( !checkExtensionTable( extensionInfo,
3797  FAILSAFE_ARRAYSIZE( extensionInfo, \
3798  ATTRIBUTE_INFO ), FALSE ) )
3799  {
3800  DEBUG_DIAG(( "Certificate extension definition consistency check failed" ));
3802  }
3803  if( !checkExtensionTable( cmsAttributeInfo,
3804  FAILSAFE_ARRAYSIZE( cmsAttributeInfo, \
3805  ATTRIBUTE_INFO ), FALSE ) )
3806  {
3807  DEBUG_DIAG(( "CMS attribute definition consistency check failed" ));
3809  }
3810  if( !checkExtensionTable( generalNameInfo,
3811  FAILSAFE_ARRAYSIZE( generalNameInfo, \
3812  ATTRIBUTE_INFO ), FALSE ) )
3813  {
3814  DEBUG_DIAG(( "GeneralName definition consistency check failed" ));
3816  }
3817 #if ( defined( USE_CERTREV ) || defined( USE_CERTREQ ) ) && \
3818  defined( USE_CERTLEVEL_PKIX_FULL )
3819  if( !checkExtensionTable( holdInstructionInfo,
3820  FAILSAFE_ARRAYSIZE( holdInstructionInfo, \
3821  ATTRIBUTE_INFO ), TRUE ) )
3822  {
3823  DEBUG_DIAG(( "HoldInstructionInfo definition consistency check failed" ));
3825  }
3826 #endif /* ( USE_CERTREV || USE_CERTREQ ) && USE_CERTLEVEL_PKIX_FULL */
3827  if( !checkExtensionTable( contentTypeInfo,
3828  FAILSAFE_ARRAYSIZE( contentTypeInfo, \
3829  ATTRIBUTE_INFO ), TRUE ) )
3830  {
3831  DEBUG_DIAG(( "ContentTypeInfo definition consistency check failed" ));
3833  }
3834 
3835  return( TRUE );
3836  }
3837 
3838 /****************************************************************************
3839 * *
3840 * Extended Validity Checking Functions *
3841 * *
3842 ****************************************************************************/
3843 
3844 /* Valid list of TLDs for checking FQDNs, from
3845  http://data.iana.org/TLD/tlds-alpha-by-domain.txt */
3846 
3847 static const char *tldNames[] = {
3848  "ac", "ad", "ae", "aero", "af", "ag", "ai", "al", "am", "an", "ao",
3849  "aq", "ar", "arpa", "as", "asia", "at", "au", "aw", "ax", "az", "ba",
3850  "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz", "bj", "bm", "bn", "bo",
3851  "br", "bs", "bt", "bv", "bw", "by", "bz", "ca", "cat", "cc", "cd", "cf",
3852  "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "com", "coop", "cr",
3853  "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec",
3854  "edu", "ee", "eg", "er", "es", "et", "eu", "fi", "fj", "fk", "fm", "fo",
3855  "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm", "gn",
3856  "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn",
3857  "hr", "ht", "hu", "id", "ie", "il", "im", "in", "info", "int", "io",
3858  "iq", "ir", "is", "it", "je", "jm", "jo", "jobs", "jp", "ke", "kg",
3859  "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz", "la", "lb", "lc",
3860  "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "me",
3861  "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo", "mobi", "mp", "mq",
3862  "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx", "my", "mz", "na",
3863  "name", "nc", "ne", "net", "nf", "ng", "ni", "nl", "no", "np", "nr",
3864  "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm",
3865  "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re", "ro", "rs", "ru",
3866  "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sj", "sk", "sl",
3867  "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz", "tc", "td", "tel",
3868  "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to", "tp", "tr",
3869  "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "us", "uy", "uz",
3870  "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "xxx", "ye", "yt",
3871  "za", "zm", "zw", NULL, NULL
3872  };
3873 
3874 /* Determine whether a variety of URIs are valid and return a
3875  CRYPT_ERRTYPE_TYPE describing the type of error if there's a problem.
3876  The PKIX RFC refers to a pile of complex parsing rules for various URI
3877  forms, since cryptlib is neither a resolver nor an MTA nor a web browser
3878  it leaves it up to the calling application to decide whether a particular
3879  form is acceptable to it or not. We do however perform a few basic
3880  checks to weed out obviously-incorrect forms here.
3881 
3882  In theory we could use sNetParseUrl() for this but the code won't be
3883  included if cryptlib is built without networking support, and in any case
3884  we also need to perform processing for URLs that aren't network URLs */
3885 
3886 typedef enum {
3887  URL_NONE, /* No URL */
3888  URL_RFC822, /* Email address */
3889  URL_DNS, /* FQDN */
3890  URL_HTTP, /* HTTP URL */
3891  URL_ANY, /* Generic URL */
3892  URL_LAST /* Last possible URL type */
3893  } URL_CHECK_TYPE;
3894 
3895 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
3896 static int checkURLString( IN_BUFFER( urlLength ) const char *url,
3897  IN_LENGTH_DNS const int urlLength,
3898  IN_ENUM( URL ) const URL_CHECK_TYPE urlType )
3899  {
3900  const char *schema = NULL;
3901  int schemaLength = 0, length = urlLength, offset, i;
3902 
3903  assert( isReadPtr( url, urlLength ) );
3904 
3905  REQUIRES( urlLength >= MIN_RFC822_SIZE && urlLength < MAX_URL_SIZE );
3906  /* MIN_RFC822_SIZE is the shortest value allow, MAX_URL_SIZE
3907  is the largest */
3908  REQUIRES( urlType > URL_NONE && urlType < URL_LAST );
3909 
3910  /* Make a first pass over the URL checking that it follows the RFC 1738
3911  rules for valid characters. Because of the use of wildcards in
3912  certificates we can't check for '*' at this point but have to make a
3913  second pass after we've performed URL-specific processing */
3914  for( i = 0; i < urlLength; i++ )
3915  {
3916  const int ch = byteToInt( url[ i ] );
3917 
3918  if( ch <= 0 || ch > 0x7F || !isPrint( ch ) || \
3919  ch == ' ' || ch == '<' || ch == '>' || ch == '"' || \
3920  ch == '{' || ch == '}' || ch == '|' || ch == '\\' || \
3921  ch == '^' || ch == '[' || ch == ']' || ch == '`' )
3922  return( CRYPT_ERRTYPE_ATTR_VALUE );
3923  }
3924 
3925  /* Check for a schema separator. This get a bit complicated because
3926  some URLs use "://" (HTTP, FTP, LDAP) and others just use ":" (SMTP,
3927  SIP), so we have to check for both. We can't check for a possibly-
3928  malformed ":/" because this could be something like
3929  "file:/dir/filename", which is valid. The pattern that we check for
3930  is '(2...8 chars) ":" ["//" ] (3...n chars)' */
3931  if( ( offset = strFindStr( url, urlLength, "://", 3 ) ) >= 0 )
3932  {
3933  /* Extract the URI schema */
3934  if( offset < 2 || offset > 8 || offset >= urlLength - 3 )
3935  return( CRYPT_ERRTYPE_ATTR_SIZE );
3936  offset += 3; /* Adjust for "://" */
3937  }
3938  else
3939  {
3940  if( ( offset = strFindCh( url, urlLength, ':' ) ) >= 0 )
3941  {
3942  /* Extract the URI schema */
3943  if( offset < 2 || offset > 8 || offset >= urlLength - 3 )
3944  return( CRYPT_ERRTYPE_ATTR_SIZE );
3945  offset++; /* Adjust for ":" */
3946  }
3947  }
3948  if( offset > 0 )
3949  {
3950  schema = url;
3951  schemaLength = offset;
3952  url += offset;
3953  length = urlLength - offset;
3954  }
3955  ENSURES( rangeCheckZ( schemaLength, length, urlLength ) );
3956 
3957  /* Make sure that the start of the URL looks valid. Note that this
3958  simply checks for obvious mistakes (e.g. setting an IP address for a
3959  DNS name), not for every possible way of disguising one kind of URL
3960  as another.
3961 
3962  The lengths have already been checked by the kernel but we check them
3963  again here to be sure */
3964  switch( urlType )
3965  {
3966  case URL_DNS:
3967  if( urlLength < MIN_DNS_SIZE || urlLength > MAX_DNS_SIZE )
3968  return( CRYPT_ERRTYPE_ATTR_SIZE );
3969  if( schema != NULL )
3970  {
3971  /* It's a URL, not a DNS name */
3972  return( CRYPT_ERRTYPE_ATTR_VALUE );
3973  }
3974  if( ( isDigit( url[ 0 ] && isDigit( url[ 1 ] ) ) ) || \
3975  ( url[ 0 ] == '[' && \
3976  ( url[ 1 ] == ':' || isDigit( url[ 1 ] ) ) ) )
3977  {
3978  /* It's an IPv4 or IPv6 address, not a DNS name */
3979  return( CRYPT_ERRTYPE_ATTR_VALUE );
3980  }
3981  if( !strCompare( url, "*.", 2 ) )
3982  {
3983  url += 2; /* Skip wildcard */
3984  length -= 2;
3985  }
3986  break;
3987 
3988  case URL_RFC822:
3989  if( urlLength < MIN_RFC822_SIZE || urlLength > MAX_RFC822_SIZE )
3990  return( CRYPT_ERRTYPE_ATTR_SIZE );
3991  if( schema != NULL )
3992  {
3993  /* Catch erroneous use of URL */
3994  return( CRYPT_ERRTYPE_ATTR_VALUE );
3995  }
3996  if( !strCompare( url, "*@", 2 ) )
3997  {
3998  url += 2; /* Skip wildcard */
3999  length -= 2;
4000  }
4001  break;
4002 
4003  case URL_HTTP:
4004  if( urlLength < MIN_URL_SIZE || urlLength > MAX_URL_SIZE )
4005  return( CRYPT_ERRTYPE_ATTR_SIZE );
4006  if( schema == NULL || \
4007  ( strCompare( schema, "http://", 7 ) && \
4008  strCompare( schema, "https://", 8 ) ) )
4009  return( CRYPT_ERRTYPE_ATTR_VALUE );
4010  if( !strCompare( url, "*.", 2 ) )
4011  {
4012  url += 2; /* Skip wildcard */
4013  length -= 2;
4014  }
4015  break;
4016 
4017  case URL_ANY:
4018  if( schema == NULL || length < 3 || length > MAX_URL_SIZE )
4019  return( CRYPT_ERRTYPE_ATTR_VALUE );
4020  break;
4021 
4022  default:
4023  retIntError();
4024  }
4025 
4026  /* Make a second pass over the URL checking for any remaining invalid
4027  characters. Since we've stripped any permitted wildcards earlier on,
4028  the wildcard is now an invalid character */
4029  for( i = 0; i < length; i++ )
4030  {
4031  const int ch = byteToInt( url[ i ] );
4032 
4033  if( ch == '*' )
4034  return( CRYPT_ERRTYPE_ATTR_VALUE );
4035  }
4036 
4037  return( CRYPT_OK );
4038  }
4039 
4040 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
4041 static int checkRFC822( const ATTRIBUTE_LIST *attributeListPtr )
4042  {
4043  assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
4044 
4045  return( checkURLString( attributeListPtr->value,
4046  attributeListPtr->valueLength, URL_RFC822 ) );
4047  }
4048 
4049 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
4050 static int checkDNS( const ATTRIBUTE_LIST *attributeListPtr )
4051  {
4052  assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
4053 
4054  return( checkURLString( attributeListPtr->value,
4055  attributeListPtr->valueLength, URL_DNS ) );
4056  }
4057 
4058 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
4059 static int checkURL( const ATTRIBUTE_LIST *attributeListPtr )
4060  {
4061  assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
4062 
4063  return( checkURLString( attributeListPtr->value,
4064  attributeListPtr->valueLength, URL_ANY ) );
4065  }
4066 
4067 #ifdef USE_CERT_OBSOLETE
4068 
4069 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
4070 static int checkHTTP( const ATTRIBUTE_LIST *attributeListPtr )
4071  {
4072  assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
4073 
4074  return( checkURLString( attributeListPtr->value,
4075  attributeListPtr->valueLength, URL_HTTP ) );
4076  }
4077 #endif /* USE_CERT_OBSOLETE */
4078 
4079 /* Determine whether a DN (either a complete DN or a DN subtree) is valid.
4080  Most attribute fields require a full DN but some fields (which act as
4081  filters) are allowed a partial DN */
4082 
4083 CHECK_RETVAL_ENUM( CRYPT_ERRTYPE ) STDC_NONNULL_ARG( ( 1 ) ) \
4084 static int checkDirectoryName( const ATTRIBUTE_LIST *attributeListPtr )
4085  {
4087  CRYPT_ERRTYPE_TYPE errorType;
4088  int status;
4089 
4090  assert( isReadPtr( attributeListPtr, sizeof( ATTRIBUTE_LIST ) ) );
4091 
4092  if( attributeListPtr->fieldID == CRYPT_CERTINFO_EXCLUDEDSUBTREES || \
4093  attributeListPtr->fieldID == CRYPT_CERTINFO_PERMITTEDSUBTREES )
4094  {
4095  status = checkDN( attributeListPtr->value, CHECKDN_FLAG_COUNTRY,
4096  &dummy, &errorType );
4097  }
4098  else
4099  {
4100  status = checkDN( attributeListPtr->value,
4102  &dummy, &errorType );
4103  }
4104  if( cryptStatusError( status ) )
4105  return( errorType );
4106 
4107  return( CRYPT_ERRTYPE_NONE );
4108  }
4109 
4110 /****************************************************************************
4111 * *
4112 * Miscellaneous Functions *
4113 * *
4114 ****************************************************************************/
4115 
4116 /* Since many of the attributes can be disabled to save space and reduce
4117  complexity, we may need to check that an attribute that we want to use is
4118  actually available, for example if we're about to create it as part of an
4119  internal operation for which we don't want to present an unexpected error
4120  status to the caller. The following function checks whether an attribute
4121  is enabled for use */
4122 
4123 CHECK_RETVAL_BOOL \
4125  {
4126  REQUIRES_B( fieldID >= CRYPT_CERTINFO_FIRST_EXTENSION && \
4127  fieldID <= CRYPT_CERTINFO_LAST );
4128 
4129  if( fieldID <= CRYPT_CERTINFO_LAST_EXTENSION )
4130  {
4131  return( fieldIDToAttribute( ATTRIBUTE_CERTIFICATE, fieldID,
4132  CRYPT_ATTRIBUTE_NONE, NULL ) != NULL ? \
4133  TRUE : FALSE );
4134  }
4135  return( fieldIDToAttribute( ATTRIBUTE_CMS, fieldID,
4136  CRYPT_ATTRIBUTE_NONE, NULL ) != NULL ? \
4137  TRUE : FALSE );
4138  }
4139 
4140 /* Get the encoded tag value for a field */
4141 
4143 int getFieldEncodedTag( const ATTRIBUTE_INFO *attributeInfoPtr )
4144  {
4145  int tag;
4146 
4147  assert( isReadPtr( attributeInfoPtr, sizeof( ATTRIBUTE_INFO ) ) );
4148 
4149  REQUIRES( attributeInfoPtr->fieldEncodedType == CRYPT_UNUSED || \
4150  ( attributeInfoPtr->fieldEncodedType >= 0 && \
4151  attributeInfoPtr->fieldEncodedType < MAX_TAG_VALUE ) );
4152 
4153  /* If it's a non-tagged field, we're done */
4154  if( attributeInfoPtr->fieldEncodedType == CRYPT_UNUSED )
4155  return( OK_SPECIAL );
4156 
4157  /* It's a tagged field, the actual tag is stored as the encoded-type
4158  value. If it's explicitly tagged or an implictly tagged SET/SEQUENCE
4159  then it's constructed, otherwise it's primitive */
4160  if( ( attributeInfoPtr->fieldType == BER_SEQUENCE ||
4161  attributeInfoPtr->fieldType == BER_SET ||
4162  attributeInfoPtr->fieldType == FIELDTYPE_DN ||
4163  ( attributeInfoPtr->encodingFlags & FL_EXPLICIT ) ) )
4164  tag = MAKE_CTAG( attributeInfoPtr->fieldEncodedType );
4165  else
4166  tag = MAKE_CTAG_PRIMITIVE( attributeInfoPtr->fieldEncodedType );
4167 
4168  ENSURES( ( tag >= MAKE_CTAG_PRIMITIVE( 0 ) ) && \
4169  ( tag <= MAX_TAG ) );
4170 
4171  return( tag );
4172  }
4173 #endif /* USE_CERTIFICATES */