📄 envelope.c
字号:
}
}
else
if( cryptStatusError( status ) )
{
printf( "cryptPushData() failed with error code %d, line %d.\n",
status, __LINE__ );
printErrorAttributeInfo( envelope );
return( status );
}
if( bytesIn != length )
{
printf( "cryptPushData() only copied %d of %d bytes, line %d.\n",
bytesIn, length, __LINE__ );
return( SENTINEL );
}
status = cryptGetAttribute( envelope, CRYPT_ENVINFO_CONTENTTYPE,
&contentType );
if( cryptStatusOK( status ) && contentType != CRYPT_CONTENT_DATA )
printf( "Nested content type = %d.\n", contentType );
/* Flush the data */
status = cryptFlushData( envelope );
if( cryptStatusError( status ) && status != CRYPT_ERROR_COMPLETE )
{
printf( "cryptFlushData() failed with error code %d, line %d.\n",
status, __LINE__ );
printErrorAttributeInfo( envelope );
return( status );
}
return( bytesIn );
}
static int popData( CRYPT_ENVELOPE envelope, BYTE *buffer, int bufferSize )
{
int status, bytesOut;
status = cryptPopData( envelope, buffer, bufferSize, &bytesOut );
if( cryptStatusError( status ) )
{
printf( "cryptPopData() failed with error code %d, line %d.\n",
status, __LINE__ );
printErrorAttributeInfo( envelope );
return( status );
}
return( bytesOut );
}
static int destroyEnvelope( CRYPT_ENVELOPE envelope )
{
int status;
/* Destroy the envelope */
status = cryptDestroyEnvelope( envelope );
if( cryptStatusError( status ) )
{
printf( "cryptDestroyEnvelope() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
return( TRUE );
}
/****************************************************************************
* *
* Enveloping Test Routines *
* *
****************************************************************************/
/* Test raw data enveloping */
static int envelopeData( const char *dumpFileName,
const BOOLEAN useDatasize,
const int bufferSize,
const CRYPT_FORMAT_TYPE formatType )
{
CRYPT_ENVELOPE cryptEnvelope;
BYTE *inBufPtr, *outBufPtr = globalBuffer;
int length, bufSize, count;
switch( bufferSize )
{
case 0:
printf( "Testing %splain data enveloping%s...\n",
( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "",
( useDatasize && ( formatType != CRYPT_FORMAT_PGP ) ) ? \
" with datasize hint" : "" );
length = ENVELOPE_TESTDATA_SIZE;
inBufPtr = ENVELOPE_TESTDATA;
break;
case 1:
printf( "Testing %splain data enveloping of intermediate-size data...\n",
( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "" );
length = 512;
inBufPtr = globalBuffer;
for( count = 0; count < length; count++ )
inBufPtr[ count ] = count & 0xFF;
break;
case 2:
printf( "Testing %senveloping of large data quantity...\n",
( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "" );
/* Allocate a large buffer and fill it with a known value */
length = ( INT_MAX <= 32768L ) ? 16384 : 1048576;
if( ( inBufPtr = malloc( length + 128 ) ) == NULL )
{
printf( "Couldn't allocate buffer of %d bytes, skipping large "
"buffer enveloping test.\n", length );
return( TRUE );
}
outBufPtr = inBufPtr;
for( count = 0; count < length; count++ )
inBufPtr[ count ] = count & 0xFF;
break;
default:
return( FALSE );
}
bufSize = length + 128;
/* Create the envelope, push in the data, pop the enveloped result, and
destroy the envelope */
if( !createEnvelope( &cryptEnvelope, formatType ) )
return( FALSE );
if( useDatasize )
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE, length );
if( bufferSize > 1 )
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 );
if( bufferSize == 0 && \
count != length + ( ( formatType == CRYPT_FORMAT_PGP ) ? 8 : \
useDatasize ? 17 : 25 ) )
{
printf( "Enveloped data length %d, should be %d.\n",
count, length + 25 );
return( FALSE );
}
/* Tell them what happened */
printf( "Enveloped data has size %d bytes.\n", count );
if( bufferSize < 2 )
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( bufferSize > 1 )
cryptSetAttribute( cryptEnvelope, CRYPT_ATTRIBUTE_BUFFERSIZE,
length + 1024 );
count = pushData( cryptEnvelope, outBufPtr, count, NULL, 0 );
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( bufferSize > 0 )
{
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( bufferSize > 1 )
free( inBufPtr );
puts( "Enveloping of plain data succeeded.\n" );
return( TRUE );
}
int testEnvelopeData( void )
{
if( !envelopeData( "env_datn", FALSE, 0, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Indefinite-length */
if( !envelopeData( "env_dat", TRUE, 0, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Datasize */
if( !envelopeData( "env_dat.pgp", TRUE, 0, CRYPT_FORMAT_PGP ) )
return( FALSE ); /* PGP format */
return( envelopeData( "env_datl.pgp", TRUE, 1, CRYPT_FORMAT_PGP ) );
} /* PGP format, longer data */
int testEnvelopeDataLargeBuffer( void )
{
if( !envelopeData( NULL, TRUE, 2, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Datasize, large buffer */
return( envelopeData( NULL, TRUE, 2, CRYPT_FORMAT_PGP ) );
} /* Large buffer, PGP format */
/* Test compressed enveloping */
static int envelopeDecompress( BYTE *buffer, const int length )
{
CRYPT_ENVELOPE cryptEnvelope;
BYTE smallBuffer[ 128 ];
int count, zeroCount;
/* Create the envelope, push in the data, and pop the de-enveloped
result */
if( !createDeenvelope( &cryptEnvelope ) )
return( FALSE );
count = pushData( cryptEnvelope, buffer, length, NULL, 0 );
if( cryptStatusError( count ) )
return( FALSE );
count = popData( cryptEnvelope, buffer, FILEBUFFER_SIZE );
if( cryptStatusError( count ) )
{
#ifdef __hpux
if( count == -1 )
puts( "Older HPUX compilers break zlib, to remedy this you can "
"either get a better\ncompiler/OS or grab a debugger and "
"try to figure out what HPUX is doing to\nzlib. To "
"continue the self-tests, comment out the call to\n"
"testEnvelopeCompress() and rebuild." );
#endif /* __hpux */
return( FALSE );
}
/* See what happens when we try and pop out more data. This test is done
because some compressed-data formats don't indicate the end of the
data properly, and we need to make sure that the de-enveloping code
handles this correctly */
zeroCount = popData( cryptEnvelope, smallBuffer, 128 );
if( zeroCount != 0 )
{
puts( "Attempt to pop more data after end-of-data had been reached "
"succeeded, the\nenvelope should have reported 0 bytes "
"available." );
return( FALSE );
}
/* Clean up */
if( !destroyEnvelope( cryptEnvelope ) )
return( FALSE );
return( count );
}
static int envelopeCompress( const char *dumpFileName,
const BOOLEAN useDatasize,
const CRYPT_FORMAT_TYPE formatType )
{
CRYPT_ENVELOPE cryptEnvelope;
FILE *inFile;
BYTE *buffer, *envelopedBuffer;
int dataCount = 0, count, status;
printf( "Testing %scompressed data enveloping%s...\n",
( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "",
useDatasize ? " with datasize hint" : "" );
/* Since this needs a nontrivial amount of data for the compression, we
read it from an external file into dynamically-allocated buffers */
if( ( ( buffer = malloc( FILEBUFFER_SIZE ) ) == NULL ) || \
( ( envelopedBuffer = malloc( FILEBUFFER_SIZE ) ) == NULL ) )
{
if( buffer != NULL )
free( buffer );
puts( "Couldn't allocate test buffers." );
return( FALSE );
}
inFile = fopen( convertFileName( COMPRESS_FILE ), "rb" );
if( inFile != NULL )
{
dataCount = fread( buffer, 1, FILEBUFFER_SIZE, inFile );
fclose( inFile );
assert( dataCount < FILEBUFFER_SIZE );
}
if( dataCount < 1000 || dataCount == FILEBUFFER_SIZE )
{
free( buffer );
free( envelopedBuffer );
puts( "Couldn't read test file for compression." );
return( FALSE );
}
/* Create the envelope, push in the data, pop the enveloped result, and
destroy the envelope */
if( !createEnvelope( &cryptEnvelope, formatType ) )
return( FALSE );
status = cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_COMPRESSION,
CRYPT_UNUSED );
if( cryptStatusError( status ) )
{
printf( "Attempt to enable compression failed, status = %d\n.",
status );
return( FALSE );
}
if( useDatasize )
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE, dataCount );
count = pushData( cryptEnvelope, buffer, dataCount, NULL, 0 );
if( cryptStatusError( count ) )
return( FALSE );
count = popData( cryptEnvelope, envelopedBuffer, FILEBUFFER_SIZE );
if( count > dataCount - 1000 )
{
printf( "Compression of data failed, %d bytes in -> %d bytes out.\n",
dataCount, count );
return( FALSE );
}
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, envelopedBuffer, count );
/* De-envelope the data and make sure that the result matches what we
pushed */
count = envelopeDecompress( envelopedBuffer, count );
if( !count )
return( FALSE );
if( count != dataCount || memcmp( buffer, envelopedBuffer, dataCount ) )
{
puts( "De-enveloped data != original data." );
return( FALSE );
}
/* Clean up */
free( buffer );
free( envelopedBuffer );
puts( "Enveloping of compressed data succeeded.\n" );
return( TRUE );
}
int testEnvelopeCompress( void )
{
/* In practice these two produce identical output since we always have to
use the indefinite-length encoding internally because we don't know in
advance how large the compressed data will be */
if( !envelopeCompress( "env_cprn", FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Indefinite length */
if( !envelopeCompress( "env_cpr", TRUE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Datasize */
return( envelopeCompress( "env_cpr.pgp", TRUE, CRYPT_FORMAT_PGP ) );
} /* PGP format */
/* Test encrypted enveloping with a raw session key */
static int envelopeSessionCrypt( const char *dumpFileName,
const BOOLEAN useDatasize,
const BOOLEAN useLargeBuffer,
const CRYPT_FORMAT_TYPE formatType )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -