⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certchk.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
	return( TRUE );
	}

/* Compare two altNames component by component */

static CRYPT_ATTRIBUTE_TYPE compareAltNames( const ATTRIBUTE_LIST *subjectAttributes,
											 const ATTRIBUTE_LIST *issuerAttributes )
	{
	ATTRIBUTE_LIST *subjectAttributeListPtr, *issuerAttributeListPtr;

	/* Check the otherName */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_OTHERNAME_TYPEID );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_OTHERNAME_TYPEID );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_OTHERNAME_TYPEID );
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_OTHERNAME_VALUE );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_OTHERNAME_VALUE );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_OTHERNAME_VALUE );

	/* Check the email address */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_RFC822NAME );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_RFC822NAME );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_RFC822NAME );

	/* Check the DNS name */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_DNSNAME );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_DNSNAME );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_DNSNAME );

	/* Check the directory name */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_DIRECTORYNAME );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_DIRECTORYNAME );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_DIRECTORYNAME );

	/* Check the EDI party name */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_EDIPARTYNAME_NAMEASSIGNER );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_EDIPARTYNAME_NAMEASSIGNER );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_EDIPARTYNAME_NAMEASSIGNER );
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME );

	/* Check the URI */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );

	/* Check the IP address */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_IPADDRESS );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_IPADDRESS );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_IPADDRESS );

	/* Check the registered ID */
	subjectAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_ISSUERALTNAME, CRYPT_CERTINFO_REGISTEREDID );
	issuerAttributeListPtr = findAttributeField( issuerAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_REGISTEREDID );
	if( !compareAttributeComponents( subjectAttributeListPtr,
									 issuerAttributeListPtr ) )
		return( CRYPT_CERTINFO_REGISTEREDID );

	return( CRYPT_ATTRIBUTE_NONE );
	}

/* Perform a wildcarded compare or two strings in attributes */

static BOOLEAN wildcardStringMatch( const char *wildcardString, 
									const char *string )
	{
	while( *wildcardString && *string )
		{
		/* Match a wildcard */
		if( *wildcardString == '*' )
			{
			BOOLEAN isMatch = FALSE;

			/* Skip '*'s and exit if we've reached the end of the pattern */
			while( *wildcardString == '*' )
				wildcardString++;
			if( !*wildcardString )
				return( TRUE );

			/* Match to the next literal, then match the next section with
			   backtracking in case of a mismatch */
			while( *string && *wildcardString != *string )
				string++;
			while( *string && !isMatch )
				{
				isMatch = wildcardStringMatch( wildcardString, string );
				if( !isMatch )
					string++;
				}

			return( isMatch );
			}
		else
			if( *wildcardString != *string )
				return( FALSE );

		wildcardString++;
		string++;
		}

	/* If there are literals left in the wildcard or text string, we haven't
	   found a match yet */
	if( *wildcardString && ( *wildcardString != '*' || *++wildcardString ) )
		return( FALSE );
	return( *string ? FALSE : TRUE );
	}

static BOOLEAN wildcardMatch( const ATTRIBUTE_LIST *constrainedAttribute,
							  const ATTRIBUTE_LIST *attribute,
							  const BOOLEAN errorStatus )
	{
	const char *constrainedString = \
		( constrainedAttribute->dataLength <= CRYPT_MAX_TEXTSIZE ) ? \
		( char * ) constrainedAttribute->smallData : constrainedAttribute->data;
	const char *string = ( attribute->dataLength <= CRYPT_MAX_TEXTSIZE ) ? \
		( char * ) attribute->smallData : attribute->data;
	int count = 0, i;

	/* Perform a quick damage-control check to prevent excessive recursion:
	   There shouldn't be more than ten wildcard chars present (realistically
	   there shouldn't be more than one) */
	for( i = 0; string[ i ]; i++ )
		if( string[ i ] == '*' )
			count++;
	if( count > 10 )
		return( errorStatus );

	/* Pass the call on to the string matcher (this is recursive so we can't
	   do the match in this function) */
	return( wildcardStringMatch( string, constrainedString ) );
	}

/* Check name constraints placed by an issuer.  matchValue = TRUE for
   excluded subtrees (fail on a match), FALSE for included subtrees (fail on
   a mismatch) */

int checkNameConstraints( CERT_INFO *subjectCertInfoPtr,
						  const ATTRIBUTE_LIST *issuerAttributes,
						  const BOOLEAN matchValue )
	{
	const ATTRIBUTE_LIST *subjectAttributes = subjectCertInfoPtr->attributes;
	const CRYPT_ATTRIBUTE_TYPE constraintType = ( matchValue ) ? \
		CRYPT_CERTINFO_EXCLUDEDSUBTREES : CRYPT_CERTINFO_PERMITTEDSUBTREES;
	ATTRIBUTE_LIST *attributeListPtr, *constrainedAttributeListPtr;
	int status = CRYPT_OK;

	/* Compare the DN if a constraint exists */
	attributeListPtr = findAttributeField( issuerAttributes,
							constraintType, CRYPT_CERTINFO_DIRECTORYNAME );
	if( compareDN( subjectCertInfoPtr->subjectName,
				   attributeListPtr->data, TRUE ) == matchValue )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_SUBJECTNAME,
					  CRYPT_ERRTYPE_CONSTRAINT );
		return( CRYPT_ERROR_INVALID );
		}

	/* Compare the Internet-related names if constraints exist */
	attributeListPtr = findAttributeField( issuerAttributes,
							constraintType, CRYPT_CERTINFO_RFC822NAME );
	constrainedAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_RFC822NAME );
	if( attributeListPtr != NULL && constrainedAttributeListPtr != NULL && \
		wildcardMatch( constrainedAttributeListPtr, attributeListPtr,
					   FALSE ) == matchValue )
		status = CRYPT_ERROR_INVALID;
	attributeListPtr = findAttributeField( issuerAttributes,
							constraintType, CRYPT_CERTINFO_DNSNAME );
	constrainedAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_DNSNAME );
	if( attributeListPtr != NULL && constrainedAttributeListPtr != NULL && \
		wildcardMatch( constrainedAttributeListPtr, attributeListPtr,
					   FALSE ) == matchValue )
		status = CRYPT_ERROR_INVALID;
	attributeListPtr = findAttributeField( issuerAttributes,
							constraintType, CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
	constrainedAttributeListPtr = findAttributeField( subjectAttributes,
			CRYPT_CERTINFO_SUBJECTALTNAME, CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
	if( attributeListPtr != NULL && constrainedAttributeListPtr != NULL && \
		wildcardMatch( constrainedAttributeListPtr, attributeListPtr,
					   FALSE ) == matchValue )
		status = CRYPT_ERROR_INVALID;
	if( cryptStatusError( status ) )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_SUBJECTALTNAME,
					  CRYPT_ERRTYPE_CONSTRAINT );
		return( status );
		}

	return( CRYPT_OK );
	}

/* Check policy constraints placed by an issuer */

int checkPolicyConstraints( CERT_INFO *subjectCertInfoPtr,
							const ATTRIBUTE_LIST *issuerAttributes )
	{
	ATTRIBUTE_LIST *attributeListPtr, *constrainedAttributeListPtr;

	/* Compare the issuer and subject policies if constraints exist */
	attributeListPtr = findAttributeField( issuerAttributes,
						CRYPT_CERTINFO_CERTPOLICYID, CRYPT_ATTRIBUTE_NONE );
	constrainedAttributeListPtr = findAttributeField( subjectCertInfoPtr->attributes,
						CRYPT_CERTINFO_CERTPOLICYID, CRYPT_ATTRIBUTE_NONE );
	if( constrainedAttributeListPtr == NULL || \
		attributeListPtr->dataLength != constrainedAttributeListPtr->dataLength || \
		memcmp( attributeListPtr->smallData, constrainedAttributeListPtr->smallData,
				attributeListPtr->dataLength ) )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_CERTPOLICYID,
					  CRYPT_ERRTYPE_CONSTRAINT );
		return( CRYPT_ERROR_INVALID );
		}

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						Check for Constraint Violations						*
*																			*
****************************************************************************/

/* Check the validity of a CRL based on an issuer cert */

static int checkCRL( CERT_INFO *crlInfoPtr,
					 const CERT_INFO *issuerCertInfoPtr )
	{
	ATTRIBUTE_LIST *attributeListPtr;

	/* If it's a delta CRL, make sure the CRL numbers make sense (that is,
	   that the delta CRL was issued after the full CRL) */
	attributeListPtr = findAttribute( crlInfoPtr->attributes,
									  CRYPT_CERTINFO_DELTACRLINDICATOR );
	if( attributeListPtr != NULL )
		{
		const int deltaCRLindicator = ( int ) attributeListPtr->value;

		attributeListPtr = findAttribute( crlInfoPtr->attributes,
										  CRYPT_CERTINFO_CRLNUMBER );
		if( attributeListPtr != NULL && \
			attributeListPtr->value >= deltaCRLindicator )
			{
			setErrorInfo( crlInfoPtr, CRYPT_CERTINFO_DELTACRLINDICATOR,
						  CRYPT_ERRTYPE_CONSTRAINT );
			return( CRYPT_ERROR_INVALID );
			}
		}

	/* If a key usage attribute is present, make sure the issuer can sign
	   CRL's */
	attributeListPtr = findAttribute( issuerCertInfoPtr->attributes,
									  CRYPT_CERTINFO_KEYUSAGE );
	if( attributeListPtr != NULL )
		{
		if( !( attributeListPtr->value & issuerCertInfoPtr->trustedUsage & \
			   CRYPT_KEYUSAGE_CRLSIGN ) )
			{
			setErrorInfo( crlInfoPtr, 
						  ( attributeListPtr->value & CRYPT_KEYUSAGE_CRLSIGN ) ? \
							CRYPT_CERTINFO_TRUSTED_USAGE : CRYPT_CERTINFO_KEYUSAGE,
						  CRYPT_ERRTYPE_ISSUERCONSTRAINT );
			return( CRYPT_ERROR_INVALID );
			}
		}
	else
		/* There's no key usage present, make sure the issuer is at least 
		   trusted to sign CRL's */
		if( !( issuerCertInfoPtr->trustedUsage & CRYPT_KEYUSAGE_CRLSIGN ) )
			{
			setErrorInfo( crlInfoPtr, CRYPT_CERTINFO_TRUSTED_USAGE,
						  CRYPT_ERRTYPE_ISSUERCONSTRAINT );
			return( CRYPT_ERROR_INVALID );
			}


	/* If a basic constraints attribute is present, make sure the issuer is
	   a CA */
	attributeListPtr = findAttribute( issuerCertInfoPtr->attributes,
									  CRYPT_CERTINFO_CA );
	if( attributeListPtr != NULL && !attributeListPtr->value )
		{
		setErrorInfo( crlInfoPtr, CRYPT_CERTINFO_CA,
					  CRYPT_ERRTYPE_ISSUERCONSTRAINT );
		return( CRYPT_ERROR_INVALID );
		}

	return( CRYPT_OK );
	}

/* Check the validity of a subject cert based on an issuer cert */

int checkCert( CERT_INFO *subjectCertInfoPtr,
			   const CERT_INFO *issuerCertInfoPtr )
	{
	const ATTRIBUTE_LIST *subjectAttributes = subjectCertInfoPtr->attributes;
	const ATTRIBUTE_LIST *issuerAttributes = issuerCertInfoPtr->attributes;
	ATTRIBUTE_LIST *attributeListPtr;
	BOOLEAN subjectIsCA = FALSE, issuerIsCA = FALSE, boolean1, boolean2;
	const time_t currentTime = time( NULL );
	int validityNesting, status;

	/* If it's some form of certificate request or an OCSP object, there's 
	   nothing to check (yet) */
	if( subjectCertInfoPtr->type == CRYPT_CERTTYPE_CERTREQUEST || \
		subjectCertInfoPtr->type == CRYPT_CERTTYPE_REQUEST_CERT || \
		subjectCertInfoPtr->type == CRYPT_CERTTYPE_REQUEST_REVOCATION || \
		subjectCertInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST || \
		subjectCertInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE )
		return( CRYPT_OK );

	/* If we're checking a CRL, call the special-case routine for this */
	if( subjectCertInfoPtr->type == CRYPT_CERTTYPE_CRL )
		return( checkCRL( subjectCertInfoPtr, issuerCertInfoPtr ) );

	/* Check that the validity period is in order.  If we're checking an 
	   existing cert then the start time has to be valid, if we're creating
	   a new cert then it doesn't have to be valid since the cert could be
	   created for use in the future */
	if( subjectCertInfoPtr->startTime >= subjectCertInfoPtr->endTime || \
		( subjectCertInfoPtr->certificate != NULL && \
		  currentTime < subjectCertInfoPtr->startTime ) )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_VALIDFROM,
					  CRYPT_ERRTYPE_CONSTRAINT );
		return( CRYPT_ERROR_INVALID );
		}
	if( currentTime > subjectCertInfoPtr->endTime )
		{
		setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_VALIDTO,
					  CRYPT_ERRTYPE_CONSTRAINT );
		return( CRYPT_ERROR_INVALID );
		}

	/* If it's a self-signed cert and we've already checked it, there's no 
	   need to perform any further checks again except to make sure that the
	   trusted usage hasn't changed */
	if( ( subjectCertInfoPtr->flags & CERT_FLAG_SELFSIGNED ) && \
		( subjectCertInfoPtr->flags & CERT_FLAG_CERTCHECKED ) )
		{
		if( !( subjectCertInfoPtr->trustedUsage & CRYPT_KEYUSAGE_KEYCERTSIGN ) )
			{
			setErrorInfo( subjectCertInfoPtr, CRYPT_CERTINFO_TRUSTED_USAGE,
						  CRYPT_ERRTYPE_CONSTRAINT );
			return( CRYPT_ERROR_INVALID );
			}
		return( CRYPT_OK );
		}

	/* Determine whether the subject or issuer are CA certs */
	attributeListPtr = findAttributeField( subjectAttributes, 
									CRYPT_CERTINFO_CA, CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL )
		subjectIsCA = ( BOOLEAN ) attributeListPtr->value;
	attributeListPtr = findAttributeField( issuerAttributes,
									CRYPT_CERTINFO_CA, CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL )
		issuerIsCA = ( BOOLEAN ) attributeListPtr->value;

⌨️ 快捷键说明

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