📄 testlib.c
字号:
/****************************************************************************
* *
* cryptlib Test Code *
* Copyright Peter Gutmann 1995-2007 *
* *
****************************************************************************/
#include "cryptlib.h"
#include "test/test.h"
#if defined( __MVS__ ) || defined( __VMCMS__ )
/* Suspend conversion of literals to ASCII. */
#pragma convlit( suspend )
#endif /* IBM big iron */
#if defined( __ILEC400__ )
#pragma convert( 0 )
#endif /* IBM medium iron */
/* Optionally include and activate the Visual Leak Detector library if
we're running a debug build under VC++ 6.0. Note that this can't be
run at the same time as Bounds Checker, since the two interefere with
each other */
#if defined( _MSC_VER ) && ( _MSC_VER == 1200 ) && 0
#include "binaries/vld.h"
#endif /* VC++ 6.0 */
/* Optionally include the Intel Thread Checker API to control analysis */
#if defined( _MSC_VER ) && ( _MSC_VER == 1200 ) && 0
#define USE_TCHECK
#include "../../../Intel/VTune/tcheck/Include/libittnotify.h"
#include "../../../Intel/VTune/Analyzer/Include/VtuneApi.h"
#pragma comment( lib, "C:/Program Files/Intel/VTune/Analyzer/Lib/libittnotify.lib" )
#pragma comment( lib, "C:/Program Files/Intel/VTune/Analyzer/Lib/VtuneApi.lib " )
#define THREAD_DEBUG_SUSPEND() __itt_pause(); VTPause()
#define THREAD_DEBUG_RESUME() VTResume(); __itt_resume()
#else
#define THREAD_DEBUG_SUSPEND()
#define THREAD_DEBUG_RESUME()
#endif /* VC++ 6.0 with Intel Thread Checker */
/* Whether various keyset tests worked, the results are used later to test
other routines. We initially set the key read result to TRUE in case the
keyset read tests are never called, so we can still trying reading the
keys in other tests */
int keyReadOK = TRUE, doubleCertOK = FALSE;
#ifdef TEST_CONFIG
/* The names of the configuration options we check for */
static struct {
const CRYPT_ATTRIBUTE_TYPE option; /* Option */
const char FAR_BSS *name; /* Option name */
const BOOLEAN isNumeric; /* Whether it's a numeric option */
} FAR_BSS configOption[] = {
{ CRYPT_OPTION_INFO_DESCRIPTION, "CRYPT_OPTION_INFO_DESCRIPTION", FALSE },
{ CRYPT_OPTION_INFO_COPYRIGHT, "CRYPT_OPTION_INFO_COPYRIGHT", FALSE },
{ CRYPT_OPTION_INFO_MAJORVERSION, "CRYPT_OPTION_INFO_MAJORVERSION", TRUE },
{ CRYPT_OPTION_INFO_MINORVERSION, "CRYPT_OPTION_INFO_MINORVERSION", TRUE },
{ CRYPT_OPTION_INFO_STEPPING, "CRYPT_OPTION_INFO_STEPPING", TRUE },
{ CRYPT_OPTION_ENCR_ALGO, "CRYPT_OPTION_ENCR_ALGO", TRUE },
{ CRYPT_OPTION_ENCR_HASH, "CRYPT_OPTION_ENCR_HASH", TRUE },
{ CRYPT_OPTION_ENCR_MAC, "CRYPT_OPTION_ENCR_MAC", TRUE },
{ CRYPT_OPTION_PKC_ALGO, "CRYPT_OPTION_PKC_ALGO", TRUE },
{ CRYPT_OPTION_PKC_KEYSIZE, "CRYPT_OPTION_PKC_KEYSIZE", TRUE },
{ CRYPT_OPTION_SIG_ALGO, "CRYPT_OPTION_SIG_ALGO", TRUE },
{ CRYPT_OPTION_SIG_KEYSIZE, "CRYPT_OPTION_SIG_KEYSIZE", TRUE },
{ CRYPT_OPTION_KEYING_ALGO, "CRYPT_OPTION_KEYING_ALGO", TRUE },
{ CRYPT_OPTION_KEYING_ITERATIONS, "CRYPT_OPTION_KEYING_ITERATIONS", TRUE },
{ CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES, "CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES", TRUE },
{ CRYPT_OPTION_CERT_VALIDITY, "CRYPT_OPTION_CERT_VALIDITY", TRUE },
{ CRYPT_OPTION_CERT_UPDATEINTERVAL, "CRYPT_OPTION_CERT_UPDATEINTERVAL", TRUE },
{ CRYPT_OPTION_CERT_COMPLIANCELEVEL, "CRYPT_OPTION_CERT_COMPLIANCELEVEL", TRUE },
{ CRYPT_OPTION_CERT_REQUIREPOLICY, "CRYPT_OPTION_CERT_REQUIREPOLICY", TRUE },
{ CRYPT_OPTION_CMS_DEFAULTATTRIBUTES, "CRYPT_OPTION_CMS_DEFAULTATTRIBUTES", TRUE },
{ CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS, "CRYPT_OPTION_KEYS_LDAP_OBJECTCLASS", FALSE },
{ CRYPT_OPTION_KEYS_LDAP_OBJECTTYPE, "CRYPT_OPTION_KEYS_LDAP_OBJECTTYPE", TRUE },
{ CRYPT_OPTION_KEYS_LDAP_FILTER, "CRYPT_OPTION_KEYS_LDAP_FILTER", FALSE },
{ CRYPT_OPTION_KEYS_LDAP_CACERTNAME, "CRYPT_OPTION_KEYS_LDAP_CACERTNAME", FALSE },
{ CRYPT_OPTION_KEYS_LDAP_CERTNAME, "CRYPT_OPTION_KEYS_LDAP_CERTNAME", FALSE },
{ CRYPT_OPTION_KEYS_LDAP_CRLNAME, "CRYPT_OPTION_KEYS_LDAP_CRLNAME", FALSE },
{ CRYPT_OPTION_KEYS_LDAP_EMAILNAME, "CRYPT_OPTION_KEYS_LDAP_EMAILNAME", FALSE },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR01, "CRYPT_OPTION_DEVICE_PKCS11_DVR01", FALSE },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR02, "CRYPT_OPTION_DEVICE_PKCS11_DVR02", FALSE },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR03, "CRYPT_OPTION_DEVICE_PKCS11_DVR03", FALSE },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR04, "CRYPT_OPTION_DEVICE_PKCS11_DVR04", FALSE },
{ CRYPT_OPTION_DEVICE_PKCS11_DVR05, "CRYPT_OPTION_DEVICE_PKCS11_DVR05", FALSE },
{ CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY, "CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY", TRUE },
{ CRYPT_OPTION_NET_SOCKS_SERVER, "CRYPT_OPTION_NET_SOCKS_SERVER", FALSE },
{ CRYPT_OPTION_NET_SOCKS_USERNAME, "CRYPT_OPTION_NET_SOCKS_USERNAME", FALSE },
{ CRYPT_OPTION_NET_HTTP_PROXY, "CRYPT_OPTION_NET_HTTP_PROXY", FALSE },
{ CRYPT_OPTION_NET_CONNECTTIMEOUT, "CRYPT_OPTION_NET_CONNECTTIMEOUT", TRUE },
{ CRYPT_OPTION_NET_READTIMEOUT, "CRYPT_OPTION_NET_READTIMEOUT", TRUE },
{ CRYPT_OPTION_NET_WRITETIMEOUT, "CRYPT_OPTION_NET_WRITETIMEOUT", TRUE },
{ CRYPT_OPTION_MISC_ASYNCINIT, "CRYPT_OPTION_MISC_ASYNCINIT", TRUE },
{ CRYPT_OPTION_MISC_SIDECHANNELPROTECTION, "CRYPT_OPTION_MISC_SIDECHANNELPROTECTION", TRUE },
{ CRYPT_ATTRIBUTE_NONE, NULL, 0 }
};
#endif /* TEST_CONFIG */
/* There are some sizeable (for DOS) data structures used, so we increase the
stack size to allow for them */
#if defined( __MSDOS16__ ) && defined( __TURBOC__ )
extern unsigned _stklen = 16384;
#endif /* __MSDOS16__ && __TURBOC__ */
/* Prototypes for general debug routines used to evaluate problems with certs
and envelopes from other apps */
void xxxCertImport( const char *fileName );
void xxxCertCheck( const char *certFileName, const char *caFileNameOpt );
void xxxDataImport( const char *fileName );
void xxxSignedDataImport( const char *fileName );
void xxxEncryptedDataImport( const char *fileName );
void xxxEnvTest( void );
/* Prototypes for custom key-creation routines */
int createTestKeys( void );
/* Prototype for stress test interface routine */
void smokeTest( void );
/****************************************************************************
* *
* Utility Routines *
* *
****************************************************************************/
/* The tests that use databases and cert stores require that the user set
up a suitable ODBC data source (at least when running under Windows), to
automate this process we try and create the data source if it isn't
present */
#if defined( _MSC_VER ) && defined( _WIN32 ) && !defined( _WIN32_WCE )
#define DATABASE_AUTOCONFIG
#include <odbcinst.h>
#ifdef USE_SQLSERVER
#define DRIVER_NAME TEXT( "SQL Server" )
#define DATABASE_ATTR_NAME "DSN=" DATABASE_KEYSET_NAME_ASCII "#" \
"DESCRIPTION=cryptlib test key database#" \
"Server=localhost#" \
"Database="
#define DATABASE_ATTR_CREATE ""
#define DATABASE_ATTR_TAIL DATABASE_KEYSET_NAME_ASCII "#"
#define CERTSTORE_ATTR_NAME "DSN=" CERTSTORE_KEYSET_NAME_ASCII "#" \
"DESCRIPTION=cryptlib test key database#" \
"Server=localhost#" \
"Database="
#define CERTSTORE_ATTR_CREATE ""
#define CERTSTORE_ATTR_TAIL CERTSTORE_KEYSET_NAME_ASCII "#"
#else
#define DRIVER_NAME TEXT( "Microsoft Access Driver (*.MDB)" )
#define DATABASE_ATTR_NAME "DSN=" DATABASE_KEYSET_NAME_ASCII "#" \
"DESCRIPTION=cryptlib test key database#" \
"DBQ="
#define DATABASE_ATTR_CREATE "DSN=" DATABASE_KEYSET_NAME_ASCII "#" \
"DESCRIPTION=cryptlib test key database#" \
"CREATE_DB="
#define DATABASE_ATTR_TAIL DATABASE_KEYSET_NAME_ASCII ".mdb#"
#define CERTSTORE_ATTR_NAME "DSN=" CERTSTORE_KEYSET_NAME_ASCII "#" \
"DESCRIPTION=cryptlib test key database#" \
"DBQ="
#define CERTSTORE_ATTR_CREATE "DSN=" CERTSTORE_KEYSET_NAME_ASCII "#" \
"DESCRIPTION=cryptlib test key database#" \
"CREATE_DB="
#define CERTSTORE_ATTR_TAIL CERTSTORE_KEYSET_NAME_ASCII ".mdb#"
#endif /* USE_SQLSERVER */
static void buildDBString( char *buffer, const char *attrName,
const char *attrTail, const char *path )
{
const int attrNameSize = strlen( attrName );
const int attrTailSize = strlen( attrTail ) + 1;
const int pathSize = strlen( path );
int dbStringLen, i;
/* Build up the data-source control string */
memcpy( buffer, attrName, attrNameSize + 1 );
memcpy( buffer + attrNameSize, path, pathSize );
if( attrTailSize > 0 )
{
memcpy( buffer + attrNameSize + pathSize, attrTail,
attrTailSize );
}
buffer[ attrNameSize + pathSize + attrTailSize ] = '\0';
/* Finally, convert the strings to the weird embedded-null strings
required by SQLConfigDataSource() */
dbStringLen = strlen( buffer );
for( i = 0; i < dbStringLen; i++ )
if( buffer[ i ] == '#' )
buffer[ i ] = '\0';
}
static BOOLEAN createDatabaseKeyset( const char *keysetName,
const char *nameString,
const char *createString,
const char *trailerString )
{
char tempPathBuffer[ 512 ];
char attrBuffer[ 1024 ];
#ifdef UNICODE_STRINGS
wchar_t wcAttrBuffer[ 1024 ];
#endif /* UNICODE_STRINGS */
int length, status;
if( !( length = GetTempPath( 512, tempPathBuffer ) ) )
{
strcpy( tempPathBuffer, "C:\\Temp\\" );
length = 8;
}
/* Try and create the DSN. For the default Access driver his is a two-
step process, first we create the DSN and then the underlying file
that contains the database. For SQL Server it's simpler, the database
server already exists so all we have to do is create the database */
printf( "Database keyset '%s' not found, attempting to create data "
"source...\n", keysetName );
buildDBString( attrBuffer, nameString, trailerString, tempPathBuffer );
#ifdef UNICODE_STRINGS
mbstowcs( wcAttrBuffer, attrBuffer, strlen( attrBuffer ) + 1 );
status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, DRIVER_NAME,
wcAttrBuffer );
#else
status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, DRIVER_NAME,
attrBuffer );
#endif /* UNICODE_STRINGS */
if( status != 1 )
return( FALSE );
#ifndef USE_SQLSERVER
buildDBString( attrBuffer, createString, trailerString, tempPathBuffer );
#ifdef UNICODE_STRINGS
mbstowcs( wcAttrBuffer, attrBuffer, strlen( attrBuffer ) + 1 );
status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, DRIVER_NAME,
wcAttrBuffer );
#else
status = SQLConfigDataSource( NULL, ODBC_ADD_DSN, DRIVER_NAME,
attrBuffer );
#endif /* UNICODE_STRINGS */
#endif /* !USE_SQLSERVER */
return( ( status == 1 ) ? TRUE : FALSE );
}
static void checkCreateDatabaseKeysets( void )
{
CRYPT_KEYSET cryptKeyset;
int status;
/* Try and open the test keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
CRYPT_KEYSET_ODBC, DATABASE_KEYSET_NAME,
CRYPT_KEYOPT_READONLY );
if( cryptStatusOK( status ) )
cryptKeysetClose( cryptKeyset );
else
{
if( status == CRYPT_ERROR_OPEN )
{
status = createDatabaseKeyset( DATABASE_KEYSET_NAME_ASCII,
DATABASE_ATTR_NAME,
DATABASE_ATTR_CREATE,
DATABASE_ATTR_TAIL );
puts( ( status == TRUE ) ? "Data source creation succeeded." : \
"Data source creation failed.\n\nYou need to create the "
"keyset data source as described in the cryptlib manual\n"
"for the database keyset tests to run." );
}
}
/* Try and open the test cert store. This can return a
CRYPT_ARGERROR_PARAM3 as a normal condition since a freshly-created
database is empty and therefore can't be identified as a cert store
until data is written to it */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED,
CRYPT_KEYSET_ODBC_STORE, CERTSTORE_KEYSET_NAME,
CRYPT_KEYOPT_READONLY );
if( cryptStatusOK( status ) )
cryptKeysetClose( cryptKeyset );
else
{
if( status == CRYPT_ERROR_OPEN )
{
status = createDatabaseKeyset( CERTSTORE_KEYSET_NAME_ASCII,
CERTSTORE_ATTR_NAME,
CERTSTORE_ATTR_CREATE,
CERTSTORE_ATTR_TAIL );
puts( ( status == TRUE ) ? "Data source creation succeeded.\n" : \
"Data source creation failed.\n\nYou need to create the "
"certificate store data source as described in the\n"
"cryptlib manual for the certificate management tests to "
"run.\n" );
}
}
}
#endif /* Win32 with VC++ */
/* Update the cryptlib config file. This code can be used to set the
information required to load PKCS #11 device drivers:
- Set the driver path in the CRYPT_OPTION_DEVICE_PKCS11_DVR01 setting
below.
- Add a call to updateConfig() from somewhere (e.g.the test kludge function).
- Run the test code until it calls updateConfig().
- Remove the updateConfig() call, then run the test code as normal.
The testDevices() call will report the results of trying to use your
driver.
Note that under Windows XP the path name changes from 'WinNT' to just
'Windows' */
static void updateConfig( void )
{
#if 0
const char *driverPath = "c:/winnt/system32/aetpkss1.dll"; /* AET */
const char *driverPath = "c:/winnt/system32/etpkcs11.dll"; /* Aladdin eToken */
const char *driverPath = "c:/winnt/system32/cryst32.dll"; /* Chrysalis */
const char *driverPath = "c:/program files/luna/cryst201.dll"; /* Chrysalis */
const char *driverPath = "c:/winnt/system32/pkcs201n.dll"; /* Datakey */
const char *driverPath = "c:/winnt/system32/dkck201.dll"; /* Datakey (for Entrust) */
const char *driverPath = "c:/winnt/system32/dkck232.dll"; /* Datakey/iKey (NB: buggy, use 201) */
const char *driverPath = "c:/program files/eracom/cprov sw/cryptoki.dll"; /* Eracom (old, OK) */
const char *driverPath = "c:/program files/eracom/cprov runtime/cryptoki.dll"; /* Eracom (new, buggy) */
const char *driverPath = "c:/winnt/system32/sadaptor.dll"; /* Eutron */
const char *driverPath = "c:/winnt/system32/pk2priv.dll"; /* Gemplus */
const char *driverPath = "c:/program files/gemplus/gclib.dll"; /* Gemplus */
const char *driverPath = "c:/winnt/system32/cryptoki.dll"; /* IBM */
const char *driverPath = "c:/winnt/system32/cknfast.dll"; /* nCipher */
const char *driverPath = "/opt/nfast/toolkits/pkcs11/libcknfast.so";/* nCipher under Unix */
const char *driverPath = "/usr/lib/libcknfast.so"; /* nCipher under Unix */
const char *driverPath = "softokn3.dll"; /* Netscape */
const char *driverPath = "c:/winnt/system32/nxpkcs11.dll"; /* Nexus */
const char *driverPath = "c:/winnt/system32/micardoPKCS11.dll"; /* Orga Micardo */
const char *driverPath = "c:/winnt/system32/cryptoki22.dll";/* Rainbow HSM (for USB use Datakey dvr) */
const char *driverPath = "c:/winnt/system32/p11card.dll"; /* Safelayer HSM (for USB use Datakey dvr) */
const char *driverPath = "c:/winnt/system32/slbck.dll"; /* Schlumberger */
const char *driverPath = "c:/winnt/system32/SpyPK11.dll"; /* Spyrus */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -