📄 keyfile.c
字号:
if( cryptStatusError( status ) )
{
printf( "cryptAddPrivateKey() failed with error code %d, line %d.\n",
status, __LINE__ );
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 );
}
/* Clean up */
cryptDestroyContext( privateKeyContext );
printf( "Write of %s private key to key file succeeded.\n\n",
useRSA ? "RSA" : "DSA" );
return( TRUE );
}
int testReadWriteFileKey( void )
{
int status;
status = writeFileKey( TRUE, FALSE );
if( status )
status = readFileKey( TRUE );
#ifndef CREATE_CUSTOM_CERT
/* CA test keys only uses RSA */
if( status )
status = writeFileKey( FALSE, FALSE );
if( status )
status = readFileKey( FALSE );
#endif /* CREATE_CUSTOM_CERT */
return( status );
}
int testWriteAltFileKey( void )
{
return( writeFileKey( TRUE, TRUE ) );
}
int testReadBigFileKey( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CONTEXT cryptContext;
int status;
printf( "Testing private key read from large key file...\n" );
/* Open the file keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
BIG_PRIVKEY_FILE, CRYPT_KEYOPT_READONLY );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Read the key from the file */
status = cryptGetPrivateKey( cryptKeyset, &cryptContext,
CRYPT_KEYID_NAME, TEXT( "John Smith 0" ),
TEXT( "password" ) );
if( cryptStatusError( status ) )
{
printf( "cryptGetPrivateKey() 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( "Read of private key from large key file succeeded.\n" );
return( TRUE );
}
/* Read only the public key/cert/cert chain portion of a keyset */
int testReadFilePublicKey( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CONTEXT cryptContext;
int cryptAlgo, status;
puts( "Testing public key read from key file..." );
/* Open the file keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
TEST_PRIVKEY_FILE, CRYPT_KEYOPT_READONLY );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Read the public key from the file and make sure that it really is a
public-key context */
status = cryptGetPublicKey( cryptKeyset, &cryptContext, CRYPT_KEYID_NAME,
RSA_PRIVKEY_LABEL );
if( cryptStatusError( status ) )
{
printf( "cryptGetPublicKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptGetAttribute( cryptContext, CRYPT_CTXINFO_ALGO, &cryptAlgo );
if( cryptStatusError( status ) || \
cryptAlgo < CRYPT_ALGO_FIRST_PKC || cryptAlgo > CRYPT_ALGO_LAST_PKC )
{
puts( "Returned object isn't a public-key context." );
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 );
}
cryptDestroyContext( cryptContext );
puts( "Read of public key from key file succeeded.\n" );
return( TRUE );
}
static int readCert( const char *certTypeName,
const CRYPT_CERTTYPE_TYPE certType,
const BOOLEAN readPrivateKey )
{
CRYPT_KEYSET cryptKeyset;
int value, status;
printf( "Testing %s read from key file...\n", certTypeName );
/* Open the file keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
TEST_PRIVKEY_FILE, CRYPT_KEYOPT_READONLY );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetOpen() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Read the certificate from the file and make sure that it really is a
cert */
if( readPrivateKey )
{
CRYPT_CONTEXT cryptContext;
status = cryptGetPrivateKey( cryptKeyset, &cryptContext,
CRYPT_KEYID_NAME, RSA_PRIVKEY_LABEL,
TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
printf( "cryptGetPrivateKey() failed with error code %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
status = cryptGetAttribute( cryptContext, CRYPT_CERTINFO_CERTTYPE,
&value );
if( cryptStatusError( status ) || value != certType )
{
printf( "Returned object isn't a %s.\n", certTypeName );
return( FALSE );
}
/* Make sure that we can't use the read key (the cert constrains it
from being used externally) */
status = testCrypt( cryptContext, cryptContext, NULL, FALSE, TRUE );
if( status != CRYPT_ERROR_NOTAVAIL )
{
puts( "Attempt to perform external operation on context with "
"internal-only action\npermissions succeeded. " );
return( FALSE );
}
cryptDestroyContext( cryptContext );
}
else
{
CRYPT_CERTIFICATE cryptCert;
status = cryptGetPublicKey( cryptKeyset, &cryptCert, CRYPT_KEYID_NAME,
( certType == CRYPT_CERTTYPE_CERTIFICATE ) ? \
RSA_PRIVKEY_LABEL : USER_PRIVKEY_LABEL );
if( cryptStatusError( status ) )
{
printf( "cryptGetPublicKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptGetAttribute( cryptCert, CRYPT_CERTINFO_CERTTYPE, &value );
if( cryptStatusError( status ) || value != certType )
{
printf( "Returned object isn't a %s.\n", certTypeName );
return( FALSE );
}
cryptDestroyCert( cryptCert );
}
/* Close the keyset */
status = cryptKeysetClose( cryptKeyset );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
printf( "Read of %s from key file succeeded.\n\n", certTypeName );
return( TRUE );
}
int testReadFileCert( void )
{
return( readCert( "certificate", CRYPT_CERTTYPE_CERTIFICATE, FALSE ) );
}
int testReadFileCertPrivkey( void )
{
return( readCert( "private key with certificate", CRYPT_CERTTYPE_CERTIFICATE, TRUE ) );
}
int testReadFileCertChain( void )
{
return( readCert( "cert chain", CRYPT_CERTTYPE_CERTCHAIN, FALSE ) );
}
/****************************************************************************
* *
* Certificate Read/Write Tests *
* *
****************************************************************************/
/* Update a keyset to contain a certificate */
int testAddTrustedCert( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CERTIFICATE trustedCert;
int value, status;
puts( "Testing trusted certificate add to key file..." );
/* Read the CA root cert. We have to make it explicitly non-trusted
since something else may have made it trusted previously */
status = importCertFromTemplate( &trustedCert, CERT_FILE_TEMPLATE, 1 );
if( cryptStatusError( status ) )
{
puts( "Couldn't read certificate from file, skipping test of trusted "
"cert write..." );
return( TRUE );
}
cryptGetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT,
&value );
if( value )
cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT,
FALSE );
/* Open the keyset, update it with the trusted certificate, and close it.
Before we make the cert trusted, we try adding it as a standard cert,
which should fail */
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 = cryptAddPublicKey( cryptKeyset, trustedCert );
if( cryptStatusOK( status ) )
{
printf( "cryptAddPublicKey() of non-trusted cert succeeded when it "
"should have failed, line %d.\n", __LINE__ );
return( FALSE );
}
cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, TRUE );
status = cryptAddPublicKey( cryptKeyset, trustedCert );
if( cryptStatusError( status ) )
{
printf( "cryptAddPublicKey() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, value );
cryptDestroyCert( trustedCert );
status = cryptKeysetClose( cryptKeyset );
if( cryptStatusError( status ) )
{
printf( "cryptKeysetClose() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
puts( "Trusted certificate add to key file succeeded.\n" );
return( TRUE );
}
int testAddGloballyTrustedCert( void )
{
CRYPT_CERTIFICATE trustedCert;
int status;
puts( "Testing globally trusted certificate add..." );
/* Read the CA root cert and make it trusted */
status = importCertFromTemplate( &trustedCert, CERT_FILE_TEMPLATE, 1 );
if( cryptStatusError( status ) )
{
puts( "Couldn't read certificate from file, skipping test of trusted "
"cert write..." );
return( TRUE );
}
cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, TRUE );
/* Update the config file with the globally trusted cert */
status = cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED,
FALSE );
if( cryptStatusError( status ) )
{
printf( "Globally trusted certificate add failed with error code "
"%d.\n", status );
return( FALSE );
}
/* Make the cert untrusted and update the config again */
cryptSetAttribute( trustedCert, CRYPT_CERTINFO_TRUSTED_IMPLICIT, FALSE );
status = cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CONFIGCHANGED,
FALSE );
if( cryptStatusError( status ) )
{
printf( "Globally trusted certificate delete failed with error code "
"%d.\n", status );
return( FALSE );
}
puts( "Globally trusted certificate add succeeded.\n" );
return( TRUE );
}
static const CERT_DATA cACertData[] = {
/* Identification information. Note the non-heirarchical order of the
components to test the automatic arranging of the DN */
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, TEXT( "Dave's Wetaburgers and CA" ) },
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, TEXT( "Dave Himself" ) },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, TEXT( "Certification Division" ) },
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, TEXT( "NZ" ) },
/* Self-signed X.509v3 certificate */
{ CRYPT_CERTINFO_SELFSIGNED, IS_NUMERIC, TRUE },
/* CA key usage */
#if defined( CREATE_SCEPCA_CERT )
{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC, CRYPT_KEYUSAGE_KEYCERTSIGN | \
CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
CRYPT_KEYUSAGE_KEYENCIPHERMENT },
#else
{ CRYPT_CERTINFO_KEYUSAGE, IS_NUMERIC,
CRYPT_KEYUSAGE_KEYCERTSIGN | CRYPT_KEYUSAGE_CRLSIGN },
#endif /* SCEP vs.standard CA */
{ CRYPT_CERTINFO_CA, IS_NUMERIC, TRUE },
{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
};
int testUpdateFileCert( void )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT publicKeyContext, privateKeyContext;
int status;
puts( "Testing certificate update to key file ..." );
/* Create a self-signed CA certificate using the in-memory key (which is
the same as the one in the keyset) */
#if defined( CREATE_CA_CERT ) || defined( CREATE_SCEPCA_CERT )
status = cryptCreateContext( &cryptKey, CRYPT_UNUSED, CRYPT_ALGO_RSA );
if( cryptStatusOK( status ) )
status = cryptSetAttributeString( cryptKey, CRYPT_CTXINFO_LABEL,
USER_PRIVKEY_LABEL,
paramStrlen( USER_PRIVKEY_LABEL ) );
if( cryptStatusOK( status ) )
{
cryptSetAttribute( cryptKey, CRYPT_CTXINFO_KEYSIZE, 64 );
status = cryptGenerateKey( cryptKey );
}
if( cryptStatusError( status ) )
{
printf( "Test key generation failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
#else
if( !loadRSAContexts( CRYPT_UNUSED, &publicKeyContext, &privateKeyContext ) )
return( FALSE );
#endif /* Special-purpose cert creation */
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, publicKeyContext );
if( cryptStatusOK( status ) && !addCertFields( cryptCert, cACertData ) )
return( FALSE );
#ifdef CREATE_CUSTOM_CERT
{
const time_t validity = time( NULL ) + ( 86400L * 365 * 5 );
/* Make it valid for 5 years instead of 1 to avoid problems when users
run the self-test with very old copies of the code */
cryptSetAttributeString( cryptCert,
CRYPT_CERTINFO_VALIDTO, &validity, sizeof( time_t ) );
}
#endif /* CREATE_CUSTOM_CERT */
if( cryptStatusOK( status ) )
status = cryptSignCert( cryptCert, privateKeyContext );
destroyContexts( CRYPT_UNUSED, publicKeyContext, privateKeyContext );
if( cryptStatusError( status ) )
{
printf( "Certificate creation failed with error code %d.\n", status );
cryptDestroyCert( status );
return( FALSE );
}
/* Open the keyset, update it with the certificate, and close it */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
TEST_PRIVKEY_FILE, CRYPT_KEYOPT_NONE );
if( cryptStatusError( status ) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -