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

📄 chk_cert.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
			   check - we can't even check the issuer since they're not 
			   normally issued by CAs */
			return( CRYPT_OK );

		default:
			retIntError();
		}
	ENSURES( issuerCertInfoPtr != NULL );

	/* There is one universal case in which a certificate is regarded as 
	   invalid and that's when it's explicitly not trusted for the purpose.  
	   We perform the check at this point in oblivious mode to ensure that 
	   only the basic trusted usage gets checked */
	if( issuerCertInfoPtr->cCertCert->trustedUsage != CRYPT_ERROR )
		{
		status = checkKeyUsage( issuerCertInfoPtr, CHECKKEY_FLAG_CA, 
								CRYPT_KEYUSAGE_KEYCERTSIGN,
								CRYPT_COMPLIANCELEVEL_OBLIVIOUS, 
								errorLocus, errorType );
		if( cryptStatusError( status ) )
			{
			/* There was a problem with the issuer certificate, convert the 
			   error to an issuer constraint */
			*errorType = CRYPT_ERRTYPE_ISSUERCONSTRAINT;
			return( status );
			}
		}

	/* If we're running in oblivious mode, we're done */
	if( complianceLevel < CRYPT_COMPLIANCELEVEL_REDUCED )
		return( CRYPT_OK );

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

	/* If it's a self-signed certificate or if we're doing a short-circuit 
	   check of a certificate in a chain that's already been checked and 
	   we've already checked it at the appropriate level then there's no 
	   need to perform any further checks */
	if( ( subjectSelfSigned || shortCircuitCheck ) && \
		( subjectCertInfoPtr->cCertCert->maxCheckLevel >= complianceLevel ) )
		return( CRYPT_OK );

	/* If the certificate isn't self-signed, check name chaining */
	if( !subjectSelfSigned )
		{
		/* Check that the subject issuer name and issuer subject name chain
		   properly.  If the DNs are present in pre-encoded form we do a 
		   binary comparison, which is faster than calling compareDN() */
		if( subjectCertInfoPtr->certificate != NULL )
			{
			if( subjectCertInfoPtr->issuerDNsize != \
									issuerCertInfoPtr->subjectDNsize || \
				memcmp( subjectCertInfoPtr->issuerDNptr, 
						issuerCertInfoPtr->subjectDNptr, 
						subjectCertInfoPtr->issuerDNsize ) )
				{
				setErrorValues( CRYPT_CERTINFO_ISSUERNAME, 
								CRYPT_ERRTYPE_CONSTRAINT );
				return( CRYPT_ERROR_INVALID );
				}
			}
		else
			{
			if( !compareDN( subjectCertInfoPtr->issuerName,
							issuerCertInfoPtr->subjectName, FALSE ) )
				{
				setErrorValues( CRYPT_CERTINFO_ISSUERNAME, 
								CRYPT_ERRTYPE_CONSTRAINT );
				return( CRYPT_ERROR_INVALID );
				}
			}
		}

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

	/* If we're doing a reduced level of checking, we're done */
	if( complianceLevel < CRYPT_COMPLIANCELEVEL_STANDARD )
		{
		if( subjectCertInfoPtr->cCertCert->maxCheckLevel < complianceLevel )
			subjectCertInfoPtr->cCertCert->maxCheckLevel = complianceLevel;
		return( CRYPT_OK );
		}

	/* Check that the certificate usage flags are present and consistent.  
	   The key usage checking level ranges up to 
	   CRYPT_COMPLIANCELEVEL_PKIX_PARTIAL so we re-do the check even if it's 
	   already been done at a lower level */
	if( subjectCertInfoPtr->cCertCert->maxCheckLevel < CRYPT_COMPLIANCELEVEL_PKIX_PARTIAL && \
		subjectCertInfoPtr->type != CRYPT_CERTTYPE_ATTRIBUTE_CERT )
		{
		status = checkKeyUsage( subjectCertInfoPtr, CHECKKEY_FLAG_GENCHECK, 
								CRYPT_KEYUSAGE_NONE, complianceLevel, 
								errorLocus, errorType );
		if( cryptStatusError( status ) )
			return( status );
        }

	/* If the certificate isn't self-signed check that issuer is a CA */
	if( !subjectSelfSigned )
		{
		status = checkKeyUsage( issuerCertInfoPtr, CHECKKEY_FLAG_CA, 
								CRYPT_KEYUSAGE_KEYCERTSIGN, complianceLevel, 
								errorLocus, errorType );
		if( cryptStatusError( status ) )
			{
			/* There was a problem with the issuer certificate, convert the 
			   error to an issuer constraint */
			*errorType = CRYPT_ERRTYPE_ISSUERCONSTRAINT;
			return( status );
			}
		}

	/* Check all the blob (unrecognised) attributes to see if any are marked 
	   critical.  We only do this if it's an existing certificate that we've
	   imported rather than one that we've just created since applying this 
	   check to the latter would make it impossible to create certificates 
	   with unrecognised critical extensions */
	if( subjectCertInfoPtr->certificate != NULL )
		{
		int iterationCount;
		
		for( attributeListPtr = subjectAttributes, iterationCount = 0;
			 attributeListPtr != NULL && \
				!isBlobAttribute( attributeListPtr ) && \
				iterationCount < FAILSAFE_ITERATIONS_LARGE; 
			 attributeListPtr = attributeListPtr->next, iterationCount++ );
		ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
		for( ; attributeListPtr != NULL && \
				iterationCount < FAILSAFE_ITERATIONS_LARGE;
			 attributeListPtr = attributeListPtr->next, iterationCount++ )
			{
			/* If we've found an unrecognised critical extension, reject the 
			   certificate (PKIX section 4.2).  The one exception to this is 
			   if the attribute was recognised but has been ignored at this 
			   compliance level, in which case it's treated as a blob
			   attribute */
			if( ( attributeListPtr->flags & ATTR_FLAG_CRITICAL ) && \
				!( attributeListPtr->flags & ATTR_FLAG_IGNORED ) )
				{
				setErrorValues( CRYPT_ATTRIBUTE_NONE, 
								CRYPT_ERRTYPE_CONSTRAINT );
				return( CRYPT_ERROR_INVALID );
				}
			}
		ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
		}

	/* If we're not doing at least partial PKIX checking, we're done */
	if( complianceLevel < CRYPT_COMPLIANCELEVEL_PKIX_PARTIAL )
		{
		if( subjectCertInfoPtr->cCertCert->maxCheckLevel < complianceLevel )
			subjectCertInfoPtr->cCertCert->maxCheckLevel = complianceLevel;
		return( CRYPT_OK );
		}

	/* Constraints can only be present in CA certificates.  The issuer may 
	   not be a proper CA if it's a self-signed end entity certificate or 
	   an X.509v1 CA certificate, which is why we also check for 
	   !issuerIsCA */
	if( subjectAttributes != NULL )
		{
		if( !subjectIsCA && invalidAttributesPresent( subjectAttributes, FALSE, 
													  errorLocus, errorType ) )
			return( CRYPT_ERROR_INVALID );
		if( !issuerIsCA && invalidAttributesPresent( subjectAttributes, TRUE, 
													 errorLocus, errorType ) )
			return( CRYPT_ERROR_INVALID );
		}

	/*  From this point onwards if we're doing a short-circuit check of 
	    certificates in a chain we don't apply constraint checks.  This is 
		because the certificate-chain code has already performed far more 
		complete checks of the various constraints set by all the 
		certificates in the chain rather than just the current certificate 
		issuer : subject pair */

	/* If there's a path length constraint present, apply it */
	attributeListPtr = findAttributeField( issuerAttributes,
										   CRYPT_CERTINFO_PATHLENCONSTRAINT, 
										   CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL && !shortCircuitCheck )
		{
		status = checkPathConstraints( subjectCertInfoPtr, attributeListPtr,
									   errorLocus, errorType );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* In order to dig itself out of a hole caused by a circular definition, 
	   RFC 3280 added a new extKeyUsage anyExtendedKeyUsage (rather than the
	   more obvious fix of removing the problematic definition).  
	   Unfortunately this causes more problems than it solves because the exact
	   semantics of this new usage aren't precisely defined.  To fix this 
	   problem we invent some plausible ones ourselves: If the only eKU is 
	   anyKU we treat the overall extKeyUsage as empty, i.e. there are no
	   particular restrictions on usage.  If any other usage is present the 
	   extension has become self-contradictory so we treat the anyKU as
	   being absent.  See the comment for getExtendedKeyUsageFlags() for how
	   this is handled */
	attributeListPtr = findAttributeField( subjectAttributes,
										   CRYPT_CERTINFO_EXTKEY_ANYKEYUSAGE, 
										   CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL && \
		( attributeListPtr->flags & ATTR_FLAG_CRITICAL ) )
		{
		/* If anyKU is present the extension must be non-critical 
		   (PKIX section 4.2.1.13) */
		setErrorValues( CRYPT_CERTINFO_EXTKEY_ANYKEYUSAGE, 
						CRYPT_ERRTYPE_CONSTRAINT );
		return( CRYPT_ERROR_INVALID );
		}

	/* If we're not doing full PKIX checking, we're done.  In addition since 
	   all of the remaining checks are constraint checks we can exit at this
	   point if we're doing a short-circuit check */
	if( complianceLevel < CRYPT_COMPLIANCELEVEL_PKIX_FULL || \
		shortCircuitCheck )
		{
		if( subjectCertInfoPtr->cCertCert->maxCheckLevel < complianceLevel )
			subjectCertInfoPtr->cCertCert->maxCheckLevel = complianceLevel;
		return( CRYPT_OK );
		}

	/* If the issuing certificate has name constraints and isn't 
	   self-signed make sure that the subject name and altName falls within 
	   the constrained subtrees.  Since excluded subtrees override permitted 
	   subtrees we check these first */
	if( !subjectSelfSigned )
		{
		attributeListPtr = findAttributeField( issuerAttributes, 
											   CRYPT_CERTINFO_EXCLUDEDSUBTREES,
											   CRYPT_ATTRIBUTE_NONE );
		if( attributeListPtr != NULL && \
			cryptStatusError( \
				checkNameConstraints( subjectCertInfoPtr, attributeListPtr, 
									  TRUE, errorLocus, errorType ) ) )
			return( CRYPT_ERROR_INVALID );
		attributeListPtr = findAttributeField( issuerAttributes, 
											   CRYPT_CERTINFO_PERMITTEDSUBTREES,
											   CRYPT_ATTRIBUTE_NONE );
		if( attributeListPtr != NULL && \
			cryptStatusError( \
				checkNameConstraints( subjectCertInfoPtr, attributeListPtr, 
									  FALSE, errorLocus, errorType ) ) )
			return( CRYPT_ERROR_INVALID );
		}

	/* If there's a policy constraint present and the skip count is set to 
	   zero (i.e. the constraint applies to the current certificate) check 
	   the issuer constraints against the subject */
	attributeListPtr = findAttributeField( issuerAttributes,
										   CRYPT_CERTINFO_REQUIREEXPLICITPOLICY,
										   CRYPT_ATTRIBUTE_NONE );
	if( attributeListPtr != NULL && attributeListPtr->intValue <= 0 )
		{
		POLICY_TYPE policyType = POLICY_SUBJECT;

		/* Check whether use of the the wildcard anyPolicy has been 
		   disallowed */
		attributeListPtr = findAttribute( issuerCertInfoPtr->attributes, \
										  CRYPT_CERTINFO_INHIBITANYPOLICY, 
										  TRUE );
		if( attributeListPtr != NULL && attributeListPtr->intValue <= 0 )
			policyType = POLICY_SUBJECT_SPECIFIC;

		/* Apply the appropriate policy constraint */
		status = checkPolicyConstraints( subjectCertInfoPtr,
										 issuerAttributes, policyType,
										 errorLocus, errorType );
		if( cryptStatusError( status ) )
			return( status );
		}

	if( subjectCertInfoPtr->cCertCert->maxCheckLevel < complianceLevel )
		subjectCertInfoPtr->cCertCert->maxCheckLevel = complianceLevel;
	return( CRYPT_OK );
	}

⌨️ 快捷键说明

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