📄 utils.c
字号:
"value '%s', failed with error code %d, line %d.\n",
certData[ i ].type, certData[ i ].stringValue,
status, __LINE__ );
break;
#endif /* HAS_WIDECHAR */
case IS_TIME:
status = cryptSetAttributeString( certificate,
certData[ i ].type, &certData[ i ].timeValue,
sizeof( time_t ) );
if( cryptStatusError( status ) )
printf( "cryptSetAttributeString() for field ID %d,\n"
"value 0x%lX, failed with error code %d, line %d.\n",
certData[ i ].type, certData[ i ].timeValue,
status, __LINE__ );
break;
default:
assert( FALSE );
return( FALSE );
}
if( cryptStatusError( status ) )
{
printErrorAttributeInfo( certificate );
return( FALSE );
}
}
return( TRUE );
}
/* Populate a key database with the contents of a directory. This is a
rather OS-specific utility function for setting up test databases that
only works under Win32 (in fact it's not used at all at the moment) */
#if defined( _MSC_VER ) && defined( _WIN32 ) && !defined( _WIN32_WCE ) && 0
void loadCertificates( void )
{
WIN32_FIND_DATA findData;
HANDLE searchHandle;
searchHandle = FindFirstFile( "d:/tmp/certs/*.der", &findData );
if( searchHandle == INVALID_HANDLE_VALUE )
return;
do
{
CRYPT_CERTIFICATE cryptCert;
int status;
printf( "Adding cert %s.\n", findData.cFileName );
status = importCertFile( &cryptCert, findData.cFileName );
if( cryptStatusOK( status ) )
{
cryptDestroyCert( cryptCert );
}
}
while( FindNextFile( searchHandle, &findData ) );
FindClose( searchHandle );
}
#endif /* Win32 */
/****************************************************************************
* *
* Debug Functions *
* *
****************************************************************************/
/* Write an object to a file for debugging purposes */
#if defined( _MSC_VER ) && \
!( defined( _WIN32_WCE ) || defined( __PALMSOURCE__ ) )
#include <direct.h>
#include <io.h>
#endif /* VC++ Win16/Win32 */
void debugDump( const char *fileName, const void *data, const int dataLength )
{
FILE *filePtr;
#ifdef __UNIX__
const char *tmpPath = getenv( "TMPDIR" );
char fileNameBuffer[ FILENAME_BUFFER_SIZE ];
const int tmpPathLen = ( tmpPath != NULL ) ? strlen( tmpPath ) : 0;
#else
char fileNameBuffer[ 128 ];
#endif /* __UNIX__ */
const int length = strlen( fileName );
#if defined( _WIN32_WCE )
/* Under WinCE we don't want to scribble a ton of data into flash every
time we're run, so we don't try and do anything */
return;
#elif ( defined( _MSC_VER ) && !defined( __PALMSOURCE__ ) )
if( access( "d:/tmp/", 6 ) == 0 )
{
/* There's a data partition available, dump the info there */
if( access( "d:/tmp/", 6 ) == -1 && mkdir( "d:/tmp" ) == -1 )
return;
strcpy( fileNameBuffer, "d:/tmp/" );
}
else
{
/* There's no separate data partition, everything's dumped into the
same partition */
if( access( "c:/tmp/", 6 ) == -1 && mkdir( "c:/tmp" ) == -1 )
return;
strcpy( fileNameBuffer, "c:/tmp/" );
}
#elif defined( __UNIX__ )
if( tmpPathLen > 3 && tmpPathLen < 768 )
{
strcpy( fileNameBuffer, tmpPath );
if( fileNameBuffer[ tmpPathLen - 1 ] != '/' )
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 );
}
/****************************************************************************
* *
* Session Functions *
* *
****************************************************************************/
/* Print information on the peer that we're talking to */
int printConnectInfo( const CRYPT_SESSION cryptSession )
{
#ifndef UNICODE_STRINGS
time_t theTime;
#endif /* UNICODE_STRINGS */
C_CHR serverName[ 128 ];
int serverNameLength, serverPort, status;
status = cryptGetAttributeString( cryptSession, CRYPT_SESSINFO_CLIENT_NAME,
serverName, &serverNameLength );
if( cryptStatusError( status ) )
return( FALSE );
cryptGetAttribute( cryptSession, CRYPT_SESSINFO_CLIENT_PORT, &serverPort );
#ifdef UNICODE_STRINGS
serverName[ serverNameLength / sizeof( wchar_t ) ] = TEXT( '\0' );
printf( "SVR: Connect attempt from %S, port %d", serverName, serverPort );
#else
serverName[ serverNameLength ] = '\0';
time( &theTime );
printf( "SVR: Connect attempt from %s, port %d, on %s", serverName,
serverPort, ctime( &theTime ) );
#endif /* UNICODE_STRINGS */
/* Display all the attributes that we've got */
return( displayAttributes( cryptSession ) );
}
/* Print security info for the session */
int printSecurityInfo( const CRYPT_SESSION cryptSession,
const BOOLEAN isServer,
const BOOLEAN showFingerprint )
{
BYTE fingerPrint[ CRYPT_MAX_HASHSIZE ];
int cryptAlgo, keySize, version, length, i, status;
/* Print general security info */
status = cryptGetAttribute( cryptSession, CRYPT_CTXINFO_ALGO,
&cryptAlgo );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptSession, CRYPT_CTXINFO_KEYSIZE,
&keySize );
if( cryptStatusOK( status ) )
status = cryptGetAttribute( cryptSession, CRYPT_SESSINFO_VERSION,
&version );
if( cryptStatusError( status ) )
{
printf( "Couldn't get session security parameters, status %d, line "
"%d.\n", status, __LINE__ );
return( FALSE );
}
printf( "%sSession is protected using algorithm %d with a %d bit key,\n"
" protocol version %d.\n", isServer ? "SVR: " : "",
cryptAlgo, keySize * 8, version );
if( isServer || !showFingerprint )
return( TRUE );
/* Print the server key fingerprint */
status = cryptGetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_FINGERPRINT,
fingerPrint, &length );
if( cryptStatusError( status ) )
{
printf( "cryptGetAttributeString() failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
printf( "%sServer key fingerprint =", isServer ? "SVR: " : "" );
for( i = 0; i < length; i++ )
printf( " %02X", fingerPrint[ i ] );
puts( "." );
return( TRUE );
}
/* Set up a client/server to connect locally. For the client his simply
tells it where to connect, for the server this binds it to the local
address so we don't inadvertently open up outside ports (admittedly
they can't do much except run the hardcoded self-test, but it's better
not to do this at all) */
BOOLEAN setLocalConnect( const CRYPT_SESSION cryptSession, const int port )
{
int status;
status = cryptSetAttributeString( cryptSession,
CRYPT_SESSINFO_SERVER_NAME,
TEXT( "localhost" ),
paramStrlen( TEXT( "localhost" ) ) );
#ifdef __UNIX__
/* If we're running under Unix, set the port to a nonprivileged one so
we don't have to run as root. For anything other than very low-
numbered ports (e.g. SSH), the way we determine the port is to repeat
the first digit, so e.g. TSA on 318 becomes 3318, this seems to be
the method most commonly used */
if( cryptStatusOK( status ) && port < 1024 )
{
if( port < 100 )
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_SERVER_PORT,
port + 4000 );
else
status = cryptSetAttribute( cryptSession, CRYPT_SESSINFO_SERVER_PORT,
( ( port / 100 ) * 1000 ) + port );
}
#endif /* __UNIX__ */
if( cryptStatusError( status ) )
{
printf( "cryptSetAttribute/AttributeString() failed with error code "
"%d, line %d.\n", status, __LINE__ );
return( FALSE );
}
return( TRUE );
}
/****************************************************************************
* *
* Attribute Dump Routines *
* *
****************************************************************************/
/* Print a list of all attributes present in an object */
int displayAttributes( const CRYPT_HANDLE cryptHandle )
{
int status;
if( cryptStatusError( \
cryptSetAttribute( cryptHandle, CRYPT_ATTRIBUTE_CURRENT_GROUP,
CRYPT_CURSOR_FIRST ) ) )
{
puts( " (No attributes present)." );
return( TRUE );
}
puts( "Attributes present (by cryptlib ID) are:" );
do
{
BOOLEAN firstAttr = TRUE;
int value;
status = cryptGetAttribute( cryptHandle,
CRYPT_ATTRIBUTE_CURRENT_GROUP, &value );
if( cryptStatusError( status ) )
{
printf( "\nCurrent attribute group value read failed with "
"error code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
printf( " Attribute group %d, values =", value );
do
{
status = cryptGetAttribute( cryptHandle, CRYPT_ATTRIBUTE_CURRENT,
&value );
if( cryptStatusError( status ) )
{
printf( "\nCurrent attribute value read failed with error "
"code %d, line %d.\n", status, __LINE__ );
return( FALSE );
}
if( !firstAttr )
putchar( ',' );
printf( " %d", value );
firstAttr = FALSE;
}
while( cryptSetAttribute( cryptHandle, CRYPT_ATTRIBUTE_CURRENT,
CRYPT_CURSOR_NEXT ) == CRYPT_OK );
puts( "." );
}
while( cryptSetAttribute( cryptHandle, CRYPT_ATTRIBUTE_CURRENT_GROUP,
CRYPT_CURSOR_NEXT ) == CRYPT_OK );
/* Reset the cursor to the first attribute. This is useful for things
like envelopes and sessions where the cursor points at the first
attribute that needs to be handled */
cryptSetAttribute( cryptHandle, CRYPT_ATTRIBUTE_CURRENT_GROUP,
CRYPT_CURSOR_FIRST );
return( TRUE );
}
/****************************************************************************
* *
* 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 )
printf( " " );
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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -