blob: c3af544984e82a7feb88e7f9dff8d1c7a4199c5c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <gnutls/pkcs11.h>
#include <stdlib.h>
#include <string.h>
#include "libdnssec/p11/p11.h"
#include "libdnssec/error.h"
#ifdef ENABLE_PKCS11
#define PKCS11_MODULES_MAX 16
static char *pkcs11_modules[PKCS11_MODULES_MAX] = { 0 };
static int pkcs11_modules_count = 0;
static int map_result(int gnutls_result)
{
return gnutls_result == GNUTLS_E_SUCCESS ? DNSSEC_EOK : DNSSEC_ERROR;
}
int p11_init(void)
{
int r = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
return map_result(r);
}
int p11_reinit(void)
{
int r = gnutls_pkcs11_reinit();
return map_result(r);
}
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;
gnutls_pkcs11_deinit();
}
#else
int p11_init(void)
{
return DNSSEC_EOK;
}
int p11_reinit(void)
{
return DNSSEC_EOK;
}
int p11_load_module(const char *module)
{
return DNSSEC_NOT_IMPLEMENTED_ERROR;
}
void p11_cleanup(void)
{
// this function intentionally left blank
}
#endif
|