📄 testenv.c
字号:
if( cryptStatusError( count ) )
return( FALSE );
/* Determine the result of the signature check */
if( !getSigCheckResult( cryptEnvelope ) || \
!destroyEnvelope( cryptEnvelope ) )
return( FALSE );
return( count );
}
static int envelopeSign( const void *data, const int dataLength,
const char *dumpFileName, const BOOLEAN useDatasize,
const BOOLEAN useRawKey, const BOOLEAN useAltRawKey,
const BOOLEAN useCustomHash,
const CRYPT_FORMAT_TYPE formatType )
{
CRYPT_ENVELOPE cryptEnvelope;
CRYPT_KEYSET cryptKeyset;
CRYPT_CONTEXT cryptContext;
int count, status;
if( !keyReadOK )
{
puts( "Couldn't find key files, skipping test of signed "
"enveloping..." );
return( TRUE );
}
printf( "Testing %ssigned enveloping%s",
( formatType == CRYPT_FORMAT_PGP ) ? "PGP " : "",
( useDatasize && ( formatType != CRYPT_FORMAT_PGP ) ) ? \
" with datasize hint" : "" );
if( useCustomHash )
printf( " %s custom hash",
( formatType == CRYPT_FORMAT_PGP ) ? "with" :"and" );
printf( " using %s", useAltRawKey ? "raw DSA key" : \
useRawKey ? "raw public key" : "X.509 cert" );
puts( "..." );
/* Get the private key */
if( useRawKey || useAltRawKey )
{
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
CRYPT_KEYSET_FILE, useAltRawKey ? \
OPENPGP_PRIVKEY_FILE : PGP_PRIVKEY_FILE,
CRYPT_KEYOPT_READONLY );
if( cryptStatusOK( status ) )
{
status = cryptGetPrivateKey( cryptKeyset, &cryptContext,
CRYPT_KEYID_NAME, "test",
useAltRawKey ? "test1" : "test10" );
cryptKeysetClose( cryptKeyset );
}
}
else
status = getPrivateKey( &cryptContext, USER_PRIVKEY_FILE,
USER_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
puts( "Read of private key from key file failed, cannot test "
"enveloping." );
return( FALSE );
}
/* Create the envelope, push in the signing key, any extra informatin,
and the data to sign, pop the enveloped result, and destroy the
envelope */
if( !createEnvelope( &cryptEnvelope, formatType ) )
return( FALSE );
if( useCustomHash )
{
CRYPT_CONTEXT hashContext;
/* Add the (nonstandard) hash algorithm information. We need to do
this before we add the signing key since it's automatically
associated with the last hash algorithm added */
cryptCreateContext( &hashContext, CRYPT_UNUSED, CRYPT_ALGO_MD5 );
status = addEnvInfoNumeric( cryptEnvelope, CRYPT_ENVINFO_HASH,
hashContext );
cryptDestroyContext( hashContext );
if( !status )
return( FALSE );
}
if( !addEnvInfoNumeric( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE,
cryptContext ) )
return( FALSE );
if( useDatasize && !useRawKey && !useCustomHash && \
( formatType != CRYPT_FORMAT_PGP ) )
{
CRYPT_CONTEXT hashContext;
/* Make sure that adding a (pseudo-duplicate) hash action which
duplicates the one already added implicitly by the addition of
the signature key succeeds (internally, nothing is really done
since the hash action is already present) */
cryptCreateContext( &hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA );
status = addEnvInfoNumeric( cryptEnvelope, CRYPT_ENVINFO_HASH,
hashContext );
cryptDestroyContext( hashContext );
if( !status )
return( FALSE );
}
if( cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE,
cryptContext ) != CRYPT_ERROR_INITED )
{
puts( "Addition of duplicate key to envelope wasn't detected." );
return( FALSE );
}
cryptDestroyContext( cryptContext );
if( useDatasize )
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE,
dataLength );
count = pushData( cryptEnvelope, data, dataLength, NULL, 0 );
if( cryptStatusError( count ) )
return( FALSE );
count = popData( cryptEnvelope, buffer, 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, buffer, count );
/* De-envelope the data and make sure the result matches what we
pushed */
count = envelopeSigCheck( buffer, count, CRYPT_UNUSED,
useRawKey, useAltRawKey, FALSE );
if( !count )
return( FALSE );
if( count != dataLength || memcmp( buffer, data, dataLength ) )
{
puts( "De-enveloped data != original data." );
return( FALSE );
}
/* Clean up */
puts( "Enveloping of signed data succeeded.\n" );
return( TRUE );
}
int testEnvelopeSign( void )
{
if( cryptQueryCapability( CRYPT_ALGO_IDEA, NULL ) == CRYPT_ERROR_NOTAVAIL )
puts( "Skipping raw public-key based signing, which requires the "
"IDEA cipher to\nbe enabled.\n" );
else
{
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_sign", FALSE, TRUE, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Indefinite length, raw key */
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_sig", TRUE, TRUE, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Datasize, raw key */
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_sig.pgp", TRUE, TRUE, FALSE, FALSE, CRYPT_FORMAT_PGP ) )
return( FALSE ); /* PGP format, raw key */
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_sigd.pgp", TRUE, TRUE, TRUE, FALSE, CRYPT_FORMAT_PGP ) )
return( FALSE ); /* PGP format, raw DSA key */
}
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_csgn", FALSE, FALSE, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Indefinite length, certificate */
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_csg", TRUE, FALSE, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Datasize, certificate */
if( !envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_csg.pgp", TRUE, FALSE, FALSE, FALSE, CRYPT_FORMAT_PGP ) )
return( FALSE ); /* PGP format, certificate */
return( envelopeSign( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE, "env_hsg", TRUE, FALSE, FALSE, TRUE, CRYPT_FORMAT_CRYPTLIB ) );
} /* Datasize, cert, externally-suppl.hash */
/* Test authenticated (MACd) enveloping */
static int envelopeAuthent( const void *data, const int dataLength,
const BOOLEAN useDatasize )
{
CRYPT_ENVELOPE cryptEnvelope;
int count;
printf( "Testing authenticated enveloping" );
if( useDatasize )
printf( " with datasize hint" );
puts( "..." );
/* Create the envelope and push in the password after telling the
enveloping code we want to MAC rather than encrypt */
if( !createEnvelope( &cryptEnvelope, CRYPT_FORMAT_CRYPTLIB ) || \
!addEnvInfoNumeric( cryptEnvelope, CRYPT_ENVINFO_MAC,
TRUE ) || \
!addEnvInfoString( cryptEnvelope, CRYPT_ENVINFO_PASSWORD, "Password", 8 ) )
return( FALSE );
/* Push in the data, pop the enveloped result, and destroy the
envelope */
if( useDatasize )
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_DATASIZE,
dataLength );
count = pushData( cryptEnvelope, data, dataLength, NULL, 0 );
if( cryptStatusError( count ) )
return( FALSE );
count = popData( cryptEnvelope, buffer, 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( useDatasize ? "env_mac" : "env_macn", buffer, count );
/* Create the envelope */
if( !createDeenvelope( &cryptEnvelope ) )
return( FALSE );
/* Push in the data */
count = pushData( cryptEnvelope, buffer, count, NULL, 0 );
if( cryptStatusError( count ) )
return( FALSE );
count = popData( cryptEnvelope, buffer, BUFFER_SIZE );
if( cryptStatusError( count ) )
return( FALSE );
/* Determine the result of the MAC check */
if( !getSigCheckResult( cryptEnvelope ) || \
!destroyEnvelope( cryptEnvelope ) )
return( FALSE );
/* Make sure the result matches what we pushed */
if( count != dataLength || memcmp( buffer, data, dataLength ) )
{
puts( "De-enveloped data != original data." );
return( FALSE );
}
/* Clean up */
puts( "Enveloping of authenticated data succeeded.\n" );
return( TRUE );
}
int testEnvelopeAuthenticate( void )
{
/* As of late 2001 there are no known implementations of this CMS
mechanism, any attempt to use it will trigger an assertion in the
enveloping code intended to catch things like this so we don't try
and exercise it */
return( TRUE );
if( !envelopeAuthent( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE,
FALSE ) )
return( FALSE );
return( envelopeAuthent( ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE,
TRUE ) );
}
/****************************************************************************
* *
* CMS Enveloping Test Routines *
* *
****************************************************************************/
/* Test CMS signature generation/checking */
static int displaySigResult( const CRYPT_ENVELOPE cryptEnvelope )
{
CRYPT_CERTIFICATE signerInfo;
BOOLEAN sigStatus = FALSE;
int status;
/* Determine the result of the signature check */
sigStatus = getSigCheckResult( cryptEnvelope );
/* Report on the signer and signature info. We continue even if the sig.
status is bad since we can still try and display signing info even if
the check fails */
status = cryptGetAttribute( cryptEnvelope, CRYPT_ENVINFO_SIGNATURE,
&signerInfo );
if( cryptStatusError( status ) && sigStatus )
{
printf( "Cannot retrieve signer information from CMS signature, "
"status = %d.\n", status );
return( FALSE );
}
if( cryptStatusOK( status ) )
{
puts( "Signer information is:" );
if( !printCertInfo( signerInfo ) )
return( FALSE );
cryptDestroyCert( signerInfo );
}
status = cryptGetAttribute( cryptEnvelope,
CRYPT_ENVINFO_SIGNATURE_EXTRADATA, &signerInfo );
if( cryptStatusError( status ) && sigStatus && \
status != CRYPT_ERROR_NOTFOUND )
{
printf( "Cannot retrieve signature information from CMS signature, "
"status = %d.\n", status );
return( FALSE );
}
if( cryptStatusOK( status ) )
{
puts( "Signature information is:" );
if( !printCertInfo( signerInfo ) )
return( FALSE );
cryptDestroyCert( signerInfo );
}
return( sigStatus );
}
static int cmsEnvelopeSigCheck( const void *signedData,
const int signedDataLength,
const CRYPT_CONTEXT hashContext,
const BOOLEAN detachedSig,
const BOOLEAN checkData )
{
CRYPT_ENVELOPE cryptEnvelope;
int count, status;
/* Create the envelope and push in the data. Since this is a CMS
signature which carries its certs with it, there's no need to push in
a sig.check keyset. If it has a detached sig, we need to push two
lots of data, first the signature to set the envelope state, then the
data, however if the hash is being supplied externally we just set the
hash attribute. In addition if it's a detached sig, there's nothing
to be unwrapped so we don't pop any data */
if( !createDeenvelope( &cryptEnvelope ) )
return( FALSE );
if( detachedSig && hashContext != CRYPT_UNUSED )
{
/* The hash value is being supplied externally, add it to the
envelope before we add the signature data */
status = cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_HASH,
hashContext );
if( cryptStatusError( status ) )
{
printf( "Couldn't add externally-generated hash value to "
"envelope, status %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
}
count = pushData( cryptEnvelope, signedData, signedDataLength, NULL, 0 );
if( !cryptStatusError( count ) )
if( detachedSig )
{
if( hashContext == CRYPT_UNUSED )
count = pushData( cryptEnvelope, ENVELOPE_TESTDATA,
ENVELOPE_TESTDATA_SIZE, NULL, 0 );
}
else
count = popData( cryptEnvelope, buffer, BUFFER_SIZE );
if( cryptStatusError( count ) )
return( FALSE );
/* Display the details of the envelope signature and check whether
there's more information (typically a second signature) present */
status = displaySigResult( cryptEnvelope );
if( status == TRUE && cryptStatusOK( \
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_CURRENT_COMPONENT,
CRYPT_CURSOR_NEXT ) ) )
{
puts( "Data has a second signature:" );
status = displaySigResult( cryptEnvelope );
}
if( status == TRUE && cryptStatusOK( \
cryptSetAttribute( cryptEnvelope, CRYPT_ENVINFO_CURRENT_COMPONENT,
CRYPT_CURSOR_NEXT ) ) )
{
/* We can have two, but not three */
puts( "Data appears to have (non-existant) multiple signatures." );
return( FALSE );
}
/* Make sure the result matches what we pushed */
if( !detachedSig && checkData && ( count != ENVELOPE_TESTDATA_SIZE || \
memcmp( buffer, ENVELOPE_TESTDATA, ENVELOPE_TESTDATA_SIZE ) ) )
{
puts( "De-enveloped data != original data." );
return( FALSE );
}
/* Clean up */
if( !destroyEnvelope( cryptEnvelope ) )
return( FALSE );
return( status );
}
static int cmsEnvelopeSign( const BOOLEAN useDatasize,
const BOOLEAN useAttributes, const BOOLEAN useExtAttributes,
const BOOLEAN detachedSig, const BOOLEAN useExternalHash,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -