1 /* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <https://www.gnu.org/licenses/>.
15 */
16
17 #include <gnutls/gnutls.h>
18
19 #include "libdnssec/error.h"
20 #include "libdnssec/key.h"
21 #include "libdnssec/key/algorithm.h"
22 #include "libdnssec/shared/shared.h"
23
24 /* -- internal ------------------------------------------------------------- */
25
26 struct limits {
27 unsigned min;
28 unsigned max;
29 unsigned def;
30 bool (*validate)(unsigned bits);
31 };
32
get_limits(dnssec_key_algorithm_t algorithm)33 static const struct limits *get_limits(dnssec_key_algorithm_t algorithm)
34 {
35 static const struct limits RSA = {
36 .min = 1024,
37 .max = 4096,
38 .def = 2048,
39 };
40
41 static const struct limits EC256 = {
42 .min = 256,
43 .max = 256,
44 .def = 256,
45 };
46
47 static const struct limits EC384 = {
48 .min = 384,
49 .max = 384,
50 .def = 384,
51 };
52
53 static const struct limits ED25519 = {
54 .min = 256,
55 .max = 256,
56 .def = 256,
57 };
58
59 static const struct limits ED448 = {
60 .min = 456,
61 .max = 456,
62 .def = 456,
63 };
64
65 switch (algorithm) {
66 case DNSSEC_KEY_ALGORITHM_RSA_SHA1:
67 case DNSSEC_KEY_ALGORITHM_RSA_SHA1_NSEC3:
68 case DNSSEC_KEY_ALGORITHM_RSA_SHA256:
69 case DNSSEC_KEY_ALGORITHM_RSA_SHA512:
70 return &RSA;
71 case DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256:
72 return &EC256;
73 case DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384:
74 return &EC384;
75 case DNSSEC_KEY_ALGORITHM_ED25519:
76 return &ED25519;
77 case DNSSEC_KEY_ALGORITHM_ED448:
78 return &ED448;
79 default:
80 return NULL;
81 }
82 }
83
84 /* -- internal API --------------------------------------------------------- */
85
algorithm_to_gnutls(dnssec_key_algorithm_t dnssec)86 gnutls_pk_algorithm_t algorithm_to_gnutls(dnssec_key_algorithm_t dnssec)
87 {
88 switch (dnssec) {
89 case DNSSEC_KEY_ALGORITHM_RSA_SHA1:
90 case DNSSEC_KEY_ALGORITHM_RSA_SHA1_NSEC3:
91 case DNSSEC_KEY_ALGORITHM_RSA_SHA256:
92 case DNSSEC_KEY_ALGORITHM_RSA_SHA512:
93 return GNUTLS_PK_RSA;
94 case DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256:
95 case DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384:
96 return GNUTLS_PK_EC;
97 #ifdef HAVE_ED25519
98 case DNSSEC_KEY_ALGORITHM_ED25519:
99 return GNUTLS_PK_EDDSA_ED25519;
100 #endif
101 #ifdef HAVE_ED448
102 case DNSSEC_KEY_ALGORITHM_ED448:
103 return GNUTLS_PK_EDDSA_ED448;
104 #endif
105 default:
106 return GNUTLS_PK_UNKNOWN;
107 }
108 }
109
110 /* -- public API ----------------------------------------------------------- */
111
112 _public_
dnssec_algorithm_reproducible(dnssec_key_algorithm_t algorithm,bool enabled)113 bool dnssec_algorithm_reproducible(dnssec_key_algorithm_t algorithm, bool enabled)
114 {
115 (void)enabled;
116 switch (algorithm) {
117 case DNSSEC_KEY_ALGORITHM_ED25519:
118 case DNSSEC_KEY_ALGORITHM_ED448:
119 return true; // those are always reproducible
120 case DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256:
121 case DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384:
122 #ifdef HAVE_GLNUTLS_REPRODUCIBLE
123 return enabled; // Reproducible only if GnuTLS supports && enabled
124 #else
125 return false;
126 #endif
127 default:
128 return false;
129 }
130 }
131
132 _public_
dnssec_algorithm_key_size_range(dnssec_key_algorithm_t algorithm,unsigned * min_ptr,unsigned * max_ptr)133 int dnssec_algorithm_key_size_range(dnssec_key_algorithm_t algorithm,
134 unsigned *min_ptr, unsigned *max_ptr)
135 {
136 if (!min_ptr && !max_ptr) {
137 return DNSSEC_EINVAL;
138 }
139
140 const struct limits *limits = get_limits(algorithm);
141 if (!limits) {
142 return DNSSEC_INVALID_KEY_ALGORITHM;
143 }
144
145 if (min_ptr) {
146 *min_ptr = limits->min;
147 }
148 if (max_ptr) {
149 *max_ptr = limits->max;
150 }
151
152 return DNSSEC_EOK;
153 }
154
155 _public_
dnssec_algorithm_key_size_check(dnssec_key_algorithm_t algorithm,unsigned bits)156 bool dnssec_algorithm_key_size_check(dnssec_key_algorithm_t algorithm,
157 unsigned bits)
158 {
159 const struct limits *limits = get_limits(algorithm);
160 if (!limits) {
161 return false;
162 }
163
164 if (bits < limits->min || bits > limits->max) {
165 return false;
166 }
167
168 if (limits->validate && !limits->validate(bits)) {
169 return false;
170 }
171
172 return true;
173 }
174
175 _public_
dnssec_algorithm_key_size_default(dnssec_key_algorithm_t algorithm)176 int dnssec_algorithm_key_size_default(dnssec_key_algorithm_t algorithm)
177 {
178 const struct limits *limits = get_limits(algorithm);
179 return limits ? limits->def : 0;
180 }
181