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

📄 asn1oid.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 4 页
字号:
								  RESOURCE_IMESSAGE_GETATTRIBUTE_S, &msgData, 
								  CRYPT_CTXINFO_IV );
		ivSize = msgData.length;
		sizeofIV = ( int ) sizeofObject( ivSize );
		}
	if( cryptStatusError( status ) )
		return( status );
	if( ( oid = algorithmToOIDcheck( algorithm, ( CRYPT_ALGO ) mode ) ) == NULL )
		/* Some algorithm+mode combinations can't be encoded using the
		   oddball collection of PKCS #7 OIDs, the best we can do is return
		   a CRYPT_ERROR_NOTAVAIL */
		return( CRYPT_ERROR_NOTAVAIL );
	oidSize = sizeofOID( oid );

	/* Write algorithm-specific OID parameters */
	if( algorithm == CRYPT_ALGO_CAST )
		{
		const int paramSize = sizeofIV + sizeofShortInteger( 128 );

		writeSequence( stream, oidSize + ( int ) sizeofObject( paramSize ) );
		swrite( stream, oid, oidSize );
		writeSequence( stream, paramSize );
		writeOctetString( stream, iv, ivSize, DEFAULT_TAG );
		return( writeShortInteger( stream, 128, DEFAULT_TAG ) );
		}
	if( algorithm == CRYPT_ALGO_AES || algorithm == CRYPT_ALGO_DES || \
		algorithm == CRYPT_ALGO_3DES || algorithm == CRYPT_ALGO_BLOWFISH )
		{
		const int noBits = ( algorithm == CRYPT_ALGO_AES ) ? 128 : 64;
		const int paramSize = ( mode == CRYPT_MODE_ECB ) ? sizeofNull() : \
			( ( mode == CRYPT_MODE_CBC ) || \
			  ( algorithm == CRYPT_ALGO_AES && mode == CRYPT_MODE_OFB ) ) ? \
			  sizeofIV : \
			  ( int ) sizeofObject( sizeofIV + sizeofShortInteger( noBits ) );

		writeSequence( stream, oidSize + paramSize );
		if( algorithm == CRYPT_ALGO_AES )
			{
			int keySize;

			/* AES uses a bizarre encoding in which the last byte of the OID
			   jumps in steps of 20 depending on the key size, so we adjust
			   the OID we actually write based on the key size (it's 
			   extremely unlikely that any implementation cares about this 
			   since the size information is always communicated anderswhere, 
			   but we do it just in case) */
			krnlSendMessage( iCryptContext, RESOURCE_IMESSAGE_GETATTRIBUTE, 
							 &keySize, CRYPT_CTXINFO_KEYSIZE );
			swrite( stream, oid, oidSize - 1 );
			sputc( stream, oid[ oidSize - 1 ] + \
						   ( keySize == 16 ? 0 : keySize == 24 ? 20 : 40 ) );
			}
		else
			swrite( stream, oid, oidSize );
		if( mode == CRYPT_MODE_ECB )
			return( writeNull( stream, DEFAULT_TAG ) );
		if( ( mode == CRYPT_MODE_CBC ) || \
			( algorithm == CRYPT_ALGO_AES && mode == CRYPT_MODE_OFB ) )
			return( writeOctetString( stream, iv, ivSize, DEFAULT_TAG ) );
		writeSequence( stream, sizeofIV + sizeofShortInteger( noBits ) );
		writeOctetString( stream, iv, ivSize, DEFAULT_TAG );
		return( writeShortInteger( stream, noBits, DEFAULT_TAG ) );
		}
	if( algorithm == CRYPT_ALGO_IDEA )
		{
		const int paramSize = ( mode == CRYPT_MODE_ECB ) ? \
							  sizeofNull() : ( int ) sizeofObject( sizeofIV );

		writeSequence( stream, oidSize + paramSize );
		swrite( stream, oid, oidSize );
		if( mode == CRYPT_MODE_ECB )
			return( writeNull( stream, DEFAULT_TAG ) );
		writeSequence( stream, sizeofIV );
		return( writeOctetString( stream, iv, ivSize, \
								  ( mode == CRYPT_MODE_CFB ) ? \
								  MAKE_CTAG_PRIMITIVE( 3 ) : DEFAULT_TAG ) );
		}
	if( algorithm == CRYPT_ALGO_RC2 )
		{
		const int paramSize = ( ( mode == CRYPT_MODE_ECB ) ? 0 : sizeofIV ) +
							  sizeofShortInteger( RC2_KEYSIZE_MAGIC );

		writeSequence( stream, oidSize + ( int ) sizeofObject( paramSize ) );
		swrite( stream, oid, oidSize );
		writeSequence( stream, paramSize );
		status = writeShortInteger( stream, RC2_KEYSIZE_MAGIC, DEFAULT_TAG );
		if( mode == CRYPT_MODE_CBC )
			return( writeOctetString( stream, iv, ivSize, DEFAULT_TAG ) );
		return( status );
		}
	if( algorithm == CRYPT_ALGO_RC4 )
		{
		writeSequence( stream, oidSize + sizeofNull() );
		swrite( stream, oid, oidSize );
		return( writeNull( stream, DEFAULT_TAG ) );
		}
	if( algorithm == CRYPT_ALGO_RC5 )
		{
		const int paramSize = sizeofShortInteger( 16 ) +
					sizeofShortInteger( 12 ) + sizeofShortInteger( 64 ) +
					sizeofIV;

		writeSequence( stream, oidSize + ( int ) sizeofObject( paramSize ) );
		swrite( stream, oid, oidSize );
		writeSequence( stream, paramSize );
		writeShortInteger( stream, 16, DEFAULT_TAG );	/* Version */
		writeShortInteger( stream, 12, DEFAULT_TAG );	/* Rounds */
		writeShortInteger( stream, 64, DEFAULT_TAG );	/* Block size */
		return( writeOctetString( stream, iv, ivSize, DEFAULT_TAG ) );
		}
	if( algorithm == CRYPT_ALGO_SKIPJACK )
		{
		writeSequence( stream, oidSize + ( int ) sizeofObject( sizeofIV ) );
		swrite( stream, oid, oidSize );
		writeSequence( stream, sizeofIV );
		return( writeOctetString( stream, iv, ivSize, DEFAULT_TAG ) );
		}

	assert( NOTREACHED );
	return( CRYPT_ERROR );	/* Get rid of compiler warning */
	}

/****************************************************************************
*																			*
*							AlgorithmIdentifier Routines					*
*																			*
****************************************************************************/

/* Because AlgorithmIdentifier's are only defined for a subset of the
   algorithms which cryptlib supports, we have to check that the algorithm
   and mode being used can be represented in encoded data before we try to
   do anything with it */

BOOLEAN checkAlgoID( const CRYPT_ALGO algorithm, const CRYPT_MODE mode )
	{
	return( ( algorithmToOIDcheck( algorithm, \
						( CRYPT_ALGO ) mode ) != NULL ) ? TRUE : FALSE );
	}

/* Determine the size of an AlgorithmIdentifier record */

int sizeofAlgoIDex( const CRYPT_ALGO algorithm, const CRYPT_ALGO subAlgorithm,
					const int extraLength )
	{
	return( ( int ) sizeofObject( \
				sizeofOID( algorithmToOID( algorithm, subAlgorithm ) ) + \
				( extraLength ? extraLength : sizeofNull() ) ) );
	}

int sizeofAlgoID( const CRYPT_ALGO algorithm )
	{
	return( sizeofAlgoIDex( algorithm, CRYPT_ALGO_NONE, 0 ) );
	}

/* Write an AlgorithmIdentifier record */

int writeAlgoIDex( STREAM *stream, const CRYPT_ALGO algorithm,
				   const CRYPT_ALGO subAlgorithm, const int extraLength )
	{
	BYTE *oid = algorithmToOID( algorithm, subAlgorithm );
	const int oidSize = sizeofOID( oid );

	/* Write the AlgorithmIdentifier field */
	writeSequence( stream, oidSize + \
				   ( extraLength ? extraLength : sizeofNull() ) );
	swrite( stream, oid, oidSize );
	if( !extraLength )
		/* No extra parameters so we need to write a NULL */
		writeNull( stream, DEFAULT_TAG );

	return( sGetStatus( stream ) );
	}

int writeAlgoID( STREAM *stream, const CRYPT_ALGO algorithm  )
	{
	return( writeAlgoIDex( stream, algorithm, CRYPT_ALGO_NONE, 0 ) );
	}

/* Read an AlgorithmIdentifier record */

int readAlgoIDex( STREAM *stream, CRYPT_ALGO *algorithm, 
				  CRYPT_ALGO *subAlgorithm, int *extraLength )
	{
	CRYPT_ALGO cryptAlgo;
	BYTE buffer[ MAX_OID_SIZE ];
	int bufferLength, cryptSubAlgo, length, status;

	/* Clear the result fields */
	if( algorithm != NULL )
		*algorithm = CRYPT_ALGO_NONE;
	if( subAlgorithm != NULL )
		*subAlgorithm = CRYPT_ALGO_NONE;
	if( extraLength != NULL )
		*extraLength = 0;

	/* Determine the algorithm information based on the AlgorithmIdentifier
	   field */
	readSequence( stream, &length );
	status = readRawObject( stream, buffer, &bufferLength, MAX_OID_SIZE,
							BER_OBJECT_IDENTIFIER );
	if( cryptStatusError( status ) )
		return( status );
	length -= bufferLength;
	if( ( cryptAlgo = oidToAlgorithm( buffer, &cryptSubAlgo ) ) == CRYPT_ERROR )
		return( CRYPT_ERROR_NOTAVAIL );
	if( algorithm != NULL )
		*algorithm = cryptAlgo;
	if( subAlgorithm != NULL )
		*subAlgorithm = cryptSubAlgo;

	/* Handle any remaining parameters */
	if( length == sizeofNull() )
		/* Skip the algorithm parameters field */
		status = readNull( stream );
	else
		/* Tell the caller how much remains to be read */
		if( extraLength != NULL )
			*extraLength = ( int ) length;

	return( status );
	}

int readAlgoID( STREAM *stream, CRYPT_ALGO *algorithm )
	{
	return( readAlgoIDex( stream, algorithm, NULL, NULL ) );
	}

/* Determine the size of an AlgorithmIdentifier record from an encryption
   context */

int sizeofContextAlgoID( const CRYPT_CONTEXT iCryptContext,
						 const CRYPT_ALGO subAlgorithm, 
						 const int flags )
	{
	int cryptAlgo, status;

	/* If it's a standard write, determine how large the algoID and 
	   parameters are.  Because this is a rather complex operation, the
	   easiest way to do it is to write to a null stream and get its
	   size */
	if( flags == ALGOID_FLAG_NONE )
		{
		STREAM nullStream;

		sMemOpen( &nullStream, NULL, 0 );
		status = writeContextAlgoID( &nullStream, iCryptContext, 
									 subAlgorithm, ALGOID_FLAG_NONE );
		if( cryptStatusOK( status ) )
			status = ( int ) stell( &nullStream );
		sMemClose( &nullStream );
		return( status );
		}

	assert( flags == ALGOID_FLAG_ALGOID_ONLY );

	/* Write the algoID only */
	status = krnlSendMessage( iCryptContext, RESOURCE_IMESSAGE_GETATTRIBUTE,
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( status );
	return( sizeofAlgoIDex( cryptAlgo, subAlgorithm, 0 ) );
	}

/* Write an AlgorithmIdentifier record from an encryption context */

int writeContextAlgoID( STREAM *stream, const CRYPT_CONTEXT iCryptContext,
						const CRYPT_ALGO subAlgorithm, 
						const int flags )
	{
	int cryptAlgo, status;

	status = krnlSendMessage( iCryptContext, RESOURCE_IMESSAGE_GETATTRIBUTE,
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( status );
	if( flags & ALGOID_FLAG_ALGOID_ONLY )
		return( writeAlgoIDex( stream, cryptAlgo, subAlgorithm, 0 ) );

	/* If we're writing parameters such as key and block sizes and IV 
	   alongside the algorithm identifier, it has to be a conventional
	   context */
	assert( subAlgorithm == CRYPT_ALGO_NONE );
	assert( cryptAlgo >= CRYPT_ALGO_FIRST_CONVENTIONAL && \
			cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL );

	return( writeContextCryptAlgoID( stream, iCryptContext ) );
	}

/* Turn an AlgorithmIdentifier into a hash/encryption context */

int readContextAlgoID( STREAM *stream, CRYPT_CONTEXT *iCryptContext,
					   QUERY_INFO *queryInfo, const int tag )
	{
	QUERY_INFO localQueryInfo, *queryInfoPtr = ( queryInfo == NULL ) ? \
											   &localQueryInfo : queryInfo;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	int status;

	/* Read the algorithm info.  If we're not creating a context from the
	   info, we're done */
	if( iCryptContext != NULL )
		*iCryptContext = CRYPT_ERROR;
	status = readAlgoIDInfo( stream, queryInfoPtr, tag );
	if( cryptStatusError( status ) || iCryptContext == NULL )
		{
		if( status == CRYPT_ERROR_BADDATA || status == CRYPT_ERROR_UNDERFLOW )
			/* It's a stream-related error, make it persistent */
			sSetError( stream, status );
		return( status );
		}

	/* Create the object from it */
	setMessageCreateObjectInfo( &createInfo, queryInfoPtr->cryptAlgo );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
							  &createInfo, OBJECT_TYPE_CONTEXT );
	if( cryptStatusError( status ) )
		return( status );
	if( queryInfoPtr->cryptAlgo > CRYPT_ALGO_LAST_CONVENTIONAL )
		{
		/* If it's not a conventional encryption algorithm, we're done */
		*iCryptContext = createInfo.cryptHandle;
		return( CRYPT_OK );
		}
	status = krnlSendMessage( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_SETATTRIBUTE,
							  &queryInfoPtr->cryptMode, CRYPT_CTXINFO_MODE );
	if( cryptStatusOK( status ) && \
		!isStreamCipher( queryInfoPtr->cryptAlgo ) )
		{
		RESOURCE_DATA msgData;
		int ivLength;

		status = krnlSendMessage( createInfo.cryptHandle, 
								  RESOURCE_IMESSAGE_GETATTRIBUTE, 
								  &ivLength, CRYPT_CTXINFO_IVSIZE );
		setResourceData( &msgData, queryInfoPtr->iv, 
						 min( ivLength, queryInfoPtr->ivLength ) );
		if( cryptStatusOK( status ) )
			status = krnlSendMessage( createInfo.cryptHandle, 
									  RESOURCE_IMESSAGE_SETATTRIBUTE_S,
									  &msgData, CRYPT_CTXINFO_IV );

⌨️ 快捷键说明

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