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

📄 cryptcrt.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
			messageValue >= CRYPT_FIRST_EXTENSION && messageValue <= CRYPT_LAST_EXTENSION;

		/* If it's a completed certificate, we can only add a restricted 
		   class of component selection control values to the object */
		assert( certInfoPtr->certificate == NULL || \
				isDNSelectionComponent( messageValue ) || \
				isGeneralNameSelectionComponent( messageValue ) || \
				isCursorComponent( messageValue ) || \
				isControlComponent( messageValue ) || \
				messageValue == CRYPT_IATTRIBUTE_INITIALISED || \
				messageValue == CRYPT_IATTRIBUTE_PKIUSERINFO );

		/* If it's an initialisation message, there's nothing to do (we get 
		   these when importing a cert, when the import is complete the 
		   import code sends this message to move the cert into the high
		   state because it's already signed) */
		if( messageValue == CRYPT_IATTRIBUTE_INITIALISED )
			return( CRYPT_OK );

		/* Handle internal attributes */
		if( messageValue == CRYPT_IATTRIBUTE_OCSPREQUEST )
			{
			CERT_INFO *ocspRequestInfoPtr;
			int status;

			assert( certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE );

			/* Copy the revocation information from the request to the
			   response */
			getCheckInternalResource( *valuePtr, ocspRequestInfoPtr, 
									  OBJECT_TYPE_CERTIFICATE );
			assert( ocspRequestInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST );
			status = copyRevocationEntries( &certInfoPtr->revocations,
							ocspRequestInfoPtr->revocations, 
							&certInfoPtr->errorLocus, &certInfoPtr->errorType );
			if( cryptStatusOK( status ) )
				status = copyRequestAttributes( &certInfoPtr->attributes,
							ocspRequestInfoPtr->attributes,
							&certInfoPtr->errorLocus, &certInfoPtr->errorType );
			unlockResource( ocspRequestInfoPtr );

			return( status );
			}

		/* If the passed-in value is a cursor-positioning code, make sure 
		   it's valid */
		if( *valuePtr < 0 && *valuePtr != CRYPT_UNUSED && \
			( *valuePtr > CRYPT_CURSOR_FIRST || *valuePtr < CRYPT_CURSOR_LAST ) &&
			!validCursorPosition && messageValue != CRYPT_CERTINFO_SELFSIGNED )
			return( CRYPT_ARGERROR_NUM1 );

		return( addCertComponent( certInfoPtr, messageValue, valuePtr, 
								  CRYPT_UNUSED ) );
		}
	if( message == RESOURCE_MESSAGE_SETATTRIBUTE_S )
		return( addCertComponent( certInfoPtr, messageValue, msgData->data, 
								  msgData->length ) );
	if( message == RESOURCE_MESSAGE_DELETEATTRIBUTE )
		return( deleteCertComponent( certInfoPtr, messageValue ) );

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

/* Handle a message sent to a certificate context */

static int certificateMessageFunction( const CRYPT_CERTIFICATE certificate,
									   const RESOURCE_MESSAGE_TYPE message,
									   void *messageDataPtr,
									   const int messageValue )
	{
	CERT_INFO *certInfoPtr;

	getCheckInternalResource( certificate, certInfoPtr, OBJECT_TYPE_CERTIFICATE );

	/* Process destroy object messages */
	if( message == RESOURCE_MESSAGE_DESTROY )
		{
		/* Clear the encoded certificate and miscellaneous components if
		   necessary */
		if( certInfoPtr->certificate != NULL )
			{
			zeroise( certInfoPtr->certificate, certInfoPtr->certificateSize );
			free( certInfoPtr->certificate );
			}
		if( certInfoPtr->serialNumber != NULL )
			free( certInfoPtr->serialNumber );
		if( certInfoPtr->subjectUniqueID != NULL )
			free( certInfoPtr->subjectUniqueID );
		if( certInfoPtr->issuerUniqueID != NULL )
			free( certInfoPtr->issuerUniqueID );
		if( certInfoPtr->subjectDNdata != NULL )
			free( certInfoPtr->subjectDNdata );
		if( certInfoPtr->issuerDNdata != NULL )
			free( certInfoPtr->issuerDNdata );
		if( certInfoPtr->ocspUrl != NULL )
			free( certInfoPtr->ocspUrl );

		/* Clear the DN's if necessary */
		if( certInfoPtr->issuerName != NULL )
			deleteDN( &certInfoPtr->issuerName );
		if( certInfoPtr->subjectName != NULL )
			deleteDN( &certInfoPtr->subjectName );

		/* Clear the attributes and CRL's if necessary */
		if( certInfoPtr->attributes != NULL )
			deleteAttributes( &certInfoPtr->attributes );
		if( certInfoPtr->revocations != NULL )
			deleteRevocationEntries( &certInfoPtr->revocations );

		/* Clear the cert chain if necessary */
		if( certInfoPtr->certChainEnd )
			{
			int i;

			for( i = 0; i < certInfoPtr->certChainEnd; i++ )
				krnlSendNotifier( certInfoPtr->certChain[ i ],
								  RESOURCE_IMESSAGE_DECREFCOUNT );
			}

		/* Delete the objects locking variables and the object itself */
		unlockResource( certInfoPtr );
		deleteResourceLock( certInfoPtr );
		zeroise( certInfoPtr, sizeof( CERT_INFO ) );
		free( certInfoPtr );

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		int status = CRYPT_OK;

		/* Lock the currently selected cert in a cert chain unless the 
		   message being processed is a certificate cursor movement command 
		   or something specifically directed at the entire chain (for
		   example a get type or self-signed status command - we want to get 
		   the type/status of the chain, not of the certs within it) */
		if( certInfoPtr->certChainPos != CRYPT_ERROR && \
			!( ( message == RESOURCE_MESSAGE_SETATTRIBUTE ) && \
			   ( messageValue == CRYPT_CERTINFO_CURRENT_CERTIFICATE ) ) && \
			!( ( message == RESOURCE_MESSAGE_GETATTRIBUTE ) && \
			   ( messageValue == CRYPT_CERTINFO_CERTTYPE || \
				 messageValue == CRYPT_CERTINFO_SELFSIGNED ) ) && \
			!( ( message == RESOURCE_MESSAGE_GETATTRIBUTE_S ) && \
			   ( messageValue == CRYPT_IATTRIBUTE_CERTSET || \
				 messageValue == CRYPT_IATTRIBUTE_ENC_CERT || \
				 messageValue == CRYPT_IATTRIBUTE_ENC_CERTCHAIN || \
				 messageValue == CRYPT_IATTRIBUTE_ENC_OBJDATA || \
				 messageValue == CRYPT_IATTRIBUTE_TEXT_CERT || \
				 messageValue == CRYPT_IATTRIBUTE_TEXT_CERTCHAIN ) ) )
			{
			CERT_INFO *certChainInfoPtr;

			getCheckInternalResource( certInfoPtr->certChain[ certInfoPtr->certChainPos ],
									  certChainInfoPtr, OBJECT_TYPE_CERTIFICATE );
			unlockResource( certInfoPtr );
			certInfoPtr = certChainInfoPtr;
			}

		status = processCertData( certInfoPtr, message, messageDataPtr, 
								  messageValue );
		unlockResourceExit( certInfoPtr, status );
		}

	/* Process messages which compare the object */
	if( message == RESOURCE_MESSAGE_COMPARE )
		{
		const RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
		CERT_INFO *certInfoPtr2;
		STREAM stream;
		const BYTE *dataStart;
		int serialNoLength, length, status;

		switch( messageValue )
			{
			case RESOURCE_MESSAGE_COMPARE_SUBJECT:
				if( msgData->length != certInfoPtr->subjectDNsize || \
					memcmp( msgData->data, certInfoPtr->subjectDNptr,
							certInfoPtr->subjectDNsize ) )
					unlockResourceExit( certInfoPtr, CRYPT_ERROR );
				unlockResourceExit( certInfoPtr, CRYPT_OK );

			case RESOURCE_MESSAGE_COMPARE_ISSUERANDSERIALNUMBER:
				/* Comparing an iAndS can get quite tricky because of 
				   assorted braindamage in encoding methods, so that two
				   dissimilar iAndSs aren't necessarily supposed to be 
				   regarded as non-equal.  First we try a trivial reject 
				   check, if that passes we compare the issuerName and
				   serialNumber with corrections for common encoding
				   braindamage.  Note that even this comparison can fail
				   since older versions of the Entegrity toolkit rewrote
				   T61Strings in certs as PrintableStrings in recipientInfo, 
				   which means any kind of straight comparison fails.  We 
				   don't bother handling this sort of thing, and it's likely 
				   that most other software won't either (this situation only 
				   occurs when a cert issuerName contains PrintableString 
				   text incorrectly encoded as T61String, which is rare 
				   enough that it required artifically-created certs just to 
				   reproduce the problem).  In addition the trivial reject 
				   check can also fail since in an extreme encoding 
				   braindamage case a BMPString rewritten as a 
				   PrintableString would experience a large enough change in
				   length to fail the check, but as with the Entegrity 
				   problem this is a level of brokenness up with which we 
				   will not put.  If it's really necessary to handle this,
				   we'd need to use readDN() on the supplied isser name and
				   then use the full compareDN() for the comparison */
				length = ( int ) sizeofObject( \
									certInfoPtr->issuerDNsize + \
									sizeofObject( certInfoPtr->serialNumberLength ) );
				if( length < msgData->length - 2 || \
					length > msgData->length + 2 )
					/* Trivial reject, the lengths are two dissimilar for
					   any fixup attempts to work */
					return( CRYPT_ERROR );

				/* The trivial accept/reject checks failed, try a more
				   detailed check, first the issuerName */
				sMemConnect( &stream, msgData->data, msgData->length );
				readSequence( &stream, NULL );
				dataStart = sMemBufPtr( &stream );
				length = getObjectLength( dataStart, msgData->length - 2 );
				status = readUniversal( &stream );
				if( cryptStatusError( status ) || \
					length != certInfoPtr->issuerDNsize || \
					memcmp( dataStart, certInfoPtr->issuerDNptr,
							certInfoPtr->issuerDNsize ) )
					{
					sMemDisconnect( &stream );
					unlockResourceExit( certInfoPtr, CRYPT_ERROR );
					}

				/* Compare the serialNumber.  This one can get a bit tricky
				   because Microsoft fairly consistently encode the serial
				   numbers incorrectly, so we normalise the values to have no
				   leading zero which is the lowest common denominator */
				readGenericHole( &stream, &serialNoLength );
				dataStart = sMemBufPtr( &stream );
				status = sSkip( &stream, serialNoLength );
				sMemDisconnect( &stream );
				if( !*dataStart )
					{ dataStart++; serialNoLength--; }	/* Skip leading zero */
				if( cryptStatusError( status ) || \
					serialNoLength != certInfoPtr->serialNumberLength || \
					memcmp( dataStart, certInfoPtr->serialNumber,
							certInfoPtr->serialNumberLength ) )
					unlockResourceExit( certInfoPtr, CRYPT_ERROR );

				unlockResourceExit( certInfoPtr, CRYPT_OK );

			case RESOURCE_MESSAGE_COMPARE_FINGERPRINT:
				getCheckInternalResource( *( ( CRYPT_CERTIFICATE * ) messageDataPtr ),
								certInfoPtr2, OBJECT_TYPE_CERTIFICATE );
				if( certInfoPtr->certificate == NULL || \
					certInfoPtr2->certificate == NULL )
					{
					/* If the cert objects haven't been signed yet, we can't
					   compare them */
					unlockResource( certInfoPtr2 );
					unlockResourceExit( certInfoPtr, CRYPT_ERROR_NOTINITED );
					}

				/* Compare the encoded certificate data.  This is the same as
				   comparing the fingerprint without requiring any hashing */
				status = ( certInfoPtr->certificateSize == \
									certInfoPtr2->certificateSize && \
						   !memcmp( certInfoPtr->certificate, certInfoPtr2->certificate,
									certInfoPtr->certificateSize ) ) ? \
						 CRYPT_OK : CRYPT_ERROR;
				unlockResource( certInfoPtr2 );
				unlockResourceExit( certInfoPtr, status );
			}

		assert( NOTREACHED );
		}

	/* Process messages which check a certificate */
	if( message == RESOURCE_MESSAGE_CHECK )
		{
		const int certCheckValue = \
			( messageValue == RESOURCE_MESSAGE_CHECK_PKC_ENCRYPT || \
              messageValue == RESOURCE_MESSAGE_CHECK_PKC_DECRYPT ) ? \
				CRYPT_KEYUSAGE_KEYENCIPHERMENT : \
			( messageValue == RESOURCE_MESSAGE_CHECK_PKC_SIGN || \
              messageValue == RESOURCE_MESSAGE_CHECK_PKC_SIGCHECK ) ? \
				( CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
				  CRYPT_KEYUSAGE_NONREPUDIATION | \
				  CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN ) : \
			( messageValue == RESOURCE_MESSAGE_CHECK_PKC_KA_EXPORT ) ? \
				CRYPT_KEYUSAGE_ENCIPHERONLY : \
			( messageValue == RESOURCE_MESSAGE_CHECK_PKC_KA_IMPORT ) ? \
				CRYPT_KEYUSAGE_DECIPHERONLY : \
			( messageValue == RESOURCE_MESSAGE_CHECK_CA ) ? \
				CRYPT_KEYUSAGE_KEYCERTSIGN : 0;
			/* enc/decOnly usage falls back to plain keyAgree if necessary */
		int status;

		/* If we're not checking for a specific type of functionality 
		   restriction set by the cert then any kind of usage is OK */
		if( !certCheckValue )
			unlockResourceExit( certInfoPtr, CRYPT_OK );

		status = checkCertUsage( certInfoPtr, certCheckValue, messageValue,
						&certInfoPtr->errorLocus, &certInfoPtr->errorType );
		status = cryptStatusError( status ) ? \
				 CRYPT_ARGERROR_OBJECT : CRYPT_OK;	/* Convert to correct form */
		unlockResourceExit( certInfoPtr, status );
		}

	/* Process messages which lock/unlock an object for exclusive use */
	if( message == RESOURCE_MESSAGE_LOCK )
		{
		/* Save the current volatile state so that any changes made while
		   the object is locked aren't reflected back to the caller */
		saveSelectionState( certInfoPtr->selectionState, certInfoPtr );

		/* Exit without unlocking the object.  Any other threads trying to
		   use the object after this point will be blocked */

⌨️ 快捷键说明

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