2002-01-16 22:49:03 +00:00
|
|
|
/*
|
|
|
|
* misc.c: Miscellaneous PKCS#11 library helper functions
|
|
|
|
*
|
2006-12-19 21:33:15 +00:00
|
|
|
* Copyright (C) 2002 Timo Teräs <timo.teras@iki.fi>
|
2002-01-16 22:49:03 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2002-03-20 19:33:52 +00:00
|
|
|
#include <stdlib.h>
|
2002-03-21 09:36:38 +00:00
|
|
|
#include <string.h>
|
2010-03-04 08:14:36 +00:00
|
|
|
|
2002-03-25 12:39:35 +00:00
|
|
|
#include "sc-pkcs11.h"
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-03-18 11:05:21 +00:00
|
|
|
#define DUMP_TEMPLATE_MAX 32
|
|
|
|
|
2010-04-21 10:51:13 +00:00
|
|
|
struct sc_to_cryptoki_error_conversion {
|
|
|
|
const char *context;
|
|
|
|
int sc_error;
|
|
|
|
CK_RV ck_error;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct sc_to_cryptoki_error_conversion sc_to_cryptoki_error_map[] = {
|
2012-05-26 19:17:39 +00:00
|
|
|
{ "C_GenerateKeyPair", SC_ERROR_INVALID_PIN_LENGTH, CKR_GENERAL_ERROR },
|
|
|
|
{ "C_Sign", SC_ERROR_NOT_ALLOWED, CKR_FUNCTION_FAILED},
|
|
|
|
{ "C_Decrypt", SC_ERROR_NOT_ALLOWED, CKR_FUNCTION_FAILED},
|
2010-04-21 10:51:13 +00:00
|
|
|
{NULL, 0, 0}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
void strcpy_bp(u8 * dst, const char *src, size_t dstsize)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2005-01-19 18:15:43 +00:00
|
|
|
size_t c;
|
2004-03-29 20:34:30 +00:00
|
|
|
|
|
|
|
if (!dst || !src || !dstsize)
|
|
|
|
return;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
memset((char *)dst, ' ', dstsize);
|
|
|
|
|
2004-03-29 20:34:30 +00:00
|
|
|
c = strlen(src) > dstsize ? dstsize : strlen(src);
|
2010-01-24 20:45:02 +00:00
|
|
|
|
|
|
|
memcpy((char *)dst, src, c);
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-04-21 10:51:13 +00:00
|
|
|
|
|
|
|
static CK_RV sc_to_cryptoki_error_common(int rc)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2012-05-12 22:27:38 +00:00
|
|
|
sc_log(context, "libopensc return value: %d (%s)\n", rc, sc_strerror(rc));
|
2002-01-16 22:49:03 +00:00
|
|
|
switch (rc) {
|
|
|
|
case SC_SUCCESS:
|
|
|
|
return CKR_OK;
|
|
|
|
case SC_ERROR_NOT_SUPPORTED:
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
case SC_ERROR_OUT_OF_MEMORY:
|
|
|
|
return CKR_HOST_MEMORY;
|
|
|
|
case SC_ERROR_PIN_CODE_INCORRECT:
|
|
|
|
return CKR_PIN_INCORRECT;
|
2003-02-11 10:38:43 +00:00
|
|
|
case SC_ERROR_AUTH_METHOD_BLOCKED:
|
|
|
|
return CKR_PIN_LOCKED;
|
2002-01-16 22:49:03 +00:00
|
|
|
case SC_ERROR_BUFFER_TOO_SMALL:
|
|
|
|
return CKR_BUFFER_TOO_SMALL;
|
|
|
|
case SC_ERROR_CARD_NOT_PRESENT:
|
|
|
|
return CKR_TOKEN_NOT_PRESENT;
|
|
|
|
case SC_ERROR_INVALID_CARD:
|
2013-12-04 17:55:37 +00:00
|
|
|
case SC_ERROR_WRONG_CARD:
|
|
|
|
case SC_ERROR_NO_CARD_SUPPORT:
|
2002-01-16 22:49:03 +00:00
|
|
|
return CKR_TOKEN_NOT_RECOGNIZED;
|
2002-12-09 13:33:39 +00:00
|
|
|
case SC_ERROR_WRONG_LENGTH:
|
|
|
|
return CKR_DATA_LEN_RANGE;
|
2003-01-06 19:28:48 +00:00
|
|
|
case SC_ERROR_INVALID_PIN_LENGTH:
|
|
|
|
return CKR_PIN_LEN_RANGE;
|
2003-01-31 12:50:26 +00:00
|
|
|
case SC_ERROR_KEYPAD_CANCELLED:
|
2003-03-03 21:07:42 +00:00
|
|
|
case SC_ERROR_KEYPAD_TIMEOUT:
|
2003-01-31 12:50:26 +00:00
|
|
|
return CKR_FUNCTION_CANCELED;
|
2003-02-12 14:20:53 +00:00
|
|
|
case SC_ERROR_CARD_REMOVED:
|
|
|
|
return CKR_DEVICE_REMOVED;
|
2003-02-16 18:09:10 +00:00
|
|
|
case SC_ERROR_SECURITY_STATUS_NOT_SATISFIED:
|
|
|
|
return CKR_USER_NOT_LOGGED_IN;
|
2003-02-26 07:27:42 +00:00
|
|
|
case SC_ERROR_KEYPAD_PIN_MISMATCH:
|
|
|
|
return CKR_PIN_INVALID;
|
2003-07-17 22:59:12 +00:00
|
|
|
case SC_ERROR_INVALID_ARGUMENTS:
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
2003-11-23 15:33:56 +00:00
|
|
|
case SC_ERROR_INVALID_DATA:
|
2005-03-26 20:00:14 +00:00
|
|
|
case SC_ERROR_INCORRECT_PARAMETERS:
|
2003-11-23 15:33:56 +00:00
|
|
|
return CKR_DATA_INVALID;
|
2009-09-14 08:56:39 +00:00
|
|
|
case SC_ERROR_CARD_UNRESPONSIVE:
|
2010-01-24 20:45:02 +00:00
|
|
|
case SC_ERROR_READER_LOCKED:
|
2009-09-14 08:56:39 +00:00
|
|
|
return CKR_DEVICE_ERROR;
|
2010-01-24 20:45:02 +00:00
|
|
|
case SC_ERROR_READER_DETACHED:
|
|
|
|
return CKR_TOKEN_NOT_PRESENT; /* Maybe CKR_DEVICE_REMOVED ? */
|
2010-01-23 19:12:52 +00:00
|
|
|
case SC_ERROR_NOT_ENOUGH_MEMORY:
|
|
|
|
return CKR_DEVICE_MEMORY;
|
2010-01-24 20:45:02 +00:00
|
|
|
case SC_ERROR_MEMORY_FAILURE: /* EEPROM has failed */
|
2010-01-24 12:38:34 +00:00
|
|
|
return CKR_DEVICE_ERROR;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
return CKR_GENERAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2010-04-21 10:51:13 +00:00
|
|
|
|
|
|
|
CK_RV sc_to_cryptoki_error(int rc, const char *ctx)
|
|
|
|
{
|
2013-12-01 11:12:32 +00:00
|
|
|
if (ctx) {
|
2010-04-21 11:57:10 +00:00
|
|
|
int ii;
|
|
|
|
|
|
|
|
for (ii = 0; sc_to_cryptoki_error_map[ii].context; ii++) {
|
|
|
|
if (sc_to_cryptoki_error_map[ii].sc_error != rc)
|
|
|
|
continue;
|
|
|
|
if (strcmp(sc_to_cryptoki_error_map[ii].context, ctx))
|
|
|
|
continue;
|
|
|
|
return sc_to_cryptoki_error_map[ii].ck_error;
|
|
|
|
}
|
2010-04-21 10:51:13 +00:00
|
|
|
}
|
|
|
|
return sc_to_cryptoki_error_common(rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-26 06:11:06 +00:00
|
|
|
struct sc_pkcs11_login {
|
|
|
|
CK_USER_TYPE userType;
|
|
|
|
CK_CHAR_PTR pPin;
|
|
|
|
CK_ULONG ulPinLen;
|
|
|
|
};
|
|
|
|
|
|
|
|
CK_RV restore_login_state(struct sc_pkcs11_slot *slot)
|
|
|
|
{
|
|
|
|
CK_RV r = CKR_OK;
|
|
|
|
|
|
|
|
if (sc_pkcs11_conf.atomic && slot) {
|
|
|
|
if (list_iterator_start(&slot->logins)) {
|
|
|
|
struct sc_pkcs11_login *login = list_iterator_next(&slot->logins);
|
|
|
|
while (login) {
|
|
|
|
r = slot->p11card->framework->login(slot, login->userType,
|
|
|
|
login->pPin, login->ulPinLen);
|
|
|
|
if (r != CKR_OK)
|
|
|
|
break;
|
|
|
|
login = list_iterator_next(&slot->logins);
|
|
|
|
}
|
|
|
|
list_iterator_stop(&slot->logins);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2015-12-02 09:24:50 +00:00
|
|
|
CK_RV reset_login_state(struct sc_pkcs11_slot *slot, CK_RV rv)
|
2015-11-26 06:11:06 +00:00
|
|
|
{
|
2015-12-02 09:24:50 +00:00
|
|
|
if (slot) {
|
|
|
|
if (sc_pkcs11_conf.atomic
|
|
|
|
&& slot->p11card && slot->p11card->framework) {
|
|
|
|
slot->p11card->framework->logout(slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv == CKR_USER_NOT_LOGGED_IN) {
|
|
|
|
slot->login_user = -1;
|
|
|
|
pop_all_login_states(slot);
|
|
|
|
}
|
2015-11-26 06:11:06 +00:00
|
|
|
}
|
|
|
|
|
2015-12-02 09:24:50 +00:00
|
|
|
return rv;
|
2015-11-26 06:11:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV push_login_state(struct sc_pkcs11_slot *slot,
|
|
|
|
CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
|
|
|
|
{
|
|
|
|
CK_RV r = CKR_HOST_MEMORY;
|
|
|
|
struct sc_pkcs11_login *login = NULL;
|
|
|
|
|
|
|
|
if (!sc_pkcs11_conf.atomic || !slot) {
|
2016-10-10 20:21:46 +00:00
|
|
|
return CKR_OK;
|
2015-11-26 06:11:06 +00:00
|
|
|
}
|
|
|
|
|
2016-10-10 20:21:46 +00:00
|
|
|
login = (struct sc_pkcs11_login *) calloc(1, sizeof *login);
|
2015-11-26 06:11:06 +00:00
|
|
|
if (login == NULL) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2017-04-13 10:46:05 +00:00
|
|
|
if (pPin && ulPinLen) {
|
2018-10-10 12:52:01 +00:00
|
|
|
login->pPin = sc_mem_secure_alloc((sizeof *pPin)*ulPinLen);
|
2017-04-13 10:46:05 +00:00
|
|
|
if (login->pPin == NULL) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
memcpy(login->pPin, pPin, (sizeof *pPin)*ulPinLen);
|
|
|
|
login->ulPinLen = ulPinLen;
|
2015-11-26 06:11:06 +00:00
|
|
|
}
|
|
|
|
login->userType = userType;
|
|
|
|
|
|
|
|
if (0 > list_append(&slot->logins, login)) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-10-10 20:21:46 +00:00
|
|
|
login = NULL;
|
2015-11-26 06:11:06 +00:00
|
|
|
r = CKR_OK;
|
|
|
|
|
|
|
|
err:
|
2016-10-10 20:21:46 +00:00
|
|
|
if (login) {
|
|
|
|
if (login->pPin) {
|
|
|
|
sc_mem_clear(login->pPin, login->ulPinLen);
|
2018-10-10 12:52:01 +00:00
|
|
|
sc_mem_secure_free(login->pPin, login->ulPinLen);
|
2016-10-10 20:21:46 +00:00
|
|
|
}
|
2015-11-26 06:11:06 +00:00
|
|
|
free(login);
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pop_login_state(struct sc_pkcs11_slot *slot)
|
|
|
|
{
|
|
|
|
if (slot) {
|
|
|
|
unsigned int size = list_size(&slot->logins);
|
|
|
|
if (size > 0) {
|
|
|
|
struct sc_pkcs11_login *login = list_get_at(&slot->logins, size-1);
|
|
|
|
if (login) {
|
|
|
|
sc_mem_clear(login->pPin, login->ulPinLen);
|
2018-10-10 12:52:01 +00:00
|
|
|
sc_mem_secure_free(login->pPin, login->ulPinLen);
|
2015-11-26 06:11:06 +00:00
|
|
|
free(login);
|
|
|
|
}
|
|
|
|
if (0 > list_delete_at(&slot->logins, size-1))
|
|
|
|
sc_log(context, "Error deleting login state");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void pop_all_login_states(struct sc_pkcs11_slot *slot)
|
|
|
|
{
|
|
|
|
if (sc_pkcs11_conf.atomic && slot) {
|
|
|
|
struct sc_pkcs11_login *login = list_fetch(&slot->logins);
|
|
|
|
while (login) {
|
|
|
|
sc_mem_clear(login->pPin, login->ulPinLen);
|
2018-10-10 12:52:01 +00:00
|
|
|
sc_mem_secure_free(login->pPin, login->ulPinLen);
|
2015-11-26 06:11:06 +00:00
|
|
|
free(login);
|
|
|
|
login = list_fetch(&slot->logins);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-01-16 22:49:03 +00:00
|
|
|
/* Session manipulation */
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV session_start_operation(struct sc_pkcs11_session * session,
|
|
|
|
int type, sc_pkcs11_mechanism_type_t * mech, struct sc_pkcs11_operation ** operation)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2002-12-17 11:49:12 +00:00
|
|
|
sc_pkcs11_operation_t *op;
|
|
|
|
|
2002-01-16 22:49:03 +00:00
|
|
|
if (context == NULL)
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2012-05-12 22:27:38 +00:00
|
|
|
LOG_FUNC_CALLED(context);
|
|
|
|
sc_log(context, "Session 0x%lx, type %d", session->handle, type);
|
2002-12-17 11:49:12 +00:00
|
|
|
if (type < 0 || type >= SC_PKCS11_OPERATION_MAX)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
|
|
|
if (session->operation[type] != NULL)
|
2002-01-16 22:49:03 +00:00
|
|
|
return CKR_OPERATION_ACTIVE;
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
if (!(op = sc_pkcs11_new_operation(session, mech)))
|
|
|
|
return CKR_HOST_MEMORY;
|
|
|
|
|
|
|
|
session->operation[type] = op;
|
|
|
|
if (operation)
|
|
|
|
*operation = op;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV session_get_operation(struct sc_pkcs11_session * session, int type, sc_pkcs11_operation_t ** operation)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2002-12-17 11:49:12 +00:00
|
|
|
sc_pkcs11_operation_t *op;
|
|
|
|
|
2012-05-12 22:27:38 +00:00
|
|
|
LOG_FUNC_CALLED(context);
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
if (type < 0 || type >= SC_PKCS11_OPERATION_MAX)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
if (!(op = session->operation[type]))
|
2002-01-16 22:49:03 +00:00
|
|
|
return CKR_OPERATION_NOT_INITIALIZED;
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
if (operation)
|
|
|
|
*operation = op;
|
|
|
|
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV session_stop_operation(struct sc_pkcs11_session * session, int type)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2002-12-17 11:49:12 +00:00
|
|
|
if (type < 0 || type >= SC_PKCS11_OPERATION_MAX)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
|
|
|
if (session->operation[type] == NULL)
|
2002-01-16 22:49:03 +00:00
|
|
|
return CKR_OPERATION_NOT_INITIALIZED;
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
sc_pkcs11_release_operation(&session->operation[type]);
|
2005-01-19 18:15:43 +00:00
|
|
|
return CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
2002-04-11 15:17:33 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV attr_extract(CK_ATTRIBUTE_PTR pAttr, void *ptr, size_t * sizep)
|
2002-04-11 15:17:33 +00:00
|
|
|
{
|
2018-10-31 12:10:12 +00:00
|
|
|
size_t size;
|
2002-04-11 15:17:33 +00:00
|
|
|
|
|
|
|
if (sizep) {
|
|
|
|
size = *sizep;
|
|
|
|
if (size < pAttr->ulValueLen)
|
|
|
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
|
|
*sizep = pAttr->ulValueLen;
|
|
|
|
} else {
|
|
|
|
switch (pAttr->type) {
|
|
|
|
case CKA_CLASS:
|
2010-01-24 20:45:02 +00:00
|
|
|
size = sizeof(CK_OBJECT_CLASS);
|
|
|
|
break;
|
2002-04-11 15:17:33 +00:00
|
|
|
case CKA_KEY_TYPE:
|
2010-01-24 20:45:02 +00:00
|
|
|
size = sizeof(CK_KEY_TYPE);
|
|
|
|
break;
|
2002-04-13 19:00:37 +00:00
|
|
|
case CKA_PRIVATE:
|
2012-05-26 19:17:39 +00:00
|
|
|
case CKA_TOKEN:
|
2010-01-24 20:45:02 +00:00
|
|
|
size = sizeof(CK_BBOOL);
|
|
|
|
break;
|
2003-06-04 12:24:19 +00:00
|
|
|
case CKA_CERTIFICATE_TYPE:
|
2010-01-24 20:45:02 +00:00
|
|
|
size = sizeof(CK_CERTIFICATE_TYPE);
|
|
|
|
break;
|
2012-05-26 19:17:39 +00:00
|
|
|
case CKA_VALUE_LEN:
|
2003-11-12 18:28:03 +00:00
|
|
|
case CKA_MODULUS_BITS:
|
2010-01-24 20:45:02 +00:00
|
|
|
size = sizeof(CK_ULONG);
|
|
|
|
break;
|
2007-06-21 09:37:18 +00:00
|
|
|
case CKA_OBJECT_ID:
|
2010-01-24 20:45:02 +00:00
|
|
|
size = sizeof(struct sc_object_id);
|
|
|
|
break;
|
2002-04-11 15:17:33 +00:00
|
|
|
default:
|
|
|
|
return CKR_FUNCTION_FAILED;
|
|
|
|
}
|
|
|
|
if (size != pAttr->ulValueLen)
|
|
|
|
return CKR_ATTRIBUTE_VALUE_INVALID;
|
|
|
|
}
|
|
|
|
memcpy(ptr, pAttr->pValue, pAttr->ulValueLen);
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV attr_find(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type, void *ptr, size_t * sizep)
|
2002-04-11 15:17:33 +00:00
|
|
|
{
|
2010-01-24 20:45:02 +00:00
|
|
|
unsigned int n;
|
2002-04-11 15:17:33 +00:00
|
|
|
|
|
|
|
for (n = 0; n < ulCount; n++, pTemplate++) {
|
|
|
|
if (pTemplate->type == type)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n >= ulCount)
|
|
|
|
return CKR_TEMPLATE_INCOMPLETE;
|
|
|
|
return attr_extract(pTemplate, ptr, sizep);
|
|
|
|
}
|
|
|
|
|
2003-06-03 13:57:52 +00:00
|
|
|
CK_RV attr_find2(CK_ATTRIBUTE_PTR pTemp1, CK_ULONG ulCount1,
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_ATTRIBUTE_PTR pTemp2, CK_ULONG ulCount2, CK_ULONG type, void *ptr, size_t * sizep)
|
2003-06-03 13:57:52 +00:00
|
|
|
{
|
|
|
|
CK_RV rv;
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2003-06-03 13:57:52 +00:00
|
|
|
rv = attr_find(pTemp1, ulCount1, type, ptr, sizep);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
rv = attr_find(pTemp2, ulCount2, type, ptr, sizep);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2015-02-24 16:38:39 +00:00
|
|
|
CK_RV attr_find_and_allocate_ptr(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type, void **out, size_t *out_len)
|
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
size_t len;
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
if (!out || !out_len)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
len = *out_len;
|
|
|
|
|
|
|
|
rv = attr_find_ptr(pTemplate, ulCount, type, &ptr, &len);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
*out = calloc(1, len);
|
|
|
|
if (*out == NULL)
|
|
|
|
return CKR_HOST_MEMORY;
|
|
|
|
|
|
|
|
memcpy(*out, ptr, len);
|
|
|
|
*out_len = len;
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV attr_find_ptr(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type, void **ptr, size_t * sizep)
|
2002-04-11 15:17:33 +00:00
|
|
|
{
|
2010-01-24 20:45:02 +00:00
|
|
|
unsigned int n;
|
2002-04-11 15:17:33 +00:00
|
|
|
|
|
|
|
for (n = 0; n < ulCount; n++, pTemplate++) {
|
|
|
|
if (pTemplate->type == type)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n >= ulCount)
|
|
|
|
return CKR_TEMPLATE_INCOMPLETE;
|
|
|
|
|
|
|
|
if (sizep)
|
|
|
|
*sizep = pTemplate->ulValueLen;
|
|
|
|
*ptr = pTemplate->pValue;
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
2017-06-09 08:30:40 +00:00
|
|
|
CK_RV attr_find_ptr2(CK_ATTRIBUTE_PTR pTemp1, CK_ULONG ulCount1,
|
|
|
|
CK_ATTRIBUTE_PTR pTemp2, CK_ULONG ulCount2, CK_ULONG type, void **ptr, size_t * sizep)
|
|
|
|
{
|
|
|
|
CK_RV rv;
|
|
|
|
|
|
|
|
rv = attr_find_ptr(pTemp1, ulCount1, type, ptr, sizep);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
rv = attr_find_ptr(pTemp2, ulCount2, type, ptr, sizep);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV attr_find_var(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG type, void *ptr, size_t * sizep)
|
2002-04-11 15:17:33 +00:00
|
|
|
{
|
2010-01-24 20:45:02 +00:00
|
|
|
unsigned int n;
|
2002-04-11 15:17:33 +00:00
|
|
|
|
|
|
|
for (n = 0; n < ulCount; n++, pTemplate++) {
|
|
|
|
if (pTemplate->type == type)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n >= ulCount)
|
|
|
|
return CKR_TEMPLATE_INCOMPLETE;
|
|
|
|
|
|
|
|
return attr_extract(pTemplate, ptr, sizep);
|
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
|
2002-12-21 16:45:37 +00:00
|
|
|
{
|
2009-01-16 16:44:35 +00:00
|
|
|
scconf_block *conf_block = NULL;
|
2010-01-08 15:41:07 +00:00
|
|
|
char *unblock_style = NULL;
|
2012-05-21 17:19:38 +00:00
|
|
|
char *create_slots_for_pins = NULL, *op, *tmp;
|
2009-02-25 09:13:35 +00:00
|
|
|
|
2009-01-16 16:44:35 +00:00
|
|
|
/* Set defaults */
|
|
|
|
conf->max_virtual_slots = 16;
|
2014-04-30 13:10:27 +00:00
|
|
|
if (strcmp(ctx->app_name, "onepin-opensc-pkcs11") == 0) {
|
|
|
|
conf->slots_per_card = 1;
|
|
|
|
} else {
|
|
|
|
conf->slots_per_card = 4;
|
|
|
|
}
|
2015-11-26 06:11:06 +00:00
|
|
|
conf->atomic = 0;
|
2010-05-19 08:17:53 +00:00
|
|
|
conf->lock_login = 0;
|
2015-09-16 05:16:21 +00:00
|
|
|
conf->init_sloppy = 1;
|
2010-01-08 15:41:07 +00:00
|
|
|
conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED;
|
2010-01-28 14:15:13 +00:00
|
|
|
conf->create_puk_slot = 0;
|
2014-03-12 13:57:47 +00:00
|
|
|
conf->create_slots_flags = SC_PKCS11_SLOT_CREATE_ALL;
|
2009-01-16 16:44:35 +00:00
|
|
|
|
|
|
|
conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1);
|
|
|
|
if (!conf_block)
|
2002-12-21 16:45:37 +00:00
|
|
|
return;
|
|
|
|
|
2008-12-28 16:01:04 +00:00
|
|
|
/* contains the defaults, if there is a "pkcs11" config block */
|
2009-01-16 16:44:35 +00:00
|
|
|
conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots);
|
|
|
|
conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card);
|
2015-11-26 06:11:06 +00:00
|
|
|
conf->atomic = scconf_get_bool(conf_block, "atomic", conf->atomic);
|
|
|
|
if (conf->atomic)
|
|
|
|
conf->lock_login = 1;
|
2009-01-16 16:44:35 +00:00
|
|
|
conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login);
|
2015-09-16 05:16:21 +00:00
|
|
|
conf->init_sloppy = scconf_get_bool(conf_block, "init_sloppy", conf->init_sloppy);
|
2010-01-08 15:41:07 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
unblock_style = (char *)scconf_get_str(conf_block, "user_pin_unblock_style", NULL);
|
2010-01-08 15:41:07 +00:00
|
|
|
if (unblock_style && !strcmp(unblock_style, "set_pin_in_unlogged_session"))
|
|
|
|
conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN;
|
|
|
|
else if (unblock_style && !strcmp(unblock_style, "set_pin_in_specific_context"))
|
|
|
|
conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN;
|
|
|
|
else if (unblock_style && !strcmp(unblock_style, "init_pin_in_so_session"))
|
|
|
|
conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN;
|
2012-04-02 22:00:56 +00:00
|
|
|
|
2010-01-28 14:15:13 +00:00
|
|
|
conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot);
|
2010-01-08 15:41:07 +00:00
|
|
|
|
2012-05-21 17:19:38 +00:00
|
|
|
create_slots_for_pins = (char *)scconf_get_str(conf_block, "create_slots_for_pins", "all");
|
2014-03-12 13:57:47 +00:00
|
|
|
conf->create_slots_flags = 0;
|
2012-05-21 17:19:38 +00:00
|
|
|
tmp = strdup(create_slots_for_pins);
|
|
|
|
op = strtok(tmp, " ,");
|
|
|
|
while (op) {
|
|
|
|
if (!strcmp(op, "user"))
|
|
|
|
conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_PIN_USER;
|
|
|
|
else if (!strcmp(op, "sign"))
|
|
|
|
conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_PIN_SIGN;
|
|
|
|
else if (!strcmp(op, "all"))
|
|
|
|
conf->create_slots_flags |= SC_PKCS11_SLOT_CREATE_ALL;
|
|
|
|
op = strtok(NULL, " ,");
|
|
|
|
}
|
2018-06-26 08:15:22 +00:00
|
|
|
free(tmp);
|
2012-05-21 17:19:38 +00:00
|
|
|
|
2016-02-25 18:23:55 +00:00
|
|
|
sc_log(ctx, "PKCS#11 options: max_virtual_slots=%d slots_per_card=%d "
|
2018-06-26 08:15:22 +00:00
|
|
|
"lock_login=%d atomic=%d pin_unblock_style=%d "
|
2018-01-30 15:17:31 +00:00
|
|
|
"create_slots_flags=0x%X",
|
2016-02-25 18:23:55 +00:00
|
|
|
conf->max_virtual_slots, conf->slots_per_card,
|
2018-06-26 08:15:22 +00:00
|
|
|
conf->lock_login, conf->atomic, conf->pin_unblock_style,
|
2018-01-30 15:17:31 +00:00
|
|
|
conf->create_slots_flags);
|
2002-12-21 16:45:37 +00:00
|
|
|
}
|