📄 testkey.c
字号:
return( FALSE );
}
status = cryptCreateCert( &cryptCertChain, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTCHAIN );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptCertChain,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptKey );
cryptDestroyContext( cryptKey );
if( cryptStatusOK( status ) && \
!addCertFields( cryptCertChain, certRequestData ) )
return( FALSE );
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptCertChain, cryptCAKey );
cryptDestroyContext( cryptCAKey );
if( cryptStatusError( status ) )
{
printf( "Cert chain creation failed with error code %d, line %d.\n",
status, __LINE__ );
printCertErrorInfo( cryptCertChain );
return( FALSE );
}
/* Write the cert chain to the file */
status = cryptAddPrivateKey( cryptKeyset, cryptCertChain,
TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
printf( "cryptAddPrivateKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
cryptDestroyCert( cryptCertChain );
status = cryptKeysetClose( cryptKeyset );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( "Cert chain write to key file succeeded.\n" );
return( TRUE );
}
/* Delete a key from a file */
int testDeleteFileKey( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CONTEXT cryptContext;
int status;
puts( "Testing delete from key file..." );
/* Open the file keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
TEST_PRIVKEY_FILE, CRYPT_KEYOPT_NONE );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Delete the key from the file. Since we don't need the DSA key any
more we use it as the key to delete */
status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME,
DSA_PRIVKEY_LABEL );
if( cryptStatusError( status ) )
{
printf( "cryptDeleteKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptGetPublicKey( cryptKeyset, &cryptContext, CRYPT_KEYID_NAME,
DSA_PRIVKEY_LABEL );
if( cryptStatusOK( status ) )
{
cryptDestroyContext( cryptContext );
puts( "cryptDeleteKey() claimed the key was deleted but it's still "
"present." );
return( FALSE );
}
/* Close the keyset */
status = cryptKeysetClose( cryptKeyset );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( "Delete from key file succeeded.\n" );
return( TRUE );
}
/* Change the password for a key in a file */
int testChangeFileKeyPassword( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CONTEXT cryptContext;
int status;
puts( "Testing change of key password for key file..." );
/* Open the file keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
TEST_PRIVKEY_FILE, CRYPT_KEYOPT_NONE );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Read the key using the old password, delete it, and write it back
using the new password. To keep things simple we just use the same
password (since the key will be used again later), the test of the
delete function earlier on has already confirmed that the old key
and password will be deleted so there's no chance of a false positive */
status = cryptGetPrivateKey( cryptKeyset, &cryptContext,
CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL,
TEST_PRIVKEY_PASSWORD );
if( cryptStatusOK( status ) )
status = cryptDeleteKey( cryptKeyset, CRYPT_KEYID_NAME,
RSA_PRIVKEY_LABEL );
if( cryptStatusOK( status ) )
status = cryptAddPrivateKey( cryptKeyset, cryptContext,
TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
printf( "Password change failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
cryptDestroyContext( cryptContext );
/* Close the keyset */
status = cryptKeysetClose( cryptKeyset );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( "Password change for key in key file succeeded.\n" );
return( TRUE );
}
/* Write a key and cert to a file in a single operation */
int testSingleStepFileCert( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT cryptContext;
int status;
puts( "Testing single-step key+cert write to key file ..." );
/* Create a self-signed CA certificate */
if( !loadRSAContexts( CRYPT_UNUSED, NULL, &cryptContext ) )
return( FALSE );
status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusError( status ) )
{
printf( "cryptCreateCert() failed with error code %d.\n", status );
return( FALSE );
}
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptContext );
if( cryptStatusOK( status ) && !addCertFields( cryptCert, cACertData ) )
return( FALSE );
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptCert, cryptContext );
if( cryptStatusError( status ) )
{
printf( "Certificate creation failed with error code %d.\n", status );
cryptDestroyCert( status );
return( FALSE );
}
/* Open the keyset, write the key and certificate, and close it */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
TEST_PRIVKEY_FILE, CRYPT_KEYOPT_CREATE );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptAddPrivateKey( cryptKeyset, cryptContext,
TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
printf( "cryptAddPrivateKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptAddPublicKey( cryptKeyset, cryptCert );
if( cryptStatusError( status ) )
{
printf( "cryptAddPublicKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
cryptDestroyContext( cryptContext );
cryptDestroyCert( cryptCert );
/* Try and read the key+cert back before we close the keyset. This
ensures that the in-memory data has been updated correctly. We use
the generic RSA key label to read it since this isn't a real user
key */
status = cryptGetPrivateKey( cryptKeyset, &cryptContext, CRYPT_KEYID_NAME,
RSA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
{
printf( "Private key read from in-memory cached keyset data failed "
"with error code %d,\n line %d.\n", status, __LINE__ );
return( FALSE );
}
/* Close the keyset, which flushes the in-memory changes to disk. The
cacheing of data in memory ensures that all keyset updates are atomic,
so that it's nearly impossible to corrupt a private key keyset during
an update */
status = cryptKeysetClose( cryptKeyset );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Try and read the key+cert back from disk rather than the cached, in-
memory version */
status = getPrivateKey( &cryptContext, TEST_PRIVKEY_FILE,
RSA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
{
printf( "Private key read from on-disk keyset data failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
puts( "Single-step key+cert write to key file succeeded.\n" );
return( TRUE );
}
/* Write two keys and certs (signature + encryption) with the same DN to a
file */
int testDoubleCertFile( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CERTIFICATE cryptSigCert, cryptEncryptCert;
CRYPT_CONTEXT cryptCAKey, cryptSigContext, cryptEncryptContext;
int status;
puts( "Testing separate signature+encryption certificate write to key file ..." );
doubleCertOK = FALSE;
/* Get the CA's key */
status = getPrivateKey( &cryptCAKey, CA_PRIVKEY_FILE,
CA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
printf( "CA private key read failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Generate two keys to certify. We can't just use the built-in test key
because cryptlib will detect it being added to the keyset a second time
(if we reuse it for both keys) and because the label is a generic one
which doesn't work if there are two keys */
status = cryptCreateContext( &cryptSigContext, CRYPT_UNUSED,
CRYPT_ALGO_RSA );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptSigContext,
CRYPT_CTXINFO_LABEL, DUAL_SIGNKEY_LABEL,
strlen( DUAL_SIGNKEY_LABEL ) );
if( cryptStatusOK( status ) )
{
cryptSetAttribute( cryptSigContext, CRYPT_CTXINFO_KEYSIZE, 64 );
status = cryptGenerateKey( cryptSigContext );
}
if( cryptStatusError( status ) )
{
printf( "Test key generation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptCreateContext( &cryptEncryptContext, CRYPT_UNUSED,
CRYPT_ALGO_RSA );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptEncryptContext,
CRYPT_CTXINFO_LABEL, DUAL_ENCRYPTKEY_LABEL,
strlen( DUAL_ENCRYPTKEY_LABEL ) );
if( cryptStatusOK( status ) )
{
cryptSetAttribute( cryptEncryptContext, CRYPT_CTXINFO_KEYSIZE, 64 );
status = cryptGenerateKey( cryptEncryptContext );
}
if( cryptStatusError( status ) )
{
printf( "Test key generation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Create the certs containing the keys. In order to avoid clashes with
other keys with the same CN in the public-key database, we give the
certs abnormal CNs. This isn't necessary for cryptlib to manage them,
but because later code tries to delete leftover certs from previous
runs with the generic name used in the self-tests, which would also
delete these certs */
status = cryptCreateCert( &cryptSigCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptSigCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptSigContext );
if( cryptStatusOK( status ) && \
!addCertFields( cryptSigCert, certRequestData ) )
return( FALSE );
if( cryptStatusOK( status ) )
{
cryptDeleteAttribute( cryptSigCert, CRYPT_CERTINFO_COMMONNAME );
status = cryptSetAttributeString( cryptSigCert,
CRYPT_CERTINFO_COMMONNAME, "Dave Smith (Dual)", 17 );
}
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptSigCert,
CRYPT_CERTINFO_KEYUSAGE, CRYPT_KEYUSAGE_DIGITALSIGNATURE );
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptSigCert, cryptCAKey );
if( cryptStatusError( status ) )
{
printf( "Signature cert creation failed with error code %d, "
"line %d.\n", status, __LINE__ );
printCertErrorInfo( cryptSigCert );
return( FALSE );
}
status = cryptCreateCert( &cryptEncryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptEncryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cryptEncryptContext );
if( cryptStatusOK( status ) && \
!addCertFields( cryptEncryptCert, certRequestData ) )
return( FALSE );
if( cryptStatusOK( status ) )
{
cryptDeleteAttribute( cryptEncryptCert, CRYPT_CERTINFO_COMMONNAME );
status = cryptSetAttributeString( cryptEncryptCert,
CRYPT_CERTINFO_COMMONNAME, "Dave Smith (Dual)", 17 );
}
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptEncryptCert,
CRYPT_CERTINFO_KEYUSAGE, CRYPT_KEYUSAGE_KEYENCIPHERMENT );
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptEncryptCert, cryptCAKey );
if( cryptStatusError( status ) )
{
printf( "Encryption cert creation failed with error code %d, "
"line %d.\n", status, __LINE__ );
printCertErrorInfo( cryptEncryptCert );
return( FALSE );
}
cryptDestroyContext( cryptCAKey );
/* Open the keyset, write the keys and certificates, and close it */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
DUAL_PRIVKEY_FILE, CRYPT_KEYOPT_CREATE );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptAddPrivateKey( cryptKeyset, cryptSigContext,
TEST_PRIVKEY_PASSWORD );
if( cryptStatusOK( status ) )
status = cryptAddPrivateKey( cryptKeyset, cryptEncryptContext,
TEST_PRIVKEY_PASSWORD );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -