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

📄 envelope.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
	CRYPT_ENVELOPE cryptEnvelope;
	CRYPT_CONTEXT cryptContext;
	CRYPT_ALGO_TYPE cryptAlgo = ( formatType == CRYPT_FORMAT_PGP ) ? \
								selectCipher( CRYPT_ALGO_IDEA ) : \
								selectCipher( CRYPT_ALGO_CAST );
	BYTE *inBufPtr = ENVELOPE_TESTDATA, *outBufPtr = globalBuffer;
	const int length = useLargeBuffer ? \
							( ( INT_MAX <= 32768L ) ? 16384 : 1048576 ) : \
							ENVELOPE_TESTDATA_SIZE;
	const int bufSize = length + 128;
	int count;

	if( useLargeBuffer )
		{
		int i;

		printf( "Testing %sraw-session-key encrypted enveloping of large "
				"data quantity...\n", 
				( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "" );

		/* Allocate a large buffer and fill it with a known value */
		if( ( inBufPtr = malloc( bufSize ) ) == NULL )
			{
			printf( "Couldn't allocate buffer of %d bytes, skipping large "
					"buffer enveloping test.\n", length );
			return( TRUE );
			}
		outBufPtr = inBufPtr;
		for( i = 0; i < length; i++ )
			inBufPtr[ i ] = i & 0xFF;
		}
	else
		printf( "Testing %sraw-session-key encrypted enveloping%s...\n",
				( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "",
				( useDatasize && ( formatType != CRYPT_FORMAT_PGP ) ) ? \
				" with datasize hint" : "" );

	if( formatType != CRYPT_FORMAT_PGP )
		{
		/* Create the session key context.  We don't check for errors here
		   since this code will already have been tested earlier */
		cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
		}
	else
		{
		/* PGP only allows a limited subset of algorithms and modes, in 
		   addition we have to specifically check that IDEA is available 
		   since it's possible to build cryptlib without IDEA support */
		if( cryptAlgo != CRYPT_ALGO_IDEA )
			{
			puts( "Can't test PGP enveloping because the IDEA algorithm "
				  "isn't available in this\nbuild of cryptlib.\n" );
			return( TRUE );
			}
		cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
		cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE, CRYPT_MODE_CFB );
		}
	cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
							 "0123456789ABCDEF", 16 );

	/* Create the envelope, push in a password and the data, pop the
	   enveloped result, and destroy the envelope */
	if( !createEnvelope( &cryptEnvelope, formatType ) || \
		!addEnvInfoNumeric( cryptEnvelope, CRYPT_ENVINFO_SESSIONKEY,
							cryptContext ) )
		return( FALSE );
	if( useDatasize && !useLargeBuffer )
		{
		/* Test the ability to destroy the context after it's been added 
		   (we replace it with a different context that's used later for 
		   de-enveloping) */
		cryptDestroyContext( cryptContext );
		cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
		cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY, 
								 "0123456789ABCDEF", 16 );
		}
	if( useDatasize )
		cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE, length );
	if( useLargeBuffer )
		cryptSetAttribute( cryptEnvelope, CRYPT_ATTRIBUTE_BUFFERSIZE,
						   length + 1024 );
	count = pushData( cryptEnvelope, inBufPtr, length, NULL, 0 );
	if( cryptStatusError( count ) )
		return( FALSE );
	count = popData( cryptEnvelope, outBufPtr, bufSize );
	if( cryptStatusError( count ) )
		return( FALSE );
	if( !destroyEnvelope( cryptEnvelope ) )
		return( FALSE );

	/* Tell them what happened */
	printf( "Enveloped data has size %d bytes.\n", count );
	if( !useLargeBuffer )
		debugDump( dumpFileName, outBufPtr, count );

	/* Create the envelope, push in the data, pop the de-enveloped result,
	   and destroy the envelope */
	if( !createDeenvelope( &cryptEnvelope ) )
		return( FALSE );
	if( useLargeBuffer )
		cryptSetAttribute( cryptEnvelope, CRYPT_ATTRIBUTE_BUFFERSIZE,
						   length + 1024 );
	count = pushData( cryptEnvelope, outBufPtr, count, NULL, cryptContext );
	if( cryptStatusError( count ) )
		return( FALSE );
	count = popData( cryptEnvelope, outBufPtr, bufSize );
	if( cryptStatusError( count ) )
		return( FALSE );
	if( !destroyEnvelope( cryptEnvelope ) )
		return( FALSE );

	/* Make sure that the result matches what we pushed */
	if( count != length )
		{
		puts( "De-enveloped data length != original length." );
		return( FALSE );
		}
	if( useLargeBuffer )
		{
		int i;

		for( i = 0; i < length; i++ )
			if( outBufPtr[ i ] != ( i & 0xFF ) )
			{
			printf( "De-enveloped data != original data at byte %d.\n", i );
			return( FALSE );
			}
		}
	else
		if( memcmp( outBufPtr, ENVELOPE_TESTDATA, length ) )
			{
			puts( "De-enveloped data != original data." );
			return( FALSE );
			}

	/* Clean up */
	if( useLargeBuffer )
		free( inBufPtr );
	cryptDestroyContext( cryptContext );
	puts( "Enveloping of raw-session-key-encrypted data succeeded.\n" );
	return( TRUE );
	}

int testEnvelopeSessionCrypt( void )
	{
	if( !envelopeSessionCrypt( "env_sesn", FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
		return( FALSE );	/* Indefinite length */
	if( !envelopeSessionCrypt( "env_ses", TRUE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
		return( FALSE );	/* Datasize */
#if 0
	/* Although in theory PGP supports raw session-key based enveloping, in
	   practice this key is always (implicitly) derived from a user password,
	   so the enveloping code doesn't allow the use of raw session keys */
	return( envelopeSessionCrypt( "env_ses.pgp", TRUE, FALSE, CRYPT_FORMAT_PGP ) );
#endif /* 0 */
	return( TRUE );
	}

int testEnvelopeSessionCryptLargeBuffer( void )
	{
	return( envelopeSessionCrypt( "env_ses", TRUE, TRUE, CRYPT_FORMAT_CRYPTLIB ) );
	}						/* Datasize, large buffer */

/* Test encrypted enveloping */

static int envelopeDecrypt( BYTE *buffer, const int length, 
							const CRYPT_CONTEXT cryptContext )
	{
	CRYPT_ENVELOPE cryptEnvelope;
	int count;

	/* Create the envelope, push in the data, pop the de-enveloped result,
	   and destroy the envelope */
	if( !createDeenvelope( &cryptEnvelope ) )
		return( FALSE );
	count = pushData( cryptEnvelope, buffer, length, NULL, cryptContext );
	if( cryptStatusError( count ) )
		return( FALSE );
	count = popData( cryptEnvelope, buffer, BUFFER_SIZE );
	if( cryptStatusError( count ) )
		return( FALSE );
	destroyEnvelope( cryptEnvelope );
	return( count );
	}

static int envelopeCrypt( const char *dumpFileName, 
						  const BOOLEAN useDatasize,
						  const CRYPT_FORMAT_TYPE formatType )
	{
	CRYPT_CONTEXT cryptContext;
	CRYPT_ENVELOPE cryptEnvelope;
	int count;

	printf( "Testing encrypted enveloping%s...\n", 
			useDatasize ? " with datasize hint" : "" );

	/* Create the session key context.  We don't check for errors here
	   since this code will already have been tested earlier */
	cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_3DES );
	cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
							 "0123456789ABCDEF", 16 );

	/* Create the envelope, push in a KEK and the data, pop the enveloped 
	   result, and destroy the envelope */
	if( !createEnvelope( &cryptEnvelope, formatType ) || \
		!addEnvInfoNumeric( cryptEnvelope, CRYPT_ENVINFO_KEY, cryptContext ) )
		return( FALSE );
	if( useDatasize )
		cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE,
						   ENVELOPE_TESTDATA_SIZE );
	count = pushData( cryptEnvelope, ENVELOPE_TESTDATA,
					  ENVELOPE_TESTDATA_SIZE, NULL, 0 );
	if( cryptStatusError( count ) )
		return( FALSE );
	count = popData( cryptEnvelope, globalBuffer, BUFFER_SIZE );
	if( cryptStatusError( count ) )
		return( FALSE );
	if( !destroyEnvelope( cryptEnvelope ) )
		return( FALSE );

	/* Tell them what happened */
	printf( "Enveloped data has size %d bytes.\n", count );
	debugDump( dumpFileName, globalBuffer, count );

	/* De-envelope the data and make sure that the result matches what we
	   pushed */
	count = envelopeDecrypt( globalBuffer, count, cryptContext );
	if( !count )
		return( FALSE );
	if( count != ENVELOPE_TESTDATA_SIZE || \
		memcmp( globalBuffer, ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE ) )
		{
		puts( "De-enveloped data != original data." );
		return( FALSE );
		}

	/* Clean up */
	cryptDestroyContext( cryptContext );
	puts( "Enveloping of encrypted data succeeded.\n" );
	return( TRUE );
	}

int testEnvelopeCrypt( void )
	{
	if( !envelopeCrypt( "env_kekn", FALSE, CRYPT_FORMAT_CRYPTLIB ) )
		return( FALSE );	/* Indefinite length */
	return( envelopeCrypt( "env_kek", TRUE, CRYPT_FORMAT_CRYPTLIB ) );
	}						/* Datasize */


/* Test password-based encrypted enveloping */

static int envelopePasswordDecrypt( BYTE *buffer, const int length )
	{
	CRYPT_ENVELOPE cryptEnvelope;
	int count;

	/* Create the envelope, push in the data, pop the de-enveloped result,
	   and destroy the envelope */
	if( !createDeenvelope( &cryptEnvelope ) )
		return( FALSE );
	count = pushData( cryptEnvelope, buffer, length, TEXT( "Password" ), 
					  paramStrlen( TEXT( "Password" ) ) );
	if( cryptStatusError( count ) )
		return( FALSE );
	count = popData( cryptEnvelope, buffer, BUFFER_SIZE );
	if( cryptStatusError( count ) )
		return( FALSE );
	destroyEnvelope( cryptEnvelope );
	return( count );
	}

static int envelopePasswordCrypt( const char *dumpFileName, 
								  const BOOLEAN useDatasize, 
								  const BOOLEAN useAltCipher, 
								  const BOOLEAN multiKeys,
								  const CRYPT_FORMAT_TYPE formatType )
	{
	CRYPT_ENVELOPE cryptEnvelope;
	int count;

	printf( "Testing %s%spassword-encrypted enveloping%s",
			( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "",
			multiKeys ? "multiple-" : "",
			( useDatasize && ( formatType != CRYPT_FORMAT_PGP ) ) ? \
			" with datasize hint" : "" );
	if( useAltCipher )
		printf( ( formatType == CRYPT_FORMAT_PGP ) ? \
				" with non-default cipher type" : " and stream cipher" );
	puts( "..." );

	/* Create the envelope, push in a password and the data, pop the
	   enveloped result, and destroy the envelope */
	if( !createEnvelope( &cryptEnvelope, formatType ) || \
		!addEnvInfoString( cryptEnvelope, CRYPT_ENVINFO_PASSWORD, 
						   TEXT( "Password" ), 
						   paramStrlen( TEXT( "Password" ) ) ) )
		return( FALSE );
	if( useAltCipher )
		{
		CRYPT_CONTEXT sessionKeyContext;
		int status;

		/* Test enveloping with an IV-less stream cipher, which tests the
		   handling of algorithms that can't be used to wrap themselves in 
		   the RecipientInfo */
		status = cryptCreateContext( &sessionKeyContext, CRYPT_UNUSED, 
									 CRYPT_ALGO_RC4 );
		if( cryptStatusOK( status ) )
			{
			cryptGenerateKey( sessionKeyContext );
			status = cryptSetAttribute( cryptEnvelope, 
										CRYPT_ENVINFO_SESSIONKEY, 
										sessionKeyContext );
			cryptDestroyContext( sessionKeyContext );
			}
		if( cryptStatusError( status ) )
			{
			printf( "Couldn't set non-default envelope cipher, error code "
					"%d, line %d.\n", status, __LINE__ );
			return( FALSE );
			}
		}
	if( multiKeys && \
		( !addEnvInfoString( cryptEnvelope, CRYPT_ENVINFO_PASSWORD, 
							 TEXT( "Password1" ), 
							 paramStrlen( TEXT( "Password1" ) ) ) || \
		  !addEnvInfoString( cryptEnvelope, CRYPT_ENVINFO_PASSWORD, 
							 TEXT( "Password2" ), 
							 paramStrlen( TEXT( "Password2" ) ) ) || \
		  !addEnvInfoString( cryptEnvelope, CRYPT_ENVINFO_PASSWORD, 
							 TEXT( "Password3" ), 
							 paramStrlen( TEXT( "Password3" ) ) ) ) )
		return( FALSE );
	if( useDatasize )
		cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE,
						   ENVELOPE_TESTDATA_SIZE );
	count = pushData( cryptEnvelope, ENVELOPE_TESTDATA,
					  ENVELOPE_TESTDATA_SIZE, NULL, 0 );
	if( cryptStatusError( count ) )
		return( FALSE );
	count = popData( cryptEnvelope, globalBuffer, BUFFER_SIZE );
	if( cryptStatusError( count ) )
		return( FALSE );
	if( !destroyEnvelope( cryptEnvelope ) )
		return( FALSE );

	/* Tell them what happened */
	printf( "Enveloped data has size %d bytes.\n", count );
	debugDump( dumpFileName, globalBuffer, count );

	/* De-envelope the data and make sure that the result matches what we
	   pushed */
	count = envelopePasswordDecrypt( globalBuffer, count );
	if( !count )
		return( FALSE );
	if( count != ENVELOPE_TESTDATA_SIZE || \
		memcmp( globalBuffer, ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE ) )
		{
		puts( "De-enveloped data != original data." );
		return( FALSE );
		}

	/* Clean up */
	puts( "Enveloping of password-encrypted data succeeded.\n" );
	return( TRUE );
	}

int testEnvelopePasswordCrypt( void )
	{
	if( !envelopePasswordCrypt( "env_pasn", FALSE, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
		return( FALSE );	/* Indefinite length */
	if( !envelopePasswordCrypt( "env_pas", TRUE, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
		return( FALSE );	/* Datasize */
	if( !envelopePasswordCrypt( "env_mpas", TRUE, FALSE, TRUE, CRYPT_FORMAT_CRYPTLIB ) )
		return( FALSE );	/* Datasize, multiple keys */
	if( !envelopePasswordCrypt( "env_pas.pgp", TRUE, FALSE, FALSE, CRYPT_FORMAT_PGP ) )

⌨️ 快捷键说明

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