2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

[master] better error output when initializing pkcs11

3786.	[func]		Provide more detailed error codes when using
			native PKCS#11. "pkcs11-tokens" now fails robustly
			rather than asserting when run against an HSM with
			an incomplete PCKS#11 API implementation. [RT #35479]
This commit is contained in:
Evan Hunt
2014-03-12 20:52:01 -07:00
parent 3911e7610f
commit acbb301e64
55 changed files with 651 additions and 185 deletions

View File

@@ -125,13 +125,11 @@
#include <pk11/pk11.h>
#include <pk11/internal.h>
#include <pk11/result.h>
#include <pkcs11/cryptoki.h>
#include <pkcs11/pkcs11.h>
void dst__pkcs11_init(isc_mem_t *mctx, const char *engine);
isc_result_t dst__pkcs11_destroy(void);
#define PINLEN 32
#ifndef PK11_NO_LOGERR
@@ -272,8 +270,9 @@ pk11_mem_put(void *ptr, size_t size) {
UNLOCK(&alloclock);
}
void
dst__pkcs11_init(isc_mem_t *mctx, const char *engine) {
isc_result_t
pk11_initialize(isc_mem_t *mctx, const char *engine) {
isc_result_t result;
CK_RV rv;
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
@@ -283,48 +282,56 @@ dst__pkcs11_init(isc_mem_t *mctx, const char *engine) {
isc_mem_attach(mctx, &pk11_mctx);
if (initialized) {
UNLOCK(&alloclock);
return;
return (ISC_R_SUCCESS);
} else {
LOCK(&sessionlock);
initialized = ISC_TRUE;
UNLOCK(&alloclock);
}
ISC_LIST_INIT(tokens);
ISC_LIST_INIT(actives);
if (engine != NULL)
lib_name = engine;
/* Initialize the CRYPTOKI library */
rv = pkcs_C_Initialize((CK_VOID_PTR) &pk11_init_args);
if (rv != CKR_OK) {
if (rv == 0xfe)
FATAL_ERROR(__FILE__, __LINE__,
"Can't load or link module \"%s\"",
lib_name);
else
FATAL_ERROR(__FILE__, __LINE__,
"pkcs_C_Initialize: Error = 0x%.8lX", rv);
if (rv == 0xfe) {
result = PK11_R_NOPROVIDER;
goto unlock;
}
if (rv != CKR_OK) {
result = PK11_R_INITFAILED;
goto unlock;
}
ISC_LIST_INIT(tokens);
ISC_LIST_INIT(actives);
choose_slots();
#ifdef PKCS11CRYPTO
if (rand_token == NULL)
FATAL_ERROR(__FILE__, __LINE__, "Can't find random service");
if (digest_token == NULL)
FATAL_ERROR(__FILE__, __LINE__, "Can't find digest service");
if (rand_token == NULL) {
result = PK11_R_NORANDOMSERVICE;
goto unlock;
}
if (digest_token == NULL) {
result = PK11_R_NODIGESTSERVICE;
goto unlock;
}
#if defined(ISC_PLATFORM_USESIT) && defined(AES_SIT)
if (aes_token == NULL)
FATAL_ERROR(__FILE__, __LINE__, "Can't find AES encrypt");
if (aes_token == NULL) {
result = PK11_R_NOAESSERVICE;
goto unlock;
}
#endif
#endif /* PKCS11CRYPTO */
result = ISC_R_SUCCESS;
unlock:
UNLOCK(&sessionlock);
return (result);
}
isc_result_t
dst__pkcs11_destroy(void) {
pk11_finalize(void) {
pk11_token_t *token, *next;
isc_result_t ret;
@@ -359,19 +366,17 @@ dst__pkcs11_destroy(void) {
return (ret);
}
void
pk11_shutdown(void) {
(void) dst__pkcs11_destroy();
}
isc_result_t
pk11_rand_bytes(unsigned char *buf, int num) {
isc_result_t ret;
CK_RV rv;
pk11_context_t ctx;
ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, NULL, 0);
if (ret != ISC_R_SUCCESS)
ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE,
ISC_FALSE, NULL, 0);
if ((ret != ISC_R_SUCCESS) &&
(ret != PK11_R_NODIGESTSERVICE) &&
(ret != PK11_R_NOAESSERVICE))
return (ret);
RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE);
rv = pkcs_C_GenerateRandom(ctx.session,
@@ -394,8 +399,11 @@ pk11_rand_seed_fromfile(const char *randomfile) {
size_t cc = 0;
isc_result_t ret;
ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, NULL, 0);
if (ret != ISC_R_SUCCESS)
ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE,
ISC_FALSE, NULL, 0);
if ((ret != ISC_R_SUCCESS) &&
(ret != PK11_R_NODIGESTSERVICE) &&
(ret != PK11_R_NOAESSERVICE))
return;
RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE);
ret = isc_stdio_open(randomfile, "r", &stream);
@@ -418,22 +426,41 @@ pk11_rand_seed_fromfile(const char *randomfile) {
isc_result_t
pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype,
isc_boolean_t rw, isc_boolean_t logon,
const char *pin, CK_SLOT_ID slot)
isc_boolean_t need_services, isc_boolean_t rw,
isc_boolean_t logon, const char *pin, CK_SLOT_ID slot)
{
pk11_token_t *token = NULL;
pk11_sessionlist_t *freelist;
pk11_session_t *sp;
isc_result_t ret = ISC_R_SUCCESS;
dst__pkcs11_init(NULL, NULL);
LOCK(&sessionlock);
/* wait for initialization to finish */
UNLOCK(&sessionlock);
isc_result_t ret;
#ifdef PKCS11CRYPTO
isc_result_t service_ret = ISC_R_SUCCESS;
#else
UNUSED(need_services);
#endif
memset(ctx, 0, sizeof(pk11_context_t));
ctx->handle = NULL;
ctx->session = CK_INVALID_HANDLE;
ret = pk11_initialize(NULL, NULL);
#ifdef PKCS11CRYPTO
if (ret == PK11_R_NORANDOMSERVICE ||
ret == PK11_R_NODIGESTSERVICE ||
ret == PK11_R_NOAESSERVICE) {
if (need_services)
return (ret);
service_ret = ret;
}
else
#endif /* PKCS11CRYPTO */
if (ret != ISC_R_SUCCESS)
return (ret);
LOCK(&sessionlock);
/* wait for initialization to finish */
UNLOCK(&sessionlock);
switch(optype) {
#ifdef PKCS11CRYPTO
case OP_RAND:
@@ -506,6 +533,10 @@ pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype,
UNLOCK(&sessionlock);
ctx->handle = sp;
ctx->session = sp->session;
#ifdef PKCS11CRYPTO
if (ret == ISC_R_SUCCESS)
ret = service_ret;
#endif
return (ret);
}
@@ -1082,10 +1113,10 @@ pk11_parse_uri(pk11_object_t *obj, const char *label,
/* get the URI scheme */
p = strchr(uri, ':');
if (p == NULL)
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
*p++ = '\0';
if (strcmp(uri, "pkcs11") != 0)
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
/* get attributes */
for (na = p; na != NULL;) {
@@ -1107,12 +1138,12 @@ pk11_parse_uri(pk11_object_t *obj, const char *label,
l = 0;
v = percent_decode(v, &l);
if (v == NULL)
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
if ((a == v) || (strcmp(a, "object") == 0)) {
/* object: CKA_LABEL */
attr = pk11_attribute_bytype(obj, CKA_LABEL);
if (attr != NULL)
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
attr = push_attribute(obj, mctx, l);
if (attr == NULL)
DST_RET(ISC_R_NOMEMORY);
@@ -1160,12 +1191,12 @@ pk11_parse_uri(pk11_object_t *obj, const char *label,
/* object-type: CKA_CLASS */
/* only private makes sense */
if (strcmp(v, "private") != 0)
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
} else if (strcmp(a, "id") == 0) {
/* id: CKA_ID */
attr = pk11_attribute_bytype(obj, CKA_ID);
if (attr != NULL)
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
attr = push_attribute(obj, mctx, l);
if (attr == NULL)
DST_RET(ISC_R_NOMEMORY);
@@ -1186,7 +1217,7 @@ pk11_parse_uri(pk11_object_t *obj, const char *label,
goto err;
gotpin = ISC_TRUE;
} else
DST_RET(DST_R_NOENGINE);
DST_RET(PK11_R_NOPROVIDER);
}
if ((pk11_attribute_bytype(obj, CKA_LABEL) == NULL) &&