From 984cf0036c882c4fada83448aaa37bbd5ebb8130 Mon Sep 17 00:00:00 2001 From: james Date: Thu, 20 Oct 2005 05:58:08 +0000 Subject: Merged with Alon's r688. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@689 e7ae566f-a301-0410-adde-c780ea21d3b5 --- pkcs11.c | 2837 +++----------------------------------------------------------- 1 file changed, 116 insertions(+), 2721 deletions(-) (limited to 'pkcs11.c') diff --git a/pkcs11.c b/pkcs11.c index 8dd9dfe..84d663b 100644 --- a/pkcs11.c +++ b/pkcs11.c @@ -38,2143 +38,34 @@ #if defined(ENABLE_PKCS11) -#include "error.h" -#include "misc.h" -#include "ssl.h" +#define PKCS11H_NO_NEED_INCLUDE_CONFIG -#if !defined(IN) -#define IN -#endif -#if !defined(OUT) -#define OUT -#endif - -#if defined(WIN32) -#include "cryptoki-win32.h" -#else -#include "cryptoki.h" -#endif - -#include "pkcs11.h" - -/*=========================================== - * MACROS - */ - -#define snprintf openvpn_snprintf - -/*=========================================== - * Constants - */ - -#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE) -# define RSA_get_default_method RSA_get_default_openssl_method -#else -# ifdef HAVE_ENGINE_GET_DEFAULT_RSA -# include -# if OPENSSL_VERSION_NUMBER < 0x0090704fL -# define BROKEN_OPENSSL_ENGINE -# endif -# endif -#endif - -#define PKCS11_MAX_ATTRIBUTE_SIZE (10*1024) - -/*=========================================== - * Types - */ - -typedef bool (*pkcs11_hook_card_prompt_t)( - IN const void *pData, - IN const char * const szLabel -); - -typedef bool (*pkcs11_hook_pin_prompt_t)( - IN const void *pData, - IN const char * const szLabel, - OUT char * const szPIN, - IN const size_t nMaxPIN -); - -typedef struct pkcs11_hooks_s { - void *card_prompt_data; - void *pin_prompt_data; - pkcs11_hook_card_prompt_t card_prompt; - pkcs11_hook_pin_prompt_t pin_prompt; -} *pkcs11_hooks_t; - -typedef struct pkcs11_provider_s { - struct pkcs11_provider_s *next; - - bool fEnabled; - -#if defined(WIN32) - HANDLE hLibrary; -#else - void *hLibrary; -#endif - CK_FUNCTION_LIST_PTR f; - bool fShouldFinalize; - char *szSignMode; - -} *pkcs11_provider_t; - -typedef struct pkcs11_session_s { - - pkcs11_provider_t provider; - - bool fProtectedAuthentication; - - char szLabel[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1]; - CK_CHAR serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)]; - - unsigned char *certificate; - size_t certificate_size; - unsigned char *certificate_id; - size_t certificate_id_size; - - CK_SLOT_ID slot; - bool fKeySignRecover; - - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE key; - - time_t timePINExpire; -} *pkcs11_session_t; - -typedef struct pkcs11_data_s { - bool fInitialized; - int nPINCachePeriod; - pkcs11_provider_t providers; - pkcs11_hooks_t hooks; -} *pkcs11_data_t; - -/*=========================================== - * Low level prototypes - */ - -static -void -_fixupFixedString ( - IN const char * const szSource, - OUT char * const szTarget, /* MUST BE >= nLength+1 */ - IN const size_t nLength /* FIXED STRING LENGTH */ -); -static -void -_hexToBinary ( - IN const char * const szSource, - OUT unsigned char * const target, - IN OUT size_t * const target_size -); -static -CK_RV -_pkcs11_getSlotById ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szSlot -); -static -CK_RV -_pkcs11_getSlotByName ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szName -); -static -CK_RV -_pkcs11_getSlotByLabel ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szLabel -); -static -CK_RV -_pkcs11_getObjectById ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_OBJECT_CLASS class, - IN const unsigned char * const id, - IN const size_t id_size, - OUT CK_OBJECT_HANDLE * const handle -); -static -CK_RV -_pkcs11_setSessionTokenInfo ( - IN const pkcs11_session_t pkcs11_session -); -static -CK_RV -_pkcs11_resetSlot ( - IN const pkcs11_session_t pkcs11_session -); -static -CK_RV -_pkcs11_loadCertificate ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szIdType, - IN const char * const szId -); -static -CK_RV -_pkcs11_loadKeyProperties ( - IN const pkcs11_session_t pkcs11_session -); -static -bool -_isBetterCertificate ( - IN const unsigned char * const pCurrent, - IN const size_t nCurrentSize, - IN const unsigned char * const pNew, - IN const size_t nNewSize -); -static -CK_RV -_pkcs11_validateSession ( - IN const pkcs11_session_t pkcs11_session -); -static -CK_RV -_pkcs11_login ( - IN const pkcs11_session_t pkcs11_session -); -static -CK_RV -_pkcs11_logout ( - IN const pkcs11_session_t pkcs11_session -); - -/*========================================= - * Simplified functions prototypes - */ -static -bool -_pkcs11_hooks_card_prompt_default ( - IN const void *pData, - IN const char * const szLabel -); -static -bool -_pkcs11_hooks_pin_prompt_default ( - IN const void *pData, - IN const char * const szLabel, - OUT char * const szPIN, - IN const size_t nMaxPIN -); -static -CK_RV -pkcs11_initialize (); -static -CK_RV -pkcs11_terminate (); -static -CK_RV -pkcs11_setCardPromptHook ( - IN const pkcs11_hook_card_prompt_t hook, - IN void * const pData -); -static -CK_RV -pkcs11_setPINPromptHook ( - IN const pkcs11_hook_pin_prompt_t hook, - IN void * const pData -); -static -CK_RV -pkcs11_setPINCachePeriod ( - IN const int nPINCachePeriod -); -static -CK_RV -pkcs11_addProvider ( - IN const char * const szProvider, - IN const char * const szSignMode -); -static -CK_RV -pkcs11_forkFixup (); -static -CK_RV -pkcs11_createSession ( - IN const char * const szSlotType, - IN const char * const szSlot, - IN const char * const szIdType, - IN const char * const szId, - IN const bool fProtectedAuthentication, - OUT pkcs11_session_t * const pkcs11_session -); -static -CK_RV -pkcs11_freeSession ( - IN const pkcs11_session_t pkcs11_session -); -static -CK_RV -pkcs11_sign ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_MECHANISM_TYPE mech_type, - IN const unsigned char * const source, - IN const size_t source_size, - OUT unsigned char * const target, - IN OUT size_t * const target_size -); -static -CK_RV -pkcs11_signRecover ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_MECHANISM_TYPE mech_type, - IN const unsigned char * const source, - IN const size_t source_size, - OUT unsigned char * const target, - IN OUT size_t * const target_size -); -static -CK_RV -pkcs11_decrypt ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_MECHANISM_TYPE mech_type, - IN const unsigned char * const source, - IN const size_t source_size, - OUT unsigned char * const target, - IN OUT size_t * const target_size -); -static -CK_RV -pkcs11_getCertificate ( - IN const pkcs11_session_t pkcs11_session, - OUT unsigned char * const certificate, - IN OUT size_t * const certificate_size -); -static -char * -pkcs11_getMessage ( - IN const int rv -); - -/*========================================== - * Static data - */ - -static pkcs11_data_t pkcs11_data = NULL; - -/*========================================== - * Internal utility functions - */ - -static -void -_fixupFixedString ( - IN const char * const szSource, - OUT char * const szTarget, /* MUST BE >= nLength+1 */ - IN const size_t nLength /* FIXED STRING LENGTH */ -) { - char *p; - - ASSERT (szSource!=NULL); - ASSERT (szTarget!=NULL); - - p = szTarget+nLength; - memmove (szTarget, szSource, nLength); - *p = '\0'; - p--; - while (p >= szTarget && *p == ' ') { - *p = '\0'; - p--; - } -} - -static -void -_hexToBinary ( - IN const char * const szSource, - OUT unsigned char * const target, - IN OUT size_t * const target_size -) { - size_t target_max_size; - const char *p; - char buf[3] = {'\0', '\0', '\0'}; - int i = 0; - - ASSERT (szSource!=NULL); - ASSERT (target!=NULL); - ASSERT (target_size!=NULL); - - target_max_size = *target_size; - p = szSource; - *target_size = 0; - - while (*p != '\0' && *target_size < target_max_size) { - if (isxdigit (*p)) { - buf[i%2] = *p; - - if ((i%2) == 1) { - unsigned v; - sscanf (buf, "%x", &v); - target[*target_size] = v & 0xff; - (*target_size)++; - } - - i++; - } - p++; - } -} - -static -bool -_isBetterCertificate ( - IN const unsigned char * const pCurrent, - IN const size_t nCurrentSize, - IN const unsigned char * const pNew, - IN const size_t nNewSize -) { - /* - * This function compare the notBefore - * and select the most recent certificate - * it does not deal with timezones... - * When openssl will have ASN1_TIME compare function - * it should be used. - */ - - X509 *x509Current = NULL, *x509New = NULL; - char szNotBeforeCurrent[1024], szNotBeforeNew[1024]; - - /* - * First certificae - * always select - */ - if (nCurrentSize == 0) { - return true; - } - - szNotBeforeCurrent[0] = '\0'; - szNotBeforeNew[0] = '\0'; - - x509Current = X509_new (); - x509New = X509_new (); - - if (x509Current != NULL && x509New != NULL) { - const unsigned char *p1, *p2; - - p1 = pCurrent; - p2 = pNew; - if ( - d2i_X509 (&x509Current, (unsigned char **)&p1, nCurrentSize) && - d2i_X509 (&x509New, (unsigned char **)&p2, nNewSize) - ) { - ASN1_TIME *notBeforeCurrent = X509_get_notBefore (x509Current); - ASN1_TIME *notBeforeNew = X509_get_notBefore (x509New); - - if ( - notBeforeCurrent != NULL && - notBeforeNew != NULL && - notBeforeCurrent->length < (int) sizeof (szNotBeforeCurrent) - 1 && - notBeforeNew->length < (int) sizeof (szNotBeforeNew) - 1 - ) { - memmove (szNotBeforeCurrent, notBeforeCurrent->data, notBeforeCurrent->length); - szNotBeforeCurrent[notBeforeCurrent->length] = '\0'; - memmove (szNotBeforeNew, notBeforeNew->data, notBeforeNew->length); - szNotBeforeNew[notBeforeNew->length] = '\0'; - } - } - } - - if (x509Current != NULL) { - X509_free (x509Current); - x509Current = NULL; - } - if (x509New != NULL) { - X509_free (x509New); - x509New = NULL; - } - - return strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0; -} - -/*======================================== - * Low level PKCS#11 functions - */ - -static -CK_RV -_pkcs11_getSlotById ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szSlot -) { - pkcs11_provider_t provider; - int provider_number; - int slot_number; - int i; - - ASSERT (pkcs11_session!=NULL); - ASSERT (szSlot!=NULL); - - if (strchr (szSlot, ':') == NULL) { - provider_number = 0; - slot_number = atoi (szSlot); - } - else { - sscanf (szSlot, "%d:%d", &provider_number, &slot_number); - } - - for ( - i=0, provider=pkcs11_data->providers; - i < provider_number && provider != NULL; - i++, provider = provider->next - ); - - if ( - provider == NULL || - ( - provider != NULL && - !provider->fEnabled - ) - ) { - return CKR_SLOT_ID_INVALID; - } - - pkcs11_session->provider = provider; - pkcs11_session->slot = slot_number; - return CKR_OK; -} - -static -CK_RV -_pkcs11_getSlotByName ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szName -) { - CK_RV rv; - - pkcs11_provider_t provider; - bool fFound = false; - - ASSERT (pkcs11_session!=NULL); - ASSERT (szName!=NULL); - - for ( - provider = pkcs11_data->providers; - ( - provider != NULL && - !fFound - ); - provider = provider->next - ) { - CK_SLOT_ID slots[1024]; - CK_ULONG slotnum; - - if (!provider->fEnabled) { - continue; - } - - slotnum = sizeof (slots) / sizeof (CK_SLOT_ID); - if ( - (rv = provider->f->C_GetSlotList ( - TRUE, - slots, - &slotnum - )) == CKR_OK - ) { - CK_SLOT_ID s; - - for (s=0;!fFound && sf->C_GetSlotInfo ( - slots[s], - &info - )) == CKR_OK - ) { - char szCurrentName[sizeof (info.slotDescription)+1]; - - _fixupFixedString ( - (char *)info.slotDescription, - szCurrentName, - sizeof (info.slotDescription) - ); - - if (!strcmp (szCurrentName, szName)) { - fFound = true; - pkcs11_session->provider = provider; - pkcs11_session->slot = slots[s]; - } - } - } - } - } - - return fFound ? CKR_OK : CKR_SLOT_ID_INVALID; -} - -static -CK_RV -_pkcs11_getSlotByLabel ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szLabel -) { - CK_RV rv; - - pkcs11_provider_t provider; - bool fFound = false; - - ASSERT (pkcs11_session!=NULL); - ASSERT (szLabel!=NULL); - - for ( - provider = pkcs11_data->providers; - ( - provider != NULL && - !fFound - ); - provider = provider->next - ) { - CK_SLOT_ID slots[1024]; - CK_ULONG slotnum; - - if (!provider->fEnabled) { - continue; - } - - slotnum = sizeof (slots) / sizeof (CK_SLOT_ID); - if ( - (rv = provider->f->C_GetSlotList ( - TRUE, - slots, - &slotnum - )) == CKR_OK - ) { - CK_SLOT_ID s; - - for (s=0;!fFound && sf->C_GetTokenInfo ( - slots[s], - &info - )) == CKR_OK - ) { - char szCurrentLabel[sizeof (info.label)+1]; - - _fixupFixedString ( - (char *)info.label, - szCurrentLabel, - sizeof (info.label) - ); - - if (!strcmp (szCurrentLabel, szLabel)) { - fFound = true; - pkcs11_session->provider = provider; - pkcs11_session->slot = slots[s]; - } - } - } - } - } - - return fFound ? CKR_OK : CKR_SLOT_ID_INVALID; -} - -static -CK_RV -_pkcs11_setSessionTokenInfo ( - IN const pkcs11_session_t pkcs11_session -) { - CK_TOKEN_INFO info; - CK_RV rv; - - ASSERT (pkcs11_session!=NULL); - - if ( - (rv = pkcs11_session->provider->f->C_GetTokenInfo ( - pkcs11_session->slot, - &info - )) == CKR_OK - ) { - _fixupFixedString ( - (char *)info.label, - pkcs11_session->szLabel, - sizeof (info.label) - ); - - memmove ( - pkcs11_session->serialNumber, - info.serialNumber, - sizeof (pkcs11_session->serialNumber) - ); - } - - return rv; -} - -static -CK_RV -_pkcs11_resetSlot ( - IN const pkcs11_session_t pkcs11_session -) { - CK_SLOT_ID slots[1024]; - CK_ULONG slotnum; - CK_RV rv; - bool fFound = false; - bool fCancel = false; - - ASSERT (pkcs11_session!=NULL); - - do { - slotnum = sizeof (slots) / sizeof (CK_SLOT_ID); - if ( - (rv = pkcs11_session->provider->f->C_GetSlotList ( - TRUE, - slots, - &slotnum - )) == CKR_OK - ) { - CK_SLOT_ID s; - - for (s=0;!fFound && sprovider->f->C_GetTokenInfo ( - slots[s], - &info - )) == CKR_OK - ) { - if ( - !memcmp ( - pkcs11_session->serialNumber, - info.serialNumber, - sizeof (pkcs11_session->serialNumber) - ) - ) { - pkcs11_session->slot = slots[s]; - fFound = true; - } - } - } - } - - if (!fFound) { - fCancel = !pkcs11_data->hooks->card_prompt ( - pkcs11_data->hooks->card_prompt_data, - pkcs11_session->szLabel - ); - } - } while (!fFound && !fCancel); - - return fFound ? CKR_OK : CKR_SLOT_ID_INVALID; -} - -static -CK_RV -_pkcs11_getObjectById ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_OBJECT_CLASS class, - IN const unsigned char * const id, - IN const size_t id_size, - OUT CK_OBJECT_HANDLE * const handle -) { - CK_ULONG count; - CK_RV rv = CKR_OK; - - CK_ATTRIBUTE filter[] = { - {CKA_CLASS, (void *)&class, sizeof (class)}, - {CKA_ID, (void *)id, id_size} - }; - - ASSERT (pkcs11_session!=NULL); - ASSERT (id!=NULL); - ASSERT (handle!=NULL); - - if (rv == CKR_OK) { - rv = pkcs11_session->provider->f->C_FindObjectsInit ( - pkcs11_session->session, - filter, - sizeof (filter) / sizeof (CK_ATTRIBUTE) - ); - } - - if (rv == CKR_OK) { - rv = pkcs11_session->provider->f->C_FindObjects ( - pkcs11_session->session, - handle, - 1, - &count - ); - } - - if ( - rv == CKR_OK && - count == 0 - ) { - rv = CKR_FUNCTION_REJECTED; - } - - pkcs11_session->provider->f->C_FindObjectsFinal ( - pkcs11_session->session - ); - - return rv; -} - -static -CK_RV -_pkcs11_loadCertificate ( - IN const pkcs11_session_t pkcs11_session, - IN const char * const szIdType, - IN const char * const szId -) { - CK_OBJECT_HANDLE objects[10]; - CK_ULONG objects_found; - CK_RV rv; - - unsigned char selected_id[PKCS11_MAX_ATTRIBUTE_SIZE]; - int selected_id_size = 0; - unsigned char selected_certificate[PKCS11_MAX_ATTRIBUTE_SIZE]; - int selected_certificate_size = 0; - - CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE; - unsigned char cert_filter_by[PKCS11_MAX_ATTRIBUTE_SIZE]; - CK_ATTRIBUTE cert_filter[] = { - {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}, - {0, cert_filter_by, 0} - }; - - ASSERT (pkcs11_session!=NULL); - ASSERT (szIdType!=NULL); - ASSERT (szId!=NULL); - - if (!strcmp (szIdType, "label")) { - cert_filter[1].type = CKA_LABEL; - cert_filter[1].ulValueLen = (CK_ULONG)( - strlen (szId) < sizeof (cert_filter_by) ? - strlen (szId) : - sizeof (cert_filter_by) - ); - memmove ( - cert_filter_by, - szId, - cert_filter[1].ulValueLen - ); - } - else if (!strcmp (szIdType, "id")) { - size_t s = sizeof (cert_filter_by); - - cert_filter[1].type = CKA_ID; - _hexToBinary ( - szId, - cert_filter_by, - &s - ); - cert_filter[1].ulValueLen = s; - } - else if (!strcmp (szIdType, "subject")) { - memmove (&cert_filter[1], &cert_filter[0], sizeof (CK_ATTRIBUTE)); - } - else { - return CKR_ARGUMENTS_BAD; - } - - if ( - (rv = pkcs11_session->provider->f->C_FindObjectsInit ( - pkcs11_session->session, - cert_filter, - sizeof (cert_filter) / sizeof (CK_ATTRIBUTE) - )) != CKR_OK - ) { - return rv; - } - - while ( - (rv = pkcs11_session->provider->f->C_FindObjects ( - pkcs11_session->session, - objects, - sizeof (objects) / sizeof (CK_OBJECT_HANDLE), - &objects_found - )) == CKR_OK && - objects_found > 0 - ) { - CK_ULONG i; - - for (i=0;iprovider->f->C_GetAttributeValue ( - pkcs11_session->session, - objects[i], - attrs, - sizeof (attrs) / sizeof (CK_ATTRIBUTE) - ) == CKR_OK - ) { - bool fSelected = false; - - if (!strcmp (szIdType, "subject")) { - X509 *x509 = NULL; - char szSubject[1024]; - unsigned char *p; - - x509 = X509_new (); - - p = attrs_value; - if (d2i_X509 (&x509, &p, attrs[1].ulValueLen)) { - X509_NAME_oneline ( - X509_get_subject_name (x509), - szSubject, - sizeof (szSubject) - ); - szSubject[sizeof (szSubject) - 1] = '\0'; - } - - if (x509 != NULL) { - X509_free (x509); - x509 = NULL; - } - - if (!strcmp (szId, szSubject)) { - fSelected = true; - } - } - else { - fSelected = true; - } - - if ( - fSelected && - _isBetterCertificate ( - selected_certificate, - selected_certificate_size, - attrs_value, - attrs[1].ulValueLen - ) - ) { - selected_certificate_size = attrs[1].ulValueLen; - memmove ( - selected_certificate, - attrs_value, - selected_certificate_size - ); - selected_id_size = attrs[0].ulValueLen; - memmove ( - selected_id, - attrs_id, - selected_id_size - ); - } - } - } - } - - pkcs11_session->provider->f->C_FindObjectsFinal ( - pkcs11_session->session - ); - - if (selected_certificate_size == 0) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - if ((pkcs11_session->certificate = (unsigned char *)malloc (selected_certificate_size)) == NULL) { - return CKR_HOST_MEMORY; - } - pkcs11_session->certificate_size = selected_certificate_size; - memmove ( - pkcs11_session->certificate, - selected_certificate, - selected_certificate_size - ); - if ((pkcs11_session->certificate_id = (unsigned char *)malloc (selected_id_size)) == NULL) { - return CKR_HOST_MEMORY; - } - pkcs11_session->certificate_id_size = selected_id_size; - memmove ( - pkcs11_session->certificate_id, - selected_id, - selected_id_size - ); - - return CKR_OK; -} - -static -CK_RV -_pkcs11_loadKeyProperties ( - IN const pkcs11_session_t pkcs11_session -) { - CK_OBJECT_HANDLE key; - CK_RV rv; - - CK_BBOOL key_attrs_sign_recover; - CK_BBOOL key_attrs_sign; - CK_ATTRIBUTE key_attrs[] = { - {CKA_SIGN, &key_attrs_sign_recover, sizeof (key_attrs_sign_recover)}, - {CKA_SIGN_RECOVER, &key_attrs_sign, sizeof (key_attrs_sign)} - }; - - ASSERT (pkcs11_session!=NULL); - - if (!strcmp (pkcs11_session->provider->szSignMode, "recover")) { - pkcs11_session->fKeySignRecover = true; - } - else if (!strcmp (pkcs11_session->provider->szSignMode, "sign")) { - pkcs11_session->fKeySignRecover = false; - } - else { - if ( - (rv = _pkcs11_getObjectById ( - pkcs11_session, - CKO_PRIVATE_KEY, - pkcs11_session->certificate_id, - pkcs11_session->certificate_id_size, - &key - )) != CKR_OK - ) { - return rv; - } - - if ( - pkcs11_session->provider->f->C_GetAttributeValue ( - pkcs11_session->session, - key, - key_attrs, - sizeof (key_attrs) / sizeof (CK_ATTRIBUTE) - ) == CKR_OK - ) { - if (key_attrs_sign_recover != CK_FALSE) { - pkcs11_session->fKeySignRecover = true; - } - else if (key_attrs_sign != CK_FALSE) { - pkcs11_session->fKeySignRecover = false; - } - else { - return CKR_KEY_TYPE_INCONSISTENT; - } - } - - } - - return CKR_OK; -} - -static -CK_RV -_pkcs11_validateSession ( - IN const pkcs11_session_t pkcs11_session -) { - if ( - pkcs11_session->timePINExpire != (time_t)0 && - pkcs11_session->timePINExpire < time (NULL) - ) { - _pkcs11_logout (pkcs11_session); - } - return CKR_OK; -} - -static -CK_RV -_pkcs11_login ( - IN const pkcs11_session_t pkcs11_session -) { - CK_RV rv = CKR_OK; - - - ASSERT (pkcs11_session!=NULL); - - _pkcs11_logout (pkcs11_session); - - if (rv == CKR_OK) { - rv = _pkcs11_resetSlot (pkcs11_session); - } - - if (rv == CKR_OK) { - rv = pkcs11_session->provider->f->C_OpenSession ( - pkcs11_session->slot, - CKF_SERIAL_SESSION, - NULL_PTR, - NULL_PTR, - &pkcs11_session->session - ); - } - - if (rv == CKR_OK) { - int nRetryCount = 0; - do { - CK_UTF8CHAR_PTR utfPIN = NULL; - CK_ULONG lPINLength = 0; - char szPIN[1024]; - - /* - * Assume OK for next iteration - */ - rv = CKR_OK; - - if ( - rv == CKR_OK && - !pkcs11_session->fProtectedAuthentication - ) { - if ( - !pkcs11_data->hooks->pin_prompt ( - pkcs11_data->hooks->pin_prompt_data, - pkcs11_session->szLabel, - szPIN, - sizeof (szPIN) - ) - ) { - rv = CKR_FUNCTION_FAILED; - } - else { - utfPIN = (CK_UTF8CHAR_PTR)szPIN; - lPINLength = strlen (szPIN); - } - } - - if (pkcs11_data->nPINCachePeriod == -1) { - pkcs11_session->timePINExpire = 0; - } - else { - pkcs11_session->timePINExpire = ( - time (NULL) + - (time_t)pkcs11_data->nPINCachePeriod - ); - } - if ( - rv == CKR_OK && - (rv = pkcs11_session->provider->f->C_Login ( - pkcs11_session->session, - CKU_USER, - utfPIN, - lPINLength - )) != CKR_OK - ) { - if (rv == CKR_USER_ALREADY_LOGGED_IN) { - rv = CKR_OK; - } - } - - /* - * Clean PIN buffer - */ - memset (szPIN, 0, sizeof (szPIN)); - } while ( - ++nRetryCount < 3 && - ( - rv == CKR_PIN_INCORRECT || - rv == CKR_PIN_INVALID - ) - ); - } - - if ( - rv == CKR_OK && - pkcs11_session->certificate_id != NULL - ) { - rv = _pkcs11_getObjectById ( - pkcs11_session, - CKO_PRIVATE_KEY, - pkcs11_session->certificate_id, - pkcs11_session->certificate_id_size, - &pkcs11_session->key - ); - } - - return rv; -} - -static -CK_RV -_pkcs11_logout ( - IN const pkcs11_session_t pkcs11_session -) { - ASSERT (pkcs11_session!=NULL); - - if (pkcs11_session->session != (CK_SESSION_HANDLE)-1) { - pkcs11_session->provider->f->C_Logout (pkcs11_session->session); - pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session); - pkcs11_session->key = (CK_OBJECT_HANDLE)-1; - pkcs11_session->session = (CK_SESSION_HANDLE)-1; - } - - return CKR_OK; -} - - -/*======================================= - * Simplified PKCS#11 functions - */ - -static -bool -_pkcs11_hooks_card_prompt_default ( - IN const void * pData, - IN const char * const szLabel -) { - return false; -} - -static -bool -_pkcs11_hooks_pin_prompt_default ( - IN const void * pData, - IN const char * const szLabel, - OUT char * const szPIN, - IN const size_t nMaxPIN -) { - return false; -} - -static -CK_RV -pkcs11_initialize () { - - pkcs11_terminate (); - - pkcs11_data = (pkcs11_data_t)malloc (sizeof (struct pkcs11_data_s)); - if (pkcs11_data == NULL) { - return CKR_HOST_MEMORY; - } - - memset (pkcs11_data, 0, sizeof (struct pkcs11_data_s)); - - pkcs11_data->nPINCachePeriod = -1; - - pkcs11_data->hooks = (pkcs11_hooks_t)malloc (sizeof (struct pkcs11_hooks_s)); - if (pkcs11_data->hooks == NULL) { - return CKR_HOST_MEMORY; - } - - memset (pkcs11_data->hooks, 0, sizeof (struct pkcs11_hooks_s)); - - pkcs11_data->fInitialized = true; - - pkcs11_setCardPromptHook (_pkcs11_hooks_card_prompt_default, NULL); - pkcs11_setPINPromptHook (_pkcs11_hooks_pin_prompt_default, NULL); - - return CKR_OK; -} - -static -CK_RV -pkcs11_terminate () { - - if (pkcs11_data != NULL) { - pkcs11_provider_t last = NULL; - - for ( - ; - pkcs11_data->providers != NULL; - pkcs11_data->providers = pkcs11_data->providers->next - ) { - if (last != NULL) { - free (last); - } - last = pkcs11_data->providers; - - if (pkcs11_data->providers->szSignMode != NULL) { - free (pkcs11_data->providers->szSignMode); - pkcs11_data->providers->szSignMode = NULL; - } - - if (pkcs11_data->providers->fShouldFinalize) { - pkcs11_data->providers->f->C_Finalize (NULL); - pkcs11_data->providers->fShouldFinalize = false; - } - - if (pkcs11_data->providers->f != NULL) { - pkcs11_data->providers->f = NULL; - } - - if (pkcs11_data->providers->hLibrary != NULL) { -#if defined(WIN32) - FreeLibrary (pkcs11_data->providers->hLibrary); -#else - dlclose (pkcs11_data->providers->hLibrary); -#endif - pkcs11_data->providers->hLibrary = NULL; - } - } - - if (last != NULL) { - free (last); - } - - if (pkcs11_data->hooks != NULL) { - free (pkcs11_data->hooks); - pkcs11_data->hooks = NULL; - } - - free (pkcs11_data); - pkcs11_data = NULL; - } - - return CKR_OK; -} - -static -CK_RV -pkcs11_setPINPromptHook ( - IN const pkcs11_hook_pin_prompt_t hook, - IN void * const pData -) { - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - - pkcs11_data->hooks->pin_prompt = hook; - pkcs11_data->hooks->pin_prompt_data = pData; - - return CKR_OK; -} - -static -CK_RV -pkcs11_setCardPromptHook ( - IN const pkcs11_hook_card_prompt_t hook, - IN void * const pData -) { - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - - pkcs11_data->hooks->card_prompt = hook; - pkcs11_data->hooks->card_prompt_data = pData; - - return CKR_OK; -} - -static -CK_RV -pkcs11_setPINCachePeriod ( - IN const int nPINCachePeriod -) { - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - - pkcs11_data->nPINCachePeriod = nPINCachePeriod; - - return CKR_OK; -} - -static -CK_RV -pkcs11_addProvider ( - IN const char * const szProvider, - IN const char * const szSignMode -) { - pkcs11_provider_t provider = NULL; - CK_C_GetFunctionList gfl = NULL; - CK_RV rv = CKR_OK; - - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - ASSERT (szProvider!=NULL); - - if ( - rv == CKR_OK && - (provider = (pkcs11_provider_t)malloc (sizeof (struct pkcs11_provider_s))) == NULL - ) { - rv = CKR_HOST_MEMORY; - } - - if (rv == CKR_OK) { - memset (provider, 0, sizeof (struct pkcs11_provider_s)); - if (szSignMode == NULL) { - provider->szSignMode = strdup ("auto"); - } - else { - provider->szSignMode = strdup (szSignMode); - } - if (provider->szSignMode == NULL) { - rv = CKR_HOST_MEMORY; - } - } - - if (rv == CKR_OK) { -#if defined(WIN32) - provider->hLibrary = LoadLibrary (szProvider); -#else - provider->hLibrary = dlopen (szProvider, RTLD_NOW); -#endif - if (provider->hLibrary == NULL) { - rv = CKR_FUNCTION_FAILED; - } - } - - if (rv == CKR_OK) { -#if defined(WIN32) - gfl = (CK_C_GetFunctionList)GetProcAddress ( - provider->hLibrary, - "C_GetFunctionList" - ); -#else - /* - * Make compiler happy! - */ - void *p = dlsym ( - provider->hLibrary, - "C_GetFunctionList" - ); - memmove ( - &gfl, - &p, - sizeof (void *) - ); -#endif - if (gfl == NULL) { - rv = CKR_FUNCTION_FAILED; - } - } - - if (rv == CKR_OK) { - rv = gfl (&provider->f); - } - - if (rv == CKR_OK) { - if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) { - if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) { - rv = CKR_OK; - } - } - else { - provider->fShouldFinalize = true; - } - } - - if (rv == CKR_OK) { - provider->fEnabled = true; - } - - if (provider != NULL) { - if (pkcs11_data->providers == NULL) { - pkcs11_data->providers = provider; - } - else { - pkcs11_provider_t last = NULL; - - for ( - last = pkcs11_data->providers; - last->next != NULL; - last = last->next - ); - last->next = provider; - } - } - - return rv; -} - -static -CK_RV -pkcs11_forkFixup () { - - if (pkcs11_data != NULL && pkcs11_data->fInitialized) { - - pkcs11_provider_t current; - - for ( - current = pkcs11_data->providers; - current != NULL; - current = current->next - ) { - if (current->fEnabled) { - current->f->C_Initialize (NULL); - } - } - } - - return CKR_OK; -} - -static -CK_RV -pkcs11_createSession ( - IN const char * const szSlotType, - IN const char * const szSlot, - IN const char * const szIdType, - IN const char * const szId, - IN const bool fProtectedAuthentication, - OUT pkcs11_session_t * const p_pkcs11_session -) { - pkcs11_session_t pkcs11_session; - CK_RV rv = CKR_OK; - - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - ASSERT (szSlotType!=NULL); - ASSERT (szSlot!=NULL); - ASSERT (szIdType!=NULL); - ASSERT (szId!=NULL); - ASSERT (p_pkcs11_session!=NULL); - - if ( - rv == CKR_OK && - (pkcs11_session = (pkcs11_session_t)malloc (sizeof (struct pkcs11_session_s))) == NULL - ) { - rv = CKR_HOST_MEMORY; - } - - if (rv == CKR_OK) { - *p_pkcs11_session = pkcs11_session; - memset (pkcs11_session, 0, sizeof (struct pkcs11_session_s)); - } - - if (rv == CKR_OK) { - pkcs11_session->key = (CK_OBJECT_HANDLE)-1; - pkcs11_session->session = (CK_SESSION_HANDLE)-1; - pkcs11_session->fProtectedAuthentication = fProtectedAuthentication; - } - - if (rv == CKR_OK) { - bool fCancel = false; - - do { - if (!strcmp (szSlotType, "id")) { - rv = _pkcs11_getSlotById (pkcs11_session, szSlot); - } - else if (!strcmp (szSlotType, "name")) { - rv = _pkcs11_getSlotByName (pkcs11_session, szSlot); - } - else if (!strcmp (szSlotType, "label")) { - rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot); - } - else { - rv = CKR_ARGUMENTS_BAD; - } - - if (rv == CKR_SLOT_ID_INVALID) { - char szLabel[1024]; - snprintf (szLabel, sizeof (szLabel), "SLOT(%s=%s)", szSlotType, szSlot); - fCancel = !pkcs11_data->hooks->card_prompt ( - pkcs11_data->hooks->card_prompt_data, - szLabel - ); - } - } while (rv == CKR_SLOT_ID_INVALID && !fCancel); - } - - if (rv == CKR_OK) { - rv = _pkcs11_setSessionTokenInfo (pkcs11_session); - } - - if (rv == CKR_OK) { - rv = _pkcs11_login ( - pkcs11_session - ); - } - - if (rv == CKR_OK) { - rv = _pkcs11_loadCertificate ( - pkcs11_session, - szIdType, - szId - ); - } - - if (rv == CKR_OK) { - rv = _pkcs11_loadKeyProperties ( - pkcs11_session - ); - } - - /* - * Complete missing login process - */ - if (rv == CKR_OK) { - rv = _pkcs11_getObjectById ( - pkcs11_session, - CKO_PRIVATE_KEY, - pkcs11_session->certificate_id, - pkcs11_session->certificate_id_size, - &pkcs11_session->key - ); - } - - return rv; -} - -CK_RV -pkcs11_freeSession ( - IN const pkcs11_session_t pkcs11_session -) { - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - - if (pkcs11_session != NULL) { - _pkcs11_logout (pkcs11_session); - - if (pkcs11_session->certificate != NULL) { - free (pkcs11_session->certificate); - } - if (pkcs11_session->certificate_id != NULL) { - free (pkcs11_session->certificate_id); - } - - free (pkcs11_session); - } - - return CKR_OK; -} - -static -CK_RV -pkcs11_sign ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_MECHANISM_TYPE mech_type, - IN const unsigned char * const source, - IN const size_t source_size, - OUT unsigned char * const target, - IN OUT size_t * const target_size -) { - CK_MECHANISM mech = { - mech_type, NULL, 0 - }; - CK_RV rv = CKR_OK; - bool fLogonRetry = false; - bool fOpSuccess = false; - - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - ASSERT (pkcs11_session!=NULL); - ASSERT (source!=NULL); - ASSERT (target_size!=NULL); - - rv = _pkcs11_validateSession (pkcs11_session); - - while (rv == CKR_OK && !fOpSuccess) { - rv = pkcs11_session->provider->f->C_SignInit ( - pkcs11_session->session, - &mech, - pkcs11_session->key - ); - - if (rv == CKR_OK) { - fOpSuccess = true; - } - else { - if (!fLogonRetry) { - fLogonRetry = true; - rv = _pkcs11_login (pkcs11_session); - } - } - } - - if (rv == CKR_OK) { - CK_ULONG size = *target_size; - rv = pkcs11_session->provider->f->C_Sign ( - pkcs11_session->session, - (CK_BYTE_PTR)source, - source_size, - (CK_BYTE_PTR)target, - &size - ); - - *target_size = (int)size; - } - - return rv; -} - -static -CK_RV -pkcs11_signRecover ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_MECHANISM_TYPE mech_type, - IN const unsigned char * const source, - IN const size_t source_size, - OUT unsigned char * const target, - IN OUT size_t * const target_size -) { - CK_MECHANISM mech = { - mech_type, NULL, 0 - }; - CK_RV rv = CKR_OK; - bool fLogonRetry = false; - bool fOpSuccess = false; - - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - ASSERT (pkcs11_session!=NULL); - ASSERT (source!=NULL); - ASSERT (target_size!=NULL); - - rv = _pkcs11_validateSession (pkcs11_session); - - while (rv == CKR_OK && !fOpSuccess) { - rv = pkcs11_session->provider->f->C_SignRecoverInit ( - pkcs11_session->session, - &mech, - pkcs11_session->key - ); - - if (rv == CKR_OK) { - fOpSuccess = true; - } - else { - if (!fLogonRetry) { - fLogonRetry = true; - rv = _pkcs11_login (pkcs11_session); - } - } - } - - if (rv == CKR_OK) { - CK_ULONG size = *target_size; - rv = pkcs11_session->provider->f->C_SignRecover ( - pkcs11_session->session, - (CK_BYTE_PTR)source, - source_size, - (CK_BYTE_PTR)target, - &size - ); - - *target_size = (int)size; - } - - return rv; -} - -static -CK_RV -pkcs11_decrypt ( - IN const pkcs11_session_t pkcs11_session, - IN const CK_MECHANISM_TYPE mech_type, - IN const unsigned char * const source, - IN const size_t source_size, - OUT unsigned char * const target, - IN OUT size_t * const target_size -) { - CK_MECHANISM mech = { - mech_type, NULL, 0 - }; - CK_ULONG size; - CK_RV rv = CKR_OK; - bool fLogonRetry = false; - bool fOpSuccess = false; - - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - ASSERT (pkcs11_session!=NULL); - ASSERT (source!=NULL); - ASSERT (target_size!=NULL); - - rv = _pkcs11_validateSession (pkcs11_session); - - while (rv == CKR_OK && !fOpSuccess) { - rv = pkcs11_session->provider->f->C_DecryptInit ( - pkcs11_session->session, - &mech, - pkcs11_session->key - ); - - if (rv == CKR_OK) { - fOpSuccess = true; - } - else { - if (!fLogonRetry) { - fLogonRetry = true; - rv = _pkcs11_login (pkcs11_session); - } - } - } - - if (rv == CKR_OK) { - size = *target_size; - rv = pkcs11_session->provider->f->C_Decrypt ( - pkcs11_session->session, - (CK_BYTE_PTR)source, - source_size, - (CK_BYTE_PTR)target, - &size - ); - - *target_size = (int)size; - } - - return rv; -} - -static -CK_RV -pkcs11_getCertificate ( - IN const pkcs11_session_t pkcs11_session, - OUT unsigned char * const certificate, - IN OUT size_t * const certificate_size -) { - ASSERT (pkcs11_data!=NULL); - ASSERT (pkcs11_data->fInitialized); - ASSERT (certificate_size!=NULL); - - *certificate_size = pkcs11_session->certificate_size; - - if (certificate == NULL) { - return CKR_OK; - } - - if (*certificate_size > pkcs11_session->certificate_size) { - return CKR_BUFFER_TOO_SMALL; - } - - memmove (certificate, pkcs11_session->certificate, *certificate_size); - - return CKR_OK; -} - -static -char * -pkcs11_getMessage ( - IN const int rv -) { - switch (rv) { - case CKR_OK: return "CKR_OK"; - case CKR_CANCEL: return "CKR_CANCEL"; - case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY"; - case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID"; - case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR"; - case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED"; - case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD"; - case CKR_NO_EVENT: return "CKR_NO_EVENT"; - case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS"; - case CKR_CANT_LOCK: return "CKR_CANT_LOCK"; - case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY"; - case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE"; - case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID"; - case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID"; - case CKR_DATA_INVALID: return "CKR_DATA_INVALID"; - case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE"; - case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR"; - case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY"; - case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED"; - case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID"; - case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE"; - case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED"; - case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL"; - case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED"; - case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID"; - case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE"; - case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT"; - case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED"; - case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED"; - case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED"; - case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE"; - case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED"; - case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE"; - case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE"; - case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID"; - case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID"; - case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID"; - case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE"; - case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED"; - case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT"; - case CKR_PIN_INVALID: return "CKR_PIN_INVALID"; - case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE"; - case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED"; - case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED"; - case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED"; - case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT"; - case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID"; - case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED"; - case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY"; - case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS"; - case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS"; - case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS"; - case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID"; - case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE"; - case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE"; - case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT"; - case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT"; - case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED"; - case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED"; - case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID"; - case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE"; - case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"; - case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN"; - case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN"; - case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED"; - case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID"; - case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN"; - case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES"; - case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID"; - case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE"; - case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID"; - case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE"; - case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"; - case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED"; - case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG"; - case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID"; - case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL"; - case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID"; - case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE"; - case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE"; - case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED"; - case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED"; - case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD"; - case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED"; - case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED"; - case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED"; - default: return "Unknown PKCS#11 error"; - } -} - -/*========================================== - * openssl interface - */ - -typedef struct openssl_session_s { - RSA_METHOD smart_rsa; - int (*orig_finish)(RSA *rsa); - pkcs11_session_t pkcs11_session; -} *openssl_session_t; - -static -pkcs11_session_t -_openssl_get_pkcs11_session (const RSA *rsa) { - openssl_session_t session; - - ASSERT (rsa!=NULL); - session = (openssl_session_t)RSA_get_app_data (rsa); - ASSERT (session!=NULL); - ASSERT (session->pkcs11_session!=NULL); - - return session->pkcs11_session; -} - -static -int -openssl_pkcs11_priv_enc ( - int flen, - const unsigned char *from, - unsigned char *to, - RSA *rsa, - int padding -) { - msg(M_WARN, "PKCS#11: Private key encryption not supported"); - return -1; -} - -static -int -openssl_pkcs11_priv_dec ( - int flen, const unsigned char *from, - unsigned char *to, - RSA *rsa, - int padding -) { - pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa); - CK_RV rv = CKR_OK; - - msg ( - D_PKCS11_DEBUG, - "PKCS#11: openssl_pkcs11_priv_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d", - flen, - from, - to, - (void *)rsa, - padding - ); - - ASSERT (from!=NULL); - ASSERT (to!=NULL); - - msg ( - D_SHOW_PKCS11, - "PKCS#11: Performing decryption using private key" - ); - - if (padding != RSA_PKCS1_PADDING) { - rv = CKR_ARGUMENTS_BAD; - } - - if ( - rv == CKR_OK && - (rv = pkcs11_decrypt ( - pkcs11_session, - CKM_RSA_PKCS, - from, - flen, - to, - (size_t *)&flen - )) != CKR_OK - ) { - msg (M_WARN, "PKCS#11: Cannot decrypt using private key %ld:'%s'", rv, pkcs11_getMessage (rv)); - } +#include "pkcs11-helper.h" +#include "pkcs11.h" - msg ( - D_PKCS11_DEBUG, - "PKCS#11: openssl_pkcs11_priv_dec - return rv=%ld", - rv - ); - - return rv == CKR_OK ? 1 : -1; -} +#define snprintf openvpn_snprintf static -int -openssl_pkcs11_sign ( - int type, - const unsigned char *m, - unsigned int m_len, - unsigned char *sigret, - unsigned int *siglen, - const RSA *rsa +void +_pkcs11_openvpn_print ( + IN const void *pData, + IN const char * const szFormat, + IN ... ) { - pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa); - CK_RV rv = CKR_OK; - - msg ( - D_PKCS11_DEBUG, - "PKCS#11: openssl_pkcs11_priv_sign entered - type=%d, m=%p, m_len=%u, signret=%p, signlen=%p, rsa=%p", - type, - m, - m_len, - sigret, - (void *)siglen, - (void *)rsa - ); - - ASSERT (m!=NULL); - ASSERT (siglen!=NULL); - - msg ( - D_SHOW_PKCS11, - "PKCS#11: Performing signature" - ); - - *siglen = RSA_size(rsa); - - if (pkcs11_session->fKeySignRecover) { - if ( - (rv = pkcs11_signRecover ( - pkcs11_session, - CKM_RSA_PKCS, - m, - m_len, - sigret, - siglen - )) != CKR_OK - ) { - msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv)); - } - } - else { - if ( - (rv = pkcs11_sign ( - pkcs11_session, - CKM_RSA_PKCS, - m, - m_len, - sigret, - siglen - )) != CKR_OK - ) { - msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv)); - } - } - - msg ( - D_PKCS11_DEBUG, - "PKCS#11: openssl_pkcs11_priv_sign - return rv=%ld", - rv - ); - - return rv == CKR_OK ? 1 : -1; -} - -static -int -openssl_pkcs11_finish(RSA *rsa) { - pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa); - openssl_session_t openssl_session; - - msg ( - D_PKCS11_DEBUG, - "PKCS#11: openssl_pkcs11_finish - entered rsa=%p", - (void *)rsa - ); - - openssl_session = (openssl_session_t)RSA_get_app_data (rsa); - - RSA_set_app_data (rsa, NULL); - pkcs11_freeSession (pkcs11_session); - - if (openssl_session->orig_finish != NULL) { - openssl_session->orig_finish (rsa); - -#ifdef BROKEN_OPENSSL_ENGINE - { - /* We get called TWICE here, once for - * releasing the key and also for - * releasing the engine. - * To prevent endless recursion, FIRST - * clear rsa->engine, THEN call engine->finish - */ - ENGINE *e = rsa->engine; - rsa->engine = NULL; - if (e) { - ENGINE_finish(e); - } - } -#endif - } - - free (openssl_session); - - msg ( - D_PKCS11_DEBUG, - "PKCS#11: openssl_pkcs11_finish - return" - ); + char Buffer[10*1024]; + va_list args; - return 1; -} - -void -openssl_pkcs11_set_rsa(const openssl_session_t openssl_session, RSA *rsa) -{ - const RSA_METHOD *def = RSA_get_default_method(); - - ASSERT (openssl_session!=NULL); - ASSERT (rsa!=NULL); - - memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD)); - - openssl_session->orig_finish = def->finish; - - openssl_session->smart_rsa.name = "pkcs11"; - openssl_session->smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc; - openssl_session->smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec; - openssl_session->smart_rsa.rsa_sign = openssl_pkcs11_sign; - openssl_session->smart_rsa.finish = openssl_pkcs11_finish; - openssl_session->smart_rsa.flags = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY; - - RSA_set_method (rsa, &openssl_session->smart_rsa); - RSA_set_app_data (rsa, openssl_session); + va_start (args, szFormat); + vsnprintf (Buffer, sizeof (Buffer), szFormat, args); + va_end (args); + Buffer[sizeof (Buffer)-1] = 0; -#ifdef BROKEN_OPENSSL_ENGINE - if (fOK) { - if (!rsa->engine) - rsa->engine = ENGINE_get_default_RSA(); - - ENGINE_set_RSA(ENGINE_get_default_RSA(), openssl_session->smart_rsa); - msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled"); - } -#endif + msg (M_INFO|M_NOPREFIX|M_NOLF, "%s", Buffer); } - -#ifdef BROKEN_OPENSSL_ENGINE -static void broken_openssl_init() __attribute__ ((constructor)); -static void broken_openssl_init() -{ - SSL_library_init(); - ENGINE_load_openssl(); - ENGINE_register_all_RSA(); -} -#endif - -/*========================================== - * openvpn interface - */ - static bool -_openvpn_pkcs11_card_prompt ( +_pkcs11_openvpn_card_prompt ( IN const void *pData, IN const char * const szLabel ) { @@ -2184,11 +75,11 @@ _openvpn_pkcs11_card_prompt ( ASSERT (szLabel!=NULL); - openvpn_snprintf (szPrompt, sizeof (szPrompt), "INSERT"); + openvpn_snprintf (szPrompt, sizeof (szPrompt), "Please insert %s token", szLabel); token_pass.defined = false; token_pass.nocache = true; - get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE); + get_user_pass (&token_pass, NULL, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK); strncpynt (szTemp, token_pass.password, sizeof (szTemp)); purge_user_pass (&token_pass, true); @@ -2202,7 +93,7 @@ _openvpn_pkcs11_card_prompt ( static bool -_openvpn_pkcs11_pin_prompt ( +_pkcs11_openvpn_pin_prompt ( IN const void *pData, IN const char * const szLabel, OUT char * const szPIN, @@ -2217,7 +108,7 @@ _openvpn_pkcs11_pin_prompt ( token_pass.defined = false; token_pass.nocache = true; - get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE); + get_user_pass (&token_pass, NULL, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY); strncpynt (szPIN, token_pass.password, nMaxPIN); purge_user_pass (&token_pass, true); @@ -2230,213 +121,166 @@ _openvpn_pkcs11_pin_prompt ( } void -init_pkcs11 ( +pkcs11_initialize ( const int nPINCachePeriod ) { CK_RV rv; - msg ( - D_PKCS11_DEBUG, - "PKCS#11: init_pkcs11 - entered" + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: pkcs11_initialize - entered" ); - if ((rv = pkcs11_initialize ()) != CKR_OK) { - msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11_getMessage (rv)); + if ((rv = pkcs11h_initialize ()) != CKR_OK) { + PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv)); } -/*Until REQUEST/REPLY interface. - if ((rv = pkcs11_setCardPromptHook (_openvpn_pkcs11_card_prompt, NULL)) != CKR_OK) { - msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv)); + + if ((rv = pkcs11h_setCardPromptHook (_pkcs11_openvpn_card_prompt, NULL)) != CKR_OK) { + PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); } -*/ - if ((rv = pkcs11_setPINPromptHook (_openvpn_pkcs11_pin_prompt, NULL)) != CKR_OK) { - msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv)); + + if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK) { + PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv)); } - if ((rv = pkcs11_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) { - msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11_getMessage (rv)); + if ((rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) { + PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv)); } - msg ( - D_PKCS11_DEBUG, - "PKCS#11: init_pkcs11 - return" + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: pkcs11_initialize - return" ); } void -free_pkcs11 () { - msg ( - D_PKCS11_DEBUG, - "PKCS#11: free_pkcs11 - entered" +pkcs11_terminate () { + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: pkcs11_terminate - entered" ); - pkcs11_terminate (); + pkcs11h_terminate (); - msg ( - D_PKCS11_DEBUG, - "PKCS#11: free_pkcs11 - return" + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: pkcs11_terminate - return" ); } void -fork_fix_pkcs11 () { - pkcs11_forkFixup (); +pkcs11_forkFixup () { + pkcs11h_forkFixup (); } void -add_pkcs11 ( +pkcs11_addProvider ( IN const char * const provider, IN const char * const sign_mode ) { CK_RV rv; - msg ( - D_PKCS11_DEBUG, - "PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'", + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'", provider, sign_mode == NULL ? "default" : sign_mode ); - msg ( - M_INFO, + PKCS11LOG ( + PKCS11_LOG_INFO, "PKCS#11: Adding PKCS#11 provider '%s'", provider ); - if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) { - msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv)); + if ((rv = pkcs11h_addProvider (provider, sign_mode)) != CKR_OK) { + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv)); } - msg ( - D_PKCS11_DEBUG, - "PKCS#11: add_pkcs11 - return" + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: pkcs11_addProvider - return" ); } int SSL_CTX_use_pkcs11 ( IN OUT SSL_CTX * const ssl_ctx, - IN const char * const pkcs11_slot_type, - IN const char * const pkcs11_slot, - IN const char * const pkcs11_id_type, - IN const char * const pkcs11_id, - IN const bool pkcs11_protected_authentication + IN const char * const pkcs11h_slot_type, + IN const char * const pkcs11h_slot, + IN const char * const pkcs11h_id_type, + IN const char * const pkcs11h_id, + IN const bool pkcs11h_protected_authentication ) { X509 *x509 = NULL; RSA *rsa = NULL; - EVP_PKEY *pubkey = NULL; - openssl_session_t openssl_session = NULL; - bool fShouldFreeOpenSSLSession = true; + pkcs11h_openssl_session_t pkcs11h_openssl_session = NULL; CK_RV rv = CKR_OK; - unsigned char certificate[10*1024]; - size_t certificate_size; - unsigned char *p; bool fOK = true; - msg ( - D_PKCS11_DEBUG, - "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_slot_type='%s', pkcs11_slot='%s', pkcs11_id_type='%s', pkcs11_id='%s', pkcs11_protected_authentication=%d", + PKCS11LOG ( + PKCS11_LOG_DEBUG2, + "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11h_slot_type='%s', pkcs11h_slot='%s', pkcs11h_id_type='%s', pkcs11h_id='%s', pkcs11h_protected_authentication=%d", (void *)ssl_ctx, - pkcs11_slot_type, - pkcs11_slot, - pkcs11_id_type, - pkcs11_id, - pkcs11_protected_authentication ? 1 : 0 + pkcs11h_slot_type, + pkcs11h_slot, + pkcs11h_id_type, + pkcs11h_id, + pkcs11h_protected_authentication ? 1 : 0 ); - ASSERT (ssl_ctx!=NULL); - ASSERT (pkcs11_slot_type!=NULL); - ASSERT (pkcs11_slot!=NULL); - ASSERT (pkcs11_id_type!=NULL); - ASSERT (pkcs11_id!=NULL); + PKCS11ASSERT (ssl_ctx!=NULL); + PKCS11ASSERT (pkcs11h_slot_type!=NULL); + PKCS11ASSERT (pkcs11h_slot!=NULL); + PKCS11ASSERT (pkcs11h_id_type!=NULL); + PKCS11ASSERT (pkcs11h_id!=NULL); if ( fOK && - (openssl_session = (openssl_session_t)malloc (sizeof (struct openssl_session_s))) == NULL + (pkcs11h_openssl_session = pkcs11h_openssl_createSession (false)) == NULL ) { fOK = false; - msg (M_WARN, "PKCS#11: Cannot allocate memory"); + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize openssh session"); } - if (fOK) { - memset (openssl_session, 0, sizeof (struct openssl_session_s)); - } - if ( fOK && - (rv = pkcs11_createSession ( - pkcs11_slot_type, - pkcs11_slot, - pkcs11_id_type, - pkcs11_id, - pkcs11_protected_authentication, - &openssl_session->pkcs11_session + (rv = pkcs11h_createSession ( + pkcs11h_slot_type, + pkcs11h_slot, + pkcs11h_id_type, + pkcs11h_id, + pkcs11h_protected_authentication, + &pkcs11h_openssl_session->pkcs11h_session )) != CKR_OK ) { fOK = false; - msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - if ( - fOK && - (x509 = X509_new ()) == NULL - ) { - fOK = false; - msg (M_WARN, "PKCS#11: Unable to allocate certificate object"); - } - - certificate_size = sizeof (certificate); - if ( - fOK && - (rv = pkcs11_getCertificate ( - openssl_session->pkcs11_session, - certificate, - &certificate_size - )) != CKR_OK - ) { - fOK = false; - msg (M_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11_getMessage (rv)); + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv)); } - p = certificate; if ( fOK && - !d2i_X509 (&x509, &p, certificate_size) + (rsa = pkcs11h_openssl_getRSA (pkcs11h_openssl_session)) == NULL ) { fOK = false; - msg (M_WARN, "PKCS#11: Unable to parse X.509 certificate"); + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get rsa object"); } if ( fOK && - (pubkey = X509_get_pubkey (x509)) == NULL - ) { - fOK = false; - msg (M_WARN, "PKCS#11: Cannot get public key"); - } - - if ( - fOK && - pubkey->type != EVP_PKEY_RSA + (x509 = pkcs11h_openssl_getX509 (pkcs11h_openssl_session)) == NULL ) { fOK = false; - msg (M_WARN, "PKCS#11: Invalid public key algorithm"); + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get certificate object"); } if ( fOK && - (rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL + !SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa) ) { fOK = false; - msg (M_WARN, "PKCS#11: Cannot get RSA key"); - } - - if (fOK) { - openssl_pkcs11_set_rsa (openssl_session, rsa); - rsa->flags |= RSA_FLAG_SIGN_VER; - - /* it will be freed when rsa usage count will be zero */ - fShouldFreeOpenSSLSession = false; + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set private key for openssl"); } if ( @@ -2444,25 +288,13 @@ SSL_CTX_use_pkcs11 ( !SSL_CTX_use_certificate (ssl_ctx, x509) ) { fOK = false; - msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); - } - - if ( - fOK && - !SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa) - ) { - fOK = false; - msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); + PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set certificate for openssl"); } /* * openssl objects have reference * count, so release them */ - if (pubkey != NULL) { - EVP_PKEY_free (pubkey); - pubkey = NULL; - } if (x509 != NULL) { X509_free (x509); @@ -2473,19 +305,14 @@ SSL_CTX_use_pkcs11 ( RSA_free (rsa); rsa = NULL; } - - if (fShouldFreeOpenSSLSession) { - if (openssl_session != NULL) { - if (openssl_session->pkcs11_session != NULL) { - pkcs11_freeSession (openssl_session->pkcs11_session); - } - free (openssl_session); - openssl_session = NULL; - } + + if (pkcs11h_openssl_session != NULL) { + pkcs11h_openssl_freeSession (pkcs11h_openssl_session); + pkcs11h_openssl_session = NULL; } - msg ( - D_PKCS11_DEBUG, + PKCS11LOG ( + PKCS11_LOG_DEBUG2, "PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld", fOK ? 1 : 0, rv @@ -2496,460 +323,28 @@ SSL_CTX_use_pkcs11 ( void show_pkcs11_slots ( - IN const int msglev, - IN const int warnlev, - IN const char * const provider -) { - CK_INFO info; - CK_SLOT_ID slots[1024]; - CK_ULONG slotnum; - CK_SLOT_ID s; - CK_RV rv; - - pkcs11_provider_t pkcs11_provider; - - ASSERT (provider!=NULL); - - if ( - (rv = pkcs11_initialize ()) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_addProvider (provider, NULL)) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - /* - * our provider is head - */ - pkcs11_provider = pkcs11_data->providers; - if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) { - msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_provider->f->C_GetInfo (&info)) != CKR_OK - ) { - msg (warnlev, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - else { - char szManufacturerID[sizeof (info.manufacturerID)+1]; - - _fixupFixedString ( - (char *)info.manufacturerID, - szManufacturerID, - sizeof (info.manufacturerID) - ); - - msg ( - msglev, - ( - "Provider Information:\n" - "\tcryptokiVersion: %u.%u\n" - "\tmanufacturerID: %s\n" - "\tflags: %d\n" - ), - info.cryptokiVersion.major, - info.cryptokiVersion.minor, - szManufacturerID, - (unsigned)info.flags - ); - } - - slotnum = sizeof (slots) / sizeof (CK_SLOT_ID); - if ( - (rv = pkcs11_provider->f->C_GetSlotList ( - FALSE, - slots, - &slotnum - )) != CKR_OK - ) { - msg (warnlev, "PKCS#11: Cannot get slot list %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - else { - msg ( - msglev, - ( - "The following slots are available for use with this provider.\n" - "Each slot shown below may be used as a parameter to a\n" - "--pkcs11-slot-type and --pkcs11-slot options.\n" - "\n" - "Slots: (id - name)" - ) - ); - for (s=0;sf->C_GetSlotInfo ( - slots[s], - &info - )) == CKR_OK - ) { - char szCurrentName[sizeof (info.slotDescription)+1]; - - _fixupFixedString ( - (char *)info.slotDescription, - szCurrentName, - sizeof (info.slotDescription) - ); - - msg (msglev, "\t%lu - %s", slots[s], szCurrentName); - } - } - } - - pkcs11_terminate (); -} - -static -bool -_show_pkcs11_objects_pin_prompt ( - IN const void *pData, - IN const char * const szLabel, - OUT char * const szPIN, - IN const size_t nMaxPIN + const char * const provider ) { - strncpy (szPIN, (char *)pData, nMaxPIN); - return true; + pkcs11h_standalone_dump_slots ( + _pkcs11_openvpn_print, + NULL, + provider + ); } void show_pkcs11_objects ( - IN const int msglev, - IN const int warnlev, - IN const char * const provider, - IN const char * const slot, - IN const char * const pin + const char * const provider, + const char * const slot, + const char * const pin ) { - CK_OBJECT_HANDLE objects[10]; - CK_SESSION_HANDLE session; - CK_ULONG objects_found; - CK_TOKEN_INFO info; - CK_SLOT_ID s; - CK_RV rv; - - pkcs11_provider_t pkcs11_provider; - - ASSERT (provider!=NULL); - ASSERT (slot!=NULL); - ASSERT (pin!=NULL); - - s = atoi (slot); - - if ( - (rv = pkcs11_initialize ()) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_setPINPromptHook (_show_pkcs11_objects_pin_prompt, (void *)pin)) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_addProvider (provider, NULL)) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - /* - * our provider is head - */ - pkcs11_provider = pkcs11_data->providers; - if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) { - msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_provider->f->C_GetTokenInfo ( - s, - &info - )) != CKR_OK - ) { - msg (warnlev, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv)); - } - else { - char szLabel[sizeof (info.label)+1]; - char szManufacturerID[sizeof (info.manufacturerID)+1]; - char szModel[sizeof (info.model)+1]; - char szSerialNumber[sizeof (info.serialNumber)+1]; - - _fixupFixedString ( - (char *)info.label, - szLabel, - sizeof (info.label) - ); - _fixupFixedString ( - (char *)info.manufacturerID, - szManufacturerID, - sizeof (info.manufacturerID) - ); - _fixupFixedString ( - (char *)info.model, - szModel, - sizeof (info.model) - ); - _fixupFixedString ( - (char *)info.serialNumber, - szSerialNumber, - sizeof (info.serialNumber) - ); - - msg ( - msglev, - ( - "Token Information:\n" - "\tlabel:\t\t%s\n" - "\tmanufacturerID:\t%s\n" - "\tmodel:\t\t%s\n" - "\tserialNumber:\t%s\n" - "\tflags:\t\t%08x\n" - "\n" - "You can access this token using\n" - "--pkcs11-slot-type \"label\" --pkcs11-slot \"%s\" options.\n" - ), - szLabel, - szManufacturerID, - szModel, - szSerialNumber, - (unsigned)info.flags, - szLabel - ); - } - - if ( - (rv = pkcs11_provider->f->C_OpenSession ( - s, - CKF_SERIAL_SESSION, - NULL_PTR, - NULL_PTR, - &session - )) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot open session to slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_provider->f->C_Login ( - session, - CKU_USER, - (CK_CHAR_PTR)pin, - (CK_ULONG)strlen (pin) - )) != CKR_OK && - rv != CKR_USER_ALREADY_LOGGED_IN - ) { - msg (M_FATAL, "PKCS#11: Cannot login to token on slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv)); - } - - if ( - (rv = pkcs11_provider->f->C_FindObjectsInit ( - session, - NULL, - 0 - )) != CKR_OK - ) { - msg (M_FATAL, "PKCS#11: Cannot query objects for token on slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv)); - } - - msg ( - msglev, - "The following objects are available for use with this token.\n" - "Each object shown below may be used as a parameter to\n" - "--pkcs11-id-type and --pkcs11-id options.\n" + pkcs11h_standalone_dump_objects ( + _pkcs11_openvpn_print, + NULL, + provider, + slot, + pin ); - - while ( - (rv = pkcs11_provider->f->C_FindObjects ( - session, - objects, - sizeof (objects) / sizeof (CK_OBJECT_HANDLE), - &objects_found - )) == CKR_OK && - objects_found > 0 - ) { - CK_ULONG i; - - for (i=0;if->C_GetAttributeValue ( - session, - objects[i], - attrs, - sizeof (attrs) / sizeof (CK_ATTRIBUTE) - ) == CKR_OK - ) { - int id_len = attrs[1].ulValueLen; - int j; - - attrs_label[attrs[2].ulValueLen] = 0; - - msg ( - msglev, - ( - "Object\n" - "\tLabel:\t\t%s\n" - "\tId:" - ), - attrs_label - ); - - - for (j=0;jf->C_GetAttributeValue ( - session, - objects[i], - attrs_cert, - sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE) - ) == CKR_OK - ) { - X509 *x509 = NULL; - BIO *bioSerial = NULL; - - char szSubject[1024]; - char szSerial[1024]; - char szNotBefore[1024]; - - szSubject[0] = '\0'; - szSerial[0] = '\0'; - szNotBefore[0] = '\0'; - - if ((x509 = X509_new ()) == NULL) { - msg (warnlev, "Cannot create x509 context"); - } - else { - unsigned char *p; - - p = certificate; - if (d2i_X509 (&x509, &p, attrs_cert[0].ulValueLen)) { - - ASN1_TIME *notBefore = X509_get_notBefore (x509); - if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) { - memmove (szNotBefore, notBefore->data, notBefore->length); - szNotBefore[notBefore->length] = '\0'; - } - - X509_NAME_oneline ( - X509_get_subject_name (x509), - szSubject, - sizeof (szSubject) - ); - szSubject[sizeof (szSubject) - 1] = '\0'; - } - } - - if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) { - msg (warnlev, "Cannot create BIO context"); - } - else { - int n; - - i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509)); - n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1); - if (n<0) { - szSerial[0] = '\0'; - } - else { - szSerial[n] = '\0'; - } - } - - - if (x509 != NULL) { - X509_free (x509); - x509 = NULL; - } - if (bioSerial != NULL) { - BIO_free_all (bioSerial); - bioSerial = NULL; - } - - msg ( - msglev, - ( - "\tsubject:\t%s\n" - "\tserialNumber:\t%s\n" - "\tnotBefore:\t%s" - ), - szSubject, - szSerial, - szNotBefore - ); - } - } - else if (attrs_class == CKO_PRIVATE_KEY) { - CK_BBOOL sign_recover; - CK_BBOOL sign; - CK_ATTRIBUTE attrs_key[] = { - {CKA_SIGN, &sign_recover, sizeof (sign_recover)}, - {CKA_SIGN_RECOVER, &sign, sizeof (sign)} - }; - - msg (msglev, "\tType:\t\tPrivate Key"); - - if ( - pkcs11_provider->f->C_GetAttributeValue ( - session, - objects[i], - attrs_key, - sizeof (attrs_key) / sizeof (CK_ATTRIBUTE) - ) == CKR_OK - ) { - msg ( - msglev, - ( - "\tSign:\t\t%s\n" - "\tSign Recover:\t%s" - ), - sign ? "TRUE" : "FALSE", - sign_recover ? "TRUE" : "FALSE" - ); - } - } - else { - msg (msglev, "\tType:\t\tUnsupported"); - } - } - } - } - pkcs11_provider->f->C_FindObjectsFinal (session); - pkcs11_provider->f->C_Logout (session); - pkcs11_provider->f->C_CloseSession (session); - pkcs11_terminate (); } #else -- cgit