cryptcrt.c

来自「提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发」· C语言 代码 · 共 960 行 · 第 1/3 页

C
960
字号
		return( CRYPT_OK );
		}
	if( message == RESOURCE_MESSAGE_UNLOCK )
		{
		/* Restore the volatile state from before the object was locked */
		restoreSelectionState( certInfoPtr->selectionState, certInfoPtr );

		/* "Wenn drei Leute in ein Zimmer reingehen und fuenf kommen raus,
			dann muessen erst mal zwei wieder reingehen bis das Zimmer leer
			ist" */
		unlockResource( certInfoPtr );	/* Undo RESOURCE_MESSAGE_LOCK lock */
		unlockResourceExit( certInfoPtr, CRYPT_OK );
		}

	/* Process object-specific messages */
	if( message == RESOURCE_MESSAGE_CRT_SIGN )
		{
		int status;

		assert( certInfoPtr->certificate == NULL );

		/* Make sure the signing object can actually be used for signing, the
		   sole exception is a CRMF request which can be created with an
		   encryption-only key if the private key POP is performed via an 
		   out-of-band mechanism */
		status = krnlSendMessage( messageValue, RESOURCE_IMESSAGE_CHECK, NULL,
								  RESOURCE_MESSAGE_CHECK_PKC_SIGN );
		if( cryptStatusError( status ) && \
			certInfoPtr->type != CRYPT_CERTTYPE_REQUEST_CERT )
			unlockResourceExit( certInfoPtr, CRYPT_ARGERROR_VALUE );

		/* We're changing data in a certificate, clear the error 
		   information */
		clearErrorInfo( certInfoPtr );

		status = signCert( certInfoPtr, messageValue );
		unlockResourceExit( certInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_CRT_SIGCHECK )
		{
		int status;

		assert( certInfoPtr->certificate != NULL || \
				certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE );

		/* We're checking data in a certificate, clear the error 
		   information */
		clearErrorInfo( certInfoPtr );

		status = checkCertValidity( certInfoPtr, messageValue );
		unlockResourceExit( certInfoPtr, status );
		}

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

/* Create a certificate object, returning a pointer to the locked cert info 
   ready for further initialisation */

int createCertificateInfo( CERT_INFO **certInfoPtrPtr, 
						   const CRYPT_USER cryptOwner,
						   const CRYPT_CERTTYPE_TYPE certType )
	{
	CRYPT_CERTIFICATE iCertificate;
	CERT_INFO *certInfoPtr;
	const int subType = \
		/* Standard types */
		( certType == CRYPT_CERTTYPE_CERTIFICATE ) ? SUBTYPE_CERT_CERT : \
		( certType == CRYPT_CERTTYPE_ATTRIBUTE_CERT ) ? SUBTYPE_CERT_ATTRCERT : \
		( certType == CRYPT_CERTTYPE_CERTCHAIN ) ? SUBTYPE_CERT_CERTCHAIN : \
		( certType == CRYPT_CERTTYPE_CERTREQUEST ) ? SUBTYPE_CERT_CERTREQ : \
		( certType == CRYPT_CERTTYPE_REQUEST_CERT ) ? SUBTYPE_CERT_REQ_CERT : \
		( certType == CRYPT_CERTTYPE_REQUEST_REVOCATION ) ? SUBTYPE_CERT_REQ_REV : \
		( certType == CRYPT_CERTTYPE_CRL ) ? SUBTYPE_CERT_CRL : \
		( certType == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? SUBTYPE_CERT_CMSATTR : \
		( certType == CRYPT_CERTTYPE_OCSP_REQUEST ) ? SUBTYPE_CERT_OCSP_REQ : \
		( certType == CRYPT_CERTTYPE_OCSP_RESPONSE ) ? SUBTYPE_CERT_OCSP_RESP : \
		( certType == CRYPT_CERTTYPE_PKIUSER ) ? SUBTYPE_CERT_PKIUSER : 0;

	assert( certInfoPtrPtr != NULL );
	assert( subType != 0 );

	*certInfoPtrPtr = NULL;

	/* Create the certificate object */
	iCertificate = krnlCreateObject( ( void ** ) &certInfoPtr, cryptOwner,
									 OBJECT_TYPE_CERTIFICATE, subType,
									 sizeof( CERT_INFO ), 0, 0, 
									 certificateMessageFunction );
	if( cryptStatusError( iCertificate ) )
		return( iCertificate );
	initResourceLock( certInfoPtr ); 
	lockResource( certInfoPtr ); 
	certInfoPtr->objectHandle = iCertificate;
	certInfoPtr->ownerHandle = cryptOwner;
	certInfoPtr->type = certType;

	/* Set up any internal objects to contain invalid handles */
	certInfoPtr->iCryptContext = CRYPT_ERROR;

	/* Set the state information to its initial state */
	certInfoPtr->certChainPos = CRYPT_ERROR;
	certInfoPtr->trustedUsage = CRYPT_ERROR;

	/* Return the locked cert info pointer */
	*certInfoPtrPtr = certInfoPtr;
	return( iCertificate );
	}

/* Create a certificate */

int createCertificate( MESSAGE_CREATEOBJECT_INFO *createInfo, 
					   const void *auxDataPtr, const int auxValue )
	{
	CRYPT_CERTIFICATE iCertificate;
	CERT_INFO *certInfoPtr;
	int status;

	assert( auxDataPtr == NULL );
	assert( auxValue == 0 );
	assert( createInfo->arg2 == 0 );
	assert( createInfo->strArg1 == NULL );
	assert( createInfo->strArgLen1 == 0 );

	/* Perform basic error checking */
	if( createInfo->arg1 <= CRYPT_CERTTYPE_NONE || \
		createInfo->arg1 >= CRYPT_CERTTYPE_LAST )
		return( CRYPT_ARGERROR_NUM1 );

	status = createCertificateInfo( &certInfoPtr, createInfo->cryptOwner,
									createInfo->arg1 );
	if( cryptStatusError( status ) )
		return( status );
	iCertificate = status;

	/* We've finished setting up the object-type-specific info, tell the 
	   kernel the object is ready for use */
	unlockResource( certInfoPtr );
	status = krnlSendMessage( iCertificate, RESOURCE_IMESSAGE_SETATTRIBUTE, 
							  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	if( cryptStatusOK( status ) )
		createInfo->cryptHandle = iCertificate;
	return( status );
	}

/* Create a certificate by instantiating it from its encoded form */

int createCertificateIndirect( MESSAGE_CREATEOBJECT_INFO *createInfo, 
							   const void *auxDataPtr, const int auxValue )
	{
	CRYPT_CERTIFICATE iCertificate;
	int status;

	assert( auxDataPtr == NULL );
	assert( auxValue == 0 );
	assert( createInfo->arg1 >= CERTFORMAT_NORMAL && \
			createInfo->arg1 < CERTFORMAT_LAST );
	assert( createInfo->strArg1 != NULL );
	assert( createInfo->strArgLen1 > 16 );	/* May be CMS attr.*/
	assert( ( createInfo->arg2 == 0 && createInfo->strArg2 == NULL && \
			  createInfo->strArgLen2 == 0 ) || \
			( ( createInfo->arg2 == CRYPT_IKEYID_KEYID || \
				createInfo->arg2 == CRYPT_IKEYID_ISSUERANDSERIALNUMBER ) && \
			  createInfo->strArg2 != NULL && createInfo->strArgLen2 > 2 ) );

	/* Pass the call through to the low-level import function.  This returns 
	   a length value so we convert it to a proper status for the caller */
	status = importCert( createInfo->strArg1, createInfo->strArgLen1,
						 &iCertificate, createInfo->cryptOwner,
						 createInfo->arg2, createInfo->strArg2, 
						 createInfo->strArgLen2, createInfo->arg1 );
	if( !cryptStatusError( status ) )
		{
		createInfo->cryptHandle = iCertificate;
		return( CRYPT_OK );
		}
	return( status );
	}

/* Get/add/delete certificate attributes */

C_RET cryptGetCertExtension( C_IN CRYPT_HANDLE cryptHandle,
							 C_IN char C_PTR oid, 
							 C_OUT int C_PTR criticalFlag,
							 C_OUT void C_PTR extension, 
							 C_OUT int C_PTR extensionLength )
	{
	CRYPT_CERTIFICATE certificate;
	CERT_INFO *certInfoPtr;
	ATTRIBUTE_LIST *attributeListPtr;
	BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];
	BOOLEAN returnData = ( extension != NULL ) ? TRUE : FALSE;
	int status;

	/* Perform basic error checking */
	status = krnlSendMessage( cryptHandle, RESOURCE_MESSAGE_GETDEPENDENT,
							  &certificate, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM1 : status );
	getCheckInternalResource( certificate, certInfoPtr, 
							  OBJECT_TYPE_CERTIFICATE );
	if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
	if( checkBadPtrWrite( criticalFlag, sizeof( int ) ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM3 );
	*criticalFlag = CRYPT_ERROR;
	if( extension != NULL )
		*( ( BYTE * ) extension ) = 0;
	if( checkBadPtrWrite( extensionLength, sizeof( int ) ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM5 );
	*extensionLength = CRYPT_ERROR;

	/* Lock the currently selected cert in a cert chain if necessary */
	if( certInfoPtr->certChainPos != CRYPT_ERROR )
		{
		CERT_INFO *certChainInfoPtr;

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

	/* Convert the OID to its binary form and try and locate the attribute
	   identified by the OID */
	if( !textToOID( oid, strlen( oid ), binaryOID ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
	attributeListPtr = findAttributeByOID( certInfoPtr->attributes, binaryOID );
	if( attributeListPtr == NULL )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_NOTFOUND );
	*criticalFlag = ( attributeListPtr->flags & ATTR_FLAG_CRITICAL ) ? \
					TRUE : FALSE;
	*extensionLength = attributeListPtr->dataLength;
	if( returnData )
		{
		const void *dataPtr = \
				( attributeListPtr->dataLength <= CRYPT_MAX_TEXTSIZE ) ? \
				attributeListPtr->smallData : attributeListPtr->data;

		if( checkBadPtrWrite( extension, attributeListPtr->dataLength ) )
			unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM3 );
		memcpy( extension, dataPtr, attributeListPtr->dataLength );
		}
	unlockResourceExit( certInfoPtr, CRYPT_OK );
	}

C_RET cryptAddCertExtension( C_IN CRYPT_CERTIFICATE certificate,
							 C_IN char C_PTR oid, C_IN int criticalFlag,
							 C_IN void C_PTR extension,
							 C_IN int extensionLength )
	{
	CERT_INFO *certInfoPtr;
	BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];
	int status;

	/* Perform basic error checking */
	getCheckResource( certificate, certInfoPtr, OBJECT_TYPE_CERTIFICATE,
					  CRYPT_ERROR_PARAM1 );
	if( certInfoPtr->certificate != NULL || \
		certInfoPtr->certChainPos != CRYPT_ERROR )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PERMISSION );
	if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
	if( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES && \
		criticalFlag != CRYPT_UNUSED )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM3 );
	if( extensionLength <= 3 || extensionLength > MAX_ATTRIBUTE_SIZE )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM5 );
	if( checkBadPtrRead( extension, extensionLength ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM4 );
	status = checkObjectEncoding( extension, extensionLength );
	if( cryptStatusError( status ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM4 );

	/* Convert the OID to its binary form, copy the data to an internal
	   buffer, and add the attribute to the certificate */
	if( !textToOID( oid, strlen( oid ), binaryOID ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
	status = addAttribute( ( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? \
		ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE, &certInfoPtr->attributes,
		binaryOID, ( BOOLEAN )	/* Fix for VC++ */
		( ( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? FALSE : \
		  criticalFlag ), extension, extensionLength );
	if( status == CRYPT_ERROR_INITED )
		/* If the attribute is already present, set error information for it.
		   We can't set an error locus since it's an unknown blob */
		setErrorInfo( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
					  CRYPT_ERRTYPE_ATTR_PRESENT );
	unlockResourceExit( certInfoPtr, status );
	}

C_RET cryptDeleteCertExtension( C_IN CRYPT_CERTIFICATE certificate,
								C_IN char C_PTR oid )
	{
	CERT_INFO *certInfoPtr;
	ATTRIBUTE_LIST *attributeListPtr;
	BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];

	/* Perform basic error checking */
	getCheckResource( certificate, certInfoPtr, OBJECT_TYPE_CERTIFICATE,
					  CRYPT_ERROR_PARAM1 );
	if( certInfoPtr->certificate != NULL || \
		certInfoPtr->certChainPos != CRYPT_ERROR )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PERMISSION );
	if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );

	/* Convert the OID to its binary form, find the attribute identified by
	   this OID, and delete it */
	if( !textToOID( oid, strlen( oid ), binaryOID ) )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_PARAM2 );
	attributeListPtr = findAttributeByOID( certInfoPtr->attributes, binaryOID );
	if( attributeListPtr == NULL )
		unlockResourceExit( certInfoPtr, CRYPT_ERROR_NOTFOUND );
	deleteAttribute( &certInfoPtr->attributes, NULL, attributeListPtr );
	unlockResourceExit( certInfoPtr, CRYPT_OK );
	}

⌨️ 快捷键说明

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