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

📄 cryptcrt.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 3 页
字号:
	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_RTCS_REQUEST ) ? SUBTYPE_CERT_RTCS_REQ : \
		( certType == CRYPT_CERTTYPE_RTCS_RESPONSE ) ? SUBTYPE_CERT_RTCS_RESP : \
		( 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, 
									 sizeof( CERT_INFO ), 
									 OBJECT_TYPE_CERTIFICATE, subType,
									 CREATEOBJECT_FLAG_NONE, cryptOwner, 
									 ACTION_PERM_NONE_ALL, 
									 certificateMessageFunction );
	if( cryptStatusError( iCertificate ) )
		return( iCertificate );
	certInfoPtr->objectHandle = iCertificate;
	certInfoPtr->ownerHandle = cryptOwner;
	certInfoPtr->type = certType;

	/* Set up the default version number.  These values are set here mostly 
	   so that attempting to read the version attribute won't return a 
	   version of 0.

	   In some cases this is an indication only that will be modified based 
	   on information added to the object (for example the CRL version is 
	   implicitly set based on whether extensions are added or not).  If this 
	   can happen we start with the lowest version available (the default 
	   v1), which will be automatically incremented whenever information 
	   that can't be represented with that format version is added */
	switch( certType )
		{
		case CRYPT_CERTTYPE_CERTIFICATE:
		case CRYPT_CERTTYPE_CERTCHAIN:
			certInfoPtr->version = 3;
			break;

		case CRYPT_CERTTYPE_ATTRIBUTE_CERT:
			certInfoPtr->version = 2;
			break;

		default:
			certInfoPtr->version = 1;
			break;
		}

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

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

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

	/* Pass the call on to the lower-level open function */
	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 */
	status = krnlSendMessage( iCertificate, 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 >= CRYPT_CERTTYPE_NONE && \
			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( cryptStatusOK( status ) )
		createInfo->cryptHandle = iCertificate;
	return( status );
	}

/* Generic management function for this class of object */

int certManagementFunction( const MANAGEMENT_ACTION_TYPE action )
	{
	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

/* Get/add/delete certificate attributes */

#ifdef EBCDIC_CHARS

static char *bufferToAscii( char *buffer, const char *string )
	{
	strcpy( buffer, string );
	ebcdicToAscii( buffer, strlen( string ) );
	return( buffer );
	}
#endif /* EBCDIC_CHARS */

C_RET cryptGetCertExtension( C_IN CRYPT_CERTIFICATE certificate,
							 C_IN char C_PTR oid, 
							 C_OUT int C_PTR criticalFlag,
							 C_OUT void C_PTR extension, 
							 C_OUT int C_PTR extensionLength )
	{
	CERT_INFO *certInfoPtr;
	ATTRIBUTE_LIST *attributeListPtr;
	BYTE binaryOID[ CRYPT_MAX_TEXTSIZE ];
#ifdef EBCDIC_CHARS
	char asciiOID[ CRYPT_MAX_TEXTSIZE + 1 ];
#endif /* EBCDIC_CHARS */
	BOOLEAN returnData = ( extension != NULL ) ? TRUE : FALSE;
	int value, status;

	/* Perform basic parameter error checking */
	if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
		return( CRYPT_ERROR_PARAM2 );
	if( checkBadPtrWrite( criticalFlag, sizeof( int ) ) )
		return( CRYPT_ERROR_PARAM3 );
	*criticalFlag = CRYPT_ERROR;
	if( extension != NULL )
		*( ( BYTE * ) extension ) = 0;
	if( checkBadPtrWrite( extensionLength, sizeof( int ) ) )
		return( CRYPT_ERROR_PARAM5 );
	*extensionLength = CRYPT_ERROR;
	if( strlen( oid ) > CRYPT_MAX_TEXTSIZE )
		return( CRYPT_ERROR_PARAM2 );
#ifdef EBCDIC_CHARS
	bufferToAscii( asciiOID, oid );
	if( !textToOID( asciiOID, strlen( asciiOID ), binaryOID ) )
		return( CRYPT_ERROR_PARAM2 );
#else
	if( !textToOID( oid, strlen( oid ), binaryOID ) )
		return( CRYPT_ERROR_PARAM2 );
#endif /* EBCDIC_CHARS */

	/* Perform object error checking.  Normally this is handled by the 
	   kernel, however since this function accesses multiple parameters and
	   the target isn't a cryptlib attribute, we have to handle the access
	   ourselves here.  In order to avoid potential race conditions, we 
	   check whether the object is internal twice, once before we lock it 
	   and again afterwards */
	status = krnlSendMessage( certificate, MESSAGE_GETATTRIBUTE,
							  &value, CRYPT_CERTINFO_CERTTYPE );
	if( cryptStatusError( status ) )
		return( CRYPT_ERROR_PARAM1 );
	status = krnlGetObject( certificate, OBJECT_TYPE_CERTIFICATE, 
							( void ** ) &certInfoPtr, CRYPT_ERROR_PARAM1 );
	if( cryptStatusError( status ) )
		return( status );
	status = krnlSendMessage( certificate, IMESSAGE_GETATTRIBUTE,
							  &value, CRYPT_IATTRIBUTE_INTERNAL );
	if( cryptStatusError( status ) || value )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_PARAM1 );
		}

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

		status = krnlGetObject( certInfoPtr->certChain[ certInfoPtr->certChainPos ], 
								OBJECT_TYPE_CERTIFICATE, 
								( void ** ) &certChainInfoPtr, 
								CRYPT_ERROR_PARAM1 );
		if( cryptStatusError( status ) )
			return( status );
		krnlReleaseObject( certInfoPtr->objectHandle );
		certInfoPtr = certChainInfoPtr;
		}

	/* Locate the attribute identified by the OID and get its information */
	attributeListPtr = findAttributeByOID( certInfoPtr->attributes, binaryOID );
	if( attributeListPtr == NULL )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_NOTFOUND );
		}
	*criticalFlag = ( attributeListPtr->flags & ATTR_FLAG_CRITICAL ) ? \
					TRUE : FALSE;
	*extensionLength = attributeListPtr->valueLength;
	if( returnData )
		{
		const void *dataPtr = attributeListPtr->value;

		if( checkBadPtrWrite( extension, attributeListPtr->valueLength ) )
			status = CRYPT_ERROR_PARAM3;
		else
			memcpy( extension, dataPtr, attributeListPtr->valueLength );
		}
	krnlReleaseObject( certInfoPtr->objectHandle );
	return( status );
	}

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 ];
#ifdef EBCDIC_CHARS
	char asciiOID[ CRYPT_MAX_TEXTSIZE + 1 ];
#endif /* EBCDIC_CHARS */
	int value, status;

	/* Perform basic parameter error checking */
	if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
		return( CRYPT_ERROR_PARAM2 );
	if( extensionLength <= 3 || extensionLength > MAX_ATTRIBUTE_SIZE )
		return( CRYPT_ERROR_PARAM5 );
	if( checkBadPtrRead( extension, extensionLength ) )
		return( CRYPT_ERROR_PARAM4 );
	status = checkObjectEncoding( extension, extensionLength );
	if( cryptStatusError( status ) )
		return( CRYPT_ERROR_PARAM4 );
	if( strlen( oid ) > CRYPT_MAX_TEXTSIZE )
		return( CRYPT_ERROR_PARAM2 );
#ifdef EBCDIC_CHARS
	bufferToAscii( asciiOID, oid );
	if( !textToOID( asciiOID, strlen( asciiOID ), binaryOID ) )
		return( CRYPT_ERROR_PARAM2 );
#else
	if( !textToOID( oid, strlen( oid ), binaryOID ) )
		return( CRYPT_ERROR_PARAM2 );
#endif /* EBCDIC_CHARS */

	/* Perform object error checking.  Normally this is handled by the 
	   kernel, however since this function accesses multiple parameters and
	   the target isn't a cryptlib attribute, we have to handle the access
	   ourselves here.  In order to avoid potential race conditions, we 
	   check whether the object is internal twice, once before we lock it 
	   and again afterwards */
	status = krnlSendMessage( certificate, MESSAGE_GETATTRIBUTE,
							  &value, CRYPT_CERTINFO_CERTTYPE );
	if( cryptStatusError( status ) )
		return( CRYPT_ERROR_PARAM1 );
	status = krnlGetObject( certificate, OBJECT_TYPE_CERTIFICATE, 
							( void ** ) &certInfoPtr, CRYPT_ERROR_PARAM1 );
	if( cryptStatusError( status ) )
		return( status );
	status = krnlSendMessage( certificate, IMESSAGE_GETATTRIBUTE,
							  &value, CRYPT_IATTRIBUTE_INTERNAL );
	if( cryptStatusError( status ) || value )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_PARAM1 );
		}
	if( certInfoPtr->certificate != NULL || \
		certInfoPtr->certChainPos >= 0 )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_PERMISSION );
		}
	if( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES && \
		criticalFlag != CRYPT_UNUSED )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_PARAM3 );
		}

	/* Add the attribute to the certificate */
	status = addAttribute( \
				( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? \
					ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE, 
				&certInfoPtr->attributes, binaryOID, 
				( certInfoPtr->type == CRYPT_CERTTYPE_CMS_ATTRIBUTES ) ? \
					FALSE : criticalFlag, 
				extension, extensionLength, ATTR_FLAG_NONE );
	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 );
	krnlReleaseObject( certInfoPtr->objectHandle );
	return( 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 ];
#ifdef EBCDIC_CHARS
	char asciiOID[ CRYPT_MAX_TEXTSIZE + 1 ];
#endif /* EBCDIC_CHARS */
	int value, status;

	/* Perform basic parameter error checking */
	if( checkBadPtrRead( oid, MIN_ASCII_OIDSIZE ) )
		return( CRYPT_ERROR_PARAM2 );
	if( strlen( oid ) > CRYPT_MAX_TEXTSIZE )
		return( CRYPT_ERROR_PARAM2 );
#ifdef EBCDIC_CHARS
	bufferToAscii( asciiOID, oid );
	if( !textToOID( asciiOID, strlen( asciiOID ), binaryOID ) )
		return( CRYPT_ERROR_PARAM2 );
#else
	if( !textToOID( oid, strlen( oid ), binaryOID ) )
		return( CRYPT_ERROR_PARAM2 );
#endif /* EBCDIC_CHARS */

	/* Perform object error checking.  Normally this is handled by the 
	   kernel, however since this function accesses multiple parameters and
	   the target isn't a cryptlib attribute, we have to handle the access
	   ourselves here.  In order to avoid potential race conditions, we 
	   check whether the object is internal twice, once before we lock it 
	   and again afterwards */
	status = krnlSendMessage( certificate, MESSAGE_GETATTRIBUTE,
							  &value, CRYPT_CERTINFO_CERTTYPE );
	if( cryptStatusError( status ) )
		return( CRYPT_ERROR_PARAM1 );
	status = krnlGetObject( certificate, OBJECT_TYPE_CERTIFICATE, 
							( void ** ) &certInfoPtr, CRYPT_ERROR_PARAM1 );
	if( cryptStatusError( status ) )
		return( status );
	status = krnlSendMessage( certificate, IMESSAGE_GETATTRIBUTE,
							  &value, CRYPT_IATTRIBUTE_INTERNAL );
	if( cryptStatusError( status ) || value )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_PARAM1 );
		}
	if( certInfoPtr->certificate != NULL || \
		certInfoPtr->certChainPos >= 0 )
		{
		krnlReleaseObject( certInfoPtr->objectHandle );
		return( CRYPT_ERROR_PERMISSION );
		}

	/* Find the attribute identified by the OID and delete it */
	attributeListPtr = findAttributeByOID( certInfoPtr->attributes, 
										   binaryOID );
	if( attributeListPtr == NULL )
		status = CRYPT_ERROR_NOTFOUND;
	else
		deleteAttribute( &certInfoPtr->attributes, NULL, attributeListPtr, 
						 NULL );
	krnlReleaseObject( certInfoPtr->objectHandle );
	return( status );
	}

⌨️ 快捷键说明

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