📄 pgptokenlib.c
字号:
PGP_TOKEN_TRACE1( "sPutGetKeyContainer: return container %s", curr_uuid );
return kPGPError_NoErr;
}
free( curr_uuid );
}
if( uuid == NULL ) /* Nothing was found and we cannot create new cont. */
return kPGPError_NoErr;
/* Ready to create key container */
rv = F->C_CreateObject(tptr->session, srchTemplate, srchTemplateSize, &handle);
if (rv != CKR_OK) {
pgpDebugMsg( "C_CreateObject failed" );
return ( rv == CKR_DEVICE_MEMORY ) ?
kPGPError_SmartCardOutOfMemory : kPGPError_SmartCardError;
}
else {
ret = kPGPError_NoErr;
if( uuidOut ) {
*uuidOut = malloc( uuid_size );
if( *uuidOut == NULL )
return kPGPError_OutOfMemory;
memcpy( *uuidOut, uuid, uuid_size );
PGP_TOKEN_TRACE1( "sPutGetKeyContainer: return container %s", uuid );
}
#if PGP_DEBUG
else
PGP_TOKEN_TRACE1( "sPutGetKeyContainer: container %s created", uuid );
#endif
if( uuidOutSize )
*uuidOutSize = uuid_size;
}
return ret;
#else /* PGP_WIN32 */
return kPGPError_NoErr;
#endif
}
static PGPError sWipe(PGPToken *tptr, PGPByte *id, int id_size)
{
CK_RV rv;
PGPBoolean failed = FALSE;
CK_BBOOL True = TRUE;
CK_ATTRIBUTE templ[] =
{
{ CKA_TOKEN, &True, 1 },
{ CKA_ID, id, id_size } /* should be second */
};
int templSize = sizeof(templ);
CK_OBJECT_HANDLE handle;
CK_ULONG howmany;
int max_objects = id ? 10 : 128;
/* Sanity check for the case when C_DestroyObject fails */
PGP_TOKEN_TRACE2("sWipe( %x, %d )", id ? *(unsigned*)id : -1, id_size );
if (!tptr->have_session || !tptr->logged_in)
{
pgpDebugMsg( "Wipe called without smartcard login" );
return kPGPError_SmartCardError;
}
if( id == NULL )
templSize -= sizeof(templ[0]);
do {
/* One vendor failed when we first find all objects
and then delete them one by one.
It will fail on the second object.
The same vendor required extra find in V4 key generation code.
*/
sFindP11Objs( tptr, templ, templSize, &howmany, &handle, 1 );
if( howmany == 1 ) {
rv = F->C_DestroyObject(tptr->session, handle);
if (rv != CKR_OK) {
pgpDebugMsg( "C_DestroyObject failed, wipe proceeding..." );
failed = TRUE;
}
}
if( failed )
max_objects--;
} while( howmany && max_objects>0 );
return failed ? kPGPError_SmartCardError : kPGPError_NoErr;
}
#if 0
static PGPUInt32 sSimpleHash32( void *p, int bytes ) {
PGPUInt32 out = 0;
bytes /= sizeof(PGPUInt32);
while( bytes-- )
out ^= *(((unsigned*)p)++);
return out;
}
#endif
/*** EXPORTABLE FUNCTIONS ***/
/* Return nonzero iff we found a change in the token list
*/
#define ID_FROM_SLOT_ID(tptr, i) ~(i)
PGPInt32 pgpAcquireAllTokens(void)
{
int i;
static PGPUInt32 before_ids[MAXTOKENS] = { 0 };
int slots=0;
CK_RV rv;
PGPUInt32 ret=0;
int n_ids_matched=0;
PGPUInt32 new_id=0;
PGPUInt32 new_slot=0;
if (!enable_checking) return 0;
/* PGP_TOKEN_TRACE("pgpAcquireAllTokens"); */
if (is_CRYPTOKI_initialized == 0)
{
PGP_TOKEN_TRACE("Calling C_Initialize(NULL)");
pgpAssert( F ); /* Possibly, pgpTokenInit was not called */
rv = F->C_Initialize(NULL);
if (rv != CKR_OK)
{
pgpDebugMsg( "C_Initialize failed" );
return 0;
}
PGP_TOKEN_TRACE("C_Initialize(NULL) OK");
is_CRYPTOKI_initialized = 1;
}
rv = F->C_GetSlotList(TRUE, NULL, &slots);
if (rv != CKR_OK) {
pgpDebugMsg( "C_GetSlotList failed" );
return 0;
}
/* Nothing is present now -- clean and return */
if (slots == 0) {
if( s_how_many_tokens == 0 )
return 0;
PGP_TOKEN_TRACE("All tokens removed");
for (i = 0 ; i < MAXTOKENS ; i++)
if (token[i].have_session) PKCS11Destroy(token+i);
memset( before_ids, 0, sizeof(before_ids) );
s_how_many_tokens = 0;
return -1;
}
/* One vendor was ignoring given size and corrupting small buffer.
Make sure we allocate enough space for all slots. */
/* Expand buffer */
if( now_slots_allocated < slots*sizeof(PGPUInt32) ) {
now_slots = realloc( now_slots,
now_slots_allocated=slots*sizeof(PGPUInt32) );
}
if( now_slots == NULL ) {
pgpAssert(0);
return 0;
}
rv = F->C_GetSlotList(TRUE, now_slots, &slots);
if (rv != CKR_OK) {
pgpDebugMsg( "C_GetSlotList failed" );
return 0;
}
/* Some tokens -- see if there are changes. Slot IDs are unique in PKCS11 */
for( i=0; i<slots; i++ )
{
int j=0;
const PGPUInt32 id = ID_FROM_SLOT_ID(token+i, now_slots[i]);
/* Check for the case when token was moved to another slot */
for( j=0; j<MAXTOKENS; j++ ) {
PGPToken t;
/* Reorder, if possible */
if( id == before_ids[j] ) {
if( n_ids_matched != j ) {
before_ids[j] = before_ids[n_ids_matched];
before_ids[n_ids_matched] = id;
memcpy( &t, token+j, sizeof(t) );
memcpy( token+j, token+n_ids_matched, sizeof(*token) );
memcpy( token+n_ids_matched, &t, sizeof(t) );
}
if( (++n_ids_matched) >= MAXTOKENS) {
s_how_many_tokens = MAXTOKENS;
/* PGP_TOKEN_TRACE1("No changes: recognized all %d tokens", MAXTOKENS ); */
return FALSE; /* No changes: recognized all tokens */
}
break; /* will go to next slot */
}
}
/* new token with id is in slot now_slots[i] */
if( j==MAXTOKENS ) {
PGP_TOKEN_TRACE1("Token in slot %x is new", now_slots[i] );
new_id = id;
new_slot = now_slots[i];
}
}
/* Handle removed tokens (those which we didn't match with existing tokens) */
for( i=n_ids_matched; i<MAXTOKENS; i++ ) {
if (token[i].have_session) {
PGP_TOKEN_TRACE2("One token removed (%d/%d)",
i-n_ids_matched, MAXTOKENS-n_ids_matched);
PKCS11Destroy(token+i);
ret = 1;
}
before_ids[i] = 0;
}
/* We have one new token to add. We add only one at a time.
n_ids_matched tokens already present */
if( new_id && (i = n_ids_matched) < MAXTOKENS ) {
PGP_TOKEN_TRACE("New token found");
/* Add new token to the end of the list */
PKCS11Init(token+i, new_slot, TRUE, i);
before_ids[i] = new_id;
ret = 1;
s_how_many_tokens = n_ids_matched+1;
}
else {
s_how_many_tokens = n_ids_matched;
}
return ret;
}
void pgpReleaseAllTokens(void)
{
PGPUInt32 i;
HINSTANCE hModule;
CK_C_GetFunctionList pC_GetFunctionList;
PGP_TOKEN_TRACE("pgpReleaseAllTokens");
/* Test that library is still loaded */
if( (hModule = GetModuleHandle(CryptoKiDll)) != NULL )
{
pC_GetFunctionList = (CK_C_GetFunctionList)GetProcAddress(hModule,
"C_GetFunctionList");
if( pC_GetFunctionList != NULL )
{
if( (*pC_GetFunctionList)(&F) == CKR_OK )
{
for (i = 0 ; i < MAXTOKENS ; i++)
if (token[i].have_session) token[i].destroy(&token[i]);
PGP_TOKEN_TRACE( "Calling C_Finalize(0)" );
F->C_Finalize(0);
F = NULL;
}
}
}
is_CRYPTOKI_initialized = 0;
s_how_many_tokens = -1; /* don't know */
enable_checking = TRUE;
free(now_slots);
now_slots = NULL;
memset( token, 0, sizeof(token) );
FreeLibrary( hModule );
}
PGPError pgpTokenInit(void)
{
pgpAssert( sizeof(pgpTokenKeyInfoPriv) == sizeof(PGPTokenKeyInfo) );
return PKCS11ConstructAllTokenFields();
}
PGPUInt32 pgpCountTokenObjects(void)
{
return (s_how_many_tokens <= 0) ? 0 : s_how_many_tokens;
}
PGPToken *pgpGetNthTokenObject(PGPUInt32 x)
{
if( (int)x >= s_how_many_tokens || (int)x < 0 )
{
pgpDebugMsg( "Asking for token which doesn't exist" );
return NULL;
}
return &token[x];
}
PGPToken *pgpGetTokenObjectByPrivKeyID(const PGPByte *keyID)
{
int i = 0, j = 0;
PGPToken *tptr;
for (i = 0 ; i < s_how_many_tokens ; i++)
{
tptr = pgpGetNthTokenObject(i);
j = sKeyIDToPrivKeyInfo( tptr, keyID, NULL, TRUE );
if (j) return tptr;
}
return NULL;
}
/*
PGPToken *pgpGetTokenObjectByPubKeyID(const PGPByte *keyID)
{
int i = 0, j = 0;
PGPToken *tptr;
pgpAssert(0);
for (i = 0 ; i < s_how_many_tokens ; i++)
{
tptr = pgpGetNthTokenObject(i);
if (tptr == NULL) return NULL;
j = sKeyIDToPubKeyInfo(tptr, keyID, NULL);
if (j) return tptr;
}
return NULL;
}
*/
/*** STATIC PKCS11 FUNCTIONS ***/
static void PKCS11ConstructTokenFields(PGPToken *tptr)
{
tptr->init = &PKCS11Init;
tptr->destroy = &PKCS11Destroy;
tptr->decrypt = &PKCS11Decrypt;
tptr->sign = &PKCS11Sign;
tptr->login = &PKCS11Login;
tptr->logout = &PKCS11Logout;
tptr->getPrivKeyIDs = &PKCS11GetPrivKeyIDs;
tptr->getPubKeyIDs = &PKCS11GetPubKeyIDs;
tptr->getPublicData = &PKCS11GetPublicData;
tptr->getX509Certs = &PKCS11GetCerts;
tptr->getX509Cert = &PKCS11GetCert;
tptr->putPublicData = &PKCS11PutPublicData;
tptr->putPrivate = &PKCS11PutPrivate;
tptr->del = &PKCS11Delete;
tptr->keygen = &PKCS11Keygen;
tptr->editKeyList = &PKCS11EditKeyList;
tptr->setPIN = &PKCS11SetPIN;
tptr->wipe = &PKCS11Wipe;
tptr->format = &PKCS11Format;
tptr->getInfo = &PKCS11GetInfo;
tptr->importX509 = &PKCS11ImportX509;
tptr->putKeyContainer = &PKCS11PutKeyContainer;
tptr->getKeyContainer = &PKCS11GetKeyContainer;
}
static PGPError PKCS11ConstructAllTokenFields(void)
{
PGPUInt32 i = 0;
CK_RV rv;
HINSTANCE hModule;
CK_C_GetFunctionList pC_GetFunctionList;
s_how_many_tokens = -1; /* don't know */
PGP_TOKEN_TRACE("PKCS11ConstructAllTokenFields");
hModule = LoadLibrary(CryptoKiDll);
if (hModule == NULL)
{
pgpDebugMsg( "Target smartcard DLL not loaded" );
enable_checking = FALSE;
return kPGPError_SmartCardError;
}
pC_GetFunctionList = (CK_C_GetFunctionList)GetProcAddress(hModule,
"C_GetFunctionList");
if (pC_GetFunctionList == NULL)
{
pgpDebugMsg( "C_GetFunctionList failed" );
FreeLibrary(hModule);
return kPGPError_SmartCardError;
}
rv = (*pC_GetFunctionList)(&F);
for (i = 0 ; i < MAXTOKENS ; i++)
PKCS11ConstructTokenFields(token+i);
return kPGPError_NoErr;
}
static PGPError PKCS11Init(PGPToken *tptr, PGPUInt32 whichslot,
PGPBoolean haveslot, PGPInt32 index)
{
tptr->logged_in = FALSE;
tptr->slot = whichslot;
tptr->have_slot = haveslot;
tptr->tokenNum1 = index + 1;
if( sP11OpenSession( tptr ) != CKR_OK ) {
pgpDebugMsg( "sP11OpenSession failed" );
return kPGPError_SmartCardError;
}
return kPGPError_NoErr;
}
static PGPError PKCS11Destroy(PGPToken *tptr)
{
CK_RV rv;
PGP_TOKEN_TRACE("PKCS11Destroy");
if (tptr->logged_in)
{
rv = F->C_Logout(tptr->session);
if (rv != CKR_OK)
{
/* pgpDebugMsg( "C_Logout failed" ); */
}
}
if (tptr->have_session)
{
rv = F->C_CloseAllSessions(tptr->slot);
if (rv != CKR_OK)
{
/* pgpDebugMsg( "C_CloseAllSessions failed" ); */
}
}
free( tptr->privKeyIDs );
free( tptr->pubKeyIDs );
memset( tptr, 0, sizeof(*tptr) );
PKCS11ConstructTokenFields( tptr );
return kPGPError_NoErr;
}
static PGPError PKCS11Logout(PGPToken *tptr)
{
CK_RV rv;
PGP_TOKEN_TRACE("PKCS11Logout");
if (!tptr->have_slot) return kPGPError_NoErr;
if (!tptr->have_session) return kPGPError_NoErr;
if (!tptr->logged_in) return kPGPError_NoErr;
rv = F->C_Logout(tptr->session);
if (rv != CKR_OK)
{
pgpDebugMsg( "C_Logout failed" );
}
tptr->logged_in = 0;
return kPGPError_NoErr;
}
static PGPError sLogin(PGPToken *tptr, CK_USER_TYPE user_type, char const *input, PGPSize l
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -