📄 certs.c
字号:
CRYPT_CERTINFO_BASICCONSTRAINTS );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptDeleteAttribute()", status,
__LINE__ ) );
if( cryptStatusOK( status ) )
status = cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CA, TRUE );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSetAttribute()", 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 );
/* Make sure that GeneralName component selection is working properly */
cryptSetAttribute( cryptCert, CRYPT_ATTRIBUTE_CURRENT,
CRYPT_CERTINFO_SUBJECTALTNAME );
status = cryptGetAttributeString( cryptCert,
CRYPT_CERTINFO_RFC822NAME, buffer1, &length1 );
if( cryptStatusOK( status ) )
status = cryptGetAttributeString( cryptCert,
CRYPT_CERTINFO_RFC822NAME, buffer2, &length2 );
if( cryptStatusError( status ) )
{
printf( "Attempt to read and re-read email address failed, line "
"%d.\n", __LINE__ );
return( FALSE );
}
#ifdef UNICODE_STRINGS
buffer1[ length1 / sizeof( wchar_t ) ] = TEXT( '\0' );
buffer2[ length2 / sizeof( wchar_t ) ] = TEXT( '\0' );
#else
buffer1[ length1 ] = '\0';
buffer2[ length2 ] = '\0';
#endif /* UNICODE_STRINGS */
if( ( length1 != ( int ) paramStrlen( TEXT( "dave@wetas-r-us.com" ) ) ) || \
( length1 != length2 ) || \
memcmp( buffer1, TEXT( "dave@wetas-r-us.com" ), length1 ) || \
memcmp( buffer2, TEXT( "dave@wetas-r-us.com" ), length2 ) )
{
printf( "Email address on read #1 = '%s',\n read #2 = '%s', should "
"have been '%s', line %d.\n", buffer1, buffer2,
"dave@wetas-r-us.com", __LINE__ );
return( FALSE );
}
/* Export the cert */
status = cryptExportCert( certBuffer, BUFFER_SIZE, &certificateLength,
CRYPT_CERTFORMAT_CERTIFICATE, cryptCert );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptExportCert()", status,
__LINE__ ) );
printf( "Exported certificate is %d bytes long.\n", certificateLength );
debugDump( "certc", 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 */
puts( "Complex certificate creation succeeded.\n" );
return( TRUE );
}
int testCertExtension( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
BYTE buffer[ 16 ];
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, __LINE__ ) )
return( FALSE );
/* Add a nonstandard critical extension */
status = cryptAddCertExtension( cryptCert, "1.2.3.4.5", TRUE, 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 that 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, BUFFER_SIZE, &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 );
}
/* Check the cert. Since it contains an unrecognised critical extension
it should be rejected, but accepted at a lowered compliance level */
status = cryptCheckCert( cryptCert, CRYPT_UNUSED );
if( cryptStatusOK( status ) )
{
printf( "Certificate with unrecognised critical extension was "
"accepted when it should\nhave been rejected, line %d.\n",
__LINE__ );
return( FALSE );
}
cryptGetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL,
&value );
cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL,
CRYPT_COMPLIANCELEVEL_REDUCED );
status = cryptCheckCert( cryptCert, CRYPT_UNUSED );
cryptSetAttribute( CRYPT_UNUSED, CRYPT_OPTION_CERT_COMPLIANCELEVEL,
value );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptCheckCert()", status,
__LINE__ ) );
/* Read back the nonstandard extension and make sure that it's what we
originally wrote */
status = cryptGetCertExtension( cryptCert, "1.2.3.4.5", &value, buffer,
16, &length );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptGetCertExtension()", status,
__LINE__ ) );
if( value != TRUE || 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 C_STR customDN = \
TEXT( "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, paramStrlen( 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, BUFFER_SIZE, &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 that 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 ) paramStrlen( 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 FAR_BSS setCertData[] = {
/* Identification information */
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, TEXT( "NZ" ) },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, TEXT( "Dave's Wetaburgers and Temple of SET" ) },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, TEXT( "SET Commerce Division" ) },
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, TEXT( "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, TEXT( "12345678900987654321" ) },
{ CRYPT_CERTINFO_SET_MERID, IS_STRING, 0, TEXT( "Wetaburger Vendor" ) },
{ CRYPT_CERTINFO_SET_MERACQUIRERBIN, IS_STRING, 0, TEXT( "123456" ) },
{ CRYPT_CERTINFO_SET_MERCHANTLANGUAGE, IS_STRING, 0, TEXT( "English" ) },
{ CRYPT_CERTINFO_SET_MERCHANTNAME, IS_STRING, 0, TEXT( "Dave's Wetaburgers and SET Merchant" ) },
{ CRYPT_CERTINFO_SET_MERCHANTCITY, IS_STRING, 0, TEXT( "Eketahuna" ) },
{ CRYPT_CERTINFO_SET_MERCHANTCOUNTRYNAME, IS_STRING, 0, TEXT( "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, __LINE__ ) )
return( FALSE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -