split libp11.h in an internal and a public part.
add p11_ops.c and other code by kevin stefanik. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2401 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
cbada7cbca
commit
23685829b8
|
@ -4,12 +4,13 @@ MAINTAINERCLEANFILES = Makefile.in
|
|||
DISTCLEANFILES= libp11.pc
|
||||
EXTRA_DIST = Makefile.mak
|
||||
|
||||
noinst_HEADERS= libp11-int.h
|
||||
include_HEADERS= libp11.h
|
||||
|
||||
lib_LTLIBRARIES = libp11.la
|
||||
|
||||
libp11_la_SOURCES = p11_attr.c p11_cert.c p11_err.c p11_key.c \
|
||||
p11_load.c p11_misc.c p11_rsa.c p11_slot.c
|
||||
p11_load.c p11_misc.c p11_rsa.c p11_slot.c p11_ops.c
|
||||
|
||||
libp11_la_CFLAGS = -I$(srcdir)
|
||||
libp11_la_LDFLAGS = -version-info @OPENSC_LT_CURRENT@:@OPENSC_LT_REVISION@:@OPENSC_LT_AGE@
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* pkcs11.h */
|
||||
/* libp11.h */
|
||||
/* Written by Olaf Kirch <okir@lst.de>
|
||||
*/
|
||||
/* ====================================================================
|
||||
|
@ -55,12 +55,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef _PKCS11_INTERNAL_H
|
||||
#define _PKCS11_INTERNAL_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#ifndef _LIB11_INT_H
|
||||
#define _LIB11_INT_H
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
@ -212,123 +208,6 @@ extern void ERR_load_PKCS11_strings(void);
|
|||
#define PKCS11_NO_SESSION (PKCS11_ERR_BASE+5)
|
||||
#define PKCS11_KEYGEN_FAILED (PKCS11_ERR_BASE+6)
|
||||
|
||||
/* get private implementations of PKCS11 structures */
|
||||
|
||||
/*
|
||||
* PKCS11_CTX: context for a PKCS11 implementation
|
||||
*/
|
||||
typedef struct pkcs11_ctx_private {
|
||||
char *name;
|
||||
void *libinfo;
|
||||
CK_FUNCTION_LIST_PTR method;
|
||||
|
||||
CK_SESSION_HANDLE session;
|
||||
int nslots;
|
||||
PKCS11_SLOT *slots;
|
||||
} PKCS11_CTX_private;
|
||||
#define PRIVCTX(ctx) ((PKCS11_CTX_private *) (ctx->_private))
|
||||
|
||||
typedef struct pkcs11_slot_private {
|
||||
PKCS11_CTX *parent;
|
||||
unsigned char haveSession, loggedIn;
|
||||
CK_SLOT_ID id;
|
||||
CK_SESSION_HANDLE session;
|
||||
} PKCS11_SLOT_private;
|
||||
#define PRIVSLOT(slot) ((PKCS11_SLOT_private *) (slot->_private))
|
||||
#define SLOT2CTX(slot) (PRIVSLOT(slot)->parent)
|
||||
|
||||
typedef struct pkcs11_token_private {
|
||||
PKCS11_SLOT *parent;
|
||||
int nkeys, nprkeys;
|
||||
PKCS11_KEY *keys;
|
||||
int ncerts;
|
||||
PKCS11_CERT *certs;
|
||||
} PKCS11_TOKEN_private;
|
||||
#define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) (token->_private))
|
||||
#define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent)
|
||||
#define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token))
|
||||
|
||||
typedef struct pkcs11_key_ops {
|
||||
int type; /* EVP_PKEY_xxx */
|
||||
int (*get_public) (PKCS11_KEY *, EVP_PKEY *);
|
||||
int (*get_private) (PKCS11_KEY *, EVP_PKEY *);
|
||||
} PKCS11_KEY_ops;
|
||||
|
||||
typedef struct pkcs11_key_private {
|
||||
PKCS11_TOKEN *parent;
|
||||
CK_OBJECT_HANDLE object;
|
||||
unsigned char id[255];
|
||||
size_t id_len;
|
||||
PKCS11_KEY_ops *ops;
|
||||
} PKCS11_KEY_private;
|
||||
#define PRIVKEY(key) ((PKCS11_KEY_private *) key->_private)
|
||||
#define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key))
|
||||
#define KEY2TOKEN(key) (PRIVKEY(key)->parent)
|
||||
#define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key))
|
||||
|
||||
typedef struct pkcs11_cert_private {
|
||||
PKCS11_TOKEN *parent;
|
||||
CK_OBJECT_HANDLE object;
|
||||
unsigned char id[255];
|
||||
size_t id_len;
|
||||
} PKCS11_CERT_private;
|
||||
#define PRIVCERT(cert) ((PKCS11_CERT_private *) cert->_private)
|
||||
|
||||
/*
|
||||
* Mapping Cryptoki error codes to those used internally
|
||||
* by this code.
|
||||
* Right now, we just map them directly, and make sure
|
||||
* that the few genuine messages we use don't clash with
|
||||
* PKCS#11
|
||||
*/
|
||||
#define pkcs11_map_err(rv) (rv)
|
||||
|
||||
/*
|
||||
* Internal functions
|
||||
*/
|
||||
#define CRYPTOKI_checkerr(f, rv) \
|
||||
do { if (rv) { \
|
||||
PKCS11err(f, pkcs11_map_err(rv)); \
|
||||
return -1; \
|
||||
} } while (0)
|
||||
#define CRYPTOKI_call(ctx, func_and_args) \
|
||||
PRIVCTX(ctx)->method->func_and_args
|
||||
|
||||
/* Memory allocation */
|
||||
#define PKCS11_NEW(type) \
|
||||
((type *) pkcs11_malloc(sizeof(type)))
|
||||
#define PKCS11_DUP(s) \
|
||||
pkcs11_strdup((char *) s, sizeof(s))
|
||||
|
||||
extern int PKCS11_open_session(PKCS11_SLOT *, int);
|
||||
extern void pkcs11_destroy_all_slots(PKCS11_CTX *);
|
||||
extern void pkcs11_destroy_slot(PKCS11_CTX *, PKCS11_SLOT *);
|
||||
extern void pkcs11_destroy_keys(PKCS11_TOKEN *);
|
||||
extern void pkcs11_destroy_certs(PKCS11_TOKEN *);
|
||||
extern void *pkcs11_malloc(size_t);
|
||||
extern char *pkcs11_strdup(char *, size_t);
|
||||
|
||||
extern int pkcs11_getattr(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||
unsigned int, void *, size_t);
|
||||
extern int pkcs11_getattr_s(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||
unsigned int, void *, size_t);
|
||||
extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||
unsigned int, void *, size_t *);
|
||||
extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||
unsigned int, BIGNUM **);
|
||||
|
||||
typedef int (*pkcs11_i2d_fn) (void *, unsigned char **);
|
||||
extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t);
|
||||
extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long);
|
||||
extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *);
|
||||
extern void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *);
|
||||
extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *);
|
||||
extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int);
|
||||
|
||||
extern void *memdup(const void *, size_t);
|
||||
|
||||
extern PKCS11_KEY_ops pkcs11_rsa_ops;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
* Copyright (C) 2002, Olaf Kirch <okir@lst.de>
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libp11-int.h"
|
||||
|
||||
static int pkcs11_getattr_int(PKCS11_CTX *, CK_SESSION_HANDLE,
|
||||
CK_OBJECT_HANDLE, CK_ATTRIBUTE_TYPE, void *, size_t *);
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* Copyright (C) 2002, Olaf Kirch <okir@lst.de>
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <string.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
static int pkcs11_find_certs(PKCS11_TOKEN *);
|
||||
static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *, CK_SESSION_HANDLE);
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef NO_ERR
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <string.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
|
||||
static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||
|
@ -68,12 +68,14 @@ static int pkcs11_store_private_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
|
|||
unsigned char *, unsigned int, PKCS11_KEY **);
|
||||
static int pkcs11_store_public_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
|
||||
unsigned char *, unsigned int, PKCS11_KEY **);
|
||||
static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen);
|
||||
|
||||
static CK_OBJECT_CLASS key_search_class;
|
||||
static CK_ATTRIBUTE key_search_attrs[] = {
|
||||
{CKA_CLASS, &key_search_class, sizeof(key_search_class)},
|
||||
};
|
||||
#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
#define MAX_VALUE_LEN 200
|
||||
|
||||
/*
|
||||
* Enumerate all keys on the card
|
||||
|
@ -183,6 +185,12 @@ EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY * key)
|
|||
return pk;
|
||||
}
|
||||
|
||||
EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY * key)
|
||||
{
|
||||
return PKCS11_get_private_key(key);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find all keys of a given type (public or private)
|
||||
*/
|
||||
|
@ -212,6 +220,225 @@ int pkcs11_find_keys(PKCS11_TOKEN * token, unsigned int type)
|
|||
return (res < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
int pkcs11_find_key(PKCS11_CTX * ctx, PKCS11_KEY **key, char* passphrase, char* s_slot_key_id, int verbose)
|
||||
{
|
||||
/* need to confirm if passphrase required, perhaps substitute callback */
|
||||
|
||||
#define fail(msg) { fprintf(stderr,msg); return NULL;}
|
||||
PKCS11_SLOT *slot, *slot_list;
|
||||
PKCS11_TOKEN *tok;
|
||||
PKCS11_CERT *certs;
|
||||
PKCS11_KEY *keys, *selected_key = NULL;
|
||||
char *s_key_id = NULL, buf[MAX_VALUE_LEN];
|
||||
size_t key_id_len;
|
||||
int slot_nr = -1;
|
||||
char flags[64];
|
||||
int logged_in = 0;
|
||||
int n,m,count,isPrivate=0;
|
||||
|
||||
char *p_sep1, *p_sep2;
|
||||
char val[MAX_VALUE_LEN];
|
||||
int val_len;;
|
||||
|
||||
key_id_len=strlen(s_slot_key_id);
|
||||
while (s_slot_key_id != NULL && *(s_slot_key_id) != '\0') {
|
||||
|
||||
p_sep1 = strchr(s_slot_key_id, '_');
|
||||
if (p_sep1 == NULL) {
|
||||
fprintf(stderr,"No \'_\' found in key id option \"%s\"\n", s_slot_key_id);
|
||||
fprintf(stderr,"Format: [slot_<slotNr>][-][id_<keyID>]\n");
|
||||
fprintf(stderr," with slotNr = 0, 1, ... and keyID = a hex string\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_sep2 = strchr(p_sep1, '-');
|
||||
if (p_sep2 == NULL)
|
||||
p_sep2 = p_sep1 + strlen(p_sep1);
|
||||
|
||||
/* val = the string between the _ and the - (or '\0') */
|
||||
val_len = p_sep2 - p_sep1 - 1;
|
||||
if (val_len >= MAX_VALUE_LEN || val_len == 0) {
|
||||
fprintf(stderr,"Too long or empty value after the \'-\' sign\n"); return 0; }
|
||||
memcpy(val, p_sep1 + 1, val_len);
|
||||
val[val_len] = '\0';
|
||||
|
||||
if (strncasecmp(s_slot_key_id, "slot", p_sep1 - s_slot_key_id) == 0) {
|
||||
if (val_len >= 3) {
|
||||
fprintf(stderr,"Slot number \"%s\" should be a small integer\n", val);
|
||||
return 0;
|
||||
}
|
||||
slot_nr = atoi(val);
|
||||
if (slot_nr == 0 && val[0] != '0') {
|
||||
fprintf(stderr,"Slot number \"%s\" should be an integer\n", val);
|
||||
return 0;
|
||||
}
|
||||
} else if (strncasecmp(s_slot_key_id, "id", p_sep1 - s_slot_key_id)
|
||||
== 0) {
|
||||
if (!hex_to_bin(p_sep1+1, val, &key_id_len)) {
|
||||
fprintf(stderr,"Key id \"%s\" should be a hex string\n", val);
|
||||
return 0;
|
||||
}
|
||||
strcpy(buf, val);
|
||||
s_key_id = buf;
|
||||
} else {
|
||||
memcpy(val, s_slot_key_id, p_sep1 - s_slot_key_id);
|
||||
val[p_sep1 - s_slot_key_id] = '\0';
|
||||
fprintf(stderr,"Now allowed in -key: \"%s\"\n", val);
|
||||
return 0;
|
||||
}
|
||||
s_slot_key_id = (*p_sep2 == '\0' ? p_sep2 : p_sep2 + 1);
|
||||
}
|
||||
|
||||
if (PKCS11_enumerate_slots(ctx, &slot_list, &count) < 0) {
|
||||
fprintf(stderr, "failed to enumerate slots\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(verbose) {
|
||||
fprintf(stderr,"Found %u slot%s\n", count, (count <= 1) ? "" : "s");
|
||||
}
|
||||
|
||||
if(verbose) { /* or looking for labelled token */
|
||||
for (n = 0; n < count; n++) {
|
||||
slot = slot_list + n;
|
||||
flags[0] = '\0';
|
||||
if (slot->token) {
|
||||
if (!slot->token->initialized)
|
||||
strcat(flags, "uninitialized, ");
|
||||
else if (!slot->token->userPinSet)
|
||||
strcat(flags, "no pin, ");
|
||||
if (slot->token->loginRequired)
|
||||
strcat(flags, "login, ");
|
||||
if (slot->token->readOnly)
|
||||
strcat(flags, "ro, ");
|
||||
} else {
|
||||
strcpy(flags, "no token");
|
||||
}
|
||||
if ((m = strlen(flags)) != 0) {
|
||||
flags[m - 2] = '\0';
|
||||
}
|
||||
|
||||
fprintf(stderr,"[%u] %-25.25s %-16s", n, slot->description, flags);
|
||||
if (slot->token) {
|
||||
fprintf(stderr," (%s)",
|
||||
slot->token->label[0] ?
|
||||
slot->token->label : "no label");
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (slot_nr == -1) {
|
||||
if (!(slot = PKCS11_find_token(ctx)))
|
||||
fail("didn't find any tokens\n");
|
||||
} else if (slot_nr >= 0 && slot_nr < count)
|
||||
slot = slot_list + slot_nr;
|
||||
else {
|
||||
fprintf(stderr,"Invalid slot number: %d\n", slot_nr);
|
||||
return 0;
|
||||
}
|
||||
tok = slot->token;
|
||||
|
||||
if (tok == NULL) {
|
||||
fprintf(stderr,"Found empty token; \n");
|
||||
return 0;
|
||||
}
|
||||
if (!tok->initialized) {
|
||||
fprintf(stderr,"Found uninitialized token; \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isPrivate && !tok->userPinSet && !tok->readOnly) {
|
||||
fprintf(stderr,"Found slot without user PIN\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(verbose) {
|
||||
fprintf(stderr,"Found slot: %s\n", slot->description);
|
||||
fprintf(stderr,"Found token: %s\n", slot->token->label);
|
||||
}
|
||||
|
||||
|
||||
if(verbose) {
|
||||
if (PKCS11_enumerate_certs(tok, &certs, &count))
|
||||
fail("unable to enumerate certificates\n");
|
||||
fprintf(stderr,"Found %u certificate%s:\n", count, (count <= 1) ? "" : "s");
|
||||
for (n = 0; n < count; n++) {
|
||||
PKCS11_CERT *c = certs + n;
|
||||
char *dn = NULL;
|
||||
|
||||
fprintf(stderr," %2u %s", n + 1, c->label);
|
||||
if (c->x509)
|
||||
dn = X509_NAME_oneline(X509_get_subject_name(c->x509), NULL, 0);
|
||||
if (dn) {
|
||||
fprintf(stderr," (%s)", dn);
|
||||
OPENSSL_free(dn);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (PKCS11_enumerate_keys(tok, &keys, &count))
|
||||
fail("unable to enumerate keys\n");
|
||||
if (count)
|
||||
break;
|
||||
if (logged_in || !tok->loginRequired)
|
||||
break;
|
||||
/* if (pin == NULL) {
|
||||
pin = (char *) malloc(12);
|
||||
get_pin(ui_method, pin, 12);
|
||||
}
|
||||
*/
|
||||
if (!passphrase || PKCS11_login(slot, 0, passphrase)) {
|
||||
/* if(pin != NULL) {
|
||||
free(pin);
|
||||
pin = NULL;
|
||||
}*/
|
||||
passphrase=NULL;
|
||||
fail("Card login failed\n");
|
||||
}
|
||||
logged_in++;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
fprintf(stderr,"No keys found.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(verbose) {
|
||||
fprintf(stderr,"Found %u key%s:\n", count, (count <= 1) ? "" : "s");
|
||||
}
|
||||
for (n = 0; n < count; n++) {
|
||||
PKCS11_KEY *k = keys + n;
|
||||
|
||||
if(verbose) {
|
||||
fprintf(stderr," %2u %c%c %s\n", n + 1,
|
||||
k->isPrivate ? 'P' : ' ', k->needLogin ? 'L' : ' ', k->label);
|
||||
}
|
||||
if(verbose) {
|
||||
fprintf(stderr," ID = %s\n", k->id);
|
||||
}
|
||||
if (key_id_len != 0 && k->id_len == key_id_len &&
|
||||
memcmp(k->id, s_key_id, key_id_len) == 0) {
|
||||
selected_key = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected_key == NULL) {
|
||||
if (s_key_id != NULL) {
|
||||
fprintf(stderr,"No key with ID \"%s\" found.\n", s_key_id);
|
||||
return 0;
|
||||
} else /* Take the first key that was found */
|
||||
selected_key = &keys[0];
|
||||
}
|
||||
|
||||
*key=selected_key;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type)
|
||||
|
@ -422,3 +649,79 @@ pkcs11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label,
|
|||
/* Gobble the key object */
|
||||
return pkcs11_init_key(ctx, token, session, object, CKO_PUBLIC_KEY, ret_key);
|
||||
}
|
||||
int PKCS11_get_key_modulus(PKCS11_KEY * key, BIGNUM **bn)
|
||||
{
|
||||
|
||||
if (pkcs11_getattr_bn(KEY2TOKEN(key), PRIVKEY(key)->object, CKA_MODULUS, bn))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
int PKCS11_get_key_exponent(PKCS11_KEY * key, BIGNUM **bn)
|
||||
{
|
||||
|
||||
if (pkcs11_getattr_bn(KEY2TOKEN(key), PRIVKEY(key)->object, CKA_PUBLIC_EXPONENT, bn))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int PKCS11_get_key_size(PKCS11_KEY * key)
|
||||
{
|
||||
BIGNUM* n;
|
||||
int numbytes=0;
|
||||
n=BN_new();
|
||||
if(key_getattr_bn(key, CKA_MODULUS, &n))
|
||||
return 0;
|
||||
numbytes=BN_num_bytes(n);
|
||||
BN_free(n);
|
||||
return numbytes;
|
||||
}
|
||||
|
||||
|
||||
static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen)
|
||||
{
|
||||
size_t left, count = 0;
|
||||
|
||||
if (in == NULL || *in == '\0') {
|
||||
*outlen = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
left = *outlen;
|
||||
|
||||
while (*in != '\0') {
|
||||
int byte = 0, nybbles = 2;
|
||||
char c;
|
||||
|
||||
while (nybbles-- && *in && *in != ':') {
|
||||
byte <<= 4;
|
||||
c = *in++;
|
||||
if ('0' <= c && c <= '9')
|
||||
c -= '0';
|
||||
else if ('a' <= c && c <= 'f')
|
||||
c = c - 'a' + 10;
|
||||
else if ('A' <= c && c <= 'F')
|
||||
c = c - 'A' + 10;
|
||||
else {
|
||||
fprintf(stderr,"hex_to_bin(): invalid char '%c' in hex string\n", c);
|
||||
*outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
byte |= c;
|
||||
}
|
||||
if (*in == ':')
|
||||
in++;
|
||||
if (left <= 0) {
|
||||
fprintf(stderr,"hex_to_bin(): hex string too long");
|
||||
*outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
out[count++] = (unsigned char) byte;
|
||||
left--;
|
||||
c++;
|
||||
}
|
||||
|
||||
*outlen = count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <string.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
static void *handle = NULL;
|
||||
|
||||
|
|
|
@ -55,9 +55,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
void *pkcs11_malloc(size_t size)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
/* p11_ops.c */
|
||||
/* Written by Olaf Kirch <okir@lst.de>
|
||||
* Edited by Kevin Stefanik <kstef@mtppi.org>
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* this file does certain cryptographic operations via the pkcs11 library */
|
||||
|
||||
#include <string.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
|
||||
int
|
||||
pkcs11_sign(int type, const unsigned char *m, unsigned int m_len,
|
||||
unsigned char *sigret, unsigned int *siglen, const PKCS11_KEY * key)
|
||||
{
|
||||
|
||||
PKCS11_KEY_private *priv;
|
||||
PKCS11_SLOT *slot;
|
||||
PKCS11_CTX *ctx;
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_MECHANISM mechanism;
|
||||
int rv, ssl = ((type == NID_md5_sha1) ? 1 : 0);
|
||||
unsigned char *encoded = NULL;
|
||||
int sigsize;
|
||||
CK_ULONG ck_sigsize;
|
||||
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
ctx = KEY2CTX(key);
|
||||
priv = PRIVKEY(key);
|
||||
slot = TOKEN2SLOT(priv->parent);
|
||||
session = PRIVSLOT(slot)->session;
|
||||
|
||||
sigsize=PKCS11_get_key_size(key);
|
||||
ck_sigsize=sigsize;
|
||||
|
||||
if (ssl) {
|
||||
if((m_len != 36) /* SHA1 + MD5 */ ||
|
||||
((m_len + RSA_PKCS1_PADDING) > sigsize)) {
|
||||
return(0); /* the size is wrong */
|
||||
}
|
||||
} else {
|
||||
ASN1_TYPE parameter = { V_ASN1_NULL, { NULL } };
|
||||
ASN1_STRING digest = { m_len, V_ASN1_OCTET_STRING, (unsigned char *)m };
|
||||
X509_ALGOR algor = { NULL, ¶meter };
|
||||
X509_SIG digest_info = { &algor, &digest };
|
||||
int size;
|
||||
/* Fetch the OID of the algorithm used */
|
||||
if((algor.algorithm = OBJ_nid2obj(type)) &&
|
||||
(algor.algorithm->length) &&
|
||||
/* Get the size of the encoded DigestInfo */
|
||||
(size = i2d_X509_SIG(&digest_info, NULL)) &&
|
||||
/* Check that size is compatible with PKCS#11 padding */
|
||||
(size + RSA_PKCS1_PADDING <= sigsize) &&
|
||||
(encoded = (unsigned char *) malloc(sigsize))) {
|
||||
unsigned char *tmp = encoded;
|
||||
/* Actually do the encoding */
|
||||
i2d_X509_SIG(&digest_info,&tmp);
|
||||
m = encoded;
|
||||
m_len = size;
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&mechanism, 0, sizeof(mechanism));
|
||||
mechanism.mechanism = CKM_RSA_PKCS;
|
||||
|
||||
/* API is somewhat fishy here. *siglen is 0 on entry (cleared
|
||||
* by OpenSSL). The library assumes that the memory passed
|
||||
* by the caller is always big enough */
|
||||
if((rv = CRYPTOKI_call(ctx, C_SignInit
|
||||
(session, &mechanism, priv->object))) == 0) {
|
||||
rv = CRYPTOKI_call(ctx, C_Sign
|
||||
(session, (CK_BYTE *) m, m_len,
|
||||
sigret, &ck_sigsize));
|
||||
}
|
||||
*siglen = ck_sigsize;
|
||||
free(encoded);
|
||||
|
||||
if (rv) {
|
||||
PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
|
||||
}
|
||||
return (rv) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pkcs11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
|
||||
const PKCS11_KEY * rsa, int padding)
|
||||
{
|
||||
/* PKCS11 calls go here */
|
||||
PKCS11err(PKCS11_F_PKCS11_RSA_ENCRYPT, PKCS11_NOT_SUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
pkcs11_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
|
||||
PKCS11_KEY * key, int padding)
|
||||
{
|
||||
CK_RV rv;
|
||||
PKCS11_KEY_private *priv;
|
||||
PKCS11_SLOT *slot;
|
||||
PKCS11_CTX *ctx;
|
||||
CK_SESSION_HANDLE session;
|
||||
CK_MECHANISM mechanism;
|
||||
CK_ULONG size;
|
||||
|
||||
if (padding != RSA_PKCS1_PADDING) {
|
||||
printf("pkcs11 engine: only RSA_PKCS1_PADDING allowed so far\n");
|
||||
return -1;
|
||||
}
|
||||
if (key == NULL)
|
||||
return -1;
|
||||
|
||||
/* PKCS11 calls go here */
|
||||
|
||||
ctx = KEY2CTX(key);
|
||||
priv = PRIVKEY(key);
|
||||
slot = TOKEN2SLOT(priv->parent);
|
||||
session = PRIVSLOT(slot)->session;
|
||||
memset(&mechanism, 0, sizeof(mechanism));
|
||||
mechanism.mechanism = CKM_RSA_PKCS;
|
||||
|
||||
if( (rv = CRYPTOKI_call(ctx, C_DecryptInit(session, &mechanism, priv->object))) == 0) {
|
||||
rv = CRYPTOKI_call(ctx, C_Decrypt
|
||||
(session, (CK_BYTE *) from, (CK_ULONG)flen,
|
||||
(CK_BYTE_PTR)to, &size));
|
||||
}
|
||||
|
||||
if (rv) {
|
||||
PKCS11err(PKCS11_F_PKCS11_RSA_DECRYPT, pkcs11_map_err(rv));
|
||||
}
|
||||
|
||||
return (rv) ? 0 : size;
|
||||
}
|
||||
|
||||
int
|
||||
pkcs11_verify(int type, const unsigned char *m, unsigned int m_len,
|
||||
unsigned char *signature, unsigned int siglen, PKCS11_KEY * key)
|
||||
{
|
||||
|
||||
/* PKCS11 calls go here */
|
||||
PKCS11err(PKCS11_F_PKCS11_RSA_VERIFY, PKCS11_NOT_SUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -60,10 +60,10 @@
|
|||
* PKCS11 token
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
static int pkcs11_get_rsa_public(PKCS11_KEY *, EVP_PKEY *);
|
||||
static int pkcs11_get_rsa_private(PKCS11_KEY *, EVP_PKEY *);
|
||||
|
|
|
@ -55,9 +55,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <libp11.h>
|
||||
#include <string.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include "libp11-int.h"
|
||||
|
||||
static int pkcs11_init_slot(PKCS11_CTX *, PKCS11_SLOT *, CK_SLOT_ID);
|
||||
static int pkcs11_check_token(PKCS11_CTX *, PKCS11_SLOT *);
|
||||
|
|
Loading…
Reference in New Issue