Implementid basic signing functionality.
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@24 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
a1af155018
commit
2f086f5261
|
@ -1,5 +1,24 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "sc-pkcs11.h"
|
#include "sc-pkcs11.h"
|
||||||
|
|
||||||
|
static void hex_dump(const unsigned char *buf, int count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
unsigned char c = buf[i];
|
||||||
|
int printch = 0;
|
||||||
|
if (!isalnum(c) && !ispunct(c) && !isspace(c))
|
||||||
|
printch = 0;
|
||||||
|
if (printch)
|
||||||
|
LOG("%02X%c ", c, c);
|
||||||
|
else
|
||||||
|
LOG("%02X ", c);
|
||||||
|
}
|
||||||
|
LOG("\n");
|
||||||
|
}
|
||||||
|
|
||||||
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
CK_MECHANISM_PTR pMechanism) /* the digesting mechanism */
|
CK_MECHANISM_PTR pMechanism) /* the digesting mechanism */
|
||||||
{
|
{
|
||||||
|
@ -44,8 +63,41 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
|
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
|
||||||
CK_OBJECT_HANDLE hKey) /* handle of the signature key */
|
CK_OBJECT_HANDLE hKey) /* handle of the signature key */
|
||||||
{
|
{
|
||||||
LOG("C_SignInit\n");
|
struct pkcs11_slot *slt;
|
||||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
struct pkcs11_session *ses;
|
||||||
|
struct pkcs11_object *object;
|
||||||
|
|
||||||
|
LOG("C_SignInit(%d, {%d, 0x%x, %d}, %d)\n",
|
||||||
|
hSession,
|
||||||
|
pMechanism->mechanism, pMechanism->pParameter, pMechanism->ulParameterLen,
|
||||||
|
hKey);
|
||||||
|
|
||||||
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
||||||
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
ses = session[hSession];
|
||||||
|
slt = &slot[ses->slot];
|
||||||
|
if (hKey < 1 || hKey > slt->num_objects)
|
||||||
|
return CKR_OBJECT_HANDLE_INVALID;
|
||||||
|
object = slt->object[hKey];
|
||||||
|
|
||||||
|
if (object->object_type != CKO_PRIVATE_KEY)
|
||||||
|
return CKR_OBJECT_HANDLE_INVALID;
|
||||||
|
|
||||||
|
switch (pMechanism->mechanism) {
|
||||||
|
case CKM_RSA_PKCS:
|
||||||
|
// Signing according to PKCS#1 standard
|
||||||
|
LOG("CKM_RSA_PKCS mechanism requested\n");
|
||||||
|
ses->sign.algorithm_ref = 0x02;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG("Requested mechanism #d not supported\n", pMechanism->mechanism);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("Token id is %d\n", object->token_id);
|
||||||
|
ses->sign.private_key_id = object->token_id;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
|
@ -54,15 +106,57 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
CK_BYTE_PTR pSignature, /* receives the signature */
|
CK_BYTE_PTR pSignature, /* receives the signature */
|
||||||
CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */
|
CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */
|
||||||
{
|
{
|
||||||
LOG("C_Sign\n");
|
char signature[1024];
|
||||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
struct sc_pkcs15_card *p15card;
|
||||||
|
struct sc_security_env senv;
|
||||||
|
struct pkcs11_session *ses;
|
||||||
|
int i, c;
|
||||||
|
|
||||||
|
LOG("C_Sign(%d, 0x%x, %d, 0x%x, 0x%x)\n",
|
||||||
|
hSession, pData, ulDataLen, pSignature, pulSignatureLen);
|
||||||
|
hex_dump(pData, ulDataLen);
|
||||||
|
|
||||||
|
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
|
||||||
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
ses = session[hSession];
|
||||||
|
p15card = slot[ses->slot].p15card;
|
||||||
|
|
||||||
|
senv.signature = 1;
|
||||||
|
senv.algorithm_ref = ses->sign.algorithm_ref; //0x02;
|
||||||
|
senv.key_ref = 0;
|
||||||
|
senv.key_file_id = p15card->prkey_info[ses->sign.private_key_id].file_id;
|
||||||
|
senv.app_df_path = p15card->file_app.path;
|
||||||
|
i = sc_set_security_env(p15card->card, &senv);
|
||||||
|
if (i) {
|
||||||
|
LOG("Security environment set failed: %s\n", sc_strerror(i));
|
||||||
|
return CKR_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = sc_compute_signature(p15card->card, pData, ulDataLen, signature, sizeof(signature));
|
||||||
|
if (c < 0) {
|
||||||
|
LOG("Compute signature failed: (%d) %s\n", c, sc_strerror(c));
|
||||||
|
return CKR_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pulSignatureLen < c) {
|
||||||
|
LOG("Buffer too small, %d < %d\n", *pulSignatureLen, c);
|
||||||
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("Got signature, %d bytes (buffer was %d)\n", c, *pulSignatureLen);
|
||||||
|
hex_dump(signature, c);
|
||||||
|
memcpy(pSignature, signature, c);
|
||||||
|
*pulSignatureLen = c;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
CK_BYTE_PTR pPart, /* the data (digest) to be signed */
|
CK_BYTE_PTR pPart, /* the data (digest) to be signed */
|
||||||
CK_ULONG ulPartLen) /* count of bytes to be signed */
|
CK_ULONG ulPartLen) /* count of bytes to be signed */
|
||||||
{
|
{
|
||||||
LOG("C_SignUpdate\n");
|
LOG("C_SignUpdate(%d, 0x%x, %d)\n",
|
||||||
|
hSession, pPart, ulPartLen);
|
||||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +164,8 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||||
CK_BYTE_PTR pSignature, /* receives the signature */
|
CK_BYTE_PTR pSignature, /* receives the signature */
|
||||||
CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */
|
CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */
|
||||||
{
|
{
|
||||||
LOG("C_SignFinal\n");
|
LOG("C_SignFinal(%d, 0x%x, %d)\n",
|
||||||
|
hSession, pSignature, pulSignatureLen);
|
||||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "pkcs11/pkcs11.h"
|
#include "pkcs11/pkcs11.h"
|
||||||
#include "../sc.h"
|
#include "../sc.h"
|
||||||
|
#include "../sc-pkcs15.h"
|
||||||
|
|
||||||
#define PKCS11_MAX_SLOTS 4
|
#define PKCS11_MAX_SLOTS 4
|
||||||
#define PKCS11_MAX_SESSIONS 8
|
#define PKCS11_MAX_SESSIONS 8
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
|
|
||||||
// Object information
|
// Object information
|
||||||
struct pkcs11_object {
|
struct pkcs11_object {
|
||||||
|
int object_type, token_id;
|
||||||
int num_attributes;
|
int num_attributes;
|
||||||
CK_ATTRIBUTE_PTR attribute;
|
CK_ATTRIBUTE_PTR attribute;
|
||||||
};
|
};
|
||||||
|
@ -21,6 +23,11 @@ struct pkcs11_search_context {
|
||||||
int num_matches, position;
|
int num_matches, position;
|
||||||
CK_OBJECT_HANDLE handles[PKCS11_MAX_OBJECTS];
|
CK_OBJECT_HANDLE handles[PKCS11_MAX_OBJECTS];
|
||||||
};
|
};
|
||||||
|
// Signing information
|
||||||
|
struct pkcs11_sign_context {
|
||||||
|
int private_key_id;
|
||||||
|
int algorithm_ref;
|
||||||
|
};
|
||||||
|
|
||||||
// Per session information; "context"
|
// Per session information; "context"
|
||||||
struct pkcs11_session {
|
struct pkcs11_session {
|
||||||
|
@ -31,6 +38,7 @@ struct pkcs11_session {
|
||||||
CK_VOID_PTR notify_parameter;
|
CK_VOID_PTR notify_parameter;
|
||||||
|
|
||||||
struct pkcs11_search_context search;
|
struct pkcs11_search_context search;
|
||||||
|
struct pkcs11_sign_context sign;
|
||||||
//...
|
//...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,30 @@
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include "sc-pkcs11.h"
|
#include "sc-pkcs11.h"
|
||||||
|
|
||||||
|
static CK_BYTE modulus[] =
|
||||||
|
#if 0
|
||||||
|
"\x00\xc7\x50\xbb\x9e\xf7\x43\x18\x7e\x8d\xb5\xe3\xa1\x6e\x4c"
|
||||||
|
"\x8c\x0f\x0f\xc7\x9a\xce\xad\x05\x1b\x16\xf0\x30\x25\xdb\x1f"
|
||||||
|
"\xbd\xf3\x68\x76\x29\xee\x75\x97\xba\x20\x1a\x48\xa8\x55\xa1"
|
||||||
|
"\x50\x91\x45\x0e\x64\x70\xcd\xda\x52\x0b\x67\x94\x16\x89\x73"
|
||||||
|
"\x7d\xa1\x7c\x5b\xa9\x29\xd8\xe2\x38\xc8\x24\x73\xaa\xc1\x7a"
|
||||||
|
"\x99\x6f\x4f\xe9\xa6\xcc\x9e\x02\xd4\xb2\xf1\xf5\xe5\x94\x1f"
|
||||||
|
"\x30\x70\x6c\x29\xe6\x65\x06\x55\x67\xc5\xa7\x35\x82\x5c\x6d"
|
||||||
|
"\x4d\xe7\x60\x83\xf4\x0c\xed\xbe\x6b\xb1\xc3\xe4\x55\x99\x7f"
|
||||||
|
"\x79\x07\x99\x2f\x65\x8b\xe5\x89\xe5";
|
||||||
|
#else
|
||||||
|
"\x00\xba\xb3\xc3\x65\xfb\xab\xd3\x4f\xf1\xe8\x72\xb8\xaa\x48"
|
||||||
|
"\x6a\x82\x31\x43\xc9\x3e\xe6\xff\x6b\xb6\x0e\xa3\x82\xb4\xda"
|
||||||
|
"\x3f\xed\xa6\x0b\xbc\xf2\xd3\xad\x53\x88\x88\x14\x14\x3f\x2b"
|
||||||
|
"\x24\x8d\xd7\x3f\x4b\xb3\xe6\xc1\xb9\xb1\x4d\x3a\x10\xc4\x65"
|
||||||
|
"\xdc\xe2\xa1\x27\xd2\x8f\xb2\x67\x54\x34\x73\x53\xeb\xec\x84"
|
||||||
|
"\xab\xdd\xc1\x76\xc9\x73\x49\x4c\x7c\x18\x98\xd3\x40\xc4\x1c"
|
||||||
|
"\xfd\x0d\x6b\xae\xb7\x9f\x44\xc6\x0a\x5a\x89\x91\xb8\x6e\x20"
|
||||||
|
"\x38\x2b\xff\x42\xf7\xfe\x95\xc0\x1f\xa5\xca\x07\x2e\x4a\xb0"
|
||||||
|
"\x9c\x07\x60\x02\x61\xe1\x8b\x25\x01";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void set_attribute(CK_ATTRIBUTE_PTR attr, CK_OBJECT_CLASS oc, void *ptr, int len)
|
void set_attribute(CK_ATTRIBUTE_PTR attr, CK_OBJECT_CLASS oc, void *ptr, int len)
|
||||||
{
|
{
|
||||||
attr->type = oc;
|
attr->type = oc;
|
||||||
|
@ -10,35 +34,50 @@ void set_attribute(CK_ATTRIBUTE_PTR attr, CK_OBJECT_CLASS oc, void *ptr, int len
|
||||||
attr->ulValueLen = len;
|
attr->ulValueLen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slot_add_object(int id, CK_ATTRIBUTE_PTR object, int num_attrs)
|
int slot_add_object(int id, int token_id, CK_ATTRIBUTE_PTR object, int num_attrs)
|
||||||
{
|
{
|
||||||
struct pkcs11_slot *slt = &slot[id];
|
struct pkcs11_slot *slt = &slot[id];
|
||||||
int idx;
|
int idx, i;
|
||||||
|
|
||||||
if (slt->num_objects >= PKCS11_MAX_OBJECTS)
|
if (slt->num_objects >= PKCS11_MAX_OBJECTS)
|
||||||
return CKR_BUFFER_TOO_SMALL;
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
idx = ++slt->num_objects;
|
idx = ++slt->num_objects;
|
||||||
slt->object[idx] = (struct pkcs11_object*) malloc(sizeof(struct pkcs11_object));
|
slt->object[idx] = (struct pkcs11_object*) malloc(sizeof(struct pkcs11_object));
|
||||||
|
slt->object[idx]->object_type = -1;
|
||||||
|
slt->object[idx]->token_id = token_id;
|
||||||
slt->object[idx]->num_attributes = num_attrs;
|
slt->object[idx]->num_attributes = num_attrs;
|
||||||
slt->object[idx]->attribute = object;
|
slt->object[idx]->attribute = object;
|
||||||
|
|
||||||
|
for (i = 0; i < num_attrs; i++) {
|
||||||
|
if (object[i].type == CKA_CLASS && object[i].ulValueLen == 4) {
|
||||||
|
slt->object[idx]->object_type = *(int*)object[i].pValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slot_add_private_key_object(int id, struct sc_pkcs15_prkey_info *key)
|
int slot_add_private_key_object(int id, int token_id, struct sc_pkcs15_prkey_info *key)
|
||||||
{
|
{
|
||||||
static CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
|
static CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
|
||||||
CK_ATTRIBUTE_PTR object = (CK_ATTRIBUTE_PTR) malloc(sizeof(CK_ATTRIBUTE) * 3);
|
static CK_BBOOL btrue = 1;
|
||||||
|
static CK_KEY_TYPE rsakey = CKK_RSA;
|
||||||
|
CK_ATTRIBUTE_PTR object = (CK_ATTRIBUTE_PTR) malloc(sizeof(CK_ATTRIBUTE) * 6);
|
||||||
|
|
||||||
set_attribute(&object[0], CKA_CLASS, &key_class, sizeof(key_class));
|
set_attribute(&object[0], CKA_CLASS, &key_class, sizeof(key_class));
|
||||||
set_attribute(&object[1], CKA_LABEL, key->com_attr.label, strlen(key->com_attr.label));
|
set_attribute(&object[1], CKA_LABEL, key->com_attr.label, strlen(key->com_attr.label));
|
||||||
set_attribute(&object[2], CKA_ID, key->id.value, key->id.len);
|
set_attribute(&object[2], CKA_ID, key->id.value, key->id.len);
|
||||||
|
set_attribute(&object[3], CKA_TOKEN, &btrue, sizeof(btrue));
|
||||||
|
set_attribute(&object[4], CKA_KEY_TYPE, &rsakey, sizeof(rsakey));
|
||||||
|
set_attribute(&object[5], CKA_MODULUS, modulus, sizeof(modulus)-1);
|
||||||
|
|
||||||
return slot_add_object(id, object, 3);
|
return slot_add_object(id, token_id, object, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
int slot_add_certificate_object(int id, struct sc_pkcs15_cert_info *cert,
|
int slot_add_certificate_object(int id, int token_id,
|
||||||
|
struct sc_pkcs15_cert_info *cert,
|
||||||
u8 *x509data, int x509length)
|
u8 *x509data, int x509length)
|
||||||
{
|
{
|
||||||
static CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
|
static CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
|
||||||
|
@ -49,7 +88,7 @@ int slot_add_certificate_object(int id, struct sc_pkcs15_cert_info *cert,
|
||||||
set_attribute(&object[2], CKA_ID, cert->id.value, cert->id.len);
|
set_attribute(&object[2], CKA_ID, cert->id.value, cert->id.len);
|
||||||
set_attribute(&object[3], CKA_VALUE, x509data, x509length);
|
set_attribute(&object[3], CKA_VALUE, x509data, x509length);
|
||||||
|
|
||||||
return slot_add_object(id, object, 4);
|
return slot_add_object(id, token_id, object, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int slot_connect(int id)
|
int slot_connect(int id)
|
||||||
|
@ -96,7 +135,7 @@ int slot_connect(int id)
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
LOG("Adding '%s' certificate object.\n", p15card->cert_info[c].com_attr.label);
|
LOG("Adding '%s' certificate object.\n", p15card->cert_info[c].com_attr.label);
|
||||||
slot_add_certificate_object(id, &p15card->cert_info[c],
|
slot_add_certificate_object(id, c, &p15card->cert_info[c],
|
||||||
buf, len);
|
buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +146,7 @@ int slot_connect(int id)
|
||||||
LOG("Found total of %d private keys.\n", r);
|
LOG("Found total of %d private keys.\n", r);
|
||||||
for (c = 0; c < r; c++) {
|
for (c = 0; c < r; c++) {
|
||||||
LOG("Adding '%s' private key object.\n", p15card->prkey_info[c].com_attr.label);
|
LOG("Adding '%s' private key object.\n", p15card->prkey_info[c].com_attr.label);
|
||||||
slot_add_private_key_object(id, &p15card->prkey_info[c]);
|
slot_add_private_key_object(id, c, &p15card->prkey_info[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
Loading…
Reference in New Issue