LCOV - code coverage report
Current view: top level - resolve - test-dnssec.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 272 272 100.0 %
Date: 2019-08-23 13:36:53 Functions: 9 9 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 104 206 50.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <arpa/inet.h>
       4                 :            : #if HAVE_GCRYPT
       5                 :            : #include <gcrypt.h>
       6                 :            : #endif
       7                 :            : #include <netinet/in.h>
       8                 :            : #include <sys/socket.h>
       9                 :            : 
      10                 :            : #include "alloc-util.h"
      11                 :            : #include "resolved-dns-dnssec.h"
      12                 :            : #include "resolved-dns-rr.h"
      13                 :            : #include "string-util.h"
      14                 :            : #include "hexdecoct.h"
      15                 :            : 
      16                 :         28 : static void test_dnssec_canonicalize_one(const char *original, const char *canonical, int r) {
      17                 :            :         char canonicalized[DNSSEC_CANONICAL_HOSTNAME_MAX];
      18                 :            : 
      19         [ -  + ]:         28 :         assert_se(dnssec_canonicalize(original, canonicalized, sizeof(canonicalized)) == r);
      20         [ +  + ]:         28 :         if (r < 0)
      21                 :          4 :                 return;
      22                 :            : 
      23         [ -  + ]:         24 :         assert_se(streq(canonicalized, canonical));
      24                 :            : }
      25                 :            : 
      26                 :          4 : static void test_dnssec_canonicalize(void) {
      27                 :          4 :         test_dnssec_canonicalize_one("", ".", 1);
      28                 :          4 :         test_dnssec_canonicalize_one(".", ".", 1);
      29                 :          4 :         test_dnssec_canonicalize_one("foo", "foo.", 4);
      30                 :          4 :         test_dnssec_canonicalize_one("foo.", "foo.", 4);
      31                 :          4 :         test_dnssec_canonicalize_one("FOO.", "foo.", 4);
      32                 :          4 :         test_dnssec_canonicalize_one("FOO.bar.", "foo.bar.", 8);
      33                 :          4 :         test_dnssec_canonicalize_one("FOO..bar.", NULL, -EINVAL);
      34                 :          4 : }
      35                 :            : 
      36                 :            : #if HAVE_GCRYPT
      37                 :            : 
      38                 :          4 : static void test_dnssec_verify_dns_key(void) {
      39                 :            : 
      40                 :            :         static const uint8_t ds1_fprint[] = {
      41                 :            :                 0x46, 0x8B, 0xC8, 0xDD, 0xC7, 0xE8, 0x27, 0x03, 0x40, 0xBB, 0x8A, 0x1F, 0x3B, 0x2E, 0x45, 0x9D,
      42                 :            :                 0x80, 0x67, 0x14, 0x01,
      43                 :            :         };
      44                 :            :         static const uint8_t ds2_fprint[] = {
      45                 :            :                 0x8A, 0xEE, 0x80, 0x47, 0x05, 0x5F, 0x83, 0xD1, 0x48, 0xBA, 0x8F, 0xF6, 0xDD, 0xA7, 0x60, 0xCE,
      46                 :            :                 0x94, 0xF7, 0xC7, 0x5E, 0x52, 0x4C, 0xF2, 0xE9, 0x50, 0xB9, 0x2E, 0xCB, 0xEF, 0x96, 0xB9, 0x98,
      47                 :            :         };
      48                 :            :         static const uint8_t dnskey_blob[] = {
      49                 :            :                 0x03, 0x01, 0x00, 0x01, 0xa8, 0x12, 0xda, 0x4f, 0xd2, 0x7d, 0x54, 0x14, 0x0e, 0xcc, 0x5b, 0x5e,
      50                 :            :                 0x45, 0x9c, 0x96, 0x98, 0xc0, 0xc0, 0x85, 0x81, 0xb1, 0x47, 0x8c, 0x7d, 0xe8, 0x39, 0x50, 0xcc,
      51                 :            :                 0xc5, 0xd0, 0xf2, 0x00, 0x81, 0x67, 0x79, 0xf6, 0xcc, 0x9d, 0xad, 0x6c, 0xbb, 0x7b, 0x6f, 0x48,
      52                 :            :                 0x97, 0x15, 0x1c, 0xfd, 0x0b, 0xfe, 0xd3, 0xd7, 0x7d, 0x9f, 0x81, 0x26, 0xd3, 0xc5, 0x65, 0x49,
      53                 :            :                 0xcf, 0x46, 0x62, 0xb0, 0x55, 0x6e, 0x47, 0xc7, 0x30, 0xef, 0x51, 0xfb, 0x3e, 0xc6, 0xef, 0xde,
      54                 :            :                 0x27, 0x3f, 0xfa, 0x57, 0x2d, 0xa7, 0x1d, 0x80, 0x46, 0x9a, 0x5f, 0x14, 0xb3, 0xb0, 0x2c, 0xbe,
      55                 :            :                 0x72, 0xca, 0xdf, 0xb2, 0xff, 0x36, 0x5b, 0x4f, 0xec, 0x58, 0x8e, 0x8d, 0x01, 0xe9, 0xa9, 0xdf,
      56                 :            :                 0xb5, 0x60, 0xad, 0x52, 0x4d, 0xfc, 0xa9, 0x3e, 0x8d, 0x35, 0x95, 0xb3, 0x4e, 0x0f, 0xca, 0x45,
      57                 :            :                 0x1b, 0xf7, 0xef, 0x3a, 0x88, 0x25, 0x08, 0xc7, 0x4e, 0x06, 0xc1, 0x62, 0x1a, 0xce, 0xd8, 0x77,
      58                 :            :                 0xbd, 0x02, 0x65, 0xf8, 0x49, 0xfb, 0xce, 0xf6, 0xa8, 0x09, 0xfc, 0xde, 0xb2, 0x09, 0x9d, 0x39,
      59                 :            :                 0xf8, 0x63, 0x9c, 0x32, 0x42, 0x7c, 0xa0, 0x30, 0x86, 0x72, 0x7a, 0x4a, 0xc6, 0xd4, 0xb3, 0x2d,
      60                 :            :                 0x24, 0xef, 0x96, 0x3f, 0xc2, 0xda, 0xd3, 0xf2, 0x15, 0x6f, 0xda, 0x65, 0x4b, 0x81, 0x28, 0x68,
      61                 :            :                 0xf4, 0xfe, 0x3e, 0x71, 0x4f, 0x50, 0x96, 0x72, 0x58, 0xa1, 0x89, 0xdd, 0x01, 0x61, 0x39, 0x39,
      62                 :            :                 0xc6, 0x76, 0xa4, 0xda, 0x02, 0x70, 0x3d, 0xc0, 0xdc, 0x8d, 0x70, 0x72, 0x04, 0x90, 0x79, 0xd4,
      63                 :            :                 0xec, 0x65, 0xcf, 0x49, 0x35, 0x25, 0x3a, 0x14, 0x1a, 0x45, 0x20, 0xeb, 0x31, 0xaf, 0x92, 0xba,
      64                 :            :                 0x20, 0xd3, 0xcd, 0xa7, 0x13, 0x44, 0xdc, 0xcf, 0xf0, 0x27, 0x34, 0xb9, 0xe7, 0x24, 0x6f, 0x73,
      65                 :            :                 0xe7, 0xea, 0x77, 0x03,
      66                 :            :         };
      67                 :            : 
      68                 :          4 :         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds1 = NULL, *ds2 = NULL;
      69                 :            : 
      70                 :            :         /* The two DS RRs in effect for nasa.gov on 2015-12-01. */
      71                 :          4 :         ds1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "nasa.gov");
      72         [ -  + ]:          4 :         assert_se(ds1);
      73                 :            : 
      74                 :          4 :         ds1->ds.key_tag = 47857;
      75                 :          4 :         ds1->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
      76                 :          4 :         ds1->ds.digest_type = DNSSEC_DIGEST_SHA1;
      77                 :          4 :         ds1->ds.digest_size = sizeof(ds1_fprint);
      78                 :          4 :         ds1->ds.digest = memdup(ds1_fprint, ds1->ds.digest_size);
      79         [ -  + ]:          4 :         assert_se(ds1->ds.digest);
      80                 :            : 
      81         [ +  - ]:          4 :         log_info("DS1: %s", strna(dns_resource_record_to_string(ds1)));
      82                 :            : 
      83                 :          4 :         ds2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "NASA.GOV");
      84         [ -  + ]:          4 :         assert_se(ds2);
      85                 :            : 
      86                 :          4 :         ds2->ds.key_tag = 47857;
      87                 :          4 :         ds2->ds.algorithm = DNSSEC_ALGORITHM_RSASHA256;
      88                 :          4 :         ds2->ds.digest_type = DNSSEC_DIGEST_SHA256;
      89                 :          4 :         ds2->ds.digest_size = sizeof(ds2_fprint);
      90                 :          4 :         ds2->ds.digest = memdup(ds2_fprint, ds2->ds.digest_size);
      91         [ -  + ]:          4 :         assert_se(ds2->ds.digest);
      92                 :            : 
      93         [ +  - ]:          4 :         log_info("DS2: %s", strna(dns_resource_record_to_string(ds2)));
      94                 :            : 
      95                 :          4 :         dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nasa.GOV");
      96         [ -  + ]:          4 :         assert_se(dnskey);
      97                 :            : 
      98                 :          4 :         dnskey->dnskey.flags = 257;
      99                 :          4 :         dnskey->dnskey.protocol = 3;
     100                 :          4 :         dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
     101                 :          4 :         dnskey->dnskey.key_size = sizeof(dnskey_blob);
     102                 :          4 :         dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
     103         [ -  + ]:          4 :         assert_se(dnskey->dnskey.key);
     104                 :            : 
     105         [ +  - ]:          4 :         log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
     106         [ +  - ]:          4 :         log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
     107                 :            : 
     108         [ -  + ]:          4 :         assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds1, false) > 0);
     109         [ -  + ]:          4 :         assert_se(dnssec_verify_dnskey_by_ds(dnskey, ds2, false) > 0);
     110                 :          4 : }
     111                 :            : 
     112                 :          4 : static void test_dnssec_verify_rfc8080_ed25519_example1(void) {
     113                 :            :         static const uint8_t dnskey_blob[] = {
     114                 :            :                 0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, 0x91, 0x47, 0x7d,
     115                 :            :                 0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59,
     116                 :            :                 0x24, 0xe
     117                 :            :         };
     118                 :            :         static const uint8_t ds_fprint[] = {
     119                 :            :                 0xdd, 0xa6, 0xb9, 0x69, 0xbd, 0xfb, 0x79, 0xf7, 0x1e, 0xe7, 0xb7, 0xfb, 0xdf, 0xb7, 0xdc,
     120                 :            :                 0xd7, 0xad, 0xbb, 0xd3, 0x5d, 0xdf, 0x79, 0xed, 0x3b, 0x6d, 0xd7, 0xf6, 0xe3, 0x56, 0xdd,
     121                 :            :                 0xd7, 0x47, 0xf7, 0x6f, 0x5f, 0x7a, 0xe1, 0xa6, 0xf9, 0xe5, 0xce, 0xfc, 0x7b, 0xbf, 0x5a,
     122                 :            :                 0xdf, 0x4e, 0x1b
     123                 :            :         };
     124                 :            :         static const uint8_t signature_blob[] = {
     125                 :            :                 0xa0, 0xbf, 0x64, 0xac, 0x9b, 0xa7, 0xef, 0x17, 0xc1, 0x38, 0x85, 0x9c, 0x18, 0x78, 0xbb,
     126                 :            :                 0x99, 0xa8, 0x39, 0xfe, 0x17, 0x59, 0xac, 0xa5, 0xb0, 0xd7, 0x98, 0xcf, 0x1a, 0xb1, 0xe9,
     127                 :            :                 0x8d, 0x07, 0x91, 0x02, 0xf4, 0xdd, 0xb3, 0x36, 0x8f, 0x0f, 0xe4, 0x0b, 0xb3, 0x77, 0xf1,
     128                 :            :                 0xf0, 0x0e, 0x0c, 0xdd, 0xed, 0xb7, 0x99, 0x16, 0x7d, 0x56, 0xb6, 0xe9, 0x32, 0x78, 0x30,
     129                 :            :                 0x72, 0xba, 0x8d, 0x02
     130                 :            :         };
     131                 :            : 
     132                 :          4 :         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *mx = NULL,
     133                 :          4 :                 *rrsig = NULL;
     134                 :          4 :         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
     135                 :            :         DnssecResult result;
     136                 :            : 
     137                 :          4 :         dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.com.");
     138         [ -  + ]:          4 :         assert_se(dnskey);
     139                 :            : 
     140                 :          4 :         dnskey->dnskey.flags = 257;
     141                 :          4 :         dnskey->dnskey.protocol = 3;
     142                 :          4 :         dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ED25519;
     143                 :          4 :         dnskey->dnskey.key_size = sizeof(dnskey_blob);
     144                 :          4 :         dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
     145         [ -  + ]:          4 :         assert_se(dnskey->dnskey.key);
     146                 :            : 
     147         [ +  - ]:          4 :         log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
     148                 :            : 
     149                 :          4 :         ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.com.");
     150         [ -  + ]:          4 :         assert_se(ds);
     151                 :            : 
     152                 :          4 :         ds->ds.key_tag = 3613;
     153                 :          4 :         ds->ds.algorithm = DNSSEC_ALGORITHM_ED25519;
     154                 :          4 :         ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
     155                 :          4 :         ds->ds.digest_size = sizeof(ds_fprint);
     156                 :          4 :         ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
     157         [ -  + ]:          4 :         assert_se(ds->ds.digest);
     158                 :            : 
     159         [ +  - ]:          4 :         log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
     160                 :            : 
     161                 :          4 :         mx = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "example.com.");
     162         [ -  + ]:          4 :         assert_se(mx);
     163                 :            : 
     164                 :          4 :         mx->mx.priority = 10;
     165                 :          4 :         mx->mx.exchange = strdup("mail.example.com.");
     166         [ -  + ]:          4 :         assert_se(mx->mx.exchange);
     167                 :            : 
     168         [ +  - ]:          4 :         log_info("MX: %s", strna(dns_resource_record_to_string(mx)));
     169                 :            : 
     170                 :          4 :         rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "example.com.");
     171         [ -  + ]:          4 :         assert_se(rrsig);
     172                 :            : 
     173                 :          4 :         rrsig->rrsig.type_covered = DNS_TYPE_MX;
     174                 :          4 :         rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ED25519;
     175                 :          4 :         rrsig->rrsig.labels = 2;
     176                 :          4 :         rrsig->rrsig.original_ttl = 3600;
     177                 :          4 :         rrsig->rrsig.expiration = 1440021600;
     178                 :          4 :         rrsig->rrsig.inception = 1438207200;
     179                 :          4 :         rrsig->rrsig.key_tag = 3613;
     180                 :          4 :         rrsig->rrsig.signer = strdup("example.com.");
     181         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signer);
     182                 :          4 :         rrsig->rrsig.signature_size = sizeof(signature_blob);
     183                 :          4 :         rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
     184         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signature);
     185                 :            : 
     186         [ +  - ]:          4 :         log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
     187                 :            : 
     188         [ -  + ]:          4 :         assert_se(dnssec_key_match_rrsig(mx->key, rrsig) > 0);
     189         [ -  + ]:          4 :         assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
     190                 :            : 
     191                 :          4 :         answer = dns_answer_new(1);
     192         [ -  + ]:          4 :         assert_se(answer);
     193         [ -  + ]:          4 :         assert_se(dns_answer_add(answer, mx, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
     194                 :            : 
     195         [ -  + ]:          4 :         assert_se(dnssec_verify_rrset(answer, mx->key, rrsig, dnskey,
     196                 :            :                                 rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
     197                 :            : #if GCRYPT_VERSION_NUMBER >= 0x010600
     198         [ -  + ]:          4 :         assert_se(result == DNSSEC_VALIDATED);
     199                 :            : #else
     200                 :            :         assert_se(result == DNSSEC_UNSUPPORTED_ALGORITHM);
     201                 :            : #endif
     202                 :          4 : }
     203                 :            : 
     204                 :          4 : static void test_dnssec_verify_rfc8080_ed25519_example2(void) {
     205                 :            :         static const uint8_t dnskey_blob[] = {
     206                 :            :                 0xcc, 0xf9, 0xd9, 0xfd, 0x0c, 0x04, 0x7b, 0xb4, 0xbc, 0x0b, 0x94, 0x8f, 0xcf, 0x63, 0x9f,
     207                 :            :                 0x4b, 0x94, 0x51, 0xe3, 0x40, 0x13, 0x93, 0x6f, 0xeb, 0x62, 0x71, 0x3d, 0xc4, 0x72, 0x4,
     208                 :            :                 0x8a, 0x3b
     209                 :            :         };
     210                 :            :         static const uint8_t ds_fprint[] = {
     211                 :            :                 0xe3, 0x4d, 0x7b, 0xf3, 0x56, 0xfd, 0xdf, 0x87, 0xb7, 0xf7, 0x67, 0x5e, 0xe3, 0xdd, 0x9e,
     212                 :            :                 0x73, 0xbe, 0xda, 0x7b, 0x67, 0xb5, 0xe5, 0xde, 0xf4, 0x7f, 0xae, 0x7b, 0xe5, 0xad, 0x5c,
     213                 :            :                 0xd1, 0xb7, 0x39, 0xf5, 0xce, 0x76, 0xef, 0x97, 0x34, 0xe1, 0xe6, 0xde, 0xf3, 0x47, 0x3a,
     214                 :            :                 0xeb, 0x5e, 0x1c
     215                 :            :         };
     216                 :            :         static const uint8_t signature_blob[] = {
     217                 :            :                 0xcd, 0x74, 0x34, 0x6e, 0x46, 0x20, 0x41, 0x31, 0x05, 0xc9, 0xf2, 0xf2, 0x8b, 0xd4, 0x28,
     218                 :            :                 0x89, 0x8e, 0x83, 0xf1, 0x97, 0x58, 0xa3, 0x8c, 0x32, 0x52, 0x15, 0x62, 0xa1, 0x86, 0x57,
     219                 :            :                 0x15, 0xd4, 0xf8, 0xd7, 0x44, 0x0f, 0x44, 0x84, 0xd0, 0x4a, 0xa2, 0x52, 0x9f, 0x34, 0x28,
     220                 :            :                 0x4a, 0x6e, 0x69, 0xa0, 0x9e, 0xe0, 0x0f, 0xb0, 0x10, 0x47, 0x43, 0xbb, 0x2a, 0xe2, 0x39,
     221                 :            :                 0x93, 0x6a, 0x5c, 0x06
     222                 :            :         };
     223                 :            : 
     224                 :          4 :         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *dnskey = NULL, *ds = NULL, *mx = NULL,
     225                 :          4 :                 *rrsig = NULL;
     226                 :          4 :         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
     227                 :            :         DnssecResult result;
     228                 :            : 
     229                 :          4 :         dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "example.com.");
     230         [ -  + ]:          4 :         assert_se(dnskey);
     231                 :            : 
     232                 :          4 :         dnskey->dnskey.flags = 257;
     233                 :          4 :         dnskey->dnskey.protocol = 3;
     234                 :          4 :         dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_ED25519;
     235                 :          4 :         dnskey->dnskey.key_size = sizeof(dnskey_blob);
     236                 :          4 :         dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
     237         [ -  + ]:          4 :         assert_se(dnskey->dnskey.key);
     238                 :            : 
     239         [ +  - ]:          4 :         log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
     240                 :            : 
     241                 :          4 :         ds = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DS, "example.com.");
     242         [ -  + ]:          4 :         assert_se(ds);
     243                 :            : 
     244                 :          4 :         ds->ds.key_tag = 35217;
     245                 :          4 :         ds->ds.algorithm = DNSSEC_ALGORITHM_ED25519;
     246                 :          4 :         ds->ds.digest_type = DNSSEC_DIGEST_SHA256;
     247                 :          4 :         ds->ds.digest_size = sizeof(ds_fprint);
     248                 :          4 :         ds->ds.digest = memdup(ds_fprint, ds->ds.digest_size);
     249         [ -  + ]:          4 :         assert_se(ds->ds.digest);
     250                 :            : 
     251         [ +  - ]:          4 :         log_info("DS: %s", strna(dns_resource_record_to_string(ds)));
     252                 :            : 
     253                 :          4 :         mx = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "example.com.");
     254         [ -  + ]:          4 :         assert_se(mx);
     255                 :            : 
     256                 :          4 :         mx->mx.priority = 10;
     257                 :          4 :         mx->mx.exchange = strdup("mail.example.com.");
     258         [ -  + ]:          4 :         assert_se(mx->mx.exchange);
     259                 :            : 
     260         [ +  - ]:          4 :         log_info("MX: %s", strna(dns_resource_record_to_string(mx)));
     261                 :            : 
     262                 :          4 :         rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "example.com.");
     263         [ -  + ]:          4 :         assert_se(rrsig);
     264                 :            : 
     265                 :          4 :         rrsig->rrsig.type_covered = DNS_TYPE_MX;
     266                 :          4 :         rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_ED25519;
     267                 :          4 :         rrsig->rrsig.labels = 2;
     268                 :          4 :         rrsig->rrsig.original_ttl = 3600;
     269                 :          4 :         rrsig->rrsig.expiration = 1440021600;
     270                 :          4 :         rrsig->rrsig.inception = 1438207200;
     271                 :          4 :         rrsig->rrsig.key_tag = 35217;
     272                 :          4 :         rrsig->rrsig.signer = strdup("example.com.");
     273         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signer);
     274                 :          4 :         rrsig->rrsig.signature_size = sizeof(signature_blob);
     275                 :          4 :         rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
     276         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signature);
     277                 :            : 
     278         [ +  - ]:          4 :         log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
     279                 :            : 
     280         [ -  + ]:          4 :         assert_se(dnssec_key_match_rrsig(mx->key, rrsig) > 0);
     281         [ -  + ]:          4 :         assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
     282                 :            : 
     283                 :          4 :         answer = dns_answer_new(1);
     284         [ -  + ]:          4 :         assert_se(answer);
     285         [ -  + ]:          4 :         assert_se(dns_answer_add(answer, mx, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
     286                 :            : 
     287         [ -  + ]:          4 :         assert_se(dnssec_verify_rrset(answer, mx->key, rrsig, dnskey,
     288                 :            :                                 rrsig->rrsig.inception * USEC_PER_SEC, &result) >= 0);
     289                 :            : #if GCRYPT_VERSION_NUMBER >= 0x010600
     290         [ -  + ]:          4 :         assert_se(result == DNSSEC_VALIDATED);
     291                 :            : #else
     292                 :            :         assert_se(result == DNSSEC_UNSUPPORTED_ALGORITHM);
     293                 :            : #endif
     294                 :          4 : }
     295                 :          4 : static void test_dnssec_verify_rrset(void) {
     296                 :            : 
     297                 :            :         static const uint8_t signature_blob[] = {
     298                 :            :                 0x7f, 0x79, 0xdd, 0x5e, 0x89, 0x79, 0x18, 0xd0, 0x34, 0x86, 0x8c, 0x72, 0x77, 0x75, 0x48, 0x4d,
     299                 :            :                 0xc3, 0x7d, 0x38, 0x04, 0xab, 0xcd, 0x9e, 0x4c, 0x82, 0xb0, 0x92, 0xca, 0xe9, 0x66, 0xe9, 0x6e,
     300                 :            :                 0x47, 0xc7, 0x68, 0x8c, 0x94, 0xf6, 0x69, 0xcb, 0x75, 0x94, 0xe6, 0x30, 0xa6, 0xfb, 0x68, 0x64,
     301                 :            :                 0x96, 0x1a, 0x84, 0xe1, 0xdc, 0x16, 0x4c, 0x83, 0x6c, 0x44, 0xf2, 0x74, 0x4d, 0x74, 0x79, 0x8f,
     302                 :            :                 0xf3, 0xf4, 0x63, 0x0d, 0xef, 0x5a, 0xe7, 0xe2, 0xfd, 0xf2, 0x2b, 0x38, 0x7c, 0x28, 0x96, 0x9d,
     303                 :            :                 0xb6, 0xcd, 0x5c, 0x3b, 0x57, 0xe2, 0x24, 0x78, 0x65, 0xd0, 0x9e, 0x77, 0x83, 0x09, 0x6c, 0xff,
     304                 :            :                 0x3d, 0x52, 0x3f, 0x6e, 0xd1, 0xed, 0x2e, 0xf9, 0xee, 0x8e, 0xa6, 0xbe, 0x9a, 0xa8, 0x87, 0x76,
     305                 :            :                 0xd8, 0x77, 0xcc, 0x96, 0xa0, 0x98, 0xa1, 0xd1, 0x68, 0x09, 0x43, 0xcf, 0x56, 0xd9, 0xd1, 0x66,
     306                 :            :         };
     307                 :            : 
     308                 :            :         static const uint8_t dnskey_blob[] = {
     309                 :            :                 0x03, 0x01, 0x00, 0x01, 0x9b, 0x49, 0x9b, 0xc1, 0xf9, 0x9a, 0xe0, 0x4e, 0xcf, 0xcb, 0x14, 0x45,
     310                 :            :                 0x2e, 0xc9, 0xf9, 0x74, 0xa7, 0x18, 0xb5, 0xf3, 0xde, 0x39, 0x49, 0xdf, 0x63, 0x33, 0x97, 0x52,
     311                 :            :                 0xe0, 0x8e, 0xac, 0x50, 0x30, 0x8e, 0x09, 0xd5, 0x24, 0x3d, 0x26, 0xa4, 0x49, 0x37, 0x2b, 0xb0,
     312                 :            :                 0x6b, 0x1b, 0xdf, 0xde, 0x85, 0x83, 0xcb, 0x22, 0x4e, 0x60, 0x0a, 0x91, 0x1a, 0x1f, 0xc5, 0x40,
     313                 :            :                 0xb1, 0xc3, 0x15, 0xc1, 0x54, 0x77, 0x86, 0x65, 0x53, 0xec, 0x10, 0x90, 0x0c, 0x91, 0x00, 0x5e,
     314                 :            :                 0x15, 0xdc, 0x08, 0x02, 0x4c, 0x8c, 0x0d, 0xc0, 0xac, 0x6e, 0xc4, 0x3e, 0x1b, 0x80, 0x19, 0xe4,
     315                 :            :                 0xf7, 0x5f, 0x77, 0x51, 0x06, 0x87, 0x61, 0xde, 0xa2, 0x18, 0x0f, 0x40, 0x8b, 0x79, 0x72, 0xfa,
     316                 :            :                 0x8d, 0x1a, 0x44, 0x47, 0x0d, 0x8e, 0x3a, 0x2d, 0xc7, 0x39, 0xbf, 0x56, 0x28, 0x97, 0xd9, 0x20,
     317                 :            :                 0x4f, 0x00, 0x51, 0x3b,
     318                 :            :         };
     319                 :            : 
     320                 :          4 :         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *a = NULL, *rrsig = NULL, *dnskey = NULL;
     321                 :          4 :         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
     322                 :            :         DnssecResult result;
     323                 :            : 
     324                 :          4 :         a = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "nAsA.gov");
     325         [ -  + ]:          4 :         assert_se(a);
     326                 :            : 
     327                 :          4 :         a->a.in_addr.s_addr = inet_addr("52.0.14.116");
     328                 :            : 
     329         [ +  - ]:          4 :         log_info("A: %s", strna(dns_resource_record_to_string(a)));
     330                 :            : 
     331                 :          4 :         rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV.");
     332         [ -  + ]:          4 :         assert_se(rrsig);
     333                 :            : 
     334                 :          4 :         rrsig->rrsig.type_covered = DNS_TYPE_A;
     335                 :          4 :         rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
     336                 :          4 :         rrsig->rrsig.labels = 2;
     337                 :          4 :         rrsig->rrsig.original_ttl = 600;
     338                 :          4 :         rrsig->rrsig.expiration = 0x5683135c;
     339                 :          4 :         rrsig->rrsig.inception = 0x565b7da8;
     340                 :          4 :         rrsig->rrsig.key_tag = 63876;
     341                 :          4 :         rrsig->rrsig.signer = strdup("Nasa.Gov.");
     342         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signer);
     343                 :          4 :         rrsig->rrsig.signature_size = sizeof(signature_blob);
     344                 :          4 :         rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
     345         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signature);
     346                 :            : 
     347         [ +  - ]:          4 :         log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
     348                 :            : 
     349                 :          4 :         dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV");
     350         [ -  + ]:          4 :         assert_se(dnskey);
     351                 :            : 
     352                 :          4 :         dnskey->dnskey.flags = 256;
     353                 :          4 :         dnskey->dnskey.protocol = 3;
     354                 :          4 :         dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
     355                 :          4 :         dnskey->dnskey.key_size = sizeof(dnskey_blob);
     356                 :          4 :         dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
     357         [ -  + ]:          4 :         assert_se(dnskey->dnskey.key);
     358                 :            : 
     359         [ +  - ]:          4 :         log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
     360         [ +  - ]:          4 :         log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
     361                 :            : 
     362         [ -  + ]:          4 :         assert_se(dnssec_key_match_rrsig(a->key, rrsig) > 0);
     363         [ -  + ]:          4 :         assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
     364                 :            : 
     365                 :          4 :         answer = dns_answer_new(1);
     366         [ -  + ]:          4 :         assert_se(answer);
     367         [ -  + ]:          4 :         assert_se(dns_answer_add(answer, a, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
     368                 :            : 
     369                 :            :         /* Validate the RR as it if was 2015-12-2 today */
     370         [ -  + ]:          4 :         assert_se(dnssec_verify_rrset(answer, a->key, rrsig, dnskey, 1449092754*USEC_PER_SEC, &result) >= 0);
     371         [ -  + ]:          4 :         assert_se(result == DNSSEC_VALIDATED);
     372                 :          4 : }
     373                 :            : 
     374                 :          4 : static void test_dnssec_verify_rrset2(void) {
     375                 :            : 
     376                 :            :         static const uint8_t signature_blob[] = {
     377                 :            :                 0x48, 0x45, 0xc8, 0x8b, 0xc0, 0x14, 0x92, 0xf5, 0x15, 0xc6, 0x84, 0x9d, 0x2f, 0xe3, 0x32, 0x11,
     378                 :            :                 0x7d, 0xf1, 0xe6, 0x87, 0xb9, 0x42, 0xd3, 0x8b, 0x9e, 0xaf, 0x92, 0x31, 0x0a, 0x53, 0xad, 0x8b,
     379                 :            :                 0xa7, 0x5c, 0x83, 0x39, 0x8c, 0x28, 0xac, 0xce, 0x6e, 0x9c, 0x18, 0xe3, 0x31, 0x16, 0x6e, 0xca,
     380                 :            :                 0x38, 0x31, 0xaf, 0xd9, 0x94, 0xf1, 0x84, 0xb1, 0xdf, 0x5a, 0xc2, 0x73, 0x22, 0xf6, 0xcb, 0xa2,
     381                 :            :                 0xe7, 0x8c, 0x77, 0x0c, 0x74, 0x2f, 0xc2, 0x13, 0xb0, 0x93, 0x51, 0xa9, 0x4f, 0xae, 0x0a, 0xda,
     382                 :            :                 0x45, 0xcc, 0xfd, 0x43, 0x99, 0x36, 0x9a, 0x0d, 0x21, 0xe0, 0xeb, 0x30, 0x65, 0xd4, 0xa0, 0x27,
     383                 :            :                 0x37, 0x3b, 0xe4, 0xc1, 0xc5, 0xa1, 0x2a, 0xd1, 0x76, 0xc4, 0x7e, 0x64, 0x0e, 0x5a, 0xa6, 0x50,
     384                 :            :                 0x24, 0xd5, 0x2c, 0xcc, 0x6d, 0xe5, 0x37, 0xea, 0xbd, 0x09, 0x34, 0xed, 0x24, 0x06, 0xa1, 0x22,
     385                 :            :         };
     386                 :            : 
     387                 :            :         static const uint8_t dnskey_blob[] = {
     388                 :            :                 0x03, 0x01, 0x00, 0x01, 0xc3, 0x7f, 0x1d, 0xd1, 0x1c, 0x97, 0xb1, 0x13, 0x34, 0x3a, 0x9a, 0xea,
     389                 :            :                 0xee, 0xd9, 0x5a, 0x11, 0x1b, 0x17, 0xc7, 0xe3, 0xd4, 0xda, 0x20, 0xbc, 0x5d, 0xba, 0x74, 0xe3,
     390                 :            :                 0x37, 0x99, 0xec, 0x25, 0xce, 0x93, 0x7f, 0xbd, 0x22, 0x73, 0x7e, 0x14, 0x71, 0xe0, 0x60, 0x07,
     391                 :            :                 0xd4, 0x39, 0x8b, 0x5e, 0xe9, 0xba, 0x25, 0xe8, 0x49, 0xe9, 0x34, 0xef, 0xfe, 0x04, 0x5c, 0xa5,
     392                 :            :                 0x27, 0xcd, 0xa9, 0xda, 0x70, 0x05, 0x21, 0xab, 0x15, 0x82, 0x24, 0xc3, 0x94, 0xf5, 0xd7, 0xb7,
     393                 :            :                 0xc4, 0x66, 0xcb, 0x32, 0x6e, 0x60, 0x2b, 0x55, 0x59, 0x28, 0x89, 0x8a, 0x72, 0xde, 0x88, 0x56,
     394                 :            :                 0x27, 0x95, 0xd9, 0xac, 0x88, 0x4f, 0x65, 0x2b, 0x68, 0xfc, 0xe6, 0x41, 0xc1, 0x1b, 0xef, 0x4e,
     395                 :            :                 0xd6, 0xc2, 0x0f, 0x64, 0x88, 0x95, 0x5e, 0xdd, 0x3a, 0x02, 0x07, 0x50, 0xa9, 0xda, 0xa4, 0x49,
     396                 :            :                 0x74, 0x62, 0xfe, 0xd7,
     397                 :            :         };
     398                 :            : 
     399                 :          4 :         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *nsec = NULL, *rrsig = NULL, *dnskey = NULL;
     400                 :          4 :         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
     401                 :            :         DnssecResult result;
     402                 :            : 
     403                 :          4 :         nsec = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC, "nasa.gov");
     404         [ -  + ]:          4 :         assert_se(nsec);
     405                 :            : 
     406                 :          4 :         nsec->nsec.next_domain_name = strdup("3D-Printing.nasa.gov");
     407         [ -  + ]:          4 :         assert_se(nsec->nsec.next_domain_name);
     408                 :            : 
     409                 :          4 :         nsec->nsec.types = bitmap_new();
     410         [ -  + ]:          4 :         assert_se(nsec->nsec.types);
     411         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_A) >= 0);
     412         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NS) >= 0);
     413         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_SOA) >= 0);
     414         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_MX) >= 0);
     415         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_TXT) >= 0);
     416         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_RRSIG) >= 0);
     417         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_NSEC) >= 0);
     418         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, DNS_TYPE_DNSKEY) >= 0);
     419         [ -  + ]:          4 :         assert_se(bitmap_set(nsec->nsec.types, 65534) >= 0);
     420                 :            : 
     421         [ +  - ]:          4 :         log_info("NSEC: %s", strna(dns_resource_record_to_string(nsec)));
     422                 :            : 
     423                 :          4 :         rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "NaSa.GOV.");
     424         [ -  + ]:          4 :         assert_se(rrsig);
     425                 :            : 
     426                 :          4 :         rrsig->rrsig.type_covered = DNS_TYPE_NSEC;
     427                 :          4 :         rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256;
     428                 :          4 :         rrsig->rrsig.labels = 2;
     429                 :          4 :         rrsig->rrsig.original_ttl = 300;
     430                 :          4 :         rrsig->rrsig.expiration = 0x5689002f;
     431                 :          4 :         rrsig->rrsig.inception = 0x56617230;
     432                 :          4 :         rrsig->rrsig.key_tag = 30390;
     433                 :          4 :         rrsig->rrsig.signer = strdup("Nasa.Gov.");
     434         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signer);
     435                 :          4 :         rrsig->rrsig.signature_size = sizeof(signature_blob);
     436                 :          4 :         rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size);
     437         [ -  + ]:          4 :         assert_se(rrsig->rrsig.signature);
     438                 :            : 
     439         [ +  - ]:          4 :         log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig)));
     440                 :            : 
     441                 :          4 :         dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "nASA.gOV");
     442         [ -  + ]:          4 :         assert_se(dnskey);
     443                 :            : 
     444                 :          4 :         dnskey->dnskey.flags = 256;
     445                 :          4 :         dnskey->dnskey.protocol = 3;
     446                 :          4 :         dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256;
     447                 :          4 :         dnskey->dnskey.key_size = sizeof(dnskey_blob);
     448                 :          4 :         dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob));
     449         [ -  + ]:          4 :         assert_se(dnskey->dnskey.key);
     450                 :            : 
     451         [ +  - ]:          4 :         log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey)));
     452         [ +  - ]:          4 :         log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false));
     453                 :            : 
     454         [ -  + ]:          4 :         assert_se(dnssec_key_match_rrsig(nsec->key, rrsig) > 0);
     455         [ -  + ]:          4 :         assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0);
     456                 :            : 
     457                 :          4 :         answer = dns_answer_new(1);
     458         [ -  + ]:          4 :         assert_se(answer);
     459         [ -  + ]:          4 :         assert_se(dns_answer_add(answer, nsec, 0, DNS_ANSWER_AUTHENTICATED) >= 0);
     460                 :            : 
     461                 :            :         /* Validate the RR as it if was 2015-12-11 today */
     462         [ -  + ]:          4 :         assert_se(dnssec_verify_rrset(answer, nsec->key, rrsig, dnskey, 1449849318*USEC_PER_SEC, &result) >= 0);
     463         [ -  + ]:          4 :         assert_se(result == DNSSEC_VALIDATED);
     464                 :          4 : }
     465                 :            : 
     466                 :          4 : static void test_dnssec_nsec3_hash(void) {
     467                 :            :         static const uint8_t salt[] = { 0xB0, 0x1D, 0xFA, 0xCE };
     468                 :            :         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 };
     469                 :          4 :         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
     470                 :          4 :         uint8_t h[DNSSEC_HASH_SIZE_MAX];
     471                 :          4 :         _cleanup_free_ char *b = NULL;
     472                 :            :         int k;
     473                 :            : 
     474                 :            :         /* The NSEC3 RR for eurid.eu on 2015-12-14. */
     475                 :          4 :         rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_NSEC3, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM.eurid.eu.");
     476         [ -  + ]:          4 :         assert_se(rr);
     477                 :            : 
     478                 :          4 :         rr->nsec3.algorithm = DNSSEC_DIGEST_SHA1;
     479                 :          4 :         rr->nsec3.flags = 1;
     480                 :          4 :         rr->nsec3.iterations = 1;
     481                 :          4 :         rr->nsec3.salt = memdup(salt, sizeof(salt));
     482         [ -  + ]:          4 :         assert_se(rr->nsec3.salt);
     483                 :          4 :         rr->nsec3.salt_size = sizeof(salt);
     484                 :          4 :         rr->nsec3.next_hashed_name = memdup(next_hashed_name, sizeof(next_hashed_name));
     485         [ -  + ]:          4 :         assert_se(rr->nsec3.next_hashed_name);
     486                 :          4 :         rr->nsec3.next_hashed_name_size = sizeof(next_hashed_name);
     487                 :            : 
     488         [ +  - ]:          4 :         log_info("NSEC3: %s", strna(dns_resource_record_to_string(rr)));
     489                 :            : 
     490                 :          4 :         k = dnssec_nsec3_hash(rr, "eurid.eu", &h);
     491         [ -  + ]:          4 :         assert_se(k >= 0);
     492                 :            : 
     493                 :          4 :         b = base32hexmem(h, k, false);
     494         [ -  + ]:          4 :         assert_se(b);
     495         [ -  + ]:          4 :         assert_se(strcasecmp(b, "PJ8S08RR45VIQDAQGE7EN3VHKNROTBMM") == 0);
     496                 :          4 : }
     497                 :            : 
     498                 :            : #endif
     499                 :            : 
     500                 :          4 : int main(int argc, char *argv[]) {
     501                 :            : 
     502                 :          4 :         test_dnssec_canonicalize();
     503                 :            : 
     504                 :            : #if HAVE_GCRYPT
     505                 :          4 :         test_dnssec_verify_dns_key();
     506                 :          4 :         test_dnssec_verify_rfc8080_ed25519_example1();
     507                 :          4 :         test_dnssec_verify_rfc8080_ed25519_example2();
     508                 :          4 :         test_dnssec_verify_rrset();
     509                 :          4 :         test_dnssec_verify_rrset2();
     510                 :          4 :         test_dnssec_nsec3_hash();
     511                 :            : #endif
     512                 :            : 
     513                 :          4 :         return 0;
     514                 :            : }

Generated by: LCOV version 1.14