📄 testhl.c
字号:
{
printf( "Unexpected encryption algorithm %d found.\n", cryptAlgo );
return( FALSE );
}
printf( "%s key generation succeeded.\n", algoName );
return( TRUE );
}
int testKeygen( void )
{
if( !keygen( CRYPT_ALGO_RSA, "RSA" ) )
return( FALSE );
if( !keygen( CRYPT_ALGO_DSA, "DSA" ) )
return( FALSE );
if( !keygen( CRYPT_ALGO_ELGAMAL, "Elgamal" ) )
return( FALSE );
if( !keygen( CRYPT_ALGO_DH, "DH" ) )
return( FALSE );
putchar( '\n' );
return( TRUE );
}
int testKeygenAsync( void )
{
#if !defined( UNIX_THREADS ) && !defined( WINDOWS_THREADS ) && \
!defined( OS2_THREADS )
return( TRUE );
#else
CRYPT_CONTEXT cryptContext;
int status;
puts( "Testing asynchronous key generation..." );
/* Create an encryption context and generate a longish (2K bit) key
into it (this ensures that we can see the async operation in
action, anything smaller and it's done almost immediately) */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, CRYPT_ALGO_RSA );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL,
"Private key", 11 );
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYSIZE, 256 );
status = cryptGenerateKeyAsync( cryptContext );
if( cryptStatusError( status ) )
{
printf( "cryptGenerateKeyAsync() failed with error code %d, line "
"%d.\n", status );
return( FALSE );
}
/* Hang around a bit to allow things to start. This value is a bit of a
difficult quantity to get right since VC++ can spend longer than the
startup time thrashing the drive doing nothing so it has to be high,
but on faster PC's even a 2K bit key can be generated in a few
seconds, so it can't be too high or the keygen will have finished.
The following value is safe for a 400MHz PII, presumably the next step
will be to move to 3K bit keys (3072 bits, 384 in the above keygen
call) but this may cause problems with some external implementations
which cap the keysize at 2K bits. For the Unix version it's also
going to cause problems on the faster systems */
printf( "Delaying 2s to allow keygen to start..." );
delayThread( 2 );
puts( "done." );
/* Check that the async keygen is still in progress */
status = cryptAsyncQuery( cryptContext );
if( status == CRYPT_ERROR_BUSY )
puts( "Async keygen in progress." );
else
{
/* If the machine's really fast, the keygen could have completed
already */
if( status == CRYPT_OK )
{
printf( "The async keygen has completed before the rest of the "
"test code could run.\nTo fix this, either decrease "
"the startup delay on line %d\nof " __FILE__ " or "
"increase the size of the key being generated to slow\n"
"down the generation process.\n\n", __LINE__ - 15 );
cryptDestroyContext( cryptContext );
return( TRUE );
}
printf( "Async keygen failed with error code %d, line %d.\n", status,
__LINE__ );
return( FALSE );
}
/* Cancel the async keygen */
status = cryptAsyncCancel( cryptContext );
if( cryptStatusError( status ) )
{
printf( "cryptAsyncCancel() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "Cancelling async operation..." );
while( cryptAsyncQuery( cryptContext ) == CRYPT_ERROR_BUSY )
delayThread( 1 );
puts( "done." );
/* Clean up */
cryptDestroyContext( cryptContext );
puts( "Asynchronous key generation succeeded.\n" );
return( TRUE );
#endif /* Systems with threading support */
}
#endif /* TEST_MIDLEVEL */
/****************************************************************************
* *
* High-level Routines Test *
* *
****************************************************************************/
#ifdef TEST_HIGHLEVEL
/* Test the code to export/import a CMS key */
int testKeyExportImportCMS( void )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_KEYSET cryptKeyset;
CRYPT_CONTEXT cryptContext;
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
BYTE *buffer;
int status, length;
puts( "Testing CMS public-key export/import..." );
/* Get a private key with a cert chain attached */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
USER_PRIVKEY_FILE, CRYPT_KEYOPT_READONLY );
if( cryptStatusOK( status ) )
{
status = cryptGetPrivateKey( cryptKeyset, &cryptContext,
CRYPT_KEYID_NAME, USER_PRIVKEY_LABEL,
TEST_PRIVKEY_PASSWORD );
cryptKeysetClose( cryptKeyset );
}
if( cryptStatusError( status ) )
{
printf( "Couldn't read private key, status %d, line %d.\n", status,
__LINE__ );
return( FALSE );
}
/* Create triple-DES encryption contexts for the exported and imported
session keys */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED, CRYPT_ALGO_3DES );
cryptSetAttribute( sessionKeyContext1, CRYPT_CTXINFO_MODE, CRYPT_MODE_CBC );
cryptGenerateKey( sessionKeyContext1 );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED, CRYPT_ALGO_3DES );
cryptSetAttribute( sessionKeyContext2, CRYPT_CTXINFO_MODE, CRYPT_MODE_CBC );
/* Find out how big the exported key will be */
status = cryptExportKeyEx( NULL, &length, CRYPT_FORMAT_SMIME,
cryptContext, sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKeyEx() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "cryptExportKeyEx() reports CMS exported key will be %d bytes "
"long\n", length );
if( ( buffer = malloc( length ) ) == NULL )
return( FALSE );
/* Export the key */
status = cryptExportKeyEx( buffer, &length, CRYPT_FORMAT_SMIME,
cryptContext, sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKeyEx() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Query the encrypted key object */
status = cryptQueryObject( buffer, &cryptObjectInfo );
if( cryptStatusError( status ) )
{
printf( "cryptQueryObject() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
printf( "cryptQueryObject() reports object type %d, algorithm %d, mode "
"%d.\n", cryptObjectInfo.objectType, cryptObjectInfo.cryptAlgo,
cryptObjectInfo.cryptMode );
memset( &cryptObjectInfo, 0, sizeof( CRYPT_OBJECT_INFO ) );
debugDump( "cms_ri", buffer, length );
/* Import the encrypted key and load it into the session key context */
status = cryptImportKeyEx( buffer, cryptContext, sessionKeyContext2 );
if( cryptStatusError( status ) )
{
printf( "cryptImportKeyEx() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Make sure the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, sessionKeyContext1, sessionKeyContext2 );
cryptDestroyContext( cryptContext );
puts( "Export/import of CMS session key succeeded.\n" );
free( buffer );
return( TRUE );
}
/* Test the code to create an CMS signature */
static const CERT_DATA cmsAttributeData[] = {
/* Content type */
{ CRYPT_CERTINFO_CMS_CONTENTTYPE, IS_NUMERIC, CRYPT_CONTENT_SPCINDIRECTDATACONTEXT },
/* Odds and ends */
{ CRYPT_CERTINFO_CMS_SPCOPUSINFO, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_CERTINFO_CMS_SPCSTMT_COMMERCIALCODESIGNING, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
};
static int signDataCMS( const char *description,
const CRYPT_CERTIFICATE signingAttributes )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CERTIFICATE cmsAttributes = signingAttributes;
CRYPT_CONTEXT signContext, hashContext;
BYTE *buffer, hashBuffer[] = "abcdefghijklmnopqrstuvwxyz";
int status, length;
printf( "Testing %s...\n", description );
/* Create an SHA hash context and hash the test buffer */
cryptCreateContext( &hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA );
cryptEncrypt( hashContext, hashBuffer, 26 );
cryptEncrypt( hashContext, hashBuffer, 0 );
/* Get a private key with a cert chain attached */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
USER_PRIVKEY_FILE, CRYPT_KEYOPT_READONLY );
if( cryptStatusOK( status ) )
{
status = cryptGetPrivateKey( cryptKeyset, &signContext,
CRYPT_KEYID_NAME, USER_PRIVKEY_LABEL,
TEST_PRIVKEY_PASSWORD );
cryptKeysetClose( cryptKeyset );
}
if( cryptStatusError( status ) )
{
printf( "Couldn't read private key, status %d, line %d.\n", status,
__LINE__ );
return( FALSE );
}
/* Find out how big the signature will be */
status = cryptCreateSignatureEx( NULL, &length, CRYPT_FORMAT_SMIME,
signContext, hashContext, cmsAttributes );
if( cryptStatusError( status ) )
{
printf( "cryptCreateSignatureEx() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
printf( "cryptCreateSignatureEx() reports CMS signature will be %d "
"bytes long\n", length );
if( ( buffer = malloc( length ) ) == NULL )
return( FALSE );
/* Sign the hashed data */
status = cryptCreateSignatureEx( buffer, &length, CRYPT_FORMAT_SMIME,
signContext, hashContext, cmsAttributes );
if( cryptStatusError( status ) )
{
printf( "cryptCreateSignatureEx() failed with error code %d, line "
"%d.\n", status, __LINE__ );
free( buffer );
return( FALSE );
}
debugDump( ( signingAttributes == CRYPT_USE_DEFAULT ) ? \
"cms_sigd" : "cms_sig", buffer, length );
/* Check the signature on the hash */
status = cryptCheckSignatureEx( buffer, signContext, hashContext,
( cmsAttributes == CRYPT_USE_DEFAULT ) ? NULL : &cmsAttributes );
if( cryptStatusError( status ) )
{
printf( "cryptCheckSignatureEx() failed with error code %d, line "
"%d.\n", status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Display the signing attributes */
if( cmsAttributes != CRYPT_USE_DEFAULT )
printCertInfo( cmsAttributes );
/* Clean up */
cryptDestroyContext( hashContext );
cryptDestroyContext( signContext );
cryptDestroyCert( cmsAttributes );
printf( "Generation and checking of %s succeeded.\n\n", description );
free( buffer );
return( TRUE );
}
int testSignDataCMS( void )
{
CRYPT_CERTIFICATE cmsAttributes;
int status;
/* First test the basic CMS signature with default attributes (content
type, signing time, and message digest) */
if( !signDataCMS( "CMS signature", CRYPT_USE_DEFAULT ) )
return( FALSE );
/* Create some CMS attributes and sign the data with the user-defined
attributes */
status = cryptCreateCert( &cmsAttributes, CRYPT_UNUSED,
CRYPT_CERTTYPE_CMS_ATTRIBUTES );
if( cryptStatusError( status ) || \
!addCertFields( cmsAttributes, cmsAttributeData ) )
return( FALSE );
status = signDataCMS( "complex CMS signature", cmsAttributes );
cryptDestroyCert( cmsAttributes );
return( status );
}
#endif /* TEST_HIGHLEVEL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -