dbxpk15.c

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

C
1,715
字号
	if( commonAttributeSize )
		writeCharacterString( &stream, ( BYTE * ) pkcs15info->label,
							  pkcs15info->labelLength, BER_STRING_UTF8 );
	writeSequence( &stream, commonCertAttributeSize );
	writeOctetString( &stream, pkcs15info->iD, pkcs15info->iDlength, 
					  DEFAULT_TAG );
	if( isCA )
		writeBoolean( &stream, TRUE, DEFAULT_TAG );
	if( trustedUsage != CRYPT_UNUSED )
		{
		writeConstructed( &stream, trustedUsageSize, CTAG_CA_TRUSTED_USAGE );
		writeBitString( &stream, trustedUsage, DEFAULT_TAG );
		}
	writeConstructed( &stream, keyIdentifierDataSize, CTAG_CA_IDENTIFIERS );
	writeSequence( &stream, 
				   sizeofShortInteger( PKCS15_KEYID_SUBJECTKEYIDENTIFIER ) +
				   sizeofObject( pkcs15info->keyIDlength ) );
	writeShortInteger( &stream, PKCS15_KEYID_SUBJECTKEYIDENTIFIER,
					   DEFAULT_TAG );
	writeOctetString( &stream, pkcs15info->keyID, 
					  pkcs15info->keyIDlength, DEFAULT_TAG );
	writeSequence( &stream, 
				   sizeofShortInteger( PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH ) +
				   sizeofObject( pkcs15info->iAndSIDlength ) );
	writeShortInteger( &stream, PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH,
					   DEFAULT_TAG );
	writeOctetString( &stream, pkcs15info->iAndSID, 
					  pkcs15info->iAndSIDlength, DEFAULT_TAG );
	writeSequence( &stream, 
				   sizeofShortInteger( PKCS15_KEYID_ISSUERNAMEHASH ) +
				   sizeofObject( pkcs15info->issuerNameIDlength ) );
	writeShortInteger( &stream, PKCS15_KEYID_ISSUERNAMEHASH, DEFAULT_TAG );
	writeOctetString( &stream, pkcs15info->issuerNameID, 
					  pkcs15info->issuerNameIDlength, DEFAULT_TAG );
	writeSequence( &stream, 
				   sizeofShortInteger( PKCS15_KEYID_SUBJECTNAMEHASH ) +
				   sizeofObject( pkcs15info->subjectNameIDlength ) );
	writeShortInteger( &stream, PKCS15_KEYID_SUBJECTNAMEHASH, DEFAULT_TAG );
	writeOctetString( &stream, pkcs15info->subjectNameID, 
					  pkcs15info->subjectNameIDlength, DEFAULT_TAG );
	if( pkcs15info->pgp2KeyIDlength )
		{
		writeSequence( &stream, 
					   sizeofShortInteger( PKCS15_KEYID_PGP2 ) +
					   sizeofObject( pkcs15info->pgp2KeyIDlength ) );
		writeShortInteger( &stream, PKCS15_KEYID_PGP2, DEFAULT_TAG );
		writeOctetString( &stream, pkcs15info->pgp2KeyID, 
						  pkcs15info->pgp2KeyIDlength, DEFAULT_TAG );
		}
	writeSequence( &stream, 
				   sizeofShortInteger( PKCS15_KEYID_OPENPGP ) +
				   sizeofObject( pkcs15info->openPGPKeyIDlength ) );
	writeShortInteger( &stream, PKCS15_KEYID_OPENPGP, DEFAULT_TAG );
	writeOctetString( &stream, pkcs15info->openPGPKeyID, 
					  pkcs15info->openPGPKeyIDlength, DEFAULT_TAG );
	if( trustedImplicit )	
		writeBoolean( &stream, TRUE, CTAG_CA_TRUSTED_IMPLICIT );
	writeGeneralizedTime( &stream, pkcs15info->validFrom, DEFAULT_TAG );
	writeGeneralizedTime( &stream, pkcs15info->validTo, CTAG_CA_VALIDTO );
	*certAttributeSize = ( int ) stell( &stream );
	assert( sStatusOK( &stream ) );
	sMemDisconnect( &stream );

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						PKCS #15 Init/Shutdown Functions					*
*																			*
****************************************************************************/

/* Write the multiple layers of wrapping needed for individual objects */

static void writeObjectWrapper( STREAM *stream, const int length, 
								const int tag )
	{
#if 0	/* pcg 28/6/00 Changed for another interp.of ASN.1 rules */
	writeConstructed( stream, ( int ) sizeofObject( \
										sizeofObject( \
										  sizeofObject( length ) ) ), 
					  tag );
	writeSequence( stream, ( int ) sizeofObject( \
										sizeofObject( length ) ) );
	writeConstructed( stream, ( int ) sizeofObject( length ), 
					  CTAG_OV_DIRECT );
	writeSequence( stream, length );
#else
	writeConstructed( stream, ( int ) sizeofObject( length ), tag );
	writeConstructed( stream, length, CTAG_OV_DIRECT );
#endif /* 0 */
	}

/* Write a data item */

static int sizeofDataItem( const PKCS15_INFO *pkcs15infoPtr )
	{
	const int dataSize = \
			( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
				pkcs15infoPtr->dataDataSize : \
				( int ) sizeofObject( pkcs15infoPtr->dataDataSize );
	const int labelSize = \
			( pkcs15infoPtr->labelLength ) ? \
				( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;

	return( ( int ) \
		sizeofObject( \
			sizeofObject( labelSize ) + \
			sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
			sizeofObject( \
				sizeofObject( \
					sizeofOID( OID_CRYPTLIB_CONFIGDATA ) + dataSize ) ) ) );
	}

static void writeDataItem( STREAM *stream, const PKCS15_INFO *pkcs15infoPtr )
	{
	const BYTE *oid = \
			( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA ) ? \
				OID_CRYPTLIB_CONFIGDATA : \
			( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX ) ? \
				OID_CRYPTLIB_USERINDEX : OID_CRYPTLIB_USERINFO;
	const int labelSize = \
			( pkcs15infoPtr->labelLength ) ? \
				( int ) sizeofObject( pkcs15infoPtr->labelLength ) : 0;
	const int contentSize = sizeofOID( oid ) + \
			( ( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO ) ? \
				pkcs15infoPtr->dataDataSize : \
				( int ) sizeofObject( pkcs15infoPtr->dataDataSize ) );

	assert( pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_CONFIGDATA || \
			pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINDEX || \
			pkcs15infoPtr->dataType == CRYPT_IATTRIBUTE_USERINFO );

	writeConstructed( stream, \
			( int ) sizeofObject( labelSize ) + \
			( int ) sizeofObject( sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) ) + \
			( int ) sizeofObject( sizeofObject( contentSize ) ), 
			CTAG_DO_OIDDO );
	writeSequence( stream, labelSize );
	if( labelSize )
		writeCharacterString( stream, ( BYTE * ) pkcs15infoPtr->label,
							  pkcs15infoPtr->labelLength, BER_STRING_UTF8 );
	writeSequence( stream, sizeofOID( OID_CRYPTLIB_CONTENTTYPE ) );
	writeOID( stream, OID_CRYPTLIB_CONTENTTYPE );
	writeConstructed( stream, ( int ) sizeofObject( contentSize ), 
					  CTAG_OB_TYPEATTR );
	writeSequence( stream, contentSize );
	writeOID( stream, oid );
	if( pkcs15infoPtr->dataType != CRYPT_IATTRIBUTE_USERINFO )
		/* UserInfo is a straight object, the others are SEQUENCEs of 
		   objects */
		writeSequence( stream, pkcs15infoPtr->dataDataSize );
	swrite( stream, pkcs15infoPtr->dataData, pkcs15infoPtr->dataDataSize );
	}

/* Flush a PKCS #15 collection to a stream */

static int pkcs15Flush( STREAM *stream, const PKCS15_INFO *pkcs15info )
	{
	int pubKeySize = 0, privKeySize = 0, certSize = 0, dataSize = 0;
	int objectsSize = 0, i;

	/* Determine the overall size of the objects */
	for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
		switch( pkcs15info[ i ].type )
			{
			case PKCS15_SUBTYPE_NONE:
				break;

			case PKCS15_SUBTYPE_NORMAL:
				pubKeySize += pkcs15info[ i ].pubKeyDataSize;
				privKeySize += pkcs15info[ i ].privKeyDataSize;
				/* Drop through */
			case PKCS15_SUBTYPE_CERT:
				certSize += pkcs15info[ i ].certDataSize;
				break;

			case PKCS15_SUBTYPE_SECRETKEY:
				assert( NOTREACHED );
				break;

			case PKCS15_SUBTYPE_DATA:
				dataSize += sizeofDataItem( &pkcs15info[ i ] );
				break;

			default:
				assert( NOTREACHED );
			}

	/* Determine how much data there is to write.  If there's no data 
	   present, let the caller know that the keyset is empty */
#if 0	/* pcg 28/6/00 Changed for another interp.of ASN.1 rules */
	objectsSize = \
		( pubKeySize ? \
			( int ) sizeofObject( sizeofObject( \
									sizeofObject( \
									  sizeofObject( pubKeySize ) ) ) ) : 0 ) + 
		( privKeySize ? \
			( int ) sizeofObject( sizeofObject( \
									sizeofObject( \
									  sizeofObject( privKeySize ) ) ) ) : 0 ) + 
		( certSize ? \
			( int ) sizeofObject( sizeofObject( \
									sizeofObject( \
									  sizeofObject( certSize ) ) ) ) : 0 ) +
		( dataSize ? \
			( int ) sizeofObject( sizeofObject( \
									sizeofObject( \
									  sizeofObject( dataSize ) ) ) ) : 0 );
#else
	objectsSize = \
		( pubKeySize ? \
			( int ) sizeofObject( sizeofObject( pubKeySize ) ) : 0 ) + 
		( privKeySize ? \
			( int ) sizeofObject( sizeofObject( privKeySize ) ) : 0 ) + 
		( certSize ? \
			( int ) sizeofObject( sizeofObject( certSize ) ) : 0 ) +
		( dataSize ? \
			( int ) sizeofObject( sizeofObject( dataSize ) ) : 0 );
#endif /* 0 */
	if( !objectsSize )
		return( OK_SPECIAL );

	/* Write the header information and each public key, private key, and 
	   cert */
	writeCMSheader( stream, OID_PKCS15_CONTENTTYPE,
					sizeofShortInteger( 0 ) + sizeofObject( objectsSize ), 
					FALSE );
	writeShortInteger( stream, 0, DEFAULT_TAG );
	writeSequence( stream, objectsSize );
	if( privKeySize )
		{
		writeObjectWrapper( stream, privKeySize, PKCS15_OBJECT_PRIVKEY );
		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( pkcs15info[ i ].privKeyDataSize )
				swrite( stream, pkcs15info[ i ].privKeyData, 
						pkcs15info[ i ].privKeyDataSize );
		}
	if( pubKeySize )
		{
		writeObjectWrapper( stream, pubKeySize, PKCS15_OBJECT_PUBKEY );
		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( pkcs15info[ i ].pubKeyDataSize )
				swrite( stream, pkcs15info[ i ].pubKeyData, 
						pkcs15info[ i ].pubKeyDataSize );
		}
	if( certSize )
		{
		writeObjectWrapper( stream, certSize, PKCS15_OBJECT_CERT );
		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( ( pkcs15info[ i ].type == PKCS15_SUBTYPE_NORMAL && \
				  pkcs15info[ i ].certDataSize ) || \
				( pkcs15info[ i ].type == PKCS15_SUBTYPE_CERT ) )
				swrite( stream, pkcs15info[ i ].certData, 
						pkcs15info[ i ].certDataSize );
		}
	if( dataSize )
		{
		writeObjectWrapper( stream, dataSize, PKCS15_OBJECT_DATA );

		for( i = 0; i < MAX_PKCS15_OBJECTS; i++ )
			if( pkcs15info[ i ].dataDataSize )
				writeDataItem( stream, &pkcs15info[ i ] );
		}

	return( sflush( stream ) );
	}

/* A PKCS #15 keyset can contain multiple keys and whatnot, so when we open
   it we scan it and record various pieces of information about it which we
   can use later when we need to access it */

static int initFunction( KEYSET_INFO *keysetInfo, const char *name,
						 const char *arg1, const CRYPT_KEYOPT_TYPE options )
	{
	PKCS15_INFO *pkcs15info, pkcs15objectInfo;
	STREAM *stream = &keysetInfo->keysetFile.stream;
	long outerEndPos;
	int status;

	assert( name == NULL ); assert( arg1 == NULL ); 

	/* Allocate the PKCS #15 object info */
	if( ( pkcs15info = malloc( sizeof( PKCS15_INFO ) * \
							   MAX_PKCS15_OBJECTS ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( pkcs15info, 0, sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS );
	keysetInfo->keyData = pkcs15info;
	keysetInfo->keyDataSize = sizeof( PKCS15_INFO ) * MAX_PKCS15_OBJECTS;

	/* If this is a newly-created keyset, there's nothing left to do */
	if( options == CRYPT_KEYOPT_CREATE )
		return( CRYPT_OK );

	/* Skip the outer header, optional keyManagementInfo, and inner header */
	status = readCMSheader( stream, keyFileOIDselection, &outerEndPos, FALSE );
	if( !cryptStatusError( status ) && outerEndPos < 16 )
		/* Make sure the length is sensible, problems can occur if the 
		   indefinite encoding is used */
		status = CRYPT_ERROR_BADDATA;
	outerEndPos += stell( stream ) - sizeofShortInteger( 0 );
	if( !cryptStatusError( status ) && peekTag( stream ) == MAKE_CTAG( 0 ) )
		status = readUniversal( stream );
	if( !cryptStatusError( status ) )
		status = readSequence( stream, NULL );
	if( cryptStatusError( status ) )
		{
		free( keysetInfo->keyData );
		keysetInfo->keyDataSize = 0;
		return( status );
		}

	/* Scan all the objects in the file.  We allow a bit of slop to handle 
	   incorrect length encodings (16 bytes = roughly min.object size) */
	while( !cryptStatusError( status ) && stell( stream ) < outerEndPos - 16 )
		{
		const PKCS15_OBJECT_TYPE type = EXTRACT_CTAG( readTag( stream ) );
		int innerEndPos;

		/* Read the [n] [0] wrapper to find out what we're dealing with */
		if( type < 0 || type >= PKCS15_OBJECT_LAST )
			{
			status = CRYPT_ERROR_BADDATA;
			break;
			}
		readShortLength( stream );
		status = readConstructed( stream, &innerEndPos, CTAG_OV_DIRECT );
		if( cryptStatusError( status ) )
			break;
		innerEndPos += stell( stream );

		/* Scan all objects of this type, again allowing for slop */
		while( stell( stream ) < innerEndPos - 16 )
			{
			PKCS15_INFO *pkcs15infoPtr;
			void *objectData;
			const int startPos = ( int ) stell( stream );
			int objectLength;

			/* Read the current object.  We can't use getObjectLength() here
			   because we're reading from a file rather than a memory stream */
			readTag( stream );
			objectLength = readShortLength( stream );

⌨️ 快捷键说明

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