Skip to content
Snippets Groups Projects
Commit a0361fc7 authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

dnssec: prevent duplicate PKCS11 module loading

parent e61e8dc3
No related branches found
No related tags found
1 merge request!553PKCS 11 duplicate module loading prevention
......@@ -129,6 +129,8 @@ libdnssec_la_SOURCES = \
lib/nsec/bitmap.c \
lib/nsec/hash.c \
lib/nsec/nsec.c \
lib/p11/p11.c \
lib/p11/p11.h \
lib/random.c \
lib/sign/der.c \
lib/sign/der.h \
......
......@@ -18,6 +18,7 @@
#include <gnutls/pkcs11.h>
#include "crypto.h"
#include "p11/p11.h"
#include "shared.h"
_public_
......@@ -35,6 +36,7 @@ void dnssec_crypto_cleanup(void)
gnutls_global_deinit();
#ifdef ENABLE_PKCS11
gnutls_pkcs11_deinit();
p11_cleanup();
#endif
}
......
......@@ -91,7 +91,11 @@ enum dnssec_error {
DNSSEC_KEYSTORE_INVALID_BACKEND,
DNSSEC_KEYSTORE_INVALID_CONFIG,
DNSSEC_KEYSTORE_FAILED_TO_LOAD_P11_MODULE,
DNSSEC_P11_INVALID_CONFIG,
DNSSEC_P11_FAILED_TO_LOAD_MODULE,
DNSSEC_P11_TOO_MANY_MODULES,
DNSSEC_P11_TOKEN_NOT_AVAILABLE,
DNSSEC_ERROR_MAX = -1001
};
......
......@@ -68,7 +68,11 @@ static const error_message_t ERROR_MESSAGES[] = {
{ DNSSEC_KEYSTORE_INVALID_BACKEND, "invalid KASP keystore backend" },
{ DNSSEC_KEYSTORE_INVALID_CONFIG, "invalid KASP keystore configuration" },
{ DNSSEC_KEYSTORE_FAILED_TO_LOAD_P11_MODULE, "failed to load PKCS #11 module" },
{ DNSSEC_P11_INVALID_CONFIG, "invalid PKCS #11 configuration" },
{ DNSSEC_P11_FAILED_TO_LOAD_MODULE, "failed to load PKCS #11 module" },
{ DNSSEC_P11_TOO_MANY_MODULES, "too many PKCS #11 modules loaded" },
{ DNSSEC_P11_TOKEN_NOT_AVAILABLE, "PKCS #11 token not available" },
{ 0 }
};
......
......@@ -23,6 +23,7 @@
#include "keyid_gnutls.h"
#include "keystore.h"
#include "keystore/internal.h"
#include "p11/p11.h"
#include "pem.h"
#include "shared.h"
......@@ -119,18 +120,18 @@ static int safe_open(const char *config, char **url_ptr)
return r;
}
r = gnutls_pkcs11_add_provider(module, NULL);
r = p11_load_module(module);
free(module);
if (r != GNUTLS_E_SUCCESS) {
free(url);
return DNSSEC_KEYSTORE_FAILED_TO_LOAD_P11_MODULE;
return DNSSEC_P11_FAILED_TO_LOAD_MODULE;
}
unsigned int flags = 0;
r = gnutls_pkcs11_token_get_flags(url, &flags);
if (r != GNUTLS_E_SUCCESS) {
free(url);
return DNSSEC_KEYSTORE_FAILED_TO_LOAD_P11_MODULE;
return DNSSEC_P11_TOKEN_NOT_AVAILABLE;
}
*url_ptr = url;
......@@ -241,7 +242,7 @@ static int pkcs11_list_keys(void *_ctx, dnssec_list_t **list)
int r = gnutls_pkcs11_obj_list_import_url4(&objects, &count, ctx->url, flags);
if (r != GNUTLS_E_SUCCESS) {
dnssec_list_free(ids);
return DNSSEC_ERROR; // TODO
return DNSSEC_P11_TOKEN_NOT_AVAILABLE;
}
for (unsigned i = 0; i < count; i++) {
......
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "p11/p11.h"
#include "error.h"
#include <assert.h>
#include <gnutls/pkcs11.h>
#include <stdlib.h>
#include <string.h>
#define PKCS11_MODULES_MAX 16
static char *pkcs11_modules[PKCS11_MODULES_MAX] = { 0 };
static int pkcs11_modules_count = 0;
int p11_load_module(const char *module)
{
for (int i = 0; i < pkcs11_modules_count; i++) {
if (strcmp(pkcs11_modules[i], module) == 0) {
return DNSSEC_EOK;
}
}
assert(pkcs11_modules_count <= PKCS11_MODULES_MAX);
if (pkcs11_modules_count == PKCS11_MODULES_MAX) {
return DNSSEC_P11_TOO_MANY_MODULES;
}
char *copy = strdup(module);
if (!copy) {
return DNSSEC_ENOMEM;
}
int r = gnutls_pkcs11_add_provider(module, NULL);
if (r != GNUTLS_E_SUCCESS) {
free(copy);
return DNSSEC_P11_FAILED_TO_LOAD_MODULE;
}
pkcs11_modules[pkcs11_modules_count] = copy;
pkcs11_modules_count += 1;
return DNSSEC_EOK;
}
void p11_cleanup(void)
{
for (int i = 0; i < pkcs11_modules_count; i++) {
free(pkcs11_modules[i]);
pkcs11_modules[i] = NULL;
}
pkcs11_modules_count = 0;
}
/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/*!
* Load PKCS11 module unless the module was already loaded.
*
* Duplicates are detected based on the module path.
*/
int p11_load_module(const char *name);
/*!
* Clenaup list of loaded modules.
*
* Should be called when the library is deinitialized to prevent memory leaks.
*/
void p11_cleanup(void);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment