certedef.c

来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 1,651 行 · 第 1/5 页

C
1,651
字号
/****************************************************************************
*																			*
*						Certificate Attribute Definitions					*
*						Copyright Peter Gutmann 1996-2002					*
*																			*
****************************************************************************/

#include <ctype.h>
#include <string.h>
#if defined( INC_ALL ) ||  defined( INC_CHILD )
  #include "asn1.h"
  #include "asn1oid.h"
  #include "cert.h"
  #include "certattr.h"
#else
  #include "keymgmt/asn1.h"
  #include "keymgmt/asn1oid.h"
  #include "keymgmt/cert.h"
  #include "keymgmt/certattr.h"
#endif /* Compiler-specific includes */

/* The following certificate/CMS extensions are currently supported.  If
   'Enforced' is set to 'Yes', this means that they are constraint extensions
   which are enforced by the cert checking code; if set to '-', they are
   informational extensions for which enforcement doesn't apply; if set to
   'No', they need to be handled by the user (this only applies for
   certificate policies, where the user has to decide whether a given cert
   policy is acceptable or not).  If 'Read-only' is set to 'Yes', this means
   that they can be read by the user but not set (this applies for most
   informational extensions which are set by cryptlib, and to deprecated
   extensions).  The Yes/No in policyConstraints means that everything except
   the policy mapping constraint is enforced (because policyMappings itself
   isn't enforced).				Enforced	Read-only
								--------	---------
	authorityInfoAccess			   -			-
	authorityKeyIdentifier		   -		   Yes
	basicConstraints			  Yes			-
	biometricInfo (QualifiedCert)  -			-
	certCardRequired (SET)		   -			-
	certificateIssuer			   -			-
	certificatePolicies			  Yes			-
	certificateType (SET)		   -			-
	cRLDistributionPoints		   -			-
	cRLNumber					   -			-
	cRLReason					   -			-
	dateOfCertGen (SigG)		   -			-
	deltaCRLIndicator			   -			-
	extKeyUsage					  Yes			-
	hashedRootKey (SET)			   -			-
	holdInstructionCode			   -			-
	invalidityDate				   -			-
	issuerAltName				   -		   Yes
	issuingDistributionPoint	   -			-
	keyUsage					  Yes			-
	monetaryLimit (SigG)		   -			-
	nameConstraints				  Yes			-
	netscape-cert-type			  Yes			-
	netscape-base-url			   -			-
	netscape-revocation-url 	   -			-
	netscape-ca-revocation-url	   -			-
	netscape-cert-renewal-url	   -			-
	netscape-ca-policy-url		   -			-
	netscape-ssl-server-name	   -			-
	netscape-comment			   -			-
	merchantData (SET)			   -			-
	ocspArchiveCutoff (OCSP)	   -			-
	ocspCRL (OCSP)				   -			-
	ocspNoCheck					   -			-
	ocspNonce (OCSP)			   -		   Yes
	ocspResposne (OCSP)			   -		   Yes
	policyConstraints			 Yes/No			-
	policyMappings				  No			-
	privateKeyUsagePeriod		  Yes			-
	procuration (SigG)			   -			-
	qcStatements (QualifiedCert)   -			-
	restriction (SigG)			   -			-
	strongExtranet (Thawte)		   -			-
	subjectAltName				   -			-
	subjectDirectoryAttributes	   -		   Yes
	subjectKeyIdentifier		   -		   Yes
	tunneling (SET)				   -			-

   The extensions are specified in tables which are used to both check the 
   validity of extension data and to describe the structure of an extension.  
   For example to describe the structure of the basicConstraints extension 
   the entries would be:

	fieldID = CRYPT_CERTINFO_BASICCONSTRAINTS, fieldType = BER_SEQUENCE,
			OID = xxx, flags = FL_CRITICAL, FL_VALID_CERT, FL_MORE
	fieldID = CRYPT_CERTINFO_CA, fieldType = BER_BOOLEAN,
			flags = FL_OPTIONAL, FL_DEFAULT, FL_MORE, default = FALSE
	fieldID = CRYPT_CERTINFO_PATHLENCONSTRAINT, fieldType = BER_INTEGER,
			flags = FL_OPTIONAL

   If the extension has a single member rather than being built up as a
   SEQUENCE then the OID is set but the field-specific values are also set,
   so keyUsage would be:

	fieldID = CRYPT_CERTINFO_KEYUSAGE, fieldType = BER_BITSTRING,
			OID = xxx, flags = FL_CRITICAL, FL_VALID_CERTREQ, FL_VALID_CERT

   There are many special cases to handle things like no vs implicit vs
   explicit tagging (the X.509v3 default is to use implicit tags for
   extensions, so any explicit tags have to be explicitly specified):

	fieldID = CRYPT_NOTAG, fieldType = BER_INTEGER
	fieldID = CRYPT_IMPLICIT_TAG, fieldType = BER_INTEGER,
		fieldEncodedType = CTAG( 0 )
	fieldID = CRYPT_EXPLICIT_TAG, fieldType = BER_INTEGER,
		fieldEncodedType = CTAG( 0 ), flags = FL_EXPLICIT

   Constructed objects are handled by starting them with a BER_SEQUENCE and
   ending them with a BER_SEQEND flag at the last member:

	fieldID = CRYPT_SEQUENCE, fieldType = BER_SEQUENCE,
		flags = FL_MORE
	fieldID = CRYPT_SEQUENCE_INTEGER, fieldType = BER_INTEGER,
		flags = FL_MORE
	fieldID = CRYPT_SEQUENCE_BOOLEAN, fieldType = BER_BOOLEAN,
		flags = FL_SEQEND

   If the constructed object is nested, it's possible to specify the level of
   unnesting with BER_SEQEND_1... BER_SEQEND_3.

   Some extensions are specified as a SEQUENCE OF thing, to make it possible
   to process these automatically we rewrite them as a SEQUENCE OF
   thingInstance1 OPTIONAL, thingInstance2 OPTIONAL, ... thingInstanceN
   OPTIONAL.  Examples of this are extKeyUsage and the altNames.

   Since some extensions fields are tagged, the fields as encoded differ from
   the fields as defined by the tagging, the following macro is used to turn
   a small integer into a context-specific tag.  By default the tag is
   implicit as per X.509v3, to make it an explicit tag we need to set the
   FL_EXPLICIT flag for the field */

#define CTAG( x )		( x | BER_CONTEXT_SPECIFIC )

/* Extended checking functions */

static int checkRFC822( const ATTRIBUTE_LIST *attributeListPtr );
static int checkDNS( const ATTRIBUTE_LIST *attributeListPtr );
static int checkURL( const ATTRIBUTE_LIST *attributeListPtr );
static int checkHTTP( const ATTRIBUTE_LIST *attributeListPtr );
static int checkDirectoryName( const ATTRIBUTE_LIST *attributeListPtr );

/* Forward declarations for alternative encoding tables used by the main
   tables.  These are declared in a somewhat peculiar manner because there's
   no clean way in C to forward declare a static array */

extern const ATTRIBUTE_INFO FAR_BSS generalNameInfo[];
extern const ATTRIBUTE_INFO FAR_BSS holdInstructionInfo[];
extern const ATTRIBUTE_INFO FAR_BSS contentTypeInfo[];

/****************************************************************************
*																			*
*						Certificate Extension Definitions					*
*																			*
****************************************************************************/

/* Certificate extensions are encoded using the following table */

static const ATTRIBUTE_INFO FAR_BSS extensionInfo[] = {
	/* authorityInfoAccess:
		OID = 1 3 6 1 5 5 7 1 1
		critical = FALSE
		SEQUENCE SIZE (1...MAX) OF {
			SEQUENCE {
				accessMethod	OBJECT IDENTIFIER,
				accessLocation	GeneralName
				}
			} */
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x01" ), CRYPT_CERTINFO_AUTHORITYINFOACCESS,
	  MKDESC( "authorityInfoAccess" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_SETOF_VARIABLE | FL_VALID_CERT, 0, 0, 0, NULL },
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.accessDescription (ocsp)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x01" ), 0,
	  MKDESC( "authorityInfoAccess.ocsp (1 3 6 1 5 5 7 48 1)" )
	  FIELDTYPE_IDENTIFIER, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, CRYPT_CERTINFO_AUTHORITYINFO_OCSP,
	  MKDESC( "authorityInfoAccess.accessDescription.accessLocation (ocsp)" )
	  FIELDTYPE_SUBTYPED, 0,
	  FL_MORE | FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, 0, 0, 0, ( void * ) generalNameInfo },
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.accessDescription (caIssuers)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x02" ), 0,
	  MKDESC( "authorityInfoAccess.caIssuers (1 3 6 1 5 5 7 48 2)" )
	  FIELDTYPE_IDENTIFIER, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, CRYPT_CERTINFO_AUTHORITYINFO_CAISSUERS,
	  MKDESC( "authorityInfoAccess.accessDescription.accessLocation (caIssuers)" )
	  FIELDTYPE_SUBTYPED, 0,
	  FL_MORE | FL_OPTIONAL | FL_MULTIVALUED | FL_SEQEND, 0, 0, 0, ( void * ) generalNameInfo },
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.accessDescription (timeStamping)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x03" ), 0,
	  MKDESC( "authorityInfoAccess.timeStamping (1 3 6 1 5 5 7 48 3)" )
	  FIELDTYPE_IDENTIFIER, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, CRYPT_CERTINFO_AUTHORITYINFO_TIMESTAMPING,
	  MKDESC( "authorityInfoAccess.accessDescription.accessLocation (timeStamping)" )
	  FIELDTYPE_SUBTYPED, 0,
	  FL_MORE | FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, 0, 0, 0, ( void * ) generalNameInfo },
#if 0
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.accessDescription (httpCerts)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x06" ), 0,
	  MKDESC( "authorityInfoAccess.httpCerts (1 3 6 1 5 5 7 48 6)" )
	  FIELDTYPE_IDENTIFIER, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_AUTHORITYINFO_HTTP_CERTS, */
	  MKDESC( "authorityInfoAccess.accessDescription.accessLocation (httpCerts)" )
	  FIELDTYPE_SUBTYPED, 0,
	  FL_MORE | FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, 0, 0, 0, ( void * ) generalNameInfo },
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.accessDescription (httpCRLs)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x07" ), 0,
	  MKDESC( "authorityInfoAccess.httpCRLs (1 3 6 1 5 5 7 48 7)" )
	  FIELDTYPE_IDENTIFIER, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_AUTHORITYINFO_HTTP_CRLS, */
	  MKDESC( "authorityInfoAccess.accessDescription.accessLocation (httpCRLs)" )
	  FIELDTYPE_SUBTYPED, 0,
	  FL_MORE | FL_MULTIVALUED | FL_OPTIONAL | FL_SEQEND, 0, 0, 0, ( void * ) generalNameInfo },
#endif
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.accessDescription (catchAll)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ NULL, 0,
	  MKDESC( "authorityInfoAccess.catchAll" )
	  FIELDTYPE_BLOB, 0,		/* Match anything and ignore it */
	  FL_OPTIONAL | FL_NONENCODING | FL_SEQEND, 0, 0, 0, NULL },

	/* biometricInfo
		OID = 1 3 6 1 5 5 7 1 2
		critical = FALSE
		SEQUENCE OF {						-- SIZE (1)
			SEQUENCE {
				typeOfData		INTEGER,
				hashAlgorithm	OBJECT IDENTIFIER,
				dataHash		OCTET STRING,
				sourceDataUri	IA5String OPTIONAL
				}
			} */
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x02" ), 0, /* CRYPT_CERTINFO_BIOMETRICINFO, */
	  MKDESC( "biometricInfo" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_VALID_CERT, 0, 0, 0, NULL },
	{ NULL, 0,
	  MKDESC( "biometricInfo.biometricData" )
	  BER_SEQUENCE, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, 0,  /* CRYPT_CERTINFO_BIOMETRICINFO_TYPE, */
	  MKDESC( "biometricInfo.biometricData.typeOfData" )
	  BER_INTEGER, 0,
	  FL_MORE, 0, 1, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_BIOMETRICINFO_HASHALGO, */
	  MKDESC( "biometricInfo.biometricData.hashAlgorithm" )
	  BER_OBJECT_IDENTIFIER, 0,
	  FL_MORE, 3, 32, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_BIOMETRICINFO_HASH, */
	  MKDESC( "biometricInfo.biometricData.dataHash" )
	  BER_OCTETSTRING, 0,
	  FL_MORE, 16, CRYPT_MAX_HASHSIZE, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_BIOMETRICINFO_URL, */
	  MKDESC( "biometricInfo.biometricData.sourceDataUri" )
	  BER_STRING_IA5, 0,
	  FL_OPTIONAL | FL_SEQEND_2, MIN_URL_SIZE, MAX_URL_SIZE, 0, NULL },

	/* qcStatements
		OID = 1 3 6 1 5 5 7 1 3
		critical = TRUE
		SEQUENCE OF {						-- SIZE (1)
			SEQUENCE {
				statementID		OBJECT IDENTIFIER,
				statementInfo	SEQUENCE {
					semanticsIdentifier	OBJECT IDENTIFIER OPTIONAL,
					nameRegistrationAuthorities SEQUENCE OF {	-- SIZE (1)
						GeneralName }
				}
			} */
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x01\x03" ), 0, /* CRYPT_CERTINFO_QCSTATEMENT, */
	  MKDESC( "qcStatements" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_CRITICAL | FL_VALID_CERT, 0, 0, 0, NULL },
	{ NULL, 0,
	  MKDESC( "qcStatements.qcStatement (statementID)" )
	  BER_SEQUENCE, 0,
	  FL_MORE | FL_IDENTIFIER, 0, 0, 0, NULL },
	{ MKOID( "\x06\x08\x2B\x06\x01\x05\x05\x07\x0B\x01" ), 0,
	  MKDESC( "qcStatements.qcStatement.statementID (1 3 6 1 5 5 7 11 1)" )
	  FIELDTYPE_IDENTIFIER, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, 0,
	  MKDESC( "qcStatements.qcStatement.statementInfo (statementID)" )
	  BER_SEQUENCE, 0,
	  FL_MORE, 0, 0, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_QCSTATEMENT_SEMANTICS, */
	  MKDESC( "qcStatements.qcStatement.statementInfo.semanticsIdentifier (statementID)" )
	  BER_OBJECT_IDENTIFIER, 0,
	  FL_MORE | FL_OPTIONAL, 3, 32, 0, NULL },
	{ NULL, 0, /* CRYPT_CERTINFO_QCSTATEMENT_REGISTRATIONAUTHORITY, */
	  MKDESC( "qcStatements.qcStatement.statementInfo.nameRegistrationAuthorities (statementID)" )
	  FIELDTYPE_SUBTYPED, 0,
	  FL_OPTIONAL | FL_SEQEND_2, 0, 0, 0, ( void * ) generalNameInfo },

	/* ocspNonce:
		OID = 1 3 6 1 5 5 7 48 1 2
		critical = FALSE (!!)
		nonce		INTEGER
	   Although the nonce should be an integer, it's really an integer 
	   equivalent of an octet string hole so we call it an octet string to 
	   make sure it gets handled appropriately */
	{ MKOID( "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x02" ), CRYPT_CERTINFO_OCSP_NONCE,
	  MKDESC( "ocspNonce" )
	  BER_OCTETSTRING, BER_INTEGER,	/* Actually an INTEGER hole */
	  FL_RO | FL_VALID_OCSPREQ | FL_VALID_OCSPRESP, 1, 64, 0, NULL },

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?