📄 testdev.c
字号:
/* Generate a key in the device */
printf( "Generating a %s key in the device...", description );
status = cryptDeviceCreateContext( cryptDevice, &cryptContext,
cryptAlgo );
if( cryptStatusError( status ) )
{
printf( "\ncryptDeviceCreateContext() failed with error code %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_LABEL, labelBuffer,
strlen( labelBuffer ) );
status = cryptGenerateKey( cryptContext );
if( cryptStatusError( status ) )
{
cryptDestroyContext( cryptContext );
printf( "\ncryptGenerateKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( " succeeded." );
/* Create a certificate for the key */
printf( "Generating a certificate for the key..." );
cryptCreateCert( &cryptCert, CRYPT_UNUSED, ( isCA ) ? \
CRYPT_CERTTYPE_CERTIFICATE : CRYPT_CERTTYPE_CERTCHAIN );
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptContext );
if( cryptStatusOK( status ) && \
!addCertFields( cryptCert, certData ) )
return( FALSE );
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptCert, isCA ? cryptContext : signingKey );
cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
{
cryptDestroyCert( cryptCert );
printf( "\nCreation of certificate failed with error code %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
puts( " succeeded." );
/* Dump the resulting cert for debugging */
if( dumpName != NULL )
{
status = cryptExportCert( certBuffer, &certificateLength, isCA ? \
CRYPT_CERTFORMAT_CERTIFICATE : CRYPT_CERTFORMAT_CERTCHAIN,
cryptCert );
if( cryptStatusOK( status ) )
debugDump( dumpName, certBuffer, certificateLength );
}
/* Update the key with the cert */
printf( "Updating device with certificate..." );
status = cryptAddPublicKey( cryptDevice, cryptCert );
cryptDestroyCert( cryptCert );
if( cryptStatusError( status ) )
{
printf( "\ncryptAddPublicKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( " succeeded." );
return( TRUE );
}
/* Test the high-level functionality provided by a device */
static BOOLEAN testDeviceHighlevel( const CRYPT_DEVICE cryptDevice,
const CRYPT_DEVICE_TYPE deviceType,
const char *keyLabel,
const char *password,
const BOOLEAN isWriteProtected )
{
CRYPT_CONTEXT pubKeyContext, privKeyContext, sigKeyContext;
int status;
if( !isWriteProtected )
{
const CRYPT_ALGO cryptAlgo = ( deviceType == CRYPT_DEVICE_PKCS11 ) ? \
CRYPT_ALGO_RSA : CRYPT_ALGO_DSA;
/* Create a CA key in the device */
if( !createKey( cryptDevice, cryptAlgo, "CA",
( deviceType == CRYPT_DEVICE_PKCS11 ) ? \
"dp_cacert" : "df_cacert", CRYPT_UNUSED ) )
return( FALSE );
/* Read back the CA key for use in generating end entity certs */
status = cryptGetPrivateKey( cryptDevice, &sigKeyContext,
CRYPT_KEYID_NAME, "Test CA key",
NULL );
if( cryptStatusError( status ) )
{
printf( "\nRead of CA key failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Create end-entity certificate(s) for keys using the previously-
generated CA key. If it's a Fortezza card we have to generate two
sets of keys/certs, one for signing and one for encryption */
status = createKey( cryptDevice, cryptAlgo, "user",
( deviceType == CRYPT_DEVICE_PKCS11 ) ? \
"dp_usrcert" : "df_usrcert", sigKeyContext );
if( status && deviceType == CRYPT_DEVICE_FORTEZZA )
status = createKey( cryptDevice, CRYPT_ALGO_KEA, "KEA",
"df_keacert", sigKeyContext );
cryptDestroyContext( sigKeyContext );
if( !status )
return( FALSE );
}
/* See whether there are any existing keys or certs - some tokens have
these built in and don't allow anything new to be created, after this
point the handling is somewhat special-case but we can at least report
their presence. Although generally we can reuse a private key context
for both public and private operations, some devices or drivers (and
by extension the cryptlib kernel) don't allow public-key ops with
private keys so we have to eplicitly handle public and private keys.
This gets somewhat messy because some devices don't have public keys
but allow public-key ops with their private keys, while others
separate public and private keys and don't allow the private key to do
public-key ops */
status = cryptGetPublicKey( cryptDevice, &pubKeyContext,
CRYPT_KEYID_NAME, keyLabel );
if( cryptStatusOK( status ) )
{
puts( "Found a public key in the device, details follow..." );
printCertChainInfo( pubKeyContext );
}
else
{
puts( "Error: Couldn't locate public key in device." );
pubKeyContext = CRYPT_UNUSED;
}
status = cryptGetPrivateKey( cryptDevice, &privKeyContext,
CRYPT_KEYID_NAME, keyLabel, NULL );
if( cryptStatusOK( status ) )
{
puts( "Found a private key in the device, details follow..." );
printCertChainInfo( privKeyContext );
if( pubKeyContext == CRYPT_UNUSED )
{
/* No explicit public key found, try using the private key for
both key types */
puts( "No public key found, attempting to continue using the "
"private key as both a\npublic and a private key." );
pubKeyContext = privKeyContext;
}
}
else
{
puts( "Error: Couldn't locate private key in device." );
privKeyContext = CRYPT_UNUSED;
}
sigKeyContext = privKeyContext;
if( deviceType == CRYPT_DEVICE_FORTEZZA )
{
cryptDestroyContext( pubKeyContext ); /* pubK is sig.only */
status = cryptGetPrivateKey( cryptDevice, &privKeyContext,
CRYPT_KEYID_NAME, "Test KEA key", NULL );
if( cryptStatusOK( status ) )
{
puts( "Found a key agreement key in the device, details follow..." );
printCertChainInfo( privKeyContext );
pubKeyContext = privKeyContext; /* Fortezza allows both uses */
}
else
{
pubKeyContext = CRYPT_UNUSED;
privKeyContext = CRYPT_UNUSED;
}
}
/* If we got something, try some simple operations with it */
if( pubKeyContext != CRYPT_UNUSED )
{
if( !testCMSEnvelopePKCCryptEx( pubKeyContext, cryptDevice, password ) )
return( FALSE );
}
else
puts( "Public-key enveloping tests skipped because no key was "
"available." );
if( sigKeyContext != CRYPT_UNUSED )
{
if( !testCMSEnvelopeSignEx( sigKeyContext ) )
return( FALSE );
}
else
puts( "Signed enveloping tests skipped because no key was "
"available." );
/* Test the key with a server session, meant to imitate use with an HSM.
This is disabled by default since it requires the simultaneous use of
both a client and server session, which has to be done manually */
#if 0
testSessionTSPServerEx( sigKeyContext );
#endif /* 0 */
/* Clean up */
if( pubKeyContext == CRYPT_UNUSED && sigKeyContext == CRYPT_UNUSED )
return( FALSE );
if( privKeyContext != CRYPT_UNUSED )
{
cryptDestroyContext( privKeyContext );
if( privKeyContext != sigKeyContext )
cryptDestroyContext( sigKeyContext );
}
if( pubKeyContext != CRYPT_UNUSED && pubKeyContext != privKeyContext )
cryptDestroyContext( pubKeyContext );
return( TRUE );
}
/* Test cryptlib's CAW functionality with a Fortezza card. Note that these
operations have to be done in a more or less continuous sequence (ie
without an intervening device open call) because it's not possible to
escape from some of the states if the card is closed and reopened in
between */
static int testCAW( void )
{
CRYPT_DEVICE cryptDevice;
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT signContext;
int status;
puts( "Testing Certificate Authority Workstation (CAW) functionality..." );
status = cryptDeviceOpen( &cryptDevice, CRYPT_UNUSED,
CRYPT_DEVICE_FORTEZZA, NULL );
if( status == CRYPT_ERROR_PARAM2 )
{
puts( "Support for Fortezza cards isn't enabled in this build of "
"cryptlib." );
return( CRYPT_ERROR_NOTAVAIL ); /* Device access not available */
}
if( cryptStatusError( status ) )
{
if( status == CRYPT_ERROR_PARAM3 )
puts( "Fortezza card not detected, skipping test." );
else
printf( "cryptDeviceOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Zeroise the card prior to initialising it */
printf( "Zeroising device... " );
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_ZEROISE, FORTEZZA_ZEROISE_PIN,
strlen( FORTEZZA_ZEROISE_PIN ) );
if( cryptStatusError( status ) )
{
printf( "\nZeroise failed with error code %d, line %d.\n", status,
__LINE__ );
return( FALSE );
}
puts( "succeeded." );
/* Initialise the card */
printf( "Initialising device... " );
status = cryptSetAttributeString( cryptDevice,
CRYPT_DEVINFO_INITIALISE, FORTEZZA_SSO_DEFAULT_PIN,
strlen( FORTEZZA_SSO_DEFAULT_PIN ) );
if( cryptStatusError( status ) )
{
printf( "\nInitialisation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( "succeeded." );
/* Set the SSO PIN */
printf( "Setting SSO PIN... " );
status = cryptDeviceControlEx( cryptDevice,
CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR,
FORTEZZA_SSO_DEFAULT_PIN, strlen( FORTEZZA_SSO_DEFAULT_PIN ),
FORTEZZA_SSO_PIN, strlen( FORTEZZA_SSO_PIN ) );
if( cryptStatusError( status ) )
{
printf( "\ncryptDeviceControlEx() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( "set to " FORTEZZA_SSO_PIN "." );
/* Create a CA root key and install its cert. We can't use the card to
do this because cert slot 0 is a data-only slot (that is, it can't
correspond to a key held on the card), so we create a dummy external
cert and use that */
printf( "Loading PAA certificate... " );
if( !loadDSAContexts( CRYPT_UNUSED, &signContext, NULL ) )
return( FALSE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -