testcert.c
来自「老外写的加密库cryptlib(版本3.1)」· C语言 代码 · 共 1,830 行 · 第 1/5 页
C
1,830 行
const char *extensionData = "\x0C\x04Test";
int value, length, status;
puts( "Testing certificate with nonstd.extension creation/export..." );
/* Create the RSA en/decryption contexts */
if( !loadRSAContexts( CRYPT_UNUSED, &pubKeyContext, &privKeyContext ) )
return( FALSE );
/* Create the certificate */
status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusError( status ) )
{
printf( "cryptCreateCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, pubKeyContext );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CA, TRUE );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSetAttribute()", status,
__LINE__ ) );
if( !addCertFields( cryptCert, certData ) )
return( FALSE );
/* Add a nonstandard extension */
status = cryptAddCertExtension( cryptCert, "1.2.3.4.5", FALSE, extensionData, 6 );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptAddCertExtension()", status,
__LINE__ ) );
/* Sign the certificate. Since we're adding a nonstandard extension we
have to set the CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES flag to
make sure cryptlib will sign it */
cryptGetAttribute( CRYPT_UNUSED,
CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, &value );
cryptSetAttribute( CRYPT_UNUSED,
CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, TRUE );
status = cryptSignCert( cryptCert, privKeyContext );
cryptSetAttribute( CRYPT_UNUSED,
CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, value );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSignCert()", status,
__LINE__ ) );
destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
/* Print information on what we've got */
if( !printCertInfo( cryptCert ) )
return( FALSE );
/* Export the cert and make sure that we can read what we created */
status = cryptExportCert( certBuffer, &certificateLength,
CRYPT_CERTFORMAT_CERTIFICATE, cryptCert );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptExportCert()", status,
__LINE__ ) );
printf( "Exported certificate is %d bytes long.\n", certificateLength );
debugDump( "certext", certBuffer, certificateLength );
cryptDestroyCert( cryptCert );
status = cryptImportCert( certBuffer, certificateLength, CRYPT_UNUSED,
&cryptCert );
if( cryptStatusError( status ) )
{
printf( "cryptImportCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptCheckCert( cryptCert, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptCheckCert()", status,
__LINE__ ) );
/* Read back the nonstandard extension and make sure it's what we
originally wrote */
status = cryptGetCertExtension( cryptCert, "1.2.3.4.5", &value, buffer,
&length );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptGetCertExtension()", status,
__LINE__ ) );
if( value != FALSE || length != 6 || memcmp( extensionData, buffer, 6 ) )
{
printf( "Recovered nonstandard extension data differs from what was "
"written, line %d.\n", __LINE__ );
return( FALSE );
}
/* Clean up */
cryptDestroyCert( cryptCert );
puts( "Certificate with nonstd.extension creation succeeded.\n" );
return( TRUE );
}
int testCustomDNCert( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
const char *customDN = \
"cn=Dave Taylor + sn=12345, ou=Org.Unit 2\\=1, ou=Org.Unit 2, "
"ou=Org.Unit 1, o=Dave's Big Organisation, c=PT";
char buffer[ BUFFER_SIZE ];
int length, status;
puts( "Testing certificate with custom DN creation/export..." );
/* Create the RSA en/decryption contexts */
if( !loadRSAContexts( CRYPT_UNUSED, &pubKeyContext, &privKeyContext ) )
return( FALSE );
/* Create the certificate */
status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusError( status ) )
{
printf( "cryptCreateCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, pubKeyContext );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CA, TRUE );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptCert, CRYPT_CERTINFO_SELFSIGNED, TRUE );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSetAttribute()", status,
__LINE__ ) );
/* Add the custom DN in string form */
status = cryptSetAttributeString( cryptCert, CRYPT_CERTINFO_DN,
customDN, strlen( customDN ) );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSetAttributeString()", status,
__LINE__ ) );
/* Sign the certificate and print information on what we got */
status = cryptSignCert( cryptCert, privKeyContext );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSignCert()", status,
__LINE__ ) );
destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
if( !printCertInfo( cryptCert ) )
return( FALSE );
/* Export the cert and make sure that we can read what we created */
status = cryptExportCert( certBuffer, &certificateLength,
CRYPT_CERTFORMAT_CERTIFICATE, cryptCert );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptExportCert()", status,
__LINE__ ) );
printf( "Exported certificate is %d bytes long.\n", certificateLength );
debugDump( "certext", certBuffer, certificateLength );
cryptDestroyCert( cryptCert );
status = cryptImportCert( certBuffer, certificateLength, CRYPT_UNUSED,
&cryptCert );
if( cryptStatusError( status ) )
{
printf( "cryptImportCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptCheckCert( cryptCert, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptCheckCert()", status,
__LINE__ ) );
/* Read back the custom DN and make sure it's what we originally wrote */
status = cryptGetAttributeString( cryptCert, CRYPT_CERTINFO_DN,
buffer, &length );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptGetAttributeString()", status,
__LINE__ ) );
if( length != ( int ) strlen( customDN ) || \
memcmp( customDN, buffer, length ) )
{
printf( "Recovered custom DN differs from what was written, line "
"%d.\n", __LINE__ );
return( FALSE );
}
/* Clean up */
cryptDestroyCert( cryptCert );
puts( "Certificate with custom DN creation succeeded.\n" );
return( TRUE );
}
static const CERT_DATA setCertData[] = {
/* Identification information */
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers and Temple of SET" },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "SET Commerce Division" },
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's Cousin Bob" },
/* Self-signed X.509v3 certificate */
{ CRYPT_CERTINFO_SELFSIGNED, IS_NUMERIC, TRUE },
/* Add the SET extensions */
{ CRYPT_CERTINFO_SET_CERTIFICATETYPE, IS_NUMERIC, CRYPT_SET_CERTTYPE_RCA },
{ CRYPT_CERTINFO_SET_CERTCARDREQUIRED, IS_NUMERIC, TRUE },
{ CRYPT_CERTINFO_SET_ROOTKEYTHUMBPRINT, IS_STRING, 20, "12345678900987654321" },
{ CRYPT_CERTINFO_SET_MERID, IS_STRING, 0, "Wetaburger Vendor" },
{ CRYPT_CERTINFO_SET_MERACQUIRERBIN, IS_STRING, 0, "123456" },
{ CRYPT_CERTINFO_SET_MERCHANTLANGUAGE, IS_STRING, 0, "English" },
{ CRYPT_CERTINFO_SET_MERCHANTNAME, IS_STRING, 0, "Dave's Wetaburgers and SET Merchant" },
{ CRYPT_CERTINFO_SET_MERCHANTCITY, IS_STRING, 0, "Eketahuna" },
{ CRYPT_CERTINFO_SET_MERCHANTCOUNTRYNAME, IS_STRING, 0, "New Zealand" },
{ CRYPT_CERTINFO_SET_MERCOUNTRY, IS_NUMERIC, 554 }, /* ISO 3166 */
{ CRYPT_ATTRIBUTE_NONE, 0, 0, NULL }
};
int testSETCert( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
int status;
puts( "Testing SET certificate creation/export..." );
/* Create the RSA en/decryption contexts */
if( !loadRSAContexts( CRYPT_UNUSED, &pubKeyContext, &privKeyContext ) )
return( FALSE );
/* Create the certificate */
status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusError( status ) )
{
printf( "cryptCreateCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Add some certificate components */
status = cryptSetAttribute( cryptCert,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, pubKeyContext );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSetAttribute()", status,
__LINE__ ) );
if( !addCertFields( cryptCert, setCertData ) )
return( FALSE );
/* Sign the certificate and print information on what we got */
status = cryptSignCert( cryptCert, privKeyContext );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSignCert()", status,
__LINE__ ) );
if( !printCertInfo( cryptCert ) )
return( FALSE );
/* Export the cert */
status = cryptExportCert( certBuffer, &certificateLength,
CRYPT_CERTFORMAT_CERTIFICATE, cryptCert );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptExportCert()", status,
__LINE__ ) );
printf( "Exported certificate is %d bytes long.\n", certificateLength );
debugDump( "certset", certBuffer, certificateLength );
/* Destroy the certificate */
status = cryptDestroyCert( cryptCert );
if( cryptStatusError( status ) )
{
printf( "cryptDestroyCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Make sure that we can read what we created */
status = cryptImportCert( certBuffer, certificateLength, CRYPT_UNUSED,
&cryptCert );
if( cryptStatusError( status ) )
{
printf( "cryptImportCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
status = cryptCheckCert( cryptCert, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptCheckCert()", status,
__LINE__ ) );
cryptDestroyCert( cryptCert );
/* Clean up */
destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
puts( "SET certificate creation succeeded.\n" );
return( TRUE );
}
static const CERT_DATA attributeCertData[] = {
/* Identification information */
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NI" }, /* Ni! Ni! Ni! */
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers and Attributes" },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "Attribute Management" },
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave's Mum" },
{ CRYPT_ATTRIBUTE_NONE, 0, 0, NULL }
};
int testAttributeCert( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT cryptAuthorityKey;
int status;
puts( "Testing attribute certificate creation/export..." );
/* Get the authority's private key */
status = getPrivateKey( &cryptAuthorityKey, CA_PRIVKEY_FILE,
CA_PRIVKEY_LABEL, TEST_PRIVKEY_PASSWORD );
if( cryptStatusError( status ) )
{
printf( "Authority private key read failed with error code %d, "
"line %d.\n", status, __LINE__ );
return( FALSE );
}
/* Create the certificate */
status = cryptCreateCert( &cryptCert, CRYPT_UNUSED,
CRYPT_CERTTYPE_ATTRIBUTE_CERT );
if( cryptStatusError( status ) )
{
printf( "cryptCreateCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Add some certificate components. Note that we don't add any
attributes because these hadn't been defined yet (at least not as of
the JTC1 SC21/ITU-T Q.17/7 draft of July 1997) */
if( !addCertFields( cryptCert, attributeCertData ) )
return( FALSE );
/* Sign the certificate and print information on what we got */
status = cryptSignCert( cryptCert, cryptAuthorityKey );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSignCert()", status,
__LINE__ ) );
if( !printCertInfo( cryptCert ) )
return( FALSE );
/* Export the cert */
status = cryptExportCert( certBuffer, &certificateLength,
CRYPT_CERTFORMAT_CERTIFICATE, cryptCert );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptExportCert()", status,
__LINE__ ) );
printf( "Exported certificate is %d bytes long.\n", certificateLength );
debugDump( "certattr", certBuffer, certificateLength );
/* Destroy the certificate */
status = cryptDestroyCert( cryptCert );
if( cryptStatusError( status ) )
{
printf( "cryptDestroyCert() failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
/* Make sure that we can read what we created */
status = cryptImportCert( certBuffer, certificateLength, CRYPT_UNUSED,
&cryptCert );
if( cryptStatusError( status ) )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?