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

📄 dev_fort.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:

/* Set up certificate/raw key information and load it into the card */

static int updateCertificate( FORTEZZA_INFO *fortezzaInfo, const int certIndex, 
							  const CRYPT_CERTIFICATE iCryptCert, 
							  const char *labelData, const int parentIndex )
	{
	CI_PERSON *personalityList = fortezzaInfo->personalities;
	CI_CERT_STR label;
	CI_CERTIFICATE certificate;
	CI_PERSON *personality = getPersonality( fortezzaInfo, certIndex );
	RESOURCE_DATA msgData;
	int certificateLength, status;

	/* If we're trying to load the PAA cert, the device must be in the SSO 
	   initialised state */
	if( !certIndex )
		{
		CI_STATE deviceState;

		status = pCI_GetState( &deviceState );
		if( status != CI_OK || deviceState != CI_SSO_INITIALIZED )
			return( CRYPT_ERROR_PERMISSION );
		}

	/* Get the SDN.605 label for the cert */
	getCertificateLabel( fortezzaInfo, certIndex, parentIndex, iCryptCert, 
						 personality->CertLabel[ 0 ] ? FALSE : TRUE, label );

	/* If there's label data supplied (which happens for data-only certs 
	   with no associated personality), use that */
	if( labelData != NULL )
		strcpy( label + 8, labelData );
	else
		/* Reuse the existing label from the personality corresponding to
		   the cert */
		strcpy( label + 8, personality->CertLabel + 8 );

	/* Set up the certificate data and send it to the card */
	memset( certificate, 0, sizeof( CI_CERTIFICATE ) );
	setMessageData( &msgData, NULL, 0 );
	status = krnlSendMessage( iCryptCert, IMESSAGE_CRT_EXPORT, &msgData, 
							  CRYPT_CERTFORMAT_CERTIFICATE );
	if( cryptStatusOK( status ) )
		{
		certificateLength = msgData.length;
		if( certificateLength > sizeof( CI_CERTIFICATE ) )
			return( CRYPT_ERROR_OVERFLOW );
		setMessageData( &msgData, certificate, certificateLength );
		status = krnlSendMessage( iCryptCert, IMESSAGE_CRT_EXPORT, &msgData,
								  CRYPT_CERTFORMAT_CERTIFICATE );
		}
	if( cryptStatusError( status ) )
		return( status );
#ifndef NO_UPDATE
	status = pCI_LoadCertificate( certIndex, label, certificate, 0 );
	if( status != CI_OK )
		return( mapError( status, CRYPT_ERROR_FAILED ) );
#endif /* NO_UPDATE */

	/* Update the in-memory copy of the cert information */
	updateCertificateInfo( fortezzaInfo, certIndex, certificate, 
						   certificateLength, label );

	return( CRYPT_OK );
	}

static int updateRawKey( FORTEZZA_INFO *fortezzaInfo, const int certIndex, 
						 const void *rawKeyData, const int rawKeySize,
						 const char *labelData, const int parentIndex )
	{
	CI_CERT_STR label;
	CI_CERTIFICATE certificate;
	int status;

	/* Set the SDN.605 related certificate locator to indicate that no 
	   parent or sibling certificates are present for this key, and use the 
	   cryptlib U/E specifier "TEMP" to indicate a temporary key awaiting a 
	   certificate */
	strcpy( label, "TEMPFFFF" );
	strncpy( label + 8, labelData, 24 );

	/* Set up the raw key data and send it to the card */
	memset( certificate, 0, sizeof( CI_CERTIFICATE ) );
	memcpy( certificate, rawKeyData, rawKeySize );
#ifndef NO_UPDATE
	status = pCI_LoadCertificate( certIndex, label, certificate, 0 );
	if( status != CI_OK )
		return( mapError( status, CRYPT_ERROR_FAILED ) );
#endif /* NO_UPDATE */

	/* Update the in-memory copy of the cert information */
	updateCertificateInfo( fortezzaInfo, certIndex, rawKeyData, 
						   rawKeySize, label );

	return( CRYPT_OK );
	}

/* Information about certs on the card.  The slot index and parent slot 
   index contain the mapping of cert positions in the chain to cert
   positions and parent cert positions in the card, the certPresent and
   personalityPresent flags indicate whether the cert is already present in 
   the card and whether the cert being added corresponds to a personality
   in the card rather than being a data-only cert (e.g. from a CA that
   issued the end-entity cert corresponding to a present personality) */

typedef struct {
	int index, parentIndex;		/* Pos.of cert and parent cert */
	BOOLEAN certPresent;		/* Whether cert present in card */
	BOOLEAN personalityPresent;	/* Whether cert corresponds to card pers.*/
	} CARDCERT_INFO;

/* Update a card using the certs in a cert chain */

static int updateCertChain( FORTEZZA_INFO *fortezzaInfo,
							const CRYPT_CERTIFICATE iCryptCert )
	{
	CI_PERSON *personalityList = fortezzaInfo->personalities;
	CARDCERT_INFO cardCertInfo[ 16 ];
	int chainIndex = -1, oldCertIndex, value, i;

	/* Initialise the certificate index information and hashes for the certs
	   on the card if necessary.  certList[] contains the mapping of certs in
	   the chain to positions in the card, parentList[] contains the mapping
	   of certs in the chain to the position of their parents in the card */
	for( i = 0; i < 16; i++ )
		{
		memset( &cardCertInfo[ i ], 0, sizeof( CARDCERT_INFO ) );
		cardCertInfo[ i ].index = \
				cardCertInfo[ i ].parentIndex = CRYPT_UNUSED;
		}
	if( !fortezzaInfo->certHashesInitialised )
		getCertificateInfo( fortezzaInfo );

	/* Start at the top-level cert and work our way down, which ensures that
	   the CA certs appear first, and that if an update fails, the parent
	   cert pointers point to valid fields (since higher-level certs are
	   added first) */
	krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, 
					 MESSAGE_VALUE_CURSORLAST, CRYPT_CERTINFO_CURRENT_CERTIFICATE );

	/* Pass 1: Build an index of cert and parent cert positions in the card.  
	   Once this loop has completed, certList[] contains a mapping from cert 
	   chain position to position in the card, and parentList[] contains a 
	   mapping from cert chain position to parent cert position in the card */
	do
		{
		RESOURCE_DATA msgData;
		CI_HASHVALUE hash;
		BOOLEAN isPresent = FALSE;
		int certIndex;

		/* Increment the chain index.  We do this at the start of the loop 
		   since we start at the -1th position */
		chainIndex++;

		/* Get the hash for this cert and check whether it's already present */
		setMessageData( &msgData, &hash, sizeof( CI_HASHVALUE ) );
		if( cryptStatusError( \
			krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE_S,
							 &msgData, CRYPT_CERTINFO_FINGERPRINT_SHA ) ) )
			return( CRYPT_ARGERROR_NUM1 );
		certIndex = findCertFromHash( fortezzaInfo, hash );
		if( !cryptStatusError( certIndex ) )
			isPresent = TRUE;

		/* Set the mapping from cert to parent cert position in the card.  
		   The cert at position 0 is the root cert */
		if( chainIndex > 0 )
			cardCertInfo[ chainIndex ].parentIndex = oldCertIndex;
		
		/* Set the mapping from cert to position in the card */
		if( isPresent )
			{
			cardCertInfo[ chainIndex ].index = certIndex;
			cardCertInfo[ chainIndex ].certPresent = TRUE;
			}
		else
			{
			int freeCertIndex;;

			/* Allocate this cert to the next free position in the card */
			for( freeCertIndex = 0; \
				 freeCertIndex < fortezzaInfo->personalityCount && \
				 personalityList[ freeCertIndex ].CertLabel[ 0 ] != '\0'; \
				 freeCertIndex++ );
			if( freeCertIndex >= fortezzaInfo->personalityCount )
				/* There's no more room for any new certificates in the 
				   card */
				return( CRYPT_ERROR_OVERFLOW );
			cardCertInfo[ chainIndex ].index = freeCertIndex;
			}

		/* Remember the just-assigned position in the card */
		oldCertIndex = cardCertInfo[ chainIndex ].index;
		}
	while( krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, 
							MESSAGE_VALUE_CURSORPREVIOUS,
							CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK );

	/* The last cert in the chain will either already be present or will be 
	   present in raw-key form.  If it's present in raw-key form the previous
	   code will add it as a pseudo-new cert, so we find the location of the
	   corresponding raw and set its index to the raw key position */
	if( !cardCertInfo[ chainIndex ].certPresent )
		{
		HASHFUNCTION hashFunction;
		RESOURCE_DATA msgData;
		BYTE hash[ CRYPT_MAX_HASHSIZE ], keyDataBuffer[ 1024 ];
		int certIndex;

		/* Get the keyID for the leaf certificate */
		getHashParameters( CRYPT_ALGO_SHA, &hashFunction, NULL );
		setMessageData( &msgData, keyDataBuffer, 1024 );
		if( cryptStatusError( \
			krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE_S,
							 &msgData, CRYPT_IATTRIBUTE_SPKI ) ) )
			return( CRYPT_ARGERROR_NUM1 );
		hashFunction( NULL, hash, keyDataBuffer, msgData.length, HASH_ALL );

		/* If we're not adding the cert as a data-only PAA cert in the 0-th
		   slot (which is a special case with no corresponding personality 
		   present), find the slot for the cert based on the location of the 
		   corresponding raw key.  If there's no raw key present, we can't 
		   add the chain, since it doesn't correspond to any known key or 
		   cert */
		if( cardCertInfo[ chainIndex ].index > 0 )
			{
			certIndex = findCertFromHash( fortezzaInfo, hash );
			if( cryptStatusError( certIndex ) )
				return( CRYPT_ERROR_NOTFOUND );
			cardCertInfo[ chainIndex ].index = certIndex;
			}
		cardCertInfo[ chainIndex ].personalityPresent = TRUE;
		}

	/* Pass 2: Update either the label or cert+label as required */
	value = CRYPT_CURSOR_LAST;
	krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, &value, 
					 CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	value = CRYPT_CURSOR_PREVIOUS;
	chainIndex = 0;
	do
		{
		CARDCERT_INFO *currentCertInfo = &cardCertInfo[ chainIndex++ ];
		char name[ CRYPT_MAX_TEXTSIZE + 1 ], *labelPtr = NULL;
		int status;

		/* If the cert is already present, make sure that the parent index 
		   info is correct */
		if( currentCertInfo->certPresent )
			{
			CI_CERTIFICATE certificate;
			const int certIndex = currentCertInfo->index;
			char buffer[ 8 ];
			int index;

			/* If the cert is present and the parent cert index is correct,
			   continue */
			if( ( sscanf( personalityList[ certIndex ].CertLabel + 6, 
						  "%02X", &index ) == 1 ) && \
				( currentCertInfo->parentIndex == index || \
				  currentCertInfo->parentIndex == CRYPT_UNUSED ) )
				continue;

			/* Update the parent cert index in the label, read the cert, and 
			   write it back out with the new label */
			sprintf( buffer, "%02X", currentCertInfo->parentIndex );
			memcpy( personalityList[ certIndex ].CertLabel + 6, buffer, 2 );
			status = pCI_GetCertificate( certIndex, certificate );
#ifndef NO_UPDATE
			if( status == CI_OK )
				status = pCI_LoadCertificate( certIndex, 
									personalityList[ certIndex ].CertLabel,
									certificate, 0 );
#endif /* NO_UPDATE */
			if( status != CI_OK )
				return( mapError( status, CRYPT_ERROR_WRITE ) );
			continue;
			}
		
		/* If we're adding a new cert for a non-present personality (that is,
		   a data-only CA cert from higher up in the chain that doesn't 
		   correspond to a personality on the card), get SubjectName 
		   information from the cert to use as the label and make sure that 
		   it's within the maximum allowed length.  Some certs don't have CN 
		   components, so we try for the OU instead.  If that also fails, we 
		   try for the O, and if that fails we  just use a dummy label 
		   identifying it as a generic CA cert */
		if( !currentCertInfo->personalityPresent )
			{
			RESOURCE_DATA msgData;

			value = CRYPT_UNUSED;
			krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, &value, 
							 CRYPT_CERTINFO_SUBJECTNAME );
			setMessageData( &msgData, name, CRYPT_MAX_TEXTSIZE );
			status = krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE_S,
							&msgData, CRYPT_CERTINFO_COMMONNAME );
			if( status == CRYPT_ERROR_NOTFOUND )
				status = krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE_S, 
							&msgData, CRYPT_CERTINFO_ORGANIZATIONALUNITNAME );
			if( status == CRYPT_ERROR_NOTFOUND )
				status = krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE_S, 
							&msgData, CRYPT_CERTINFO_ORGANIZATIONALUNITNAME );
			if( status == CRYPT_ERROR_NOTFOUND )
				strcpy( name, "CA certificate-only entry" );
			else
				name[ min( msgData.length, 24 ) ] = '\0';
			labelPtr = name;
			}

		/* Write the new cert and label */
		status = updateCertificate( fortezzaInfo, currentCertInfo->index, 
									iCryptCert, labelPtr, 
									currentCertInfo->parentIndex );
		if( cryptStatusError( status ) )
			return( status );
		}
	while( krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, &value,
							CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK );
	
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*					Device Init/Shutdown/Device Control Routines			*
*																			*
****************************************************************************/

/* Table of mechanisms supported by this device.  These are sorted in order 
   of frequency of use in order to make lookups a bit faster */

int exportKEA( DEVICE_INFO *deviceInfo, MECHANISM_WRAP_INFO *mechanismInfo );
int importKEA( DEVICE_INFO *deviceInfo, MECHANISM_WRAP_INFO *mechanismInfo );

static const MECHANISM_FUNCTION_INFO objectMechanisms[] = {
	{ MESSAGE_DEV_EXPORT, MECHANISM_KEA, exportKEA },
	{ MESSAGE_DEV_IMPORT, MECHANISM_KEA, importKEA },

⌨️ 快捷键说明

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