2002-01-16 22:49:03 +00:00
|
|
|
/*
|
|
|
|
* pkcs11-object.c: PKCS#11 object management and handling 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-01-16 22:49:03 +00:00
|
|
|
#include <string.h>
|
2010-03-04 08:14:36 +00:00
|
|
|
|
2002-01-16 22:49:03 +00:00
|
|
|
#include "sc-pkcs11.h"
|
|
|
|
|
2010-09-22 14:41:50 +00:00
|
|
|
static void sc_find_release(sc_pkcs11_operation_t *operation);
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
/* Pseudo mechanism for the Find operation */
|
2010-01-24 20:45:02 +00:00
|
|
|
static sc_pkcs11_mechanism_type_t find_mechanism = {
|
2010-12-17 19:09:24 +00:00
|
|
|
0, /* mech */
|
|
|
|
{0,0,0}, /* mech_info */
|
|
|
|
0, /* key_type */
|
|
|
|
sizeof(struct sc_pkcs11_find_operation), /* obj_size */
|
|
|
|
sc_find_release, /* release */
|
|
|
|
NULL, /* md_init */
|
|
|
|
NULL, /* md_update */
|
|
|
|
NULL, /* md_final */
|
|
|
|
NULL, /* sign_init */
|
|
|
|
NULL, /* sign_update */
|
|
|
|
NULL, /* sign_final */
|
|
|
|
NULL, /* sign_size */
|
|
|
|
#ifdef ENABLE_OPENSSL
|
|
|
|
NULL, /* verif_init */
|
|
|
|
NULL, /* verif_update */
|
|
|
|
NULL, /* verif_final */
|
|
|
|
#endif
|
|
|
|
NULL, /* decrypt_init */
|
|
|
|
NULL, /* decrypt */
|
|
|
|
NULL /* mech_data */
|
2002-12-17 11:49:12 +00:00
|
|
|
};
|
|
|
|
|
2010-09-22 14:41:50 +00:00
|
|
|
static void sc_find_release(sc_pkcs11_operation_t *operation)
|
|
|
|
{
|
|
|
|
struct sc_pkcs11_find_operation *fop =
|
|
|
|
(struct sc_pkcs11_find_operation *)operation;
|
|
|
|
|
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL,"freeing %d handles used %d at %p",
|
|
|
|
fop->allocated_handles, fop->num_handles, fop->handles);
|
|
|
|
if (fop->handles) {
|
|
|
|
free(fop->handles);
|
|
|
|
fop->handles = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
static CK_RV get_object_from_session(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
|
|
|
|
struct sc_pkcs11_session **session,
|
|
|
|
struct sc_pkcs11_object **object)
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV rv;
|
|
|
|
struct sc_pkcs11_session *sess;
|
|
|
|
rv = get_session(hSession, &sess);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
*object = list_seek(&sess->slot->objects, &hObject);
|
|
|
|
if (!*object)
|
|
|
|
return CKR_OBJECT_HANDLE_INVALID;
|
|
|
|
*session = sess;
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
|
|
|
|
CK_ULONG ulCount, /* attributes in template */
|
|
|
|
CK_OBJECT_HANDLE_PTR phObject)
|
|
|
|
{ /* receives new object's handle. */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-04-11 15:17:33 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_card *card;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pTemplate == NULL_PTR || ulCount == 0)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_CALLED(context, SC_LOG_DEBUG_VERBOSE);
|
Fix: any of these calls
C_CreateObject(hSession, NULL_PTR, 1, NULL_PTR);
C_GetAttributeValue(hSession, hObject, NULL_PTR, 1);
C_SetAttributeValue(hSession, hObject, NULL_PTR, 1);
C_FindObjectsInit(hSession, NULL_PTR, 1);
C_FindObjects(hSession, NULL_PTR, 0, NULL_PTR);
C_FindObjects(hSession, NULL_PTR, 1, NULL_PTR);
C_FindObjects(hSession, NULL_PTR, 1, pulObjectCount);
C_DigestInit(hSession, NULL_PTR);
C_SignInit(hSession, NULL_PTR, hKey);
C_SignRecoverInit(hSession, NULL_PTR, hKey);
C_DecryptInit(hSession, NULL_PTR, hKey);
C_VerifyInit(hSession, NULL_PTR, hKey);
C_GenerateKeyPair(hSession, NULL_PTR, pubKeyTmpl, arraysize(pubKeyTmpl),
prvKeyTmpl, arraysize(prvKeyTmpl), &hPubKey, &hPrvKey);
C_GenerateKeyPair(hSession, pMechanism, pubKeyTmpl,
arraysize(pubKeyTmpl), NULL_PTR, 1, &hPubKey, &hPrvKey);
C_GenerateKeyPair(hSession, pMechanism, NULL_PTR, 1, prvKeyTmpl,
arraysize(prvKeyTmpl), &hPubKey, &hPrvKey);
=>
Segmentation fault
Remark: Allow calls:
C_FindObjectsInit(hSession, NULL_PTR, 0)
C_GenerateKeyPair(hSession, pMechanism, NULL_PTR, 0, NULL_PTR, 0, phPublicKey, phPrivateKey)
C_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, ulWrappedKeyLen, NULL_PTR, 0, phKey)
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3891 c6295689-39f2-0310-b995-f0e70906c6a9
2009-12-10 14:50:32 +00:00
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, "C_CreateObject()", pTemplate, ulCount);
|
2002-04-11 15:17:33 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
session = list_seek(&sessions, &hSession);
|
|
|
|
if (!session) {
|
|
|
|
rv = CKR_SESSION_HANDLE_INVALID;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2010-01-24 20:45:02 +00:00
|
|
|
}
|
2002-04-11 15:17:33 +00:00
|
|
|
|
Fix: return CKR_SESSION_READ_ONLY from C_InitPIN, C_SetPIN,
C_CreateObject, C_CopyObject, C_DestroyObject, C_SetAttributeValue,
C_GenerateKey, C_GenerateKeyPair, C_UnwrapKey, C_DeriveKey if session is
read-only.
PKCS#11:
"C_InitPIN can only be called in the 'R/W SO Functions' state."
"C_SetPIN can only be called in the 'R/W Public Session' state, 'R/W SO
Functions' state, or 'R/W User Functions' state. An attempt to call it
from a session in any other state fails with error CKR_SESSION_READ_ONLY."
"Only session objects can be created/destroyed/modified
(C_CreateObject/C_DestroyObject/C_SetAttributeValue) during a read-only
session."
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3886 c6295689-39f2-0310-b995-f0e70906c6a9
2009-12-08 14:29:49 +00:00
|
|
|
if (!(session->flags & CKF_RW_SESSION)) {
|
|
|
|
rv = CKR_SESSION_READ_ONLY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2002-04-11 15:17:33 +00:00
|
|
|
card = session->slot->card;
|
|
|
|
if (card->framework->create_object == NULL)
|
2003-02-17 14:21:38 +00:00
|
|
|
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
else
|
|
|
|
rv = card->framework->create_object(card, session->slot,
|
2010-01-27 16:04:19 +00:00
|
|
|
pTemplate, ulCount, phObject);
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2010-12-01 20:08:42 +00:00
|
|
|
SC_FUNC_RETURN(context, SC_LOG_DEBUG_VERBOSE, rv);
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
|
|
|
|
CK_ULONG ulCount, /* attributes in template */
|
|
|
|
CK_OBJECT_HANDLE_PTR phNewObject)/* receives handle of copy */
|
2002-01-16 22:49:03 +00:00
|
|
|
{
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE hObject)
|
|
|
|
{ /* the object's handle */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2007-06-21 09:37:18 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
|
|
|
|
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_DestroyObject(hSession=0x%lx, hObject=0x%lx)", hSession, hObject);
|
2007-06-21 09:37:18 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_object_from_session(hSession, hObject, &session, &object);
|
2007-06-21 09:37:18 +00:00
|
|
|
if (rv != CKR_OK)
|
|
|
|
goto out;
|
|
|
|
|
Fix: return CKR_SESSION_READ_ONLY from C_InitPIN, C_SetPIN,
C_CreateObject, C_CopyObject, C_DestroyObject, C_SetAttributeValue,
C_GenerateKey, C_GenerateKeyPair, C_UnwrapKey, C_DeriveKey if session is
read-only.
PKCS#11:
"C_InitPIN can only be called in the 'R/W SO Functions' state."
"C_SetPIN can only be called in the 'R/W Public Session' state, 'R/W SO
Functions' state, or 'R/W User Functions' state. An attempt to call it
from a session in any other state fails with error CKR_SESSION_READ_ONLY."
"Only session objects can be created/destroyed/modified
(C_CreateObject/C_DestroyObject/C_SetAttributeValue) during a read-only
session."
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3886 c6295689-39f2-0310-b995-f0e70906c6a9
2009-12-08 14:29:49 +00:00
|
|
|
if (!(session->flags & CKF_RW_SESSION)) {
|
|
|
|
rv = CKR_SESSION_READ_ONLY;
|
|
|
|
goto out;
|
|
|
|
}
|
2010-01-27 12:22:50 +00:00
|
|
|
|
2007-06-21 09:37:18 +00:00
|
|
|
if (object->ops->destroy_object == NULL)
|
|
|
|
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
else
|
|
|
|
rv = object->ops->destroy_object(session, object);
|
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2007-06-21 09:37:18 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
|
|
|
CK_ULONG_PTR pulSize)
|
|
|
|
{ /* receives size of object */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes, gets values */
|
|
|
|
CK_ULONG ulCount)
|
|
|
|
{ /* attributes in template */
|
2002-11-22 09:09:04 +00:00
|
|
|
static int precedence[] = {
|
|
|
|
CKR_OK,
|
|
|
|
CKR_BUFFER_TOO_SMALL,
|
|
|
|
CKR_ATTRIBUTE_TYPE_INVALID,
|
|
|
|
CKR_ATTRIBUTE_SENSITIVE,
|
|
|
|
-1
|
|
|
|
};
|
2010-01-24 20:45:02 +00:00
|
|
|
char object_name[64];
|
2010-06-16 11:43:10 +00:00
|
|
|
int j;
|
|
|
|
CK_RV rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
2010-01-24 20:45:02 +00:00
|
|
|
int res, res_type;
|
2005-01-19 18:15:43 +00:00
|
|
|
unsigned int i;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pTemplate == NULL_PTR || ulCount == 0)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
rv = get_object_from_session(hSession, hObject, &session, &object);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2003-04-16 14:18:07 +00:00
|
|
|
/* Debug printf */
|
2010-01-24 20:45:02 +00:00
|
|
|
snprintf(object_name, sizeof(object_name), "Object %lu", (unsigned long)hObject);
|
2003-04-16 14:18:07 +00:00
|
|
|
|
2002-11-22 09:09:04 +00:00
|
|
|
res_type = 0;
|
2002-01-16 22:49:03 +00:00
|
|
|
for (i = 0; i < ulCount; i++) {
|
2010-01-24 20:45:02 +00:00
|
|
|
res = object->ops->get_attribute(session, object, &pTemplate[i]);
|
2002-11-22 09:09:04 +00:00
|
|
|
if (res != CKR_OK)
|
2010-01-24 20:45:02 +00:00
|
|
|
pTemplate[i].ulValueLen = (CK_ULONG) - 1;
|
2002-11-22 09:09:04 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, object_name, &pTemplate[i], 1);
|
2003-04-16 14:18:07 +00:00
|
|
|
|
2002-11-22 09:09:04 +00:00
|
|
|
/* the pkcs11 spec has complicated rules on
|
|
|
|
* what errors take precedence:
|
2010-01-24 20:45:02 +00:00
|
|
|
* CKR_ATTRIBUTE_SENSITIVE
|
|
|
|
* CKR_ATTRIBUTE_INVALID
|
|
|
|
* CKR_BUFFER_TOO_SMALL
|
2002-11-22 09:09:04 +00:00
|
|
|
* It does not exactly specify how other errors
|
|
|
|
* should be handled - we give them highest
|
|
|
|
* precedence
|
|
|
|
*/
|
|
|
|
for (j = 0; precedence[j] != -1; j++) {
|
|
|
|
if (precedence[j] == res)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (j > res_type) {
|
|
|
|
res_type = j;
|
|
|
|
rv = res;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = %s",
|
2010-01-27 16:04:19 +00:00
|
|
|
hSession, hObject, lookup_enum ( RV_T, rv ));
|
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE hObject, /* the object's handle */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes and values */
|
|
|
|
CK_ULONG ulCount)
|
|
|
|
{ /* attributes in template */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2005-01-19 18:15:43 +00:00
|
|
|
unsigned int i;
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pTemplate == NULL_PTR || ulCount == 0)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, "C_SetAttributeValue", pTemplate, ulCount);
|
2003-04-16 14:18:07 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_object_from_session(hSession, hObject, &session, &object);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
Fix: return CKR_SESSION_READ_ONLY from C_InitPIN, C_SetPIN,
C_CreateObject, C_CopyObject, C_DestroyObject, C_SetAttributeValue,
C_GenerateKey, C_GenerateKeyPair, C_UnwrapKey, C_DeriveKey if session is
read-only.
PKCS#11:
"C_InitPIN can only be called in the 'R/W SO Functions' state."
"C_SetPIN can only be called in the 'R/W Public Session' state, 'R/W SO
Functions' state, or 'R/W User Functions' state. An attempt to call it
from a session in any other state fails with error CKR_SESSION_READ_ONLY."
"Only session objects can be created/destroyed/modified
(C_CreateObject/C_DestroyObject/C_SetAttributeValue) during a read-only
session."
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3886 c6295689-39f2-0310-b995-f0e70906c6a9
2009-12-08 14:29:49 +00:00
|
|
|
if (!(session->flags & CKF_RW_SESSION)) {
|
|
|
|
rv = CKR_SESSION_READ_ONLY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2002-01-16 22:49:03 +00:00
|
|
|
if (object->ops->set_attribute == NULL)
|
2005-01-19 20:12:55 +00:00
|
|
|
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
2003-02-17 14:21:38 +00:00
|
|
|
else {
|
|
|
|
for (i = 0; i < ulCount; i++) {
|
|
|
|
rv = object->ops->set_attribute(session, object, &pTemplate[i]);
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
break;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
|
|
|
|
CK_ULONG ulCount)
|
|
|
|
{ /* attributes in search template */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2005-01-19 20:12:55 +00:00
|
|
|
CK_BBOOL is_private = TRUE;
|
2002-01-16 22:49:03 +00:00
|
|
|
CK_ATTRIBUTE private_attribute = { CKA_PRIVATE, &is_private, sizeof(is_private) };
|
2010-06-16 11:43:10 +00:00
|
|
|
int match, hide_private;
|
2010-01-24 20:45:02 +00:00
|
|
|
unsigned int i, j;
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
|
|
|
struct sc_pkcs11_find_operation *operation;
|
2003-05-15 15:27:33 +00:00
|
|
|
struct sc_pkcs11_slot *slot;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pTemplate == NULL_PTR && ulCount > 0)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_FindObjectsInit(slot = %d)\n", session->slot->id);
|
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, "C_FindObjectsInit()", pTemplate, ulCount);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = session_start_operation(session, SC_PKCS11_OPERATION_FIND,
|
2010-01-24 20:45:02 +00:00
|
|
|
&find_mechanism, (struct sc_pkcs11_operation **)&operation);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2005-01-19 20:12:55 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2005-01-19 20:12:55 +00:00
|
|
|
operation->current_handle = 0;
|
2002-01-16 22:49:03 +00:00
|
|
|
operation->num_handles = 0;
|
2010-09-22 14:41:50 +00:00
|
|
|
operation->allocated_handles = 0;
|
|
|
|
operation->handles = NULL;
|
2003-05-15 15:27:33 +00:00
|
|
|
slot = session->slot;
|
|
|
|
|
|
|
|
/* Check whether we should hide private objects */
|
|
|
|
hide_private = 0;
|
2010-01-24 20:45:02 +00:00
|
|
|
if (slot->login_user != CKU_USER && (slot->token_info.flags & CKF_LOGIN_REQUIRED))
|
2003-05-15 15:27:33 +00:00
|
|
|
hide_private = 1;
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2002-01-16 22:49:03 +00:00
|
|
|
/* For each object in token do */
|
2010-01-24 20:45:02 +00:00
|
|
|
for (i=0; i<list_size(&slot->objects); i++) {
|
|
|
|
object = (struct sc_pkcs11_object *)list_get_at(&slot->objects, i);
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Object with handle 0x%lx", object->handle);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
/* User not logged in and private object? */
|
2003-05-15 15:27:33 +00:00
|
|
|
if (hide_private) {
|
2002-01-16 22:49:03 +00:00
|
|
|
if (object->ops->get_attribute(session, object, &private_attribute) != CKR_OK)
|
2010-01-24 20:45:02 +00:00
|
|
|
continue;
|
2002-01-24 16:27:09 +00:00
|
|
|
if (is_private) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL,
|
2010-01-24 20:45:02 +00:00
|
|
|
"Object %d/%d: Private object and not logged in.\n",
|
|
|
|
slot->id, object->handle);
|
2002-01-24 16:27:09 +00:00
|
|
|
continue;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Try to match every attribute */
|
2005-01-19 20:12:55 +00:00
|
|
|
match = 1;
|
2002-01-16 22:49:03 +00:00
|
|
|
for (j = 0; j < ulCount; j++) {
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = object->ops->cmp_attribute(session, object, &pTemplate[j]);
|
2002-03-18 11:05:21 +00:00
|
|
|
if (rv == 0) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL,
|
|
|
|
"Object %d/%d: Attribute 0x%x does NOT match.\n",
|
|
|
|
slot->id, object->handle, pTemplate[j].type);
|
2002-01-16 22:49:03 +00:00
|
|
|
match = 0;
|
2005-01-19 20:12:55 +00:00
|
|
|
break;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2003-04-16 14:18:07 +00:00
|
|
|
if (context->debug >= 4) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Object %d/%d: Attribute 0x%x matches.\n",
|
2010-01-24 20:45:02 +00:00
|
|
|
slot->id, object->handle, pTemplate[j].type);
|
2003-04-16 14:18:07 +00:00
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (match) {
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "Object %d/%d matches\n", slot->id, object->handle);
|
2010-09-22 14:41:50 +00:00
|
|
|
/* Realloc handles - remove restriction on only 32 matching objects -dee */
|
|
|
|
if (operation->num_handles >= operation->allocated_handles) {
|
|
|
|
operation->allocated_handles += SC_PKCS11_FIND_INC_HANDLES;
|
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "realloc for %d handles",
|
|
|
|
operation->allocated_handles);
|
|
|
|
operation->handles = realloc(operation->handles,
|
|
|
|
sizeof(CK_OBJECT_HANDLE) * operation->allocated_handles);
|
|
|
|
if (operation->handles == NULL) {
|
|
|
|
rv = CKR_HOST_MEMORY;
|
|
|
|
break;
|
|
|
|
}
|
2002-03-04 06:58:12 +00:00
|
|
|
}
|
2010-01-24 20:45:02 +00:00
|
|
|
operation->handles[operation->num_handles++] = object->handle;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
}
|
2003-02-20 18:54:52 +00:00
|
|
|
rv = CKR_OK;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "%d matching objects\n", operation->num_handles);
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE_PTR phObject, /* receives object handle array */
|
|
|
|
CK_ULONG ulMaxObjectCount, /* max handles to be returned */
|
|
|
|
CK_ULONG_PTR pulObjectCount)
|
|
|
|
{ /* actual number returned */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2005-01-19 18:15:43 +00:00
|
|
|
CK_ULONG to_return;
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_find_operation *operation;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (phObject == NULL_PTR || ulMaxObjectCount == 0 || pulObjectCount == NULL_PTR)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = session_get_operation(session, SC_PKCS11_OPERATION_FIND,
|
2010-01-24 20:45:02 +00:00
|
|
|
(sc_pkcs11_operation_t **) & operation);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
to_return = (CK_ULONG) operation->num_handles - operation->current_handle;
|
2002-01-16 22:49:03 +00:00
|
|
|
if (to_return > ulMaxObjectCount)
|
|
|
|
to_return = ulMaxObjectCount;
|
|
|
|
|
|
|
|
*pulObjectCount = to_return;
|
|
|
|
|
|
|
|
memcpy(phObject,
|
|
|
|
&operation->handles[operation->current_handle],
|
|
|
|
to_return * sizeof(CK_OBJECT_HANDLE));
|
|
|
|
|
2005-02-11 20:09:34 +00:00
|
|
|
operation->current_handle += to_return;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2003-02-17 14:21:38 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
|
|
|
|
{ /* the session's handle */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = session_get_operation(session, SC_PKCS11_OPERATION_FIND, NULL);
|
2003-02-17 14:21:38 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
session_stop_operation(session, SC_PKCS11_OPERATION_FIND);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2003-02-17 14:21:38 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Below here all functions are wrappers to pass all object attribute and method
|
|
|
|
* handling to appropriate object layer.
|
|
|
|
*/
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism)
|
|
|
|
{ /* the digesting mechanism */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pMechanism == NULL_PTR)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_DigestInit(hSession=0x%lx)", hSession);
|
2010-01-27 16:04:19 +00:00
|
|
|
rv = get_session(hSession, &session);
|
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_md_init(session, pMechanism);
|
|
|
|
|
2010-11-06 17:00:09 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_DigestInit() = %s", lookup_enum ( RV_T, rv ));
|
2010-01-24 20:45:02 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pData, /* data to be digested */
|
|
|
|
CK_ULONG ulDataLen, /* bytes of data to be digested */
|
|
|
|
CK_BYTE_PTR pDigest, /* receives the message digest */
|
|
|
|
CK_ULONG_PTR pulDigestLen)
|
|
|
|
{ /* receives byte length of digest */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2011-06-23 14:10:46 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Digest(hSession=0x%lx)", hSession);
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2002-12-17 11:49:12 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
|
|
|
rv = sc_pkcs11_md_update(session, pData, ulDataLen);
|
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Digest() = %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pPart, /* data to be digested */
|
|
|
|
CK_ULONG ulPartLen)
|
|
|
|
{ /* bytes of data to be digested */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2010-01-27 16:04:19 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_md_update(session, pPart, ulPartLen);
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_DigestUpdate() == %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DigestKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of secret key to digest */
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pDigest, /* receives the message digest */
|
|
|
|
CK_ULONG_PTR pulDigestLen)
|
|
|
|
{ /* receives byte count of digest */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2010-01-27 16:04:19 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_DigestFinal() = %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SignInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of the signature key */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2005-01-19 20:12:55 +00:00
|
|
|
CK_BBOOL can_sign;
|
2002-12-17 11:49:12 +00:00
|
|
|
CK_KEY_TYPE key_type;
|
2002-01-16 22:49:03 +00:00
|
|
|
CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) };
|
2002-12-17 11:49:12 +00:00
|
|
|
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pMechanism == NULL_PTR)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_object_from_session(hSession, hKey, &session, &object);
|
2009-12-07 12:50:59 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
|
|
|
rv = CKR_KEY_HANDLE_INVALID;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2009-12-07 12:50:59 +00:00
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2003-02-17 14:21:38 +00:00
|
|
|
if (object->ops->sign == NULL_PTR) {
|
2005-02-11 20:09:34 +00:00
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
|
|
|
rv = object->ops->get_attribute(session, object, &sign_attribute);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK || !can_sign) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_SignInit() = %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pData, /* the data (digest) to be signed */
|
|
|
|
CK_ULONG ulDataLen, /* count of bytes to be signed */
|
|
|
|
CK_BYTE_PTR pSignature, /* receives the signature */
|
|
|
|
CK_ULONG_PTR pulSignatureLen)
|
|
|
|
{ /* receives byte count of signature */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
2003-01-03 14:28:50 +00:00
|
|
|
CK_ULONG length;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2002-01-16 22:49:03 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2003-01-03 14:28:50 +00:00
|
|
|
/* According to the pkcs11 specs, we must not do any calls that
|
|
|
|
* change our crypto state if the caller is just asking for the
|
|
|
|
* signature buffer size, or if the result would be
|
|
|
|
* CKR_BUFFER_TOO_SMALL. Thus we cannot do the sign_update call
|
|
|
|
* below. */
|
|
|
|
if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2003-01-03 14:28:50 +00:00
|
|
|
|
|
|
|
if (pSignature == NULL || length > *pulSignatureLen) {
|
|
|
|
*pulSignatureLen = length;
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = pSignature ? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2003-01-03 14:28:50 +00:00
|
|
|
}
|
|
|
|
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = sc_pkcs11_sign_update(session, pData, ulDataLen);
|
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
2002-01-16 22:49:03 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Sign() = %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pPart, /* the data (digest) to be signed */
|
|
|
|
CK_ULONG ulPartLen)
|
|
|
|
{ /* count of bytes to be signed */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2003-02-17 14:21:38 +00:00
|
|
|
if (rv == CKR_OK)
|
2010-01-27 16:04:19 +00:00
|
|
|
rv = sc_pkcs11_sign_update(session, pPart, ulPartLen);
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_SignUpdate() = %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pSignature, /* receives the signature */
|
|
|
|
CK_ULONG_PTR pulSignatureLen)
|
|
|
|
{ /* receives byte count of signature */
|
2002-12-17 11:49:12 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
2003-01-03 14:28:50 +00:00
|
|
|
CK_ULONG length;
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2002-12-17 11:49:12 +00:00
|
|
|
if (rv != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2003-01-03 14:28:50 +00:00
|
|
|
/* According to the pkcs11 specs, we must not do any calls that
|
|
|
|
* change our crypto state if the caller is just asking for the
|
|
|
|
* signature buffer size, or if the result would be
|
|
|
|
* CKR_BUFFER_TOO_SMALL.
|
|
|
|
*/
|
|
|
|
if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK)
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2003-01-03 14:28:50 +00:00
|
|
|
|
|
|
|
if (pSignature == NULL || length > *pulSignatureLen) {
|
|
|
|
*pulSignatureLen = length;
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = pSignature ? CKR_BUFFER_TOO_SMALL : CKR_OK;
|
2003-02-17 14:21:38 +00:00
|
|
|
} else {
|
|
|
|
rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen);
|
2003-01-03 14:28:50 +00:00
|
|
|
}
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_SignFinal() = %s", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of the signature key */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2005-02-11 20:09:34 +00:00
|
|
|
CK_BBOOL can_sign;
|
2002-12-17 11:49:12 +00:00
|
|
|
CK_KEY_TYPE key_type;
|
|
|
|
CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) };
|
|
|
|
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-02-24 14:06:04 +00:00
|
|
|
/* FIXME #47: C_SignRecover is not implemented */
|
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pMechanism == NULL_PTR)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_object_from_session(hSession, hKey, &session, &object);
|
2009-12-07 12:50:59 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
|
|
|
rv = CKR_KEY_HANDLE_INVALID;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
2009-12-07 12:50:59 +00:00
|
|
|
}
|
2002-12-17 11:49:12 +00:00
|
|
|
|
2003-02-17 14:21:38 +00:00
|
|
|
if (object->ops->sign == NULL_PTR) {
|
2005-02-11 20:09:34 +00:00
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2002-12-17 11:49:12 +00:00
|
|
|
|
|
|
|
rv = object->ops->get_attribute(session, object, &sign_attribute);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK || !can_sign) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2002-12-17 11:49:12 +00:00
|
|
|
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-02-17 14:21:38 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2002-12-17 11:49:12 +00:00
|
|
|
|
|
|
|
/* XXX: need to tell the signature algorithm that we want
|
|
|
|
* to recover the signature */
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "SignRecover operation initialized\n");
|
2002-12-17 11:49:12 +00:00
|
|
|
|
|
|
|
rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type);
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_SignRecoverInit() = %sn", lookup_enum ( RV_T, rv ));
|
2003-02-17 14:21:38 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-02-11 20:09:34 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SignRecover(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pData, /* the data (digest) to be signed */
|
|
|
|
CK_ULONG ulDataLen, /* count of bytes to be signed */
|
|
|
|
CK_BYTE_PTR pSignature, /* receives the signature */
|
|
|
|
CK_ULONG_PTR pulSignatureLen)
|
|
|
|
{ /* receives byte count of signature */
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of encryption key */
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pData, /* the plaintext data */
|
|
|
|
CK_ULONG ulDataLen, /* bytes of plaintext data */
|
|
|
|
CK_BYTE_PTR pEncryptedData, /* receives encrypted data */
|
|
|
|
CK_ULONG_PTR pulEncryptedDataLen)
|
|
|
|
{ /* receives encrypted byte count */
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pPart, /* the plaintext data */
|
|
|
|
CK_ULONG ulPartLen, /* bytes of plaintext data */
|
|
|
|
CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */
|
|
|
|
CK_ULONG_PTR pulEncryptedPartLen)
|
|
|
|
{ /* receives encrypted byte count */
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pLastEncryptedPart, /* receives encrypted last part */
|
|
|
|
CK_ULONG_PTR pulLastEncryptedPartLen)
|
|
|
|
{ /* receives byte count */
|
2005-02-11 20:09:34 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of the decryption key */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2005-01-19 20:12:55 +00:00
|
|
|
CK_BBOOL can_decrypt;
|
2003-10-01 06:51:49 +00:00
|
|
|
CK_KEY_TYPE key_type;
|
|
|
|
CK_ATTRIBUTE decrypt_attribute = { CKA_DECRYPT, &can_decrypt, sizeof(can_decrypt) };
|
|
|
|
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pMechanism == NULL_PTR)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-10-01 06:51:49 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_object_from_session(hSession, hKey, &session, &object);
|
2009-12-07 12:50:59 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
|
|
|
rv = CKR_KEY_HANDLE_INVALID;
|
2003-10-01 06:51:49 +00:00
|
|
|
goto out;
|
2009-12-07 12:50:59 +00:00
|
|
|
}
|
2003-10-01 06:51:49 +00:00
|
|
|
|
|
|
|
if (object->ops->decrypt == NULL_PTR) {
|
2005-02-11 20:09:34 +00:00
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-10-01 06:51:49 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = object->ops->get_attribute(session, object, &decrypt_attribute);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK || !can_decrypt) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-10-01 06:51:49 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-10-01 06:51:49 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_pkcs11_decr_init(session, pMechanism, object, key_type);
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_DecryptInit() = %s", lookup_enum ( RV_T, rv ));
|
2003-10-01 06:51:49 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pEncryptedData, /* input encrypted data */
|
|
|
|
CK_ULONG ulEncryptedDataLen, /* count of bytes of input */
|
|
|
|
CK_BYTE_PTR pData, /* receives decrypted output */
|
|
|
|
CK_ULONG_PTR pulDataLen)
|
|
|
|
{ /* receives decrypted byte count */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-10-01 06:51:49 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2010-01-27 16:04:19 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_decr(session, pEncryptedData, ulEncryptedDataLen,
|
|
|
|
pData, pulDataLen);
|
2003-10-01 06:51:49 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Decrypt() = %s", lookup_enum ( RV_T, rv ));
|
2003-10-01 06:51:49 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DecryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pEncryptedPart, /* input encrypted data */
|
|
|
|
CK_ULONG ulEncryptedPartLen, /* count of bytes of input */
|
|
|
|
CK_BYTE_PTR pPart, /* receives decrypted output */
|
|
|
|
CK_ULONG_PTR pulPartLen)
|
|
|
|
{ /* receives decrypted byte count */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pLastPart, /* receives decrypted output */
|
|
|
|
CK_ULONG_PTR pulLastPartLen)
|
|
|
|
{ /* receives decrypted byte count */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pPart, /* the plaintext data */
|
|
|
|
CK_ULONG ulPartLen, /* bytes of plaintext data */
|
|
|
|
CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */
|
|
|
|
CK_ULONG_PTR pulEncryptedPartLen)
|
|
|
|
{ /* receives encrypted byte count */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pEncryptedPart, /* input encrypted data */
|
|
|
|
CK_ULONG ulEncryptedPartLen, /* count of bytes of input */
|
|
|
|
CK_BYTE_PTR pPart, /* receives decrypted output */
|
|
|
|
CK_ULONG_PTR pulPartLen)
|
|
|
|
{ /* receives decrypted byte count */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pPart, /* the plaintext data */
|
|
|
|
CK_ULONG ulPartLen, /* bytes of plaintext data */
|
|
|
|
CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */
|
|
|
|
CK_ULONG_PTR pulEncryptedPartLen)
|
|
|
|
{ /* receives encrypted byte count */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pEncryptedPart, /* input encrypted data */
|
|
|
|
CK_ULONG ulEncryptedPartLen, /* count of byes of input */
|
|
|
|
CK_BYTE_PTR pPart, /* receives decrypted output */
|
|
|
|
CK_ULONG_PTR pulPartLen)
|
|
|
|
{ /* receives decrypted byte count */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the key generation mechanism */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */
|
|
|
|
CK_ULONG ulCount, /* number of attributes in template */
|
|
|
|
CK_OBJECT_HANDLE_PTR phKey)
|
|
|
|
{ /* receives handle of new key */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the key gen. mech. */
|
|
|
|
CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* pub. attr. template */
|
|
|
|
CK_ULONG ulPublicKeyAttributeCount, /* # of pub. attrs. */
|
|
|
|
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* priv. attr. template */
|
|
|
|
CK_ULONG ulPrivateKeyAttributeCount, /* # of priv. attrs. */
|
|
|
|
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */
|
|
|
|
CK_OBJECT_HANDLE_PTR phPrivateKey)
|
|
|
|
{ /* gets priv. key handle */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-06-03 13:57:52 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_slot *slot;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pMechanism == NULL_PTR
|
|
|
|
|| (pPublicKeyTemplate == NULL_PTR && ulPublicKeyAttributeCount > 0)
|
|
|
|
|| (pPrivateKeyTemplate == NULL_PTR && ulPrivateKeyAttributeCount > 0))
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-06-03 13:57:52 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2010-04-21 10:51:13 +00:00
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, "C_GenerateKeyPair(), PrivKey attrs", pPrivateKeyTemplate, ulPrivateKeyAttributeCount);
|
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, "C_GenerateKeyPair(), PubKey attrs", pPublicKeyTemplate, ulPublicKeyAttributeCount);
|
2003-06-03 13:57:52 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2003-06-03 13:57:52 +00:00
|
|
|
if (rv != CKR_OK)
|
|
|
|
goto out;
|
|
|
|
|
Fix: return CKR_SESSION_READ_ONLY from C_InitPIN, C_SetPIN,
C_CreateObject, C_CopyObject, C_DestroyObject, C_SetAttributeValue,
C_GenerateKey, C_GenerateKeyPair, C_UnwrapKey, C_DeriveKey if session is
read-only.
PKCS#11:
"C_InitPIN can only be called in the 'R/W SO Functions' state."
"C_SetPIN can only be called in the 'R/W Public Session' state, 'R/W SO
Functions' state, or 'R/W User Functions' state. An attempt to call it
from a session in any other state fails with error CKR_SESSION_READ_ONLY."
"Only session objects can be created/destroyed/modified
(C_CreateObject/C_DestroyObject/C_SetAttributeValue) during a read-only
session."
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3886 c6295689-39f2-0310-b995-f0e70906c6a9
2009-12-08 14:29:49 +00:00
|
|
|
if (!(session->flags & CKF_RW_SESSION)) {
|
|
|
|
rv = CKR_SESSION_READ_ONLY;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2003-06-03 13:57:52 +00:00
|
|
|
slot = session->slot;
|
|
|
|
if (slot->card->framework->gen_keypair == NULL) {
|
|
|
|
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
} else {
|
|
|
|
rv = slot->card->framework->gen_keypair(slot->card, slot,
|
2010-01-24 20:45:02 +00:00
|
|
|
pMechanism, pPublicKeyTemplate,
|
|
|
|
ulPublicKeyAttributeCount,
|
|
|
|
pPrivateKeyTemplate,
|
|
|
|
ulPrivateKeyAttributeCount, phPublicKey,
|
|
|
|
phPrivateKey);
|
2003-06-03 13:57:52 +00:00
|
|
|
}
|
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
out: sc_pkcs11_unlock();
|
2003-06-03 13:57:52 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_WrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
|
|
|
|
CK_OBJECT_HANDLE hWrappingKey, /* handle of the wrapping key */
|
|
|
|
CK_OBJECT_HANDLE hKey, /* handle of the key to be wrapped */
|
|
|
|
CK_BYTE_PTR pWrappedKey, /* receives the wrapped key */
|
|
|
|
CK_ULONG_PTR pulWrappedKeyLen)
|
|
|
|
{ /* receives byte size of wrapped key */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_UnwrapKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the unwrapping mechanism */
|
|
|
|
CK_OBJECT_HANDLE hUnwrappingKey, /* handle of the unwrapping key */
|
|
|
|
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
|
|
|
|
CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */
|
|
|
|
CK_ULONG ulAttributeCount, /* # of attributes in template */
|
|
|
|
CK_OBJECT_HANDLE_PTR phKey)
|
|
|
|
{ /* gets handle of recovered key */
|
2010-08-23 14:47:07 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the key derivation mechanism */
|
|
|
|
CK_OBJECT_HANDLE hBaseKey, /* handle of the base key */
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */
|
|
|
|
CK_ULONG ulAttributeCount, /* # of attributes in template */
|
|
|
|
CK_OBJECT_HANDLE_PTR phKey)
|
|
|
|
{ /* gets handle of derived key */
|
2010-12-01 20:08:42 +00:00
|
|
|
/* TODO: -DEE ECDH with Cofactor on PIV is an example */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_SeedRandom(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pSeed, /* the seed material */
|
|
|
|
CK_ULONG ulSeedLen)
|
|
|
|
{ /* count of bytes of seed material */
|
2010-09-01 06:23:26 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_GenerateRandom(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR RandomData, /* receives the random data */
|
|
|
|
CK_ULONG ulRandomLen)
|
|
|
|
{ /* number of bytes to be generated */
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-01-16 20:10:28 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
2010-01-24 20:45:02 +00:00
|
|
|
struct sc_pkcs11_slot *slot;
|
2003-01-16 20:10:28 +00:00
|
|
|
|
2003-02-19 13:44:36 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
2003-02-17 14:21:38 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2005-07-18 20:20:22 +00:00
|
|
|
if (rv == CKR_OK) {
|
|
|
|
slot = session->slot;
|
|
|
|
if (slot->card->framework->get_random == NULL)
|
2008-11-24 22:06:27 +00:00
|
|
|
rv = CKR_RANDOM_NO_RNG;
|
2005-07-18 20:20:22 +00:00
|
|
|
else
|
|
|
|
rv = slot->card->framework->get_random(slot->card, RandomData, ulRandomLen);
|
|
|
|
}
|
2003-01-16 20:10:28 +00:00
|
|
|
|
2010-01-27 16:04:19 +00:00
|
|
|
sc_pkcs11_unlock();
|
2003-02-17 14:21:38 +00:00
|
|
|
return rv;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
|
|
|
|
{ /* the session's handle */
|
|
|
|
return CKR_FUNCTION_NOT_PARALLEL;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_CancelFunction(CK_SESSION_HANDLE hSession)
|
|
|
|
{ /* the session's handle */
|
|
|
|
return CKR_FUNCTION_NOT_PARALLEL;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of the verification key */
|
2008-03-06 16:06:59 +00:00
|
|
|
#ifndef ENABLE_OPENSSL
|
2003-06-27 15:26:17 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
#else
|
2003-08-05 17:28:29 +00:00
|
|
|
#if 0
|
2005-02-11 20:09:34 +00:00
|
|
|
CK_BBOOL can_verify;
|
2003-06-27 15:26:17 +00:00
|
|
|
CK_ATTRIBUTE verify_attribute = { CKA_VERIFY, &can_verify, sizeof(can_verify) };
|
2003-08-05 17:28:29 +00:00
|
|
|
#endif
|
|
|
|
CK_KEY_TYPE key_type;
|
2003-06-27 15:26:17 +00:00
|
|
|
CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
struct sc_pkcs11_object *object;
|
|
|
|
|
2010-08-23 14:47:14 +00:00
|
|
|
if (pMechanism == NULL_PTR)
|
|
|
|
return CKR_ARGUMENTS_BAD;
|
|
|
|
|
2003-06-27 15:26:17 +00:00
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
Fix: any of these calls
C_CreateObject(hSession, NULL_PTR, 1, NULL_PTR);
C_GetAttributeValue(hSession, hObject, NULL_PTR, 1);
C_SetAttributeValue(hSession, hObject, NULL_PTR, 1);
C_FindObjectsInit(hSession, NULL_PTR, 1);
C_FindObjects(hSession, NULL_PTR, 0, NULL_PTR);
C_FindObjects(hSession, NULL_PTR, 1, NULL_PTR);
C_FindObjects(hSession, NULL_PTR, 1, pulObjectCount);
C_DigestInit(hSession, NULL_PTR);
C_SignInit(hSession, NULL_PTR, hKey);
C_SignRecoverInit(hSession, NULL_PTR, hKey);
C_DecryptInit(hSession, NULL_PTR, hKey);
C_VerifyInit(hSession, NULL_PTR, hKey);
C_GenerateKeyPair(hSession, NULL_PTR, pubKeyTmpl, arraysize(pubKeyTmpl),
prvKeyTmpl, arraysize(prvKeyTmpl), &hPubKey, &hPrvKey);
C_GenerateKeyPair(hSession, pMechanism, pubKeyTmpl,
arraysize(pubKeyTmpl), NULL_PTR, 1, &hPubKey, &hPrvKey);
C_GenerateKeyPair(hSession, pMechanism, NULL_PTR, 1, prvKeyTmpl,
arraysize(prvKeyTmpl), &hPubKey, &hPrvKey);
=>
Segmentation fault
Remark: Allow calls:
C_FindObjectsInit(hSession, NULL_PTR, 0)
C_GenerateKeyPair(hSession, pMechanism, NULL_PTR, 0, NULL_PTR, 0, phPublicKey, phPrivateKey)
C_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, ulWrappedKeyLen, NULL_PTR, 0, phKey)
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3891 c6295689-39f2-0310-b995-f0e70906c6a9
2009-12-10 14:50:32 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_object_from_session(hSession, hKey, &session, &object);
|
2009-12-07 12:50:59 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
if (rv == CKR_OBJECT_HANDLE_INVALID)
|
|
|
|
rv = CKR_KEY_HANDLE_INVALID;
|
2003-06-27 15:26:17 +00:00
|
|
|
goto out;
|
2009-12-07 12:50:59 +00:00
|
|
|
}
|
2003-07-11 16:31:06 +00:00
|
|
|
#if 0
|
|
|
|
rv = object->ops->get_attribute(session, object, &verify_attribute);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK || !can_verify) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-07-11 16:31:06 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
#endif
|
2003-06-27 15:26:17 +00:00
|
|
|
rv = object->ops->get_attribute(session, object, &key_type_attr);
|
2005-02-11 20:09:34 +00:00
|
|
|
if (rv != CKR_OK) {
|
|
|
|
rv = CKR_KEY_TYPE_INCONSISTENT;
|
2003-06-27 15:26:17 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = sc_pkcs11_verif_init(session, pMechanism, object, key_type);
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_VerifyInit() = %s", lookup_enum ( RV_T, rv ));
|
2003-06-27 15:26:17 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
#endif
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_Verify(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pData, /* plaintext data (digest) to compare */
|
|
|
|
CK_ULONG ulDataLen, /* length of data (digest) in bytes */
|
|
|
|
CK_BYTE_PTR pSignature, /* the signature to be verified */
|
|
|
|
CK_ULONG ulSignatureLen)
|
|
|
|
{ /* count of bytes of signature */
|
2008-03-06 16:06:59 +00:00
|
|
|
#ifndef ENABLE_OPENSSL
|
2003-06-27 15:26:17 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
#else
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2003-06-27 15:26:17 +00:00
|
|
|
if (rv != CKR_OK)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
rv = sc_pkcs11_verif_update(session, pData, ulDataLen);
|
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen);
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
out: sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Verify() = %s", lookup_enum ( RV_T, rv ));
|
2003-06-27 15:26:17 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
#endif
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pPart, /* plaintext data (digest) to compare */
|
|
|
|
CK_ULONG ulPartLen)
|
|
|
|
{ /* length of data (digest) in bytes */
|
2008-03-06 16:06:59 +00:00
|
|
|
#ifndef ENABLE_OPENSSL
|
2003-06-27 15:26:17 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
#else
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2003-06-27 15:26:17 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_verif_update(session, pPart, ulPartLen);
|
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_VerifyUpdate() = %s", lookup_enum ( RV_T, rv ));
|
2003-06-27 15:26:17 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
#endif
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pSignature, /* the signature to be verified */
|
|
|
|
CK_ULONG ulSignatureLen)
|
|
|
|
{ /* count of bytes of signature */
|
2008-03-06 16:06:59 +00:00
|
|
|
#ifndef ENABLE_OPENSSL
|
2003-06-27 15:26:17 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
|
|
|
#else
|
2010-06-16 11:43:10 +00:00
|
|
|
CK_RV rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
struct sc_pkcs11_session *session;
|
|
|
|
|
|
|
|
rv = sc_pkcs11_lock();
|
|
|
|
if (rv != CKR_OK)
|
|
|
|
return rv;
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
rv = get_session(hSession, &session);
|
2010-01-27 16:04:19 +00:00
|
|
|
if (rv == CKR_OK)
|
|
|
|
rv = sc_pkcs11_verif_final(session, pSignature, ulSignatureLen);
|
2010-01-24 20:45:02 +00:00
|
|
|
|
2010-03-15 12:17:13 +00:00
|
|
|
sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_VerifyFinal() = %s", lookup_enum ( RV_T, rv ));
|
2003-06-27 15:26:17 +00:00
|
|
|
sc_pkcs11_unlock();
|
2005-01-19 20:12:55 +00:00
|
|
|
return rv;
|
2003-06-27 15:26:17 +00:00
|
|
|
#endif
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
|
|
|
|
CK_OBJECT_HANDLE hKey)
|
|
|
|
{ /* handle of the verification key */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
CK_RV C_VerifyRecover(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|
|
|
CK_BYTE_PTR pSignature, /* the signature to be verified */
|
|
|
|
CK_ULONG ulSignatureLen, /* count of bytes of signature */
|
|
|
|
CK_BYTE_PTR pData, /* receives decrypted data (digest) */
|
|
|
|
CK_ULONG_PTR pulDataLen)
|
|
|
|
{ /* receives byte count of data */
|
2005-01-19 20:12:55 +00:00
|
|
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
2002-01-16 22:49:03 +00:00
|
|
|
}
|
|
|
|
|
2002-03-18 11:05:21 +00:00
|
|
|
/*
|
|
|
|
* Helper function to compare attributes on any sort of object
|
|
|
|
*/
|
2010-01-24 20:45:02 +00:00
|
|
|
int sc_pkcs11_any_cmp_attribute(struct sc_pkcs11_session *session, void *ptr, CK_ATTRIBUTE_PTR attr)
|
2002-03-18 11:05:21 +00:00
|
|
|
{
|
2010-06-16 11:43:10 +00:00
|
|
|
int rv;
|
2002-03-18 11:05:21 +00:00
|
|
|
struct sc_pkcs11_object *object;
|
2010-01-24 20:45:02 +00:00
|
|
|
u8 temp1[1024];
|
|
|
|
u8 *temp2 = NULL; /* dynamic allocation for large attributes */
|
|
|
|
CK_ATTRIBUTE temp_attr;
|
2010-06-16 11:43:10 +00:00
|
|
|
int res;
|
2002-03-18 11:05:21 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
object = (struct sc_pkcs11_object *)ptr;
|
2002-03-18 11:05:21 +00:00
|
|
|
temp_attr.type = attr->type;
|
2003-11-20 09:17:57 +00:00
|
|
|
temp_attr.pValue = NULL;
|
|
|
|
temp_attr.ulValueLen = 0;
|
2002-03-18 11:05:21 +00:00
|
|
|
|
2003-11-20 09:17:57 +00:00
|
|
|
/* Get the length of the attribute */
|
2002-03-18 11:05:21 +00:00
|
|
|
rv = object->ops->get_attribute(session, object, &temp_attr);
|
2003-11-20 09:17:57 +00:00
|
|
|
if (rv != CKR_OK || temp_attr.ulValueLen != attr->ulValueLen)
|
2002-03-18 11:05:21 +00:00
|
|
|
return 0;
|
|
|
|
|
2003-11-20 09:17:57 +00:00
|
|
|
if (temp_attr.ulValueLen <= sizeof(temp1))
|
|
|
|
temp_attr.pValue = temp1;
|
|
|
|
else {
|
Do not cast the return value of malloc(3) and calloc(3)
From http://en.wikipedia.org/wiki/Malloc#Casting_and_type_safety
" Casting and type safety
malloc returns a void pointer (void *), which indicates that it is a
pointer to a region of unknown data type. One may "cast" (see type
conversion) this pointer to a specific type, as in
int *ptr = (int*)malloc(10 * sizeof (int));
When using C, this is considered bad practice; it is redundant under the
C standard. Moreover, putting in a cast may mask failure to include the
header stdlib.h, in which the prototype for malloc is found. In the
absence of a prototype for malloc, the C compiler will assume that
malloc returns an int, and will issue a warning in a context such as the
above, provided the error is not masked by a cast. On certain
architectures and data models (such as LP64 on 64 bit systems, where
long and pointers are 64 bit and int is 32 bit), this error can actually
result in undefined behavior, as the implicitly declared malloc returns
a 32 bit value whereas the actually defined function returns a 64 bit
value. Depending on calling conventions and memory layout, this may
result in stack smashing.
The returned pointer need not be explicitly cast to a more specific
pointer type, since ANSI C defines an implicit conversion between the
void pointer type and other pointers to objects. An explicit cast of
malloc's return value is sometimes performed because malloc originally
returned a char *, but this cast is unnecessary in standard C
code.[4][5] Omitting the cast, however, creates an incompatibility with
C++, which does require it.
The lack of a specific pointer type returned from malloc is type-unsafe
behaviour: malloc allocates based on byte count but not on type. This
distinguishes it from the C++ new operator that returns a pointer whose
type relies on the operand. (see C Type Safety). "
See also
http://www.opensc-project.org/pipermail/opensc-devel/2010-August/014586.html
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4636 c6295689-39f2-0310-b995-f0e70906c6a9
2010-08-18 15:08:51 +00:00
|
|
|
temp2 = malloc(temp_attr.ulValueLen);
|
2003-11-20 09:17:57 +00:00
|
|
|
if (temp2 == NULL)
|
|
|
|
return 0;
|
|
|
|
temp_attr.pValue = temp2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the attribute */
|
|
|
|
rv = object->ops->get_attribute(session, object, &temp_attr);
|
|
|
|
if (rv != CKR_OK) {
|
|
|
|
res = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
2002-03-18 11:05:21 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
{
|
2010-01-24 20:45:02 +00:00
|
|
|
char foo[64];
|
2002-03-18 11:05:21 +00:00
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
snprintf(foo, sizeof(foo), "Object %p (slot 0x%lx)", object, session->slot->id);
|
2010-03-15 12:17:13 +00:00
|
|
|
dump_template(SC_LOG_DEBUG_NORMAL, foo, &temp_attr, 1);
|
2002-03-18 11:05:21 +00:00
|
|
|
}
|
|
|
|
#endif
|
2003-11-20 09:17:57 +00:00
|
|
|
res = temp_attr.ulValueLen == attr->ulValueLen
|
|
|
|
&& !memcmp(temp_attr.pValue, attr->pValue, attr->ulValueLen);
|
|
|
|
|
2010-01-24 20:45:02 +00:00
|
|
|
done:
|
2003-11-20 09:17:57 +00:00
|
|
|
if (temp2 != NULL)
|
|
|
|
free(temp2);
|
|
|
|
|
|
|
|
return res;
|
2002-03-18 11:05:21 +00:00
|
|
|
}
|