Indent sources
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1426 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
a02ef5e722
commit
bbc64d01ff
|
@ -36,14 +36,15 @@
|
||||||
#include "engine_opensc.h"
|
#include "engine_opensc.h"
|
||||||
|
|
||||||
/* static state info one card/reader at a time */
|
/* static state info one card/reader at a time */
|
||||||
static int quiet=1;
|
static int quiet = 1;
|
||||||
static int sc_reader_id= 0;
|
static int sc_reader_id = 0;
|
||||||
static sc_context_t *ctx = NULL;
|
static sc_context_t *ctx = NULL;
|
||||||
static sc_card_t *card = NULL;
|
static sc_card_t *card = NULL;
|
||||||
static sc_pkcs15_card_t *p15card = NULL;
|
static sc_pkcs15_card_t *p15card = NULL;
|
||||||
static char* sc_pin=NULL;
|
static char *sc_pin = NULL;
|
||||||
|
|
||||||
int opensc_finish(void) {
|
int opensc_finish(void)
|
||||||
|
{
|
||||||
if (p15card) {
|
if (p15card) {
|
||||||
sc_pkcs15_unbind(p15card);
|
sc_pkcs15_unbind(p15card);
|
||||||
p15card = NULL;
|
p15card = NULL;
|
||||||
|
@ -59,11 +60,12 @@ int opensc_finish(void) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int opensc_init(void) {
|
int opensc_init(void)
|
||||||
int r=0;
|
{
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
if(!quiet)
|
if (!quiet)
|
||||||
fprintf(stderr,"initializing engine");
|
fprintf(stderr, "initializing engine");
|
||||||
|
|
||||||
r = sc_establish_context(&ctx, "openssl");
|
r = sc_establish_context(&ctx, "openssl");
|
||||||
if (r)
|
if (r)
|
||||||
|
@ -76,48 +78,53 @@ int opensc_init(void) {
|
||||||
if (r)
|
if (r)
|
||||||
goto err;
|
goto err;
|
||||||
return 1;
|
return 1;
|
||||||
err:
|
err:
|
||||||
/* need to do engine stuff? */
|
/* need to do engine stuff? */
|
||||||
fprintf(stderr, "error: %d",r);
|
fprintf(stderr, "error: %d", r);
|
||||||
opensc_finish();
|
opensc_finish();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int opensc_rsa_finish(RSA * rsa)
|
||||||
opensc_rsa_finish(RSA* rsa) {
|
{
|
||||||
struct sc_pkcs15_key_id *key_id;
|
struct sc_pkcs15_key_id *key_id;
|
||||||
|
|
||||||
key_id = (struct sc_pkcs15_key_id *) RSA_get_app_data(rsa);
|
key_id = (struct sc_pkcs15_key_id *) RSA_get_app_data(rsa);
|
||||||
free(key_id);
|
free(key_id);
|
||||||
if(sc_pin) {free(sc_pin);}
|
if (sc_pin) {
|
||||||
|
free(sc_pin);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BIGNUM *sc_bignum_t_to_BIGNUM(sc_pkcs15_bignum_t* bignum, BIGNUM* BN) {
|
BIGNUM *sc_bignum_t_to_BIGNUM(sc_pkcs15_bignum_t * bignum, BIGNUM * BN)
|
||||||
BN_bin2bn( (unsigned char *) bignum->data, bignum->len, BN);
|
{
|
||||||
|
BN_bin2bn((unsigned char *) bignum->data, bignum->len, BN);
|
||||||
return BN;
|
return BN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc_set_pubkey_data(EVP_PKEY* key_out, sc_pkcs15_pubkey_t* pubkey) {
|
void sc_set_pubkey_data(EVP_PKEY * key_out, sc_pkcs15_pubkey_t * pubkey)
|
||||||
key_out->pkey.rsa->n=sc_bignum_t_to_BIGNUM(&(pubkey->u.rsa.modulus),BN_new());
|
{
|
||||||
key_out->pkey.rsa->e=sc_bignum_t_to_BIGNUM(&(pubkey->u.rsa.exponent),BN_new());
|
key_out->pkey.rsa->n =
|
||||||
|
sc_bignum_t_to_BIGNUM(&(pubkey->u.rsa.modulus), BN_new());
|
||||||
|
key_out->pkey.rsa->e =
|
||||||
|
sc_bignum_t_to_BIGNUM(&(pubkey->u.rsa.exponent), BN_new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* private key operations */
|
/* private key operations */
|
||||||
|
|
||||||
int
|
int sc_prkey_op_init(const RSA * rsa, struct sc_pkcs15_object **key_obj_out)
|
||||||
sc_prkey_op_init(const RSA *rsa, struct sc_pkcs15_object **key_obj_out)
|
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct sc_pkcs15_object *key_obj;
|
struct sc_pkcs15_object *key_obj;
|
||||||
struct sc_pkcs15_prkey_info *key;
|
struct sc_pkcs15_prkey_info *key;
|
||||||
struct sc_pkcs15_id* key_id;
|
struct sc_pkcs15_id *key_id;
|
||||||
struct sc_pkcs15_object *pin_obj;
|
struct sc_pkcs15_object *pin_obj;
|
||||||
struct sc_pkcs15_pin_info *pin;
|
struct sc_pkcs15_pin_info *pin;
|
||||||
|
|
||||||
key_id = (struct sc_pkcs15_id *) RSA_get_app_data(rsa);
|
key_id = (struct sc_pkcs15_id *) RSA_get_app_data(rsa);
|
||||||
if(key_id==NULL) {
|
if (key_id == NULL) {
|
||||||
fprintf(stderr,"key not loaded yet");
|
fprintf(stderr, "key not loaded yet");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,29 +132,28 @@ sc_prkey_op_init(const RSA *rsa, struct sc_pkcs15_object **key_obj_out)
|
||||||
opensc_finish();
|
opensc_finish();
|
||||||
r = opensc_init();
|
r = opensc_init();
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(stderr,"SmartCard init failed: %s", sc_strerror(r));
|
fprintf(stderr, "SmartCard init failed: %s", sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r = sc_pkcs15_find_prkey_by_id(p15card, key_id , &key_obj);
|
r = sc_pkcs15_find_prkey_by_id(p15card, key_id, &key_obj);
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(stderr,"Unable to find private key from SmartCard: %s",
|
fprintf(stderr, "Unable to find private key from SmartCard: %s",
|
||||||
sc_strerror(r));
|
sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
key = (struct sc_pkcs15_prkey_info *) key_obj->data;
|
key = (struct sc_pkcs15_prkey_info *) key_obj->data;
|
||||||
r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
|
r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, &pin_obj);
|
||||||
&pin_obj);
|
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(stderr,"Unable to find PIN object from SmartCard: %s",
|
fprintf(stderr, "Unable to find PIN object from SmartCard: %s",
|
||||||
sc_strerror(r));
|
sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
pin = (struct sc_pkcs15_pin_info *) pin_obj->data;
|
pin = (struct sc_pkcs15_pin_info *) pin_obj->data;
|
||||||
|
|
||||||
r = sc_lock(card);
|
r = sc_lock(card);
|
||||||
if (r) {
|
if (r) {
|
||||||
fprintf(stderr,"Unable to lock smartcard: %s", sc_strerror(r));
|
fprintf(stderr, "Unable to lock smartcard: %s", sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (sc_pin != NULL) {
|
if (sc_pin != NULL) {
|
||||||
|
@ -155,32 +161,32 @@ sc_prkey_op_init(const RSA *rsa, struct sc_pkcs15_object **key_obj_out)
|
||||||
strlen(sc_pin));
|
strlen(sc_pin));
|
||||||
if (r) {
|
if (r) {
|
||||||
sc_unlock(card);
|
sc_unlock(card);
|
||||||
fprintf(stderr,"PIN code verification failed: %s",
|
fprintf(stderr, "PIN code verification failed: %s",
|
||||||
sc_strerror(r));
|
sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"Warning: PIN not verified");
|
fprintf(stderr, "Warning: PIN not verified");
|
||||||
}
|
}
|
||||||
*key_obj_out = key_obj;
|
*key_obj_out = key_obj;
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY *opensc_load_public_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *opensc_load_public_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data) {
|
UI_METHOD * ui_method, void *callback_data)
|
||||||
|
{
|
||||||
int r;
|
int r;
|
||||||
struct sc_pkcs15_id* id;
|
struct sc_pkcs15_id *id;
|
||||||
struct sc_pkcs15_object *obj;
|
struct sc_pkcs15_object *obj;
|
||||||
sc_pkcs15_pubkey_t *pubkey = NULL;
|
sc_pkcs15_pubkey_t *pubkey = NULL;
|
||||||
sc_pkcs15_cert_t *cert = NULL;
|
sc_pkcs15_cert_t *cert = NULL;
|
||||||
EVP_PKEY* key_out=NULL;
|
EVP_PKEY *key_out = NULL;
|
||||||
|
|
||||||
if(!quiet)
|
if (!quiet)
|
||||||
fprintf(stderr,"Loading public key!\n");
|
fprintf(stderr, "Loading public key!\n");
|
||||||
id = (struct sc_pkcs15_id *) malloc(sizeof(struct sc_pkcs15_id));
|
id = (struct sc_pkcs15_id *) malloc(sizeof(struct sc_pkcs15_id));
|
||||||
id->len = SC_PKCS15_MAX_ID_SIZE;
|
id->len = SC_PKCS15_MAX_ID_SIZE;
|
||||||
sc_pkcs15_hex_string_to_id(s_key_id, id);
|
sc_pkcs15_hex_string_to_id(s_key_id, id);
|
||||||
|
|
||||||
|
@ -194,10 +200,11 @@ EVP_PKEY *opensc_load_public_key(ENGINE *e, const char *s_key_id,
|
||||||
r = sc_pkcs15_find_cert_by_id(p15card, id, &obj);
|
r = sc_pkcs15_find_cert_by_id(p15card, id, &obj);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
printf("Reading certificate with ID '%s'\n", s_key_id);
|
printf("Reading certificate with ID '%s'\n",
|
||||||
|
s_key_id);
|
||||||
r = sc_pkcs15_read_certificate(p15card,
|
r = sc_pkcs15_read_certificate(p15card,
|
||||||
(sc_pkcs15_cert_info_t *) obj->data,
|
(sc_pkcs15_cert_info_t *)
|
||||||
&cert);
|
obj->data, &cert);
|
||||||
}
|
}
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
pubkey = &cert->key;
|
pubkey = &cert->key;
|
||||||
|
@ -208,19 +215,22 @@ EVP_PKEY *opensc_load_public_key(ENGINE *e, const char *s_key_id,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
|
fprintf(stderr, "Public key enumeration failed: %s\n",
|
||||||
|
sc_strerror(r));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now, set EVP_PKEY data from pubkey object */
|
/* now, set EVP_PKEY data from pubkey object */
|
||||||
key_out=EVP_PKEY_new();
|
key_out = EVP_PKEY_new();
|
||||||
if(!key_out)
|
if (!key_out) {
|
||||||
{fprintf(stderr, "failed to create new EVP_PKEY\n"); return NULL;};
|
fprintf(stderr, "failed to create new EVP_PKEY\n");
|
||||||
EVP_PKEY_assign_RSA(key_out,RSA_new_method(e));
|
return NULL;
|
||||||
|
};
|
||||||
|
EVP_PKEY_assign_RSA(key_out, RSA_new_method(e));
|
||||||
#if 0
|
#if 0
|
||||||
RSA_set_method(keyout->rsa, sc_get_rsa_method());
|
RSA_set_method(keyout->rsa, sc_get_rsa_method());
|
||||||
#endif
|
#endif
|
||||||
key_out->pkey.rsa->flags|=RSA_FLAG_EXT_PKEY||RSA_FLAG_SIGN_VER;
|
key_out->pkey.rsa->flags |= RSA_FLAG_EXT_PKEY || RSA_FLAG_SIGN_VER;
|
||||||
RSA_set_app_data(key_out->pkey.rsa, id);
|
RSA_set_app_data(key_out->pkey.rsa, id);
|
||||||
sc_set_pubkey_data(key_out, pubkey);
|
sc_set_pubkey_data(key_out, pubkey);
|
||||||
|
|
||||||
|
@ -231,40 +241,49 @@ EVP_PKEY *opensc_load_public_key(ENGINE *e, const char *s_key_id,
|
||||||
return key_out;
|
return key_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_pin(UI_METHOD* ui_method, char* sc_pin, int maxlen) {
|
char *get_pin(UI_METHOD * ui_method, char *sc_pin, int maxlen)
|
||||||
UI* ui;
|
{
|
||||||
ui=UI_new();
|
UI *ui;
|
||||||
UI_set_method(ui,ui_method);
|
|
||||||
if(!UI_add_input_string(ui, "SmartCard Password: ", 0, sc_pin, 1, maxlen)) {
|
ui = UI_new();
|
||||||
fprintf(stderr, "UI_add_input_string failed");
|
UI_set_method(ui, ui_method);
|
||||||
UI_free(ui); return NULL; }
|
if (!UI_add_input_string(ui, "SmartCard Password: ", 0, sc_pin, 1, maxlen)) {
|
||||||
if(!UI_process(ui)) {
|
fprintf(stderr, "UI_add_input_string failed");
|
||||||
fprintf(stderr, "UI_process failed"); return NULL;}
|
UI_free(ui);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!UI_process(ui)) {
|
||||||
|
fprintf(stderr, "UI_process failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
UI_free(ui);
|
UI_free(ui);
|
||||||
return sc_pin;
|
return sc_pin;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY *opensc_load_private_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *opensc_load_private_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data) {
|
UI_METHOD * ui_method, void *callback_data)
|
||||||
EVP_PKEY* key_out;
|
{
|
||||||
if(!quiet)
|
EVP_PKEY *key_out;
|
||||||
fprintf(stderr,"Loading private key!");
|
|
||||||
|
|
||||||
if(sc_pin) {free(sc_pin); sc_pin=NULL;}
|
if (!quiet)
|
||||||
key_out=opensc_load_public_key(e, s_key_id, ui_method, callback_data);
|
fprintf(stderr, "Loading private key!");
|
||||||
sc_pin=(char *) malloc(12);
|
if (sc_pin) {
|
||||||
get_pin(ui_method,sc_pin,12); /* do this here, when storing sc_pin in RSA */
|
free(sc_pin);
|
||||||
if(!key_out) {
|
sc_pin = NULL;
|
||||||
fprintf(stderr,"Failed to get private key");
|
}
|
||||||
return NULL;
|
key_out = opensc_load_public_key(e, s_key_id, ui_method, callback_data);
|
||||||
|
sc_pin = (char *) malloc(12);
|
||||||
|
get_pin(ui_method, sc_pin, 12); /* do this here, when storing sc_pin in RSA */
|
||||||
|
if (!key_out) {
|
||||||
|
fprintf(stderr, "Failed to get private key");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return key_out;
|
return key_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sc_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
|
sc_private_decrypt(int flen, const u_char * from, u_char * to, RSA * rsa,
|
||||||
int padding)
|
int padding)
|
||||||
{
|
{
|
||||||
struct sc_pkcs15_object *key_obj;
|
struct sc_pkcs15_object *key_obj;
|
||||||
int r;
|
int r;
|
||||||
|
@ -277,50 +296,52 @@ sc_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
|
||||||
r = sc_pkcs15_decipher(p15card, key_obj, 0, from, flen, to, flen);
|
r = sc_pkcs15_decipher(p15card, key_obj, 0, from, flen, to, flen);
|
||||||
sc_unlock(card);
|
sc_unlock(card);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fprintf(stderr,"sc_pkcs15_decipher() failed: %s", sc_strerror(r));
|
fprintf(stderr, "sc_pkcs15_decipher() failed: %s", sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
err:
|
err:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sc_sign(int type, const u_char *m, unsigned int m_len,
|
sc_sign(int type, const u_char * m, unsigned int m_len,
|
||||||
unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
|
unsigned char *sigret, unsigned int *siglen, const RSA * rsa)
|
||||||
{
|
{
|
||||||
struct sc_pkcs15_object *key_obj;
|
struct sc_pkcs15_object *key_obj;
|
||||||
int r;
|
int r;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
|
|
||||||
if(!quiet)
|
if (!quiet)
|
||||||
fprintf(stderr,"signing with type %d\n", type);
|
fprintf(stderr, "signing with type %d\n", type);
|
||||||
r = sc_prkey_op_init(rsa, &key_obj);
|
r = sc_prkey_op_init(rsa, &key_obj);
|
||||||
if (r)
|
if (r)
|
||||||
return -1;
|
return -1;
|
||||||
/* FIXME: length of sigret correct? */
|
/* FIXME: length of sigret correct? */
|
||||||
/* FIXME: check 'type' and modify flags accordingly */
|
/* FIXME: check 'type' and modify flags accordingly */
|
||||||
flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||||
if(type==NID_sha1) flags|=SC_ALGORITHM_RSA_HASH_SHA1;
|
if (type == NID_sha1)
|
||||||
if(type==NID_md5) flags|=SC_ALGORITHM_RSA_HASH_MD5;
|
flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
||||||
|
if (type == NID_md5)
|
||||||
|
flags |= SC_ALGORITHM_RSA_HASH_MD5;
|
||||||
r = sc_pkcs15_compute_signature(p15card, key_obj, flags,
|
r = sc_pkcs15_compute_signature(p15card, key_obj, flags,
|
||||||
m, m_len, sigret, RSA_size(rsa));
|
m, m_len, sigret, RSA_size(rsa));
|
||||||
sc_unlock(card);
|
sc_unlock(card);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
fprintf(stderr,"sc_pkcs15_compute_signature() failed: %s",
|
fprintf(stderr, "sc_pkcs15_compute_signature() failed: %s",
|
||||||
sc_strerror(r));
|
sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
*siglen = r;
|
*siglen = r;
|
||||||
return 1;
|
return 1;
|
||||||
err:
|
err:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sc_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
|
sc_private_encrypt(int flen, const u_char * from, u_char * to, RSA * rsa,
|
||||||
int padding)
|
int padding)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Private key encryption not supported");
|
fprintf(stderr, "Private key encryption not supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
int opensc_finish(void);
|
int opensc_finish(void);
|
||||||
int opensc_init(void);
|
int opensc_init(void);
|
||||||
|
|
||||||
EVP_PKEY *opensc_load_public_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *opensc_load_public_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data);
|
UI_METHOD * ui_method, void *callback_data);
|
||||||
EVP_PKEY *opensc_load_private_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *opensc_load_private_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data);
|
UI_METHOD * ui_method, void *callback_data);
|
||||||
int sc_private_decrypt(int flen, const u_char *from, u_char *to,
|
int sc_private_decrypt(int flen, const u_char * from, u_char * to,
|
||||||
RSA *rsa, int padding);
|
RSA * rsa, int padding);
|
||||||
int sc_sign(int type, const u_char *m, unsigned int m_len,
|
int sc_sign(int type, const u_char * m, unsigned int m_len,
|
||||||
unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
|
unsigned char *sigret, unsigned int *siglen, const RSA * rsa);
|
||||||
int sc_private_encrypt(int flen, const u_char *from, u_char *to,
|
int sc_private_encrypt(int flen, const u_char * from, u_char * to,
|
||||||
RSA *rsa, int padding);
|
RSA * rsa, int padding);
|
||||||
int opensc_rsa_finish(RSA* rsa);
|
int opensc_rsa_finish(RSA * rsa);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,63 +34,68 @@
|
||||||
|
|
||||||
#define fail(msg) { fprintf(stderr,msg); return NULL;}
|
#define fail(msg) { fprintf(stderr,msg); return NULL;}
|
||||||
|
|
||||||
PKCS11_CTX *ctx;
|
PKCS11_CTX *ctx;
|
||||||
char* pin;
|
char *pin = NULL;
|
||||||
int quiet=1;
|
int quiet = 1;
|
||||||
|
|
||||||
const char *module = PKCS11_DEFAULT_MODULE_NAME;
|
const char *module = PKCS11_DEFAULT_MODULE_NAME;
|
||||||
|
|
||||||
int set_module(const char *modulename) {
|
int set_module(const char *modulename)
|
||||||
module=modulename;
|
{
|
||||||
|
module = modulename;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* get_pin(UI_METHOD* ui_method, char* sc_pin, int maxlen) {
|
char *get_pin(UI_METHOD * ui_method, char *sc_pin, int maxlen)
|
||||||
UI* ui;
|
{
|
||||||
ui=UI_new();
|
UI *ui;
|
||||||
UI_set_method(ui,ui_method);
|
|
||||||
if(!UI_add_input_string(ui, "SmartCard PIN: ", 0, sc_pin, 1, maxlen)) {
|
ui = UI_new();
|
||||||
fprintf(stderr, "UI_add_input_string failed\n");
|
UI_set_method(ui, ui_method);
|
||||||
UI_free(ui); return NULL; }
|
if (!UI_add_input_string(ui, "SmartCard PIN: ", 0, sc_pin, 1, maxlen)) {
|
||||||
if(!UI_process(ui)) {
|
fprintf(stderr, "UI_add_input_string failed\n");
|
||||||
fprintf(stderr, "UI_process failed\n"); return NULL;}
|
UI_free(ui);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!UI_process(ui)) {
|
||||||
|
fprintf(stderr, "UI_process failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
UI_free(ui);
|
UI_free(ui);
|
||||||
return sc_pin;
|
return sc_pin;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pkcs11_finish(ENGINE *engine) {
|
int pkcs11_finish(ENGINE * engine)
|
||||||
|
{
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
PKCS11_CTX_free(ctx);
|
PKCS11_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pkcs11_init(ENGINE *engine) {
|
int pkcs11_init(ENGINE * engine)
|
||||||
if(!quiet)
|
{
|
||||||
fprintf(stderr,"initializing engine\n");
|
if (!quiet)
|
||||||
|
fprintf(stderr, "initializing engine\n");
|
||||||
|
|
||||||
ctx = PKCS11_CTX_new();
|
ctx = PKCS11_CTX_new();
|
||||||
if (PKCS11_CTX_load(ctx, module) < 0) {
|
if (PKCS11_CTX_load(ctx, module) < 0) {
|
||||||
fprintf(stderr, "unable to load module\n");
|
fprintf(stderr, "unable to load module\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int pkcs11_rsa_finish(RSA * rsa)
|
||||||
pkcs11_rsa_finish(RSA* rsa) {
|
{
|
||||||
|
if (pin) {
|
||||||
if(pin) {free(pin);}
|
free(pin);
|
||||||
|
}
|
||||||
/* need to free RSA_ex_data? */
|
/* need to free RSA_ex_data? */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen)
|
static int hex_to_bin(const char *in, unsigned char *out, size_t * outlen)
|
||||||
{
|
{
|
||||||
size_t left, count = 0;
|
size_t left, count = 0;
|
||||||
|
|
||||||
|
@ -99,7 +104,7 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
left = *outlen;
|
left = *outlen;
|
||||||
|
|
||||||
while (*in != '\0') {
|
while (*in != '\0') {
|
||||||
int byte = 0, nybbles = 2;
|
int byte = 0, nybbles = 2;
|
||||||
|
@ -110,11 +115,9 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen)
|
||||||
c = *in++;
|
c = *in++;
|
||||||
if ('0' <= c && c <= '9')
|
if ('0' <= c && c <= '9')
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else
|
else if ('a' <= c && c <= 'f')
|
||||||
if ('a' <= c && c <= 'f')
|
|
||||||
c = c - 'a' + 10;
|
c = c - 'a' + 10;
|
||||||
else
|
else if ('A' <= c && c <= 'F')
|
||||||
if ('A' <= c && c <= 'F')
|
|
||||||
c = c - 'A' + 10;
|
c = c - 'A' + 10;
|
||||||
else {
|
else {
|
||||||
printf("hex_to_bin(): invalid char '%c' in hex string\n", c);
|
printf("hex_to_bin(): invalid char '%c' in hex string\n", c);
|
||||||
|
@ -141,21 +144,21 @@ static int hex_to_bin(const char *in, unsigned char *out, size_t *outlen)
|
||||||
|
|
||||||
#define MAX_VALUE_LEN 200
|
#define MAX_VALUE_LEN 200
|
||||||
|
|
||||||
EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
EVP_PKEY *pkcs11_load_key(ENGINE * e, const char *s_slot_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data, int isPrivate) {
|
UI_METHOD * ui_method, void *callback_data, int isPrivate)
|
||||||
|
{
|
||||||
PKCS11_SLOT *slot_list, *slot;
|
PKCS11_SLOT *slot_list, *slot;
|
||||||
PKCS11_TOKEN *tok;
|
PKCS11_TOKEN *tok;
|
||||||
PKCS11_KEY *keys, *selected_key = NULL;
|
PKCS11_KEY *keys, *selected_key = NULL;
|
||||||
PKCS11_CERT *certs;
|
PKCS11_CERT *certs;
|
||||||
EVP_PKEY *pk;
|
EVP_PKEY *pk;
|
||||||
unsigned int count, n, m;
|
unsigned int count, n, m;
|
||||||
unsigned char key_id[MAX_VALUE_LEN / 2];
|
unsigned char key_id[MAX_VALUE_LEN / 2];
|
||||||
char *s_key_id = NULL, buf[MAX_VALUE_LEN];
|
char *s_key_id = NULL, buf[MAX_VALUE_LEN];
|
||||||
size_t key_id_len = sizeof(key_id);
|
size_t key_id_len = sizeof(key_id);
|
||||||
int slot_nr = -1;
|
int slot_nr = -1;
|
||||||
char flags[64];
|
char flags[64];
|
||||||
int logged_in = 0;
|
int logged_in = 0;
|
||||||
|
|
||||||
/* Parse s_slot_key_id: [slot:<slotNr>][;][id:<keyID>] or NULL,
|
/* Parse s_slot_key_id: [slot:<slotNr>][;][id:<keyID>] or NULL,
|
||||||
with slotNr in decimal (0 = first slot, ...), and keyID in hex.
|
with slotNr in decimal (0 = first slot, ...), and keyID in hex.
|
||||||
|
@ -194,29 +197,27 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
printf("Slot number \"%s\" should be an integer\n", val);
|
printf("Slot number \"%s\" should be an integer\n", val);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
} else if (strncasecmp(s_slot_key_id, "id", p_sep1 - s_slot_key_id)
|
||||||
else if (strncasecmp(s_slot_key_id, "id", p_sep1 - s_slot_key_id) == 0) {
|
== 0) {
|
||||||
if (!hex_to_bin(val, key_id, &key_id_len)) {
|
if (!hex_to_bin(val, key_id, &key_id_len)) {
|
||||||
printf("Key id \"%s\" should be a hex string\n", val);
|
printf("Key id \"%s\" should be a hex string\n", val);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(buf, val);
|
strcpy(buf, val);
|
||||||
s_key_id = buf;
|
s_key_id = buf;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
memcpy(val, s_slot_key_id, p_sep1 - s_slot_key_id);
|
memcpy(val, s_slot_key_id, p_sep1 - s_slot_key_id);
|
||||||
val[p_sep1 - s_slot_key_id] = '\0';
|
val[p_sep1 - s_slot_key_id] = '\0';
|
||||||
printf("Now allowed in -key: \"%s\"\n", val);
|
printf("Now allowed in -key: \"%s\"\n", val);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_slot_key_id = (*p_sep2 == '\0' ? p_sep2 : p_sep2 + 1);
|
s_slot_key_id = (*p_sep2 == '\0' ? p_sep2 : p_sep2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PKCS11_enumerate_slots(ctx, &slot_list, &count) < 0)
|
if (PKCS11_enumerate_slots(ctx, &slot_list, &count) < 0)
|
||||||
fail("failed to enumerate slots\n");
|
fail("failed to enumerate slots\n");
|
||||||
|
|
||||||
printf("Found %u slot%s\n", count, (count <= 1)? "" : "s");
|
printf("Found %u slot%s\n", count, (count <= 1) ? "" : "s");
|
||||||
for (n = 0; n < count; n++) {
|
for (n = 0; n < count; n++) {
|
||||||
slot = slot_list + n;
|
slot = slot_list + n;
|
||||||
flags[0] = '\0';
|
flags[0] = '\0';
|
||||||
|
@ -233,13 +234,13 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
strcpy(flags, "no token");
|
strcpy(flags, "no token");
|
||||||
}
|
}
|
||||||
if ((m = strlen(flags)) != 0) {
|
if ((m = strlen(flags)) != 0) {
|
||||||
flags[m-2] = '\0';
|
flags[m - 2] = '\0';
|
||||||
}
|
}
|
||||||
printf("[%u] %-25.25s %-16s", n, slot->description, flags);
|
printf("[%u] %-25.25s %-16s", n, slot->description, flags);
|
||||||
if (slot->token) {
|
if (slot->token) {
|
||||||
printf(" (%s)",
|
printf(" (%s)",
|
||||||
slot->token->label[0]?
|
slot->token->label[0] ?
|
||||||
slot->token->label : "no label");
|
slot->token->label : "no label");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -247,8 +248,7 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
if (slot_nr == -1) {
|
if (slot_nr == -1) {
|
||||||
if (!(slot = PKCS11_find_token(ctx)))
|
if (!(slot = PKCS11_find_token(ctx)))
|
||||||
fail("didn't find any tokens\n");
|
fail("didn't find any tokens\n");
|
||||||
}
|
} else if (slot_nr >= 0 && slot_nr < count)
|
||||||
else if (slot_nr >= 0 && slot_nr < count)
|
|
||||||
slot = slot_list + slot_nr;
|
slot = slot_list + slot_nr;
|
||||||
else {
|
else {
|
||||||
printf("Invalid slot number: %d\n", slot_nr);
|
printf("Invalid slot number: %d\n", slot_nr);
|
||||||
|
@ -261,7 +261,7 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPrivate && !tok->userPinSet && !tok->readOnly) {
|
if (isPrivate && !tok->userPinSet && !tok->readOnly) {
|
||||||
printf("Found slot without user PIN\n");
|
printf("Found slot without user PIN\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -272,13 +272,12 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
if (PKCS11_enumerate_certs(tok, &certs, &count))
|
if (PKCS11_enumerate_certs(tok, &certs, &count))
|
||||||
fail("unable to enumerate certificates\n");
|
fail("unable to enumerate certificates\n");
|
||||||
|
|
||||||
printf("Found %u certificate%s:\n", count, (count <= 1)? "" : "s");
|
printf("Found %u certificate%s:\n", count, (count <= 1) ? "" : "s");
|
||||||
for (n = 0; n < count; n++) {
|
for (n = 0; n < count; n++) {
|
||||||
PKCS11_CERT *c = certs + n;
|
PKCS11_CERT *c = certs + n;
|
||||||
char *dn = NULL;
|
char *dn = NULL;
|
||||||
|
|
||||||
printf(" %2u %s", n+1,
|
printf(" %2u %s", n + 1, c->label);
|
||||||
c->label);
|
|
||||||
if (c->x509)
|
if (c->x509)
|
||||||
dn = X509_NAME_oneline(X509_get_subject_name(c->x509), NULL, 0);
|
dn = X509_NAME_oneline(X509_get_subject_name(c->x509), NULL, 0);
|
||||||
if (dn) {
|
if (dn) {
|
||||||
|
@ -296,8 +295,8 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
if (logged_in || !tok->loginRequired)
|
if (logged_in || !tok->loginRequired)
|
||||||
break;
|
break;
|
||||||
if (pin == NULL) {
|
if (pin == NULL) {
|
||||||
pin=(char *) malloc(12);
|
pin = (char *) malloc(12);
|
||||||
get_pin(ui_method,pin,12);
|
get_pin(ui_method, pin, 12);
|
||||||
}
|
}
|
||||||
if (PKCS11_login(slot, 0, pin))
|
if (PKCS11_login(slot, 0, pin))
|
||||||
fail("Card login failed\n");
|
fail("Card login failed\n");
|
||||||
|
@ -309,14 +308,12 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Found %u key%s:\n", count, (count <= 1)? "" : "s");
|
printf("Found %u key%s:\n", count, (count <= 1) ? "" : "s");
|
||||||
for (n = 0; n < count; n++) {
|
for (n = 0; n < count; n++) {
|
||||||
PKCS11_KEY *k = keys + n;
|
PKCS11_KEY *k = keys + n;
|
||||||
|
|
||||||
printf(" %2u %c%c %s\n", n+1,
|
printf(" %2u %c%c %s\n", n + 1,
|
||||||
k->isPrivate? 'P' : ' ',
|
k->isPrivate ? 'P' : ' ', k->needLogin ? 'L' : ' ', k->label);
|
||||||
k->needLogin? 'L' : ' ',
|
|
||||||
k->label);
|
|
||||||
|
|
||||||
if (key_id_len != 0 && k->id_len == key_id_len &&
|
if (key_id_len != 0 && k->id_len == key_id_len &&
|
||||||
memcmp(k->id, key_id, key_id_len) == 0) {
|
memcmp(k->id, key_id, key_id_len) == 0) {
|
||||||
|
@ -329,36 +326,39 @@ EVP_PKEY *pkcs11_load_key(ENGINE *e, const char *s_slot_key_id,
|
||||||
if (s_key_id != NULL) {
|
if (s_key_id != NULL) {
|
||||||
printf("No key with ID \"%s\" found.\n", s_key_id);
|
printf("No key with ID \"%s\" found.\n", s_key_id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
} else /* Take the first key that was found */
|
||||||
else /* Take the first key that was found */
|
|
||||||
selected_key = &keys[0];
|
selected_key = &keys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isPrivate) {
|
if (isPrivate) {
|
||||||
pk = PKCS11_get_private_key(selected_key);
|
pk = PKCS11_get_private_key(selected_key);
|
||||||
} else {
|
} else {
|
||||||
/*pk = PKCS11_get_public_key(&keys[0]);
|
/*pk = PKCS11_get_public_key(&keys[0]);
|
||||||
need a get_public_key? */
|
need a get_public_key? */
|
||||||
pk = PKCS11_get_private_key(selected_key);
|
pk = PKCS11_get_private_key(selected_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pk;
|
return pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY *pkcs11_load_public_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *pkcs11_load_public_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data) {
|
UI_METHOD * ui_method, void *callback_data)
|
||||||
|
{
|
||||||
EVP_PKEY *pk;
|
EVP_PKEY *pk;
|
||||||
pk=pkcs11_load_key(e, s_key_id, ui_method, callback_data, 0);
|
|
||||||
|
pk = pkcs11_load_key(e, s_key_id, ui_method, callback_data, 0);
|
||||||
if (pk == NULL)
|
if (pk == NULL)
|
||||||
fail("PKCS11_load_public_key returned NULL\n");
|
fail("PKCS11_load_public_key returned NULL\n");
|
||||||
return pk;
|
return pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY *pkcs11_load_private_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *pkcs11_load_private_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data) {
|
UI_METHOD * ui_method, void *callback_data)
|
||||||
EVP_PKEY* pk;
|
{
|
||||||
pk=pkcs11_load_key(e, s_key_id, ui_method, callback_data, 1);
|
EVP_PKEY *pk;
|
||||||
if (pk == NULL)
|
|
||||||
fail("PKCS11_get_private_key returned NULL\n");
|
pk = pkcs11_load_key(e, s_key_id, ui_method, callback_data, 1);
|
||||||
return pk;
|
if (pk == NULL)
|
||||||
|
fail("PKCS11_get_private_key returned NULL\n");
|
||||||
|
return pk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,19 +35,19 @@
|
||||||
|
|
||||||
int set_module(const char *modulename);
|
int set_module(const char *modulename);
|
||||||
|
|
||||||
int pkcs11_finish(ENGINE *engine);
|
int pkcs11_finish(ENGINE * engine);
|
||||||
|
|
||||||
int pkcs11_init(ENGINE *engine);
|
int pkcs11_init(ENGINE * engine);
|
||||||
|
|
||||||
int pkcs11_rsa_finish(RSA* rsa);
|
int pkcs11_rsa_finish(RSA * rsa);
|
||||||
|
|
||||||
EVP_PKEY *pkcs11_load_public_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *pkcs11_load_public_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data);
|
UI_METHOD * ui_method, void *callback_data);
|
||||||
|
|
||||||
EVP_PKEY *pkcs11_load_private_key(ENGINE *e, const char *s_key_id,
|
EVP_PKEY *pkcs11_load_private_key(ENGINE * e, const char *s_key_id,
|
||||||
UI_METHOD *ui_method, void *callback_data);
|
UI_METHOD * ui_method, void *callback_data);
|
||||||
|
|
||||||
/* defined in p11_rsa.c */
|
/* defined in p11_rsa.c */
|
||||||
RSA_METHOD * pkcs11_get_rsa_method(void);
|
RSA_METHOD *pkcs11_get_rsa_method(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -79,10 +79,10 @@
|
||||||
|
|
||||||
#define CMD_SO_PATH ENGINE_CMD_BASE
|
#define CMD_SO_PATH ENGINE_CMD_BASE
|
||||||
|
|
||||||
static int opensc_engine_destroy(ENGINE *e);
|
static int opensc_engine_destroy(ENGINE * e);
|
||||||
static int opensc_engine_init(ENGINE *e);
|
static int opensc_engine_init(ENGINE * e);
|
||||||
static int opensc_engine_finish(ENGINE *e);
|
static int opensc_engine_finish(ENGINE * e);
|
||||||
static int opensc_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
|
static int opensc_engine_ctrl(ENGINE * e, int cmd, long i, void *p, void (*f) ());
|
||||||
|
|
||||||
/* The definitions for control commands specific to this engine */
|
/* The definitions for control commands specific to this engine */
|
||||||
|
|
||||||
|
@ -90,54 +90,52 @@ static int opensc_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
|
||||||
|
|
||||||
static const ENGINE_CMD_DEFN opensc_cmd_defns[] = {
|
static const ENGINE_CMD_DEFN opensc_cmd_defns[] = {
|
||||||
{CMD_SO_PATH,
|
{CMD_SO_PATH,
|
||||||
"SO_PATH",
|
"SO_PATH",
|
||||||
"Specifies the path to the 'opensc-engine' shared library",
|
"Specifies the path to the 'opensc-engine' shared library",
|
||||||
ENGINE_CMD_FLAG_STRING},
|
ENGINE_CMD_FLAG_STRING},
|
||||||
{0, NULL, NULL, 0}
|
{0, NULL, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int opensc_engine_finish(ENGINE *e) {
|
static int opensc_engine_finish(ENGINE * e)
|
||||||
|
{
|
||||||
return opensc_finish();
|
return opensc_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int opensc_engine_init(ENGINE * e)
|
||||||
opensc_engine_init(ENGINE *e)
|
|
||||||
{
|
{
|
||||||
return opensc_init();
|
return opensc_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destructor */
|
/* Destructor */
|
||||||
static int opensc_engine_destroy(ENGINE *e)
|
static int opensc_engine_destroy(ENGINE * e)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int opensc_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
|
static int opensc_engine_ctrl(ENGINE * e, int cmd, long i, void *p, void (*f) ())
|
||||||
{
|
{
|
||||||
switch(cmd)
|
switch (cmd) {
|
||||||
{
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* set up default rsa_meth_st with overloaded rsa functions */
|
/* set up default rsa_meth_st with overloaded rsa functions */
|
||||||
/* the actual implementation needs to be in another object */
|
/* the actual implementation needs to be in another object */
|
||||||
|
|
||||||
static int (*orig_finish)(RSA* rsa);
|
static int (*orig_finish) (RSA * rsa);
|
||||||
|
|
||||||
static int
|
static int opensc_engine_rsa_finish(RSA * rsa)
|
||||||
opensc_engine_rsa_finish(RSA* rsa) {
|
{
|
||||||
|
opensc_rsa_finish(rsa);
|
||||||
opensc_rsa_finish(rsa);
|
|
||||||
|
|
||||||
if (orig_finish)
|
if (orig_finish)
|
||||||
orig_finish(rsa);
|
orig_finish(rsa);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RSA_METHOD * sc_get_rsa_method(void)
|
static RSA_METHOD *sc_get_rsa_method(void)
|
||||||
{
|
{
|
||||||
static RSA_METHOD smart_rsa;
|
static RSA_METHOD smart_rsa;
|
||||||
const RSA_METHOD *def = RSA_get_default_method();
|
const RSA_METHOD *def = RSA_get_default_method();
|
||||||
|
@ -145,64 +143,66 @@ static RSA_METHOD * sc_get_rsa_method(void)
|
||||||
/* use the OpenSSL version */
|
/* use the OpenSSL version */
|
||||||
memcpy(&smart_rsa, def, sizeof(smart_rsa));
|
memcpy(&smart_rsa, def, sizeof(smart_rsa));
|
||||||
|
|
||||||
smart_rsa.name = "opensc";
|
smart_rsa.name = "opensc";
|
||||||
|
|
||||||
/* overload */
|
/* overload */
|
||||||
smart_rsa.rsa_priv_enc = sc_private_encrypt;
|
smart_rsa.rsa_priv_enc = sc_private_encrypt;
|
||||||
smart_rsa.rsa_priv_dec = sc_private_decrypt;
|
smart_rsa.rsa_priv_dec = sc_private_decrypt;
|
||||||
smart_rsa.rsa_sign = sc_sign;
|
smart_rsa.rsa_sign = sc_sign;
|
||||||
|
|
||||||
/* save original */
|
/* save original */
|
||||||
orig_finish = def->finish;
|
orig_finish = def->finish;
|
||||||
smart_rsa.finish = opensc_engine_rsa_finish;
|
smart_rsa.finish = opensc_engine_rsa_finish;
|
||||||
|
|
||||||
/* set flags for sign version */
|
/* set flags for sign version */
|
||||||
smart_rsa.flags|=RSA_FLAG_SIGN_VER;
|
smart_rsa.flags |= RSA_FLAG_SIGN_VER;
|
||||||
return &smart_rsa;
|
return &smart_rsa;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This internal function is used by ENGINE_opensc() and possibly by the
|
/* This internal function is used by ENGINE_opensc() and possibly by the
|
||||||
* "dynamic" ENGINE support too */
|
* "dynamic" ENGINE support too */
|
||||||
static int bind_helper(ENGINE *e)
|
static int bind_helper(ENGINE * e)
|
||||||
{
|
{
|
||||||
if(
|
if (!ENGINE_set_id(e, OPENSC_ENGINE_ID) ||
|
||||||
!ENGINE_set_id(e, OPENSC_ENGINE_ID) ||
|
!ENGINE_set_destroy_function(e, opensc_engine_destroy) ||
|
||||||
!ENGINE_set_destroy_function(e, opensc_engine_destroy) ||
|
!ENGINE_set_init_function(e, opensc_engine_init) ||
|
||||||
!ENGINE_set_init_function(e, opensc_engine_init) ||
|
!ENGINE_set_finish_function(e, opensc_engine_finish) ||
|
||||||
!ENGINE_set_finish_function(e, opensc_engine_finish) ||
|
!ENGINE_set_ctrl_function(e, opensc_engine_ctrl) ||
|
||||||
!ENGINE_set_ctrl_function(e, opensc_engine_ctrl) ||
|
!ENGINE_set_cmd_defns(e, opensc_cmd_defns) ||
|
||||||
!ENGINE_set_cmd_defns(e, opensc_cmd_defns) ||
|
!ENGINE_set_name(e, OPENSC_ENGINE_NAME) ||
|
||||||
!ENGINE_set_name(e, OPENSC_ENGINE_NAME) ||
|
|
||||||
#ifndef OPENSSL_NO_RSA
|
#ifndef OPENSSL_NO_RSA
|
||||||
!ENGINE_set_RSA(e, sc_get_rsa_method())||
|
!ENGINE_set_RSA(e, sc_get_rsa_method()) ||
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPENSSL_NO_DSA
|
#ifndef OPENSSL_NO_DSA
|
||||||
!ENGINE_set_DSA(e, DSA_get_default_method()) ||
|
!ENGINE_set_DSA(e, DSA_get_default_method()) ||
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
!ENGINE_set_DH(e, DH_get_default_method()) ||
|
!ENGINE_set_DH(e, DH_get_default_method()) ||
|
||||||
#endif
|
#endif
|
||||||
!ENGINE_set_RAND(e, RAND_SSLeay()) ||
|
!ENGINE_set_RAND(e, RAND_SSLeay()) ||
|
||||||
#if 0
|
#if 0
|
||||||
!ENGINE_set_BN_mod_exp(e, BN_mod_exp) ||
|
!ENGINE_set_BN_mod_exp(e, BN_mod_exp) ||
|
||||||
#endif
|
#endif
|
||||||
!ENGINE_set_load_pubkey_function(e, opensc_load_public_key ) ||
|
!ENGINE_set_load_pubkey_function(e, opensc_load_public_key) ||
|
||||||
!ENGINE_set_load_privkey_function(e, opensc_load_private_key) )
|
!ENGINE_set_load_privkey_function(e, opensc_load_private_key)) {
|
||||||
{
|
return 0;
|
||||||
return 0;
|
} else {
|
||||||
} else {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int bind_fn(ENGINE *e, const char *id)
|
static int bind_fn(ENGINE * e, const char *id)
|
||||||
{
|
{
|
||||||
if(id && (strcmp(id, OPENSC_ENGINE_ID) != 0))
|
if (id && (strcmp(id, OPENSC_ENGINE_ID) != 0)) {
|
||||||
{fprintf(stderr, "bad engine id");return 0;}
|
fprintf(stderr, "bad engine id");
|
||||||
if(!bind_helper(e))
|
return 0;
|
||||||
{fprintf(stderr, "bind failed"); return 0;}
|
}
|
||||||
|
if (!bind_helper(e)) {
|
||||||
|
fprintf(stderr, "bind failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CHECK_FN()
|
IMPLEMENT_DYNAMIC_CHECK_FN();
|
||||||
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
|
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn);
|
||||||
|
|
|
@ -76,8 +76,8 @@
|
||||||
#define CMD_SO_PATH ENGINE_CMD_BASE
|
#define CMD_SO_PATH ENGINE_CMD_BASE
|
||||||
#define CMD_MODULE_PATH (ENGINE_CMD_BASE+1)
|
#define CMD_MODULE_PATH (ENGINE_CMD_BASE+1)
|
||||||
|
|
||||||
static int pkcs11_engine_destroy(ENGINE *e);
|
static int pkcs11_engine_destroy(ENGINE * e);
|
||||||
static int pkcs11_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
|
static int pkcs11_engine_ctrl(ENGINE * e, int cmd, long i, void *p, void (*f) ());
|
||||||
|
|
||||||
/* The definitions for control commands specific to this engine */
|
/* The definitions for control commands specific to this engine */
|
||||||
|
|
||||||
|
@ -85,44 +85,44 @@ static int pkcs11_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
|
||||||
|
|
||||||
static const ENGINE_CMD_DEFN pkcs11_cmd_defns[] = {
|
static const ENGINE_CMD_DEFN pkcs11_cmd_defns[] = {
|
||||||
{CMD_SO_PATH,
|
{CMD_SO_PATH,
|
||||||
"SO_PATH",
|
"SO_PATH",
|
||||||
"Specifies the path to the 'pkcs11-engine' shared library",
|
"Specifies the path to the 'pkcs11-engine' shared library",
|
||||||
ENGINE_CMD_FLAG_STRING},
|
ENGINE_CMD_FLAG_STRING},
|
||||||
{CMD_MODULE_PATH,
|
{CMD_MODULE_PATH,
|
||||||
"MODULE_PATH",
|
"MODULE_PATH",
|
||||||
"Specifies the path to the pkcs11 module shared library",
|
"Specifies the path to the pkcs11 module shared library",
|
||||||
ENGINE_CMD_FLAG_STRING},
|
ENGINE_CMD_FLAG_STRING},
|
||||||
{0, NULL, NULL, 0}
|
{0, NULL, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Destructor */
|
/* Destructor */
|
||||||
static int pkcs11_engine_destroy(ENGINE *e)
|
static int pkcs11_engine_destroy(ENGINE * e)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkcs11_engine_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
|
static int pkcs11_engine_ctrl(ENGINE * e, int cmd, long i, void *p, void (*f) ())
|
||||||
{
|
{
|
||||||
/*int initialised = ((pkcs11_dso == NULL) ? 0 : 1);*/
|
/*int initialised = ((pkcs11_dso == NULL) ? 0 : 1); */
|
||||||
switch(cmd)
|
switch (cmd) {
|
||||||
{
|
|
||||||
case CMD_MODULE_PATH:
|
case CMD_MODULE_PATH:
|
||||||
return set_module((const char *)p);
|
return set_module((const char *) p);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* set up default rsa_meth_st with overloaded rsa functions */
|
/* set up default rsa_meth_st with overloaded rsa functions */
|
||||||
/* the actual implementation needs to be in another object */
|
/* the actual implementation needs to be in another object */
|
||||||
|
|
||||||
static int (*orig_finish)(RSA* rsa);
|
static int (*orig_finish) (RSA * rsa);
|
||||||
|
|
||||||
static int
|
static int pkcs11_engine_rsa_finish(RSA * rsa)
|
||||||
pkcs11_engine_rsa_finish(RSA* rsa) {
|
{
|
||||||
|
|
||||||
pkcs11_rsa_finish(rsa);
|
pkcs11_rsa_finish(rsa);
|
||||||
|
|
||||||
if (orig_finish)
|
if (orig_finish)
|
||||||
orig_finish(rsa);
|
orig_finish(rsa);
|
||||||
|
@ -132,46 +132,48 @@ pkcs11_engine_rsa_finish(RSA* rsa) {
|
||||||
|
|
||||||
/* This internal function is used by ENGINE_pkcs11() and possibly by the
|
/* This internal function is used by ENGINE_pkcs11() and possibly by the
|
||||||
* "dynamic" ENGINE support too */
|
* "dynamic" ENGINE support too */
|
||||||
static int bind_helper(ENGINE *e)
|
static int bind_helper(ENGINE * e)
|
||||||
{
|
{
|
||||||
if(
|
if (!ENGINE_set_id(e, PKCS11_ENGINE_ID) ||
|
||||||
!ENGINE_set_id(e, PKCS11_ENGINE_ID) ||
|
!ENGINE_set_destroy_function(e, pkcs11_engine_destroy) ||
|
||||||
!ENGINE_set_destroy_function(e, pkcs11_engine_destroy) ||
|
!ENGINE_set_init_function(e, pkcs11_init) ||
|
||||||
!ENGINE_set_init_function(e, pkcs11_init) ||
|
!ENGINE_set_finish_function(e, pkcs11_finish) ||
|
||||||
!ENGINE_set_finish_function(e, pkcs11_finish) ||
|
!ENGINE_set_ctrl_function(e, pkcs11_engine_ctrl) ||
|
||||||
!ENGINE_set_ctrl_function(e, pkcs11_engine_ctrl) ||
|
!ENGINE_set_cmd_defns(e, pkcs11_cmd_defns) ||
|
||||||
!ENGINE_set_cmd_defns(e, pkcs11_cmd_defns) ||
|
!ENGINE_set_name(e, PKCS11_ENGINE_NAME) ||
|
||||||
!ENGINE_set_name(e, PKCS11_ENGINE_NAME) ||
|
|
||||||
#ifndef OPENSSL_NO_RSA
|
#ifndef OPENSSL_NO_RSA
|
||||||
!ENGINE_set_RSA(e, pkcs11_get_rsa_method())||
|
!ENGINE_set_RSA(e, pkcs11_get_rsa_method()) ||
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPENSSL_NO_DSA
|
#ifndef OPENSSL_NO_DSA
|
||||||
!ENGINE_set_DSA(e, DSA_get_default_method()) ||
|
!ENGINE_set_DSA(e, DSA_get_default_method()) ||
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPENSSL_NO_DH
|
#ifndef OPENSSL_NO_DH
|
||||||
!ENGINE_set_DH(e, DH_get_default_method()) ||
|
!ENGINE_set_DH(e, DH_get_default_method()) ||
|
||||||
#endif
|
#endif
|
||||||
!ENGINE_set_RAND(e, RAND_SSLeay()) ||
|
!ENGINE_set_RAND(e, RAND_SSLeay()) ||
|
||||||
#if 0
|
#if 0
|
||||||
!ENGINE_set_BN_mod_exp(e, BN_mod_exp) ||
|
!ENGINE_set_BN_mod_exp(e, BN_mod_exp) ||
|
||||||
#endif
|
#endif
|
||||||
!ENGINE_set_load_pubkey_function(e, pkcs11_load_public_key ) ||
|
!ENGINE_set_load_pubkey_function(e, pkcs11_load_public_key) ||
|
||||||
!ENGINE_set_load_privkey_function(e, pkcs11_load_private_key) )
|
!ENGINE_set_load_privkey_function(e, pkcs11_load_private_key)) {
|
||||||
{
|
return 0;
|
||||||
return 0;
|
} else {
|
||||||
} else {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int bind_fn(ENGINE *e, const char *id)
|
static int bind_fn(ENGINE * e, const char *id)
|
||||||
{
|
{
|
||||||
if(id && (strcmp(id, PKCS11_ENGINE_ID) != 0))
|
if (id && (strcmp(id, PKCS11_ENGINE_ID) != 0)) {
|
||||||
{fprintf(stderr, "bad engine id");return 0;}
|
fprintf(stderr, "bad engine id");
|
||||||
if(!bind_helper(e))
|
return 0;
|
||||||
{fprintf(stderr, "bind failed"); return 0;}
|
}
|
||||||
|
if (!bind_helper(e)) {
|
||||||
|
fprintf(stderr, "bind failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CHECK_FN()
|
IMPLEMENT_DYNAMIC_CHECK_FN();
|
||||||
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
|
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn);
|
||||||
|
|
|
@ -11,19 +11,19 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static int pkcs11_getattr_int(PKCS11_CTX *, CK_SESSION_HANDLE,
|
static int pkcs11_getattr_int(PKCS11_CTX *, CK_SESSION_HANDLE,
|
||||||
CK_OBJECT_HANDLE, CK_ATTRIBUTE_TYPE,
|
CK_OBJECT_HANDLE, CK_ATTRIBUTE_TYPE, void *, size_t *);
|
||||||
void *, size_t *);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Query pkcs11 attributes
|
* Query pkcs11 attributes
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
pkcs11_getattr_int(PKCS11_CTX *ctx, CK_SESSION_HANDLE session,
|
pkcs11_getattr_int(PKCS11_CTX * ctx, CK_SESSION_HANDLE session,
|
||||||
CK_OBJECT_HANDLE o, CK_ATTRIBUTE_TYPE type, void *value, size_t *size)
|
CK_OBJECT_HANDLE o, CK_ATTRIBUTE_TYPE type, void *value,
|
||||||
|
size_t * size)
|
||||||
{
|
{
|
||||||
CK_ATTRIBUTE templ;
|
CK_ATTRIBUTE templ;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
templ.type = type;
|
templ.type = type;
|
||||||
templ.pValue = value;
|
templ.pValue = value;
|
||||||
|
@ -37,52 +37,51 @@ pkcs11_getattr_int(PKCS11_CTX *ctx, CK_SESSION_HANDLE session,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_getattr_var(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
pkcs11_getattr_var(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
|
||||||
unsigned int type, void *value, size_t *size)
|
unsigned int type, void *value, size_t * size)
|
||||||
{
|
{
|
||||||
return pkcs11_getattr_int(TOKEN2CTX(token),
|
return pkcs11_getattr_int(TOKEN2CTX(token),
|
||||||
PRIVSLOT(TOKEN2SLOT(token))->session,
|
PRIVSLOT(TOKEN2SLOT(token))->session,
|
||||||
object, type, value, size);
|
object, type, value, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_getattr(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
pkcs11_getattr(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
|
||||||
unsigned int type, void *value, size_t size)
|
unsigned int type, void *value, size_t size)
|
||||||
{
|
{
|
||||||
return pkcs11_getattr_var(token, object, type, value, &size);
|
return pkcs11_getattr_var(token, object, type, value, &size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_getattr_s(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
pkcs11_getattr_s(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
|
||||||
unsigned int type, void *value, size_t size)
|
unsigned int type, void *value, size_t size)
|
||||||
{
|
{
|
||||||
memset(value, 0, size);
|
memset(value, 0, size);
|
||||||
return pkcs11_getattr_var(token, object, type, value, &size);
|
return pkcs11_getattr_var(token, object, type, value, &size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_getattr_bn(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
pkcs11_getattr_bn(PKCS11_TOKEN * token, CK_OBJECT_HANDLE object,
|
||||||
unsigned int type, BIGNUM **bn)
|
unsigned int type, BIGNUM ** bn)
|
||||||
{
|
{
|
||||||
CK_BYTE binary[4196 / 8];
|
CK_BYTE binary[4196 / 8];
|
||||||
size_t size = sizeof(binary);
|
size_t size = sizeof(binary);
|
||||||
|
|
||||||
if (pkcs11_getattr_var(token, object, type, binary, &size))
|
if (pkcs11_getattr_var(token, object, type, binary, &size))
|
||||||
return -1;
|
return -1;
|
||||||
if (size == -1) {
|
if (size == -1) {
|
||||||
PKCS11err(PKCS11_F_PKCS11_GETATTR,
|
PKCS11err(PKCS11_F_PKCS11_GETATTR,
|
||||||
pkcs11_map_err(CKR_ATTRIBUTE_TYPE_INVALID));
|
pkcs11_map_err(CKR_ATTRIBUTE_TYPE_INVALID));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*bn = BN_bin2bn(binary, size, NULL);
|
*bn = BN_bin2bn(binary, size, NULL);
|
||||||
return *bn? 0 : -1;
|
return *bn ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add attributes to template
|
* Add attributes to template
|
||||||
*/
|
*/
|
||||||
void
|
void pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size)
|
||||||
pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size)
|
|
||||||
{
|
{
|
||||||
ap->type = type;
|
ap->type = type;
|
||||||
ap->pValue = malloc(size);
|
ap->pValue = malloc(size);
|
||||||
|
@ -91,35 +90,31 @@ pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In PKCS11, virtually every integer is a CK_ULONG */
|
/* In PKCS11, virtually every integer is a CK_ULONG */
|
||||||
void
|
void pkcs11_addattr_int(CK_ATTRIBUTE_PTR ap, int type, unsigned long value)
|
||||||
pkcs11_addattr_int(CK_ATTRIBUTE_PTR ap, int type, unsigned long value)
|
|
||||||
{
|
{
|
||||||
CK_ULONG ulValue = value;
|
CK_ULONG ulValue = value;
|
||||||
|
|
||||||
pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue));
|
pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s)
|
||||||
pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s)
|
|
||||||
{
|
{
|
||||||
pkcs11_addattr(ap, type, s, s? strlen(s) + 1 : 0);
|
pkcs11_addattr(ap, type, s, s ? strlen(s) + 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM * bn)
|
||||||
pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM *bn)
|
|
||||||
{
|
{
|
||||||
unsigned char temp[1024];
|
unsigned char temp[1024];
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
|
|
||||||
assert (BN_num_bytes(bn) <= sizeof(temp));
|
assert(BN_num_bytes(bn) <= sizeof(temp));
|
||||||
n = BN_bn2bin(bn, temp);
|
n = BN_bn2bin(bn, temp);
|
||||||
pkcs11_addattr(ap, type, temp, n);
|
pkcs11_addattr(ap, type, temp, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj)
|
||||||
pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj)
|
|
||||||
{
|
{
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
ap->type = type;
|
ap->type = type;
|
||||||
ap->ulValueLen = enc(obj, NULL);
|
ap->ulValueLen = enc(obj, NULL);
|
||||||
|
@ -127,8 +122,7 @@ pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj)
|
||||||
enc(obj, &p);
|
enc(obj, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR ap, unsigned int n)
|
||||||
pkcs11_zap_attrs(CK_ATTRIBUTE_PTR ap, unsigned int n)
|
|
||||||
{
|
{
|
||||||
while (n--) {
|
while (n--) {
|
||||||
if (ap[n].pValue)
|
if (ap[n].pValue)
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
#include "pkcs11-internal.h"
|
#include "pkcs11-internal.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static int pkcs11_find_certs(PKCS11_TOKEN *);
|
static int pkcs11_find_certs(PKCS11_TOKEN *);
|
||||||
static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *,
|
static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *, CK_SESSION_HANDLE);
|
||||||
CK_SESSION_HANDLE);
|
static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||||
static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
|
||||||
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
|
PKCS11_CERT **);
|
||||||
PKCS11_CERT **);
|
static int pkcs11_store_certificate(PKCS11_TOKEN *, X509 *,
|
||||||
static int pkcs11_store_certificate(PKCS11_TOKEN *, X509 *,
|
char *, unsigned char *, unsigned int,
|
||||||
char *, unsigned char *, unsigned int,
|
PKCS11_CERT **);
|
||||||
PKCS11_CERT **);
|
|
||||||
|
|
||||||
static CK_OBJECT_CLASS cert_search_class;
|
static CK_OBJECT_CLASS cert_search_class;
|
||||||
static CK_ATTRIBUTE cert_search_attrs[] = {
|
static CK_ATTRIBUTE cert_search_attrs[] = {
|
||||||
{ CKA_CLASS, &cert_search_class, sizeof(cert_search_class) },
|
{CKA_CLASS, &cert_search_class, sizeof(cert_search_class)},
|
||||||
};
|
};
|
||||||
#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
|
#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||||
|
|
||||||
|
@ -27,9 +26,8 @@ static CK_ATTRIBUTE cert_search_attrs[] = {
|
||||||
* Enumerate all certs on the card
|
* Enumerate all certs on the card
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
PKCS11_enumerate_certs(PKCS11_TOKEN *token,
|
PKCS11_enumerate_certs(PKCS11_TOKEN * token,
|
||||||
PKCS11_CERT **certp,
|
PKCS11_CERT ** certp, unsigned int *countp)
|
||||||
unsigned int *countp)
|
|
||||||
{
|
{
|
||||||
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
||||||
|
|
||||||
|
@ -48,13 +46,12 @@ PKCS11_enumerate_certs(PKCS11_TOKEN *token,
|
||||||
/*
|
/*
|
||||||
* Find certificate matching a key
|
* Find certificate matching a key
|
||||||
*/
|
*/
|
||||||
PKCS11_CERT *
|
PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY * key)
|
||||||
PKCS11_find_certificate(PKCS11_KEY *key)
|
|
||||||
{
|
{
|
||||||
PKCS11_KEY_private *kpriv;
|
PKCS11_KEY_private *kpriv;
|
||||||
PKCS11_CERT_private *cpriv;
|
PKCS11_CERT_private *cpriv;
|
||||||
PKCS11_CERT *cert;
|
PKCS11_CERT *cert;
|
||||||
unsigned int n, count;
|
unsigned int n, count;
|
||||||
|
|
||||||
kpriv = PRIVKEY(key);
|
kpriv = PRIVKEY(key);
|
||||||
if (PKCS11_enumerate_certs(KEY2TOKEN(key), &cert, &count))
|
if (PKCS11_enumerate_certs(KEY2TOKEN(key), &cert, &count))
|
||||||
|
@ -62,7 +59,7 @@ PKCS11_find_certificate(PKCS11_KEY *key)
|
||||||
for (n = 0; n < count; n++, cert++) {
|
for (n = 0; n < count; n++, cert++) {
|
||||||
cpriv = PRIVCERT(cert);
|
cpriv = PRIVCERT(cert);
|
||||||
if (cpriv->id_len == kpriv->id_len
|
if (cpriv->id_len == kpriv->id_len
|
||||||
&& !memcmp(cpriv->id, kpriv->id, kpriv->id_len))
|
&& !memcmp(cpriv->id, kpriv->id, kpriv->id_len))
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -71,13 +68,12 @@ PKCS11_find_certificate(PKCS11_KEY *key)
|
||||||
/*
|
/*
|
||||||
* Find all certs of a given type (public or private)
|
* Find all certs of a given type (public or private)
|
||||||
*/
|
*/
|
||||||
int
|
int pkcs11_find_certs(PKCS11_TOKEN * token)
|
||||||
pkcs11_find_certs(PKCS11_TOKEN *token)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
||||||
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
int rv, res = -1;
|
int rv, res = -1;
|
||||||
|
|
||||||
/* Make sure we have a session */
|
/* Make sure we have a session */
|
||||||
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0))
|
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0))
|
||||||
|
@ -87,7 +83,7 @@ pkcs11_find_certs(PKCS11_TOKEN *token)
|
||||||
/* Tell the PKCS11 lib to enumerate all matching objects */
|
/* Tell the PKCS11 lib to enumerate all matching objects */
|
||||||
cert_search_class = CKO_CERTIFICATE;
|
cert_search_class = CKO_CERTIFICATE;
|
||||||
rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, cert_search_attrs,
|
rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, cert_search_attrs,
|
||||||
numof(cert_search_attrs)));
|
numof(cert_search_attrs)));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -95,16 +91,15 @@ pkcs11_find_certs(PKCS11_TOKEN *token)
|
||||||
} while (res == 0);
|
} while (res == 0);
|
||||||
|
|
||||||
CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
|
CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
|
||||||
return (res < 0)? -1 : 0;
|
return (res < 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_next_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
pkcs11_next_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session)
|
||||||
CK_SESSION_HANDLE session)
|
|
||||||
{
|
{
|
||||||
CK_OBJECT_HANDLE obj;
|
CK_OBJECT_HANDLE obj;
|
||||||
CK_ULONG count;
|
CK_ULONG count;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* Get the next matching object */
|
/* Get the next matching object */
|
||||||
rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
|
rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
|
||||||
|
@ -120,21 +115,19 @@ pkcs11_next_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||||
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
|
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
|
||||||
PKCS11_CERT **ret)
|
|
||||||
{
|
{
|
||||||
PKCS11_TOKEN_private *tpriv;
|
PKCS11_TOKEN_private *tpriv;
|
||||||
PKCS11_CERT_private *kpriv;
|
PKCS11_CERT_private *kpriv;
|
||||||
PKCS11_CERT *cert;
|
PKCS11_CERT *cert;
|
||||||
char label[256], data[2048];
|
char label[256], data[2048];
|
||||||
unsigned char id[256];
|
unsigned char id[256];
|
||||||
CK_CERTIFICATE_TYPE cert_type;
|
CK_CERTIFICATE_TYPE cert_type;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
size = sizeof(cert_type);
|
size = sizeof(cert_type);
|
||||||
if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE,
|
if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size))
|
||||||
&cert_type, &size))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Ignore any certs we don't understand */
|
/* Ignore any certs we don't understand */
|
||||||
|
@ -143,7 +136,8 @@ pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
|
|
||||||
tpriv = PRIVTOKEN(token);
|
tpriv = PRIVTOKEN(token);
|
||||||
tpriv->certs = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs,
|
tpriv->certs = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs,
|
||||||
(tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
|
(tpriv->ncerts +
|
||||||
|
1) * sizeof(PKCS11_CERT));
|
||||||
|
|
||||||
cert = tpriv->certs + tpriv->ncerts++;
|
cert = tpriv->certs + tpriv->ncerts++;
|
||||||
memset(cert, 0, sizeof(*cert));
|
memset(cert, 0, sizeof(*cert));
|
||||||
|
@ -155,12 +149,12 @@ pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
cert->label = BUF_strdup(label);
|
cert->label = BUF_strdup(label);
|
||||||
size = sizeof(data);
|
size = sizeof(data);
|
||||||
if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) {
|
if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) {
|
||||||
unsigned char *p = (unsigned char *) data;
|
unsigned char *p = (unsigned char *) data;
|
||||||
|
|
||||||
cert->x509 = d2i_X509(NULL, &p, size);
|
cert->x509 = d2i_X509(NULL, &p, size);
|
||||||
}
|
}
|
||||||
cert->id_len = sizeof(id);
|
cert->id_len = sizeof(id);
|
||||||
if (!pkcs11_getattr_var(token, obj, CKA_ID, id, (size_t *) &cert->id_len)) {
|
if (!pkcs11_getattr_var(token, obj, CKA_ID, id, (size_t *) & cert->id_len)) {
|
||||||
cert->id = (unsigned char *) malloc(cert->id_len);
|
cert->id = (unsigned char *) malloc(cert->id_len);
|
||||||
memcpy(cert->id, id, cert->id_len);
|
memcpy(cert->id, id, cert->id_len);
|
||||||
}
|
}
|
||||||
|
@ -179,13 +173,12 @@ pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
/*
|
/*
|
||||||
* Destroy all certs
|
* Destroy all certs
|
||||||
*/
|
*/
|
||||||
void
|
void pkcs11_destroy_certs(PKCS11_TOKEN * token)
|
||||||
pkcs11_destroy_certs(PKCS11_TOKEN *token)
|
|
||||||
{
|
{
|
||||||
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
||||||
|
|
||||||
while (priv->ncerts > 0) {
|
while (priv->ncerts > 0) {
|
||||||
PKCS11_CERT *cert = &priv->certs[--(priv->ncerts)];
|
PKCS11_CERT *cert = &priv->certs[--(priv->ncerts)];
|
||||||
|
|
||||||
if (cert->x509)
|
if (cert->x509)
|
||||||
X509_free(cert->x509);
|
X509_free(cert->x509);
|
||||||
|
@ -203,17 +196,17 @@ pkcs11_destroy_certs(PKCS11_TOKEN *token)
|
||||||
* Store certificate
|
* Store certificate
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pkcs11_store_certificate(PKCS11_TOKEN *token, X509 *x509, char *label,
|
pkcs11_store_certificate(PKCS11_TOKEN * token, X509 * x509, char *label,
|
||||||
unsigned char *id, unsigned int id_len,
|
unsigned char *id, unsigned int id_len,
|
||||||
PKCS11_CERT **ret_cert)
|
PKCS11_CERT ** ret_cert)
|
||||||
{
|
{
|
||||||
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
||||||
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
CK_OBJECT_HANDLE object;
|
CK_OBJECT_HANDLE object;
|
||||||
CK_ATTRIBUTE attrs[32];
|
CK_ATTRIBUTE attrs[32];
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* First, make sure we have a session */
|
/* First, make sure we have a session */
|
||||||
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
||||||
|
@ -223,8 +216,7 @@ pkcs11_store_certificate(PKCS11_TOKEN *token, X509 *x509, char *label,
|
||||||
/* Now build the template */
|
/* Now build the template */
|
||||||
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE);
|
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE);
|
||||||
pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509);
|
pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509);
|
||||||
pkcs11_addattr_obj(attrs + n++, CKA_VALUE,
|
pkcs11_addattr_obj(attrs + n++, CKA_VALUE, (pkcs11_i2d_fn) i2d_X509, x509);
|
||||||
(pkcs11_i2d_fn) i2d_X509, x509);
|
|
||||||
if (label)
|
if (label)
|
||||||
pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
|
pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
|
||||||
if (id && id_len)
|
if (id && id_len)
|
||||||
|
@ -239,6 +231,5 @@ pkcs11_store_certificate(PKCS11_TOKEN *token, X509 *x509, char *label,
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_CERTIFICATE, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_CERTIFICATE, rv);
|
||||||
|
|
||||||
/* Gobble the key object */
|
/* Gobble the key object */
|
||||||
return pkcs11_init_cert(ctx, token, session,
|
return pkcs11_init_cert(ctx, token, session, object, ret_cert);
|
||||||
object, ret_cert);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,141 +60,131 @@
|
||||||
/* BEGIN ERROR CODES */
|
/* BEGIN ERROR CODES */
|
||||||
#ifndef NO_ERR
|
#ifndef NO_ERR
|
||||||
static ERR_STRING_DATA PKCS11_str_library[] = {
|
static ERR_STRING_DATA PKCS11_str_library[] = {
|
||||||
{ERR_PACK(ERR_LIB_PKCS11,0,0) ,"PKCS11 library"},
|
{ERR_PACK(ERR_LIB_PKCS11, 0, 0), "PKCS11 library"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static ERR_STRING_DATA PKCS11_str_functs[] = {
|
static ERR_STRING_DATA PKCS11_str_functs[] = {
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_CTX_LOAD, 0), "PKCS11_CTX_load" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_CTX_LOAD, 0), "PKCS11_CTX_load"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_ENUM_SLOTS, 0), "PKCS11_enum_slots" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_ENUM_SLOTS, 0), "PKCS11_enum_slots"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_CHECK_TOKEN, 0), "PKCS11_check_token" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_CHECK_TOKEN, 0), "PKCS11_check_token"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_OPEN_SESSION, 0), "PKCS11_open_session" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_OPEN_SESSION, 0), "PKCS11_open_session"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_LOGIN, 0), "PKCS11_login" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_LOGIN, 0), "PKCS11_login"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_ENUM_KEYS, 0), "PKCS11_enum_keys" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_ENUM_KEYS, 0), "PKCS11_enum_keys"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_GET_KEY, 0), "PKCS11_get_key" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_GET_KEY, 0), "PKCS11_get_key"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_DECRYPT, 0), "PKCS11_rsa_decrypt" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_DECRYPT, 0), "PKCS11_rsa_decrypt"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_ENCRYPT, 0), "PKCS11_rsa_encrypt" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_ENCRYPT, 0), "PKCS11_rsa_encrypt"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_SIGN, 0), "PKCS11_rsa_sign" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_SIGN, 0), "PKCS11_rsa_sign"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_VERIFY, 0), "PKCS11_rsa_verify" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_RSA_VERIFY, 0), "PKCS11_rsa_verify"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_ENUM_CERTS, 0), "PKCS11_enum_certs" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_ENUM_CERTS, 0), "PKCS11_enum_certs"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_INIT_TOKEN, 0), "PKCS11_init_token" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_INIT_TOKEN, 0), "PKCS11_init_token"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_INIT_PIN, 0), "PKCS11_init_pin" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_INIT_PIN, 0), "PKCS11_init_pin"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_GETATTR, 0), "PKCS11_get_attribute" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_GETATTR, 0), "PKCS11_get_attribute"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_LOGOUT, 0), "PKCS11_logout" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_LOGOUT, 0), "PKCS11_logout"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_STORE_PRIVATE_KEY, 0),"PKCS11_store_private_key" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_STORE_PRIVATE_KEY, 0), "PKCS11_store_private_key"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_GENERATE_KEY, 0), "PKCS11_generate_key" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_GENERATE_KEY, 0), "PKCS11_generate_key"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_STORE_PUBLIC_KEY, 0),"PKCS11_store_public_key" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_STORE_PUBLIC_KEY, 0), "PKCS11_store_public_key"},
|
||||||
{ERR_PACK(0, PKCS11_F_PKCS11_STORE_CERTIFICATE, 0),"PKCS11_store_certificate" },
|
{ERR_PACK(0, PKCS11_F_PKCS11_STORE_CERTIFICATE, 0), "PKCS11_store_certificate"},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static ERR_STRING_DATA PKCS11_str_reasons[] = {
|
static ERR_STRING_DATA PKCS11_str_reasons[] = {
|
||||||
{PKCS11_LOAD_MODULE_ERROR ,"Unable to load PKCS#11 module" },
|
{PKCS11_LOAD_MODULE_ERROR, "Unable to load PKCS#11 module"},
|
||||||
{PKCS11_MODULE_LOADED_ERROR ,"Already loaded module for PKCS11 context" },
|
{PKCS11_MODULE_LOADED_ERROR, "Already loaded module for PKCS11 context"},
|
||||||
{PKCS11_SYMBOL_NOT_FOUND_ERROR ,"Symbol not found in PKCS#11 module" },
|
{PKCS11_SYMBOL_NOT_FOUND_ERROR, "Symbol not found in PKCS#11 module"},
|
||||||
{PKCS11_NOT_SUPPORTED ,"Not supported" },
|
{PKCS11_NOT_SUPPORTED, "Not supported"},
|
||||||
{PKCS11_NO_SESSION ,"No session open" },
|
{PKCS11_NO_SESSION, "No session open"},
|
||||||
|
{CKR_CANCEL, "Cancel"},
|
||||||
{CKR_CANCEL, "Cancel" },
|
{CKR_HOST_MEMORY, "Host memory error"},
|
||||||
{CKR_HOST_MEMORY, "Host memory error" },
|
{CKR_SLOT_ID_INVALID, "Invalid slot ID"},
|
||||||
{CKR_SLOT_ID_INVALID, "Invalid slot ID" },
|
{CKR_GENERAL_ERROR, "General Error"},
|
||||||
{CKR_GENERAL_ERROR, "General Error" },
|
{CKR_FUNCTION_FAILED, "Function failed"},
|
||||||
{CKR_FUNCTION_FAILED, "Function failed" },
|
{CKR_ARGUMENTS_BAD, "Invalid arguments"},
|
||||||
{CKR_ARGUMENTS_BAD, "Invalid arguments" },
|
{CKR_NO_EVENT, "No event"},
|
||||||
{CKR_NO_EVENT, "No event" },
|
{CKR_NEED_TO_CREATE_THREADS, "Need to create threads"},
|
||||||
{CKR_NEED_TO_CREATE_THREADS, "Need to create threads" },
|
{CKR_CANT_LOCK, "Cannott lock"},
|
||||||
{CKR_CANT_LOCK, "Cannott lock" },
|
{CKR_ATTRIBUTE_READ_ONLY, "Attribute read only"},
|
||||||
{CKR_ATTRIBUTE_READ_ONLY, "Attribute read only" },
|
{CKR_ATTRIBUTE_SENSITIVE, "Attribute sensitive"},
|
||||||
{CKR_ATTRIBUTE_SENSITIVE, "Attribute sensitive" },
|
{CKR_ATTRIBUTE_TYPE_INVALID, "Attribute type invalid"},
|
||||||
{CKR_ATTRIBUTE_TYPE_INVALID, "Attribute type invalid" },
|
{CKR_ATTRIBUTE_VALUE_INVALID, "Attribute value invalid"},
|
||||||
{CKR_ATTRIBUTE_VALUE_INVALID, "Attribute value invalid" },
|
{CKR_DATA_INVALID, "Data invalid"},
|
||||||
{CKR_DATA_INVALID, "Data invalid" },
|
{CKR_DATA_LEN_RANGE, "Data len range"},
|
||||||
{CKR_DATA_LEN_RANGE, "Data len range" },
|
{CKR_DEVICE_ERROR, "Device error"},
|
||||||
{CKR_DEVICE_ERROR, "Device error" },
|
{CKR_DEVICE_MEMORY, "Device memory"},
|
||||||
{CKR_DEVICE_MEMORY, "Device memory" },
|
{CKR_DEVICE_REMOVED, "Device removed"},
|
||||||
{CKR_DEVICE_REMOVED, "Device removed" },
|
{CKR_ENCRYPTED_DATA_INVALID, "Encrypted data invalid"},
|
||||||
{CKR_ENCRYPTED_DATA_INVALID, "Encrypted data invalid" },
|
{CKR_ENCRYPTED_DATA_LEN_RANGE, "Encrypted data len range"},
|
||||||
{CKR_ENCRYPTED_DATA_LEN_RANGE, "Encrypted data len range" },
|
{CKR_FUNCTION_CANCELED, "Function canceled"},
|
||||||
{CKR_FUNCTION_CANCELED, "Function canceled" },
|
{CKR_FUNCTION_NOT_PARALLEL, "Function not parallel"},
|
||||||
{CKR_FUNCTION_NOT_PARALLEL, "Function not parallel" },
|
{CKR_FUNCTION_NOT_SUPPORTED, "Function not supported"},
|
||||||
{CKR_FUNCTION_NOT_SUPPORTED, "Function not supported" },
|
{CKR_KEY_HANDLE_INVALID, "Key handle invalid"},
|
||||||
{CKR_KEY_HANDLE_INVALID, "Key handle invalid" },
|
{CKR_KEY_SIZE_RANGE, "Key size range"},
|
||||||
{CKR_KEY_SIZE_RANGE, "Key size range" },
|
{CKR_KEY_TYPE_INCONSISTENT, "Key type inconsistent"},
|
||||||
{CKR_KEY_TYPE_INCONSISTENT, "Key type inconsistent" },
|
{CKR_KEY_NOT_NEEDED, "Key not needed"},
|
||||||
{CKR_KEY_NOT_NEEDED, "Key not needed" },
|
{CKR_KEY_CHANGED, "Key changed"},
|
||||||
{CKR_KEY_CHANGED, "Key changed" },
|
{CKR_KEY_NEEDED, "Key needed"},
|
||||||
{CKR_KEY_NEEDED, "Key needed" },
|
{CKR_KEY_INDIGESTIBLE, "Key indigestible"},
|
||||||
{CKR_KEY_INDIGESTIBLE, "Key indigestible" },
|
{CKR_KEY_FUNCTION_NOT_PERMITTED, "Key function not permitted"},
|
||||||
{CKR_KEY_FUNCTION_NOT_PERMITTED,"Key function not permitted" },
|
{CKR_KEY_NOT_WRAPPABLE, "Key not wrappable"},
|
||||||
{CKR_KEY_NOT_WRAPPABLE, "Key not wrappable" },
|
{CKR_KEY_UNEXTRACTABLE, "Key unextractable"},
|
||||||
{CKR_KEY_UNEXTRACTABLE, "Key unextractable" },
|
{CKR_MECHANISM_INVALID, "Mechanism invalid"},
|
||||||
{CKR_MECHANISM_INVALID, "Mechanism invalid" },
|
{CKR_MECHANISM_PARAM_INVALID, "Mechanism param invalid"},
|
||||||
{CKR_MECHANISM_PARAM_INVALID, "Mechanism param invalid" },
|
{CKR_OBJECT_HANDLE_INVALID, "Object handle invalid"},
|
||||||
{CKR_OBJECT_HANDLE_INVALID, "Object handle invalid" },
|
{CKR_OPERATION_ACTIVE, "Operation active"},
|
||||||
{CKR_OPERATION_ACTIVE, "Operation active" },
|
{CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized"},
|
||||||
{CKR_OPERATION_NOT_INITIALIZED, "Operation not initialized" },
|
{CKR_PIN_INCORRECT, "PIN incorrect"},
|
||||||
{CKR_PIN_INCORRECT, "PIN incorrect" },
|
{CKR_PIN_INVALID, "PIN invalid"},
|
||||||
{CKR_PIN_INVALID, "PIN invalid" },
|
{CKR_PIN_LEN_RANGE, "Invalid PIN length"},
|
||||||
{CKR_PIN_LEN_RANGE, "Invalid PIN length" },
|
{CKR_PIN_EXPIRED, "PIN expired"},
|
||||||
{CKR_PIN_EXPIRED, "PIN expired" },
|
{CKR_PIN_LOCKED, "PIN locked"},
|
||||||
{CKR_PIN_LOCKED, "PIN locked" },
|
{CKR_SESSION_CLOSED, "Session closed"},
|
||||||
{CKR_SESSION_CLOSED, "Session closed" },
|
{CKR_SESSION_COUNT, "Session count"},
|
||||||
{CKR_SESSION_COUNT, "Session count" },
|
{CKR_SESSION_HANDLE_INVALID, "Session handle invalid"},
|
||||||
{CKR_SESSION_HANDLE_INVALID, "Session handle invalid" },
|
{CKR_SESSION_PARALLEL_NOT_SUPPORTED, "Session parallel not supported"},
|
||||||
{CKR_SESSION_PARALLEL_NOT_SUPPORTED,
|
{CKR_SESSION_READ_ONLY, "Session read only"},
|
||||||
"Session parallel not supported" },
|
{CKR_SESSION_EXISTS, "Session exists"},
|
||||||
{CKR_SESSION_READ_ONLY, "Session read only" },
|
{CKR_SESSION_READ_ONLY_EXISTS, "Read-only session exists"},
|
||||||
{CKR_SESSION_EXISTS, "Session exists" },
|
{CKR_SESSION_READ_WRITE_SO_EXISTS, "Read/write SO session exists"},
|
||||||
{CKR_SESSION_READ_ONLY_EXISTS, "Read-only session exists" },
|
{CKR_SIGNATURE_INVALID, "Signature invalid"},
|
||||||
{CKR_SESSION_READ_WRITE_SO_EXISTS,
|
{CKR_SIGNATURE_LEN_RANGE, "Signature len range"},
|
||||||
"Read/write SO session exists" },
|
{CKR_TEMPLATE_INCOMPLETE, "Incomplete template"},
|
||||||
{CKR_SIGNATURE_INVALID, "Signature invalid" },
|
{CKR_TEMPLATE_INCONSISTENT, "Inconsistent template"},
|
||||||
{CKR_SIGNATURE_LEN_RANGE, "Signature len range" },
|
{CKR_TOKEN_NOT_PRESENT, "No PKCS#11 token present"},
|
||||||
{CKR_TEMPLATE_INCOMPLETE, "Incomplete template" },
|
{CKR_TOKEN_NOT_RECOGNIZED, "PKCS#11 token not recognized"},
|
||||||
{CKR_TEMPLATE_INCONSISTENT, "Inconsistent template" },
|
{CKR_TOKEN_WRITE_PROTECTED, "Token write protected"},
|
||||||
{CKR_TOKEN_NOT_PRESENT, "No PKCS#11 token present" },
|
{CKR_UNWRAPPING_KEY_HANDLE_INVALID, "Unwrapping key handle invalid"},
|
||||||
{CKR_TOKEN_NOT_RECOGNIZED, "PKCS#11 token not recognized" },
|
{CKR_UNWRAPPING_KEY_SIZE_RANGE, "Unwrapping key size range"},
|
||||||
{CKR_TOKEN_WRITE_PROTECTED, "Token write protected" },
|
{CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "Unwrapping key type inconsistent"},
|
||||||
{CKR_UNWRAPPING_KEY_HANDLE_INVALID,
|
{CKR_USER_ALREADY_LOGGED_IN, "User already logged in"},
|
||||||
"Unwrapping key handle invalid" },
|
{CKR_USER_NOT_LOGGED_IN, "User not logged in"},
|
||||||
{CKR_UNWRAPPING_KEY_SIZE_RANGE, "Unwrapping key size range" },
|
{CKR_USER_PIN_NOT_INITIALIZED, "User pin not initialized"},
|
||||||
{CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT,
|
{CKR_USER_TYPE_INVALID, "User type invalid"},
|
||||||
"Unwrapping key type inconsistent" },
|
{CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "User another is already logged in"},
|
||||||
{CKR_USER_ALREADY_LOGGED_IN, "User already logged in" },
|
{CKR_USER_TOO_MANY_TYPES, "User too many types"},
|
||||||
{CKR_USER_NOT_LOGGED_IN, "User not logged in" },
|
{CKR_WRAPPED_KEY_INVALID, "Wrapped key invalid"},
|
||||||
{CKR_USER_PIN_NOT_INITIALIZED, "User pin not initialized" },
|
{CKR_WRAPPED_KEY_LEN_RANGE, "Wrapped key len range"},
|
||||||
{CKR_USER_TYPE_INVALID, "User type invalid" },
|
{CKR_WRAPPING_KEY_HANDLE_INVALID, "Wrapping key handle invalid"},
|
||||||
{CKR_USER_ANOTHER_ALREADY_LOGGED_IN,
|
{CKR_WRAPPING_KEY_SIZE_RANGE, "Wrapping key size range"},
|
||||||
"User another is already logged in" },
|
{CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "Wrapping key type inconsistent"},
|
||||||
{CKR_USER_TOO_MANY_TYPES, "User too many types" },
|
{CKR_RANDOM_SEED_NOT_SUPPORTED, "Random seed not supported"},
|
||||||
{CKR_WRAPPED_KEY_INVALID, "Wrapped key invalid" },
|
{CKR_RANDOM_NO_RNG, "Random no rng"},
|
||||||
{CKR_WRAPPED_KEY_LEN_RANGE, "Wrapped key len range" },
|
{CKR_DOMAIN_PARAMS_INVALID, "Domain params invalid"},
|
||||||
{CKR_WRAPPING_KEY_HANDLE_INVALID,
|
{CKR_BUFFER_TOO_SMALL, "Buffer too small"},
|
||||||
"Wrapping key handle invalid" },
|
{CKR_SAVED_STATE_INVALID, "Saved state invalid"},
|
||||||
{CKR_WRAPPING_KEY_SIZE_RANGE, "Wrapping key size range" },
|
{CKR_INFORMATION_SENSITIVE, "Information sensitive"},
|
||||||
{CKR_WRAPPING_KEY_TYPE_INCONSISTENT,
|
{CKR_STATE_UNSAVEABLE, "State unsaveable"},
|
||||||
"Wrapping key type inconsistent" },
|
{CKR_CRYPTOKI_NOT_INITIALIZED, "Cryptoki not initialized"},
|
||||||
{CKR_RANDOM_SEED_NOT_SUPPORTED, "Random seed not supported" },
|
{CKR_CRYPTOKI_ALREADY_INITIALIZED, "Cryptoki already initialized"},
|
||||||
{CKR_RANDOM_NO_RNG, "Random no rng" },
|
{CKR_MUTEX_BAD, "Mutex bad"},
|
||||||
{CKR_DOMAIN_PARAMS_INVALID, "Domain params invalid" },
|
{CKR_MUTEX_NOT_LOCKED, "Mutex not locked"},
|
||||||
{CKR_BUFFER_TOO_SMALL, "Buffer too small" },
|
{CKR_VENDOR_DEFINED, "Vendor defined"},
|
||||||
{CKR_SAVED_STATE_INVALID, "Saved state invalid" },
|
{0, NULL}
|
||||||
{CKR_INFORMATION_SENSITIVE, "Information sensitive" },
|
|
||||||
{CKR_STATE_UNSAVEABLE, "State unsaveable" },
|
|
||||||
{CKR_CRYPTOKI_NOT_INITIALIZED, "Cryptoki not initialized" },
|
|
||||||
{CKR_CRYPTOKI_ALREADY_INITIALIZED,
|
|
||||||
"Cryptoki already initialized" },
|
|
||||||
{CKR_MUTEX_BAD, "Mutex bad" },
|
|
||||||
{CKR_MUTEX_NOT_LOCKED, "Mutex not locked" },
|
|
||||||
{CKR_VENDOR_DEFINED, "Vendor defined" },
|
|
||||||
{0, NULL}
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void ERR_load_PKCS11_strings(void)
|
||||||
ERR_load_PKCS11_strings(void)
|
|
||||||
{
|
{
|
||||||
static int init = 1;
|
static int init = 1;
|
||||||
|
|
||||||
if (init) {
|
if (init) {
|
||||||
init = 0;
|
init = 0;
|
||||||
|
|
|
@ -58,22 +58,20 @@
|
||||||
#include "pkcs11-internal.h"
|
#include "pkcs11-internal.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
|
static int pkcs11_find_keys(PKCS11_TOKEN *, unsigned int);
|
||||||
static int pkcs11_next_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
static int pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||||
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type);
|
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type);
|
||||||
static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
static int pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||||
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
|
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o,
|
||||||
CK_OBJECT_CLASS type, PKCS11_KEY **);
|
CK_OBJECT_CLASS type, PKCS11_KEY **);
|
||||||
static int pkcs11_store_private_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
|
static int pkcs11_store_private_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
|
||||||
unsigned char *, unsigned int,
|
unsigned char *, unsigned int, PKCS11_KEY **);
|
||||||
PKCS11_KEY **);
|
static int pkcs11_store_public_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
|
||||||
static int pkcs11_store_public_key(PKCS11_TOKEN *, EVP_PKEY *, char *,
|
unsigned char *, unsigned int, PKCS11_KEY **);
|
||||||
unsigned char *, unsigned int,
|
|
||||||
PKCS11_KEY **);
|
|
||||||
|
|
||||||
static CK_OBJECT_CLASS key_search_class;
|
static CK_OBJECT_CLASS key_search_class;
|
||||||
static CK_ATTRIBUTE key_search_attrs[] = {
|
static CK_ATTRIBUTE key_search_attrs[] = {
|
||||||
{ CKA_CLASS, &key_search_class, sizeof(key_search_class) },
|
{CKA_CLASS, &key_search_class, sizeof(key_search_class)},
|
||||||
};
|
};
|
||||||
#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
|
#define numof(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||||
|
|
||||||
|
@ -82,9 +80,7 @@ static CK_ATTRIBUTE key_search_attrs[] = {
|
||||||
* For now, we enumerate just the private keys.
|
* For now, we enumerate just the private keys.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
PKCS11_enumerate_keys(PKCS11_TOKEN *token,
|
PKCS11_enumerate_keys(PKCS11_TOKEN * token, PKCS11_KEY ** keyp, unsigned int *countp)
|
||||||
PKCS11_KEY **keyp,
|
|
||||||
unsigned int *countp)
|
|
||||||
{
|
{
|
||||||
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
||||||
|
|
||||||
|
@ -108,8 +104,7 @@ PKCS11_enumerate_keys(PKCS11_TOKEN *token,
|
||||||
/*
|
/*
|
||||||
* Store a private key on the token
|
* Store a private key on the token
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label)
|
||||||
PKCS11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label)
|
|
||||||
{
|
{
|
||||||
if (pkcs11_store_private_key(token, pk, label, NULL, 0, NULL))
|
if (pkcs11_store_private_key(token, pk, label, NULL, 0, NULL))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -122,28 +117,25 @@ PKCS11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label)
|
||||||
* on-board key generation, and if it does, use its own algorithm
|
* on-board key generation, and if it does, use its own algorithm
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
PKCS11_generate_key(PKCS11_TOKEN *token,
|
PKCS11_generate_key(PKCS11_TOKEN * token,
|
||||||
int algorithm, unsigned int bits,
|
int algorithm, unsigned int bits, char *label)
|
||||||
char *label)
|
|
||||||
{
|
{
|
||||||
PKCS11_KEY *key_obj;
|
PKCS11_KEY *key_obj;
|
||||||
EVP_PKEY *pk;
|
EVP_PKEY *pk;
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
BIO *err;
|
BIO *err;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (algorithm != EVP_PKEY_RSA) {
|
if (algorithm != EVP_PKEY_RSA) {
|
||||||
PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY,
|
PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_NOT_SUPPORTED);
|
||||||
PKCS11_NOT_SUPPORTED);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||||
rsa = RSA_generate_key(bits, 0x10001, NULL, err);
|
rsa = RSA_generate_key(bits, 0x10001, NULL, err);
|
||||||
BIO_free(err);
|
BIO_free(err);
|
||||||
if (rsa == NULL) {
|
if (rsa == NULL) {
|
||||||
PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY,
|
PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_KEYGEN_FAILED);
|
||||||
PKCS11_KEYGEN_FAILED);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +148,7 @@ PKCS11_generate_key(PKCS11_TOKEN *token,
|
||||||
|
|
||||||
kpriv = PRIVKEY(key_obj);
|
kpriv = PRIVKEY(key_obj);
|
||||||
rc = pkcs11_store_public_key(token, pk, label,
|
rc = pkcs11_store_public_key(token, pk, label,
|
||||||
kpriv->id, kpriv->id_len, NULL);
|
kpriv->id, kpriv->id_len, NULL);
|
||||||
}
|
}
|
||||||
EVP_PKEY_free(pk);
|
EVP_PKEY_free(pk);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -165,8 +157,7 @@ PKCS11_generate_key(PKCS11_TOKEN *token,
|
||||||
/*
|
/*
|
||||||
* Get the key type
|
* Get the key type
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_get_key_type(PKCS11_KEY * key)
|
||||||
PKCS11_get_key_type(PKCS11_KEY *key)
|
|
||||||
{
|
{
|
||||||
PKCS11_KEY_private *priv = PRIVKEY(key);
|
PKCS11_KEY_private *priv = PRIVKEY(key);
|
||||||
|
|
||||||
|
@ -177,15 +168,14 @@ PKCS11_get_key_type(PKCS11_KEY *key)
|
||||||
* Create a key object that will allow an OpenSSL application
|
* Create a key object that will allow an OpenSSL application
|
||||||
* to use the token via an EVP_PKEY
|
* to use the token via an EVP_PKEY
|
||||||
*/
|
*/
|
||||||
EVP_PKEY *
|
EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY * key)
|
||||||
PKCS11_get_private_key(PKCS11_KEY *key)
|
|
||||||
{
|
{
|
||||||
PKCS11_KEY_private *priv = PRIVKEY(key);
|
PKCS11_KEY_private *priv = PRIVKEY(key);
|
||||||
EVP_PKEY *pk;
|
EVP_PKEY *pk;
|
||||||
|
|
||||||
pk = EVP_PKEY_new();
|
pk = EVP_PKEY_new();
|
||||||
if (priv->ops->get_private(key, pk)
|
if (priv->ops->get_private(key, pk)
|
||||||
|| priv->ops->get_public(key, pk)) {
|
|| priv->ops->get_public(key, pk)) {
|
||||||
EVP_PKEY_free(pk);
|
EVP_PKEY_free(pk);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -196,13 +186,12 @@ PKCS11_get_private_key(PKCS11_KEY *key)
|
||||||
/*
|
/*
|
||||||
* Find all keys of a given type (public or private)
|
* Find all keys of a given type (public or private)
|
||||||
*/
|
*/
|
||||||
int
|
int pkcs11_find_keys(PKCS11_TOKEN * token, unsigned int type)
|
||||||
pkcs11_find_keys(PKCS11_TOKEN *token, unsigned int type)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
||||||
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
int rv, res = -1;
|
int rv, res = -1;
|
||||||
|
|
||||||
/* Make sure we have a session */
|
/* Make sure we have a session */
|
||||||
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0))
|
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 0))
|
||||||
|
@ -212,7 +201,7 @@ pkcs11_find_keys(PKCS11_TOKEN *token, unsigned int type)
|
||||||
/* Tell the PKCS11 lib to enumerate all matching objects */
|
/* Tell the PKCS11 lib to enumerate all matching objects */
|
||||||
key_search_class = type;
|
key_search_class = type;
|
||||||
rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, key_search_attrs,
|
rv = CRYPTOKI_call(ctx, C_FindObjectsInit(session, key_search_attrs,
|
||||||
numof(key_search_attrs)));
|
numof(key_search_attrs)));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -220,16 +209,16 @@ pkcs11_find_keys(PKCS11_TOKEN *token, unsigned int type)
|
||||||
} while (res == 0);
|
} while (res == 0);
|
||||||
|
|
||||||
CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
|
CRYPTOKI_call(ctx, C_FindObjectsFinal(session));
|
||||||
return (res < 0)? -1 : 0;
|
return (res < 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_next_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
pkcs11_next_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||||
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type)
|
CK_SESSION_HANDLE session, CK_OBJECT_CLASS type)
|
||||||
{
|
{
|
||||||
CK_OBJECT_HANDLE obj;
|
CK_OBJECT_HANDLE obj;
|
||||||
CK_ULONG count;
|
CK_ULONG count;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* Get the next matching object */
|
/* Get the next matching object */
|
||||||
rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
|
rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
|
||||||
|
@ -245,19 +234,18 @@ pkcs11_next_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
pkcs11_init_key(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
|
||||||
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
|
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
|
||||||
CK_OBJECT_CLASS type,
|
CK_OBJECT_CLASS type, PKCS11_KEY ** ret)
|
||||||
PKCS11_KEY **ret)
|
|
||||||
{
|
{
|
||||||
PKCS11_TOKEN_private *tpriv;
|
PKCS11_TOKEN_private *tpriv;
|
||||||
PKCS11_KEY_private *kpriv;
|
PKCS11_KEY_private *kpriv;
|
||||||
PKCS11_KEY *key;
|
PKCS11_KEY *key;
|
||||||
char label[256];
|
char label[256];
|
||||||
unsigned char id[256];
|
unsigned char id[256];
|
||||||
CK_KEY_TYPE key_type;
|
CK_KEY_TYPE key_type;
|
||||||
PKCS11_KEY_ops *ops;
|
PKCS11_KEY_ops *ops;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
size = sizeof(key_type);
|
size = sizeof(key_type);
|
||||||
if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, &key_type, &size))
|
if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, &key_type, &size))
|
||||||
|
@ -274,7 +262,8 @@ pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
|
|
||||||
tpriv = PRIVTOKEN(token);
|
tpriv = PRIVTOKEN(token);
|
||||||
tpriv->keys = (PKCS11_KEY *) OPENSSL_realloc(tpriv->keys,
|
tpriv->keys = (PKCS11_KEY *) OPENSSL_realloc(tpriv->keys,
|
||||||
(tpriv->nkeys + 1) * sizeof(PKCS11_KEY));
|
(tpriv->nkeys +
|
||||||
|
1) * sizeof(PKCS11_KEY));
|
||||||
|
|
||||||
key = tpriv->keys + tpriv->nkeys++;
|
key = tpriv->keys + tpriv->nkeys++;
|
||||||
memset(key, 0, sizeof(*key));
|
memset(key, 0, sizeof(*key));
|
||||||
|
@ -285,7 +274,7 @@ pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label)))
|
if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label)))
|
||||||
key->label = BUF_strdup(label);
|
key->label = BUF_strdup(label);
|
||||||
key->id_len = sizeof(id);
|
key->id_len = sizeof(id);
|
||||||
if (!pkcs11_getattr_var(token, obj, CKA_ID, id, (size_t *) &key->id_len)) {
|
if (!pkcs11_getattr_var(token, obj, CKA_ID, id, (size_t *) & key->id_len)) {
|
||||||
key->id = (unsigned char *) malloc(key->id_len);
|
key->id = (unsigned char *) malloc(key->id_len);
|
||||||
memcpy(key->id, id, key->id_len);
|
memcpy(key->id, id, key->id_len);
|
||||||
}
|
}
|
||||||
|
@ -305,13 +294,12 @@ pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
||||||
/*
|
/*
|
||||||
* Destroy all keys
|
* Destroy all keys
|
||||||
*/
|
*/
|
||||||
void
|
void pkcs11_destroy_keys(PKCS11_TOKEN * token)
|
||||||
pkcs11_destroy_keys(PKCS11_TOKEN *token)
|
|
||||||
{
|
{
|
||||||
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
PKCS11_TOKEN_private *priv = PRIVTOKEN(token);
|
||||||
|
|
||||||
while (priv->nkeys > 0) {
|
while (priv->nkeys > 0) {
|
||||||
PKCS11_KEY *key = &priv->keys[--(priv->nkeys)];
|
PKCS11_KEY *key = &priv->keys[--(priv->nkeys)];
|
||||||
|
|
||||||
if (key->evp_key)
|
if (key->evp_key)
|
||||||
EVP_PKEY_free(key->evp_key);
|
EVP_PKEY_free(key->evp_key);
|
||||||
|
@ -330,17 +318,17 @@ pkcs11_destroy_keys(PKCS11_TOKEN *token)
|
||||||
* Store private key
|
* Store private key
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pkcs11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
pkcs11_store_private_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label,
|
||||||
unsigned char *id, unsigned int id_len,
|
unsigned char *id, unsigned int id_len,
|
||||||
PKCS11_KEY **ret_key)
|
PKCS11_KEY ** ret_key)
|
||||||
{
|
{
|
||||||
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
||||||
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
CK_OBJECT_HANDLE object;
|
CK_OBJECT_HANDLE object;
|
||||||
CK_ATTRIBUTE attrs[32];
|
CK_ATTRIBUTE attrs[32];
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* First, make sure we have a session */
|
/* First, make sure we have a session */
|
||||||
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
||||||
|
@ -349,7 +337,7 @@ pkcs11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
||||||
|
|
||||||
/* Now build the key attrs */
|
/* Now build the key attrs */
|
||||||
if (pk->type == EVP_PKEY_RSA) {
|
if (pk->type == EVP_PKEY_RSA) {
|
||||||
RSA *rsa = EVP_PKEY_get1_RSA(pk);
|
RSA *rsa = EVP_PKEY_get1_RSA(pk);
|
||||||
|
|
||||||
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PRIVATE_KEY);
|
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PRIVATE_KEY);
|
||||||
pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
|
pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
|
||||||
|
@ -363,8 +351,7 @@ pkcs11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
||||||
if (id && id_len)
|
if (id && id_len)
|
||||||
pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
|
pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
|
||||||
} else {
|
} else {
|
||||||
PKCS11err(PKCS11_F_PKCS11_STORE_PRIVATE_KEY,
|
PKCS11err(PKCS11_F_PKCS11_STORE_PRIVATE_KEY, PKCS11_NOT_SUPPORTED);
|
||||||
PKCS11_NOT_SUPPORTED);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,24 +365,24 @@ pkcs11_store_private_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
||||||
|
|
||||||
/* Gobble the key object */
|
/* Gobble the key object */
|
||||||
return pkcs11_init_key(ctx, token, session, object,
|
return pkcs11_init_key(ctx, token, session, object,
|
||||||
CKO_PRIVATE_KEY, ret_key);
|
CKO_PRIVATE_KEY, ret_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store public key
|
* Store public key
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pkcs11_store_public_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
pkcs11_store_public_key(PKCS11_TOKEN * token, EVP_PKEY * pk, char *label,
|
||||||
unsigned char *id, unsigned int id_len,
|
unsigned char *id, unsigned int id_len,
|
||||||
PKCS11_KEY **ret_key)
|
PKCS11_KEY ** ret_key)
|
||||||
{
|
{
|
||||||
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
||||||
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
PKCS11_CTX *ctx = TOKEN2CTX(token);
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
CK_OBJECT_HANDLE object;
|
CK_OBJECT_HANDLE object;
|
||||||
CK_ATTRIBUTE attrs[32];
|
CK_ATTRIBUTE attrs[32];
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* First, make sure we have a session */
|
/* First, make sure we have a session */
|
||||||
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
||||||
|
@ -404,7 +391,7 @@ pkcs11_store_public_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
||||||
|
|
||||||
/* Now build the key attrs */
|
/* Now build the key attrs */
|
||||||
if (pk->type == EVP_PKEY_RSA) {
|
if (pk->type == EVP_PKEY_RSA) {
|
||||||
RSA *rsa = EVP_PKEY_get1_RSA(pk);
|
RSA *rsa = EVP_PKEY_get1_RSA(pk);
|
||||||
|
|
||||||
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PUBLIC_KEY);
|
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_PUBLIC_KEY);
|
||||||
pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
|
pkcs11_addattr_int(attrs + n++, CKA_KEY_TYPE, CKK_RSA);
|
||||||
|
@ -415,8 +402,7 @@ pkcs11_store_public_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
||||||
if (id && id_len)
|
if (id && id_len)
|
||||||
pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
|
pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
|
||||||
} else {
|
} else {
|
||||||
PKCS11err(PKCS11_F_PKCS11_STORE_PUBLIC_KEY,
|
PKCS11err(PKCS11_F_PKCS11_STORE_PUBLIC_KEY, PKCS11_NOT_SUPPORTED);
|
||||||
PKCS11_NOT_SUPPORTED);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,6 +415,5 @@ pkcs11_store_public_key(PKCS11_TOKEN *token, EVP_PKEY *pk, char *label,
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PUBLIC_KEY, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_STORE_PUBLIC_KEY, rv);
|
||||||
|
|
||||||
/* Gobble the key object */
|
/* Gobble the key object */
|
||||||
return pkcs11_init_key(ctx, token, session,
|
return pkcs11_init_key(ctx, token, session, object, CKO_PUBLIC_KEY, ret_key);
|
||||||
object, CKO_PUBLIC_KEY, ret_key);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,17 +63,16 @@ static void *handle = NULL;
|
||||||
/*
|
/*
|
||||||
* Create a new context
|
* Create a new context
|
||||||
*/
|
*/
|
||||||
PKCS11_CTX *
|
PKCS11_CTX *PKCS11_CTX_new(void)
|
||||||
PKCS11_CTX_new(void)
|
|
||||||
{
|
{
|
||||||
PKCS11_CTX_private *priv;
|
PKCS11_CTX_private *priv;
|
||||||
PKCS11_CTX *ctx;
|
PKCS11_CTX *ctx;
|
||||||
|
|
||||||
/* Load error strings */
|
/* Load error strings */
|
||||||
ERR_load_PKCS11_strings();
|
ERR_load_PKCS11_strings();
|
||||||
|
|
||||||
priv = PKCS11_NEW(PKCS11_CTX_private);
|
priv = PKCS11_NEW(PKCS11_CTX_private);
|
||||||
ctx = PKCS11_NEW(PKCS11_CTX);
|
ctx = PKCS11_NEW(PKCS11_CTX);
|
||||||
ctx->_private = priv;
|
ctx->_private = priv;
|
||||||
|
|
||||||
/* Mark list of slots as "need to fetch from card" */
|
/* Mark list of slots as "need to fetch from card" */
|
||||||
|
@ -85,18 +84,17 @@ PKCS11_CTX_new(void)
|
||||||
/*
|
/*
|
||||||
* Load the shared library, and initialize it.
|
* Load the shared library, and initialize it.
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_CTX_load(PKCS11_CTX * ctx, const char *name)
|
||||||
PKCS11_CTX_load(PKCS11_CTX *ctx, const char *name)
|
|
||||||
{
|
{
|
||||||
PKCS11_CTX_private *priv = PRIVCTX(ctx);
|
PKCS11_CTX_private *priv = PRIVCTX(ctx);
|
||||||
CK_INFO ck_info;
|
CK_INFO ck_info;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (priv->libinfo != NULL) {
|
if (priv->libinfo != NULL) {
|
||||||
PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_MODULE_LOADED_ERROR);
|
PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_MODULE_LOADED_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
handle=C_LoadModule(name, &priv->method );
|
handle = C_LoadModule(name, &priv->method);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_LOAD_MODULE_ERROR);
|
PKCS11err(PKCS11_F_PKCS11_CTX_LOAD, PKCS11_LOAD_MODULE_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -119,11 +117,10 @@ PKCS11_CTX_load(PKCS11_CTX *ctx, const char *name)
|
||||||
/*
|
/*
|
||||||
* Unload the shared library
|
* Unload the shared library
|
||||||
*/
|
*/
|
||||||
void
|
void PKCS11_CTX_unload(PKCS11_CTX * ctx)
|
||||||
PKCS11_CTX_unload(PKCS11_CTX *ctx)
|
|
||||||
{
|
{
|
||||||
PKCS11_CTX_private *priv;
|
PKCS11_CTX_private *priv;
|
||||||
priv= PRIVCTX(ctx);
|
priv = PRIVCTX(ctx);
|
||||||
|
|
||||||
/* Free any slot info we have allocated */
|
/* Free any slot info we have allocated */
|
||||||
pkcs11_destroy_all_slots(ctx);
|
pkcs11_destroy_all_slots(ctx);
|
||||||
|
@ -138,10 +135,9 @@ PKCS11_CTX_unload(PKCS11_CTX *ctx)
|
||||||
/*
|
/*
|
||||||
* Free a context
|
* Free a context
|
||||||
*/
|
*/
|
||||||
void
|
void PKCS11_CTX_free(PKCS11_CTX * ctx)
|
||||||
PKCS11_CTX_free(PKCS11_CTX *ctx)
|
|
||||||
{
|
{
|
||||||
PKCS11_CTX_unload(ctx); /* Make sure */
|
PKCS11_CTX_unload(ctx); /* Make sure */
|
||||||
OPENSSL_free(ctx->manufacturer);
|
OPENSSL_free(ctx->manufacturer);
|
||||||
OPENSSL_free(ctx->description);
|
OPENSSL_free(ctx->description);
|
||||||
OPENSSL_free(ctx->_private);
|
OPENSSL_free(ctx->_private);
|
||||||
|
|
|
@ -59,10 +59,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
|
|
||||||
void *
|
void *pkcs11_malloc(size_t size)
|
||||||
pkcs11_malloc(size_t size)
|
|
||||||
{
|
{
|
||||||
void *p = OPENSSL_malloc(size);
|
void *p = OPENSSL_malloc(size);
|
||||||
memset(p, 0, size);
|
memset(p, 0, size);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -71,14 +70,13 @@ pkcs11_malloc(size_t size)
|
||||||
* so when strduping them we must make sure
|
* so when strduping them we must make sure
|
||||||
* we stop at the end of the buffer, and while we're
|
* we stop at the end of the buffer, and while we're
|
||||||
* at it it's nice to remove the padding */
|
* at it it's nice to remove the padding */
|
||||||
char *
|
char *pkcs11_strdup(char *mem, size_t size)
|
||||||
pkcs11_strdup(char *mem, size_t size)
|
|
||||||
{
|
{
|
||||||
char *res;
|
char *res;
|
||||||
|
|
||||||
while (size && mem[size-1] == ' ')
|
while (size && mem[size - 1] == ' ')
|
||||||
size--;
|
size--;
|
||||||
res = (char *) OPENSSL_malloc(size+1);
|
res = (char *) OPENSSL_malloc(size + 1);
|
||||||
memcpy(res, mem, size);
|
memcpy(res, mem, size);
|
||||||
res[size] = '\0';
|
res[size] = '\0';
|
||||||
return res;
|
return res;
|
||||||
|
@ -87,10 +85,9 @@ pkcs11_strdup(char *mem, size_t size)
|
||||||
/*
|
/*
|
||||||
* Dup memory
|
* Dup memory
|
||||||
*/
|
*/
|
||||||
void *
|
void *memdup(const void *src, size_t size)
|
||||||
memdup(const void *src, size_t size)
|
|
||||||
{
|
{
|
||||||
void *dst;
|
void *dst;
|
||||||
|
|
||||||
dst = malloc(size);
|
dst = malloc(size);
|
||||||
memcpy(dst, src, size);
|
memcpy(dst, src, size);
|
||||||
|
|
|
@ -65,9 +65,9 @@
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
|
|
||||||
static int pkcs11_get_rsa_public(PKCS11_KEY *, EVP_PKEY *);
|
static int pkcs11_get_rsa_public(PKCS11_KEY *, EVP_PKEY *);
|
||||||
static int pkcs11_get_rsa_private(PKCS11_KEY *, EVP_PKEY *);
|
static int pkcs11_get_rsa_private(PKCS11_KEY *, EVP_PKEY *);
|
||||||
RSA_METHOD * pkcs11_get_rsa_method(void);
|
RSA_METHOD *pkcs11_get_rsa_method(void);
|
||||||
|
|
||||||
#define key_getattr(k, t, p, s) \
|
#define key_getattr(k, t, p, s) \
|
||||||
pkcs11_getattr(KEY2TOKEN(key), PRIVKEY(key)->object, t, p, s)
|
pkcs11_getattr(KEY2TOKEN(key), PRIVKEY(key)->object, t, p, s)
|
||||||
|
@ -77,20 +77,19 @@ RSA_METHOD * pkcs11_get_rsa_method(void);
|
||||||
/*
|
/*
|
||||||
* Get RSA key material
|
* Get RSA key material
|
||||||
*/
|
*/
|
||||||
int
|
int pkcs11_get_rsa_private(PKCS11_KEY * key, EVP_PKEY * pk)
|
||||||
pkcs11_get_rsa_private(PKCS11_KEY *key, EVP_PKEY *pk)
|
|
||||||
{
|
{
|
||||||
CK_BBOOL sensitive, extractable;
|
CK_BBOOL sensitive, extractable;
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
|
|
||||||
if (!(rsa = EVP_PKEY_get1_RSA(pk))) {
|
if (!(rsa = EVP_PKEY_get1_RSA(pk))) {
|
||||||
ERR_clear_error(); /* the above flags an error */
|
ERR_clear_error(); /* the above flags an error */
|
||||||
rsa = RSA_new();
|
rsa = RSA_new();
|
||||||
EVP_PKEY_set1_RSA(pk, rsa);
|
EVP_PKEY_set1_RSA(pk, rsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_getattr(key, CKA_SENSITIVE, &sensitive, sizeof(sensitive))
|
if (key_getattr(key, CKA_SENSITIVE, &sensitive, sizeof(sensitive))
|
||||||
|| key_getattr(key, CKA_EXTRACTABLE, &extractable, sizeof(extractable)))
|
|| key_getattr(key, CKA_EXTRACTABLE, &extractable, sizeof(extractable)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!rsa->n && key_getattr_bn(key, CKA_MODULUS, &rsa->n))
|
if (!rsa->n && key_getattr_bn(key, CKA_MODULUS, &rsa->n))
|
||||||
|
@ -112,8 +111,7 @@ pkcs11_get_rsa_private(PKCS11_KEY *key, EVP_PKEY *pk)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int pkcs11_get_rsa_public(PKCS11_KEY * key, EVP_PKEY * pk)
|
||||||
pkcs11_get_rsa_public(PKCS11_KEY *key, EVP_PKEY *pk)
|
|
||||||
{
|
{
|
||||||
/* TBD */
|
/* TBD */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -121,9 +119,9 @@ pkcs11_get_rsa_public(PKCS11_KEY *key, EVP_PKEY *pk)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pkcs11_rsa_decrypt(int flen, const unsigned char *from, unsigned char *to,
|
pkcs11_rsa_decrypt(int flen, const unsigned char *from, unsigned char *to,
|
||||||
RSA *rsa, int padding)
|
RSA * rsa, int padding)
|
||||||
{
|
{
|
||||||
PKCS11_KEY *key = (PKCS11_KEY *) RSA_get_app_data(rsa);
|
PKCS11_KEY *key = (PKCS11_KEY *) RSA_get_app_data(rsa);
|
||||||
|
|
||||||
if (padding != RSA_PKCS1_PADDING)
|
if (padding != RSA_PKCS1_PADDING)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -137,7 +135,7 @@ pkcs11_rsa_decrypt(int flen, const unsigned char *from, unsigned char *to,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pkcs11_rsa_encrypt(int flen, const unsigned char *from, unsigned char *to,
|
pkcs11_rsa_encrypt(int flen, const unsigned char *from, unsigned char *to,
|
||||||
RSA *rsa, int padding)
|
RSA * rsa, int padding)
|
||||||
{
|
{
|
||||||
/* PKCS11 calls go here */
|
/* PKCS11 calls go here */
|
||||||
PKCS11err(PKCS11_F_PKCS11_RSA_ENCRYPT, PKCS11_NOT_SUPPORTED);
|
PKCS11err(PKCS11_F_PKCS11_RSA_ENCRYPT, PKCS11_NOT_SUPPORTED);
|
||||||
|
@ -146,16 +144,16 @@ pkcs11_rsa_encrypt(int flen, const unsigned char *from, unsigned char *to,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
|
pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
|
||||||
unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
|
unsigned char *sigret, unsigned int *siglen, const RSA * rsa)
|
||||||
{
|
{
|
||||||
PKCS11_KEY *key = (PKCS11_KEY *) RSA_get_app_data(rsa);
|
PKCS11_KEY *key = (PKCS11_KEY *) RSA_get_app_data(rsa);
|
||||||
PKCS11_KEY_private *priv;
|
PKCS11_KEY_private *priv;
|
||||||
PKCS11_SLOT *slot;
|
PKCS11_SLOT *slot;
|
||||||
PKCS11_CTX *ctx;
|
PKCS11_CTX *ctx;
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
CK_MECHANISM mechanism;
|
CK_MECHANISM mechanism;
|
||||||
CK_ULONG sigsize;
|
CK_ULONG sigsize;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -175,14 +173,15 @@ pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
|
||||||
* by OpenSSL). The library assumes that the memory passed
|
* by OpenSSL). The library assumes that the memory passed
|
||||||
* by the caller is always big enough */
|
* by the caller is always big enough */
|
||||||
sigsize = BN_num_bytes(rsa->n);
|
sigsize = BN_num_bytes(rsa->n);
|
||||||
rv = CRYPTOKI_call(ctx, C_Sign(session, (CK_BYTE *) m, m_len, sigret, &sigsize));
|
rv = CRYPTOKI_call(ctx,
|
||||||
|
C_Sign(session, (CK_BYTE *) m, m_len, sigret, &sigsize));
|
||||||
if (rv)
|
if (rv)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
*siglen = sigsize;
|
*siglen = sigsize;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
fail: PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
|
fail:PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,10 +193,10 @@ fail: PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
|
pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
|
||||||
unsigned char *signature, unsigned int siglen, const RSA *rsa)
|
unsigned char *signature, unsigned int siglen, const RSA * rsa)
|
||||||
{
|
{
|
||||||
RSA *r = (RSA *) rsa; /* Ugly hack to get rid of compiler warning */
|
RSA *r = (RSA *) rsa; /* Ugly hack to get rid of compiler warning */
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (r->flags & RSA_FLAG_SIGN_VER) {
|
if (r->flags & RSA_FLAG_SIGN_VER) {
|
||||||
r->flags &= ~RSA_FLAG_SIGN_VER;
|
r->flags &= ~RSA_FLAG_SIGN_VER;
|
||||||
|
@ -213,8 +212,7 @@ pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
|
||||||
/*
|
/*
|
||||||
* Overload the default OpenSSL methods for RSA
|
* Overload the default OpenSSL methods for RSA
|
||||||
*/
|
*/
|
||||||
RSA_METHOD *
|
RSA_METHOD *pkcs11_get_rsa_method(void)
|
||||||
pkcs11_get_rsa_method(void)
|
|
||||||
{
|
{
|
||||||
static RSA_METHOD ops;
|
static RSA_METHOD ops;
|
||||||
|
|
||||||
|
@ -222,13 +220,13 @@ pkcs11_get_rsa_method(void)
|
||||||
ops = *RSA_get_default_method();
|
ops = *RSA_get_default_method();
|
||||||
ops.rsa_priv_enc = pkcs11_rsa_encrypt;
|
ops.rsa_priv_enc = pkcs11_rsa_encrypt;
|
||||||
ops.rsa_priv_dec = pkcs11_rsa_decrypt;
|
ops.rsa_priv_dec = pkcs11_rsa_decrypt;
|
||||||
ops.rsa_sign = pkcs11_rsa_sign;
|
ops.rsa_sign = pkcs11_rsa_sign;
|
||||||
ops.rsa_verify = pkcs11_rsa_verify;
|
ops.rsa_verify = pkcs11_rsa_verify;
|
||||||
}
|
}
|
||||||
return &ops;
|
return &ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
PKCS11_KEY_ops pkcs11_rsa_ops = {
|
PKCS11_KEY_ops pkcs11_rsa_ops = {
|
||||||
EVP_PKEY_RSA,
|
EVP_PKEY_RSA,
|
||||||
pkcs11_get_rsa_public,
|
pkcs11_get_rsa_public,
|
||||||
pkcs11_get_rsa_private
|
pkcs11_get_rsa_private
|
||||||
|
|
|
@ -59,31 +59,28 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/buffer.h>
|
#include <openssl/buffer.h>
|
||||||
|
|
||||||
static int pkcs11_init_slot(PKCS11_CTX *, PKCS11_SLOT *, CK_SLOT_ID);
|
static int pkcs11_init_slot(PKCS11_CTX *, PKCS11_SLOT *, CK_SLOT_ID);
|
||||||
static int pkcs11_check_token(PKCS11_CTX *, PKCS11_SLOT *);
|
static int pkcs11_check_token(PKCS11_CTX *, PKCS11_SLOT *);
|
||||||
static void pkcs11_destroy_token(PKCS11_TOKEN *);
|
static void pkcs11_destroy_token(PKCS11_TOKEN *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enumerate slots
|
* Enumerate slots
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
PKCS11_enumerate_slots(PKCS11_CTX *ctx,
|
PKCS11_enumerate_slots(PKCS11_CTX * ctx, PKCS11_SLOT ** slotp, unsigned int *countp)
|
||||||
PKCS11_SLOT **slotp,
|
|
||||||
unsigned int *countp)
|
|
||||||
{
|
{
|
||||||
PKCS11_CTX_private *priv = PRIVCTX(ctx);
|
PKCS11_CTX_private *priv = PRIVCTX(ctx);
|
||||||
|
|
||||||
if (priv->nslots < 0) {
|
if (priv->nslots < 0) {
|
||||||
CK_SLOT_ID slotid[64];
|
CK_SLOT_ID slotid[64];
|
||||||
CK_ULONG nslots = sizeof(slotid), n;
|
CK_ULONG nslots = sizeof(slotid), n;
|
||||||
PKCS11_SLOT *slots;
|
PKCS11_SLOT *slots;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = priv->method->C_GetSlotList(FALSE, slotid, &nslots);
|
rv = priv->method->C_GetSlotList(FALSE, slotid, &nslots);
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
|
||||||
|
|
||||||
slots = (PKCS11_SLOT *) pkcs11_malloc(nslots
|
slots = (PKCS11_SLOT *) pkcs11_malloc(nslots * sizeof(PKCS11_SLOT));
|
||||||
* sizeof(PKCS11_SLOT));
|
|
||||||
for (n = 0; n < nslots; n++) {
|
for (n = 0; n < nslots; n++) {
|
||||||
if (pkcs11_init_slot(ctx, &slots[n], slotid[n])) {
|
if (pkcs11_init_slot(ctx, &slots[n], slotid[n])) {
|
||||||
while (n--)
|
while (n--)
|
||||||
|
@ -104,12 +101,11 @@ PKCS11_enumerate_slots(PKCS11_CTX *ctx,
|
||||||
/*
|
/*
|
||||||
* Find a slot with a token that looks "valuable"
|
* Find a slot with a token that looks "valuable"
|
||||||
*/
|
*/
|
||||||
PKCS11_SLOT *
|
PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX * ctx)
|
||||||
PKCS11_find_token(PKCS11_CTX *ctx)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT *slot_list, *slot, *best;
|
PKCS11_SLOT *slot_list, *slot, *best;
|
||||||
PKCS11_TOKEN *tok;
|
PKCS11_TOKEN *tok;
|
||||||
unsigned int n, nslots;
|
unsigned int n, nslots;
|
||||||
|
|
||||||
if (PKCS11_enumerate_slots(ctx, &slot_list, &nslots))
|
if (PKCS11_enumerate_slots(ctx, &slot_list, &nslots))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -118,9 +114,9 @@ PKCS11_find_token(PKCS11_CTX *ctx)
|
||||||
for (n = 0, slot = slot_list; n < nslots; n++, slot++) {
|
for (n = 0, slot = slot_list; n < nslots; n++, slot++) {
|
||||||
if ((tok = slot->token) != NULL) {
|
if ((tok = slot->token) != NULL) {
|
||||||
if (best == NULL
|
if (best == NULL
|
||||||
|| (tok->initialized > best->token->initialized
|
|| (tok->initialized > best->token->initialized
|
||||||
&& tok->userPinSet > best->token->userPinSet
|
&& tok->userPinSet > best->token->userPinSet
|
||||||
&& tok->loginRequired > best->token->loginRequired))
|
&& tok->loginRequired > best->token->loginRequired))
|
||||||
best = slot;
|
best = slot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,21 +126,21 @@ PKCS11_find_token(PKCS11_CTX *ctx)
|
||||||
/*
|
/*
|
||||||
* Open a session with this slot
|
* Open a session with this slot
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_open_session(PKCS11_SLOT * slot, int rw)
|
||||||
PKCS11_open_session(PKCS11_SLOT *slot, int rw)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
||||||
PKCS11_CTX *ctx = SLOT2CTX(slot);
|
PKCS11_CTX *ctx = SLOT2CTX(slot);
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (priv->haveSession) {
|
if (priv->haveSession) {
|
||||||
CRYPTOKI_call(ctx, C_CloseSession(priv->session));
|
CRYPTOKI_call(ctx, C_CloseSession(priv->session));
|
||||||
priv->haveSession = 0;
|
priv->haveSession = 0;
|
||||||
}
|
}
|
||||||
rv = CRYPTOKI_call(ctx,
|
rv = CRYPTOKI_call(ctx,
|
||||||
C_OpenSession(priv->id,
|
C_OpenSession(priv->id,
|
||||||
CKF_SERIAL_SESSION | (rw? CKF_RW_SESSION : 0),
|
CKF_SERIAL_SESSION | (rw ? CKF_RW_SESSION :
|
||||||
NULL, NULL, &priv->session));
|
0), NULL, NULL,
|
||||||
|
&priv->session));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_OPEN_SESSION, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_OPEN_SESSION, rv);
|
||||||
priv->haveSession = 1;
|
priv->haveSession = 1;
|
||||||
|
|
||||||
|
@ -154,12 +150,11 @@ PKCS11_open_session(PKCS11_SLOT *slot, int rw)
|
||||||
/*
|
/*
|
||||||
* Authenticate with the card
|
* Authenticate with the card
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_login(PKCS11_SLOT * slot, int so, char *pin)
|
||||||
PKCS11_login(PKCS11_SLOT *slot, int so, char *pin)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
||||||
PKCS11_CTX *ctx = priv->parent;
|
PKCS11_CTX *ctx = priv->parent;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* Calling PKCS11_login invalidates all cached
|
/* Calling PKCS11_login invalidates all cached
|
||||||
* keys we have */
|
* keys we have */
|
||||||
|
@ -178,8 +173,8 @@ PKCS11_login(PKCS11_SLOT *slot, int so, char *pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = CRYPTOKI_call(ctx, C_Login(priv->session,
|
rv = CRYPTOKI_call(ctx, C_Login(priv->session,
|
||||||
so? CKU_SO : CKU_USER,
|
so ? CKU_SO : CKU_USER,
|
||||||
(CK_UTF8CHAR *) pin, strlen(pin)));
|
(CK_UTF8CHAR *) pin, strlen(pin)));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv);
|
||||||
priv->loggedIn = 1;
|
priv->loggedIn = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -188,12 +183,11 @@ PKCS11_login(PKCS11_SLOT *slot, int so, char *pin)
|
||||||
/*
|
/*
|
||||||
* Log out
|
* Log out
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_logout(PKCS11_SLOT * slot)
|
||||||
PKCS11_logout(PKCS11_SLOT *slot)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
||||||
PKCS11_CTX *ctx = priv->parent;
|
PKCS11_CTX *ctx = priv->parent;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
/* Calling PKCS11_logout invalidates all cached
|
/* Calling PKCS11_logout invalidates all cached
|
||||||
* keys we have */
|
* keys we have */
|
||||||
|
@ -213,18 +207,18 @@ PKCS11_logout(PKCS11_SLOT *slot)
|
||||||
/*
|
/*
|
||||||
* Initialize the token
|
* Initialize the token
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_init_token(PKCS11_TOKEN * token, char *pin, char *label)
|
||||||
PKCS11_init_token(PKCS11_TOKEN *token, char *pin, char *label)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token));
|
PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token));
|
||||||
PKCS11_CTX_private *cpriv;
|
PKCS11_CTX_private *cpriv;
|
||||||
PKCS11_CTX *ctx = priv->parent;
|
PKCS11_CTX *ctx = priv->parent;
|
||||||
int n, rv;
|
int n, rv;
|
||||||
|
|
||||||
if (!label)
|
if (!label)
|
||||||
label = "PKCS#11 Token";
|
label = "PKCS#11 Token";
|
||||||
rv = CRYPTOKI_call(ctx, C_InitToken(priv->id,
|
rv = CRYPTOKI_call(ctx, C_InitToken(priv->id,
|
||||||
(CK_UTF8CHAR *) pin, strlen(pin), (CK_UTF8CHAR *) label));
|
(CK_UTF8CHAR *) pin, strlen(pin),
|
||||||
|
(CK_UTF8CHAR *) label));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_TOKEN, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_TOKEN, rv);
|
||||||
|
|
||||||
cpriv = PRIVCTX(ctx);
|
cpriv = PRIVCTX(ctx);
|
||||||
|
@ -239,19 +233,18 @@ PKCS11_init_token(PKCS11_TOKEN *token, char *pin, char *label)
|
||||||
/*
|
/*
|
||||||
* Set the User PIN
|
* Set the User PIN
|
||||||
*/
|
*/
|
||||||
int
|
int PKCS11_init_pin(PKCS11_TOKEN * token, char *pin)
|
||||||
PKCS11_init_pin(PKCS11_TOKEN *token, char *pin)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token));
|
PKCS11_SLOT_private *priv = PRIVSLOT(TOKEN2SLOT(token));
|
||||||
PKCS11_CTX *ctx = priv->parent;
|
PKCS11_CTX *ctx = priv->parent;
|
||||||
int len, rv;
|
int len, rv;
|
||||||
|
|
||||||
if (!priv->haveSession) {
|
if (!priv->haveSession) {
|
||||||
PKCS11err(PKCS11_F_PKCS11_INIT_PIN, PKCS11_NO_SESSION);
|
PKCS11err(PKCS11_F_PKCS11_INIT_PIN, PKCS11_NO_SESSION);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = pin? strlen(pin) : 0;
|
len = pin ? strlen(pin) : 0;
|
||||||
rv = CRYPTOKI_call(ctx, C_InitPIN(priv->session, (CK_UTF8CHAR *) pin, len));
|
rv = CRYPTOKI_call(ctx, C_InitPIN(priv->session, (CK_UTF8CHAR *) pin, len));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_PIN, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_INIT_PIN, rv);
|
||||||
|
|
||||||
|
@ -261,12 +254,11 @@ PKCS11_init_pin(PKCS11_TOKEN *token, char *pin)
|
||||||
/*
|
/*
|
||||||
* Helper functions
|
* Helper functions
|
||||||
*/
|
*/
|
||||||
int
|
int pkcs11_init_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot, CK_SLOT_ID id)
|
||||||
pkcs11_init_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot, CK_SLOT_ID id)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv;
|
PKCS11_SLOT_private *priv;
|
||||||
CK_SLOT_INFO info;
|
CK_SLOT_INFO info;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = CRYPTOKI_call(ctx, C_GetSlotInfo(id, &info));
|
rv = CRYPTOKI_call(ctx, C_GetSlotInfo(id, &info));
|
||||||
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
|
CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_SLOTS, rv);
|
||||||
|
@ -277,7 +269,7 @@ pkcs11_init_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot, CK_SLOT_ID id)
|
||||||
|
|
||||||
slot->description = PKCS11_DUP(info.slotDescription);
|
slot->description = PKCS11_DUP(info.slotDescription);
|
||||||
slot->manufacturer = PKCS11_DUP(info.manufacturerID);
|
slot->manufacturer = PKCS11_DUP(info.manufacturerID);
|
||||||
slot->removable = (info.flags & CKF_REMOVABLE_DEVICE)? 1 : 0;
|
slot->removable = (info.flags & CKF_REMOVABLE_DEVICE) ? 1 : 0;
|
||||||
slot->_private = priv;
|
slot->_private = priv;
|
||||||
|
|
||||||
if ((info.flags & CKF_TOKEN_PRESENT) && pkcs11_check_token(ctx, slot))
|
if ((info.flags & CKF_TOKEN_PRESENT) && pkcs11_check_token(ctx, slot))
|
||||||
|
@ -286,8 +278,7 @@ pkcs11_init_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot, CK_SLOT_ID id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_destroy_all_slots(PKCS11_CTX * ctx)
|
||||||
pkcs11_destroy_all_slots(PKCS11_CTX *ctx)
|
|
||||||
{
|
{
|
||||||
PKCS11_CTX_private *priv = PRIVCTX(ctx);
|
PKCS11_CTX_private *priv = PRIVCTX(ctx);
|
||||||
|
|
||||||
|
@ -298,8 +289,7 @@ pkcs11_destroy_all_slots(PKCS11_CTX *ctx)
|
||||||
priv->nslots = -1;
|
priv->nslots = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_destroy_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot)
|
||||||
pkcs11_destroy_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
||||||
|
|
||||||
|
@ -314,14 +304,13 @@ pkcs11_destroy_slot(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
|
||||||
memset(slot, 0, sizeof(*slot));
|
memset(slot, 0, sizeof(*slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int pkcs11_check_token(PKCS11_CTX * ctx, PKCS11_SLOT * slot)
|
||||||
pkcs11_check_token(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
|
|
||||||
{
|
{
|
||||||
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
PKCS11_SLOT_private *priv = PRIVSLOT(slot);
|
||||||
PKCS11_TOKEN_private *tpriv;
|
PKCS11_TOKEN_private *tpriv;
|
||||||
CK_TOKEN_INFO info;
|
CK_TOKEN_INFO info;
|
||||||
PKCS11_TOKEN *token;
|
PKCS11_TOKEN *token;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (slot->token)
|
if (slot->token)
|
||||||
pkcs11_destroy_token(slot->token);
|
pkcs11_destroy_token(slot->token);
|
||||||
|
@ -346,17 +335,16 @@ pkcs11_check_token(PKCS11_CTX *ctx, PKCS11_SLOT *slot)
|
||||||
token->label = PKCS11_DUP(info.label);
|
token->label = PKCS11_DUP(info.label);
|
||||||
token->manufacturer = PKCS11_DUP(info.manufacturerID);
|
token->manufacturer = PKCS11_DUP(info.manufacturerID);
|
||||||
token->model = PKCS11_DUP(info.model);
|
token->model = PKCS11_DUP(info.model);
|
||||||
token->initialized = (info.flags & CKF_TOKEN_INITIALIZED)? 1 : 0;
|
token->initialized = (info.flags & CKF_TOKEN_INITIALIZED) ? 1 : 0;
|
||||||
token->loginRequired = (info.flags & CKF_LOGIN_REQUIRED)? 1 : 0;
|
token->loginRequired = (info.flags & CKF_LOGIN_REQUIRED) ? 1 : 0;
|
||||||
token->userPinSet = (info.flags & CKF_USER_PIN_INITIALIZED)? 1 : 0;
|
token->userPinSet = (info.flags & CKF_USER_PIN_INITIALIZED) ? 1 : 0;
|
||||||
token->readOnly = (info.flags & CKF_WRITE_PROTECTED)? 1 : 0;
|
token->readOnly = (info.flags & CKF_WRITE_PROTECTED) ? 1 : 0;
|
||||||
token->_private = tpriv;
|
token->_private = tpriv;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void pkcs11_destroy_token(PKCS11_TOKEN * token)
|
||||||
pkcs11_destroy_token(PKCS11_TOKEN *token)
|
|
||||||
{
|
{
|
||||||
/* XXX destroy keys associated with this token */
|
/* XXX destroy keys associated with this token */
|
||||||
OPENSSL_free(token->label);
|
OPENSSL_free(token->label);
|
||||||
|
|
|
@ -87,108 +87,97 @@ ERR_PUT_error(ERR_LIB_PKCS11,(f),(r),__FILE__,__LINE__)
|
||||||
*
|
*
|
||||||
* - no support for any operations that alter the card,
|
* - no support for any operations that alter the card,
|
||||||
* i.e. readonly-login
|
* i.e. readonly-login
|
||||||
*
|
|
||||||
* Rather than include the complete PKCS#11 type definition
|
|
||||||
* header file here, I'm defining my own bunch of types,
|
|
||||||
* leaving out those that are not needed.
|
|
||||||
* I also hope that they will be more in line with OpenSSL
|
|
||||||
* coding style.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* PKCS11 key object (public or private) */
|
/* PKCS11 key object (public or private) */
|
||||||
typedef struct PKCS11_key_st {
|
typedef struct PKCS11_key_st {
|
||||||
char * label;
|
char *label;
|
||||||
unsigned char * id;
|
unsigned char *id;
|
||||||
int id_len;
|
int id_len;
|
||||||
unsigned char isPrivate; /* private key present? */
|
unsigned char isPrivate; /* private key present? */
|
||||||
unsigned char needLogin; /* login to read private key? */
|
unsigned char needLogin; /* login to read private key? */
|
||||||
EVP_PKEY * evp_key; /* initially NULL, need to call PKCS11_load_key */
|
EVP_PKEY *evp_key; /* initially NULL, need to call PKCS11_load_key */
|
||||||
void * _private;
|
void *_private;
|
||||||
} PKCS11_KEY;
|
} PKCS11_KEY;
|
||||||
|
|
||||||
/* PKCS11 certificate object */
|
/* PKCS11 certificate object */
|
||||||
typedef struct PKCS11_cert_st {
|
typedef struct PKCS11_cert_st {
|
||||||
char * label;
|
char *label;
|
||||||
unsigned char * id;
|
unsigned char *id;
|
||||||
int id_len;
|
int id_len;
|
||||||
X509 * x509;
|
X509 *x509;
|
||||||
void * _private;
|
void *_private;
|
||||||
} PKCS11_CERT;
|
} PKCS11_CERT;
|
||||||
|
|
||||||
/* PKCS11 token, e.g. smart card or USB key */
|
/* PKCS11 token, e.g. smart card or USB key */
|
||||||
typedef struct PKCS11_token_st {
|
typedef struct PKCS11_token_st {
|
||||||
char * label;
|
char *label;
|
||||||
char * manufacturer;
|
char *manufacturer;
|
||||||
char * model;
|
char *model;
|
||||||
unsigned char initialized;
|
unsigned char initialized;
|
||||||
unsigned char loginRequired;
|
unsigned char loginRequired;
|
||||||
unsigned char userPinSet;
|
unsigned char userPinSet;
|
||||||
unsigned char readOnly;
|
unsigned char readOnly;
|
||||||
void * _private;
|
void *_private;
|
||||||
} PKCS11_TOKEN;
|
} PKCS11_TOKEN;
|
||||||
|
|
||||||
/* PKCS11 slot, e.g. card reader */
|
/* PKCS11 slot, e.g. card reader */
|
||||||
typedef struct PKCS11_slot_st {
|
typedef struct PKCS11_slot_st {
|
||||||
char * manufacturer;
|
char *manufacturer;
|
||||||
char * description;
|
char *description;
|
||||||
unsigned char removable;
|
unsigned char removable;
|
||||||
PKCS11_TOKEN * token; /* NULL if no token present */
|
PKCS11_TOKEN *token; /* NULL if no token present */
|
||||||
void * _private;
|
void *_private;
|
||||||
} PKCS11_SLOT;
|
} PKCS11_SLOT;
|
||||||
|
|
||||||
typedef struct PKCS11_ctx_st {
|
typedef struct PKCS11_ctx_st {
|
||||||
char * manufacturer;
|
char *manufacturer;
|
||||||
char * description;
|
char *description;
|
||||||
void * _private;
|
void *_private;
|
||||||
} PKCS11_CTX;
|
} PKCS11_CTX;
|
||||||
|
|
||||||
extern PKCS11_CTX * PKCS11_CTX_new(void);
|
extern PKCS11_CTX *PKCS11_CTX_new(void);
|
||||||
extern int PKCS11_CTX_load(PKCS11_CTX *, const char *ident);
|
extern int PKCS11_CTX_load(PKCS11_CTX *, const char *ident);
|
||||||
extern void PKCS11_CTX_unload(PKCS11_CTX *);
|
extern void PKCS11_CTX_unload(PKCS11_CTX *);
|
||||||
extern void PKCS11_CTX_free(PKCS11_CTX *);
|
extern void PKCS11_CTX_free(PKCS11_CTX *);
|
||||||
|
|
||||||
/* Get a list of all slots */
|
/* Get a list of all slots */
|
||||||
extern int PKCS11_enumerate_slots(PKCS11_CTX *, PKCS11_SLOT **, unsigned int *);
|
extern int PKCS11_enumerate_slots(PKCS11_CTX *, PKCS11_SLOT **, unsigned int *);
|
||||||
|
|
||||||
/* Find the first slot with a token */
|
/* Find the first slot with a token */
|
||||||
extern PKCS11_SLOT * PKCS11_find_token(PKCS11_CTX *);
|
extern PKCS11_SLOT *PKCS11_find_token(PKCS11_CTX *);
|
||||||
|
|
||||||
/* Authenticate to the card */
|
/* Authenticate to the card */
|
||||||
extern int PKCS11_login(PKCS11_SLOT *, int so, char *pin);
|
extern int PKCS11_login(PKCS11_SLOT *, int so, char *pin);
|
||||||
extern int PKCS11_logout(PKCS11_SLOT *);
|
extern int PKCS11_logout(PKCS11_SLOT *);
|
||||||
|
|
||||||
/* Get a list of all keys associated with this token */
|
/* Get a list of all keys associated with this token */
|
||||||
extern int PKCS11_enumerate_keys(PKCS11_TOKEN *,
|
extern int PKCS11_enumerate_keys(PKCS11_TOKEN *, PKCS11_KEY **, unsigned int *);
|
||||||
PKCS11_KEY **, unsigned int *);
|
|
||||||
|
|
||||||
/* Get the key type (as EVP_PKEY_XXX) */
|
/* Get the key type (as EVP_PKEY_XXX) */
|
||||||
extern int PKCS11_get_key_type(PKCS11_KEY *);
|
extern int PKCS11_get_key_type(PKCS11_KEY *);
|
||||||
|
|
||||||
/* Get the enveloped private key */
|
/* Get the enveloped private key */
|
||||||
extern EVP_PKEY * PKCS11_get_private_key(PKCS11_KEY *);
|
extern EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *);
|
||||||
|
|
||||||
/* Find the corresponding certificate (if any) */
|
/* Find the corresponding certificate (if any) */
|
||||||
extern PKCS11_CERT * PKCS11_find_certificate(PKCS11_KEY *);
|
extern PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *);
|
||||||
|
|
||||||
/* Get a list of all certificates associated with this token */
|
/* Get a list of all certificates associated with this token */
|
||||||
extern int PKCS11_enumerate_certs(PKCS11_TOKEN *,
|
extern int PKCS11_enumerate_certs(PKCS11_TOKEN *, PKCS11_CERT **, unsigned int *);
|
||||||
PKCS11_CERT **, unsigned int *);
|
|
||||||
|
|
||||||
/* Initialize a token */
|
/* Initialize a token */
|
||||||
extern int PKCS11_init_token(PKCS11_TOKEN *,
|
extern int PKCS11_init_token(PKCS11_TOKEN *, char *pin, char *label);
|
||||||
char *pin, char *label);
|
|
||||||
|
|
||||||
/* Initialize the user PIN on a token */
|
/* Initialize the user PIN on a token */
|
||||||
extern int PKCS11_init_pin(PKCS11_TOKEN *, char *pin);
|
extern int PKCS11_init_pin(PKCS11_TOKEN *, char *pin);
|
||||||
|
|
||||||
/* Store various objects on the token */
|
/* Store various objects on the token */
|
||||||
extern int PKCS11_generate_key(PKCS11_TOKEN *, int,
|
extern int PKCS11_generate_key(PKCS11_TOKEN *, int, unsigned int, char *);
|
||||||
unsigned int, char *);
|
extern int PKCS11_store_private_key(PKCS11_TOKEN *, EVP_PKEY *, char *);
|
||||||
extern int PKCS11_store_private_key(PKCS11_TOKEN *,
|
|
||||||
EVP_PKEY *, char *);
|
|
||||||
|
|
||||||
/* Load PKCS11 error strings */
|
/* Load PKCS11 error strings */
|
||||||
extern void ERR_load_PKCS11_strings(void);
|
extern void ERR_load_PKCS11_strings(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function and reason codes
|
* Function and reason codes
|
||||||
|
@ -228,49 +217,48 @@ extern void ERR_load_PKCS11_strings(void);
|
||||||
* PKCS11_CTX: context for a PKCS11 implementation
|
* PKCS11_CTX: context for a PKCS11 implementation
|
||||||
*/
|
*/
|
||||||
typedef struct pkcs11_ctx_private {
|
typedef struct pkcs11_ctx_private {
|
||||||
char * name;
|
char *name;
|
||||||
void * libinfo;
|
void *libinfo;
|
||||||
CK_FUNCTION_LIST_PTR method;
|
CK_FUNCTION_LIST_PTR method;
|
||||||
|
|
||||||
CK_SESSION_HANDLE session;
|
CK_SESSION_HANDLE session;
|
||||||
int nslots;
|
int nslots;
|
||||||
PKCS11_SLOT * slots;
|
PKCS11_SLOT *slots;
|
||||||
} PKCS11_CTX_private;
|
} PKCS11_CTX_private;
|
||||||
#define PRIVCTX(ctx) ((PKCS11_CTX_private *) (ctx->_private))
|
#define PRIVCTX(ctx) ((PKCS11_CTX_private *) (ctx->_private))
|
||||||
|
|
||||||
typedef struct pkcs11_slot_private {
|
typedef struct pkcs11_slot_private {
|
||||||
PKCS11_CTX * parent;
|
PKCS11_CTX *parent;
|
||||||
unsigned char haveSession,
|
unsigned char haveSession, loggedIn;
|
||||||
loggedIn;
|
CK_SLOT_ID id;
|
||||||
CK_SLOT_ID id;
|
CK_SESSION_HANDLE session;
|
||||||
CK_SESSION_HANDLE session;
|
|
||||||
} PKCS11_SLOT_private;
|
} PKCS11_SLOT_private;
|
||||||
#define PRIVSLOT(slot) ((PKCS11_SLOT_private *) (slot->_private))
|
#define PRIVSLOT(slot) ((PKCS11_SLOT_private *) (slot->_private))
|
||||||
#define SLOT2CTX(slot) (PRIVSLOT(slot)->parent)
|
#define SLOT2CTX(slot) (PRIVSLOT(slot)->parent)
|
||||||
|
|
||||||
typedef struct pkcs11_token_private {
|
typedef struct pkcs11_token_private {
|
||||||
PKCS11_SLOT * parent;
|
PKCS11_SLOT *parent;
|
||||||
int nkeys, nprkeys;
|
int nkeys, nprkeys;
|
||||||
PKCS11_KEY * keys;
|
PKCS11_KEY *keys;
|
||||||
int ncerts;
|
int ncerts;
|
||||||
PKCS11_CERT * certs;
|
PKCS11_CERT *certs;
|
||||||
} PKCS11_TOKEN_private;
|
} PKCS11_TOKEN_private;
|
||||||
#define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) (token->_private))
|
#define PRIVTOKEN(token) ((PKCS11_TOKEN_private *) (token->_private))
|
||||||
#define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent)
|
#define TOKEN2SLOT(token) (PRIVTOKEN(token)->parent)
|
||||||
#define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token))
|
#define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token))
|
||||||
|
|
||||||
typedef struct pkcs11_key_ops {
|
typedef struct pkcs11_key_ops {
|
||||||
int type; /* EVP_PKEY_xxx */
|
int type; /* EVP_PKEY_xxx */
|
||||||
int (*get_public)(PKCS11_KEY *, EVP_PKEY *);
|
int (*get_public) (PKCS11_KEY *, EVP_PKEY *);
|
||||||
int (*get_private)(PKCS11_KEY *, EVP_PKEY *);
|
int (*get_private) (PKCS11_KEY *, EVP_PKEY *);
|
||||||
} PKCS11_KEY_ops;
|
} PKCS11_KEY_ops;
|
||||||
|
|
||||||
typedef struct pkcs11_key_private {
|
typedef struct pkcs11_key_private {
|
||||||
PKCS11_TOKEN * parent;
|
PKCS11_TOKEN *parent;
|
||||||
CK_OBJECT_HANDLE object;
|
CK_OBJECT_HANDLE object;
|
||||||
unsigned char id[32];
|
unsigned char id[32];
|
||||||
size_t id_len;
|
size_t id_len;
|
||||||
PKCS11_KEY_ops * ops;
|
PKCS11_KEY_ops *ops;
|
||||||
} PKCS11_KEY_private;
|
} PKCS11_KEY_private;
|
||||||
#define PRIVKEY(key) ((PKCS11_KEY_private *) key->_private)
|
#define PRIVKEY(key) ((PKCS11_KEY_private *) key->_private)
|
||||||
#define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key))
|
#define KEY2SLOT(key) TOKEN2SLOT(KEY2TOKEN(key))
|
||||||
|
@ -278,10 +266,10 @@ typedef struct pkcs11_key_private {
|
||||||
#define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key))
|
#define KEY2CTX(key) TOKEN2CTX(KEY2TOKEN(key))
|
||||||
|
|
||||||
typedef struct pkcs11_cert_private {
|
typedef struct pkcs11_cert_private {
|
||||||
PKCS11_TOKEN * parent;
|
PKCS11_TOKEN *parent;
|
||||||
CK_OBJECT_HANDLE object;
|
CK_OBJECT_HANDLE object;
|
||||||
unsigned char id[32];
|
unsigned char id[32];
|
||||||
size_t id_len;
|
size_t id_len;
|
||||||
} PKCS11_CERT_private;
|
} PKCS11_CERT_private;
|
||||||
#define PRIVCERT(cert) ((PKCS11_CERT_private *) cert->_private)
|
#define PRIVCERT(cert) ((PKCS11_CERT_private *) cert->_private)
|
||||||
|
|
||||||
|
@ -311,35 +299,34 @@ typedef struct pkcs11_cert_private {
|
||||||
#define PKCS11_DUP(s) \
|
#define PKCS11_DUP(s) \
|
||||||
pkcs11_strdup((char *) s, sizeof(s))
|
pkcs11_strdup((char *) s, sizeof(s))
|
||||||
|
|
||||||
extern int PKCS11_open_session(PKCS11_SLOT *, int);
|
extern int PKCS11_open_session(PKCS11_SLOT *, int);
|
||||||
extern void pkcs11_destroy_all_slots(PKCS11_CTX *);
|
extern void pkcs11_destroy_all_slots(PKCS11_CTX *);
|
||||||
extern void pkcs11_destroy_slot(PKCS11_CTX *, PKCS11_SLOT *);
|
extern void pkcs11_destroy_slot(PKCS11_CTX *, PKCS11_SLOT *);
|
||||||
extern void pkcs11_destroy_keys(PKCS11_TOKEN *);
|
extern void pkcs11_destroy_keys(PKCS11_TOKEN *);
|
||||||
extern void pkcs11_destroy_certs(PKCS11_TOKEN *);
|
extern void pkcs11_destroy_certs(PKCS11_TOKEN *);
|
||||||
extern void * pkcs11_malloc(size_t);
|
extern void *pkcs11_malloc(size_t);
|
||||||
extern char * pkcs11_strdup(char *, size_t);
|
extern char *pkcs11_strdup(char *, size_t);
|
||||||
|
|
||||||
extern int pkcs11_getattr(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
extern int pkcs11_getattr(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||||
unsigned int, void *, size_t);
|
unsigned int, void *, size_t);
|
||||||
extern int pkcs11_getattr_s(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
extern int pkcs11_getattr_s(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||||
unsigned int, void *, size_t);
|
unsigned int, void *, size_t);
|
||||||
extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||||
unsigned int, void *, size_t *);
|
unsigned int, void *, size_t *);
|
||||||
extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE,
|
||||||
unsigned int, BIGNUM **);
|
unsigned int, BIGNUM **);
|
||||||
|
|
||||||
typedef int (*pkcs11_i2d_fn)(void *, unsigned char **);
|
typedef int (*pkcs11_i2d_fn) (void *, unsigned char **);
|
||||||
extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t);
|
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_int(CK_ATTRIBUTE_PTR, int, unsigned long);
|
||||||
extern void pkcs11_addattr_s(CK_ATTRIBUTE_PTR, int, const char *);
|
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_bn(CK_ATTRIBUTE_PTR, int, const BIGNUM *);
|
||||||
extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int,
|
extern void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR, int, pkcs11_i2d_fn, void *);
|
||||||
pkcs11_i2d_fn, void *);
|
extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int);
|
||||||
extern void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR, unsigned int);
|
|
||||||
|
|
||||||
extern void * memdup(const void *, size_t);
|
extern void *memdup(const void *, size_t);
|
||||||
|
|
||||||
extern PKCS11_KEY_ops pkcs11_rsa_ops;
|
extern PKCS11_KEY_ops pkcs11_rsa_ops;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue