📄 tpm_pkcs11.c
字号:
/* * The Initial Developer of the Original Code is International * Business Machines Corporation. Portions created by IBM * Corporation are Copyright (C) 2005 International Business * Machines Corporation. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the Common Public License as published by * IBM Corporation; either version 1 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Common Public License for more details. * * You should have received a copy of the Common Public License * along with this program; if not, a copy can be viewed at * http://www.opensource.org/licenses/cpl1.0.php. */#include <tpm_pkcs11.h>#include <stdlib.h>#include <dlfcn.h>#include <opencryptoki/pkcs11.h>/* * Global variables */char * g_pszSoLib = TPM_OPENCRYPTOKI_SO;void * g_pSoLib = NULL; // Handle of libopencryptoki libraryCK_FUNCTION_LIST_PTR g_pFcnList = NULL; // Function ListBOOL g_bInit = FALSE; // Indicates if C_Initialize has been calledBOOL g_bTokenOpen = FALSE; // Indicates if the token has been openedCK_SLOT_ID g_tSlotId; // Slot ID of the TPM tokenCK_TOKEN_INFO g_tToken; // TPM token informationvoidpkcsDebug( const char *a_pszName, CK_RV a_tResult ) { logDebug( _("%s success\n"), a_pszName );}voidpkcsError( const char *a_pszName, CK_RV a_tResult ) { logError( _("%s failed: 0x%08x (%ld)\n"), a_pszName, a_tResult, a_tResult );}voidpkcsResult( const char *a_pszName, CK_RV a_tResult ) { if ( a_tResult == CKR_OK ) pkcsDebug( a_pszName, a_tResult ); else pkcsError( a_pszName, a_tResult );}voidpkcsResultException( const char *a_pszName, CK_RV a_tResult, CK_RV a_tExcept ) { if ( ( a_tResult == CKR_OK ) || ( a_tResult == a_tExcept ) ) pkcsDebug( a_pszName, a_tResult ); else pkcsError( a_pszName, a_tResult );}/* * pkcsSlotInfo * Display some information about the slot. */voidpkcsSlotInfo(CK_SLOT_INFO *a_ptSlotInfo ) { char szSlotDesc[ sizeof( a_ptSlotInfo->slotDescription ) + 1 ]; char szSlotMfr[ sizeof( a_ptSlotInfo->manufacturerID ) + 1 ]; memset( szSlotDesc, 0, sizeof( szSlotDesc ) ); memset( szSlotMfr, 0, sizeof( szSlotMfr ) ); strncpy( szSlotDesc, (char *)a_ptSlotInfo->slotDescription, sizeof( a_ptSlotInfo->slotDescription ) ); strncpy( szSlotMfr, (char *)a_ptSlotInfo->manufacturerID, sizeof( a_ptSlotInfo->manufacturerID ) ); logDebug( _("Slot description: %s\n"), szSlotDesc ); logDebug( _("Slot manufacturer: %s\n"), szSlotMfr ); if ( a_ptSlotInfo->flags & CKF_TOKEN_PRESENT ) logDebug( _("Token is present\n") ); else logDebug( _("Token is not present\n") );}/* * pkcsTokenInfo * Display some information about the token. */voidpkcsTokenInfo(CK_TOKEN_INFO *a_ptTokenInfo ) { char szTokenLabel[ sizeof( a_ptTokenInfo->label ) + 1 ]; char szTokenMfr[ sizeof( a_ptTokenInfo->manufacturerID ) + 1 ]; char szTokenModel[ sizeof( a_ptTokenInfo->model ) + 1 ]; memset( szTokenLabel, 0, sizeof( szTokenLabel ) ); memset( szTokenMfr, 0, sizeof( szTokenMfr ) ); memset( szTokenModel, 0, sizeof( szTokenModel ) ); strncpy( szTokenLabel, (char *)a_ptTokenInfo->label, sizeof( a_ptTokenInfo->label ) ); strncpy( szTokenMfr, (char *)a_ptTokenInfo->manufacturerID, sizeof( a_ptTokenInfo->manufacturerID ) ); strncpy( szTokenModel, (char *)a_ptTokenInfo->model, sizeof( a_ptTokenInfo->model ) ); logDebug( _("Token Label: %s\n"), szTokenLabel ); logDebug( _("Token manufacturer: %s\n"), szTokenMfr ); logDebug( _("Token model: %s\n"), szTokenModel ); if ( a_ptTokenInfo->flags & CKF_TOKEN_INITIALIZED ) logDebug( _("Token is initialized\n") ); else logDebug( _("Token is not initialized\n") );}/* * openToken * Iterate through the available slots and tokens looking * for the TPM token and "opening" it if it is found. */CK_RVopenToken( char *a_pszTokenLabel ) { CK_C_GetFunctionList fGetFunctionList; int i; CK_RV rv; CK_ULONG ulSlots; CK_SLOT_ID *ptSlots; CK_SLOT_INFO tSlotInfo; CK_TOKEN_INFO tTokenInfo; char szTokenLabel[ sizeof( tTokenInfo.label ) ]; char *pszTokenLabel; // Load the PKCS#11 library g_pSoLib = dlopen( g_pszSoLib, RTLD_NOW ); if ( !g_pSoLib ) { logError( _("The PKCS#11 library cannot be loaded: %s\n"), dlerror( ) ); rv = CKR_GENERAL_ERROR; goto out; } fGetFunctionList = (CK_C_GetFunctionList)dlsym( g_pSoLib, "C_GetFunctionList" ); if ( !fGetFunctionList ) { logError( _("Unable to find the C_GetFunctionList function: %s\n"), dlerror( ) ); rv = CKR_GENERAL_ERROR; goto out; } rv = fGetFunctionList( &g_pFcnList ); pkcsResult( "C_GetFunctionList", rv ); if ( rv != CKR_OK ) goto out; // Set the name of the TPM token memset( szTokenLabel, ' ', sizeof( szTokenLabel ) ); if ( a_pszTokenLabel ) { if ( strlen( a_pszTokenLabel ) > sizeof( szTokenLabel ) ) { logError( _("The token label cannot be greater than %ld characters\n"), sizeof( szTokenLabel ) ); rv = CKR_GENERAL_ERROR; goto out; } pszTokenLabel = a_pszTokenLabel; } else pszTokenLabel = TPM_TOKEN_LABEL; strncpy( szTokenLabel, pszTokenLabel, strlen( pszTokenLabel ) ); // Initialize the PKCS#11 library rv = g_pFcnList->C_Initialize( NULL ); pkcsResult( "C_Initialize", rv ); if ( rv != CKR_OK ) goto out; g_bInit = TRUE; // Determine the number of slots that are present rv = g_pFcnList->C_GetSlotList( FALSE, NULL, &ulSlots ); pkcsResult( "C_GetSlotList", rv ); if ( rv != CKR_OK ) goto out; if ( ulSlots == 0 ) { logError( _("No PKCS#11 slots present\n") ); rv = CKR_TOKEN_NOT_PRESENT; goto out; } // Allocate a buffer to hold the slot ids logDebug( _("Slots present: %ld\n"), ulSlots ); ptSlots = (CK_SLOT_ID_PTR)calloc( 1, sizeof( CK_SLOT_ID ) * ulSlots ); if ( !ptSlots ) { logError( _("Unable to obtain memory for PKCS#11 slot IDs\n") ); rv = CKR_HOST_MEMORY; goto out; } // Retrieve the list of slot ids that are present rv = g_pFcnList->C_GetSlotList( FALSE, ptSlots, &ulSlots ); pkcsResult( "C_GetSlotList", rv ); if ( rv != CKR_OK ) goto out; // Iterate through the slots looking for the TPM token for ( i = 0; i < ulSlots; i++ ) { // Obtain information about the slot logDebug( _("Retrieving slot information for SlotID %ld\n"), ptSlots[ i ] ); rv = g_pFcnList->C_GetSlotInfo( ptSlots[ i ], &tSlotInfo ); pkcsResult( "C_GetSlotInfo", rv ); if ( rv != CKR_OK ) goto out; pkcsSlotInfo( &tSlotInfo ); if ( tSlotInfo.flags & CKF_TOKEN_PRESENT ) { // The slot token is present, obtain information about the token logDebug( _("Retrieving token information for SlotID %ld\n"), ptSlots[ i ] ); rv = g_pFcnList->C_GetTokenInfo( ptSlots[ i ], &tTokenInfo ); pkcsResult( "C_GetTokenInfo", rv ); if ( rv != CKR_OK ) goto out; pkcsTokenInfo( &tTokenInfo ); // Check for the TPM token if ( !strncmp( (char *)tTokenInfo.label, szTokenLabel, sizeof( szTokenLabel ) ) ) { g_bTokenOpen = TRUE; g_tSlotId = ptSlots[ i ]; g_tToken = tTokenInfo; break; } } } if ( !g_bTokenOpen ) { logError( _("PKCS#11 TPM Token is not present\n") ); rv = CKR_TOKEN_NOT_PRESENT; }out: if ( !g_bTokenOpen && g_bInit ) { g_pFcnList->C_Finalize( NULL ); g_bInit = FALSE; } if ( !g_bTokenOpen && g_pSoLib ) { dlclose( g_pSoLib ); g_pSoLib = NULL; } return rv;}/* * closeToken * "Close" the TPM token. */CK_RVcloseToken( ) { CK_RV rv = CKR_OK; // Tear down the PKCS#11 environment if ( g_bInit ) { rv = g_pFcnList->C_Finalize( NULL ); pkcsResult( "C_Finalize", rv ); } // Unload the PKCS#11 library if ( g_pSoLib ) dlclose( g_pSoLib ); g_bTokenOpen = FALSE; g_bInit = FALSE; g_pSoLib = NULL; return rv;}/* * initToken * Invoke the PKCS#11 C_InitToken API. */CK_RVinitToken( char *a_pszPin ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; rv = g_pFcnList->C_InitToken( g_tSlotId, (CK_CHAR *)a_pszPin, strlen( a_pszPin ), g_tToken.label ); pkcsResult( "C_InitToken", rv ); return rv;}/* * openTokenSession * Invoke the PKCS#11 C_OpenSession API. */CK_RVopenTokenSession( CK_FLAGS a_tType, CK_SESSION_HANDLE *a_phSession ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; a_tType |= CKF_SERIAL_SESSION; // This flag must always be set rv = g_pFcnList->C_OpenSession( g_tSlotId, a_tType, NULL, NULL, a_phSession ); pkcsResult( "C_OpenSession", rv ); return rv;}/* * closeTokenSession * Invoke the PKCS#11 C_CloseSession API. */CK_RVcloseTokenSession( CK_SESSION_HANDLE a_hSession ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; rv = g_pFcnList->C_CloseSession( a_hSession ); pkcsResult( "C_CloseSession", rv ); return rv;}/* * closeAllTokenSessions * Invoke the PKCS#11 C_CloseAllSessions API. */CK_RVcloseAllTokenSessions( ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; rv = g_pFcnList->C_CloseAllSessions( g_tSlotId ); pkcsResult( "C_CloseAllSessions", rv ); return rv;}/* * loginToken * Invoke the PKCS#11 C_Login API for the specified user type. */CK_RVloginToken( CK_SESSION_HANDLE a_hSession, CK_USER_TYPE a_tType, char *a_pszPin ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; rv = g_pFcnList->C_Login( a_hSession, a_tType, (CK_CHAR *)a_pszPin, strlen( a_pszPin ) ); pkcsResult( "C_Login", rv ); return rv;}/* * Invoke the PKCS#11 C_InitPin API. */CK_RVinitPin( CK_SESSION_HANDLE a_hSession, char *a_pszPin ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; rv = g_pFcnList->C_InitPIN( a_hSession, (CK_CHAR *)a_pszPin, strlen( a_pszPin ) ); pkcsResult( "C_InitPIN", rv ); return rv;}/* * setPin * Invoke the PKCS#11 C_SetPIN API. */CK_RVsetPin( CK_SESSION_HANDLE a_hSession, char *a_pszOldPin, char *a_pszNewPin ) { CK_RV rv; if ( !g_bTokenOpen ) return CKR_GENERAL_ERROR; rv = g_pFcnList->C_SetPIN( a_hSession, (CK_CHAR *)a_pszOldPin, strlen( a_pszOldPin ), (CK_CHAR *)a_pszNewPin, strlen( a_pszNewPin ) ); pkcsResult( "C_SetPIN", rv ); return rv;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -