📄 dev_pk11.c
字号:
/* Instantiate a cert object from a handle */
static int instantiateCert( DEVICE_INFO *deviceInfo,
const CK_OBJECT_HANDLE hCertificate,
CRYPT_CERTIFICATE *iCryptCert,
const BOOLEAN createContext )
{
CK_ATTRIBUTE dataTemplate = \
{ CKA_VALUE, NULL_PTR, 0 };
CK_RV status;
MESSAGE_CREATEOBJECT_INFO createInfo;
BYTE buffer[ MAX_BUFFER_SIZE ], *bufPtr = buffer;
int cryptStatus;
*iCryptCert = CRYPT_ERROR;
/* Fetch the cert data into local memory */
status = C_GetAttributeValue( deviceInfo->deviceHandle, hCertificate,
&dataTemplate, 1 );
if( status == CKR_OK )
{
if( dataTemplate.ulValueLen > MAX_BUFFER_SIZE && \
( bufPtr = malloc( ( size_t ) ( dataTemplate.ulValueLen ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
dataTemplate.pValue = bufPtr;
status = C_GetAttributeValue( deviceInfo->deviceHandle, hCertificate,
&dataTemplate, 1 );
}
if( status != CKR_OK )
{
if( bufPtr != buffer )
free( bufPtr );
return( mapError( deviceInfo, status, CRYPT_ERROR_NOTFOUND ) );
}
/* Import the cert as a cryptlib object */
setMessageCreateObjectIndirectInfo( &createInfo, bufPtr,
dataTemplate.ulValueLen );
createInfo.arg1 = createContext ? CERTFORMAT_NORMAL : CERTFORMAT_DATAONLY;
cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
RESOURCE_IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
&createInfo, OBJECT_TYPE_CERTIFICATE );
if( bufPtr != buffer )
free( bufPtr );
if( cryptStatusOK( cryptStatus ) )
*iCryptCert = createInfo.cryptHandle;
return( cryptStatus );
}
/* Find a certificate object based on various search criteria:
- Find cert matching the ID of an object hObject - certFromObject()
- Find cert matching a supplied template - certFromTemplate()
- Find cert matching a given ID - certFromID()
- Find cert matching a given label - certFromLabel()
- Find any X.509 cert - certFromLabel().
These are general-purpose functions whose behaviour can be modified through
the following action codes */
typedef enum {
FINDCERT_NORMAL, /* Instantiate standard cert+context */
FINDCERT_DATAONLY, /* Instantiate data-only cert */
FINDCERT_P11OBJECT /* Return handle to PKCS #11 object */
} FINDCERT_ACTION;
static int findCertFromID( DEVICE_INFO *deviceInfo,
const void *certID,
const int certIDlength,
CRYPT_CERTIFICATE *iCryptCert,
const FINDCERT_ACTION findAction )
{
static const CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
static const CK_CERTIFICATE_TYPE certType = CKC_X_509;
CK_ATTRIBUTE certTemplate[] = {
{ CKA_CLASS, ( CK_VOID_PTR ) &certClass, sizeof( CK_OBJECT_CLASS ) },
{ CKA_CERTIFICATE_TYPE, ( CK_VOID_PTR ) &certType, sizeof( CK_CERTIFICATE_TYPE ) },
{ CKA_ID, ( CK_VOID_PTR ) certID, certIDlength }
};
CK_OBJECT_HANDLE hCertificate;
int cryptStatus;
*iCryptCert = CRYPT_ERROR;
/* Try and find the cert with the given ID */
cryptStatus = findObject( deviceInfo, &hCertificate, certTemplate, 3 );
if( cryptStatusError( cryptStatus ) )
return( cryptStatus );
if( findAction == FINDCERT_P11OBJECT )
{
*iCryptCert = hCertificate;
return( CRYPT_OK );
}
return( instantiateCert( deviceInfo, hCertificate, iCryptCert,
( findAction == FINDCERT_NORMAL ) ? \
TRUE : FALSE ) );
}
static int findCertFromObject( DEVICE_INFO *deviceInfo,
const CK_OBJECT_HANDLE hObject,
CRYPT_CERTIFICATE *iCryptCert,
const FINDCERT_ACTION findAction )
{
static const CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
static const CK_CERTIFICATE_TYPE certType = CKC_X_509;
CK_ATTRIBUTE certTemplate[] = {
{ CKA_CLASS, ( CK_VOID_PTR ) &certClass, sizeof( CK_OBJECT_CLASS ) },
{ CKA_CERTIFICATE_TYPE, ( CK_VOID_PTR ) &certType, sizeof( CK_CERTIFICATE_TYPE ) },
{ CKA_ID, NULL, 0 }
};
CK_ATTRIBUTE idTemplate = \
{ CKA_ID, NULL_PTR, 0 };
CK_RV status;
BYTE buffer[ MAX_BUFFER_SIZE ], *bufPtr = buffer;
int cryptStatus;
*iCryptCert = CRYPT_ERROR;
/* We're looking for a cert whose ID matches the object, read the key ID
from the device */
status = C_GetAttributeValue( deviceInfo->deviceHandle, hObject,
&idTemplate, 1 );
if( status == CKR_OK )
{
if( idTemplate.ulValueLen > MAX_BUFFER_SIZE && \
( bufPtr = malloc( ( size_t ) ( idTemplate.ulValueLen ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
idTemplate.pValue = bufPtr;
status = C_GetAttributeValue( deviceInfo->deviceHandle, hObject,
&idTemplate, 1 );
}
if( status != CKR_OK )
{
if( bufPtr != buffer )
free( bufPtr );
return( mapError( deviceInfo, status, CRYPT_ERROR_NOTFOUND ) );
}
/* Look for a certificate with the same ID as the key */
cryptStatus = findCertFromID( deviceInfo, bufPtr,
idTemplate.ulValueLen, iCryptCert,
findAction );
if( bufPtr != buffer )
free( bufPtr );
return( cryptStatus );
}
static int findCertFromTemplate( DEVICE_INFO *deviceInfo,
const CK_ATTRIBUTE *findTemplate,
const int templateCount,
CRYPT_CERTIFICATE *iCryptCert,
const FINDCERT_ACTION findAction )
{
CK_OBJECT_HANDLE hCertificate;
int cryptStatus;
*iCryptCert = CRYPT_ERROR;
/* Try and find the cert from the given template */
cryptStatus = findObject( deviceInfo, &hCertificate, findTemplate,
templateCount );
if( cryptStatusError( cryptStatus ) )
return( cryptStatus );
if( findAction == FINDCERT_P11OBJECT )
{
*iCryptCert = hCertificate;
return( CRYPT_OK );
}
return( instantiateCert( deviceInfo, hCertificate, iCryptCert,
( findAction == FINDCERT_NORMAL ) ? \
TRUE : FALSE ) );
}
static int findCertFromLabel( DEVICE_INFO *deviceInfo,
const char *label, const int labelLength,
CRYPT_CERTIFICATE *iCryptCert,
const FINDCERT_ACTION findAction )
{
static const CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
static const CK_CERTIFICATE_TYPE certType = CKC_X_509;
CK_ATTRIBUTE certTemplate[] = {
{ CKA_CLASS, ( CK_VOID_PTR ) &certClass, sizeof( CK_OBJECT_CLASS ) },
{ CKA_CERTIFICATE_TYPE, ( CK_VOID_PTR ) &certType, sizeof( CK_CERTIFICATE_TYPE ) },
{ CKA_LABEL, NULL, 0 }
};
CK_OBJECT_HANDLE hCertificate;
int cryptStatus;
*iCryptCert = CRYPT_ERROR;
/* Try and find the cert with the given label */
if( label != NULL )
{
certTemplate[ 2 ].pValue = ( CK_VOID_PTR ) label;
certTemplate[ 2 ].ulValueLen = labelLength;
}
cryptStatus = findObject( deviceInfo, &hCertificate, certTemplate,
( label == NULL ) ? 2 : 3 );
if( cryptStatusError( cryptStatus ) )
return( cryptStatus );
if( findAction == FINDCERT_P11OBJECT )
{
*iCryptCert = hCertificate;
return( CRYPT_OK );
}
return( instantiateCert( deviceInfo, hCertificate, iCryptCert,
( findAction == FINDCERT_NORMAL ) ? \
TRUE : FALSE ) );
}
/* Find an object from a source object by matching ID's. This is used to
find a key matching a cert, a public key matching a private key, or
other objects with similar relationships */
static int findObjectFromObject( DEVICE_INFO *deviceInfo,
const CK_OBJECT_HANDLE hSourceObject,
const CK_OBJECT_CLASS objectClass,
CK_OBJECT_HANDLE *hObject )
{
CK_ATTRIBUTE keyTemplate[] = {
{ CKA_CLASS, ( CK_VOID_PTR ) &objectClass, sizeof( CK_OBJECT_CLASS ) },
{ CKA_ID, NULL_PTR, 0 }
};
CK_ATTRIBUTE idTemplate = \
{ CKA_ID, NULL_PTR, 0 };
CK_RV status;
BYTE buffer[ MAX_BUFFER_SIZE ], *bufPtr = buffer;
int cryptStatus;
*hObject = CRYPT_ERROR;
/* We're looking for a key whose ID matches that of the source object,
read it's cert ID */
status = C_GetAttributeValue( deviceInfo->deviceHandle, hSourceObject,
&idTemplate, 1 );
if( status == CKR_OK )
{
if( idTemplate.ulValueLen > MAX_BUFFER_SIZE && \
( bufPtr = malloc( ( size_t ) ( idTemplate.ulValueLen ) ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
idTemplate.pValue = bufPtr;
status = C_GetAttributeValue( deviceInfo->deviceHandle, hSourceObject,
&idTemplate, 1 );
}
if( status != CKR_OK )
{
if( bufPtr != buffer )
free( bufPtr );
return( mapError( deviceInfo, status, CRYPT_ERROR_NOTFOUND ) );
}
/* Find the key object with the given ID */
keyTemplate[ 1 ].pValue = bufPtr;
keyTemplate[ 1 ].ulValueLen = idTemplate.ulValueLen;
cryptStatus = findObject( deviceInfo, hObject, keyTemplate, 2 );
if( bufPtr != buffer )
free( bufPtr );
return( cryptStatus );
}
/* Read a flag for an object. An absent value is treated as FALSE */
static BOOLEAN readFlag( DEVICE_INFO *deviceInfo,
const CK_OBJECT_HANDLE hObject,
const CK_ATTRIBUTE_TYPE flagType )
{
CK_BBOOL bFlag = FALSE;
CK_ATTRIBUTE flagTemplate = { flagType, &bFlag, sizeof( CK_BBOOL ) };
/* Some buggy implementations return CKR_OK but forget to set the
data value in the template (!!!) so we have to initialise bFlag
to a default of FALSE to handle this */
return( ( C_GetAttributeValue( deviceInfo->deviceHandle, hObject,
&flagTemplate, 1 ) == CKR_OK && bFlag ) ? \
TRUE : FALSE );
}
/* Instantiate an object in a device. This works like the create context
function but instantiates a cryptlib object using data already contained
in the device (for example a stored private key or certificate). If the
value being read is a public key and there's a certificate attached, the
instantiated object is a native cryptlib object rather than a device
object with a native certificate object attached because there doesn't
appear to be any good reason to create the public-key object in the device,
and for most devices the cryptlib native object will be faster anyway */
static int rsaSetPublicComponents( DEVICE_INFO *deviceInfo,
const CRYPT_CONTEXT iCryptContext,
const CK_OBJECT_HANDLE hRsaKey );
static int getItemFunction( DEVICE_INFO *deviceInfo,
CRYPT_CONTEXT *iCryptContext,
const KEYMGMT_ITEM_TYPE itemType,
const CRYPT_KEYID_TYPE keyIDtype,
const void *keyID, const int keyIDlength,
void *auxInfo, int *auxInfoLength,
const int flags )
{
static const CK_OBJECT_CLASS pubkeyClass = CKO_PUBLIC_KEY;
static const CK_OBJECT_CLASS privkeyClass = CKO_PRIVATE_KEY;
static const CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
static const CK_CERTIFICATE_TYPE certType = CKC_X_509;
const CAPABILITY_INFO *capabilityInfoPtr;
CK_ATTRIBUTE iAndSTemplate[] = {
{ CKA_CLASS, ( CK_VOID_PTR ) &certClass, sizeof( CK_OBJECT_CLASS ) },
{ CKA_CERTIFICATE_TYPE, ( CK_VOID_PTR ) &certType, sizeof( CK_CERTIFICATE_TYPE ) },
{ CKA_ISSUER, NULL_PTR, 0 },
{ CKA_SERIAL_NUMBER, NULL_PTR, 0 }
}, iAndSTemplateAlt[ 4 ];
CK_ATTRIBUTE keyTemplate[] = {
{ CKA_CLASS, NULL_PTR, sizeof( CK_OBJECT_CLASS ) },
{ CKA_LABEL, NULL_PTR, 0 }
};
CK_ATTRIBUTE keyTypeTemplate = \
{ CKA_KEY_TYPE, NULL_PTR, sizeof( CK_KEY_TYPE ) };
CK_ATTRIBUTE keySizeTemplate = \
{ 0, NULL_PTR, 0 };
CK_ATTRIBUTE keyLabelTemplate = \
{ CKA_LABEL, NULL_PTR, 0 };
CK_OBJECT_HANDLE hObject, hCertificate;
CK_KEY_TYPE keyType;
CRYPT_CERTIFICATE iCryptCert;
CRYPT_ALGO cryptAlgo;
BOOLEAN certViaPrivateKey = FALSE, privateKeyViaCert = FALSE;
BOOLEAN certPresent = FALSE;
char label[ CRYPT_MAX_TEXTSIZE ];
int keySize, actionFlags = 0, labelLength, cryptStatus;
assert( itemType == KEYMGMT_ITEM_PUBLICKEY || \
itemType == KEYMGMT_ITEM_PRIVATEKEY );
/* If we're looking for something based on an issuerAndSerialNumber, set
up the search template. Because Netscape incorrectly uses the raw
serial number, we also set up an alternative template with the serial
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -