📄 highlvl.c
字号:
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 );
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 the code to exchange a session key via Diffie-Hellman. We're not as
picky with error-checking here since most of the functions have just
executed successfully */
int testKeyAgreement( void )
{
CRYPT_OBJECT_INFO cryptObjectInfo;
CRYPT_CONTEXT cryptContext1, cryptContext2;
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
BYTE *buffer;
int length, status;
puts( "Testing key agreement..." );
/* Create the DH encryption contexts, one with a key loaded and the
other as a blank template for the import from the first one */
if( !loadDHContexts( &cryptContext1, NULL, PKC_KEYSIZE ) )
return( FALSE );
cryptCreateContext( &cryptContext2, CRYPT_UNUSED, CRYPT_ALGO_DH );
/* Create the session key templates */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED,
selectCipher( CRYPT_ALGO_RC5 ) );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED,
selectCipher( CRYPT_ALGO_RC5 ) );
/* Find out how big the exported key will be */
status = cryptExportKey( NULL, 0, &length, cryptContext1,
sessionKeyContext1 );
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", length );
if( ( buffer = malloc( length ) ) == NULL )
return( FALSE );
/* Perform phase 1 of the exchange */
status = cryptExportKey( buffer, length, &length, cryptContext1,
sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() #1 failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
status = cryptImportKey( buffer, length, cryptContext2,
sessionKeyContext2 );
if( cryptStatusError( status ) )
{
printf( "cryptImportKey() #1 failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
/* Query the encrypted key object */
status = cryptQueryObject( buffer, length, &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( "keyagree", buffer, length );
/* Perform phase 2 of the exchange */
status = cryptExportKey( buffer, length, &length, cryptContext2,
sessionKeyContext2 );
if( cryptStatusError( status ) )
{
printf( "cryptExportKey() #2 failed with error code %d, line %d.\n",
status, __LINE__ );
free( buffer );
return( FALSE );
}
status = cryptImportKey( buffer, length, cryptContext1,
sessionKeyContext1 );
if( cryptStatusError( status ) )
{
printf( "cryptImportKey() #2 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 );
destroyContexts( CRYPT_UNUSED, cryptContext1, cryptContext2 );
printf( "Exchange of session key via %d-bit Diffie-Hellman succeeded.\n\n",
PKC_KEYSIZE );
free( buffer );
return( TRUE );
}
/* 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 */
cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL,
TEXT( "Private key" ),
paramStrlen( TEXT( "Private key" ) ) );
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYSIZE, 64 );
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 */
cryptCreateContext( &hashContext, CRYPT_UNUSED, CRYPT_ALGO_SHA );
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 */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED,
CRYPT_ALGO_DES );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED,
CRYPT_ALGO_DES );
cryptGenerateKey( sessionKeyContext1 );
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 the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, sessionKeyContext1,
sessionKeyContext2 );
}
else
if( cryptAlgo == CRYPT_ALGO_DH )
{
CRYPT_CONTEXT dhContext;
CRYPT_CONTEXT sessionKeyContext1, sessionKeyContext2;
KLUDGE_WARN( "DH test because of absence of DH key exchange mechanism" );
cryptDestroyContext( cryptContext );
return( TRUE );
/* Test the key exchange */
cryptCreateContext( &sessionKeyContext1, CRYPT_UNUSED,
CRYPT_ALGO_DES );
cryptCreateContext( &sessionKeyContext2, CRYPT_UNUSED,
CRYPT_ALGO_DES );
cryptCreateContext( &dhContext, CRYPT_UNUSED, CRYPT_ALGO_DH );
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 the two keys match */
if( !compareSessionKeys( sessionKeyContext1, sessionKeyContext2 ) )
return( FALSE );
/* Clean up */
destroyContexts( CRYPT_UNUSED, sessionKeyContext1,
sessionKeyContext2 );
}
else
{
printf( "Unexpected encryption algorithm %d found.\n", cryptAlgo );
return( FALSE );
}
printf( "%s key generation succeeded.\n", algoName );
return( TRUE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -