1:255.16-alt1
[systemd_ALT.git] / src / resolve / test-dnssec.c
blobd325b533eae6b9bab42331a3b002d737deb8b97f
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <arpa/inet.h>
4 #include <netinet/in.h>
5 #include <sys/socket.h>
7 #if HAVE_GCRYPT
8 # include <gcrypt.h>
9 #endif
11 #include "alloc-util.h"
12 #include "hexdecoct.h"
13 #include "resolved-dns-dnssec.h"
14 #include "resolved-dns-rr.h"
15 #include "string-util.h"
16 #include "tests.h"
18 TEST(dnssec_verify_dns_key) {
19 static const uint8_t ds1_fprint[] = {
20 0x46, 0x8B, 0xC8, 0xDD, 0xC7, 0xE8, 0x27, 0x03, 0x40, 0xBB, 0x8A, 0x1F, 0x3B, 0x2E, 0x45, 0x9D,
21 0x80, 0x67, 0x14, 0x01,
23 static const uint8_t ds2_fprint[] = {
24 0x8A, 0xEE, 0x80, 0x47, 0x05, 0x5F, 0x83, 0xD1, 0x48, 0xBA, 0x8F, 0xF6, 0xDD, 0xA7, 0x60, 0xCE,
25 0x94, 0xF7, 0xC7, 0x5E, 0x52, 0x4C, 0xF2, 0xE9, 0x50, 0xB9, 0x2E, 0xCB, 0xEF, 0x96, 0xB9, 0x98,
27 static const uint8_t dnskey_blob[] = {
28 0x03, 0x01, 0x00, 0x01, 0xa8, 0x12, 0xda, 0x4f, 0xd2, 0x7d, 0x54, 0x14, 0x0e, 0xcc, 0x5b, 0x5e,
29 0x45, 0x9c, 0x96, 0x98, 0xc0, 0xc0, 0x85, 0x81, 0xb1, 0x47, 0x8c, 0x7d, 0xe8, 0x39, 0x50, 0xcc,
30 0xc5, 0xd0, 0xf2, 0x00, 0x81, 0x67, 0x79, 0xf6, 0xcc, 0x9d, 0xad, 0x6c, 0xbb, 0x7b, 0x6f, 0x48,
31 0x97, 0x15, 0x1c, 0xfd, 0x0b, 0xfe, 0xd3, 0xd7, 0x7d, 0x9f, 0x81, 0x26, 0xd3, 0xc5, 0x65, 0x49,
32 0xcf, 0x46, 0x62, 0xb0, 0x55, 0x6e, 0x47, 0xc7, 0x30, 0xef, 0x51, 0xfb, 0x3e, 0xc6, 0xef, 0xde,
33 0x27, 0x3f, 0xfa, 0x57, 0x2d, 0xa7, 0x1d, 0x80, 0x46, 0x9a, 0x5f, 0x14, 0xb3, 0xb0, 0x2c, 0xbe,
34 0x72, 0xca, 0xdf, 0xb2, 0xff, 0x36, 0x5b, 0x4f, 0xec, 0x58, 0x8e, 0x8d, 0x01, 0xe9, 0xa9, 0xdf,
35 0xb5, 0x60, 0xad, 0x52, 0x4d, 0xfc, 0xa9, 0x3e, 0x8d, 0x35, 0x95, 0xb3, 0x4e, 0x0f, 0xca, 0x45,
36 0x1b, 0xf7, 0xef, 0x3a, 0x88, 0x25, 0x08, 0xc7, 0x4e, 0x06, 0xc1, 0x62, 0x1a, 0xce, 0xd8, 0x77,
37 0xbd, 0x02, 0x65, 0xf8, 0x49, 0xfb, 0xce, 0xf6, 0xa8, 0x09, 0xfc, 0xde, 0xb2, 0x09, 0x9d, 0x39,
38 0xf8, 0x63, 0x9c, 0x32, 0x42, 0x7c, 0xa0, 0x30, 0x86, 0x72, 0x7a, 0x4a, 0xc6, 0xd4, 0xb3, 0x2d,
39 0x24, 0xef, 0x96, 0x3f, 0xc2, 0xda, 0xd3, 0xf2, 0x15, 0x6f, 0xda, 0x65, 0x4b, 0x81, 0x28, 0x68,
40 0xf4, 0xfe, 0x3e, 0x71, 0x4f, 0x50, 0x96, 0x72, 0x58, 0xa1, 0x89, 0xdd, 0x01, 0x61, 0x39, 0x39,
41 0xc6, 0x76, 0xa4, 0xda, 0x02, 0x70, 0x3d, 0xc0, 0xdc, 0x8d, 0x70, 0x72, 0x04, 0x90, 0x79, 0xd4,
42 0xec, 0x65, 0xcf, 0x49, 0x35, 0x25, 0x3a, 0x14, 0x1a, 0x45, 0x20, 0xeb, 0x31, 0xaf, 0x92, 0xba,
43 0x20, 0xd3, 0xcd, 0xa7, 0x13, 0x44, 0xdc, 0xcf, 0xf0, 0x27, 0x34, 0xb9, 0xe7, 0x24, 0x6f, 0x73,
44 0xe7, 0xea, 0x77, 0x03,
47 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds1 = NULL, *ds2 = NULL;
49 /* The two DS RRs in effect for nasa.gov on 2015-12-01. */
50 ds1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "nasa.gov");
51 assert_se(ds1);
53 ds1->ds.key_tag = 47857;
54 ds1->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
55 ds1->ds.digest_type = DNSSEC_DIGEST_SHA1;
56 ds1->ds.digest_size = sizeof(ds1_fprint);
57 ds1->ds.digest = memdup(ds1_fprint, ds1->ds.digest_size);
58 assert_se(ds1->ds.digest);
60 log_info("DS1: %s", strna(dns_resource_record_to_string(ds1)));
62 ds2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "NASA.GOV");
63 assert_se(ds2);
65 ds2->ds.key_tag = 47857;
66 ds2->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
67 ds2->ds.digest_type = DNSSEC_DIGEST_SHA256;
68 ds2->ds.digest_size = sizeof(ds2_fprint);
69 ds2->ds.digest = memdup(ds2_fprint, ds2->ds.digest_size);
70 assert_se(ds2->ds.digest);
72 log_info("DS2: %s", strna(dns_resource_record_to_string(ds2)));
74 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nasa.GOV");
75 assert_se(dnskey);
77 dnskey->dnskey.flags = 257;
78 dnskey->dnskey.protocol = 3;
79 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
80 dnskey->dnskey.key_size = sizeof(dnskey_blob);
81 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
82 assert_se(dnskey->dnskey.key);
84 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
85 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
87 assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds1, false) > 0);
88 assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds2, false) > 0);
91 TEST(dnssec_verify_rfc8080_ed25519_example1) {
92 static const uint8_t dnskey_blob[] = {
93 0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, 0x91, 0x47, 0x7d,
94 0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59,
95 0x24, 0xe
97 static const uint8_t ds_fprint[] = {
98 0xdd, 0xa6, 0xb9, 0x69, 0xbd, 0xfb, 0x79, 0xf7, 0x1e, 0xe7, 0xb7, 0xfb, 0xdf, 0xb7, 0xdc,
99 0xd7, 0xad, 0xbb, 0xd3, 0x5d, 0xdf, 0x79, 0xed, 0x3b, 0x6d, 0xd7, 0xf6, 0xe3, 0x56, 0xdd,
100 0xd7, 0x47, 0xf7, 0x6f, 0x5f, 0x7a, 0xe1, 0xa6, 0xf9, 0xe5, 0xce, 0xfc, 0x7b, 0xbf, 0x5a,
101 0xdf, 0x4e, 0x1b
103 static const uint8_t signature_blob[] = {
104 0xa0, 0xbf, 0x64, 0xac, 0x9b, 0xa7, 0xef, 0x17, 0xc1, 0x38, 0x85, 0x9c, 0x18, 0x78, 0xbb,
105 0x99, 0xa8, 0x39, 0xfe, 0x17, 0x59, 0xac, 0xa5, 0xb0, 0xd7, 0x98, 0xcf, 0x1a, 0xb1, 0xe9,
106 0x8d, 0x07, 0x91, 0x02, 0xf4, 0xdd, 0xb3, 0x36, 0x8f, 0x0f, 0xe4, 0x0b, 0xb3, 0x77, 0xf1,
107 0xf0, 0x0e, 0x0c, 0xdd, 0xed, 0xb7, 0x99, 0x16, 0x7d, 0x56, 0xb6, 0xe9, 0x32, 0x78, 0x30,
108 0x72, 0xba, 0x8d, 0x02
111 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *mx = NULL,
112 *rrsig = NULL;
113 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
114 DnssecResult result;
116 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.com.");
117 assert_se(dnskey);
119 dnskey->dnskey.flags = 257;
120 dnskey->dnskey.protocol = 3;
121 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ED25519;
122 dnskey->dnskey.key_size = sizeof(dnskey_blob);
123 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
124 assert_se(dnskey->dnskey.key);
126 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
128 ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.com.");
129 assert_se(ds);
131 ds->ds.key_tag = 3613;
132 ds->ds.algorithm = DNSSEC_ALGORITHM_ED25519;
133 ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
134 ds->ds.digest_size = sizeof(ds_fprint);
135 ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
136 assert_se(ds->ds.digest);
138 log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
140 mx = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "example.com.");
141 assert_se(mx);
143 mx->mx.priority = 10;
144 mx->mx.exchange = strdup("mail.example.com.");
145 assert_se(mx->mx.exchange);
147 log_info("MX: %s", strna(dns_resource_record_to_string(mx)));
149 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "example.com.");
150 assert_se(rrsig);
152 rrsig->rrsig.type_covered = DNS_TYPE_MX;
153 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ED25519;
154 rrsig->rrsig.labels = 2;
155 rrsig->rrsig.original_ttl = 3600;
156 rrsig->rrsig.expiration = 1440021600;
157 rrsig->rrsig.inception = 1438207200;
158 rrsig->rrsig.key_tag = 3613;
159 rrsig->rrsig.signer = strdup("example.com.");
160 assert_se(rrsig->rrsig.signer);
161 rrsig->rrsig.signature_size = sizeof(signature_blob);
162 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
163 assert_se(rrsig->rrsig.signature);
165 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
167 assert_se(dnssec_key_match_rrsig(mx->key, rrsig) > 0);
168 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
170 answer = dns_answer_new(1);
171 assert_se(answer);
172 assert_se(dns_answer_add(answer, mx, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
174 assert_se(dnssec_verify_rrset(answer, mx->key, rrsig, dnskey,
175 rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
176 #if PREFER_OPENSSL || GCRYPT_VERSION_NUMBER >= 0x010600
177 assert_se(result == DNSSEC_VALIDATED);
178 #else
179 assert_se(result == DNSSEC_UNSUPPORTED_ALGORITHM);
180 #endif
183 TEST(dnssec_verify_rfc8080_ed25519_example2) {
184 static const uint8_t dnskey_blob[] = {
185 0xcc, 0xf9, 0xd9, 0xfd, 0x0c, 0x04, 0x7b, 0xb4, 0xbc, 0x0b, 0x94, 0x8f, 0xcf, 0x63, 0x9f,
186 0x4b, 0x94, 0x51, 0xe3, 0x40, 0x13, 0x93, 0x6f, 0xeb, 0x62, 0x71, 0x3d, 0xc4, 0x72, 0x4,
187 0x8a, 0x3b
189 static const uint8_t ds_fprint[] = {
190 0xe3, 0x4d, 0x7b, 0xf3, 0x56, 0xfd, 0xdf, 0x87, 0xb7, 0xf7, 0x67, 0x5e, 0xe3, 0xdd, 0x9e,
191 0x73, 0xbe, 0xda, 0x7b, 0x67, 0xb5, 0xe5, 0xde, 0xf4, 0x7f, 0xae, 0x7b, 0xe5, 0xad, 0x5c,
192 0xd1, 0xb7, 0x39, 0xf5, 0xce, 0x76, 0xef, 0x97, 0x34, 0xe1, 0xe6, 0xde, 0xf3, 0x47, 0x3a,
193 0xeb, 0x5e, 0x1c
195 static const uint8_t signature_blob[] = {
196 0xcd, 0x74, 0x34, 0x6e, 0x46, 0x20, 0x41, 0x31, 0x05, 0xc9, 0xf2, 0xf2, 0x8b, 0xd4, 0x28,
197 0x89, 0x8e, 0x83, 0xf1, 0x97, 0x58, 0xa3, 0x8c, 0x32, 0x52, 0x15, 0x62, 0xa1, 0x86, 0x57,
198 0x15, 0xd4, 0xf8, 0xd7, 0x44, 0x0f, 0x44, 0x84, 0xd0, 0x4a, 0xa2, 0x52, 0x9f, 0x34, 0x28,
199 0x4a, 0x6e, 0x69, 0xa0, 0x9e, 0xe0, 0x0f, 0xb0, 0x10, 0x47, 0x43, 0xbb, 0x2a, 0xe2, 0x39,
200 0x93, 0x6a, 0x5c, 0x06
203 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *mx = NULL,
204 *rrsig = NULL;
205 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
206 DnssecResult result;
208 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.com.");
209 assert_se(dnskey);
211 dnskey->dnskey.flags = 257;
212 dnskey->dnskey.protocol = 3;
213 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ED25519;
214 dnskey->dnskey.key_size = sizeof(dnskey_blob);
215 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
216 assert_se(dnskey->dnskey.key);
218 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
220 ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.com.");
221 assert_se(ds);
223 ds->ds.key_tag = 35217;
224 ds->ds.algorithm = DNSSEC_ALGORITHM_ED25519;
225 ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
226 ds->ds.digest_size = sizeof(ds_fprint);
227 ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
228 assert_se(ds->ds.digest);
230 log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
232 mx = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "example.com.");
233 assert_se(mx);
235 mx->mx.priority = 10;
236 mx->mx.exchange = strdup("mail.example.com.");
237 assert_se(mx->mx.exchange);
239 log_info("MX: %s", strna(dns_resource_record_to_string(mx)));
241 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "example.com.");
242 assert_se(rrsig);
244 rrsig->rrsig.type_covered = DNS_TYPE_MX;
245 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ED25519;
246 rrsig->rrsig.labels = 2;
247 rrsig->rrsig.original_ttl = 3600;
248 rrsig->rrsig.expiration = 1440021600;
249 rrsig->rrsig.inception = 1438207200;
250 rrsig->rrsig.key_tag = 35217;
251 rrsig->rrsig.signer = strdup("example.com.");
252 assert_se(rrsig->rrsig.signer);
253 rrsig->rrsig.signature_size = sizeof(signature_blob);
254 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
255 assert_se(rrsig->rrsig.signature);
257 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
259 assert_se(dnssec_key_match_rrsig(mx->key, rrsig) > 0);
260 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
262 answer = dns_answer_new(1);
263 assert_se(answer);
264 assert_se(dns_answer_add(answer, mx, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
266 assert_se(dnssec_verify_rrset(answer, mx->key, rrsig, dnskey,
267 rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
268 #if PREFER_OPENSSL || GCRYPT_VERSION_NUMBER >= 0x010600
269 assert_se(result == DNSSEC_VALIDATED);
270 #else
271 assert_se(result == DNSSEC_UNSUPPORTED_ALGORITHM);
272 #endif
275 TEST(dnssec_verify_rfc6605_example1) {
276 static const uint8_t signature_blob[] = {
277 0xab, 0x1e, 0xb0, 0x2d, 0x8a, 0xa6, 0x87, 0xe9, 0x7d, 0xa0, 0x22, 0x93, 0x37, 0xaa, 0x88, 0x73,
278 0xe6, 0xf0, 0xeb, 0x26, 0xbe, 0x28, 0x9f, 0x28, 0x33, 0x3d, 0x18, 0x3f, 0x5d, 0x3b, 0x7a, 0x95,
279 0xc0, 0xc8, 0x69, 0xad, 0xfb, 0x74, 0x8d, 0xae, 0xe3, 0xc5, 0x28, 0x6e, 0xed, 0x66, 0x82, 0xc1,
280 0x2e, 0x55, 0x33, 0x18, 0x6b, 0xac, 0xed, 0x9c, 0x26, 0xc1, 0x67, 0xa9, 0xeb, 0xae, 0x95, 0x0b,
283 static const uint8_t ds_fprint[] = {
284 0x6f, 0x87, 0x3c, 0x73, 0x57, 0xde, 0xd9, 0xee, 0xf8, 0xef, 0xbd, 0x76, 0xed, 0xbd, 0xbb, 0xd7,
285 0x5e, 0x7a, 0xe7, 0xa6, 0x9d, 0xeb, 0x6e, 0x7a, 0x7f, 0x8d, 0xb8, 0xeb, 0x6e, 0x5b, 0x7f, 0x97,
286 0x35, 0x7b, 0x6e, 0xfb, 0xd1, 0xc7, 0xba, 0x77, 0xa7, 0xb7, 0xed, 0xd7, 0xfa, 0xd5, 0xdd, 0x7b,
289 static const uint8_t dnskey_blob[] = {
290 0x1a, 0x88, 0xc8, 0x86, 0x15, 0xd4, 0x37, 0xfb, 0xb8, 0xbf, 0x9e, 0x19, 0x42, 0xa1, 0x92, 0x9f,
291 0x28, 0x56, 0x27, 0x06, 0xae, 0x6c, 0x2b, 0xd3, 0x99, 0xe7, 0xb1, 0xbf, 0xb6, 0xd1, 0xe9, 0xe7,
292 0x5b, 0x92, 0xb4, 0xaa, 0x42, 0x91, 0x7a, 0xe1, 0xc6, 0x1b, 0x70, 0x1e, 0xf0, 0x35, 0xc3, 0xfe,
293 0x7b, 0xe3, 0x00, 0x9c, 0xba, 0xfe, 0x5a, 0x2f, 0x71, 0x31, 0x6c, 0x90, 0x2d, 0xcf, 0x0d, 0x00,
296 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *a = NULL,
297 *rrsig = NULL;
298 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
299 DnssecResult result;
301 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.net.");
302 assert_se(dnskey);
304 dnskey->dnskey.flags = 257;
305 dnskey->dnskey.protocol = 3;
306 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ECDSAP256SHA256;
307 dnskey->dnskey.key_size = sizeof(dnskey_blob);
308 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
309 assert_se(dnskey->dnskey.key);
311 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
313 ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.net.");
314 assert_se(ds);
316 ds->ds.key_tag = 55648;
317 ds->ds.algorithm = DNSSEC_ALGORITHM_ECDSAP256SHA256;
318 ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
319 ds->ds.digest_size = sizeof(ds_fprint);
320 ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
321 assert_se(ds->ds.digest);
323 log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
325 a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.net");
326 assert_se(a);
328 a->a.in_addr.s_addr = inet_addr("192.0.2.1");
330 log_info("A: %s", strna(dns_resource_record_to_string(a)));
332 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "www.example.net.");
333 assert_se(rrsig);
335 rrsig->rrsig.type_covered = DNS_TYPE_A;
336 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ECDSAP256SHA256;
337 rrsig->rrsig.labels = 3;
338 rrsig->rrsig.expiration = 1284026679;
339 rrsig->rrsig.inception = 1281607479;
340 rrsig->rrsig.key_tag = 55648;
341 rrsig->rrsig.original_ttl = 3600;
342 rrsig->rrsig.signer = strdup("example.net.");
343 assert_se(rrsig->rrsig.signer);
344 rrsig->rrsig.signature_size = sizeof(signature_blob);
345 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
346 assert_se(rrsig->rrsig.signature);
348 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
350 assert_se(dnssec_key_match_rrsig(a->key, rrsig) > 0);
351 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
353 answer = dns_answer_new(1);
354 assert_se(answer);
355 assert_se(dns_answer_add(answer, a, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
357 assert_se(dnssec_verify_rrset(answer, a->key, rrsig, dnskey,
358 rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
359 assert_se(result == DNSSEC_VALIDATED);
362 TEST(dnssec_verify_rfc6605_example2) {
363 static const uint8_t signature_blob[] = {
364 0xfc, 0xbe, 0x61, 0x0c, 0xa2, 0x2f, 0x18, 0x3c, 0x88, 0xd5, 0xf7, 0x00, 0x45, 0x7d, 0xf3, 0xeb,
365 0x9a, 0xab, 0x98, 0xfb, 0x15, 0xcf, 0xbd, 0xd0, 0x0f, 0x53, 0x2b, 0xe4, 0x21, 0x2a, 0x3a, 0x22,
366 0xcf, 0xf7, 0x98, 0x71, 0x42, 0x8b, 0xae, 0xae, 0x81, 0x82, 0x79, 0x93, 0xaf, 0xcc, 0x56, 0xb1,
367 0xb1, 0x3f, 0x06, 0x96, 0xbe, 0xf8, 0x85, 0xb6, 0xaf, 0x44, 0xa6, 0xb2, 0x24, 0xdb, 0xb2, 0x74,
368 0x2b, 0xb3, 0x59, 0x34, 0x92, 0x3d, 0xdc, 0xfb, 0xc2, 0x7a, 0x97, 0x2f, 0x96, 0xdd, 0x70, 0x9c,
369 0xee, 0xb1, 0xd9, 0xc8, 0xd1, 0x14, 0x8c, 0x44, 0xec, 0x71, 0xc0, 0x68, 0xa9, 0x59, 0xc2, 0x66,
373 static const uint8_t ds_fprint[] = {
374 0xef, 0x67, 0x7b, 0x6f, 0xad, 0xbd, 0xef, 0xa7, 0x1e, 0xd3, 0xae, 0x37, 0xf1, 0xef, 0x5c, 0xd1,
375 0xb7, 0xf7, 0xd7, 0xdd, 0x35, 0xdd, 0xc7, 0xfc, 0xd3, 0x57, 0xf4, 0xf5, 0xe7, 0x1c, 0xf3, 0x86,
376 0xfc, 0x77, 0xb7, 0xbd, 0xe3, 0xde, 0x5f, 0xdb, 0xb7, 0xb7, 0xd3, 0x97, 0x3a, 0x6b, 0xd6, 0xf4,
377 0xe7, 0xad, 0xda, 0xf5, 0xbe, 0x5f, 0xe1, 0xdd, 0xbc, 0xf3, 0x8d, 0x39, 0x73, 0x7d, 0x34, 0xf1,
378 0xaf, 0x78, 0xe9, 0xd7, 0xfd, 0xf3, 0x77, 0x7a,
381 static const uint8_t dnskey_blob[] = {
382 0xc4, 0xa6, 0x1a, 0x36, 0x15, 0x9d, 0x18, 0xe7, 0xc9, 0xfa, 0x73, 0xeb, 0x2f, 0xcf, 0xda, 0xae,
383 0x4c, 0x1f, 0xd8, 0x46, 0x37, 0x30, 0x32, 0x7e, 0x48, 0x4a, 0xca, 0x8a, 0xf0, 0x55, 0x4a, 0xe9,
384 0xb5, 0xc3, 0xf7, 0xa0, 0xb1, 0x7b, 0xd2, 0x00, 0x3b, 0x4d, 0x26, 0x1c, 0x9e, 0x9b, 0x94, 0x42,
385 0x3a, 0x98, 0x10, 0xe8, 0xaf, 0x17, 0xd4, 0x34, 0x52, 0x12, 0x4a, 0xdb, 0x61, 0x0f, 0x8e, 0x07,
386 0xeb, 0xfc, 0xfe, 0xe5, 0xf8, 0xe4, 0xd0, 0x70, 0x63, 0xca, 0xe9, 0xeb, 0x91, 0x7a, 0x1a, 0x5b,
387 0xab, 0xf0, 0x8f, 0xe6, 0x95, 0x53, 0x60, 0x17, 0xa5, 0xbf, 0xa9, 0x32, 0x37, 0xee, 0x6e, 0x34,
391 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *a = NULL,
392 *rrsig = NULL;
393 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
394 DnssecResult result;
396 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.net.");
397 assert_se(dnskey);
399 dnskey->dnskey.flags = 257;
400 dnskey->dnskey.protocol = 3;
401 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ECDSAP384SHA384;
402 dnskey->dnskey.key_size = sizeof(dnskey_blob);
403 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
404 assert_se(dnskey->dnskey.key);
406 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
408 ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.net.");
409 assert_se(ds);
411 ds->ds.key_tag = 10771;
412 ds->ds.algorithm = DNSSEC_ALGORITHM_ECDSAP384SHA384;
413 ds->ds.digest_type = DNSSEC_DIGEST_SHA384;
414 ds->ds.digest_size = sizeof(ds_fprint);
415 ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
416 assert_se(ds->ds.digest);
418 log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
420 a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.net");
421 assert_se(a);
423 a->a.in_addr.s_addr = inet_addr("192.0.2.1");
425 log_info("A: %s", strna(dns_resource_record_to_string(a)));
427 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "www.example.net.");
428 assert_se(rrsig);
430 rrsig->rrsig.type_covered = DNS_TYPE_A;
431 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ECDSAP384SHA384;
432 rrsig->rrsig.labels = 3;
433 rrsig->rrsig.expiration = 1284027625;
434 rrsig->rrsig.inception = 1281608425;
435 rrsig->rrsig.key_tag = 10771;
436 rrsig->rrsig.original_ttl = 3600;
437 rrsig->rrsig.signer = strdup("example.net.");
438 assert_se(rrsig->rrsig.signer);
439 rrsig->rrsig.signature_size = sizeof(signature_blob);
440 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
441 assert_se(rrsig->rrsig.signature);
443 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
445 assert_se(dnssec_key_match_rrsig(a->key, rrsig) > 0);
446 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
448 answer = dns_answer_new(1);
449 assert_se(answer);
450 assert_se(dns_answer_add(answer, a, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
452 assert_se(dnssec_verify_rrset(answer, a->key, rrsig, dnskey,
453 rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
454 assert_se(result == DNSSEC_VALIDATED);
457 TEST(dnssec_verify_rrset) {
458 static const uint8_t signature_blob[] = {
459 0x7f, 0x79, 0xdd, 0x5e, 0x89, 0x79, 0x18, 0xd0, 0x34, 0x86, 0x8c, 0x72, 0x77, 0x75, 0x48, 0x4d,
460 0xc3, 0x7d, 0x38, 0x04, 0xab, 0xcd, 0x9e, 0x4c, 0x82, 0xb0, 0x92, 0xca, 0xe9, 0x66, 0xe9, 0x6e,
461 0x47, 0xc7, 0x68, 0x8c, 0x94, 0xf6, 0x69, 0xcb, 0x75, 0x94, 0xe6, 0x30, 0xa6, 0xfb, 0x68, 0x64,
462 0x96, 0x1a, 0x84, 0xe1, 0xdc, 0x16, 0x4c, 0x83, 0x6c, 0x44, 0xf2, 0x74, 0x4d, 0x74, 0x79, 0x8f,
463 0xf3, 0xf4, 0x63, 0x0d, 0xef, 0x5a, 0xe7, 0xe2, 0xfd, 0xf2, 0x2b, 0x38, 0x7c, 0x28, 0x96, 0x9d,
464 0xb6, 0xcd, 0x5c, 0x3b, 0x57, 0xe2, 0x24, 0x78, 0x65, 0xd0, 0x9e, 0x77, 0x83, 0x09, 0x6c, 0xff,
465 0x3d, 0x52, 0x3f, 0x6e, 0xd1, 0xed, 0x2e, 0xf9, 0xee, 0x8e, 0xa6, 0xbe, 0x9a, 0xa8, 0x87, 0x76,
466 0xd8, 0x77, 0xcc, 0x96, 0xa0, 0x98, 0xa1, 0xd1, 0x68, 0x09, 0x43, 0xcf, 0x56, 0xd9, 0xd1, 0x66,
469 static const uint8_t dnskey_blob[] = {
470 0x03, 0x01, 0x00, 0x01, 0x9b, 0x49, 0x9b, 0xc1, 0xf9, 0x9a, 0xe0, 0x4e, 0xcf, 0xcb, 0x14, 0x45,
471 0x2e, 0xc9, 0xf9, 0x74, 0xa7, 0x18, 0xb5, 0xf3, 0xde, 0x39, 0x49, 0xdf, 0x63, 0x33, 0x97, 0x52,
472 0xe0, 0x8e, 0xac, 0x50, 0x30, 0x8e, 0x09, 0xd5, 0x24, 0x3d, 0x26, 0xa4, 0x49, 0x37, 0x2b, 0xb0,
473 0x6b, 0x1b, 0xdf, 0xde, 0x85, 0x83, 0xcb, 0x22, 0x4e, 0x60, 0x0a, 0x91, 0x1a, 0x1f, 0xc5, 0x40,
474 0xb1, 0xc3, 0x15, 0xc1, 0x54, 0x77, 0x86, 0x65, 0x53, 0xec, 0x10, 0x90, 0x0c, 0x91, 0x00, 0x5e,
475 0x15, 0xdc, 0x08, 0x02, 0x4c, 0x8c, 0x0d, 0xc0, 0xac, 0x6e, 0xc4, 0x3e, 0x1b, 0x80, 0x19, 0xe4,
476 0xf7, 0x5f, 0x77, 0x51, 0x06, 0x87, 0x61, 0xde, 0xa2, 0x18, 0x0f, 0x40, 0x8b, 0x79, 0x72, 0xfa,
477 0x8d, 0x1a, 0x44, 0x47, 0x0d, 0x8e, 0x3a, 0x2d, 0xc7, 0x39, 0xbf, 0x56, 0x28, 0x97, 0xd9, 0x20,
478 0x4f, 0x00, 0x51, 0x3b,
481 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *a = NULL, *rrsig = NULL, *dnskey = NULL;
482 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
483 DnssecResult result;
485 a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "nAsA.gov");
486 assert_se(a);
488 a->a.in_addr.s_addr = inet_addr("52.0.14.116");
490 log_info("A: %s", strna(dns_resource_record_to_string(a)));
492 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV.");
493 assert_se(rrsig);
495 rrsig->rrsig.type_covered = DNS_TYPE_A;
496 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
497 rrsig->rrsig.labels = 2;
498 rrsig->rrsig.original_ttl = 600;
499 rrsig->rrsig.expiration = 0x5683135c;
500 rrsig->rrsig.inception = 0x565b7da8;
501 rrsig->rrsig.key_tag = 63876;
502 rrsig->rrsig.signer = strdup("Nasa.Gov.");
503 assert_se(rrsig->rrsig.signer);
504 rrsig->rrsig.signature_size = sizeof(signature_blob);
505 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
506 assert_se(rrsig->rrsig.signature);
508 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
510 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV");
511 assert_se(dnskey);
513 dnskey->dnskey.flags = 256;
514 dnskey->dnskey.protocol = 3;
515 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
516 dnskey->dnskey.key_size = sizeof(dnskey_blob);
517 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
518 assert_se(dnskey->dnskey.key);
520 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
521 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
523 assert_se(dnssec_key_match_rrsig(a->key, rrsig) > 0);
524 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
526 answer = dns_answer_new(1);
527 assert_se(answer);
528 assert_se(dns_answer_add(answer, a, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
530 /* Validate the RR as it if was 2015-12-2 today */
531 assert_se(dnssec_verify_rrset(answer, a->key, rrsig, dnskey, 1449092754*USEC_PER_SEC, &result) >= 0);
532 assert_se(result == DNSSEC_VALIDATED);
535 TEST(dnssec_verify_rrset2) {
536 static const uint8_t signature_blob[] = {
537 0x48, 0x45, 0xc8, 0x8b, 0xc0, 0x14, 0x92, 0xf5, 0x15, 0xc6, 0x84, 0x9d, 0x2f, 0xe3, 0x32, 0x11,
538 0x7d, 0xf1, 0xe6, 0x87, 0xb9, 0x42, 0xd3, 0x8b, 0x9e, 0xaf, 0x92, 0x31, 0x0a, 0x53, 0xad, 0x8b,
539 0xa7, 0x5c, 0x83, 0x39, 0x8c, 0x28, 0xac, 0xce, 0x6e, 0x9c, 0x18, 0xe3, 0x31, 0x16, 0x6e, 0xca,
540 0x38, 0x31, 0xaf, 0xd9, 0x94, 0xf1, 0x84, 0xb1, 0xdf, 0x5a, 0xc2, 0x73, 0x22, 0xf6, 0xcb, 0xa2,
541 0xe7, 0x8c, 0x77, 0x0c, 0x74, 0x2f, 0xc2, 0x13, 0xb0, 0x93, 0x51, 0xa9, 0x4f, 0xae, 0x0a, 0xda,
542 0x45, 0xcc, 0xfd, 0x43, 0x99, 0x36, 0x9a, 0x0d, 0x21, 0xe0, 0xeb, 0x30, 0x65, 0xd4, 0xa0, 0x27,
543 0x37, 0x3b, 0xe4, 0xc1, 0xc5, 0xa1, 0x2a, 0xd1, 0x76, 0xc4, 0x7e, 0x64, 0x0e, 0x5a, 0xa6, 0x50,
544 0x24, 0xd5, 0x2c, 0xcc, 0x6d, 0xe5, 0x37, 0xea, 0xbd, 0x09, 0x34, 0xed, 0x24, 0x06, 0xa1, 0x22,
547 static const uint8_t dnskey_blob[] = {
548 0x03, 0x01, 0x00, 0x01, 0xc3, 0x7f, 0x1d, 0xd1, 0x1c, 0x97, 0xb1, 0x13, 0x34, 0x3a, 0x9a, 0xea,
549 0xee, 0xd9, 0x5a, 0x11, 0x1b, 0x17, 0xc7, 0xe3, 0xd4, 0xda, 0x20, 0xbc, 0x5d, 0xba, 0x74, 0xe3,
550 0x37, 0x99, 0xec, 0x25, 0xce, 0x93, 0x7f, 0xbd, 0x22, 0x73, 0x7e, 0x14, 0x71, 0xe0, 0x60, 0x07,
551 0xd4, 0x39, 0x8b, 0x5e, 0xe9, 0xba, 0x25, 0xe8, 0x49, 0xe9, 0x34, 0xef, 0xfe, 0x04, 0x5c, 0xa5,
552 0x27, 0xcd, 0xa9, 0xda, 0x70, 0x05, 0x21, 0xab, 0x15, 0x82, 0x24, 0xc3, 0x94, 0xf5, 0xd7, 0xb7,
553 0xc4, 0x66, 0xcb, 0x32, 0x6e, 0x60, 0x2b, 0x55, 0x59, 0x28, 0x89, 0x8a, 0x72, 0xde, 0x88, 0x56,
554 0x27, 0x95, 0xd9, 0xac, 0x88, 0x4f, 0x65, 0x2b, 0x68, 0xfc, 0xe6, 0x41, 0xc1, 0x1b, 0xef, 0x4e,
555 0xd6, 0xc2, 0x0f, 0x64, 0x88, 0x95, 0x5e, 0xdd, 0x3a, 0x02, 0x07, 0x50, 0xa9, 0xda, 0xa4, 0x49,
556 0x74, 0x62, 0xfe, 0xd7,
559 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *nsec = NULL, *rrsig = NULL, *dnskey = NULL;
560 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
561 DnssecResult result;
563 nsec = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC, "nasa.gov");
564 assert_se(nsec);
566 nsec->nsec.next_domain_name = strdup("3D-Printing.nasa.gov");
567 assert_se(nsec->nsec.next_domain_name);
569 nsec->nsec.types = bitmap_new();
570 assert_se(nsec->nsec.types);
571 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_A) >= 0);
572 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NS) >= 0);
573 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_SOA) >= 0);
574 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_MX) >= 0);
575 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_TXT) >= 0);
576 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_RRSIG) >= 0);
577 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NSEC) >= 0);
578 assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_DNSKEY) >= 0);
579 assert_se(bitmap_set(nsec->nsec.types, 65534) >= 0);
581 log_info("NSEC: %s", strna(dns_resource_record_to_string(nsec)));
583 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV.");
584 assert_se(rrsig);
586 rrsig->rrsig.type_covered = DNS_TYPE_NSEC;
587 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
588 rrsig->rrsig.labels = 2;
589 rrsig->rrsig.original_ttl = 300;
590 rrsig->rrsig.expiration = 0x5689002f;
591 rrsig->rrsig.inception = 0x56617230;
592 rrsig->rrsig.key_tag = 30390;
593 rrsig->rrsig.signer = strdup("Nasa.Gov.");
594 assert_se(rrsig->rrsig.signer);
595 rrsig->rrsig.signature_size = sizeof(signature_blob);
596 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
597 assert_se(rrsig->rrsig.signature);
599 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
601 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV");
602 assert_se(dnskey);
604 dnskey->dnskey.flags = 256;
605 dnskey->dnskey.protocol = 3;
606 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
607 dnskey->dnskey.key_size = sizeof(dnskey_blob);
608 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
609 assert_se(dnskey->dnskey.key);
611 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
612 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
614 assert_se(dnssec_key_match_rrsig(nsec->key, rrsig) > 0);
615 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
617 answer = dns_answer_new(1);
618 assert_se(answer);
619 assert_se(dns_answer_add(answer, nsec, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
621 /* Validate the RR as it if was 2015-12-11 today */
622 assert_se(dnssec_verify_rrset(answer, nsec->key, rrsig, dnskey, 1449849318*USEC_PER_SEC, &result) >= 0);
623 assert_se(result == DNSSEC_VALIDATED);
626 TEST(dnssec_verify_rrset3) {
627 static const uint8_t signature_blob[] = {
628 0x41, 0x09, 0x08, 0x67, 0x51, 0x6d, 0x02, 0xf2, 0x17, 0x1e, 0x61, 0x03, 0xc6, 0x80, 0x7a, 0x82,
629 0x8f, 0x6c, 0x8c, 0x4c, 0x68, 0x6f, 0x1c, 0xaa, 0x4a, 0xe0, 0x9b, 0x72, 0xdf, 0x7f, 0x15, 0xfa,
630 0x2b, 0xc5, 0x63, 0x6f, 0x52, 0xa2, 0x60, 0x59, 0x24, 0xb6, 0xc3, 0x43, 0x3d, 0x47, 0x38, 0xd8,
631 0x0c, 0xcc, 0x6c, 0x10, 0x49, 0x92, 0x97, 0x6c, 0x7d, 0x32, 0xc2, 0x62, 0x83, 0x34, 0x96, 0xdf,
632 0xbd, 0xf9, 0xcc, 0xcf, 0xd9, 0x4d, 0x8b, 0x8a, 0xa9, 0x3c, 0x1f, 0x89, 0xc4, 0xad, 0xd5, 0xbb,
633 0x74, 0xf8, 0xee, 0x60, 0x54, 0x7a, 0xec, 0x36, 0x45, 0xf2, 0xec, 0xb9, 0x73, 0x66, 0xae, 0x57,
634 0x2d, 0xd4, 0x91, 0x02, 0x99, 0xcd, 0xba, 0xbd, 0x6e, 0xfb, 0xa6, 0xf6, 0x34, 0xce, 0x4c, 0x44,
635 0x0b, 0xd2, 0x66, 0xdb, 0x4e, 0x5e, 0x00, 0x72, 0x1b, 0xe5, 0x2f, 0x24, 0xd2, 0xc8, 0x72, 0x37,
636 0x97, 0x2b, 0xd0, 0xcd, 0xa9, 0x6b, 0x84, 0x32, 0x56, 0x7a, 0x89, 0x6e, 0x3d, 0x8f, 0x03, 0x9a,
637 0x9d, 0x6d, 0xf7, 0xe5, 0x13, 0xd7, 0x4b, 0xbc, 0xe2, 0x6c, 0xd1, 0x18, 0x60, 0x0e, 0x1a, 0xe3,
638 0xf9, 0xc0, 0x34, 0x4b, 0x1c, 0x82, 0x17, 0x5e, 0xdf, 0x81, 0x32, 0xd7, 0x5b, 0x30, 0x1d, 0xe0,
639 0x29, 0x80, 0x6b, 0xb1, 0x69, 0xbf, 0x3f, 0x12, 0x56, 0xb0, 0x80, 0x91, 0x22, 0x1a, 0x31, 0xd5,
640 0x5d, 0x3d, 0xdd, 0x70, 0x5e, 0xcb, 0xc7, 0x2d, 0xb8, 0x3e, 0x54, 0x34, 0xd3, 0x50, 0x89, 0x77,
641 0x08, 0xc1, 0xf7, 0x11, 0x6e, 0x57, 0xd7, 0x09, 0x94, 0x20, 0x03, 0x38, 0xc3, 0x3a, 0xd3, 0x93,
642 0x8f, 0xd0, 0x65, 0xc5, 0xa1, 0xe0, 0x69, 0x2c, 0xf6, 0x0a, 0xce, 0x01, 0xb6, 0x0d, 0x95, 0xa0,
643 0x5d, 0x97, 0x94, 0xc3, 0xf1, 0xcd, 0x49, 0xea, 0x20, 0xd3, 0xa9, 0xa6, 0x67, 0x94, 0x64, 0x17
646 static const uint8_t dnskey_blob[] = {
647 0x03, 0x01, 0x00, 0x01, 0xbf, 0xdd, 0x24, 0x95, 0x21, 0x70, 0xa8, 0x5b, 0x19, 0xa6, 0x76, 0xd3,
648 0x5b, 0x37, 0xcf, 0x59, 0x0d, 0x3c, 0xdb, 0x0c, 0xcf, 0xd6, 0x19, 0x02, 0xc7, 0x8e, 0x56, 0x4d,
649 0x14, 0xb7, 0x9d, 0x71, 0xf4, 0xdd, 0x24, 0x36, 0xc8, 0x32, 0x1c, 0x63, 0xf7, 0xc0, 0xfc, 0xe3,
650 0x83, 0xa6, 0x22, 0x8b, 0x6a, 0x34, 0x41, 0x72, 0xaa, 0x95, 0x98, 0x06, 0xac, 0x03, 0xec, 0xc3,
651 0xa1, 0x6d, 0x8b, 0x1b, 0xfd, 0xa4, 0x05, 0x72, 0xe6, 0xe0, 0xb9, 0x98, 0x07, 0x54, 0x7a, 0xb2,
652 0x55, 0x30, 0x96, 0xa3, 0x22, 0x3b, 0xe0, 0x9d, 0x61, 0xf6, 0xdc, 0x31, 0x2b, 0xc9, 0x2c, 0x12,
653 0x06, 0x7f, 0x3c, 0x5d, 0x29, 0x76, 0x01, 0x62, 0xe3, 0x41, 0x41, 0x4f, 0xa6, 0x07, 0xfa, 0x2d,
654 0x0c, 0x64, 0x88, 0xd1, 0x56, 0x18, 0x4b, 0x2b, 0xc2, 0x19, 0x7e, 0xd0, 0x1a, 0x8c, 0x2d, 0x8d,
655 0x06, 0xdf, 0x4d, 0xaf, 0xd9, 0xe3, 0x31, 0x59, 0xbc, 0xc3, 0x36, 0x22, 0xe7, 0x15, 0xf9, 0xb2,
656 0x44, 0x8a, 0x33, 0xd7, 0x6c, 0xf1, 0xcc, 0x37, 0x05, 0x69, 0x32, 0x71, 0x76, 0xd8, 0x50, 0x06,
657 0xae, 0x27, 0xed, 0x3b, 0xdb, 0x1a, 0x97, 0x9b, 0xa3, 0x3e, 0x40, 0x42, 0x29, 0xaf, 0x75, 0x1c,
658 0xff, 0x1d, 0xaf, 0x85, 0x02, 0xb3, 0x2e, 0x99, 0x67, 0x08, 0x13, 0xd5, 0xda, 0x6d, 0x65, 0xb2,
659 0x36, 0x6f, 0x2f, 0x64, 0xe0, 0xfa, 0xd3, 0x81, 0x86, 0x6b, 0x41, 0x3e, 0x91, 0xaa, 0x0a, 0xd3,
660 0xb2, 0x92, 0xd9, 0x42, 0x36, 0x8a, 0x11, 0x0b, 0x5b, 0xb0, 0xea, 0xad, 0x76, 0xd5, 0xb4, 0x81,
661 0x30, 0xca, 0x5c, 0x4f, 0xd9, 0xea, 0xe7, 0x4b, 0x10, 0x0a, 0x09, 0x4b, 0x73, 0x66, 0xed, 0x8e,
662 0x84, 0xa2, 0x4f, 0x93, 0x7e, 0x29, 0xdc, 0x6a, 0xbd, 0x12, 0xa1, 0x3d, 0xd2, 0xd6, 0x2a, 0x67,
663 0x99, 0x4d, 0xf3, 0x43
666 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *mx1 = NULL, *mx2 = NULL, *mx3 = NULL, *mx4 = NULL, *rrsig = NULL, *dnskey = NULL;
667 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
668 DnssecResult result;
670 mx1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se");
671 assert_se(mx1);
673 mx1->mx.priority = 1;
674 mx1->mx.exchange = strdup("ASPMX.L.GOOGLE.COM");
675 assert_se(mx1->mx.exchange);
677 log_info("MX: %s", strna(dns_resource_record_to_string(mx1)));
679 mx2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se");
680 assert_se(mx2);
682 mx2->mx.priority = 5;
683 mx2->mx.exchange = strdup("ALT2.ASPMX.L.GOOGLE.COM");
684 assert_se(mx2->mx.exchange);
686 log_info("MX: %s", strna(dns_resource_record_to_string(mx2)));
688 mx3 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se");
689 assert_se(mx3);
691 mx3->mx.priority = 10;
692 mx3->mx.exchange = strdup("ASPMX2.GOOGLEMAIL.COM");
693 assert_se(mx3->mx.exchange);
695 log_info("MX: %s", strna(dns_resource_record_to_string(mx3)));
697 mx4 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se");
698 assert_se(mx4);
700 mx4->mx.priority = 10;
701 mx4->mx.exchange = strdup("ASPMX3.GOOGLEMAIL.COM");
702 assert_se(mx4->mx.exchange);
704 log_info("MX: %s", strna(dns_resource_record_to_string(mx4)));
706 rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "kodapan.se");
707 assert_se(rrsig);
709 rrsig->rrsig.type_covered = DNS_TYPE_MX;
710 rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
711 rrsig->rrsig.labels = 2;
712 rrsig->rrsig.original_ttl = 900;
713 rrsig->rrsig.expiration = 0x5e608a84;
714 rrsig->rrsig.inception = 0x5e4e1584;
715 rrsig->rrsig.key_tag = 44028;
716 rrsig->rrsig.signer = strdup("kodapan.se.");
717 assert_se(rrsig->rrsig.signer);
718 rrsig->rrsig.signature_size = sizeof(signature_blob);
719 rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
720 assert_se(rrsig->rrsig.signature);
722 log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
724 dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "kodapan.se");
725 assert_se(dnskey);
727 dnskey->dnskey.flags = 256;
728 dnskey->dnskey.protocol = 3;
729 dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
730 dnskey->dnskey.key_size = sizeof(dnskey_blob);
731 dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
732 assert_se(dnskey->dnskey.key);
734 log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
735 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
737 assert_se(dnssec_key_match_rrsig(mx1->key, rrsig) > 0);
738 assert_se(dnssec_key_match_rrsig(mx2->key, rrsig) > 0);
739 assert_se(dnssec_key_match_rrsig(mx3->key, rrsig) > 0);
740 assert_se(dnssec_key_match_rrsig(mx4->key, rrsig) > 0);
741 assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
743 answer = dns_answer_new(4);
744 assert_se(answer);
745 assert_se(dns_answer_add(answer, mx1, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
746 assert_se(dns_answer_add(answer, mx2, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
747 assert_se(dns_answer_add(answer, mx3, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
748 assert_se(dns_answer_add(answer, mx4, 0, DNS_ANSWER_AUTHENTICATED, NULL) >= 0);
750 /* Validate the RR as it if was 2020-02-24 today */
751 assert_se(dnssec_verify_rrset(answer, mx1->key, rrsig, dnskey, 1582534685*USEC_PER_SEC, &result) >= 0);
752 assert_se(result == DNSSEC_VALIDATED);
755 TEST(dnssec_nsec3_hash) {
756 static const uint8_t salt[] = { 0xB0, 0x1D, 0xFA, 0xCE };
757 static const uint8_t next_hashed_name[] = { 0x84, 0x10, 0x26, 0x53, 0xc9, 0xfa, 0x4d, 0x85, 0x6c, 0x97, 0x82, 0xe2, 0x8f, 0xdf, 0x2d, 0x5e, 0x87, 0x69, 0xc4, 0x52 };
758 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
759 uint8_t h[DNSSEC_HASH_SIZE_MAX];
760 _cleanup_free_ char *b = NULL;
761 int k;
763 /* The NSEC3 RR for eurid.eu on 2015-12-14. */
764 rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC3, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM.eurid.eu.");
765 assert_se(rr);
767 rr->nsec3.algorithm = DNSSEC_DIGEST_SHA1;
768 rr->nsec3.flags = 1;
769 rr->nsec3.iterations = 1;
770 rr->nsec3.salt = memdup(salt, sizeof(salt));
771 assert_se(rr->nsec3.salt);
772 rr->nsec3.salt_size = sizeof(salt);
773 rr->nsec3.next_hashed_name = memdup(next_hashed_name, sizeof(next_hashed_name));
774 assert_se(rr->nsec3.next_hashed_name);
775 rr->nsec3.next_hashed_name_size = sizeof(next_hashed_name);
777 log_info("NSEC3: %s", strna(dns_resource_record_to_string(rr)));
779 k = dnssec_nsec3_hash(rr, "eurid.eu", &h);
780 assert_se(k >= 0);
782 b = base32hexmem(h, k, false);
783 assert_se(b);
784 assert_se(strcasecmp(b, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM") == 0);
787 DEFINE_TEST_MAIN(LOG_INFO);