1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2015 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <arpa/inet.h>
23 #include <netinet/in.h>
24 #include <sys/socket.h>
26 #include "alloc-util.h"
27 #include "resolved-dns-dnssec.h"
28 #include "resolved-dns-rr.h"
29 #include "string-util.h"
30 #include "hexdecoct.h"
32 static void test_dnssec_verify_rrset2(void) {
34 static const uint8_t signature_blob
[] = {
35 0x48, 0x45, 0xc8, 0x8b, 0xc0, 0x14, 0x92, 0xf5, 0x15, 0xc6, 0x84, 0x9d, 0x2f, 0xe3, 0x32, 0x11,
36 0x7d, 0xf1, 0xe6, 0x87, 0xb9, 0x42, 0xd3, 0x8b, 0x9e, 0xaf, 0x92, 0x31, 0x0a, 0x53, 0xad, 0x8b,
37 0xa7, 0x5c, 0x83, 0x39, 0x8c, 0x28, 0xac, 0xce, 0x6e, 0x9c, 0x18, 0xe3, 0x31, 0x16, 0x6e, 0xca,
38 0x38, 0x31, 0xaf, 0xd9, 0x94, 0xf1, 0x84, 0xb1, 0xdf, 0x5a, 0xc2, 0x73, 0x22, 0xf6, 0xcb, 0xa2,
39 0xe7, 0x8c, 0x77, 0x0c, 0x74, 0x2f, 0xc2, 0x13, 0xb0, 0x93, 0x51, 0xa9, 0x4f, 0xae, 0x0a, 0xda,
40 0x45, 0xcc, 0xfd, 0x43, 0x99, 0x36, 0x9a, 0x0d, 0x21, 0xe0, 0xeb, 0x30, 0x65, 0xd4, 0xa0, 0x27,
41 0x37, 0x3b, 0xe4, 0xc1, 0xc5, 0xa1, 0x2a, 0xd1, 0x76, 0xc4, 0x7e, 0x64, 0x0e, 0x5a, 0xa6, 0x50,
42 0x24, 0xd5, 0x2c, 0xcc, 0x6d, 0xe5, 0x37, 0xea, 0xbd, 0x09, 0x34, 0xed, 0x24, 0x06, 0xa1, 0x22,
45 static const uint8_t dnskey_blob
[] = {
46 0x03, 0x01, 0x00, 0x01, 0xc3, 0x7f, 0x1d, 0xd1, 0x1c, 0x97, 0xb1, 0x13, 0x34, 0x3a, 0x9a, 0xea,
47 0xee, 0xd9, 0x5a, 0x11, 0x1b, 0x17, 0xc7, 0xe3, 0xd4, 0xda, 0x20, 0xbc, 0x5d, 0xba, 0x74, 0xe3,
48 0x37, 0x99, 0xec, 0x25, 0xce, 0x93, 0x7f, 0xbd, 0x22, 0x73, 0x7e, 0x14, 0x71, 0xe0, 0x60, 0x07,
49 0xd4, 0x39, 0x8b, 0x5e, 0xe9, 0xba, 0x25, 0xe8, 0x49, 0xe9, 0x34, 0xef, 0xfe, 0x04, 0x5c, 0xa5,
50 0x27, 0xcd, 0xa9, 0xda, 0x70, 0x05, 0x21, 0xab, 0x15, 0x82, 0x24, 0xc3, 0x94, 0xf5, 0xd7, 0xb7,
51 0xc4, 0x66, 0xcb, 0x32, 0x6e, 0x60, 0x2b, 0x55, 0x59, 0x28, 0x89, 0x8a, 0x72, 0xde, 0x88, 0x56,
52 0x27, 0x95, 0xd9, 0xac, 0x88, 0x4f, 0x65, 0x2b, 0x68, 0xfc, 0xe6, 0x41, 0xc1, 0x1b, 0xef, 0x4e,
53 0xd6, 0xc2, 0x0f, 0x64, 0x88, 0x95, 0x5e, 0xdd, 0x3a, 0x02, 0x07, 0x50, 0xa9, 0xda, 0xa4, 0x49,
54 0x74, 0x62, 0xfe, 0xd7,
57 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*nsec
= NULL
, *rrsig
= NULL
, *dnskey
= NULL
;
58 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
59 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
;
62 nsec
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_NSEC
, "nasa.gov");
65 nsec
->nsec
.next_domain_name
= strdup("3D-Printing.nasa.gov");
66 assert_se(nsec
->nsec
.next_domain_name
);
68 nsec
->nsec
.types
= bitmap_new();
69 assert_se(nsec
->nsec
.types
);
70 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_A
) >= 0);
71 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_NS
) >= 0);
72 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_SOA
) >= 0);
73 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_MX
) >= 0);
74 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_TXT
) >= 0);
75 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_RRSIG
) >= 0);
76 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_NSEC
) >= 0);
77 assert_se(bitmap_set(nsec
->nsec
.types
, DNS_TYPE_DNSKEY
) >= 0);
78 assert_se(bitmap_set(nsec
->nsec
.types
, 65534) >= 0);
80 assert_se(dns_resource_record_to_string(nsec
, &x
) >= 0);
81 log_info("NSEC: %s", x
);
83 rrsig
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_RRSIG
, "NaSa.GOV.");
86 rrsig
->rrsig
.type_covered
= DNS_TYPE_NSEC
;
87 rrsig
->rrsig
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
88 rrsig
->rrsig
.labels
= 2;
89 rrsig
->rrsig
.original_ttl
= 300;
90 rrsig
->rrsig
.expiration
= 0x5689002f;
91 rrsig
->rrsig
.inception
= 0x56617230;
92 rrsig
->rrsig
.key_tag
= 30390;
93 rrsig
->rrsig
.signer
= strdup("Nasa.Gov.");
94 assert_se(rrsig
->rrsig
.signer
);
95 rrsig
->rrsig
.signature_size
= sizeof(signature_blob
);
96 rrsig
->rrsig
.signature
= memdup(signature_blob
, rrsig
->rrsig
.signature_size
);
97 assert_se(rrsig
->rrsig
.signature
);
99 assert_se(dns_resource_record_to_string(rrsig
, &y
) >= 0);
100 log_info("RRSIG: %s", y
);
102 dnskey
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_DNSKEY
, "nASA.gOV");
105 dnskey
->dnskey
.flags
= 256;
106 dnskey
->dnskey
.protocol
= 3;
107 dnskey
->dnskey
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
108 dnskey
->dnskey
.key_size
= sizeof(dnskey_blob
);
109 dnskey
->dnskey
.key
= memdup(dnskey_blob
, sizeof(dnskey_blob
));
110 assert_se(dnskey
->dnskey
.key
);
112 assert_se(dns_resource_record_to_string(dnskey
, &z
) >= 0);
113 log_info("DNSKEY: %s", z
);
114 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey
));
116 assert_se(dnssec_key_match_rrsig(nsec
->key
, rrsig
) > 0);
117 assert_se(dnssec_rrsig_match_dnskey(rrsig
, dnskey
) > 0);
119 answer
= dns_answer_new(1);
121 assert_se(dns_answer_add(answer
, nsec
, 0) >= 0);
123 /* Validate the RR as it if was 2015-12-11 today */
124 assert_se(dnssec_verify_rrset(answer
, nsec
->key
, rrsig
, dnskey
, 1449849318*USEC_PER_SEC
, &result
) >= 0);
125 assert_se(result
== DNSSEC_VALIDATED
);
128 static void test_dnssec_verify_rrset(void) {
130 static const uint8_t signature_blob
[] = {
131 0x7f, 0x79, 0xdd, 0x5e, 0x89, 0x79, 0x18, 0xd0, 0x34, 0x86, 0x8c, 0x72, 0x77, 0x75, 0x48, 0x4d,
132 0xc3, 0x7d, 0x38, 0x04, 0xab, 0xcd, 0x9e, 0x4c, 0x82, 0xb0, 0x92, 0xca, 0xe9, 0x66, 0xe9, 0x6e,
133 0x47, 0xc7, 0x68, 0x8c, 0x94, 0xf6, 0x69, 0xcb, 0x75, 0x94, 0xe6, 0x30, 0xa6, 0xfb, 0x68, 0x64,
134 0x96, 0x1a, 0x84, 0xe1, 0xdc, 0x16, 0x4c, 0x83, 0x6c, 0x44, 0xf2, 0x74, 0x4d, 0x74, 0x79, 0x8f,
135 0xf3, 0xf4, 0x63, 0x0d, 0xef, 0x5a, 0xe7, 0xe2, 0xfd, 0xf2, 0x2b, 0x38, 0x7c, 0x28, 0x96, 0x9d,
136 0xb6, 0xcd, 0x5c, 0x3b, 0x57, 0xe2, 0x24, 0x78, 0x65, 0xd0, 0x9e, 0x77, 0x83, 0x09, 0x6c, 0xff,
137 0x3d, 0x52, 0x3f, 0x6e, 0xd1, 0xed, 0x2e, 0xf9, 0xee, 0x8e, 0xa6, 0xbe, 0x9a, 0xa8, 0x87, 0x76,
138 0xd8, 0x77, 0xcc, 0x96, 0xa0, 0x98, 0xa1, 0xd1, 0x68, 0x09, 0x43, 0xcf, 0x56, 0xd9, 0xd1, 0x66,
141 static const uint8_t dnskey_blob
[] = {
142 0x03, 0x01, 0x00, 0x01, 0x9b, 0x49, 0x9b, 0xc1, 0xf9, 0x9a, 0xe0, 0x4e, 0xcf, 0xcb, 0x14, 0x45,
143 0x2e, 0xc9, 0xf9, 0x74, 0xa7, 0x18, 0xb5, 0xf3, 0xde, 0x39, 0x49, 0xdf, 0x63, 0x33, 0x97, 0x52,
144 0xe0, 0x8e, 0xac, 0x50, 0x30, 0x8e, 0x09, 0xd5, 0x24, 0x3d, 0x26, 0xa4, 0x49, 0x37, 0x2b, 0xb0,
145 0x6b, 0x1b, 0xdf, 0xde, 0x85, 0x83, 0xcb, 0x22, 0x4e, 0x60, 0x0a, 0x91, 0x1a, 0x1f, 0xc5, 0x40,
146 0xb1, 0xc3, 0x15, 0xc1, 0x54, 0x77, 0x86, 0x65, 0x53, 0xec, 0x10, 0x90, 0x0c, 0x91, 0x00, 0x5e,
147 0x15, 0xdc, 0x08, 0x02, 0x4c, 0x8c, 0x0d, 0xc0, 0xac, 0x6e, 0xc4, 0x3e, 0x1b, 0x80, 0x19, 0xe4,
148 0xf7, 0x5f, 0x77, 0x51, 0x06, 0x87, 0x61, 0xde, 0xa2, 0x18, 0x0f, 0x40, 0x8b, 0x79, 0x72, 0xfa,
149 0x8d, 0x1a, 0x44, 0x47, 0x0d, 0x8e, 0x3a, 0x2d, 0xc7, 0x39, 0xbf, 0x56, 0x28, 0x97, 0xd9, 0x20,
150 0x4f, 0x00, 0x51, 0x3b,
153 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*a
= NULL
, *rrsig
= NULL
, *dnskey
= NULL
;
154 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
155 _cleanup_free_
char *x
= NULL
, *y
= NULL
, *z
= NULL
;
158 a
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_A
, "nAsA.gov");
161 a
->a
.in_addr
.s_addr
= inet_addr("52.0.14.116");
163 assert_se(dns_resource_record_to_string(a
, &x
) >= 0);
164 log_info("A: %s", x
);
166 rrsig
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_RRSIG
, "NaSa.GOV.");
169 rrsig
->rrsig
.type_covered
= DNS_TYPE_A
;
170 rrsig
->rrsig
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
171 rrsig
->rrsig
.labels
= 2;
172 rrsig
->rrsig
.original_ttl
= 600;
173 rrsig
->rrsig
.expiration
= 0x5683135c;
174 rrsig
->rrsig
.inception
= 0x565b7da8;
175 rrsig
->rrsig
.key_tag
= 63876;
176 rrsig
->rrsig
.signer
= strdup("Nasa.Gov.");
177 assert_se(rrsig
->rrsig
.signer
);
178 rrsig
->rrsig
.signature_size
= sizeof(signature_blob
);
179 rrsig
->rrsig
.signature
= memdup(signature_blob
, rrsig
->rrsig
.signature_size
);
180 assert_se(rrsig
->rrsig
.signature
);
182 assert_se(dns_resource_record_to_string(rrsig
, &y
) >= 0);
183 log_info("RRSIG: %s", y
);
185 dnskey
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_DNSKEY
, "nASA.gOV");
188 dnskey
->dnskey
.flags
= 256;
189 dnskey
->dnskey
.protocol
= 3;
190 dnskey
->dnskey
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
191 dnskey
->dnskey
.key_size
= sizeof(dnskey_blob
);
192 dnskey
->dnskey
.key
= memdup(dnskey_blob
, sizeof(dnskey_blob
));
193 assert_se(dnskey
->dnskey
.key
);
195 assert_se(dns_resource_record_to_string(dnskey
, &z
) >= 0);
196 log_info("DNSKEY: %s", z
);
197 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey
));
199 assert_se(dnssec_key_match_rrsig(a
->key
, rrsig
) > 0);
200 assert_se(dnssec_rrsig_match_dnskey(rrsig
, dnskey
) > 0);
202 answer
= dns_answer_new(1);
204 assert_se(dns_answer_add(answer
, a
, 0) >= 0);
206 /* Validate the RR as it if was 2015-12-2 today */
207 assert_se(dnssec_verify_rrset(answer
, a
->key
, rrsig
, dnskey
, 1449092754*USEC_PER_SEC
, &result
) >= 0);
208 assert_se(result
== DNSSEC_VALIDATED
);
211 static void test_dnssec_verify_dns_key(void) {
213 static const uint8_t ds1_fprint
[] = {
214 0x46, 0x8B, 0xC8, 0xDD, 0xC7, 0xE8, 0x27, 0x03, 0x40, 0xBB, 0x8A, 0x1F, 0x3B, 0x2E, 0x45, 0x9D,
215 0x80, 0x67, 0x14, 0x01,
217 static const uint8_t ds2_fprint
[] = {
218 0x8A, 0xEE, 0x80, 0x47, 0x05, 0x5F, 0x83, 0xD1, 0x48, 0xBA, 0x8F, 0xF6, 0xDD, 0xA7, 0x60, 0xCE,
219 0x94, 0xF7, 0xC7, 0x5E, 0x52, 0x4C, 0xF2, 0xE9, 0x50, 0xB9, 0x2E, 0xCB, 0xEF, 0x96, 0xB9, 0x98,
221 static const uint8_t dnskey_blob
[] = {
222 0x03, 0x01, 0x00, 0x01, 0xa8, 0x12, 0xda, 0x4f, 0xd2, 0x7d, 0x54, 0x14, 0x0e, 0xcc, 0x5b, 0x5e,
223 0x45, 0x9c, 0x96, 0x98, 0xc0, 0xc0, 0x85, 0x81, 0xb1, 0x47, 0x8c, 0x7d, 0xe8, 0x39, 0x50, 0xcc,
224 0xc5, 0xd0, 0xf2, 0x00, 0x81, 0x67, 0x79, 0xf6, 0xcc, 0x9d, 0xad, 0x6c, 0xbb, 0x7b, 0x6f, 0x48,
225 0x97, 0x15, 0x1c, 0xfd, 0x0b, 0xfe, 0xd3, 0xd7, 0x7d, 0x9f, 0x81, 0x26, 0xd3, 0xc5, 0x65, 0x49,
226 0xcf, 0x46, 0x62, 0xb0, 0x55, 0x6e, 0x47, 0xc7, 0x30, 0xef, 0x51, 0xfb, 0x3e, 0xc6, 0xef, 0xde,
227 0x27, 0x3f, 0xfa, 0x57, 0x2d, 0xa7, 0x1d, 0x80, 0x46, 0x9a, 0x5f, 0x14, 0xb3, 0xb0, 0x2c, 0xbe,
228 0x72, 0xca, 0xdf, 0xb2, 0xff, 0x36, 0x5b, 0x4f, 0xec, 0x58, 0x8e, 0x8d, 0x01, 0xe9, 0xa9, 0xdf,
229 0xb5, 0x60, 0xad, 0x52, 0x4d, 0xfc, 0xa9, 0x3e, 0x8d, 0x35, 0x95, 0xb3, 0x4e, 0x0f, 0xca, 0x45,
230 0x1b, 0xf7, 0xef, 0x3a, 0x88, 0x25, 0x08, 0xc7, 0x4e, 0x06, 0xc1, 0x62, 0x1a, 0xce, 0xd8, 0x77,
231 0xbd, 0x02, 0x65, 0xf8, 0x49, 0xfb, 0xce, 0xf6, 0xa8, 0x09, 0xfc, 0xde, 0xb2, 0x09, 0x9d, 0x39,
232 0xf8, 0x63, 0x9c, 0x32, 0x42, 0x7c, 0xa0, 0x30, 0x86, 0x72, 0x7a, 0x4a, 0xc6, 0xd4, 0xb3, 0x2d,
233 0x24, 0xef, 0x96, 0x3f, 0xc2, 0xda, 0xd3, 0xf2, 0x15, 0x6f, 0xda, 0x65, 0x4b, 0x81, 0x28, 0x68,
234 0xf4, 0xfe, 0x3e, 0x71, 0x4f, 0x50, 0x96, 0x72, 0x58, 0xa1, 0x89, 0xdd, 0x01, 0x61, 0x39, 0x39,
235 0xc6, 0x76, 0xa4, 0xda, 0x02, 0x70, 0x3d, 0xc0, 0xdc, 0x8d, 0x70, 0x72, 0x04, 0x90, 0x79, 0xd4,
236 0xec, 0x65, 0xcf, 0x49, 0x35, 0x25, 0x3a, 0x14, 0x1a, 0x45, 0x20, 0xeb, 0x31, 0xaf, 0x92, 0xba,
237 0x20, 0xd3, 0xcd, 0xa7, 0x13, 0x44, 0xdc, 0xcf, 0xf0, 0x27, 0x34, 0xb9, 0xe7, 0x24, 0x6f, 0x73,
238 0xe7, 0xea, 0x77, 0x03,
241 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*dnskey
= NULL
, *ds1
= NULL
, *ds2
= NULL
;
242 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
;
244 /* The two DS RRs in effect for nasa.gov on 2015-12-01. */
245 ds1
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_DS
, "nasa.gov");
248 ds1
->ds
.key_tag
= 47857;
249 ds1
->ds
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
250 ds1
->ds
.digest_type
= DNSSEC_DIGEST_SHA1
;
251 ds1
->ds
.digest_size
= sizeof(ds1_fprint
);
252 ds1
->ds
.digest
= memdup(ds1_fprint
, ds1
->ds
.digest_size
);
253 assert_se(ds1
->ds
.digest
);
255 assert_se(dns_resource_record_to_string(ds1
, &a
) >= 0);
256 log_info("DS1: %s", a
);
258 ds2
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_DS
, "NASA.GOV");
261 ds2
->ds
.key_tag
= 47857;
262 ds2
->ds
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
263 ds2
->ds
.digest_type
= DNSSEC_DIGEST_SHA256
;
264 ds2
->ds
.digest_size
= sizeof(ds2_fprint
);
265 ds2
->ds
.digest
= memdup(ds2_fprint
, ds2
->ds
.digest_size
);
266 assert_se(ds2
->ds
.digest
);
268 assert_se(dns_resource_record_to_string(ds2
, &b
) >= 0);
269 log_info("DS2: %s", b
);
271 dnskey
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_DNSKEY
, "nasa.GOV");
274 dnskey
->dnskey
.flags
= 257;
275 dnskey
->dnskey
.protocol
= 3;
276 dnskey
->dnskey
.algorithm
= DNSSEC_ALGORITHM_RSASHA256
;
277 dnskey
->dnskey
.key_size
= sizeof(dnskey_blob
);
278 dnskey
->dnskey
.key
= memdup(dnskey_blob
, sizeof(dnskey_blob
));
279 assert_se(dnskey
->dnskey
.key
);
281 assert_se(dns_resource_record_to_string(dnskey
, &c
) >= 0);
282 log_info("DNSKEY: %s", c
);
283 log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey
));
285 assert_se(dnssec_verify_dnskey(dnskey
, ds1
) > 0);
286 assert_se(dnssec_verify_dnskey(dnskey
, ds2
) > 0);
289 static void test_dnssec_canonicalize_one(const char *original
, const char *canonical
, int r
) {
290 char canonicalized
[DNSSEC_CANONICAL_HOSTNAME_MAX
];
292 assert_se(dnssec_canonicalize(original
, canonicalized
, sizeof(canonicalized
)) == r
);
296 assert_se(streq(canonicalized
, canonical
));
299 static void test_dnssec_canonicalize(void) {
300 test_dnssec_canonicalize_one("", ".", 1);
301 test_dnssec_canonicalize_one(".", ".", 1);
302 test_dnssec_canonicalize_one("foo", "foo.", 4);
303 test_dnssec_canonicalize_one("foo.", "foo.", 4);
304 test_dnssec_canonicalize_one("FOO.", "foo.", 4);
305 test_dnssec_canonicalize_one("FOO.bar.", "foo.bar.", 8);
306 test_dnssec_canonicalize_one("FOO..bar.", NULL
, -EINVAL
);
309 static void test_dnssec_nsec3_hash(void) {
310 static const uint8_t salt
[] = { 0xB0, 0x1D, 0xFA, 0xCE };
311 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 };
312 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
313 _cleanup_free_
char *a
= NULL
, *b
= NULL
;
314 uint8_t h
[DNSSEC_HASH_SIZE_MAX
];
317 /* The NSEC3 RR for eurid.eu on 2015-12-14. */
318 rr
= dns_resource_record_new_full(DNS_CLASS_IN
, DNS_TYPE_NSEC3
, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM.eurid.eu.");
321 rr
->nsec3
.algorithm
= DNSSEC_DIGEST_SHA1
;
323 rr
->nsec3
.iterations
= 1;
324 rr
->nsec3
.salt
= memdup(salt
, sizeof(salt
));
325 assert_se(rr
->nsec3
.salt
);
326 rr
->nsec3
.salt_size
= sizeof(salt
);
327 rr
->nsec3
.next_hashed_name
= memdup(next_hashed_name
, sizeof(next_hashed_name
));
328 assert_se(rr
->nsec3
.next_hashed_name
);
329 rr
->nsec3
.next_hashed_name_size
= sizeof(next_hashed_name
);
331 assert_se(dns_resource_record_to_string(rr
, &a
) >= 0);
332 log_info("NSEC3: %s", a
);
334 k
= dnssec_nsec3_hash(rr
, "eurid.eu", &h
);
337 b
= base32hexmem(h
, k
, false);
339 assert_se(strcasecmp(b
, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM") == 0);
342 int main(int argc
, char*argv
[]) {
344 test_dnssec_canonicalize();
345 test_dnssec_verify_dns_key();
346 test_dnssec_verify_rrset();
347 test_dnssec_verify_rrset2();
348 test_dnssec_nsec3_hash();