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

📄 fortezza.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
	return( CRYPT_ERROR_NOTFOUND );
	}

/* Update certificate/personality information to reflect changes made in the 
   device */

static void updateCertificateInfo( FORTEZZA_INFO *fortezzaInfo, 
								   const int certIndex, 
								   const void *certificate, 
								   const int certSize, const char *label )
	{
	CI_PERSON *personality = getPersonality( fortezzaInfo, certIndex );
	CI_HASHVALUE *hashList = fortezzaInfo->certHashes;

	/* Update the hash for the certificate/raw key */
	if( certificate != NULL )
		{
		HASHFUNCTION_ATOMIC hashFunctionAtomic;

		getHashAtomicParameters( CRYPT_ALGO_SHA1, &hashFunctionAtomic, NULL );
		hashFunctionAtomic( hashList[ certIndex ], sizeof( CI_HASHVALUE ),
							certificate, certSize );
		}
	else
		{
		/* There's no certificate present at this location (for example 
		   because we've just deleted it), make sure that the hash is zero */
		memset( hashList[ certIndex ], 0, sizeof( CI_HASHVALUE ) );
		}

	/* Update the label for the certificate/personality */
	memset( personality->CertLabel, 0, sizeof( CI_CERT_STR ) );
	strlcpy_s( personality->CertLabel, CI_CERT_NAME_SIZE, label );
	}

/* 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 labelMaxSize,
							  const int parentIndex )
	{
	CI_PERSON *personality = getPersonality( fortezzaInfo, certIndex );
	CI_CERTIFICATE certificate;
	CI_CERT_STR label;
	MESSAGE_DATA msgData;
	int certificateLength, status;

	/* If we're trying to load the PAA certificate, the device must be in 
	   the SSO initialised state */
	if( certIndex <= 0 )
		{
		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 certificate */
	getCertificateLabel( certIndex, parentIndex, iCryptCert, 
						 personality->CertLabel[ 0 ] ? FALSE : TRUE, 
						 label, sizeof( CI_CERT_STR ) );

	/* If there's label data supplied (which happens for data-only 
	   certificates with no associated personality), use that */
	if( labelData != NULL )
		strlcpy_s( label + 8, labelMaxSize - 8, labelData );
	else
		{
		/* Reuse the existing label from the personality corresponding to
		   the certificate */
		strlcpy_s( label + 8, labelMaxSize - 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( cryptStatusError( status ) )
		return( 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 certificate 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 )
	{
	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 */
	strlcpy_s( label, CI_NAME_SIZE, "TEMPFFFF" );
	strlcat_s( label, CI_NAME_SIZE, labelData );

	/* 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 certificate information */
	updateCertificateInfo( fortezzaInfo, certIndex, rawKeyData, 
						   rawKeySize, label );

	return( CRYPT_OK );
	}

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

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

/* Update a card using the certificates in a certificate chain */

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

	/* Initialise the certificate index information and hashes for the 
	   certificates on the card if necessary.  certList[] contains the 
	   mapping of certificates in the chain to positions in the card, 
	   parentList[] contains the mapping of certificates 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 certificate and work our way down, which 
	   ensures that the CA certificates appear first, and that if an update 
	   fails, the parent certificate pointers point to valid fields (since 
	   higher-level certificates are added first) */
	krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, 
					 MESSAGE_VALUE_CURSORLAST, CRYPT_CERTINFO_CURRENT_CERTIFICATE );

	/* Pass 1: Build an index of certificate and parent certificate 
	   positions in the card.  Once this loop has completed, certList[] 
	   contains a mapping from certificate chain position to position in the 
	   card, and parentList[] contains a mapping from certificate chain 
	   position to parent certificate position in the card */
	do
		{
		MESSAGE_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 certificate 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 certificate to parent certificate position 
		   in the card.  The certificate at position 0 is the root 
		   certificate */
		if( chainIndex > 0 )
			cardCertInfo[ chainIndex ].parentIndex = oldCertIndex;
		
		/* Set the mapping from certificate to position in the card */
		if( isPresent )
			{
			cardCertInfo[ chainIndex ].index = certIndex;
			cardCertInfo[ chainIndex ].certPresent = TRUE;
			}
		else
			{
			int freeCertIndex;;

			/* Allocate this certificate to the next free position in the 
			   card */
			for( freeCertIndex = 0; 
				 freeCertIndex < fortezzaInfo->personalityCount && \
					personalityList[ freeCertIndex ].CertLabel[ 0 ] != '\0' && \
					freeCertIndex < FAILSAFE_ITERATIONS_MED; 
				 freeCertIndex++ );
			if( freeCertIndex >= FAILSAFE_ITERATIONS_MED )
				retIntError();
			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 && \
		   iterationCount++ < FAILSAFE_ITERATIONS_MED );
	if( iterationCount >= FAILSAFE_ITERATIONS_MED )
		retIntError();

	/* The last certificate 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 certificate, so we find the 
	   location of the corresponding raw and set its index to the raw key 
	   position */
	if( !cardCertInfo[ chainIndex ].certPresent )
		{
		HASHFUNCTION_ATOMIC hashFunctionAtomic;
		MESSAGE_DATA msgData;
		BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ], keyDataBuffer[ 1024 + 8 ];
		int certIndex;

		/* Get the keyID for the leaf certificate */
		getHashAtomicParameters( CRYPT_ALGO_SHA1, &hashFunctionAtomic, NULL );
		setMessageData( &msgData, keyDataBuffer, 1024 );
		if( cryptStatusError( \
			krnlSendMessage( iCryptCert, IMESSAGE_GETATTRIBUTE_S,
							 &msgData, CRYPT_IATTRIBUTE_SPKI ) ) )
			return( CRYPT_ARGERROR_NUM1 );
		hashFunctionAtomic( hash, CRYPT_MAX_HASHSIZE, keyDataBuffer, 
							msgData.length );

		/* If we're not adding the certificate as a data-only PAA 
		   certificate in the 0-th slot (which is a special case with no 
		   corresponding personality present), find the slot for the 
		   certificate 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 certificate */
		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 certificate+label as required */
	value = CRYPT_CURSOR_LAST;
	krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE, &value, 
					 CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	value = CRYPT_CURSOR_PREVIOUS;
	chainIndex = 0;
	iterationCount = 0;
	do
		{
		CARDCERT_INFO *currentCertInfo = &cardCertInfo[ chainIndex++ ];
		char name[ CRYPT_MAX_TEXTSIZE + 1 + 8 ], *labelPtr = NULL;
		int status;

		/* If the certificate 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[ 16 + 8 ];
			int index;

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

			/* Update the parent certificate index in the label, read the 
			   certificate, and write it back out with the new label */
			sprintf_s( buffer, 8, "%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 certificate for a non-present personality 
		   (that is, a data-only CA certificate from higher up in the chain 
		   that doesn't correspond to a personality on the card), get holder 
		   identity information from the certificate to use as the label and 
		   make sure that it's within the maximum allowed length */
		if( !currentCertInfo->personalityPresent )
			{
			MESSAGE_DATA msgData;

⌨️ 快捷键说明

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