Added support for SLOT_ID engine config command. The engine will init as

it used to, scanning all PKCS11 tokens and creating a linked list of
available tokens. During this process, the engine will now keep a
per-token list of implemented NIDs (mechanisms) instead of one global
list of all NIDs implemented. Once the engine receives the SLOT_ID
command identifying the PKCS11 slot to use, a global pointer to a
specific _token structure is created that identifies the token the
engine will use. Leaving out a SLOT_ID command from the engine's config
will now produce errors.

Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
master
Kent Yoder 12 years ago
parent bb78e43fb2
commit daa3fc26b4

@ -17,6 +17,7 @@ engines = engine_section
ibmpkcs11 = ibmpkcs11_section
[ibmpkcs11_section]
SLOT_ID=0
dynamic_path = @LIBDIR@/libibmpkcs11.so
engine_id = ibmpkcs11
#default_algorithms = ALL

@ -142,15 +142,9 @@ static int pkcs11_engine_ciphers(ENGINE * e, const EVP_CIPHER ** cipher,
static int pkcs11_engine_digests(ENGINE * e, const EVP_MD ** digest,
const int **nids, int nid);
/* Number of NID's that exist in OpenSSL 1.0.0a */
#define NUM_NID 893
int pkcs11_implemented_ciphers[NUM_NID] = { 0, };
int pkcs11_implemented_digests[NUM_NID] = { 0, };
pid_t mypid = -1;
/* The definitions for control commands specific to this engine */
#define PKCS11_CMD_SO_PATH ENGINE_CMD_BASE
#define PKCS11_CMD_SLOT_ID (ENGINE_CMD_BASE + 1)
static const ENGINE_CMD_DEFN pkcs11_cmd_defns[] =
{
{ PKCS11_CMD_SO_PATH,
@ -158,11 +152,14 @@ static const ENGINE_CMD_DEFN pkcs11_cmd_defns[] =
"Specifies the path to the 'pkcs#11' shared library",
ENGINE_CMD_FLAG_STRING
},
{ PKCS11_CMD_SLOT_ID,
"SLOT_ID",
"Specifies the slot containing the token to use",
ENGINE_CMD_FLAG_NUMERIC
},
{0, NULL, NULL, 0}
};
#ifdef OPENSSL_NO_DYNAMIC_ENGINE
static ENGINE *engine_pkcs11(void)
{
@ -626,14 +623,19 @@ void pkcs11_atfork_init(void)
struct token_session *pkcs11_getSession(void)
{
CK_RV rv;
struct token_session *wrapper = OPENSSL_malloc(sizeof (struct token_session));
struct token_session *wrapper;
if (!pkcs11_token) {
PKCS11err(PKCS11_F_GETSESSION, PKCS11_R_NO_SLOT_SELECTED);
return NULL;
}
wrapper = OPENSSL_malloc(sizeof (struct token_session));
if (!wrapper) {
PKCS11err(PKCS11_F_GETSESSION, PKCS11_R_MALLOC_FAILURE);
return NULL;
}
wrapper->token = pkcs11_token_list;
wrapper->token = pkcs11_token;
if (!PKCS11_Initialized) {
rv = pFunctionList->C_Initialize(NULL);
@ -644,7 +646,7 @@ struct token_session *pkcs11_getSession(void)
PKCS11_Initialized = 1;
}
rv = pFunctionList->C_OpenSession(wrapper->token->slot,
rv = pFunctionList->C_OpenSession(wrapper->token->slot_id,
CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL_PTR,
NULL_PTR,
@ -755,7 +757,14 @@ static int
get_pkcs11_ciphers(const int **retnids)
{
static int nids[PKCS11_MAX_ALGS];
int i, count = 0;
int i, count = 0, *pkcs11_implemented_ciphers;
if (pkcs11_token)
pkcs11_implemented_ciphers = pkcs11_token->pkcs11_implemented_ciphers;
else {
PKCS11err(PKCS11_F_GET_PKCS11_CIPHERS, PKCS11_R_NO_SLOT_SELECTED);
return 0;
}
memset(nids, 0, sizeof(nids));
*retnids = NULL;
@ -774,7 +783,14 @@ static int
get_pkcs11_digests(const int **retnids)
{
static int nids[PKCS11_MAX_ALGS];
int i, count = 0;
int i, count = 0, *pkcs11_implemented_digests;
if (pkcs11_token)
pkcs11_implemented_digests = pkcs11_token->pkcs11_implemented_digests;
else {
PKCS11err(PKCS11_F_GET_PKCS11_DIGESTS, PKCS11_R_NO_SLOT_SELECTED);
return 0;
}
memset(nids, 0, sizeof(nids));
*retnids = NULL;
@ -799,10 +815,15 @@ static int pkcs11_engine_ciphers(ENGINE * e, const EVP_CIPHER ** cipher,
if (!cipher)
return get_pkcs11_ciphers(nids);
if (!pkcs11_token) {
PKCS11err(PKCS11_F_ENGINE_CIPHERS, PKCS11_R_NO_SLOT_SELECTED);
return 0;
}
/* If the algorithm requested was not added to the list at
* engine init time, don't return a reference to that structure.
*/
if (pkcs11_implemented_ciphers[nid]) {
if (pkcs11_token->pkcs11_implemented_ciphers[nid]) {
switch (nid) {
case NID_aes_128_ecb:
*cipher = &pkcs11_aes_128_ecb;
@ -845,11 +866,15 @@ static int pkcs11_engine_ciphers(ENGINE * e, const EVP_CIPHER ** cipher,
static int pkcs11_engine_digests(ENGINE * e, const EVP_MD ** digest,
const int **nids, int nid)
{
if (!digest)
return get_pkcs11_digests(nids);
if (pkcs11_implemented_digests[nid]) {
if (!pkcs11_token) {
PKCS11err(PKCS11_F_ENGINE_DIGESTS, PKCS11_R_NO_SLOT_SELECTED);
return 0;
}
if (pkcs11_token->pkcs11_implemented_digests[nid]) {
switch (nid) {
case NID_ripemd160:
*digest = &pkcs11_ripemd;
@ -898,7 +923,7 @@ static long set_PKCS11_LIBNAME(const char *name)
}
/* Add new NID's based on this slot's token */
void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
void pkcs11_regToken(ENGINE *e, struct _token *tok)
{
CK_RV rv;
CK_ULONG mech_cnt;
@ -907,7 +932,10 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
DBG_fprintf("%s\n", __FUNCTION__);
rv = pFunctionList->C_GetMechanismList(slot_id, NULL_PTR, &mech_cnt);
if (!tok)
return;
rv = pFunctionList->C_GetMechanismList(tok->slot_id, NULL_PTR, &mech_cnt);
if (rv != CKR_OK) {
pkcs11_die(PKCS11_F_ADDTOKEN, PKCS11_R_GETMECHANISMLIST, rv);
goto err;
@ -920,7 +948,7 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
goto err;
}
rv = pFunctionList->C_GetMechanismList(slot_id, mech_list, &mech_cnt);
rv = pFunctionList->C_GetMechanismList(tok->slot_id, mech_list, &mech_cnt);
if (rv != CKR_OK) {
pkcs11_die(PKCS11_F_ADDTOKEN, PKCS11_R_GETMECHANISMLIST, rv);
goto err_free;
@ -953,12 +981,12 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
case CKM_X9_42_DH_PARAMETER_GEN:
break;
case CKM_DES_ECB:
pkcs11_implemented_ciphers[NID_des_ecb] = 1;
tok->pkcs11_implemented_ciphers[NID_des_ecb] = 1;
num_cipher_nids++;
break;
case CKM_DES_CBC:
case CKM_DES_CBC_PAD:
pkcs11_implemented_ciphers[NID_des_cbc] = 1;
tok->pkcs11_implemented_ciphers[NID_des_cbc] = 1;
num_cipher_nids++;
break;
case CKM_DES_KEY_GEN:
@ -966,12 +994,12 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
case CKM_DES_MAC_GENERAL:
break;
case CKM_DES3_ECB:
pkcs11_implemented_ciphers[NID_des_ede3_ecb] = 1;
tok->pkcs11_implemented_ciphers[NID_des_ede3_ecb] = 1;
num_cipher_nids++;
break;
case CKM_DES3_CBC:
case CKM_DES3_CBC_PAD:
pkcs11_implemented_ciphers[NID_des_ede3_cbc] = 1;
tok->pkcs11_implemented_ciphers[NID_des_ede3_cbc] = 1;
num_cipher_nids++;
break;
case CKM_DES3_KEY_GEN:
@ -979,81 +1007,81 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
case CKM_DES3_MAC_GENERAL:
break;
case CKM_SHA_1:
pkcs11_implemented_digests[NID_sha1] = 1;
tok->pkcs11_implemented_digests[NID_sha1] = 1;
num_digest_nids++;
break;
case CKM_SHA_1_HMAC:
case CKM_SHA_1_HMAC_GENERAL:
pkcs11_implemented_digests[NID_hmacWithSHA1] = 1;
tok->pkcs11_implemented_digests[NID_hmacWithSHA1] = 1;
num_digest_nids++;
break;
case CKM_PBA_SHA1_WITH_SHA1_HMAC:
case CKM_SHA1_KEY_DERIVATION:
case CKM_SHA1_RSA_PKCS:
pkcs11_implemented_digests[NID_sha1WithRSAEncryption] = 1;
tok->pkcs11_implemented_digests[NID_sha1WithRSAEncryption] = 1;
num_digest_nids++;
break;
case CKM_SHA224:
pkcs11_implemented_digests[NID_sha224] = 1;
tok->pkcs11_implemented_digests[NID_sha224] = 1;
num_digest_nids++;
break;
case CKM_SHA224_KEY_DERIVATION:
case CKM_SHA224_RSA_PKCS:
pkcs11_implemented_digests[NID_sha224WithRSAEncryption] = 1;
tok->pkcs11_implemented_digests[NID_sha224WithRSAEncryption] = 1;
num_digest_nids++;
break;
case CKM_SHA256:
pkcs11_implemented_digests[NID_sha256] = 1;
tok->pkcs11_implemented_digests[NID_sha256] = 1;
num_digest_nids++;
break;
case CKM_SHA256_KEY_DERIVATION:
case CKM_SHA256_RSA_PKCS:
pkcs11_implemented_digests[NID_sha256WithRSAEncryption] = 1;
tok->pkcs11_implemented_digests[NID_sha256WithRSAEncryption] = 1;
num_digest_nids++;
break;
case CKM_SHA384:
pkcs11_implemented_digests[NID_sha384] = 1;
tok->pkcs11_implemented_digests[NID_sha384] = 1;
num_digest_nids++;
break;
case CKM_SHA384_KEY_DERIVATION:
case CKM_SHA384_RSA_PKCS:
pkcs11_implemented_digests[NID_sha384WithRSAEncryption] = 1;
tok->pkcs11_implemented_digests[NID_sha384WithRSAEncryption] = 1;
num_digest_nids++;
break;
case CKM_SHA512:
pkcs11_implemented_digests[NID_sha512] = 1;
tok->pkcs11_implemented_digests[NID_sha512] = 1;
num_digest_nids++;
break;
case CKM_SHA512_KEY_DERIVATION:
case CKM_SHA512_RSA_PKCS:
pkcs11_implemented_digests[NID_sha512WithRSAEncryption] = 1;
tok->pkcs11_implemented_digests[NID_sha512WithRSAEncryption] = 1;
num_digest_nids++;
break;
case CKM_AES_ECB:
pkcs11_implemented_ciphers[NID_aes_128_ecb] = 1;
pkcs11_implemented_ciphers[NID_aes_192_ecb] = 1;
pkcs11_implemented_ciphers[NID_aes_256_ecb] = 1;
tok->pkcs11_implemented_ciphers[NID_aes_128_ecb] = 1;
tok->pkcs11_implemented_ciphers[NID_aes_192_ecb] = 1;
tok->pkcs11_implemented_ciphers[NID_aes_256_ecb] = 1;
num_cipher_nids += 3;
break;
case CKM_AES_KEY_GEN:
break;
case CKM_AES_CBC_PAD:
case CKM_AES_CBC:
pkcs11_implemented_ciphers[NID_aes_128_cbc] = 1;
pkcs11_implemented_ciphers[NID_aes_192_cbc] = 1;
pkcs11_implemented_ciphers[NID_aes_256_cbc] = 1;
tok->pkcs11_implemented_ciphers[NID_aes_128_cbc] = 1;
tok->pkcs11_implemented_ciphers[NID_aes_192_cbc] = 1;
tok->pkcs11_implemented_ciphers[NID_aes_256_cbc] = 1;
num_cipher_nids += 3;
break;
case CKM_AES_MAC:
case CKM_AES_MAC_GENERAL:
break;
case CKM_MD5:
pkcs11_implemented_digests[NID_md5] = 1;
tok->pkcs11_implemented_digests[NID_md5] = 1;
num_digest_nids++;
break;
case CKM_MD5_HMAC:
@ -1065,7 +1093,7 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
case CKM_SSL3_SHA1_MAC:
break;
case CKM_RIPEMD160:
pkcs11_implemented_digests[NID_ripemd160] = 1;
tok->pkcs11_implemented_digests[NID_ripemd160] = 1;
num_digest_nids++;
break;
case CKM_RIPEMD160_HMAC:
@ -1074,7 +1102,7 @@ void pkcs11_regToken(ENGINE *e, CK_SLOT_ID slot_id)
default:
DBG_fprintf("The token in slot %lx has reported that it can "
"perform\nmechanism 0x%lx, which is not available to "
"accelerate in openssl.\n", slot_id, mech_list[i]);
"accelerate in openssl.\n", tok->slot_id, mech_list[i]);
break;
}
}
@ -1089,20 +1117,22 @@ err:
* This is called during the bind_pkcs11, in other words after openSSL has
* decided to use us for some operation.
*/
void pkcs11_addToken(CK_SLOT_ID slot_id)
struct _token *pkcs11_addToken(CK_SLOT_ID slot_id)
{
struct _token *new_tok = (struct _token *) OPENSSL_malloc(sizeof(struct _token));
if (new_tok == NULL) {
PKCS11err(PKCS11_F_ADDTOKEN, PKCS11_R_MALLOC_FAILURE);
return;
return NULL;
}
memset(new_tok, 0, sizeof(struct _token));
new_tok->slot = slot_id;
new_tok->slot_id = slot_id;
new_tok->token_next = pkcs11_token_list;
pkcs11_token_list = new_tok;
return new_tok;
}
/*
@ -1119,6 +1149,7 @@ static int pre_init_pkcs11(ENGINE *e)
CK_SLOT_ID_PTR pSlotList;
CK_ULONG ulSlotCount;
CK_SLOT_INFO slotInfo;
struct _token *tok;
int i;
if(pkcs11_dso)
@ -1209,7 +1240,11 @@ static int pre_init_pkcs11(ENGINE *e)
goto err;
}
pkcs11_regToken(e, pSlotList[i]);
/* we're mallocing memory here that may need to be freed
* if openssl chooses not to use us. We'll free it in
* the library destructor, pkcs11_engine_destructor */
tok = pkcs11_addToken(pSlotList[i]);
pkcs11_regToken(e, tok);
}
OPENSSL_free(pSlotList);
}
@ -1427,6 +1462,8 @@ err:
static int pkcs11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
{
int initialized = ((pkcs11_dso == NULL) ? 0 : 1);
struct _token *tok;
switch(cmd)
{
case PKCS11_CMD_SO_PATH:
@ -1441,6 +1478,18 @@ static int pkcs11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
return 0;
}
return set_PKCS11_LIBNAME((const char*)p);
case PKCS11_CMD_SLOT_ID:
tok = pkcs11_token_list;
while (tok) {
if (tok->slot_id == i) {
pkcs11_token = tok;
DBG_fprintf("slot %ld selected\n", i);
return 1;
}
tok = tok->token_next;
}
PKCS11err(PKCS11_F_CTRL, PKCS11_R_TOKEN_NOT_AVAILABLE);
return 0;
default:
break;
}
@ -3015,6 +3064,22 @@ pkcs11_digest_cleanup(EVP_MD_CTX *ctx)
{
return 1;
}
void pkcs11_engine_destructor(void) __attribute__((destructor));
/* the destructor handles the case where openssl called bind_pkcs11, which calls pre_init_pkcs11,
* which then found some PCKS#11 slots and called pkcs11_addToken, but then openssl decided not
* to use us */
void pkcs11_engine_destructor(void)
{
struct _token *tmp;
while (pkcs11_token_list) {
tmp = pkcs11_token_list->token_next;
OPENSSL_free(pkcs11_token_list);
pkcs11_token_list = tmp;
}
}
#endif
#endif

@ -43,6 +43,10 @@ static ERR_STRING_DATA pkcs11_str_functs[]=
{ERR_PACK(0,PKCS11_F_LOAD_PRIVKEY,0), "PKCS11_LOAD_PRIVKEY"},
{ERR_PACK(0,PKCS11_F_LOAD_PUBKEY,0), "PKCS11_LOAD_PUBKEY"},
{ERR_PACK(0,PKCS11_F_DIGESTCOPY,0), "PKCS11_DIGESTCOPY"},
{ERR_PACK(0,PKCS11_F_GET_PKCS11_CIPHERS,0), "PKCS11_GET_PKCS11_CIPHERS"},
{ERR_PACK(0,PKCS11_F_GET_PKCS11_DIGESTS,0), "PKCS11_GET_PKCS11_DIGESTS"},
{ERR_PACK(0,PKCS11_F_ENGINE_CIPHERS,0), "PKCS11_ENGINE_CIPHERS"},
{ERR_PACK(0,PKCS11_F_ENGINE_DIGESTS,0), "PKCS11_ENGINE_DIGESTS"},
{0,NULL}
};
@ -100,6 +104,9 @@ static ERR_STRING_DATA pkcs11_str_reasons[]=
{PKCS11_R_NOTOKENS ,"no hardware tokens found"},
{PKCS11_R_NOTOKENFORALGORITHM ,"no tokens available to accelerate algorithm"},
{PKCS11_R_DIGEST ,"C_Digest failed"},
{PKCS11_R_TOKEN_NOT_AVAILABLE ,"Token in requested slot is not available"},
{PKCS11_R_NO_SLOT_SELECTED ,"No slot selected, please add SLOT_ID=<num> to your"
" openssl.cnf ibmpkcs11_section"},
{0,NULL}
};

@ -2,29 +2,18 @@
#ifndef _HW_PKCS11_H_
#define _HW_PKCS11_H_
/* Number of NID's that exist in OpenSSL 1.0.0a */
#define NUM_NID 893
struct _token {
struct _token *token_next; /* next token in list of all tokens */
CK_SLOT_ID slot; /* slot ID of this token */
CK_SLOT_ID slot_id; /* slot ID of this token */
int pkcs11_implemented_ciphers[NUM_NID];
int pkcs11_implemented_digests[NUM_NID];
};
/* Future:
* Lists for free (non-busy) rsa,des... tokens.
*/
struct _token *pkcs11_token_list = NULL;
struct _token *pkcs11_rsa_head = NULL;
struct _token *pkcs11_des_head = NULL;
struct _token *pkcs11_tdes_head = NULL;
struct _token *pkcs11_sha_head = NULL;
struct _token *pkcs11_dh_head = NULL;
struct _token *pkcs11_aes_head = NULL;
struct _token *pkcs11_ripemd_head = NULL;
struct _token *pkcs11_ssl3_head = NULL;
struct _token *pkcs11_md5_head = NULL;
struct _token *pkcs11_token = NULL;
enum alg_type { alg_rsa=1, alg_des, alg_tdes, alg_sha, alg_dh, alg_aes,
alg_ripemd, alg_ssl3, alg_md5, alg_rand,

@ -47,6 +47,10 @@ void ERR_pkcs11_error(int function, int reason, char *file, int line);
#define PKCS11_F_CIPHER_UPDATE 125
#define PKCS11_F_PREINIT 126
#define PKCS11_F_DIGESTCOPY 127
#define PKCS11_F_ENGINE_DIGESTS 128
#define PKCS11_F_ENGINE_CIPHERS 129
#define PKCS11_F_GET_PKCS11_DIGESTS 130
#define PKCS11_F_GET_PKCS11_CIPHERS 131
/* Reason codes. */
#define PKCS11_R_ALREADY_LOADED 100
@ -101,4 +105,6 @@ void ERR_pkcs11_error(int function, int reason, char *file, int line);
#define PKCS11_R_NOTOKENS 149
#define PKCS11_R_NOTOKENFORALGORITHM 150
#define PKCS11_R_DIGEST 151
#define PKCS11_R_TOKEN_NOT_AVAILABLE 152
#define PKCS11_R_NO_SLOT_SELECTED 153
#endif

Loading…
Cancel
Save