Home | History | Annotate | Line # | Download | only in test
      1  1.1  christos /*
      2  1.1  christos  * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
      3  1.1  christos  *
      4  1.1  christos  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  1.1  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1  christos  * in the file LICENSE in the source distribution or at
      7  1.1  christos  * https://www.openssl.org/source/license.html
      8  1.1  christos  */
      9  1.1  christos 
     10  1.1  christos #include <openssl/crypto.h>
     11  1.1  christos #include <string.h>
     12  1.1  christos 
     13  1.1  christos #include "crypto/punycode.h"
     14  1.1  christos #include "internal/nelem.h"
     15  1.1  christos #include "testutil.h"
     16  1.1  christos 
     17  1.1  christos 
     18  1.1  christos static const struct puny_test {
     19  1.1  christos     unsigned int raw[50];
     20  1.1  christos     const char *encoded;
     21  1.1  christos } puny_cases[] = {
     22  1.1  christos     /* Test cases from RFC 3492 */
     23  1.1  christos     {   /* Arabic (Egyptian) */
     24  1.1  christos         { 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
     25  1.1  christos           0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F
     26  1.1  christos         },
     27  1.1  christos         "egbpdaj6bu4bxfgehfvwxn"
     28  1.1  christos     },
     29  1.1  christos     {   /* Chinese (simplified) */
     30  1.1  christos         { 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587
     31  1.1  christos         },
     32  1.1  christos         "ihqwcrb4cv8a8dqg056pqjye"
     33  1.1  christos     },
     34  1.1  christos     {   /* Chinese (traditional) */
     35  1.1  christos         { 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587
     36  1.1  christos         },
     37  1.1  christos         "ihqwctvzc91f659drss3x8bo0yb"
     38  1.1  christos     },
     39  1.1  christos     {    /* Czech: Pro<ccaron>prost<ecaron>nemluv<iacute><ccaron>esky */
     40  1.1  christos         { 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
     41  1.1  christos           0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
     42  1.1  christos           0x0065, 0x0073, 0x006B, 0x0079
     43  1.1  christos        },
     44  1.1  christos         "Proprostnemluvesky-uyb24dma41a"
     45  1.1  christos     },
     46  1.1  christos     {   /* Hebrew */
     47  1.1  christos         { 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
     48  1.1  christos           0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
     49  1.1  christos           0x05D1, 0x05E8, 0x05D9, 0x05EA
     50  1.1  christos         },
     51  1.1  christos         "4dbcagdahymbxekheh6e0a7fei0b"
     52  1.1  christos     },
     53  1.1  christos     {   /* Hindi (Devanagari) */
     54  1.1  christos         { 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
     55  1.1  christos           0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
     56  1.1  christos           0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
     57  1.1  christos           0x0939, 0x0948, 0x0902
     58  1.1  christos         },
     59  1.1  christos         "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"
     60  1.1  christos     },
     61  1.1  christos     {   /* Japanese (kanji and hiragana) */
     62  1.1  christos         { 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
     63  1.1  christos           0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B
     64  1.1  christos         },
     65  1.1  christos         "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"
     66  1.1  christos     },
     67  1.1  christos     {   /* Korean (Hangul syllables) */
     68  1.1  christos         { 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
     69  1.1  christos           0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
     70  1.1  christos           0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C
     71  1.1  christos         },
     72  1.1  christos         "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c"
     73  1.1  christos     },
     74  1.1  christos     {   /* Russian (Cyrillic) */
     75  1.1  christos         { 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
     76  1.1  christos           0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
     77  1.1  christos           0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
     78  1.1  christos           0x0438
     79  1.1  christos         },
     80  1.1  christos         "b1abfaaepdrnnbgefbaDotcwatmq2g4l"
     81  1.1  christos     },
     82  1.1  christos     {   /* Spanish */
     83  1.1  christos         { 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
     84  1.1  christos           0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
     85  1.1  christos           0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
     86  1.1  christos           0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
     87  1.1  christos           0x0061, 0x00F1, 0x006F, 0x006C
     88  1.1  christos         },
     89  1.1  christos         "PorqunopuedensimplementehablarenEspaol-fmd56a"
     90  1.1  christos     },
     91  1.1  christos     {   /* Vietnamese */
     92  1.1  christos         { 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
     93  1.1  christos           0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
     94  1.1  christos           0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
     95  1.1  christos           0x0056, 0x0069, 0x1EC7, 0x0074
     96  1.1  christos         },
     97  1.1  christos         "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"
     98  1.1  christos     },
     99  1.1  christos     {   /* Japanese: 3<nen>B<gumi><kinpachi><sensei> */
    100  1.1  christos         { 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F
    101  1.1  christos         },
    102  1.1  christos         "3B-ww4c5e180e575a65lsy2b"
    103  1.1  christos     },
    104  1.1  christos     {   /* Japanese: <amuro><namie>-with-SUPER-MONKEYS */
    105  1.1  christos         { 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
    106  1.1  christos           0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
    107  1.1  christos           0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053
    108  1.1  christos         },
    109  1.1  christos         "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"
    110  1.1  christos     },
    111  1.1  christos     {   /* Japanese: Hello-Another-Way-<sorezore><no><basho> */
    112  1.1  christos         { 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
    113  1.1  christos           0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
    114  1.1  christos           0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240
    115  1.1  christos         },
    116  1.1  christos         "Hello-Another-Way--fc4qua05auwb3674vfr0b"
    117  1.1  christos     },
    118  1.1  christos     {   /* Japanese: <hitotsu><yane><no><shita>2 */
    119  1.1  christos         { 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032
    120  1.1  christos         },
    121  1.1  christos         "2-u9tlzr9756bt3uc0v"
    122  1.1  christos     },
    123  1.1  christos     {   /* Japanese: Maji<de>Koi<suru>5<byou><mae> */
    124  1.1  christos         { 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
    125  1.1  christos           0x308B, 0x0035, 0x79D2, 0x524D
    126  1.1  christos         },
    127  1.1  christos         "MajiKoi5-783gue6qz075azm5e"
    128  1.1  christos     },
    129  1.1  christos     {   /* Japanese: <pafii>de<runba> */
    130  1.1  christos         { 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0
    131  1.1  christos         },
    132  1.1  christos         "de-jg4avhby1noc0d"
    133  1.1  christos     },
    134  1.1  christos     {   /* Japanese: <sono><supiido><de> */
    135  1.1  christos         { 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067
    136  1.1  christos         },
    137  1.1  christos         "d9juau41awczczp"
    138  1.1  christos     },
    139  1.1  christos     {   /* -> $1.00 <- */
    140  1.1  christos         { 0x002D, 0x003E, 0x0020, 0x0024, 0x0031, 0x002E, 0x0030, 0x0030, 0x0020,
    141  1.1  christos           0x003C, 0x002D
    142  1.1  christos         },
    143  1.1  christos         "-> $1.00 <--"
    144  1.1  christos     }
    145  1.1  christos };
    146  1.1  christos 
    147  1.1  christos static int test_punycode(int n)
    148  1.1  christos {
    149  1.1  christos     const struct puny_test *tc = puny_cases + n;
    150  1.1  christos     unsigned int buffer[50];
    151  1.1  christos     unsigned int bsize = OSSL_NELEM(buffer);
    152  1.1  christos     size_t i;
    153  1.1  christos 
    154  1.1  christos     if (!TEST_true(ossl_punycode_decode(tc->encoded, strlen(tc->encoded),
    155  1.1  christos                                         buffer, &bsize)))
    156  1.1  christos         return 0;
    157  1.1  christos     for (i = 0; i < OSSL_NELEM(tc->raw); i++)
    158  1.1  christos         if (tc->raw[i] == 0)
    159  1.1  christos             break;
    160  1.1  christos     if (!TEST_mem_eq(buffer, bsize * sizeof(*buffer),
    161  1.1  christos                      tc->raw, i * sizeof(*tc->raw)))
    162  1.1  christos         return 0;
    163  1.1  christos     return 1;
    164  1.1  christos }
    165  1.1  christos 
    166  1.1  christos static int test_a2ulabel(void)
    167  1.1  christos {
    168  1.1  christos     char out[50];
    169  1.1  christos     size_t outlen;
    170  1.1  christos 
    171  1.1  christos     /*
    172  1.1  christos      * Test that no buffer correctly returns the true length.
    173  1.1  christos      * The punycode being passed in and parsed is malformed but we're not
    174  1.1  christos      * verifying that behaviour here.
    175  1.1  christos      */
    176  1.1  christos     if (!TEST_int_eq(ossl_a2ulabel("xn--a.b.c", NULL, &outlen), 0)
    177  1.1  christos             || !TEST_size_t_eq(outlen, 7)
    178  1.1  christos             || !TEST_int_eq(ossl_a2ulabel("xn--a.b.c", out, &outlen), 1))
    179  1.1  christos         return 0;
    180  1.1  christos     /* Test that a short input length returns the true length */
    181  1.1  christos     outlen = 1;
    182  1.1  christos     if (!TEST_int_eq(ossl_a2ulabel("xn--a.b.c", out, &outlen), 0)
    183  1.1  christos             || !TEST_size_t_eq(outlen, 7)
    184  1.1  christos             || !TEST_int_eq(ossl_a2ulabel("xn--a.b.c", out, &outlen), 1)
    185  1.1  christos             || !TEST_str_eq(out,"\xc2\x80.b.c"))
    186  1.1  christos         return 0;
    187  1.1  christos     /* Test for an off by one on the buffer size works */
    188  1.1  christos     outlen = 6;
    189  1.1  christos     if (!TEST_int_eq(ossl_a2ulabel("xn--a.b.c", out, &outlen), 0)
    190  1.1  christos             || !TEST_size_t_eq(outlen, 7)
    191  1.1  christos             || !TEST_int_eq(ossl_a2ulabel("xn--a.b.c", out, &outlen), 1)
    192  1.1  christos             || !TEST_str_eq(out,"\xc2\x80.b.c"))
    193  1.1  christos         return 0;
    194  1.1  christos     return 1;
    195  1.1  christos }
    196  1.1  christos 
    197  1.1  christos static int test_puny_overrun(void)
    198  1.1  christos {
    199  1.1  christos     static const unsigned int out[] = {
    200  1.1  christos         0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F
    201  1.1  christos     };
    202  1.1  christos     static const char *in = "3B-ww4c5e180e575a65lsy2b";
    203  1.1  christos     unsigned int buf[OSSL_NELEM(out)];
    204  1.1  christos     unsigned int bsize = OSSL_NELEM(buf) - 1;
    205  1.1  christos 
    206  1.1  christos     if (!TEST_false(ossl_punycode_decode(in, strlen(in), buf, &bsize))) {
    207  1.1  christos         if (TEST_mem_eq(buf, bsize * sizeof(*buf), out, sizeof(out)))
    208  1.1  christos             TEST_error("CRITICAL: buffer overrun detected!");
    209  1.1  christos         return 0;
    210  1.1  christos     }
    211  1.1  christos     return 1;
    212  1.1  christos }
    213  1.1  christos 
    214  1.1  christos int setup_tests(void)
    215  1.1  christos {
    216  1.1  christos     ADD_ALL_TESTS(test_punycode, OSSL_NELEM(puny_cases));
    217  1.1  christos     ADD_TEST(test_a2ulabel);
    218  1.1  christos     ADD_TEST(test_puny_overrun);
    219  1.1  christos     return 1;
    220  1.1  christos }
    221