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

📄 chk_chn.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
			else
				policyType = inhibitAnyPolicy ? \
							 POLICY_NONE_SPECIFIC : POLICY_NONE;
			}

		/* Check that the current cert in the chain obeys the constraints 
		   set by the overall issuer, possibly modified by other certs in
		   the chain */
		if( hasExcludedSubtrees && \
			cryptStatusError( checkNameConstraints( subjectCertInfoPtr,
										nameConstraintPtr, TRUE,
										&subjectCertInfoPtr->errorLocus, 
										&subjectCertInfoPtr->errorType ) ) )
			status = CRYPT_ERROR_INVALID;
		if( cryptStatusOK( status ) && hasPermittedSubtrees && \
			cryptStatusError( checkNameConstraints( subjectCertInfoPtr,
										nameConstraintPtr, FALSE,
										&subjectCertInfoPtr->errorLocus, 
										&subjectCertInfoPtr->errorType ) ) )
			status = CRYPT_ERROR_INVALID;
		if( cryptStatusOK( status ) && hasPolicy && \
			cryptStatusError( checkPolicyConstraints( subjectCertInfoPtr,
										issuerCertInfoPtr->attributes, policyType,
										&subjectCertInfoPtr->errorLocus, 
										&subjectCertInfoPtr->errorType ) ) )
			status = CRYPT_ERROR_INVALID;
		if( cryptStatusOK( status ) && hasPathLength && \
			cryptStatusError( checkPathConstraints( subjectCertInfoPtr,
										&pathAttributeList, 
										CRYPT_COMPLIANCELEVEL_PKIX_FULL,
										&subjectCertInfoPtr->errorLocus, 
										&subjectCertInfoPtr->errorType ) ) )
			status = CRYPT_ERROR_INVALID;
		if( cryptStatusError( status ) )
			/* Remember which cert caused the problem */
			*errorCertIndex = certIndex;

		/* If there are length constraints, decrement them for each cert.  
		   At this point we run into another piece of PKIX weirdness: If
		   there's a path-kludge cert present, it's not counted for path-
		   length constraint purposes, but the exception only holds for path-
		   length constraint purposes, not for require/inhibit policy 
		   constraint purposes.  This is an error in the spec, sections 
		   4.2.1.12 (policy constraints) and 4.2.1.15 (path constraints) 
		   don't permit path-kludge cert exceptions while section 6.1.4(h) 
		   does.  On the other hand given the confusion in the pseudocode 
		   and the fact that it diverges from the body of the spec in other 
		   places as well, we treat it as an error in the (non-
		   authoritative) pseudocode rather than the (authoritative) spec.
		    
		   Unfortunately there's no easy way to tell just from looking at a 
		   cert whether it's one of these kludge certs or not, because it 
		   looks identical to a CA root cert (even the path-building code 
		   has to handle this speculatively, falling back to alternatives 
		   if the initial attempt to construct a path fails).

		   However, for chain-internal kludge certs the chain-assembly code 
		   can determine whether it's a path-kludge by the presence of 
		   further certs higher up in the chain (although it can't tell 
		   whether the chain ends in a path-kludge or a true CA root cert 
		   because they appear identical).  In the case where the chain-
		   assembly code has been able to identify the cert as a path-
		   kludge, we can skip it for path length constraint purposes */
		if( hasPathLength && \
			( !( subjectCertInfoPtr->flags & CERT_FLAG_PATHKLUDGE ) ) )
			pathAttributeList.intValue--;
		if( hasExplicitPolicy )
			requireExplicitPolicyLevel--;
		if( hasInhibitPolicyMap )
			inhibitPolicyMapLevel--;
		if( hasInhibitAnyPolicy )
			inhibitAnyPolicyLevel--;

		/* Release the cert again unless it's the chain cert itself, which
		   is returned by getCertInfo() as the last cert in the chain */
		if( certInfoPtr != subjectCertInfoPtr )
			krnlReleaseObject( subjectCertInfoPtr->objectHandle );
		}

	return( status );
	}

/* Walk down a chain checking each certificate */

int checkCertChain( CERT_INFO *certInfoPtr )
	{
	CRYPT_CERTIFICATE iIssuerCert;
	CERT_CERT_INFO *certChainInfo = certInfoPtr->cCertCert;
	CERT_INFO *issuerCertInfoPtr, *subjectCertInfoPtr;
	BOOLEAN explicitPolicy = TRUE;
	int certIndex, complianceLevel, status;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	/* Determine how much checking we need to perform */
	status = krnlSendMessage( certInfoPtr->ownerHandle, IMESSAGE_GETATTRIBUTE,
							  &complianceLevel, 
							  CRYPT_OPTION_CERT_COMPLIANCELEVEL );
	if( cryptStatusError( status ) )
		return( status );
	if( complianceLevel >= CRYPT_COMPLIANCELEVEL_PKIX_FULL )
		{
		int value;

		status = krnlSendMessage( certInfoPtr->ownerHandle, 
								  IMESSAGE_GETATTRIBUTE, &value, 
								  CRYPT_OPTION_CERT_REQUIREPOLICY );
		if( cryptStatusOK( status ) && !value )
			explicitPolicy = FALSE;
		}

	/* Try and find a trust anchor for the chain */
	status = findTrustAnchor( certInfoPtr, &certIndex, &iIssuerCert );
	if( status == OK_SPECIAL )
		/* The leaf is implicitly trusted, there's nothing more to do */
		return( CRYPT_OK );
	if( cryptStatusError( status ) )
		{
		int value;

		/* We couldn't find a trust anchor, either there's a missing link in 
		   the chain (CRYPT_ERROR_STUART) and it was truncated before we got 
		   to a trusted cert, or it goes to a root cert but it isn't 
		   trusted */
		certChainInfo->chainPos = certChainInfo->chainEnd - 1;
		status = krnlSendMessage( certChainInfo->chain[ certChainInfo->chainEnd - 1 ], 
								  IMESSAGE_GETATTRIBUTE, &value, 
								  CRYPT_CERTINFO_SELFSIGNED );
		if( cryptStatusOK( status ) && value )
			{
			/* We got a root cert but it's not trusted */
			setErrorInfo( certInfoPtr, CRYPT_CERTINFO_TRUSTED_IMPLICIT,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			}
		else
			{
			/* There's a missing link in the chain and it stops at this 
			   cert */
			setErrorInfo( certInfoPtr, CRYPT_CERTINFO_CERTIFICATE,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			}

		return( CRYPT_ERROR_INVALID );
		}
	status = krnlAcquireObject( iIssuerCert, OBJECT_TYPE_CERTIFICATE, 
								( void ** ) &issuerCertInfoPtr, 
								CRYPT_ERROR_SIGNALLED );
	if( cryptStatusError( status ) )
		return( status );

	/* Check the trust anchor.  Since this is the start of the chain there 
	   aren't any constraints placed on it by higher-level certs, so all 
	   that we need to check at this point is the cert itself and its 
	   signature if it's self-signed */
	if( certIndex >= certChainInfo->chainEnd )
		{
		CRYPT_ATTRIBUTE_TYPE dummyLocus;
		CRYPT_ERRTYPE_TYPE dummyType;

		/* The issuer cert info is coming from the cert trust database, 
		   don't modify its state when we check it */
		status = checkCert( issuerCertInfoPtr, issuerCertInfoPtr,
							TRUE, &dummyLocus, &dummyType );
		}
	else
		/* The issuer cert is contained in the chain, update its state when
		   we check it */
		status = checkCert( issuerCertInfoPtr, issuerCertInfoPtr,
							TRUE, &issuerCertInfoPtr->errorLocus, 
							&issuerCertInfoPtr->errorType );
	if( cryptStatusOK( status ) && \
		( issuerCertInfoPtr->flags & CERT_FLAG_SELFSIGNED ) && \
		issuerCertInfoPtr->iPubkeyContext != CRYPT_ERROR )
		status = checkX509signature( issuerCertInfoPtr->certificate, 
									 issuerCertInfoPtr->certificateSize,
									 NULL, NULL, 
									 issuerCertInfoPtr->iPubkeyContext, 
									 CRYPT_UNUSED );
	if( cryptStatusError( status ) )
		{
		krnlReleaseObject( issuerCertInfoPtr->objectHandle );
		if( certIndex < certChainInfo->chainEnd )
			certChainInfo->chainPos = certIndex;
		return( status );
		}

	/* We've checked the trust anchor, move on to the next cert */
	certIndex--;

	/* Walk down the chain from the trusted cert checking each link in turn */
	while( cryptStatusOK( status ) && certIndex >= -1 && \
		   ( status = getCertInfo( certInfoPtr, &subjectCertInfoPtr,
								   certIndex ) ) == CRYPT_OK )
		{
		/* Check the chaining from issuer to subject (as well as various 
		   other required bits and pieces such as whether the issuer is 
		   really a CA) */
		status = checkCert( subjectCertInfoPtr, issuerCertInfoPtr,
							TRUE, &subjectCertInfoPtr->errorLocus, 
							&subjectCertInfoPtr->errorType );

		/* Check the signature on the subject cert unless it's a data-only
		   cert for which there isn't a context present.  This is OK since
		   the only time that we can have a data-only chain is when we're 
		   reading from an (implicitly trusted) private key store */
		if( cryptStatusOK( status ) && \
			issuerCertInfoPtr->iPubkeyContext != CRYPT_ERROR )
			status = checkX509signature( subjectCertInfoPtr->certificate, 
										 subjectCertInfoPtr->certificateSize,
										 NULL, NULL, 
										 issuerCertInfoPtr->iPubkeyContext, 
										 CRYPT_UNUSED );

		/* Check any constraints that the issuer cert may place on the rest 
		   of the chain */
		if( cryptStatusOK( status ) && \
			complianceLevel >= CRYPT_COMPLIANCELEVEL_PKIX_FULL )
			{
			int errorCertIndex;

			status = checkConstraints( certInfoPtr, certIndex, 
									   issuerCertInfoPtr, &errorCertIndex,
									   explicitPolicy );
			if( cryptStatusError( status ) )
				certIndex = errorCertIndex;
			}

		/* Move on to the next cert */
		krnlReleaseObject( issuerCertInfoPtr->objectHandle );
		issuerCertInfoPtr = subjectCertInfoPtr;
		certIndex--;
		}

	/* If we stopped before we processed all the certs in the chain, select
	   the one that caused the problem.  We also have to unlock the last 
	   cert that we got to if it wasn't the leaf, which corresponds to the 
	   chain itself */
	if( cryptStatusError( status ) )
		{
		certChainInfo->chainPos = certIndex + 1;
		if( issuerCertInfoPtr != certInfoPtr )
			krnlReleaseObject( issuerCertInfoPtr->objectHandle );
		}

	return( status );
	}

⌨️ 快捷键说明

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