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

📄 cryptcrt.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 4 页
字号:
		{
		setMessageCreateObjectInfo( &createInfo, cryptAlgo );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT, &createInfo, 
								  OBJECT_TYPE_CONTEXT );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Send the public-key data to the context */
	setMessageData( &msgData, spkiPtr, spkiLength );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  IMESSAGE_SETATTRIBUTE_S, &msgData, 
							  deferredLoad ? \
								CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL : \
								CRYPT_IATTRIBUTE_KEY_SPKI );
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
		return( status );
		}
	*iPubkeyContext = createInfo.cryptHandle;
	assert( cryptStatusError( \
				krnlSendMessage( createInfo.cryptHandle, IMESSAGE_CHECK, 
								 NULL, MESSAGE_CHECK_PKC_PRIVATE ) ) );
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						Certificate Management API Functions				*
*																			*
****************************************************************************/

/* Handle data sent to or read from a cert object */

static int processCertData( CERT_INFO *certInfoPtr,
						    const MESSAGE_TYPE message,
							void *messageDataPtr, const int messageValue )
	{
	RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	int *valuePtr = ( int * ) messageDataPtr;

	/* Process get/set/delete attribute messages */
	if( message == MESSAGE_GETATTRIBUTE )
		{
		if( messageValue == CRYPT_ATTRIBUTE_ERRORTYPE )
			{
			*valuePtr = certInfoPtr->errorType;
			return( CRYPT_OK );
			}
		if( messageValue == CRYPT_ATTRIBUTE_ERRORLOCUS )
			{
			*valuePtr = certInfoPtr->errorLocus;
			return( CRYPT_OK );
			}
		return( getCertComponent( certInfoPtr, messageValue, valuePtr, NULL ) );
		}
	if( message == MESSAGE_GETATTRIBUTE_S )
		return( getCertComponent( certInfoPtr, messageValue, 
								  msgData->data, &msgData->length ) );
	if( message == MESSAGE_SETATTRIBUTE )
		{
		const BOOLEAN validCursorPosition = \
			( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? \
			messageValue >= CRYPT_CERTINFO_FIRST_CMS && \
								messageValue <= CRYPT_CERTINFO_LAST_CMS : \
			messageValue >= CRYPT_CERTINFO_FIRST_EXTENSION && \
								messageValue <= CRYPT_CERTINFO_LAST_EXTENSION;

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

		/* 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 );

		/* If the passed-in value is a cursor-positioning code, make sure 
		   that 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 == MESSAGE_SETATTRIBUTE_S )
		return( addCertComponent( certInfoPtr, messageValue, msgData->data, 
								  msgData->length ) );
	if( message == 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 void *objectInfoPtr,
									   const MESSAGE_TYPE message,
									   void *messageDataPtr,
									   const int messageValue )
	{
	CERT_INFO *certInfoPtr = ( CERT_INFO * ) objectInfoPtr;

	/* Process destroy object messages */
	if( message == MESSAGE_DESTROY )
		{
		/* Clear the encoded certificate and miscellaneous components if
		   necessary.  Note that there's no need to clear the associated
		   encryption context (if any) since this is a dependent object of
		   the cert and is destroyed by the kernel when the cert is 
		   destroyed */
		if( certInfoPtr->certificate != NULL )
			{
			zeroise( certInfoPtr->certificate, certInfoPtr->certificateSize );
			clFree( "certificateMessageFunction", certInfoPtr->certificate );
			}
		if( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE || \
			certInfoPtr->type == CRYPT_CERTTYPE_ATTRIBUTE_CERT || \
			certInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN )
			{
			if( certInfoPtr->cCertCert->serialNumber != NULL && \
				certInfoPtr->cCertCert->serialNumber != \
					certInfoPtr->cCertCert->serialNumberBuffer )
				clFree( "certificateMessageFunction", 
						certInfoPtr->cCertCert->serialNumber );
			}
		if( certInfoPtr->type == CRYPT_CERTTYPE_REQUEST_REVOCATION )
			{
			if( certInfoPtr->cCertReq->serialNumber != NULL && \
				certInfoPtr->cCertReq->serialNumber != \
					certInfoPtr->cCertReq->serialNumberBuffer )
				clFree( "certificateMessageFunction", 
						certInfoPtr->cCertReq->serialNumber );
			}
		if( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE )
			{
			if( certInfoPtr->cCertCert->subjectUniqueID != NULL )
				clFree( "certificateMessageFunction", 
						certInfoPtr->cCertCert->subjectUniqueID );
			if( certInfoPtr->cCertCert->issuerUniqueID != NULL )
				clFree( "certificateMessageFunction", 
						certInfoPtr->cCertCert->issuerUniqueID );
			}
		if( certInfoPtr->publicKeyData != NULL )
			clFree( "certificateMessageFunction", certInfoPtr->publicKeyData  );
		if( certInfoPtr->subjectDNdata != NULL )
			clFree( "certificateMessageFunction", certInfoPtr->subjectDNdata );
		if( certInfoPtr->issuerDNdata != NULL )
			clFree( "certificateMessageFunction", certInfoPtr->issuerDNdata );
		if( certInfoPtr->type == CRYPT_CERTTYPE_CRL || \
			certInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE )
			{
			if( certInfoPtr->cCertRev->responderUrl != NULL )
				clFree( "certificateMessageFunction", 
						certInfoPtr->cCertRev->responderUrl );
			}
		if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
			{
			if( certInfoPtr->cCertVal->responderUrl != NULL )
				clFree( "certificateMessageFunction", 
						certInfoPtr->cCertVal->responderUrl );
			}

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

		/* Clear the attributes and validity/revocation info if necessary */
		if( certInfoPtr->attributes != NULL )
			deleteAttributes( &certInfoPtr->attributes );
		if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
			{
			if( certInfoPtr->cCertVal->validityInfo != NULL )
				deleteValidityEntries( &certInfoPtr->cCertVal->validityInfo );
			}
		if( certInfoPtr->type == CRYPT_CERTTYPE_CRL || \
			certInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE )
			{
			if( certInfoPtr->cCertRev->revocations != NULL )
				deleteRevocationEntries( &certInfoPtr->cCertRev->revocations );
			}

		/* Clear the cert chain if necessary */
		if( certInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN && \
			certInfoPtr->cCertCert->chainEnd > 0)
			{
			int i;

			for( i = 0; i < certInfoPtr->cCertCert->chainEnd; i++ )
				krnlSendNotifier( certInfoPtr->cCertCert->chain[ i ],
								  IMESSAGE_DECREFCOUNT );
			}

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		/* If it's a cert chain, lock the currently selected cert in the 
		   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->type == CRYPT_CERTTYPE_CERTCHAIN && \
			certInfoPtr->cCertCert->chainPos >= 0 && \
			!( ( message == MESSAGE_SETATTRIBUTE ) && \
			   ( messageValue == CRYPT_CERTINFO_CURRENT_CERTIFICATE ) ) && \
			!( ( message == MESSAGE_GETATTRIBUTE ) && \
			   ( messageValue == CRYPT_CERTINFO_CERTTYPE || \
				 messageValue == CRYPT_CERTINFO_SELFSIGNED ) ) )
			{
			CERT_INFO *certChainInfoPtr;
			int status;

			status = krnlAcquireObject( certInfoPtr->cCertCert->chain[ certInfoPtr->cCertCert->chainPos ], 
										OBJECT_TYPE_CERTIFICATE, 
										( void ** ) &certChainInfoPtr,
										CRYPT_ARGERROR_OBJECT );
			if( cryptStatusError( status ) )
				return( status );
			status = processCertData( certChainInfoPtr, message, messageDataPtr, 
									  messageValue );
			krnlReleaseObject( certChainInfoPtr->objectHandle );
			return( status );
			}

		return( processCertData( certInfoPtr, message, messageDataPtr, 
								 messageValue ) );
		}

	/* Process messages that compare the object */
	if( message == MESSAGE_COMPARE )
		return( compareCertInfo( certInfoPtr, messageValue, 
								 messageDataPtr ) );

	/* Process messages that check a certificate */
	if( message == MESSAGE_CHECK )
		{
		int complianceLevel, keyUsageValue, checkKeyFlag = CHECKKEY_FLAG_NONE;
		int status;

		/* Map the check type to a key usage that we check for */
		switch( messageValue )
			{
			case MESSAGE_CHECK_PKC_PRIVATE:
				/* This check type can be encountered when checking a private
				   key with a cert attached */
				keyUsageValue = CRYPT_UNUSED;
				checkKeyFlag = CHECKKEY_FLAG_PRIVATEKEY;
				break;

			case MESSAGE_CHECK_PKC_ENCRYPT:
			case MESSAGE_CHECK_PKC_ENCRYPT_AVAIL:
				keyUsageValue = CRYPT_KEYUSAGE_KEYENCIPHERMENT;
				break;

			case MESSAGE_CHECK_PKC_DECRYPT:
			case MESSAGE_CHECK_PKC_DECRYPT_AVAIL:
				keyUsageValue = CRYPT_KEYUSAGE_KEYENCIPHERMENT;
				checkKeyFlag = CHECKKEY_FLAG_PRIVATEKEY;
				break;

			case MESSAGE_CHECK_PKC_SIGN:
			case MESSAGE_CHECK_PKC_SIGN_AVAIL:
				keyUsageValue = CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
								CRYPT_KEYUSAGE_NONREPUDIATION | \
								CRYPT_KEYUSAGE_KEYCERTSIGN | \
								CRYPT_KEYUSAGE_CRLSIGN;
				checkKeyFlag = CHECKKEY_FLAG_PRIVATEKEY;
				break;

			case MESSAGE_CHECK_PKC_SIGCHECK:
			case MESSAGE_CHECK_PKC_SIGCHECK_AVAIL:
				keyUsageValue = CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
								CRYPT_KEYUSAGE_NONREPUDIATION | \
								CRYPT_KEYUSAGE_KEYCERTSIGN | \
								CRYPT_KEYUSAGE_CRLSIGN;
				break;

			case MESSAGE_CHECK_PKC_KA_EXPORT:
			case MESSAGE_CHECK_PKC_KA_EXPORT_AVAIL:
				/* exportOnly usage falls back to plain keyAgreement if 
				   necessary */
				keyUsageValue = CRYPT_KEYUSAGE_KEYAGREEMENT | \
								CRYPT_KEYUSAGE_ENCIPHERONLY;
				break;

			case MESSAGE_CHECK_PKC_KA_IMPORT:
			case MESSAGE_CHECK_PKC_KA_IMPORT_AVAIL:
				/* importOnly usage falls back to plain keyAgreement if 
				   necessary */
				keyUsageValue = CRYPT_KEYUSAGE_KEYAGREEMENT | \
								CRYPT_KEYUSAGE_DECIPHERONLY;
				break;

			case MESSAGE_CHECK_CA:
			case MESSAGE_CHECK_CACERT:
				/* A special-case version of MESSAGE_CHECK_PKC_SIGN/
				   MESSAGE_CHECK_PKC_SIGCHECK that applies only to 
				   certificates */
				keyUsageValue = CRYPT_KEYUSAGE_KEYCERTSIGN;
				checkKeyFlag = CHECKKEY_FLAG_CA;
				break;
			
			case MESSAGE_CHECK_PKC:
				/* If we're just checking for generic PKC functionality
				   then any kind of usage is OK */
				return( CRYPT_OK );

			default:
				assert( NOTREACHED );
				return( CRYPT_ERROR_INVALID );
			}
		assert( keyUsageValue != CRYPT_UNUSED || \
				checkKeyFlag != CHECKKEY_FLAG_NONE );

		/* Cert requests are special-case objects in that the key they 
		   contain is usable only for signature checking of the self-
		   signature on the object (it can't be used for general-purpose 
		   usages, which would make it equivalent to a trusted self-signed 
		   cert).  This is problematic because the keyUsage may indicate 
		   that the key is valid for other things as well, or not valid for 
		   signature checking.  To get around this, we indicate that the key 
		   has a single trusted usage, signature checking, and disallow any 
		   other usage regardless of what the keyUsage says.  The actual 
		   keyUsage usage is only valid once the request has been converted 
		   into a certificate */
		if( certInfoPtr->type == CRYPT_CERTTYPE_CERTREQUEST || \
			certInfoPtr->type == CRYPT_CERTTYPE_REQUEST_CERT )
			{
			if( messageValue == MESSAGE_CHECK_PKC_SIGCHECK || \
				messageValue == MESSAGE_CHECK_PKC_SIGCHECK_AVAIL )
				return( CRYPT_OK );
			setErrorInfo( certInfoPtr, CRYPT_CERTINFO_TRUSTED_USAGE, 

⌨️ 快捷键说明

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