📄 certs.c
字号:
&endTime, &value );
if( cryptStatusError( status ) )
{
printf( "Cert time read failed with error code %d, line %d.\n",
status, __LINE__ );
return( FALSE );
}
if( startTime != CERTTIME_DATETEST )
{
printf( "Warning: cert start time is wrong, got %lX, should be "
"%lX.\n This is probably due to problems in the "
"system time handling routines.\n",
startTime, CERTTIME_DATETEST );
}
if( endTime != CERTTIME_Y2KTEST )
printf( "Warning: cert end time is wrong, got %lX, should be "
"%lX.\n This is probably due to problems in the "
"system time handling routines.\n",
endTime, CERTTIME_Y2KTEST );
cryptDestroyCert( cryptCert );
#if defined( __WINDOWS__ ) || defined( __linux__ ) || defined( sun )
if( ( startTime != CERTTIME_DATETEST && \
( startTime - CERTTIME_DATETEST != 3600 && \
startTime - CERTTIME_DATETEST != -3600 ) ) || \
( endTime != CERTTIME_Y2KTEST && \
( endTime - CERTTIME_Y2KTEST != 3600 && \
endTime - CERTTIME_Y2KTEST != -3600 ) ) )
/* If the time is off by exactly one hour this isn't a problem
because the best we can do is get the time adjusted for DST
now rather than DST when the cert was created, a problem that
is more or less undecidable. In addition we don't automatically
abort for arbitrary systems since date problems usually arise
from incorrectly configured time zone info or bugs in the system
date-handling routines or who knows what, aborting on every
random broken system would lead to a flood of unnecessary "bug"
reports */
return( FALSE );
#endif /* System with known-good time handling */
/* Clean up */
puts( "CA certificate creation succeeded.\n" );
return( TRUE );
}
static const CERT_DATA FAR_BSS xyzzyCertData[] = {
/* Identification information */
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, TEXT( "Dave Smith" ) },
/* XYZZY certificate */
{ CRYPT_CERTINFO_XYZZY, IS_NUMERIC, TRUE },
{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
};
int testXyzzyCert( void )
{
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, __LINE__ ) )
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__ ) );
destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
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, 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( "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 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( "XYZZY certificate creation succeeded.\n" );
return( TRUE );
}
#ifdef HAS_WIDECHAR
static const wchar_t FAR_BSS unicodeStr[] = {
0x0414, 0x043E, 0x0432, 0x0435, 0x0440, 0x044F, 0x0439, 0x002C,
0x0020, 0x043D, 0x043E, 0x0020, 0x043F, 0x0440, 0x043E, 0x0432,
0x0435, 0x0440, 0x044F, 0x0439, 0x0000 };
static const CERT_DATA FAR_BSS textStringCertData[] = {
/* Identification information: A latin-1 string, a Unicode string,
an ASCII-in-Unicode string, and an ASCII string */
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, TEXT( "H鰎r 豷terix" ) },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_WCSTRING, 0, unicodeStr },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_WCSTRING, 0, L"Dave's Unicode-aware CA with very long string" },
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, TEXT( "GB" ) },
/* Another XYZZY certificate */
{ CRYPT_CERTINFO_XYZZY, IS_NUMERIC, TRUE },
{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
};
int testTextStringCert( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
int status;
puts( "Testing complex string type 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, textStringCertData, __LINE__ ) )
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__ ) );
destroyContexts( CRYPT_UNUSED, pubKeyContext, privKeyContext );
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, 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( "certstr", 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 string type certificate creation succeeded.\n" );
return( TRUE );
}
#else
int testTextStringCert( void )
{
return( TRUE );
}
#endif /* Unicode-aware systems */
static const CERT_DATA FAR_BSS complexCertData[] = {
/* Identification information */
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, TEXT( "US" ) },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, TEXT( "Dave's Wetaburgers and Netscape CA" ) },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, TEXT( "SSL Certificates" ) },
{ CRYPT_CERTINFO_COMMONNAME, IS_STRING, 0, TEXT( "Bob';DROP TABLE certificates;--" ) },
/* Self-signed X.509v3 certificate */
{ CRYPT_CERTINFO_SELFSIGNED, IS_NUMERIC, TRUE },
/* Subject altName */
{ CRYPT_CERTINFO_RFC822NAME, IS_STRING, 0, TEXT( "dave@wetas-r-us.com" ) },
{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, TEXT( "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, TEXT( "EDI Name Assigner" ) },
{ CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME, IS_STRING, 0, TEXT( "EDI Party Name" ) },
{ CRYPT_CERTINFO_OTHERNAME_TYPEID, IS_STRING, 0, TEXT( "1 3 6 1 4 1 9999 2" ) },
{ CRYPT_CERTINFO_OTHERNAME_VALUE, IS_STRING, 10, "\x04\x08" "12345678" },
/* Path constraint */
{ CRYPT_ATTRIBUTE_CURRENT, IS_NUMERIC, CRYPT_CERTINFO_EXCLUDEDSUBTREES },
{ CRYPT_CERTINFO_COUNTRYNAME, IS_STRING, 0, TEXT( "CZ" ) },
{ CRYPT_CERTINFO_ORGANIZATIONNAME, IS_STRING, 0, TEXT( "Dave's Brother's CA" ) },
{ CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, IS_STRING, 0, TEXT( "SSL Certificates" ) },
/* CRL distribution points */
{ CRYPT_ATTRIBUTE_CURRENT, IS_NUMERIC, CRYPT_CERTINFO_CRLDIST_FULLNAME },
{ CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, IS_STRING, 0, TEXT( "http://www.revocations.com/crls/" ) },
/* 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, TEXT( "EXTRA1" ) },
/* Misc funnies */
{ CRYPT_CERTINFO_OCSP_NOCHECK, IS_NUMERIC, CRYPT_UNUSED },
/* Re-select the subject name after poking around in the altName */
{ CRYPT_CERTINFO_SUBJECTNAME, IS_NUMERIC, CRYPT_UNUSED },
{ CRYPT_ATTRIBUTE_NONE, IS_VOID }
};
int testComplexCert( void )
{
CRYPT_CERTIFICATE cryptCert;
CRYPT_CONTEXT pubKeyContext, privKeyContext;
C_CHR buffer1[ 64 ], buffer2[ 64 ];
int length1, length2, 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, __LINE__ ) )
return( FALSE );
/* Add an OID, read it back, and make sure that the OID en/decoding
worked correctly */
status = cryptSetAttributeString( cryptCert, CRYPT_CERTINFO_CERTPOLICYID,
TEXT( "1 2 3 4 5" ),
paramStrlen( TEXT( "1 2 3 4 5" ) ) );
if( cryptStatusOK( status ) )
status = cryptGetAttributeString( cryptCert,
CRYPT_CERTINFO_CERTPOLICYID,
buffer1, &length1 );
if( cryptStatusOK( status ) )
status = cryptDeleteAttribute( cryptCert, CRYPT_CERTINFO_CERTPOLICYID );
if( cryptStatusOK( status ) && \
( length1 != ( int ) paramStrlen( TEXT( "1 2 3 4 5" ) ) || \
memcmp( buffer1, TEXT( "1 2 3 4 5" ), length1 ) ) )
{
printf( "Error in OID en/decoding, line %d.\n", __LINE__ );
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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -