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

📄 pkcs15_adpb.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
						  pkcs15infoPtr->privKeyOffset;
		status = calculatePrivkeyStorage( pkcs15infoPtr, &newPrivKeyData,
										  &newPrivKeyDataSize, 
										  privKeyInfoSize,
										  privKeyAttributeSize, 0 );
		if( cryptStatusError( status ) )
			return( status );
		}
	setMessageData( &msgData, NULL, 0 );
	status = krnlSendMessage( iCryptCert, IMESSAGE_CRT_EXPORT, &msgData,
							  CRYPT_CERTFORMAT_CERTIFICATE );
	if( cryptStatusOK( status ) )
		{
		certInfoSize = msgData.length;
		status = calculateCertStorage( pkcs15infoPtr, &newCertData,
									   &newCertDataSize, certAttributeSize,
									   certInfoSize );
		}
	if( cryptStatusError( status ) )
		{
		if( newPrivKeyData != pkcs15infoPtr->privKeyData )
			clFree( "addCert", newPrivKeyData );
		return( status );
		}

	/* Write the PKCS #15 certificate data */
	sMemOpen( &stream, newCertData, newCertDataSize );
	writeSequence( &stream, certAttributeSize + \
							sizeofObject( sizeofObject( certInfoSize ) ) );
	swrite( &stream, certAttributes, certAttributeSize );
	writeConstructed( &stream, sizeofObject( certInfoSize ), 
					  CTAG_OB_TYPEATTR );
	status = writeSequence( &stream, certInfoSize );
	if( cryptStatusOK( status ) )
		{
		newCertOffset = stell( &stream );
		status = exportCertToStream( &stream, iCryptCert, 
									 CRYPT_CERTFORMAT_CERTIFICATE );
		}
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		{
		/* Undo what we've done so far without changing the existing PKCS #15
		   data */
		assert( DEBUG_WARN );
		if( newPrivKeyData != pkcs15infoPtr->privKeyData )
			clFree( "addCert", newPrivKeyData );
		if( newCertData != pkcs15infoPtr->certData && newCertData != NULL )
			clFree( "addCert", newCertData );
		retExt( status, 
				( status, errorInfo, 
				  "Couldn't write PKCS #15 certificate data" ) );
		}
	ENSURES( !cryptStatusError( checkObjectEncoding( newCertData, \
													 newCertDataSize ) ) );

#ifdef POST_DRAFT_ENCAPSULATION
	/* Certificates require an awkward CTAG_OV_DIRECT (= [0] IMPLICIT) tag, 
	   this is simple to handle when we're encoding the data ourselves (as 
	   we do for public and private keys) but a serious pain if we're simply 
	   exporting pre-encoded data like a certificate.  In order to handle 
	   this we modify the exported encoded data, which is easier than 
	   passing the tag requirement down through the kernel call to the 
	   certificate export code */
	( ( BYTE * ) newCertData )[ newCertOffset ] = MAKE_CTAG( CTAG_OV_DIRECT );
#endif /* POST_DRAFT_ENCAPSULATION */

	/* Replace the old certificate (if there is one) with the new one.  If 
	   it's a certificate associated with a private key we also have to 
	   update the private-key attributes, which can be affected by 
	   certificate information */
	pkcs15infoPtr->type = subType;
	replaceCertData( pkcs15infoPtr, newCertData, newCertDataSize, 
					 newCertOffset );
	if( certAddType == CERTADD_UPDATE_EXISTING )
		{
		updatePrivKeyAttributes( pkcs15infoPtr, 
								 newPrivKeyData, newPrivKeyDataSize, 
								 privKeyAttributes, privKeyAttributeSize, 
								 privKeyInfoSize, keyTypeTag );
		}

	/* The public-key data is redundant now that we've performed the update,
	   delete it */
	if( pkcs15infoPtr->pubKeyData != NULL )
		deletePubKey( pkcs15infoPtr );

	return( CRYPT_OK );
	}

/* Add a complete certificate chain to a PKCS #15 collection */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
int pkcs15AddCertChain( INOUT PKCS15_INFO *pkcs15info, 
						IN_LENGTH_SHORT const int noPkcs15objects,
						IN_HANDLE const CRYPT_CERTIFICATE iCryptCert, 
						INOUT ERROR_INFO *errorInfo )
	{
	BOOLEAN seenNonDuplicate = FALSE;
	int iterationCount = 0, status;

	assert( isWritePtr( pkcs15info, \
						sizeof( PKCS15_INFO ) * noPkcs15objects ) );

	REQUIRES( noPkcs15objects >= 1 && \
			  noPkcs15objects < MAX_INTLENGTH_SHORT );
	REQUIRES( isHandleRangeValid( iCryptCert ) );
	REQUIRES( errorInfo != NULL );

	/* See if there are certificates in the chain beyond the first one, 
	   which we've already added.  Getting a data not found error is OK 
	   since it just means that there are no more certificates present */
	status = krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_CURSORFIRST,
							  CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
								  MESSAGE_VALUE_CURSORNEXT,
								  CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ERROR_NOTFOUND ) ? CRYPT_OK : status );

	/* Walk up the chain checking each certificate to see whether we need to 
	   add it */
	do
		{
		PKCS15_INFO *pkcs15infoPtr;
		BYTE iAndSID[ CRYPT_MAX_HASHSIZE + 8 ];
		int iAndSIDlength, index;

		/* Check whether this certificate is present */
		status = getCertID( iCryptCert, CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER,
							iAndSID, KEYID_SIZE, &iAndSIDlength );
		if( cryptStatusError( status ) )
			continue;
		if( findEntry( pkcs15info, noPkcs15objects, CRYPT_IKEYID_ISSUERID, 
					   iAndSID, iAndSIDlength, KEYMGMT_FLAG_NONE ) != NULL )
			continue;

		/* We've found a certificate that isn't present yet, try and add 
		   it */
		pkcs15infoPtr = findFreeEntry( pkcs15info, noPkcs15objects, &index );
		if( pkcs15infoPtr == NULL )
			return( CRYPT_ERROR_OVERFLOW );
		status = pkcs15AddCert( pkcs15infoPtr, iCryptCert, NULL, 0, 
								CERTADD_NORMAL, errorInfo );
		if( cryptStatusOK( status ) )
			pkcs15infoPtr->index = index;

		/* A certificate being added may already be present, however we 
		   can't fail immediately because there may be further certificates 
		   in the chain that can be added so we keep track of whether we've 
		   successfully added at least one certificate and clear data 
		   duplicate errors */
		if( cryptStatusOK( status ) )
			seenNonDuplicate = TRUE;
		else
			{
			if( status == CRYPT_ERROR_DUPLICATE )
				status = CRYPT_OK;
			}
		}
	while( cryptStatusOK( status ) && \
		   krnlSendMessage( iCryptCert, IMESSAGE_SETATTRIBUTE,
							MESSAGE_VALUE_CURSORNEXT,
							CRYPT_CERTINFO_CURRENT_CERTIFICATE ) == CRYPT_OK && \
		   iterationCount++ < FAILSAFE_ITERATIONS_MED );
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
	if( cryptStatusOK( status ) && !seenNonDuplicate )
		{
		/* We reached the end of the chain without finding anything that we 
		   could add, return a data duplicate error */
		retExt( CRYPT_ERROR_DUPLICATE, 
				( CRYPT_ERROR_DUPLICATE, errorInfo, 
				  "Couldn't find any new certificates to add" ) );
		}
	return( status );
	}

/****************************************************************************
*																			*
*								Add a Public Key							*
*																			*
****************************************************************************/

/* Add a public key to a PKCS #15 collection */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 7 ) ) \
int pkcs15AddPublicKey( INOUT PKCS15_INFO *pkcs15infoPtr, 
						IN_HANDLE const CRYPT_HANDLE iCryptContext, 
						IN_BUFFER( pubKeyAttributeSize ) \
							const void *pubKeyAttributes, 
						IN_LENGTH_SHORT const int pubKeyAttributeSize,
						IN_ALGO const CRYPT_ALGO_TYPE pkcCryptAlgo, 
						IN_LENGTH_PKC const int modulusSize, 
						INOUT ERROR_INFO *errorInfo )
	{
	MESSAGE_DATA msgData;
	STREAM stream;
	void *newPubKeyData = pkcs15infoPtr->pubKeyData;
	int newPubKeyDataSize, newPubKeyOffset = DUMMY_INIT, pubKeySize;
	int extraDataSize = 0, keyTypeTag, status;

	assert( isWritePtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) );
	assert( isReadPtr( pubKeyAttributes, pubKeyAttributeSize ) );
	
	REQUIRES( isHandleRangeValid( iCryptContext ) );
	REQUIRES( pubKeyAttributeSize > 0 && \
			  pubKeyAttributeSize < MAX_INTLENGTH_SHORT );
	REQUIRES( pkcCryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
			  pkcCryptAlgo <= CRYPT_ALGO_LAST_PKC );
	REQUIRES( modulusSize >= MIN_PKCSIZE && \
			  modulusSize <= CRYPT_MAX_PKCSIZE );
	REQUIRES( errorInfo != NULL );

	/* Get the tag for encoding the key data */
	status = getKeyTypeTag( CRYPT_UNUSED, pkcCryptAlgo, &keyTypeTag );
	if( cryptStatusError( status ) )
		return( status );

	/* Find out how big the PKCS #15 data will be and allocate room for it */
	setMessageData( &msgData, NULL, 0 );
	status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S, 
							  &msgData, CRYPT_IATTRIBUTE_KEY_SPKI );
	if( cryptStatusError( status ) )
		return( status );
	pubKeySize = msgData.length;
	if( pkcCryptAlgo == CRYPT_ALGO_RSA )
		{
		/* RSA keys have an extra element for PKCS #11 compatibility */
		extraDataSize = sizeofShortInteger( modulusSize );
		}
	status = calculatePubkeyStorage( pkcs15infoPtr, &newPubKeyData, 
									 &newPubKeyDataSize, pubKeySize, 
									 pubKeyAttributeSize, extraDataSize );
	if( cryptStatusError( status ) )
		return( status );

	/* Write the public key data */
	sMemOpen( &stream, newPubKeyData, newPubKeyDataSize );
	writeConstructed( &stream, pubKeyAttributeSize + \
							   sizeofObject( \
								sizeofObject( \
								  sizeofObject( pubKeySize ) + \
								  extraDataSize ) ),
					  keyTypeTag );
	swrite( &stream, pubKeyAttributes, pubKeyAttributeSize );
	writeConstructed( &stream, sizeofObject( \
								sizeofObject( pubKeySize ) + \
								extraDataSize ),
					  CTAG_OB_TYPEATTR );
	writeSequence( &stream, sizeofObject( pubKeySize ) + extraDataSize );
	status = writeConstructed( &stream, pubKeySize, CTAG_OV_DIRECT );
	if( cryptStatusOK( status ) )
		{
		newPubKeyOffset = stell( &stream );
		status = exportAttributeToStream( &stream, iCryptContext,
										  CRYPT_IATTRIBUTE_KEY_SPKI );
		}
	if( cryptStatusOK( status ) && pkcCryptAlgo == CRYPT_ALGO_RSA )
		{
		/* When using the SPKI option for storing key components the RSA
		   components require a [1] tag since the basic (non-SPKI) option is
		   also a SEQUENCE, so if it's an RSA key we modify the tag.  This is
		   easier than passing the tag requirement down through the kernel
		   call to the context.  In addition RSA keys have an extra element
		   for PKCS #11 compatibility */
		( ( BYTE * ) newPubKeyData )[ newPubKeyOffset ] = MAKE_CTAG( 1 );
		status = writeShortInteger( &stream, modulusSize, DEFAULT_TAG );
		}
	assert( stell( &stream ) == newPubKeyDataSize );
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		{
		assert( DEBUG_WARN );
		if( newPubKeyData != pkcs15infoPtr->pubKeyData )
			clFree( "addPublicKey", newPubKeyData );
		retExt( status, 
				( status, errorInfo, 
				  "Couldn't write PKCS #15 public-key data" ) );
		}
	ENSURES( !cryptStatusError( checkObjectEncoding( newPubKeyData, \
													 newPubKeyDataSize ) ) );

	/* Replace the old data with the newly-written data */
	replacePubkeyData( pkcs15infoPtr, newPubKeyData, newPubKeyDataSize,
					   newPubKeyOffset );
	return( CRYPT_OK );
	}
#endif /* USE_PKCS15 */

⌨️ 快捷键说明

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