コード例 #1
0
ファイル: common.c プロジェクト: mbrossard/pkcs11
CK_RV pkcs11_login_session(CK_FUNCTION_LIST_PTR funcs, FILE *out,  CK_SLOT_ID slot,
                           CK_SESSION_HANDLE_PTR session, CK_BBOOL readwrite,
                           CK_USER_TYPE user, CK_UTF8CHAR_PTR pin, CK_ULONG pinLen)
{
    CK_SESSION_HANDLE h_session;
    CK_FLAGS flags = CKF_SERIAL_SESSION | (readwrite ? CKF_RW_SESSION : 0);
    CK_RV rc;

    rc = funcs->C_OpenSession(slot, flags, NULL, NULL, &h_session);
    if (rc != CKR_OK) {
        if(out) {
            show_error(stdout, "C_OpenSession", rc);
        }
        return rc;
    }

    if(pin) {
        rc = funcs->C_Login(h_session, user, pin, pinLen);
        if (rc != CKR_OK) {
            if(out) {
                show_error(out, "C_Login", rc);
            }
            goto end;
        }
    } else if(readwrite || pinLen > 0) {
        CK_TOKEN_INFO  info;

        rc = funcs->C_GetTokenInfo(slot, &info);
        if (rc != CKR_OK) {
            if(out) {
                show_error(out, "C_GetTokenInfo", rc);
            }
            goto end;
        }
        
        if(info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
            rc = funcs->C_Login(h_session, user, NULL, 0);
            if (rc != CKR_OK) {
                if(out) {
                    show_error(out, "C_Login", rc);
                }
                goto end;
            }
        }
    }

 end:
    if (rc != CKR_OK) {
        /* We want to keep the original error code */
        CK_RV r = funcs->C_CloseSession(h_session);
        if ((r != CKR_OK) && out) {
            show_error(out, "C_CloseSession", r);
        }
    } else if(session) {
        *session = h_session;
    }
    return rc;
}
コード例 #2
0
ファイル: esteid_sign.c プロジェクト: Krabi/idkaart_public
int EstEID_sighHashWindows(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) {
	CK_SESSION_HANDLE session = 0L;
	char message[1024];
	int remainingTries = 0;	
	CK_RV loginResult = CKR_FUNCTION_CANCELED;
	
	LOG_LOCATION;

	if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE;

	remainingTries = EstEID_getRemainingTries(slotID);
	EstEID_log("EstEID_getRemainingTries(slotID) = %i", remainingTries);
	if (remainingTries == -1)
		CLOSE_SESSION_AND_RETURN(FAILURE);
	if (!remainingTries) {
		sprintf_s(EstEID_error, ESTEID_ERROR_SIZE, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED);
		CLOSE_SESSION_AND_RETURN(FAILURE);
	}
	if (remainingTries < 3) {
		sprintf_s(message, 1024, "%s %i", l10n("Tries left:"), remainingTries);
	}
	else {
		message[0] = 0;
	}

	loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pinPromptData.pin2, strlen(pinPromptData.pin2));
	if(loginResult != CKR_OK) {
		EstEID_log("loginResult = %s", pkcs11_error_message(loginResult));
		sprintf_s(EstEID_error, 1024, "C_Login error: %s (%li)", pkcs11_error_message(loginResult), loginResult);
		CLOSE_SESSION_AND_RETURN(loginResult);
	}
	
	return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, NULL);
}
コード例 #3
0
ファイル: esteid_sign.c プロジェクト: Krabi/idkaart_public
THREAD_RETURN_TYPE EstEID_pinPadLogin(void* threadData) {
#ifndef _WIN32
	LOG_LOCATION;
	pthread_mutex_lock(&pinpad_thread_mutex);
	CK_SESSION_HANDLE session = ((EstEID_PINPadThreadData*)threadData)->session;
	CK_RV loginResult = fl->C_Login(session, CKU_USER, NULL, 0);		
	((EstEID_PINPadThreadData*)threadData)->result = loginResult;

	closePinPadModalSheet();
	EstEID_log("modal sheet/dialog destroyed");

	pinpad_thread_completed = TRUE;
	pthread_cond_broadcast(&pinpad_thread_condition);

	pthread_mutex_unlock(&pinpad_thread_mutex);
	pthread_exit(NULL);
#else
	EstEID_PINPromptDataEx* pinPromptDataEx;
	LOG_LOCATION;
	WaitForSingleObject(pinpad_thread_mutex, INFINITE);
	pinPromptDataEx = (EstEID_PINPromptDataEx*)threadData;
	pinPromptDataEx->pinPromptData.promptFunction(NULL, pinPromptDataEx->name, pinPromptDataEx->message, 0, TRUE);	
	ReleaseMutex(pinpad_thread_mutex);
	return TRUE;
#endif
}
コード例 #4
0
static void test_login() {

  CK_SESSION_HANDLE session;
  CK_SESSION_INFO   info;

  asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");

  asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");

  asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER");
  asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");

  asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
  asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");

  asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");

  asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");

}
コード例 #5
0
ファイル: dump_info.c プロジェクト: dariaphoebe/KeychainToken
CK_RV login(CK_FUNCTION_LIST_PTR p11p, CK_SESSION_HANDLE hSession, int admin, CK_UTF8CHAR *password, CK_ULONG passwordLen) {
    CK_UTF8CHAR pin[64];
    CK_ULONG pinLen = sizeof(pin) - 1;
    CK_RV rv;
    
    if (passwordLen > 0 && password != NULL && passwordLen <= pinLen) {
        memcpy(pin, password, passwordLen);
        pinLen = passwordLen;
    } else {
        printf("Enter %sPIN: ", (admin == 1) ? "admin " : "");
        rv = getPassword(pin, &pinLen);
        if (rv!= 0)
            return(-1);
    }
    
    if (admin == 1)
        rv = p11p->C_Login(hSession, CKU_SO, pin, pinLen);
    else
        rv = p11p->C_Login(hSession, CKU_USER, pin, pinLen);
    
    memset(pin, 0, sizeof(pin));
    return(rv);
}
コード例 #6
0
ファイル: hw_pk11_uri.c プロジェクト: 0xffea/illumos-userland
/*
 * Log in to the keystore in the child if we were logged in in the parent. There
 * are similarities in the code with pk11_token_login() but still it is quite
 * different so we need a separate function for this.
 *
 * Note that this function is called under the locked session mutex when fork is
 * detected. That means that C_Login() will be called from the child just once.
 *
 * Returns:
 *	1 on success
 *	0 on failure
 */
int
pk11_token_relogin(CK_SESSION_HANDLE session)
	{
	CK_RV rv;

	/*
	 * We are in the child so check if we should login to the token again.
	 * Note that it is enough to log in to the token through one session
	 * only, all already open and all future sessions can access the token
	 * then.
	 */
	if (passphrasedialog != NULL)
		{
		char *pin = NULL;

		/* If we cached the PIN then use it. */
		if (token_pin != NULL)
			pin = token_pin;
		else if (pk11_get_pin(passphrasedialog, &pin) == 0)
			goto err;

		(void) pthread_mutex_lock(uri_lock);
		if ((rv = pFuncList->C_Login(session, CKU_USER,
		    (CK_UTF8CHAR_PTR)pin, strlen(pin))) != CKR_OK)
			{
			PK11err_add_data(PK11_F_TOKEN_RELOGIN,
			    PK11_R_TOKEN_LOGIN_FAILED, rv);
			(void) pthread_mutex_unlock(uri_lock);
			goto err;
			}
		(void) pthread_mutex_unlock(uri_lock);

		/* Forget the PIN now if we did not cache it before. */
		if (pin != token_pin)
			{
			memset(pin, 0, strlen(pin));
			OPENSSL_free(pin);
			}
		}

	return (1);
err:
	return (0);
	}
コード例 #7
0
// Connect and login to the token
int openP11(CK_SLOT_ID slotID, char* userPIN, CK_SESSION_HANDLE* hSession)
{
	char user_pin_copy[MAX_PIN_LEN+1];
	CK_RV rv;

	rv = p11->C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION,
					NULL_PTR, NULL_PTR, hSession);
	if (rv != CKR_OK)
	{
		if (rv == CKR_SLOT_ID_INVALID)
		{
			fprintf(stderr, "ERROR: The given slot does not exist.\n");
		}
		else
		{
			fprintf(stderr, "ERROR: Could not open a session on the given slot.\n");
		}
		return 1;
	}

	// Get the password
	if (getPW(userPIN, user_pin_copy, CKU_USER) != 0)
	{
		fprintf(stderr, "ERROR: Could not get user PIN\n");
		return 1;
	}

	rv = p11->C_Login(*hSession, CKU_USER, (CK_UTF8CHAR_PTR)user_pin_copy, strlen(user_pin_copy));
	if (rv != CKR_OK)
	{
		if (rv == CKR_PIN_INCORRECT) {
			fprintf(stderr, "ERROR: The given user PIN does not match the one in the token.\n");
		}
		else
		{
			fprintf(stderr, "ERROR: Could not log in on the token.\n");
		}
		return 1;
	}

	return 0;
}
コード例 #8
0
static CK_RV
hacky_perform_initialize_pin (GP11Slot *slot)
{
	CK_FUNCTION_LIST_PTR funcs;
	CK_SESSION_HANDLE session;
	CK_SLOT_ID slot_id;
	CK_RV rv;
	
	/* 
	 * This hack only works when:
	 *  
	 *  - Module is protected authentication path
	 *  - No other sessions are open.
	 *  
	 *  Thankfully this is the case with mate-keyring-daemon and 
	 *  the mate-keyring tool. 
	 */
	
	funcs = gp11_module_get_functions (gp11_slot_get_module (slot));
	g_return_val_if_fail (funcs, CKR_GENERAL_ERROR);
	slot_id = gp11_slot_get_handle (slot);
	
	rv = funcs->C_OpenSession (slot_id, CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, &session);
	if (rv != CKR_OK)
		return rv;
	
	rv = funcs->C_Login (session, CKU_SO, NULL, 0);
	if (rv == CKR_OK) {
		rv = funcs->C_InitPIN (session, NULL, 0);
		funcs->C_Logout (session);
	}
	
	funcs->C_CloseSession (session);
	
	return rv;
}
コード例 #9
0
ファイル: esteid_sign.c プロジェクト: Krabi/idkaart_public
int EstEID_signHash(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) {
	CK_SESSION_HANDLE session = 0L;
	LOG_LOCATION;

	if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE;

	char *name = EstEID_getFullNameWithPersonalCode(cert);

	for (int attempt = 0, blocked = FALSE;; attempt++) {
		char message[1024];

		int remainingTries = EstEID_getRemainingTries(slotID);
		if (remainingTries == -1)
			CLOSE_SESSION_AND_RETURN(FAILURE);
		if (!remainingTries || blocked) {
			sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED);
			pinPromptData.alertFunction(pinPromptData.nativeWindowHandle, l10n("PIN2 blocked, can not sign!"));
			CLOSE_SESSION_AND_RETURN(FAILURE);
		}
		if (remainingTries < 3 || attempt) {
			sprintf(message, "%s%s %i", (attempt ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries);
		}
		else {
			message[0] = 0;
		}

		int isPinPad = EstEID_isPinPad(slotID);
		CK_RV loginResult = CKR_FUNCTION_CANCELED;
		if(!isPinPad) {
			// Simple card reader
			char *pin = pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")), isPinPad);
			if (!pin || strlen(pin) == 0) {
				if (pin) free(pin);
				setUserCancelErrorCodeAndMessage();
				CLOSE_SESSION_AND_RETURN(FAILURE);
			}
			loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pin, strlen(pin));
			free(pin);
		}
		else {
			// PIN pad			
#ifdef _WIN32
			EstEID_log("creating pinpad dialog UI thread");
			pinpad_thread_result = -1;
			FAIL_IF_THREAD_ERROR("CreateMutex", (pinpad_thread_mutex = CreateMutex(NULL, FALSE, NULL)));
#else
			EstEID_log("creating pinpad worker thread");
			pinpad_thread_result = -1;
			FAIL_IF_PTHREAD_ERROR("pthread_mutex_init", pthread_mutex_init(&pinpad_thread_mutex, NULL));
			FAIL_IF_PTHREAD_ERROR("pthread_cond_init", pthread_cond_init(&pinpad_thread_condition, NULL));
			pthread_t pinpad_thread;
			EstEID_PINPadThreadData threadData;
			threadData.session = session;
			threadData.result = CKR_OK;
#endif
			EstEID_log("thread launched");
#ifdef _WIN32
			/*
			NB! Due to Firefox for Windows specific behaviour C_Login() is launched from main thread
			and UI code is running in separate thread if running on Windows.
			*/
			EstEID_PINPromptDataEx pinPromptDataEx;
			pinPromptDataEx.pinPromptData = pinPromptData;
			pinPromptDataEx.message = message;
			pinPromptDataEx.name = name;
			CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_pinPadLogin, (LPVOID)&pinPromptDataEx, 0, NULL);
			loginResult = fl->C_Login(session, CKU_USER, NULL, 0);
			closePinPadModalSheet();
#else
			FAIL_IF_PTHREAD_ERROR("pthread_create", pthread_create(&pinpad_thread, NULL, EstEID_pinPadLogin, (void*)&threadData));
			pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, 0, isPinPad);
			loginResult = threadData.result;
#endif
			EstEID_log("pinpad sheet/dialog closed");			
			if (loginResult == CKR_FUNCTION_CANCELED) {
				setUserCancelErrorCodeAndMessage();				
				CLOSE_SESSION_AND_RETURN(FAILURE);
			}
		}
		EstEID_log("loginResult = %s", pkcs11_error_message(loginResult));
		switch (loginResult) {
			case CKR_PIN_LOCKED:
				blocked = TRUE;
			case CKR_PIN_INCORRECT:
			case CKR_PIN_INVALID:
			case CKR_PIN_LEN_RANGE:
				EstEID_log("this was attempt %i, loginResult causes to run next round", attempt);
				continue;
			default:
				if (EstEID_CK_failure("C_Login", loginResult)) CLOSE_SESSION_AND_RETURN(FAILURE);
		}
		break; // Login successful - correct PIN supplied
	}

	return EstEID_RealSign(session, signature, signatureLength, hash, hashLength, name);
}
コード例 #10
0
ファイル: main.cpp プロジェクト: ggonzalez/Man-In-Remote
void
processRequest(int client)
{
	DataMarshalling	*d = NULL;

	while (1) {
		d = new DataMarshalling(client);
		d->recvData();
		if (!strcmp(d->getMsgType(), "C_Initialize")) {
			int	p = 0;
			printf("Processing: C_Initialize\n");
			p = d->unpackInt();
			if (p == 0)
				pFunctionList->C_Initialize(NULL);
			else {
				printf("ERROR: C_Initialize shouldn't be called with not NULL\n");
			}
		} else if (!strcmp(d->getMsgType(), "C_Finalize")) {
			int		p = 0;
			CK_RV	ret = 0;

			printf("Processing: C_Finalize\n");
			p = d->unpackInt();
			if (p == NULL) {
				ret = pFunctionList->C_Finalize(NULL);
			} else {
				printf("ERROR: C_Finalize shouldn't be called with not NULL\n");
				ret = CKR_CANCEL;
			}
			{
				CK_ULONG		count = 0;
				
				DataMarshalling	*d2 = new DataMarshalling(client);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
			break;
		} else if (!strcmp(d->getMsgType(), "C_GetSlotList")) {
			int	p = 0;
			printf("Processing: C_GetSlotList\n");
			p = d->unpackInt();
			if (p == 0) {
				CK_ULONG		count = 0;
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Retrieving Slots size
				 */
				ret = pFunctionList->C_GetSlotList(TRUE, NULL, &count);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&count);
				d2->sendData();
				delete d2;
			} else {
				CK_ULONG		count = 0;
				CK_SLOT_ID_PTR	slot = NULL;
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Retrieving Slots size
				 */
				pFunctionList->C_GetSlotList(TRUE, NULL, &count);
				slot = new(CK_SLOT_ID[count]);

				ret = pFunctionList->C_GetSlotList(TRUE, slot, &count);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&count);
				for (int i = 0; i < count; i ++)
					d2->packInt((char *)&slot[i]);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_OpenSession")) {
			unsigned int	slotId = 0, flags = 0;
			CK_SESSION_HANDLE	sessionId = 0;
			printf("Processing: C_OpenSession\n");
			slotId = d->unpackInt();
			flags = d->unpackInt();
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_OpenSession(slotId, flags, NULL, NULL, &sessionId);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&sessionId);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_CloseSession")) {
			CK_SESSION_HANDLE	sessionId = 0;
			printf("Processing: C_CloseSession\n");
			sessionId = d->unpackInt();
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_CloseSession(sessionId);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetInfo")) {
			unsigned int	slotId = 0, flags = 0;
			CK_SESSION_HANDLE	sessionId = 0;
			CK_INFO		info;
			printf("Processing: C_GetInfo\n");
			slotId = d->unpackInt();
			{
				CK_RV			ret = 0;
				CK_TOKEN_INFO	token;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_GetInfo(&info);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packChar(info.cryptokiVersion.major);
				d2->packChar(info.cryptokiVersion.minor);
				d2->packMem((char *)info.manufacturerID, 32);
				d2->packInt((char *)&info.flags);
				d2->packMem((char *)info.libraryDescription, 32);
				d2->packChar(info.libraryVersion.major);
				d2->packChar(info.libraryVersion.minor);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetSlotInfo")) {
			unsigned int	slotId = 0, flags = 0;
			CK_SESSION_HANDLE	sessionId = 0;
			printf("Processing: C_GetSlotInfo\n");
			slotId = d->unpackInt();
			{
				CK_RV			ret = 0;
				CK_SLOT_INFO	slot;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_GetSlotInfo(slotId, &slot);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packMem((char *)slot.slotDescription, 64);
				d2->packMem((char *)slot.manufacturerID, 32);
				d2->packInt((char *)&slot.flags);
				d2->packChar(slot.hardwareVersion.major);
				d2->packChar(slot.hardwareVersion.minor);
				d2->packChar(slot.firmwareVersion.major);
				d2->packChar(slot.firmwareVersion.minor);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetTokenInfo")) {
			unsigned int	slotId = 0, flags = 0;
			CK_SESSION_HANDLE	sessionId = 0;
			printf("Processing: C_GetTokenInfo\n");
			slotId = d->unpackInt();
			{
				CK_RV			ret = 0;
				CK_TOKEN_INFO	token;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_GetTokenInfo(slotId, &token);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packMem((char *)token.label, 32);
				d2->packMem((char *)token.manufacturerID, 32);
				d2->packMem((char *)token.model, 16);
				d2->packMem((char *)token.serialNumber, 16);
				d2->packInt((char *)&token.flags);
				d2->packInt((char *)&token.ulMaxSessionCount);
				d2->packInt((char *)&token.ulSessionCount);
				d2->packInt((char *)&token.ulMaxRwSessionCount);
				d2->packInt((char *)&token.ulRwSessionCount);
				d2->packInt((char *)&token.ulMaxPinLen);
				d2->packInt((char *)&token.ulMinPinLen);
				d2->packInt((char *)&token.ulTotalPublicMemory);
				d2->packInt((char *)&token.ulFreePublicMemory);
				d2->packInt((char *)&token.ulTotalPrivateMemory);
				d2->packInt((char *)&token.ulFreePrivateMemory);
				d2->packChar(token.hardwareVersion.major);
				d2->packChar(token.hardwareVersion.minor);
				d2->packChar(token.firmwareVersion.major);
				d2->packChar(token.firmwareVersion.minor);
				d2->packMem((char *)token.utcTime, 16);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetMechanismList")) {
			unsigned int	slotId = 0;
			CK_MECHANISM_TYPE_PTR	pMechanismList = NULL;
			printf("Processing: C_GetMechanismList\n");
			slotId = d->unpackInt();
			pMechanismList = (CK_MECHANISM_TYPE_PTR)d->unpackInt();
			if (pMechanismList == NULL) {
				CK_ULONG		count = 0;
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Retrieving Slots size
				 */
				ret = pFunctionList->C_GetMechanismList(slotId, pMechanismList, &count);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&count);
				printf("C_GetMechanismList count: %d\n", count);
				d2->sendData();
				delete d2;
			} else {
				CK_ULONG		count = 0;
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Retrieving Slots size
				 */
				pFunctionList->C_GetMechanismList(TRUE, NULL, &count);
				pMechanismList = new(CK_MECHANISM_TYPE[count]);

				ret = pFunctionList->C_GetMechanismList(slotId, pMechanismList, &count);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&count);
				printf("C_GetMechanismList count: %d\n", count);
				for (int i = 0; i < count; i ++)
					d2->packInt((char *)&pMechanismList[i]);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetMechanismInfo")) {
			unsigned int	slotId = 0, mechanismType = 0;
			printf("Processing: C_GetMechanismInfo\n");
			slotId = d->unpackInt();
			mechanismType = d->unpackInt();
			{
				CK_RV				ret = 0;
				CK_MECHANISM_INFO	mechanism;
				DataMarshalling	*d2 = new DataMarshalling(client);

				ret = pFunctionList->C_GetMechanismInfo(slotId, mechanismType, &mechanism);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&mechanism.ulMinKeySize);
				d2->packInt((char *)&mechanism.ulMaxKeySize);
				d2->packInt((char *)&mechanism.flags);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_Login")) {
			CK_SESSION_HANDLE	sessionId = 0;
			unsigned int		user = 0, len = 0;
			CK_CHAR_PTR			pin = NULL;

			printf("Processing: C_Login\n");

			sessionId = d->unpackInt();
			user = d->unpackInt();
			len = d->unpackInt();
			pin = (CK_CHAR_PTR) calloc(1, len + 1);
			if (!pin) {
				printf("ERROR: NO MEMORY\n");
				break;
			}
			d->unpackMem((char *)pin, len);
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_Login(sessionId, user, pin, len);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_Logout")) {
			CK_SESSION_HANDLE	sessionId = 0;

			printf("Processing: C_Logout\n");

			sessionId = d->unpackInt();
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_Logout(sessionId);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_FindObjectsInit")) {
			CK_SESSION_HANDLE	sessionId = 0;
			unsigned int		len = 0;
			CK_ATTRIBUTE_PTR	attr = NULL;

			printf("Processing: C_FindObjectsInit\n");

			sessionId = d->unpackInt();
			len = d->unpackInt();
			attr = (CK_ATTRIBUTE_PTR) calloc(len, sizeof(CK_ATTRIBUTE));
			if (!attr) {
				printf("ERROR: NO MEMORY\n");
				break;
			}
			for (int i = 0; i < len; i ++) {
				attr[i].type = d->unpackInt();
				attr[i].ulValueLen = d->unpackInt();
				attr[i].pValue = (char *)calloc(1, attr[i].ulValueLen);
				d->unpackMem((char *)attr[i].pValue, attr[i].ulValueLen);
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_FindObjectsInit(sessionId, attr, len);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_FindObjects")) {
			CK_SESSION_HANDLE	sessionId = 0;
			CK_OBJECT_HANDLE_PTR	phObject = NULL;
			CK_ULONG			len = 0, maxlen = 0;

			printf("Processing: C_FindObjects\n");

			sessionId = d->unpackInt();
			maxlen = d->unpackInt();
			if (maxlen > 0) {
				phObject = new(CK_OBJECT_HANDLE[maxlen]);
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_FindObjects(sessionId, phObject, maxlen, &len);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&len);
				for (int i = 0; i < len && i < maxlen; i ++)
					d2->packInt((char *)&phObject[i]);
				
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetAttributeValue")) {
			CK_SESSION_HANDLE	sessionId = 0;
			CK_OBJECT_HANDLE	hObject = 0;
			CK_ULONG			len = 0;
			CK_ATTRIBUTE_PTR	attr = NULL;

			printf("Processing: C_GetAttributeValue\n");

			sessionId = d->unpackInt();
			hObject = d->unpackInt();
			len = d->unpackInt();
			attr = (CK_ATTRIBUTE_PTR) calloc(len, sizeof(CK_ATTRIBUTE));
			if (!attr) {
				printf("ERROR: NO MEM C_GetAttributeValue\n");
				break;
			}
			for (int i = 0; i < len; i ++) {
				attr[i].type = d->unpackInt();
				attr[i].ulValueLen = d->unpackInt();
				attr[i].pValue = (char *)d->unpackInt();
				if (attr[i].pValue != NULL) {
					attr[i].pValue = (char *)calloc(1, attr[i].ulValueLen);
					if (!attr[i].pValue) {
						printf("ERROR: NO MEM\n");
						exit(-1);
					}
					//d->unpackMem((char *)attr[i].pValue, attr[i].ulValueLen);
				}
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);

				ret = pFunctionList->C_GetAttributeValue(sessionId, hObject, attr, len);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				for (int i = 0; i < len; i ++) {
					d2->packInt((char *)&attr[i].type);
					d2->packInt((char *)&attr[i].ulValueLen);
					d2->packInt((char *)&attr[i].pValue);
					if (attr[i].pValue != NULL) {
						d2->packMem((char *)attr[i].pValue, attr[i].ulValueLen);
#ifdef FUNC_DEBUG_
						if (i == 2) {
							PCCERT_CONTEXT	pCertContext;

							pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,((BYTE *)attr[i].pValue),attr[i].ulValueLen);
							printf("data len: %d\n", attr[i].ulValueLen);
							printf("issuer len: %d\n", pCertContext->pCertInfo->Issuer.cbData);
							std::wcout << byte2str(pCertContext->pCertInfo->Issuer.pbData, pCertContext->pCertInfo->Issuer.cbData);
							CertFreeCertificateContext(pCertContext);
						}
		
#endif
					}
				}
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_FindObjectsFinal")) {
			CK_SESSION_HANDLE	sessionId = 0;

			printf("Processing: C_FindObjectsFinal\n");

			sessionId = d->unpackInt();
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_FindObjectsFinal(sessionId);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_SignInit")) {
			CK_SESSION_HANDLE	sessionId = 0;
			CK_MECHANISM		mechanism;
			CK_OBJECT_HANDLE	hKey;

			printf("Processing: C_SignInit\n");

			sessionId = d->unpackInt();
			hKey = d->unpackInt();
			mechanism.mechanism = d->unpackInt();
			mechanism.ulParameterLen = d->unpackInt();
			mechanism.pParameter = NULL;
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_SignInit(sessionId, &mechanism, hKey);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_Sign")) {
			CK_SESSION_HANDLE	sessionId = 0;
			char				*data = NULL, *signature = NULL;
			CK_ULONG			dataLen = 0, signatureLen = 0;

			printf("Processing: C_Sign\n");

			sessionId = d->unpackInt();
			dataLen = d->unpackInt();
			data = (char *)d->unpackInt();
			if (data != NULL) {
				data = (char *)calloc(1, dataLen);
				if (!data) {
					printf("ERROR: NO MEM C_Sign\n");
					break;
				}
				d->unpackMem((char *)data, dataLen);
			}
			signatureLen = d->unpackInt();
			signature = (char *)d->unpackInt();
			if (signature != NULL) {
				signature = (char *)calloc(1, signatureLen);
				if (!signature) {
					printf("ERROR: NO MEM C_Sign\n");
					break;
				}
				d->unpackMem((char *)signature, signatureLen);
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_Sign(sessionId, (CK_BYTE_PTR)data, dataLen, (CK_BYTE_PTR)signature, &signatureLen);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&signatureLen);
				if (signature != NULL)
					d2->packMem((char *)signature, signatureLen);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_VerifyInit")) {
			CK_SESSION_HANDLE	sessionId = 0;
			CK_MECHANISM		mechanism;
			CK_OBJECT_HANDLE	hKey;

			printf("Processing: C_VerifyInit\n");

			sessionId = d->unpackInt();
			hKey = d->unpackInt();
			mechanism.mechanism = d->unpackInt();
			mechanism.ulParameterLen = d->unpackInt();
			mechanism.pParameter = NULL;
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_VerifyInit(sessionId, &mechanism, hKey);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_Verify")) {
			CK_SESSION_HANDLE	sessionId = 0;
			char				*data = NULL, *signature = NULL;
			CK_ULONG			dataLen = 0, signatureLen = 0;

			printf("Processing: C_Verify\n");

			sessionId = d->unpackInt();
			dataLen = d->unpackInt();
			data = (char *)d->unpackInt();
			if (data != NULL) {
				data = (char *)calloc(1, dataLen);
				if (!data) {
					printf("ERROR: NO MEM C_Verify\n");
					break;
				}
				d->unpackMem((char *)data, dataLen);
			}
			signatureLen = d->unpackInt();
			signature = (char *)d->unpackInt();
			if (signature != NULL) {
				signature = (char *)calloc(1, signatureLen);
				if (!signature) {
					printf("ERROR: NO MEM C_Verify\n");
					break;
				}
				d->unpackMem((char *)signature, signatureLen);
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_Verify(sessionId, (CK_BYTE_PTR)data, dataLen, (CK_BYTE_PTR)signature, signatureLen);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GenerateRandom")) {
			CK_SESSION_HANDLE	sessionId = 0;
			char				*data = NULL;
			CK_ULONG			dataLen = 0;

			printf("Processing: C_GenerateRandom\n");

			sessionId = d->unpackInt();
			dataLen = d->unpackInt();
			data = (char *)d->unpackInt();
			if (data != NULL) {
				data = (char *)calloc(1, dataLen);
				if (!data) {
					printf("ERROR: NO MEM C_GenerateRandom\n");
					break;
				}
				//d->unpackMem((char *)data, dataLen);
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_GenerateRandom(sessionId, (CK_BYTE_PTR)data, dataLen);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				if (data != NULL)
					d2->packMem((char *)data, dataLen);
				d2->sendData();
				delete d2;
			}
		}  else if (!strcmp(d->getMsgType(), "C_SeedRandom")) {
			CK_SESSION_HANDLE	sessionId = 0;
			char				*data = NULL;
			CK_ULONG			dataLen = 0;

			printf("Processing: C_SeedRandom\n");

			sessionId = d->unpackInt();
			dataLen = d->unpackInt();
			data = (char *)d->unpackInt();
			if (data != NULL) {
				data = (char *)calloc(1, dataLen);
				if (!data) {
					printf("ERROR: NO MEM C_SeedRandom\n");
					break;
				}
				d->unpackMem((char *)data, dataLen);
			}
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_SeedRandom(sessionId, (CK_BYTE_PTR)data, dataLen);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_GetSessionInfo")) {
			CK_SESSION_HANDLE	sessionId = 0;

			printf("Processing: C_GetSessionInfo\n");
			sessionId = d->unpackInt();
			{
				CK_RV			ret = 0;
				CK_SESSION_INFO	info;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_GetSessionInfo(sessionId, &info);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->packInt((char *)&info.slotID);
				d2->packInt((char *)&info.state);
				d2->packInt((char *)&info.flags);
				d2->packInt((char *)&info.ulDeviceError);
				d2->sendData();
				delete d2;
			}
		} else if (!strcmp(d->getMsgType(), "C_CloseAllSessions")) {
			CK_SLOT_ID	slotID = 0;

			printf("Processing: C_Logout\n");

			slotID = d->unpackInt();
			{
				CK_RV			ret = 0;
				DataMarshalling	*d2 = new DataMarshalling(client);
				/*
				 * Opening session
				 */
				ret = pFunctionList->C_CloseAllSessions(slotID);
				d2->setMsgType(d->getMsgType());
				d2->packInt((char *)&ret);
				d2->sendData();
				delete d2;
			}
		} else {
			pFunctionList->C_Finalize(NULL);
		}
		delete d;
	}
}
コード例 #11
0
ファイル: hw_pk11_uri.c プロジェクト: 0xffea/illumos-userland
/*
 * Log in to the keystore if we are supposed to do that at all. Take care of
 * reading and caching the PIN etc. Log in only once even when called from
 * multiple threads.
 *
 * Returns:
 *	1 on success
 *	0 on failure
 */
int
pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
    pkcs11_uri *uri_struct, CK_BBOOL is_private)
	{
	CK_RV rv;

	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
		{
		PK11err(PK11_F_TOKEN_LOGIN,
		    PK11_R_TOKEN_NOT_INITIALIZED);
		goto err;
		}

	/*
	 * If login is required or needed but the PIN has not been even
	 * initialized we can bail out right now. Note that we are supposed to
	 * always log in if we are going to access private keys. However, we may
	 * need to log in even for accessing public keys in case that the
	 * CKF_LOGIN_REQUIRED flag is set.
	 */
	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED ||
	    is_private == CK_TRUE) && ~pubkey_token_flags &
	    CKF_USER_PIN_INITIALIZED)
		{
		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
		goto err;
		}

	/*
	 * Note on locking: it is possible that more than one thread gets into
	 * pk11_get_pin() so we must deal with that. We cannot avoid it since we
	 * cannot guard fork() in there with a lock because we could end up in
	 * a dead lock in the child. Why? Remember we are in a multithreaded
	 * environment so we must lock all mutexes in the prefork function to
	 * avoid a situation in which a thread that did not call fork() held a
	 * lock, making future unlocking impossible. We lock right before
	 * C_Login().
	 */
	if (pubkey_token_flags & CKF_LOGIN_REQUIRED || is_private == CK_TRUE)
		{
		if (*login_done == CK_FALSE &&
		    uri_struct->askpass == NULL)
			{
			PK11err(PK11_F_TOKEN_LOGIN,
			    PK11_R_TOKEN_PIN_NOT_PROVIDED);
			goto err;
			}

		if (*login_done == CK_FALSE &&
		    uri_struct->askpass != NULL)
			{
			if (pk11_get_pin(uri_struct->askpass,
			    &uri_struct->pin) == 0)
				{
				PK11err(PK11_F_TOKEN_LOGIN,
				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
				goto err;
				}
			}

		/*
		 * Note that what we are logging into is the keystore from
		 * pubkey_SLOTID because we work with OP_RSA session type here.
		 * That also means that we can work with only one keystore in
		 * the engine.
		 *
		 * We must make sure we do not try to login more than once.
		 * Also, see the comment above on locking strategy.
		 */
		(void) pthread_mutex_lock(uri_lock);
		if (*login_done == CK_FALSE)
			{
			if ((rv = pFuncList->C_Login(session,
			    CKU_USER, (CK_UTF8CHAR*)uri_struct->pin,
			    strlen(uri_struct->pin))) != CKR_OK)
				{
				PK11err_add_data(PK11_F_TOKEN_LOGIN,
				    PK11_R_TOKEN_LOGIN_FAILED, rv);
				goto err_locked;
				}

			*login_done = CK_TRUE;

			/*
			 * Cache the passphrasedialog for possible child (which
			 * would need to relogin).
			 */
			if (passphrasedialog == NULL &&
			    uri_struct->askpass != NULL)
				{
				passphrasedialog =
				    strdup(uri_struct->askpass);

				if (passphrasedialog == NULL)
					{
					PK11err_add_data(PK11_F_TOKEN_LOGIN,
					    PK11_R_MALLOC_FAILURE, rv);
					goto err_locked;
					}
				}

			/*
			 * Check the PIN caching policy. Note that user might
			 * have provided a PIN even when no PIN was required -
			 * in that case we always remove the PIN from memory.
			 */
			if (pk11_get_pin_caching_policy() ==
			    POLICY_WRONG_VALUE)
				{
				PK11err(PK11_F_TOKEN_LOGIN,
				    PK11_R_PIN_CACHING_POLICY_INVALID);
				goto err_locked;
				}

			if (pk11_get_pin_caching_policy() != POLICY_NONE)
				if (pk11_cache_pin(uri_struct->pin) == 0)
					goto err_locked;
			}
		(void) pthread_mutex_unlock(uri_lock);
		}
	else
		{
			/*
			 * If token does not require login we take it as the
			 * login was done.
			 */
			*login_done = CK_TRUE;
		}

	/*
	 * If we raced at pk11_get_pin() we must make sure that all threads that
	 * called pk11_get_pin() will erase the PIN from memory, not just the
	 * one that called C_Login(). Note that if we were supposed to cache the
	 * PIN it was already cached by now so filling "uri_struct.pin" with
	 * zero bytes is always OK since pk11_cache_pin() makes a copy of it.
	 */
	if (uri_struct->pin != NULL)
		memset(uri_struct->pin, 0, strlen(uri_struct->pin));

	return (1);

err_locked:
	(void) pthread_mutex_unlock(uri_lock);
err:
	/* Always get rid of the PIN. */
	if (uri_struct->pin != NULL)
		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
	return (0);
	}
コード例 #12
0
ファイル: esteid_sign.c プロジェクト: Krabi/idkaart_public
int EstEID_signHash(char **signature, unsigned int *signatureLength, CK_SLOT_ID slotID, EstEID_Map cert, const char *hash, unsigned int hashLength, EstEID_PINPromptData pinPromptData) {
	CK_SESSION_HANDLE session = 0L;

	if (EstEID_CK_failure("C_OpenSession", fl->C_OpenSession(slotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &session))) return FAILURE;

	const char *givenName = EstEID_mapGet(cert, "givenName");
	if (!givenName) givenName = "";
	const char *surname = EstEID_mapGet(cert, "surname");
	if (!surname) surname = "";
	const char *personalID = EstEID_mapGet(cert, "serialNumber");
	if (!personalID) personalID = "";

	char *name = (char *)malloc(strlen(givenName) + strlen(surname) + strlen(personalID) + 4);
	sprintf(name, "%s %s", givenName, surname);
	if(strlen(personalID)) {
		strcat(name, ", ");
		strcat(name, personalID);
	}

	for (int attempt = 0, blocked = FALSE;; attempt++) {
		char message[1024];

		int remainingTries = EstEID_getRemainingTries(slotID);
		if (remainingTries == -1)
			CLOSE_SESSION_AND_FAIL;
		if (!remainingTries || blocked) {
			sprintf(EstEID_error, "C_Login error: %s (%li)", pkcs11_error_message(CKR_PIN_LOCKED), CKR_PIN_LOCKED);
			pinPromptData.alertFunction(pinPromptData.nativeWindowHandle, l10n("PIN2 blocked, cannot sign!"));
			CLOSE_SESSION_AND_FAIL;
		}
		if (remainingTries < 3 || attempt) {
			sprintf(message, "%s%s %i", (attempt ? l10n("Incorrect PIN2! ") : ""), l10n("Tries left:"), remainingTries);
		}
		else {
			message[0] = 0;
		}

		int isPinPad = EstEID_isPinPad(slotID);
		CK_RV loginResult = CKR_FUNCTION_CANCELED;
		if(!isPinPad) {
			// Simple card reader
			char *pin = pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, (unsigned)atoi(EstEID_mapGet(cert, "minPinLen")), isPinPad);
			if (!pin || strlen(pin) == 0) {
				if (pin) free(pin);
				setUserCancelErrorCodeAndMessage();
				CLOSE_SESSION_AND_FAIL;
			}
			loginResult = fl->C_Login(session, CKU_USER, (unsigned char *)pin, strlen(pin));
			free(pin);
		}
		else {
			// PIN pad			
#ifdef _WIN32
			EstEID_log("creating pinpad dialog UI thread");
			pinpad_thread_result = -1;
			FAIL_IF_THREAD_ERROR("CreateMutex", (pinpad_thread_mutex = CreateMutex(NULL, FALSE, NULL)));
#else
			EstEID_log("creating pinpad worker thread");
			pinpad_thread_result = -1;
			FAIL_IF_PTHREAD_ERROR("pthread_mutex_init", pthread_mutex_init(&pinpad_thread_mutex, NULL));
			FAIL_IF_PTHREAD_ERROR("pthread_cond_init", pthread_cond_init(&pinpad_thread_condition, NULL));
			pthread_t pinpad_thread;
			EstEID_PINPadThreadData threadData;
			threadData.session = session;
			threadData.result = CKR_OK;
#endif
			EstEID_log("thread launched");
#ifdef _WIN32
			/*
			NB! Due to Firefox for Windows specific behaviour C_Login() is launched from main thread
			and UI code is running in separate thread if running on Windows.
			*/
			EstEID_PINPromptDataEx pinPromptDataEx;
			pinPromptDataEx.pinPromptData = pinPromptData;
			pinPromptDataEx.message = message;
			pinPromptDataEx.name = name;
			CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&EstEID_pinPadLogin, (LPVOID)&pinPromptDataEx, 0, NULL);
			loginResult = fl->C_Login(session, CKU_USER, NULL, 0);
			closePinPadModalSheet();
#else
			FAIL_IF_PTHREAD_ERROR("pthread_create", pthread_create(&pinpad_thread, NULL, EstEID_pinPadLogin, (void*)&threadData));
			pinPromptData.promptFunction(pinPromptData.nativeWindowHandle, name, message, 0, isPinPad);
			loginResult = threadData.result;
#endif
			EstEID_log("pinpad sheet/dialog closed");			
			if (loginResult == CKR_FUNCTION_CANCELED) {
				setUserCancelErrorCodeAndMessage();				
				CLOSE_SESSION_AND_FAIL;				
			}
		}
		EstEID_log("loginResult = %s", pkcs11_error_message(loginResult));
		switch (loginResult) {
			case CKR_PIN_LOCKED:
				blocked = TRUE;
			case CKR_PIN_INCORRECT:
			case CKR_PIN_INVALID:
			case CKR_PIN_LEN_RANGE:
				EstEID_log("this was attempt %i, loginResult causes to run next round", attempt);
				continue;
			default:
				if (EstEID_CK_failure("C_Login", loginResult)) CLOSE_SESSION_AND_FAIL;
		}
		break; // Login successful - correct PIN supplied
	}

	if (name){
		free(name);
		name = NULL;
	}

	CK_OBJECT_CLASS objectClass = CKO_PRIVATE_KEY;
	CK_ATTRIBUTE searchAttribute = {CKA_CLASS, &objectClass, sizeof(objectClass)};
	if (EstEID_CK_failure("C_FindObjectsInit", fl->C_FindObjectsInit(session, &searchAttribute, 1))) CLOSE_SESSION_AND_FAIL;

	CK_OBJECT_HANDLE privateKeyHandle;
	CK_ULONG objectCount;
	if (EstEID_CK_failure("C_FindObjects", fl->C_FindObjects(session, &privateKeyHandle, 1, &objectCount))) CLOSE_SESSION_AND_FAIL;
	if (EstEID_CK_failure("C_FindObjectsFinal", fl->C_FindObjectsFinal(session))) CLOSE_SESSION_AND_FAIL;

	if (objectCount == 0) CLOSE_SESSION_AND_FAIL; // todo ?? set error message

	CK_MECHANISM mechanism = {CKM_RSA_PKCS, 0, 0};
	if (EstEID_CK_failure("C_SignInit", fl->C_SignInit(session, &mechanism, privateKeyHandle))) CLOSE_SESSION_AND_FAIL;

	unsigned int hashWithPaddingLength;
	char *hashWithPadding = EstEID_addPadding(hash, hashLength, &hashWithPaddingLength);

	CK_ULONG len;
	if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, NULL, &len))) {
		free(hashWithPadding);
		CLOSE_SESSION_AND_FAIL;
	}
	*signature = (char *)malloc(len);
	if (EstEID_CK_failure("C_Sign", fl->C_Sign(session, (CK_BYTE_PTR)hashWithPadding, hashWithPaddingLength, (CK_BYTE_PTR) * signature, &len))) {
		free(hashWithPadding);
		CLOSE_SESSION_AND_FAIL;
	}
	*signatureLength = len;
	free(hashWithPadding);

	if (session) {
		if (EstEID_CK_failure("C_CloseSession", fl->C_CloseSession(session))) {
			return FAILURE;
		}
	}
	
	EstEID_log("successfully signed");
	return SUCCESS;
}
コード例 #13
0
// Import a newly generated RSA1024 pvt key and a certificate
// to every slot and use the key to sign some data
static void test_import_and_sign_all_10_RSA() {

  EVP_PKEY    *evp;
  RSA         *rsak;
  X509        *cert;
  ASN1_TIME   *tm;
  CK_BYTE     i, j;
  CK_BYTE     some_data[32];
  CK_BYTE     e[] = {0x01, 0x00, 0x01};
  CK_BYTE     p[64];
  CK_BYTE     q[64];
  CK_BYTE     dp[64];
  CK_BYTE     dq[64];
  CK_BYTE     qinv[64];
  BIGNUM      *e_bn;
  CK_ULONG    class_k = CKO_PRIVATE_KEY;
  CK_ULONG    class_c = CKO_CERTIFICATE;
  CK_ULONG    kt = CKK_RSA;
  CK_BYTE     id = 0;
  CK_BYTE     sig[64];
  CK_ULONG    recv_len;
  CK_BYTE     value_c[3100];
  CK_ULONG    cert_len;
  CK_BYTE     der_encoded[80];
  CK_BYTE_PTR der_ptr;
  CK_BYTE_PTR r_ptr;
  CK_BYTE_PTR s_ptr;
  CK_ULONG    r_len;
  CK_ULONG    s_len;

  unsigned char  *px;

  CK_ATTRIBUTE privateKeyTemplate[] = {
    {CKA_CLASS, &class_k, sizeof(class_k)},
    {CKA_KEY_TYPE, &kt, sizeof(kt)},
    {CKA_ID, &id, sizeof(id)},
    {CKA_PUBLIC_EXPONENT, e, sizeof(e)},
    {CKA_PRIME_1, p, sizeof(p)},
    {CKA_PRIME_2, q, sizeof(q)},
    {CKA_EXPONENT_1, dp, sizeof(dp)},
    {CKA_EXPONENT_2, dq, sizeof(dq)},
    {CKA_COEFFICIENT, qinv, sizeof(qinv)}
  };

  CK_ATTRIBUTE publicKeyTemplate[] = {
    {CKA_CLASS, &class_c, sizeof(class_c)},
    {CKA_ID, &id, sizeof(id)},
    {CKA_VALUE, value_c, sizeof(value_c)}
  };

  CK_OBJECT_HANDLE obj[24];
  CK_SESSION_HANDLE session;
  CK_MECHANISM mech = {CKM_RSA_PKCS, NULL};

  evp = EVP_PKEY_new();

  if (evp == NULL)
    exit(EXIT_FAILURE);

  rsak = RSA_new();

  if (rsak == NULL)
    exit(EXIT_FAILURE);

  e_bn = BN_bin2bn(e, 3, NULL);

  if (e_bn == NULL)
    exit(EXIT_FAILURE);

  asrt(RSA_generate_key_ex(rsak, 1024, e_bn, NULL), 1, "GENERATE RSAK");

  asrt(BN_bn2bin(rsak->p, p), 64, "GET P");
  asrt(BN_bn2bin(rsak->q, q), 64, "GET Q");
  asrt(BN_bn2bin(rsak->dmp1, dp), 64, "GET DP");
  asrt(BN_bn2bin(rsak->dmq1, dp), 64, "GET DQ");
  asrt(BN_bn2bin(rsak->iqmp, qinv), 64, "GET QINV");



  if (EVP_PKEY_set1_RSA(evp, rsak) == 0)
    exit(EXIT_FAILURE);

  cert = X509_new();

  if (cert == NULL)
    exit(EXIT_FAILURE);

  if (X509_set_pubkey(cert, evp) == 0)
    exit(EXIT_FAILURE);

  tm = ASN1_TIME_new();
  if (tm == NULL)
    exit(EXIT_FAILURE);

  ASN1_TIME_set_string(tm, "000001010000Z");
  X509_set_notBefore(cert, tm);
  X509_set_notAfter(cert, tm);

  cert->sig_alg->algorithm = OBJ_nid2obj(8);
  cert->cert_info->signature->algorithm = OBJ_nid2obj(8);

  ASN1_BIT_STRING_set_bit(cert->signature, 8, 1);
  ASN1_BIT_STRING_set(cert->signature, "\x00", 1);

  px = value_c;
  if ((cert_len = (CK_ULONG) i2d_X509(cert, &px)) == 0 || cert_len > sizeof(value_c))
    exit(EXIT_FAILURE);

  publicKeyTemplate[2].ulValueLen = cert_len;

  asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
  asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");
  asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");

  for (i = 0; i < 24; i++) {
    id = i;
    asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT");
    asrt(funcs->C_CreateObject(session, privateKeyTemplate, 9, obj + i), CKR_OK, "IMPORT KEY");
  }

  asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");

  for (i = 0; i < 24; i++) {
    for (j = 0; j < 10; j++) {

      if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1)
        exit(EXIT_FAILURE);

      asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER");
      asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit");

      recv_len = sizeof(sig);
      asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign");

      /* r_len = 32; */
      /* s_len = 32; */

      /* der_ptr = der_encoded; */
      /* *der_ptr++ = 0x30; */
      /* *der_ptr++ = 0xff; // placeholder, fix below */

      /* r_ptr = sig; */

      /* *der_ptr++ = 0x02; */
      /* *der_ptr++ = r_len; */
      /* if (*r_ptr >= 0x80) { */
      /*   *(der_ptr - 1) = *(der_ptr - 1) + 1; */
      /*   *der_ptr++ = 0x00; */
      /* } */
      /* else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) { */
      /*   r_len--; */
      /*   *(der_ptr - 1) = *(der_ptr - 1) - 1; */
      /*   r_ptr++; */
      /* } */
      /* memcpy(der_ptr, r_ptr, r_len); */
      /* der_ptr+= r_len; */

      /* s_ptr = sig + 32; */

      /* *der_ptr++ = 0x02; */
      /* *der_ptr++ = s_len; */
      /* if (*s_ptr >= 0x80) { */
      /*   *(der_ptr - 1) = *(der_ptr - 1) + 1; */
      /*   *der_ptr++ = 0x00; */
      /* } */
      /* else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) { */
      /*   s_len--; */
      /*   *(der_ptr - 1) = *(der_ptr - 1) - 1; */
      /*   s_ptr++; */
      /* } */
      /* memcpy(der_ptr, s_ptr, s_len); */
      /* der_ptr+= s_len; */

      /* der_encoded[1] = der_ptr - der_encoded - 2; */

      /* dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1); */

      /* asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION"); */

      }
  }

  asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");

  asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
  asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");

}
コード例 #14
0
// Import a newly generated P256 pvt key and a certificate
// to every slot and use the key to sign some data
static void test_import_and_sign_all_10() {

  EVP_PKEY       *evp;
  EC_KEY         *eck;
  const EC_POINT *ecp;
  const BIGNUM   *bn;
  char           pvt[32];
  X509           *cert;
  ASN1_TIME      *tm;
  CK_BYTE        i, j;
  CK_BYTE        some_data[32];

  CK_ULONG    class_k = CKO_PRIVATE_KEY;
  CK_ULONG    class_c = CKO_CERTIFICATE;
  CK_ULONG    kt = CKK_ECDSA;
  CK_BYTE     id = 0;
  CK_BYTE     params[] = {0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
  CK_BYTE     sig[64];
  CK_ULONG    recv_len;
  CK_BYTE     value_c[3100];
  CK_ULONG    cert_len;
  CK_BYTE     der_encoded[80];
  CK_BYTE_PTR der_ptr;
  CK_BYTE_PTR r_ptr;
  CK_BYTE_PTR s_ptr;
  CK_ULONG    r_len;
  CK_ULONG    s_len;

  unsigned char  *p;

  CK_ATTRIBUTE privateKeyTemplate[] = {
    {CKA_CLASS, &class_k, sizeof(class_k)},
    {CKA_KEY_TYPE, &kt, sizeof(kt)},
    {CKA_ID, &id, sizeof(id)},
    {CKA_EC_PARAMS, &params, sizeof(params)},
    {CKA_VALUE, pvt, sizeof(pvt)}
  };

  CK_ATTRIBUTE publicKeyTemplate[] = {
    {CKA_CLASS, &class_c, sizeof(class_c)},
    {CKA_ID, &id, sizeof(id)},
    {CKA_VALUE, value_c, sizeof(value_c)}
  };

  CK_OBJECT_HANDLE obj[24];
  CK_SESSION_HANDLE session;
  CK_MECHANISM mech = {CKM_ECDSA, NULL};

  evp = EVP_PKEY_new();

  if (evp == NULL)
    exit(EXIT_FAILURE);

  eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);

  if (eck == NULL)
    exit(EXIT_FAILURE);

  asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK");

  bn = EC_KEY_get0_private_key(eck);

  asrt(BN_bn2bin(bn, pvt), 32, "EXTRACT PVT");

  if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0)
    exit(EXIT_FAILURE);

  cert = X509_new();

  if (cert == NULL)
    exit(EXIT_FAILURE);

  if (X509_set_pubkey(cert, evp) == 0)
    exit(EXIT_FAILURE);

  tm = ASN1_TIME_new();
  if (tm == NULL)
    exit(EXIT_FAILURE);

  ASN1_TIME_set_string(tm, "000001010000Z");
  X509_set_notBefore(cert, tm);
  X509_set_notAfter(cert, tm);

  cert->sig_alg->algorithm = OBJ_nid2obj(8);
  cert->cert_info->signature->algorithm = OBJ_nid2obj(8);

  ASN1_BIT_STRING_set_bit(cert->signature, 8, 1);
  ASN1_BIT_STRING_set(cert->signature, "\x00", 1);

  p = value_c;
  if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c))
    exit(EXIT_FAILURE);

  publicKeyTemplate[2].ulValueLen = cert_len;

  asrt(funcs->C_Initialize(NULL), CKR_OK, "INITIALIZE");
  asrt(funcs->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session), CKR_OK, "OpenSession1");
  asrt(funcs->C_Login(session, CKU_SO, "010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");

  for (i = 0; i < 24; i++) {
    id = i;
    asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj + i), CKR_OK, "IMPORT CERT");
    asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj + i), CKR_OK, "IMPORT KEY");
  }

  asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");

  for (i = 0; i < 24; i++) {
    for (j = 0; j < 10; j++) {

      if(RAND_pseudo_bytes(some_data, sizeof(some_data)) == -1)
        exit(EXIT_FAILURE);

      asrt(funcs->C_Login(session, CKU_USER, "123456", 6), CKR_OK, "Login USER");
      asrt(funcs->C_SignInit(session, &mech, obj[i]), CKR_OK, "SignInit");

      recv_len = sizeof(sig);
      asrt(funcs->C_Sign(session, some_data, sizeof(some_data), sig, &recv_len), CKR_OK, "Sign");

      r_len = 32;
      s_len = 32;

      der_ptr = der_encoded;
      *der_ptr++ = 0x30;
      *der_ptr++ = 0xff; // placeholder, fix below

      r_ptr = sig;

      *der_ptr++ = 0x02;
      *der_ptr++ = r_len;
      if (*r_ptr >= 0x80) {
        *(der_ptr - 1) = *(der_ptr - 1) + 1;
        *der_ptr++ = 0x00;
      }
      else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) {
        r_len--;
        *(der_ptr - 1) = *(der_ptr - 1) - 1;
        r_ptr++;
      }
      memcpy(der_ptr, r_ptr, r_len);
      der_ptr+= r_len;

      s_ptr = sig + 32;

      *der_ptr++ = 0x02;
      *der_ptr++ = s_len;
      if (*s_ptr >= 0x80) {
        *(der_ptr - 1) = *(der_ptr - 1) + 1;
        *der_ptr++ = 0x00;
      }
      else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) {
        s_len--;
        *(der_ptr - 1) = *(der_ptr - 1) - 1;
        s_ptr++;
      }
      memcpy(der_ptr, s_ptr, s_len);
      der_ptr+= s_len;

      der_encoded[1] = der_ptr - der_encoded - 2;

      dump_hex(der_encoded, der_encoded[1] + 2, stderr, 1);

      asrt(ECDSA_verify(0, some_data, sizeof(some_data), der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION");

      }
  }

  asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");

  asrt(funcs->C_CloseSession(session), CKR_OK, "CloseSession");
  asrt(funcs->C_Finalize(NULL), CKR_OK, "FINALIZE");

}