quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

unit1658.c (16583B)


      1 /***************************************************************************
      2  *                                  _   _ ____  _
      3  *  Project                     ___| | | |  _ \| |
      4  *                             / __| | | | |_) | |
      5  *                            | (__| |_| |  _ <| |___
      6  *                             \___|\___/|_| \_\_____|
      7  *
      8  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
      9  *
     10  * This software is licensed as described in the file COPYING, which
     11  * you should have received as part of this distribution. The terms
     12  * are also available at https://curl.se/docs/copyright.html.
     13  *
     14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15  * copies of the Software, and permit persons to whom the Software is
     16  * furnished to do so, under the terms of the COPYING file.
     17  *
     18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19  * KIND, either express or implied.
     20  *
     21  * SPDX-License-Identifier: curl
     22  *
     23  ***************************************************************************/
     24 #include "unitcheck.h"
     25 
     26 #include "doh.h" /* from the lib dir */
     27 
     28 /* DoH + HTTPSRR are required */
     29 #if !defined(CURL_DISABLE_DOH) && defined(USE_HTTPSRR)
     30 
     31 static CURLcode t1658_setup(void)
     32 {
     33   /* whatever you want done first */
     34   curl_global_init(CURL_GLOBAL_ALL);
     35   return CURLE_OK;
     36 }
     37 
     38 extern CURLcode doh_resp_decode_httpsrr(struct Curl_easy *data,
     39                                         const unsigned char *cp, size_t len,
     40                                         struct Curl_https_rrinfo **hrr);
     41 extern void doh_print_httpsrr(struct Curl_easy *data,
     42                               struct Curl_https_rrinfo *hrr);
     43 
     44 /*
     45  * The idea here is that we pass one DNS packet at the time to the decoder. we
     46  * then generate a string output with the results and compare if it matches
     47  * the expected. One by one.
     48  */
     49 
     50 static char rrbuffer[256];
     51 static void rrresults(struct Curl_https_rrinfo *rr, CURLcode result)
     52 {
     53   char *p = rrbuffer;
     54   char *pend = rrbuffer + sizeof(rrbuffer);
     55   curl_msnprintf(rrbuffer, sizeof(rrbuffer), "r:%d|", (int)result);
     56   p += strlen(rrbuffer);
     57 
     58   if(rr) {
     59     unsigned int i;
     60     curl_msnprintf(p, pend - p, "p:%d|", rr->priority);
     61     p += strlen(p);
     62 
     63     curl_msnprintf(p, pend - p, "%s|", rr->target ? rr->target : "-");
     64     p += strlen(p);
     65 
     66     for(i = 0; i < MAX_HTTPSRR_ALPNS && rr->alpns[i] != ALPN_none; i++) {
     67       curl_msnprintf(p, pend - p, "alpn:%x|", rr->alpns[i]);
     68       p += strlen(p);
     69     }
     70     if(rr->no_def_alpn) {
     71       curl_msnprintf(p, pend - p, "no-def-alpn|");
     72       p += strlen(p);
     73     }
     74     if(rr->port >= 0) {
     75       curl_msnprintf(p, pend - p, "port:%d|", rr->port);
     76       p += strlen(p);
     77     }
     78     if(rr->ipv4hints) {
     79       for(i = 0; i < rr->ipv4hints_len; i += 4) {
     80         curl_msnprintf(p, pend - p, "ipv4:%d.%d.%d.%d|",
     81                        rr->ipv4hints[i],
     82                        rr->ipv4hints[i + 1],
     83                        rr->ipv4hints[i + 2],
     84                        rr->ipv4hints[i + 3]);
     85         p += strlen(p);
     86       }
     87     }
     88     if(rr->echconfiglist) {
     89       curl_msnprintf(p, pend - p, "ech:");
     90       p += strlen(p);
     91       for(i = 0; i < rr->echconfiglist_len; i++) {
     92         curl_msnprintf(p, pend - p, "%02x", rr->echconfiglist[i]);
     93         p += strlen(p);
     94       }
     95       curl_msnprintf(p, pend - p, "|");
     96       p += strlen(p);
     97     }
     98     if(rr->ipv6hints) {
     99       for(i = 0; i < rr->ipv6hints_len; i += 16) {
    100         int x;
    101         curl_msnprintf(p, pend - p, "ipv6:");
    102         p += strlen(p);
    103         for(x = 0; x < 16; x += 2) {
    104           curl_msnprintf(p, pend - p, "%s%02x%02x",
    105                          x ? ":" : "",
    106                          rr->ipv6hints[i + x],
    107                          rr->ipv6hints[i + x + 1]);
    108           p += strlen(p);
    109         }
    110         curl_msnprintf(p, pend - p, "|");
    111         p += strlen(p);
    112       }
    113     }
    114   }
    115 }
    116 
    117 static CURLcode test_unit1658(char *arg)
    118 {
    119   UNITTEST_BEGIN(t1658_setup())
    120 
    121   /* The "SvcParamKeys" specified within the HTTPS RR packet *must* be
    122      provided in numerical order. */
    123 
    124   struct test {
    125     const char *name;
    126     const unsigned char *dns;
    127     size_t len; /* size of the dns packet */
    128     const char *expect;
    129   };
    130 
    131   static const struct test t[] = {
    132     {
    133       "single h2 alpn",
    134       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    135       "\x04name\x00" /* RNAME */
    136       "\x00\x01" /* RR (1 == ALPN) */
    137       "\x00\x03" /* data size */
    138       "\x02" /* length byte */
    139       "h2",
    140       15,
    141       "r:0|p:0|name.|alpn:10|"
    142     },
    143     {
    144       "single h2 alpn missing last byte",
    145       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    146       "\x04name\x00" /* RNAME */
    147       "\x00\x01" /* RR (1 == ALPN) */
    148       "\x00\x03" /* data size */
    149       "\x02" /* length byte */
    150       "h", /* missing byte */
    151       14,
    152       "r:8|"
    153     },
    154     {
    155       "two alpns",
    156       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    157       "\x04name\x04some\x00" /* RNAME */
    158       "\x00\x01" /* RR (1 == ALPN) */
    159       "\x00\x06" /* data size */
    160       "\x02" /* ALPN length byte */
    161       "h2"
    162       "\x02" /* APLN length byte */
    163       "h3",
    164       23,
    165       "r:0|p:0|name.some.|alpn:10|alpn:20|"
    166     },
    167     {
    168       "wrong syntax alpns",
    169       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    170       "\x04name\x04some\x00" /* RNAME */
    171       "\x00\x01" /* RR (1 == ALPN) */
    172       "\x00\x06" /* data size */
    173       "\x02" /* ALPN length byte */
    174       "h2"
    175       "\x03" /* APLN length byte (WRONG) */
    176       "h3",
    177       23,
    178       "r:61|"
    179     },
    180     {
    181       "five alpns (ignore dupes)", /* we only support four */
    182       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    183       "\x04name\x04some\x00" /* RNAME */
    184       "\x00\x01" /* RR (1 == ALPN) */
    185       "\x00\x0f" /* data size */
    186       "\x02" /* ALPN length byte */
    187       "h2"
    188       "\x02" /* ALPN length byte */
    189       "h2"
    190       "\x02" /* ALPN length byte */
    191       "h2"
    192       "\x02" /* ALPN length byte */
    193       "h2"
    194       "\x02" /* APLN length byte */
    195       "h3",
    196       32,
    197       "r:0|p:0|name.some.|alpn:10|alpn:20|"
    198     },
    199     {
    200       "rname only",
    201       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    202       "\x04name\x04some\x00", /* RNAME */
    203       13,
    204       "r:0|p:0|name.some.|"
    205     },
    206     {
    207       "rname with low ascii byte",
    208       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    209       "\x04name\x04som\x03\x00", /* RNAME */
    210       13,
    211       "r:8|"
    212     },
    213     {
    214       "rname with null byte",
    215       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    216       "\x04sa\x00e\x04some\x00", /* RNAME */
    217       13,
    218       "r:27|"
    219     },
    220     {
    221       "rname only (missing byte)",
    222       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    223       "\x04name\x05some\x00", /* RNAME */
    224       /* it lacks a byte */
    225       13,
    226       "r:27|"
    227     },
    228     {
    229       "unrecognized alpn",
    230       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    231       "\x04name\x04some\x00" /* RNAME */
    232       "\x00\x01" /* RR (1 == ALPN) */
    233       "\x00\x06" /* data size */
    234       "\x02" /* ALPN length byte */
    235       "h8" /* unrecognized */
    236       "\x02" /* APLN length byte */
    237       "h1",
    238       23,
    239       "r:0|p:0|name.some.|alpn:8|"
    240     },
    241     {
    242       "alnt + no-default-alpn",
    243       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    244       "\x04name\x04some\x00" /* RNAME */
    245       "\x00\x01" /* RR (1 == ALPN) */
    246       "\x00\x03" /* data size */
    247       "\x02" /* ALPN length byte */
    248       "h2"
    249       "\x00\x02" /* RR (2 == NO DEFAULT ALPN) */
    250       "\x00\x00", /* must be zero */
    251       24,
    252       "r:0|p:0|name.some.|alpn:10|no-def-alpn|"
    253     },
    254     {
    255       "alnt + no-default-alpn with size",
    256       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    257       "\x04name\x04some\x00" /* RNAME */
    258       "\x00\x01" /* RR (1 == ALPN) */
    259       "\x00\x03" /* data size */
    260       "\x02" /* ALPN length byte */
    261       "h2"
    262       "\x00\x02" /* RR (2 == NO DEFAULT ALPN) */
    263       "\x00\x01" /* must be zero */
    264       "\xff",
    265       25,
    266       "r:43|"
    267     },
    268     {
    269       "alnt + no-default-alpn with size too short package",
    270       (const unsigned char *)"\x00\x00" /* 16-bit prio */
    271       "\x04name\x04some\x00" /* RNAME */
    272       "\x00\x01" /* RR (1 == ALPN) */
    273       "\x00\x03" /* data size */
    274       "\x02" /* ALPN length byte */
    275       "h2"
    276       "\x00\x02" /* RR (2 == NO DEFAULT ALPN) */
    277       "\x00\x01", /* must be zero */
    278       /* missing last byte in the packet */
    279       24,
    280       "r:8|"
    281     },
    282     {
    283       "rname + blank alpn field",
    284       (const unsigned char *)"\x11\x11" /* 16-bit prio */
    285       "\x04name\x04some\x00" /* RNAME */
    286       "\x00\x01" /* RR (1 == ALPN) */
    287       "\x00\x00", /* data size, strictly speaking this is illegal:
    288                      "one or more alpn-ids" */
    289       17,
    290       "r:0|p:4369|name.some.|"
    291     },
    292     {
    293       "no rname + blank alpn",
    294       (const unsigned char *)"\x00\x11" /* 16-bit prio */
    295       "\x00" /* no RNAME */
    296       "\x00\x01" /* RR (1 == ALPN) */
    297       "\x00\x00", /* data size */
    298       7,
    299       "r:0|p:17|.|"
    300     },
    301     {
    302       "unsupported field",
    303       (const unsigned char *)"\xff\xff" /* 16-bit prio */
    304       "\x00" /* no RNAME */
    305       "\x00\x07" /* RR (7 == not a supported data) */
    306       "\x00\x02" /* data size */
    307       "FF", /* unknown to curl */
    308       9,
    309       "r:0|p:65535|.|"
    310     },
    311     {
    312       "unsupported field (wrong size)",
    313       (const unsigned char *)"\xff\xff" /* 16-bit prio */
    314       "\x00" /* no RNAME */
    315       "\x00\x07" /* RR (7 == not a supported data) */
    316       "\x00\x02" /* data size */
    317       "F", /* unknown to curl */
    318       8,
    319       "r:8|"
    320     },
    321     {
    322       "port number",
    323       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    324       "\x00" /* no RNAME */
    325       "\x00\x01" /* RR (1 == ALPN) */
    326       "\x00\x03" /* data size */
    327       "\x02" /* ALPN length byte */
    328       "h2"
    329       "\x00\x03" /* RR (3 == PORT) */
    330       "\x00\x02" /* data size */
    331       "\x12\x34", /* port number */
    332       16,
    333       "r:0|p:16|.|alpn:10|port:4660|"
    334     },
    335     {
    336       "port number with wrong size (3 bytes)",
    337       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    338       "\x00" /* no RNAME */
    339       "\x00\x01" /* RR (1 == ALPN) */
    340       "\x00\x03" /* data size */
    341       "\x02" /* ALPN length byte */
    342       "h2"
    343       "\x00\x03" /* RR (3 == PORT) */
    344       "\x00\x03" /* data size */
    345       "\x12\x34\x00", /* 24 bit port number! */
    346       17,
    347       "r:43|"
    348     },
    349     {
    350       "port number with wrong size (1 byte)",
    351       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    352       "\x00" /* no RNAME */
    353       "\x00\x01" /* RR (1 == ALPN) */
    354       "\x00\x03" /* data size */
    355       "\x02" /* ALPN length byte */
    356       "h2"
    357       "\x00\x03" /* RR (3 == PORT) */
    358       "\x00\x01" /* data size */
    359       "\x12", /* 8 bit port number! */
    360       15,
    361       "r:43|"
    362     },
    363     {
    364       "alpn + two ipv4 addresses",
    365       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    366       "\x00" /* no RNAME */
    367       "\x00\x01" /* RR (1 == ALPN) */
    368       "\x00\x03" /* data size */
    369       "\x02" /* ALPN length byte */
    370       "h2"
    371       "\x00\x04" /* RR (4 == Ipv4hints) */
    372       "\x00\x08" /* data size */
    373       "\xc0\xa8\x00\x01"  /* 32 bits */
    374       "\xc0\xa8\x00\x02", /* 32 bits */
    375       22,
    376       "r:0|p:16|.|alpn:10|ipv4:192.168.0.1|ipv4:192.168.0.2|"
    377     },
    378     {
    379       "alpn + two ipv4 addresses in wrong order",
    380       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    381       "\x00" /* no RNAME */
    382       "\x00\x04" /* RR (4 == Ipv4hints) */
    383       "\x00\x08" /* data size */
    384       "\xc0\xa8\x00\x01"  /* 32 bits */
    385       "\xc0\xa8\x00\x02" /* 32 bits */
    386       "\x00\x01" /* RR (1 == ALPN) */
    387       "\x00\x03" /* data size */
    388       "\x02" /* ALPN length byte */
    389       "h2",
    390       22,
    391       "r:8|"
    392     },
    393     {
    394       "alpn + ipv4 address with wrong size",
    395       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    396       "\x00" /* no RNAME */
    397       "\x00\x01" /* RR (1 == ALPN) */
    398       "\x00\x03" /* data size */
    399       "\x02" /* ALPN length byte */
    400       "h2"
    401       "\x00\x04" /* RR (4 == Ipv4hints) */
    402       "\x00\x05" /* data size */
    403       "\xc0\xa8\x00\x01\xff",  /* 32 + 8 bits */
    404       19,
    405       "r:43|"
    406     },
    407     {
    408       "alpn + one ipv6 address",
    409       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    410       "\x00" /* no RNAME */
    411       "\x00\x01" /* RR (1 == ALPN) */
    412       "\x00\x03" /* data size */
    413       "\x02" /* ALPN length byte */
    414       "h2"
    415       "\x00\x06" /* RR (6 == Ipv6hints) */
    416       "\x00\x10" /* data size */
    417       "\xfe\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x23",
    418       30,
    419       "r:0|p:16|.|alpn:10|ipv6:fe80:dabb:c1ff:fea3:8a22:1234:5678:9123|"
    420     },
    421     {
    422       "alpn + one ipv6 address with wrong size",
    423       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    424       "\x00" /* no RNAME */
    425       "\x00\x01" /* RR (1 == ALPN) */
    426       "\x00\x03" /* data size */
    427       "\x02" /* ALPN length byte */
    428       "h2"
    429       "\x00\x06" /* RR (6 == Ipv6hints) */
    430       "\x00\x11" /* data size */
    431       "\xfe\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x23\x45",
    432       31,
    433       "r:43|"
    434     },
    435     {
    436       "alpn + two ipv6 addresses",
    437       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    438       "\x00" /* no RNAME */
    439       "\x00\x01" /* RR (1 == ALPN) */
    440       "\x00\x03" /* data size */
    441       "\x02" /* ALPN length byte */
    442       "h2"
    443       "\x00\x06" /* RR (6 == Ipv6hints) */
    444       "\x00\x20" /* data size */
    445       "\xfe\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x23"
    446       "\xee\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x25",
    447       46,
    448       "r:0|p:16|.|alpn:10|ipv6:fe80:dabb:c1ff:fea3:8a22:1234:5678:9123|"
    449       "ipv6:ee80:dabb:c1ff:fea3:8a22:1234:5678:9125|"
    450     },
    451     {
    452       "alpn + ech",
    453       (const unsigned char *)"\x00\x10" /* 16-bit prio */
    454       "\x00" /* no RNAME */
    455       "\x00\x01" /* RR (1 == ALPN) */
    456       "\x00\x03" /* data size */
    457       "\x02" /* ALPN length byte */
    458       "h2"
    459       "\x00\x05" /* RR (5 == ECH) */
    460       "\x00\x10" /* data size */
    461       "\xfe\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x23",
    462       30,
    463       "r:0|p:16|.|alpn:10|ech:fe80dabbc1fffea38a22123456789123|"
    464     },
    465     {
    466       "fully packed",
    467       (const unsigned char *)"\xa0\x0b" /* 16-bit prio */
    468       "\x00" /* no RNAME */
    469       "\x00\x00" /* RR (0 == MANDATORY) */
    470       "\x00\x00" /* data size */
    471       "\x00\x01" /* RR (1 == ALPN) */
    472       "\x00\x06" /* data size */
    473       "\x02" /* ALPN length byte */
    474       "h2"
    475       "\x02" /* ALPN length byte */
    476       "h1"
    477       "\x00\x02" /* RR (2 == NO DEFAULT ALPN) */
    478       "\x00\x00" /* must be zero */
    479       "\x00\x03" /* RR (3 == PORT) */
    480       "\x00\x02" /* data size */
    481       "\xbc\x71" /* port number */
    482       "\x00\x04" /* RR (4 == Ipv4hints) */
    483       "\x00\x08" /* data size */
    484       "\xc0\xa8\x00\x01" /* 32 bits */
    485       "\xc0\xa8\x00\x02" /* 32 bits */
    486       "\x00\x05" /* RR (5 == ECH) */
    487       "\x00\x10" /* data size */
    488       "\xfe\x80\xda\xbb\xc1\xff\x7e\xb3\x8a\x22\x12\x34\x56\x78\x91\x23"
    489       "\x00\x06" /* RR (6 == Ipv6hints) */
    490       "\x00\x20" /* data size */
    491       "\xfe\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x23"
    492       "\xee\x80\xda\xbb\xc1\xff\xfe\xa3\x8a\x22\x12\x34\x56\x78\x91\x25"
    493       "\x01\x07" /* RR (263 == not supported) */
    494       "\x00\x04" /* data size */
    495       "FFAA", /* unknown to the world */
    496       103,
    497       "r:0|p:40971|.|alpn:10|alpn:8|no-def-alpn|port:48241|"
    498       "ipv4:192.168.0.1|ipv4:192.168.0.2|"
    499       "ech:fe80dabbc1ff7eb38a22123456789123|"
    500       "ipv6:fe80:dabb:c1ff:fea3:8a22:1234:5678:9123|"
    501       "ipv6:ee80:dabb:c1ff:fea3:8a22:1234:5678:9125|"
    502     }
    503   };
    504 
    505   CURLcode result = CURLE_OUT_OF_MEMORY;
    506   CURL *easy;
    507 
    508   easy = curl_easy_init();
    509   /* so that we get the log output: */
    510   curl_easy_setopt(easy, CURLOPT_VERBOSE, 1L);
    511   if(easy) {
    512     unsigned int i;
    513 
    514     for(i = 0; i < CURL_ARRAYSIZE(t); i++) {
    515       struct Curl_https_rrinfo *hrr;
    516 
    517       printf("test %i: %s\n", i, t[i].name);
    518 
    519       result = doh_resp_decode_httpsrr(easy, t[i].dns, t[i].len, &hrr);
    520 
    521       /* create an output */
    522       rrresults(hrr, result);
    523 
    524       /* is the output the expected? */
    525       if(strcmp(rrbuffer, t[i].expect)) {
    526         curl_mfprintf(stderr, "Test %s (%i) failed\n"
    527                       "Expected: %s\n"
    528                       "Received: %s\n", t[i].name, i, t[i].expect, rrbuffer);
    529         unitfail++;
    530       }
    531 
    532       /* free the generated struct */
    533       if(hrr) {
    534         Curl_httpsrr_cleanup(hrr);
    535         curl_free(hrr);
    536       }
    537     }
    538     curl_easy_cleanup(easy);
    539   }
    540 
    541   UNITTEST_END(curl_global_cleanup())
    542 }
    543 
    544 #else /* CURL_DISABLE_DOH or not HTTPSRR enabled */
    545 
    546 static CURLcode test_unit1658(char *arg)
    547 {
    548   UNITTEST_BEGIN_SIMPLE
    549   UNITTEST_END_SIMPLE
    550 }
    551 
    552 #endif