📄 highlvl.c
字号:
sessionKeyContext2 ) )
return( FALSE );
cryptDestroyContext( cryptContext );
destroyContexts( CRYPT_UNUSED, sessionKeyContext1, sessionKeyContext2 );
puts( "Export/import of AES key via user-key-based AES conventional "
"encryption\n succeeded.\n" );
return( TRUE );
}
int testMACExportImport( void )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_CONTEXT cryptContext, decryptContext;
CRYPT_CONTEXT macContext1, macContext2;
BYTE mac1[ CRYPT_MAX_HASHSIZE ], mac2[ CRYPT_MAX_HASHSIZE ];
C_STR userKey = TEXT( "This is a long user key for MAC testing" );
BYTE *buffer;
int userKeyLength = paramStrlen( userKey );
int status, length1, length2;
puts( "Testing MAC key export/import..." );
/* Create HMAC-SHA1 contexts for the MAC key */
status = cryptCreateContext( &macContext1, CRYPT_UNUSED,
CRYPT_ALGO_HMAC_SHA1 );
if( cryptStatusOK( status ) )
status = cryptGenerateKey( macContext1 );
if( cryptStatusOK( status ) )
status = cryptCreateContext( &macContext2, CRYPT_UNUSED,
CRYPT_ALGO_HMAC_SHA1 );
if( cryptStatusError( status ) )
return( FALSE );
/* Create a 3DES encryption context to export the MAC key */
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED,
CRYPT_ALGO_3DES );
if( cryptStatusError( status ) )
return( FALSE );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEYING_SALT,
"\x12\x34\x56\x78\x78\x56\x34\x12", 8 );
status = cryptSetAttributeString( cryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
/* Find out how big the exported key will be */
status = cryptExportKey( NULL, 0, &length1, cryptContext, macContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "cryptExportKey() reports exported key object will be %d bytes "
"long\n", length1 );
if( ( buffer = malloc( length1 ) ) == NULL )
return( FALSE );
/* Export the MAC information */
status = cryptExportKey( buffer, length1, &length1, cryptContext,
macContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Query the encrypted key object */
status = cryptQueryObject( buffer, length1, &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 );
debugDump( "kek_mac", buffer, length1 );
/* Recreate the MAC key by importing the encrypted key */
status = cryptCreateContext( &decryptContext, CRYPT_UNUSED,
cryptObjectInfo.cryptAlgo );
if( cryptStatusError( status ) )
{
printf( "cryptCreateContext() failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE,
cryptObjectInfo.cryptMode );
cryptSetAttributeString( decryptContext, CRYPT_CTXINFO_KEYING_SALT,
cryptObjectInfo.salt, cryptObjectInfo.saltSize );
status = cryptSetAttributeString( decryptContext,
CRYPT_CTXINFO_KEYING_VALUE,
userKey, userKeyLength );
if( cryptStatusOK( status ) )
status = cryptImportKey( buffer, length1, decryptContext,
macContext2 );
free( buffer );
if( cryptStatusError( status ) )
{
printf( "cryptImportKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Make sure that the two MAC keys match */
cryptEncrypt( macContext1, "1234", 4 );
status = cryptEncrypt( macContext1, "", 0 );
if( cryptStatusOK( status ) )
{
cryptEncrypt( macContext2, "1234", 4 );
status = cryptEncrypt( macContext2, "", 0 );
}
if( cryptStatusOK( status ) )
status = cryptGetAttributeString( macContext1,
CRYPT_CTXINFO_HASHVALUE,
mac1, &length1 );
if( cryptStatusOK( status ) )
status = cryptGetAttributeString( macContext2,
CRYPT_CTXINFO_HASHVALUE,
mac2, &length2 );
if( cryptStatusError( status ) )
{
printf( "MAC operation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
if( ( length1 != length2 ) || memcmp( mac1, mac2, length1 ) || \
!memcmp( mac1, "\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) || \
!memcmp( mac2, "\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) )
{
puts( "Data MAC'd with key1 != data MAC'd with key2." );
return( FALSE );
}
/* Clean up */
destroyContexts( CRYPT_UNUSED, macContext1, macContext2 );
destroyContexts( CRYPT_UNUSED, cryptContext, decryptContext );
printf( "Export/import of MAC key via user-key-based triple DES "
"conventional\n encryption succeeded.\n\n" );
return( TRUE );
}
/* Test the code to export/import an encrypted key and sign data. We're not
as picky with error-checking here since most of the functions have just
executed successfully. We check every algorithm type since there are
different code paths for DLP and non-DLP PKCs */
int testKeyExportImport( void )
{
if( !keyExportImport( "RSA", CRYPT_ALGO_RSA, CRYPT_UNUSED, CRYPT_UNUSED, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* RSA */
if( !keyExportImport( "Elgamal", CRYPT_ALGO_ELGAMAL, CRYPT_UNUSED, CRYPT_UNUSED, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* Elgamal */
if( !keyExportImport( "RSA", CRYPT_ALGO_RSA, CRYPT_UNUSED, CRYPT_UNUSED, CRYPT_FORMAT_PGP ) )
return( FALSE ); /* RSA, PGP format */
return( keyExportImport( "Elgamal", CRYPT_ALGO_ELGAMAL, CRYPT_UNUSED, CRYPT_UNUSED, CRYPT_FORMAT_PGP ) );
} /* Elgamal, PGP format */
int testSignData( void )
{
if( !signData( "RSA", CRYPT_ALGO_RSA, CRYPT_UNUSED, CRYPT_UNUSED, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* RSA */
if( !signData( "RSA", CRYPT_ALGO_RSA, CRYPT_UNUSED, CRYPT_UNUSED, TRUE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* RSA, side-channel attack protection */
if( !signData( "RSA with SHA2", CRYPT_ALGO_RSA, CRYPT_UNUSED, CRYPT_UNUSED, FALSE, TRUE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* RSA with SHA2 */
if( !signData( "DSA", CRYPT_ALGO_DSA, CRYPT_UNUSED, CRYPT_UNUSED, FALSE, FALSE, CRYPT_FORMAT_CRYPTLIB ) )
return( FALSE ); /* DSA */
if( !signData( "RSA", CRYPT_ALGO_RSA, CRYPT_UNUSED, CRYPT_UNUSED, FALSE, FALSE, CRYPT_FORMAT_PGP ) )
return( FALSE ); /* RSA, PGP format */
return( signData( "DSA", CRYPT_ALGO_DSA, CRYPT_UNUSED, CRYPT_UNUSED, FALSE, FALSE, CRYPT_FORMAT_PGP ) );
} /* DSA, PGP format */
/* Test normal and asynchronous public-key generation */
static int keygen( const CRYPT_ALGO_TYPE cryptAlgo, const char *algoName )
{
CRYPT_CONTEXT cryptContext;
BYTE buffer[ BUFFER_SIZE ];
int length, status;
printf( "Testing %s key generation...\n", algoName );
/* Create an encryption context and generate a (short) key into it.
Generating a minimal-length 512 bit key is faster than the default
1-2K bit keys */
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
if( cryptStatusError( status ) )
return( FALSE );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL,
TEXT( "Private key" ),
paramStrlen( TEXT( "Private key" ) ) );
status = cryptGenerateKey( cryptContext );
if( cryptStatusError( status ) )
{
printf( "cryptGenerateKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Perform a test operation to check the new key */
if( cryptAlgo == CRYPT_ALGO_RSA || cryptAlgo == CRYPT_ALGO_DSA )
{
CRYPT_CONTEXT hashContext;
BYTE hashBuffer[] = "abcdefghijklmnopqrstuvwxyz";
/* Create an SHA hash context and hash the test buffer */
status = cryptCreateContext( &hashContext, CRYPT_UNUSED,
CRYPT_ALGO_SHA );
if( cryptStatusError( status ) )
return( FALSE );
cryptEncrypt( hashContext, hashBuffer, 26 );
cryptEncrypt( hashContext, hashBuffer, 0 );
/* Sign the hashed data and check the signature */
status = cryptCreateSignature( buffer, BUFFER_SIZE, &length,
cryptContext, hashContext );
if( cryptStatusOK( status ) )
status = cryptCheckSignature( buffer, length, cryptContext,
hashContext );
/* Clean up */
cryptDestroyContext( hashContext );
cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
{
printf( "Sign/signature check with generated key failed with "
"error code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
}
else
if( cryptAlgo == CRYPT_ALGO_ELGAMAL )
{
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
/* Test the key exchange */
status = cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED,
CRYPT_ALGO_DES );
if( cryptStatusOK( status ) )
status = cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED,
CRYPT_ALGO_DES );
if( cryptStatusOK( status ) )
status = cryptGenerateKey( sessionKeyContext1 );
if( cryptStatusError( status ) )
return( FALSE );
status = cryptExportKey( buffer, BUFFER_SIZE, &length, cryptContext,
sessionKeyContext1 );
if( cryptStatusOK( status ) )
status = cryptImportKey( buffer, length, cryptContext,
sessionKeyContext2 );
cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
{
destroyContexts( CRYPT_UNUSED, sessionKeyContext1,
sessionKeyContext2 );
printf( "Key exchange with generated key failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
/* Make sure that the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, sessionKeyContext1,
sessionKeyContext2 );
}
else
if( cryptAlgo == CRYPT_ALGO_DH )
{
KLUDGE_WARN( "DH test because of absence of DH key exchange mechanism" );
cryptDestroyContext( cryptContext );
return( TRUE );
#if 0 /* Get rid if unreachable-code warnings */
CRYPT_CONTEXT dhContext;
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
/* Test the key exchange */
status = cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED,
CRYPT_ALGO_DES );
if( cryptStatusOK( status ) )
status = cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED,
CRYPT_ALGO_DES );
if( cryptStatusOK( status ) )
status = cryptCreateContext( &dhContext, CRYPT_UNUSED,
CRYPT_ALGO_DH );
if( cryptStatusError( status ) )
return( FALSE );
status = cryptExportKey( buffer, BUFFER_SIZE, &length, cryptContext,
sessionKeyContext1 );
if( cryptStatusOK( status ) )
status = cryptImportKey( buffer, length, dhContext,
sessionKeyContext2 );
if( cryptStatusOK( status ) )
status = cryptExportKey( buffer, BUFFER_SIZE, &length, dhContext,
sessionKeyContext2 );
if( cryptStatusOK( status ) )
status = cryptImportKey( buffer, length, cryptContext,
sessionKeyContext1 );
cryptDestroyContext( cryptContext );
cryptDestroyContext( dhContext );
if( cryptStatusError( status ) )
{
destroyContexts( CRYPT_UNUSED, sessionKeyContext1,
sessionKeyContext2 );
printf( "Key exchange with generated key failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
/* Make sure that the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, sessionKeyContext1,
sessionKeyContext2 );
#endif /* 0 */
}
else
{
printf( "Unexpected encryption algorithm %d found, line %d.\n",
cryptAlgo, __LINE__ );
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 );
printf( "\n" );
return( TRUE );
}
int testKeygenAsync( void )
{
#if !defined( UNIX_THREADS ) && !defined( WINDOWS_THREADS ) && \
!defined( OS2_THREADS )
return( TRUE );
#else
CRYPT_CONTEXT cryptContext, hashContext;
BYTE hashBuffer[] = "abcdefghijklmnopqrstuvwxyz";
BYTE buffer[ BUFFER_SIZE ];
int cancelCount = 0, length, status;
puts( "Testing asynchronous key generation..." );
/* Create an encryption context and generate a longish (3K bit) key
into it. This ensures that we can see the async operation in
action, anything smaller and it's done almost immediately (note
that this may cause problems with some external implementations
that cap the keysize at 2K bits) */
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED,
CRYPT_ALGO_RSA );
if( cryptStatusError( status ) )
return( FALSE );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL,
TEXT( "Private key" ),
paramStrlen( TEXT( "Private key" ) ) );
status = cryptGenerateKeyAsync( cryptContext );
if( cryptStatusError( status ) )
{
printf( "cryptGenerateKeyAsync() failed with error code %d, line "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -