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