📄 pkcs11_init.c
字号:
to be v1 even though it might work in practice */
pC_GetFunctionList = ( CK_C_GetFunctionList ) \
DynamicBind( pkcs11Info->hPKCS11, "C_GetFunctionList" );
if( pC_GetFunctionList == NULL )
status = CKR_GENERAL_ERROR;
else
status = pC_GetFunctionList( &pkcs11Info->functionListPtr ) & 0xFFFF;
if( status != CKR_OK )
{
/* Free the library reference and clear the info */
DynamicUnload( pkcs11Info->hPKCS11 );
memset( pkcs11Info, 0, sizeof( PKCS11_DRIVER_INFO ) );
return( CRYPT_ERROR );
}
status = C_Initialize( NULL_PTR ) & 0xFFFF;
if( status == CKR_OK || status == CKR_CRYPTOKI_ALREADY_INITIALIZED )
{
isInitialised = TRUE;
status = C_GetInfo( &info ) & 0xFFFF;
if( status == CKR_OK && info.cryptokiVersion.major <= 1 )
{
/* It's v1, we can't work with it */
status = CKR_FUNCTION_NOT_SUPPORTED;
}
}
if( status != CKR_OK )
{
if( isInitialised )
C_Finalize( NULL_PTR );
DynamicUnload( pkcs11Info->hPKCS11 );
memset( pkcs11Info, 0, sizeof( PKCS11_DRIVER_INFO ) );
return( CRYPT_ERROR );
}
#endif /* USE_EXPLICIT_LINKING */
/* Copy out the device driver's name so that the user can access it by
name. Some vendors erroneously null-terminate the string so we check
for nulls as well */
memcpy( pkcs11Info->name, info.libraryDescription, 32 );
while( i > 0 && ( pkcs11Info->name[ i - 1 ] == ' ' || \
!pkcs11Info->name[ i - 1 ] ) )
i--;
pkcs11Info->name[ i ] = '\0';
return( CRYPT_OK );
}
void deviceEndPKCS11( void )
{
int i;
if( pkcs11Initialised )
for( i = 0; i < MAX_PKCS11_DRIVERS; i++ )
{
if( pkcs11InfoTbl[ i ].hPKCS11 != NULL_INSTANCE )
{
#ifdef USE_EXPLICIT_LINKING
pkcs11InfoTbl[ i ].pC_Finalize( NULL_PTR );
#else
PKCS11_DRIVER_INFO *pkcs11Info = &pkcs11InfoTbl[ i ];
C_Finalize( NULL_PTR );
#endif /* USE_EXPLICIT_LINKING */
DynamicUnload( pkcs11InfoTbl[ i ].hPKCS11 );
}
pkcs11InfoTbl[ i ].hPKCS11 = NULL_INSTANCE;
}
pkcs11Initialised = FALSE;
}
int deviceInitPKCS11( void )
{
int tblIndex = 0, optionIndex;
/* If we've previously tried to init the drivers, don't try it again */
if( pkcs11Initialised )
return( CRYPT_OK );
memset( pkcs11InfoTbl, 0, sizeof( pkcs11InfoTbl ) );
/* Try and link in each driver specified in the config options. Since
this is a general systemwide config option, we always query the built-
in default user object */
for( optionIndex = 0; optionIndex < MAX_PKCS11_DRIVERS; optionIndex++ )
{
MESSAGE_DATA msgData;
char deviceDriverName[ MAX_PATH_LENGTH + 1 + 8 ];
int status;
setMessageData( &msgData, deviceDriverName, MAX_PATH_LENGTH );
status = krnlSendMessage( DEFAULTUSER_OBJECT_HANDLE,
IMESSAGE_GETATTRIBUTE_S, &msgData,
optionIndex + CRYPT_OPTION_DEVICE_PKCS11_DVR01 );
if( cryptStatusError( status ) )
continue;
deviceDriverName[ msgData.length ] = '\0';
status = loadPKCS11driver( &pkcs11InfoTbl[ tblIndex ],
deviceDriverName );
if( cryptStatusOK( status ) )
{
tblIndex++;
pkcs11Initialised = TRUE;
}
}
/* If it's a Unix system and there were no drivers explicitly specified,
try with the default driver name "libpkcs11.so". Unlike Windows,
where there are large numbers of PKCS #11 vendors and we have to use
vendor-specific names, under Unix there are very few vendors and
there's usually only one device/driver in use which inevitably
co-opts /usr/lib for its own use, so we can always try for a standard
name and location.
As a backup measure, we try for the nCipher PKCS #11 driver, which is
by far the most commonly used one on Unix systems (this may sometimes
be found as /usr/lib/libcknfast.so) */
#ifdef UNIX
if( !pkcs11Initialised )
{
status = loadPKCS11driver( &pkcs11InfoTbl[ tblIndex ],
"libpkcs11.so" );
if( cryptStatusOK( status ) )
pkcs11Initialised = TRUE;
}
if( !pkcs11Initialised )
{
status = loadPKCS11driver( &pkcs11InfoTbl[ tblIndex ],
"/opt/nfast/toolkits/pkcs11/libcknfast.so" );
if( cryptStatusOK( status ) )
pkcs11Initialised = TRUE;
}
#endif /* UNIX */
return( pkcs11Initialised ? CRYPT_OK : CRYPT_ERROR );
}
#else
int deviceInitPKCS11( void )
{
int status;
/* If we've previously tried to init the drivers, don't try it again */
if( pkcs11Initialised )
return( CRYPT_OK );
status = C_Initialize( NULL_PTR );
if( status != CKR_OK && status != CKR_CRYPTOKI_ALREADY_INITIALIZED )
return( CRYPT_ERROR );
pkcs11Initialised = TRUE;
return( CRYPT_OK );
}
void deviceEndPKCS11( void )
{
if( pkcs11Initialised )
C_Finalize( NULL_PTR );
pkcs11Initialised = FALSE;
}
#endif /* DYNAMIC_LOAD */
/****************************************************************************
* *
* Device Capability Routines *
* *
****************************************************************************/
/* The reported key size for PKCS #11 implementations is rather inconsistent,
most are reported in bits, a number don't return a useful value, and a few
are reported in bytes. The following macros sort out which algorithms
have valid key size info and which report the length in bytes */
#define keysizeValid( algo ) \
( ( algo ) == CRYPT_ALGO_DH || ( algo ) == CRYPT_ALGO_RSA || \
( algo ) == CRYPT_ALGO_DSA || ( algo ) == CRYPT_ALGO_RC2 || \
( algo ) == CRYPT_ALGO_RC4 || ( algo ) == CRYPT_ALGO_RC5 || \
( algo ) == CRYPT_ALGO_CAST )
#define keysizeInBytes( algo ) \
( ( algo ) == CRYPT_ALGO_RC5 || ( algo ) == CRYPT_ALGO_CAST )
/* Templates for the various capabilities. These contain only basic
information, the remaining fields are filled in when the capability is
set up */
static CAPABILITY_INFO FAR_BSS capabilityTemplates[] = {
/* Encryption capabilities */
{ CRYPT_ALGO_DES, bitsToBytes( 64 ), "DES", 3,
MIN_KEYSIZE, bitsToBytes( 64 ), bitsToBytes( 64 ) },
{ CRYPT_ALGO_3DES, bitsToBytes( 64 ), "3DES", 4,
bitsToBytes( 64 + 8 ), bitsToBytes( 128 ), bitsToBytes( 192 ) },
#ifdef USE_IDEA
{ CRYPT_ALGO_IDEA, bitsToBytes( 64 ), "IDEA", 4,
MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 128 ) },
#endif /* USE_IDEA */
#ifdef USE_CAST
{ CRYPT_ALGO_CAST, bitsToBytes( 64 ), "CAST-128", 8,
MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 128 ) },
#endif /* USE_CAST */
#ifdef USE_RC2
{ CRYPT_ALGO_RC2, bitsToBytes( 64 ), "RC2", 3,
MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 1024 ) },
#endif /* USE_RC2 */
#ifdef USE_RC4
{ CRYPT_ALGO_RC4, bitsToBytes( 8 ), "RC4", 3,
MIN_KEYSIZE, bitsToBytes( 128 ), 256 },
#endif /* USE_RC4 */
#ifdef USE_RC5
{ CRYPT_ALGO_RC5, bitsToBytes( 64 ), "RC5", 3,
MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 832 ) },
#endif /* USE_RC5 */
{ CRYPT_ALGO_AES, bitsToBytes( 128 ), "AES", 3,
bitsToBytes( 128 ), bitsToBytes( 128 ), bitsToBytes( 256 ) },
#ifdef USE_BLOWFISH
{ CRYPT_ALGO_BLOWFISH, bitsToBytes( 64 ), "Blowfish", 8,
MIN_KEYSIZE, bitsToBytes( 128 ), bitsToBytes( 448 ) },
#endif /* USE_BLOWFISH */
#ifdef USE_SKIPJACK
{ CRYPT_ALGO_SKIPJACK, bitsToBytes( 64 ), "Skipjack", 8,
bitsToBytes( 80 ), bitsToBytes( 80 ), bitsToBytes( 80 ) },
#endif /* USE_SKIPJACK */
/* Hash capabilities */
#ifdef USE_MD2
{ CRYPT_ALGO_MD2, bitsToBytes( 128 ), "MD2", 3,
bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#endif /* USE_MD2 */
#ifdef USE_MD5
{ CRYPT_ALGO_MD5, bitsToBytes( 128 ), "MD5", 3,
bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#endif /* USE_MD2 */
{ CRYPT_ALGO_SHA1, bitsToBytes( 160 ), "SHA1", 3,
bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#ifdef USE_SHA2
{ CRYPT_ALGO_SHA2, bitsToBytes( 256 ), "SHA2", 4,
bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ) },
#endif /* USE_SHA2 */
/* MAC capabilities */
#ifdef USE_HMAC_MD5
{ CRYPT_ALGO_HMAC_MD5, bitsToBytes( 128 ), "HMAC-MD5", 8,
bitsToBytes( 64 ), bitsToBytes( 128 ), CRYPT_MAX_KEYSIZE },
#endif /* USE_HMAC_MD5 */
{ CRYPT_ALGO_HMAC_SHA, bitsToBytes( 160 ), "HMAC-SHA", 8,
bitsToBytes( 64 ), bitsToBytes( 128 ), CRYPT_MAX_KEYSIZE },
#ifdef USE_HMAC_RIPEMD160
{ CRYPT_ALGO_HMAC_RIPEMD160, bitsToBytes( 160 ), "HMAC-RIPEMD160", 14,
bitsToBytes( 64 ), bitsToBytes( 128 ), CRYPT_MAX_KEYSIZE },
#endif /* USE_HMAC_RIPEMD160 */
/* Public-key capabilities */
#ifdef USE_DH
{ CRYPT_ALGO_DH, bitsToBytes( 0 ), "Diffie-Hellman", 14,
MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE },
#endif /* USE_DH */
{ CRYPT_ALGO_RSA, bitsToBytes( 0 ), "RSA", 3,
MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE },
#ifdef USE_DSA
{ CRYPT_ALGO_DSA, bitsToBytes( 0 ), "DSA", 3,
MIN_PKCSIZE, bitsToBytes( 1024 ), CRYPT_MAX_PKCSIZE },
#endif /* USE_DSA */
/* Hier ist der Mast zu ende */
{ CRYPT_ERROR }, { CRYPT_ERROR }
};
/* Query a given capability for a device and fill out a capability info
record for it if present */
static CAPABILITY_INFO *getCapability( const DEVICE_INFO *deviceInfo,
const PKCS11_MECHANISM_INFO *mechanismInfoPtr,
const int maxMechanisms )
{
VARIABLE_CAPABILITY_INFO *capabilityInfo;
CK_MECHANISM_INFO pMechanism;
CK_RV status;
const CRYPT_ALGO_TYPE cryptAlgo = mechanismInfoPtr->cryptAlgo;
const BOOLEAN isPKC = ( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
cryptAlgo <= CRYPT_ALGO_LAST_PKC ) ? TRUE : FALSE;
const CK_FLAGS keyGenFlag = isPKC ? CKF_GENERATE_KEY_PAIR : CKF_GENERATE;
PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
int hardwareOnly, i, iterationCount;
assert( isReadPtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
assert( isReadPtr( mechanismInfoPtr, \
maxMechanisms * sizeof( PKCS11_MECHANISM_INFO ) ) );
/* Get the information for this mechanism. Since many PKCS #11 drivers
implement some of their capabilities using God knows what sort of
software implementation, we provide the option to skip emulated
mechanisms if required */
status = C_GetMechanismInfo( pkcs11Info->slotID,
mechanismInfoPtr->mechanism,
&pMechanism );
if( status != CKR_OK )
return( NULL );
krnlSendMessage( deviceInfo->ownerHandle, IMESSAGE_GETATTRIBUTE,
&hardwareOnly, CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY );
if( hardwareOnly && !( pMechanism.flags & CKF_HW ) )
return( NULL );
/* Copy across the template for this capability */
if( ( capabilityInfo = clAlloc( "getCapability", \
sizeof( CAPABILITY_INFO ) ) ) == NULL )
return( NULL );
for( i = 0; capabilityTemplates[ i ].cryptAlgo != cryptAlgo && \
capabilityTemplates[ i ].cryptAlgo != CRYPT_ERROR && \
i < FAILSAFE_ARRAYSIZE( capabilityTemplates, CAPABILITY_INFO );
i++ );
if( i >= FAILSAFE_ARRAYSIZE( capabilityTemplates, CAPABILITY_INFO ) || \
capabilityTemplates[ i ].cryptAlgo == CRYPT_ERROR )
retIntError_Null();
memcpy( capabilityInfo, &capabilityTemplates[ i ],
sizeof( CAPABILITY_INFO ) );
/* Set up the keysize information if there's anything useful available */
if( keysizeValid( cryptAlgo ) )
{
int minKeySize = ( int ) pMechanism.ulMinKeySize;
int maxKeySize = ( int ) pMechanism.ulMaxKeySize;
/* Adjust the key size to bytes and make sure that all values are
consistent. Some implementations report silly lower bounds (e.g.
1-bit RSA, "You naughty minKey") so we adjust them to a sane value
if necessary. We also limit the maximum key size to match the
cryptlib native max.key size, both for consistency and because
cryptlib performs buffer allocation based on the maximum native
buffer size */
if( !keysizeInBytes( cryptAlgo ) )
{
minKeySize = bitsToBytes( minKeySize );
maxKeySize = bitsToBytes( maxKeySize );
}
if( minKeySize > capabilityInfo->minKeySize )
capabilityInfo->minKeySize = minKeySize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -