📄 testcert.c
字号:
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
int status;
puts( "Testing XYZZY 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, xyzzyCertData ) )
return( FALSE );
/* Sign the certificate */
status = cryptSignCert( cryptCert, privKeyContext );
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 );
/* Check the signature. Since it's self-signed, we don't need to pass in
a signature check key */
status = cryptCheckCert( cryptCert, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptCheckCert()", status,
__LINE__ ) );
/* 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( "certxy", 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 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( "XYZZY certificate creation succeeded.\n" );
return( TRUE );
}
static const CERT_DATA complexCertData[] = {
/* Identification information */
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Wetaburgers and Netscape CA" },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "SSL Certificates" },
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, "Dave Himself" },
/* Self-signed X.509v3 certificate */
{ CRYPT_CERTINFO_SELFSIGNED, IS_NUMERIC, TRUE },
/* Subject altName */
{ CRYPT_CERTINFO_RFC822NAME, IS_STRING, 0, "dave@wetas-r-us.com" },
{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, "http://www.wetas-r-us.com" },
/* Oddball altName components. Note that the otherName.value must be a
DER-encoded ASN.1 object */
{ CRYPT_CERTINFO_EDIPARTYNAME_NAMEASSIGNER, IS_STRING, 0, "EDI Name Assigner" },
{ CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME, IS_STRING, 0, "EDI Party Name" },
{ CRYPT_CERTINFO_OTHERNAME_TYPEID, IS_STRING, 0, "1 3 6 1 4 1 9999 2" },
{ CRYPT_CERTINFO_OTHERNAME_VALUE, IS_STRING, 0, "\x04\x08" "12345678" },
/* Path constraint. Note the two-stage selection process, first we
select the GeneralName with CRYPT_CERTINFO_EXCLUDEDSUBTREES, then we
select the DN in the GeneralName with CRYPT_CERTINFO_DIRECTORYNAME */
{ CRYPT_CERTINFO_EXCLUDEDSUBTREES, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_CERTINFO_DIRECTORYNAME, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, "NZ" },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, "Dave's Brother's CA" },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, "SSL Certificates" },
/* CRL distribution points. Note again the two-stage selection process,
first we select the GeneralName with
CRYPT_CERTINFO_CRLDIST_FULLNAME, then we access the URI in the
GeneralName with CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER */
{ CRYPT_CERTINFO_CRLDIST_FULLNAME, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, "http://www.revocations.com/crls/" },
/* Netscape cert-type extension, revocation URL, and Netscape SGC cert
(this is a pretty confused certificate) */
{ CRYPT_CERTINFO_NS_CERTTYPE, IS_NUMERIC,
CRYPT_NS_CERTTYPE_SSLSERVER | CRYPT_NS_CERTTYPE_SMIME },
{ CRYPT_CERTINFO_NS_REVOCATIONURL, IS_STRING, 0, "http://www.ns-revocations.com/" },
{ CRYPT_CERTINFO_EXTKEY_NS_SERVERGATEDCRYPTO, IS_NUMERIC, CRYPT_UNUSED },
/* Add a vendor-specific extension, in this case a Thawte strong extranet
extension */
{ CRYPT_CERTINFO_STRONGEXTRANET_ZONE, IS_NUMERIC, 0x99 },
{ CRYPT_CERTINFO_STRONGEXTRANET_ID, IS_STRING, 0, "EXTRA1" },
/* Misc funnies */
{ CRYPT_CERTINFO_OCSP_NOCHECK, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
};
int testComplexCert( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
int status;
puts( "Testing complex 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, complexCertData ) )
return( FALSE );
/* Add a non-CA basicConstraint, delete it, and re-add it as CA
constraint */
status = cryptSetAttribute( cryptCert, CRYPT_CERTINFO_CA, FALSE );
if( cryptStatusError( status ) )
return( attrErrorExit( cryptCert, "cryptSetAttribute()", status,
__LINE__ ) );
status = cryptDeleteAttribute( cryptCert,
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 */
status = cryptSignCert( cryptCert, privKeyContext );
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 */
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( "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 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 ) )
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 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=NZ";
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 ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -