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:
127
lib/isc/pk11.c
127
lib/isc/pk11.c
@@ -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) &&
|
||||
|
Reference in New Issue
Block a user