📄 certutil.c
字号:
strcat( fileNameBuffer + tmpPathLen, "/" );
}
else
strcpy( fileNameBuffer, "/tmp/" );
#else
fileNameBuffer[ 0 ] = '\0';
#endif /* OS-specific paths */
strcat( fileNameBuffer, fileName );
if( length <= 3 || fileName[ length - 4 ] != '.' )
strcat( fileNameBuffer, ".der" );
#if defined( __VMCMS__ )
{
char formatBuffer[ 32 ];
sprintf( formatBuffer, "wb, recfm=F, lrecl=%d, noseek", dataLength );
filePtr = fopen( fileNameBuffer, formatBuffer );
}
if( filePtr == NULL )
#else
if( ( filePtr = fopen( fileNameBuffer, "wb" ) ) == NULL )
#endif /* __VMCMS__ */
return;
fwrite( data, dataLength, 1, filePtr );
fclose( filePtr );
}
/****************************************************************************
* *
* Certificate Dump Routines *
* *
****************************************************************************/
/* Print a hex string */
static void printHex( const BYTE *value, const int length )
{
int i;
for( i = 0; i < length; i++ )
{
if( i )
putchar( ' ' );
printf( "%02X", value[ i ] );
}
puts( "." );
}
/* Print a DN */
static void printDN( const CRYPT_CERTIFICATE certificate )
{
char buffer[ 1024 + 1 ];
int length, status;
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_DN, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " DN string = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_COUNTRYNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " C = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_STATEORPROVINCENAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " S = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_LOCALITYNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " L = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_ORGANIZATIONNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " O = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_ORGANIZATIONALUNITNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " OU = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_COMMONNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " CN = %s.\n", buffer ); }
}
/* Print an altName */
static void printAltName( const CRYPT_CERTIFICATE certificate )
{
char buffer[ 512 ];
int length, status;
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_RFC822NAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " Email = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_DNSNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " DNSName = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_EDIPARTYNAME_NAMEASSIGNER, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " EDI Nameassigner = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_EDIPARTYNAME_PARTYNAME, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " EDI Partyname = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " URL = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_IPADDRESS, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " IP = %s.\n", buffer ); }
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_REGISTEREDID, buffer, &length );
if( cryptStatusOK( status ) )
{ buffer[ length ] = '\0'; printf( " Registered ID = %s.\n", buffer ); }
status = cryptSetAttribute( certificate, CRYPT_CERTINFO_DIRECTORYNAME,
CRYPT_UNUSED );
if( cryptStatusOK( status ) )
{
printf( " altName DN is:\n" );
printDN( certificate );
}
}
/* The following function performs many attribute accesses, rather than using
huge numbers of status checks we use the following macro to check each
attribute access */
#define CHK( function ) \
status = function; \
if( cryptStatusError( status ) ) \
return( certInfoErrorExit( #function, status, __LINE__ ) )
static int certInfoErrorExit( const char *functionCall, const int status,
const int line )
{
printf( "\n%s failed with status %d, line %d.\n", functionCall,
status, line );
return( FALSE );
}
/* Print information on a certificate */
int printCertInfo( const CRYPT_CERTIFICATE certificate )
{
CRYPT_CERTTYPE_TYPE certType;
BOOLEAN hasExtensions = FALSE;
char buffer[ 1024 ];
int length, value, status;
CHK( cryptGetAttribute( certificate, CRYPT_CERTINFO_CERTTYPE, &value ) );
certType = value;
/* Display the issuer and subject DN */
if( certType != CRYPT_CERTTYPE_CERTREQUEST && \
certType != CRYPT_CERTTYPE_REQUEST_CERT && \
certType != CRYPT_CERTTYPE_REQUEST_REVOCATION && \
certType != CRYPT_CERTTYPE_RTCS_REQUEST && \
certType != CRYPT_CERTTYPE_RTCS_RESPONSE && \
certType != CRYPT_CERTTYPE_OCSP_REQUEST && \
certType != CRYPT_CERTTYPE_CMS_ATTRIBUTES && \
certType != CRYPT_CERTTYPE_PKIUSER )
{
puts( "Certificate object issuer name is:" );
CHK( cryptSetAttribute( certificate, CRYPT_CERTINFO_ISSUERNAME,
CRYPT_UNUSED ) );
printDN( certificate );
if( cryptStatusOK( \
cryptGetAttribute( certificate,
CRYPT_CERTINFO_ISSUERALTNAME, &value ) ) )
{
CHK( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_FIELD,
CRYPT_CERTINFO_ISSUERALTNAME ) );
printAltName( certificate );
}
}
if( certType != CRYPT_CERTTYPE_CRL && \
certType != CRYPT_CERTTYPE_REQUEST_REVOCATION && \
certType != CRYPT_CERTTYPE_CMS_ATTRIBUTES && \
certType != CRYPT_CERTTYPE_RTCS_REQUEST && \
certType != CRYPT_CERTTYPE_RTCS_RESPONSE && \
certType != CRYPT_CERTTYPE_OCSP_REQUEST && \
certType != CRYPT_CERTTYPE_OCSP_RESPONSE )
{
puts( "Certificate object subject name is:" );
CHK( cryptSetAttribute( certificate, CRYPT_CERTINFO_SUBJECTNAME,
CRYPT_UNUSED ) );
printDN( certificate );
if( cryptStatusOK( \
cryptGetAttribute( certificate,
CRYPT_CERTINFO_SUBJECTALTNAME, &value ) ) )
{
CHK( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_FIELD,
CRYPT_CERTINFO_SUBJECTALTNAME ) );
printAltName( certificate );
}
}
/* Display the validity information */
if( certType == CRYPT_CERTTYPE_CERTCHAIN ||
certType == CRYPT_CERTTYPE_CERTIFICATE || \
certType == CRYPT_CERTTYPE_ATTRIBUTE_CERT )
{
time_t validFrom, validTo;
CHK( cryptGetAttributeString( certificate, CRYPT_CERTINFO_VALIDFROM,
&validFrom, &length ) );
CHK( cryptGetAttributeString( certificate, CRYPT_CERTINFO_VALIDTO,
&validTo, &length ) );
strcpy( buffer, ctime( &validFrom ) );
buffer[ strlen( buffer ) - 1 ] = '\0'; /* Stomp '\n' */
printf( "Certificate is valid from %s to %s", buffer,
ctime( &validTo ) );
}
if( certType == CRYPT_CERTTYPE_OCSP_RESPONSE )
{
char tuBuffer[ 50 ], nuBuffer[ 50 ];
time_t timeStamp;
status = cryptGetAttributeString( certificate, CRYPT_CERTINFO_THISUPDATE,
&timeStamp, &length );
if( cryptStatusOK( status ) )
{
/* RTCS basic responses only return a minimal valid/not valid
status, so failing to find a time isn't an error */
strcpy( tuBuffer, ctime( &timeStamp ) );
tuBuffer[ strlen( tuBuffer ) - 1 ] = '\0'; /* Stomp '\n' */
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_NEXTUPDATE,
&timeStamp, &length );
if( cryptStatusOK( status ) )
{
strcpy( nuBuffer, ctime( &timeStamp ) );
nuBuffer[ strlen( nuBuffer ) - 1 ] = '\0'; /* Stomp '\n' */
printf( "OCSP source CRL time %s,\n next update %s.\n", tuBuffer,
nuBuffer );
}
else
printf( "OCSP source CRL time %s.\n", tuBuffer );
}
}
if( certType == CRYPT_CERTTYPE_CRL )
{
char tuBuffer[ 50 ], nuBuffer[ 50 ];
time_t timeStamp;
CHK( cryptGetAttributeString( certificate, CRYPT_CERTINFO_THISUPDATE,
&timeStamp, &length ) );
strcpy( tuBuffer, ctime( &timeStamp ) );
tuBuffer[ strlen( tuBuffer ) - 1 ] = '\0'; /* Stomp '\n' */
status = cryptGetAttributeString( certificate, CRYPT_CERTINFO_NEXTUPDATE,
&timeStamp, &length );
if( cryptStatusOK( status ) )
{
strcpy( nuBuffer, ctime( &timeStamp ) );
nuBuffer[ strlen( nuBuffer ) - 1 ] = '\0'; /* Stomp '\n' */
printf( "CRL time %s,\n next update %s.\n", tuBuffer, nuBuffer );
}
else
printf( "CRL time %s.\n", tuBuffer );
}
if( certType == CRYPT_CERTTYPE_CRL || \
certType == CRYPT_CERTTYPE_RTCS_RESPONSE || \
certType == CRYPT_CERTTYPE_OCSP_RESPONSE )
{
int noEntries = 0;
/* Count and display the entries */
if( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_CERTIFICATE,
CRYPT_CURSOR_FIRST ) == CRYPT_OK )
{
puts( "Revocation/validity list information: " );
do
{
char timeBuffer[ 50 ];
time_t timeStamp;
int revStatus, certStatus;
noEntries++;
/* Extract response-specific status information */
if( certType == CRYPT_CERTTYPE_RTCS_RESPONSE )
{
CHK( cryptGetAttribute( certificate,
CRYPT_CERTINFO_CERTSTATUS, &certStatus ) );
}
if( certType == CRYPT_CERTTYPE_OCSP_RESPONSE )
{
CHK( cryptGetAttribute( certificate,
CRYPT_CERTINFO_REVOCATIONSTATUS, &revStatus ) );
}
if( certType == CRYPT_CERTTYPE_CRL || \
( certType == CRYPT_CERTTYPE_OCSP_RESPONSE && \
revStatus == CRYPT_OCSPSTATUS_REVOKED ) || \
( certType == CRYPT_CERTTYPE_RTCS_RESPONSE && \
certStatus == CRYPT_CERTSTATUS_NOTVALID ) )
{
CHK( cryptGetAttributeString( certificate,
CRYPT_CERTINFO_REVOCATIONDATE, &timeStamp,
&length ) );
strcpy( timeBuffer, ctime( &timeStamp ) );
timeBuffer[ strlen( timeBuffer ) - 1 ] = '\0'; /* Stomp '\n' */
}
else
strcpy( timeBuffer, "<None>" );
/* Make sure we don't print excessive amounts of
information */
if( noEntries >= 20 )
{
if( noEntries == 20 )
puts( " (Further entries exist, but won't be printed)." );
continue;
}
/* Print details status info */
switch( certType )
{
case CRYPT_CERTTYPE_RTCS_RESPONSE:
printf( " Certificate status = %d (%s).\n",
certStatus,
( certStatus == CRYPT_CERTSTATUS_VALID ) ? \
"valid" : \
( certStatus == CRYPT_CERTSTATUS_NOTVALID ) ? \
"not valid" : \
( certStatus == CRYPT_CERTSTATUS_NONAUTHORITATIVE ) ? \
"only non-authoritative response available" : \
"unknown" );
break;
case CRYPT_CERTTYPE_OCSP_RESPONSE:
printf( " Entry %d, rev.status = %d (%s), rev.time "
"%s.\n", noEntries, revStatus,
( revStatus == CRYPT_OCSPSTATUS_NOTREVOKED ) ? \
"not revoked" : \
( revStatus == CRYPT_OCSPSTATUS_REVOKED ) ? \
"revoked" : "unknown",
timeBuffer );
break;
case CRYPT_CERTTYPE_CRL:
printf( " Entry %d, revocation time %s.\n", noEntries,
timeBuffer );
break;
default:
assert( 0 );
}
}
while( cryptSetAttribute( certificate,
CRYPT_CERTINFO_CURRENT_CERTIFICATE,
CRYPT_CURSOR_NEXT ) == CRYPT_OK );
}
printf( "Revocation/validity list has %d entr%s.\n", noEntries,
( noEntries == 1 ) ? "y" : "ies" );
}
/* Display the self-signed status and fingerprint */
if( cryptStatusOK( cryptGetAttribute( certificate,
CRYPT_CERTINFO_SELFSIGNED, &value ) ) )
printf( "Certificate object is %sself-signed.\n",
value ? "" : "not " );
if( certType == CRYPT_CERTTYPE_CERTIFICATE || \
certType == CRYPT_CERTTYPE_CERTCHAIN )
{
CHK( cryptGetAttributeString( certificate, CRYPT_CERTINFO_FINGERPRINT,
buffer, &length ) );
printf( "Certificate fingerprint = " );
printHex( buffer, length );
}
/* List the attribute types */
puts( "Certificate extension/attribute types present (by cryptlib ID) "
"are:" );
if( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_EXTENSION,
CRYPT_CURSOR_FIRST ) == CRYPT_OK )
do
{
hasExtensions = TRUE;
cryptGetAttribute( certificate, CRYPT_CERTINFO_CURRENT_EXTENSION,
&value );
printf( " Extension type = %d.\n", value );
}
while( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_EXTENSION,
CRYPT_CURSOR_NEXT ) == CRYPT_OK );
/* Display common attributes */
if( !hasExtensions )
{
puts( " (No extensions/attributes)." );
return( TRUE );
}
puts( "Some of the common extensions/attributes are:" );
if( certType == CRYPT_CERTTYPE_CRL )
{
time_t theTime;
CHK( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_EXTENSION,
CRYPT_CURSOR_FIRST ) );
status = cryptGetAttribute( certificate, CRYPT_CERTINFO_CRLNUMBER,
&value );
if( cryptStatusOK( status ) && value )
printf( " crlNumber = %d.\n", value );
status = cryptGetAttribute( certificate, CRYPT_CERTINFO_DELTACRLINDICATOR,
&value );
if( cryptStatusOK( status ) && value )
printf( " deltaCRLIndicator = %d.\n", value );
status = cryptGetAttribute( certificate, CRYPT_CERTINFO_CRLREASON,
&value );
if( cryptStatusOK( status ) && value )
printf( " crlReason = %d.\n", value );
status = cryptGetAttributeString( certificate,
CRYPT_CERTINFO_INVALIDITYDATE, &theTime, &length );
if( cryptStatusOK( status ) )
printf( " invalidityDate = %s", ctime( &theTime ) );
if( cryptStatusOK( \
cryptGetAttribute( certificate,
CRYPT_CERTINFO_ISSUINGDIST_FULLNAME, &value ) ) )
{
CHK( cryptSetAttribute( certificate, CRYPT_CERTINFO_CURRENT_FIELD,
CRYPT_CERTINFO_ISSUINGDIST_FULLNAME ) );
puts( " issuingDistributionPoint is:" );
printDN( certificate );
printAltName( certificate );
}
return( TRUE );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -