Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_identification.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2013-2015 Tobias Brunner
                      3:  * Copyright (C) 2016 Andreas Steffen
                      4:  * Copyright (C) 2009 Martin Willi
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include "test_suite.h"
                     19: 
                     20: #include <utils/identification.h>
                     21: 
                     22: /*******************************************************************************
                     23:  * create (_from_encoding, _from_data, _from_string, _from_sockaddr)
                     24:  */
                     25: 
                     26: START_TEST(test_from_encoding)
                     27: {
                     28:        identification_t *a;
                     29:        chunk_t expected, encoding;
                     30: 
                     31:        /* only ID_ANY is handled differently, for all other types the following
                     32:         * applies.  should we perhaps test that this is in fact the case? */
                     33:        expected = chunk_from_str("moon@strongswan.org");
                     34:        a = identification_create_from_encoding(ID_RFC822_ADDR, expected);
                     35:        ck_assert(ID_RFC822_ADDR == a->get_type(a));
                     36:        encoding = a->get_encoding(a);
                     37:        ck_assert(expected.ptr != encoding.ptr);
                     38:        ck_assert(chunk_equals(expected, encoding));
                     39:        a->destroy(a);
                     40: 
                     41:        a = identification_create_from_encoding(ID_ANY, expected);
                     42:        ck_assert(ID_ANY == a->get_type(a));
                     43:        encoding = a->get_encoding(a);
                     44:        ck_assert(encoding.ptr == NULL);
                     45:        ck_assert(encoding.len == 0);
                     46:        a->destroy(a);
                     47: }
                     48: END_TEST
                     49: 
                     50: START_TEST(test_from_data)
                     51: {
                     52:        identification_t *a;
                     53:        chunk_t expected, encoding;
                     54: 
                     55:        /* this uses the DN parser (C=CH) */
                     56:        expected = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
                     57:                                                                0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48);
                     58:        a = identification_create_from_data(expected);
                     59:        ck_assert(ID_DER_ASN1_DN == a->get_type(a));
                     60:        encoding = a->get_encoding(a);
                     61:        ck_assert(expected.ptr != encoding.ptr);
                     62:        ck_assert(chunk_equals(expected, encoding));
                     63:        a->destroy(a);
                     64: 
                     65:        /* everything else is handled by the string parser */
                     66:        expected = chunk_from_str("moon@strongswan.org");
                     67:        a = identification_create_from_data(expected);
                     68:        ck_assert(ID_RFC822_ADDR == a->get_type(a));
                     69:        encoding = a->get_encoding(a);
                     70:        ck_assert(expected.ptr != encoding.ptr);
                     71:        ck_assert(chunk_equals(expected, encoding));
                     72:        a->destroy(a);
                     73: }
                     74: END_TEST
                     75: 
                     76: START_TEST(test_from_sockaddr)
                     77: {
                     78:        identification_t *a;
                     79:        chunk_t expected, encoding;
                     80:        struct sockaddr_in in = {
                     81:                .sin_family = AF_INET,
                     82:        };
                     83:        struct sockaddr_in6 in6 = {
                     84:                .sin6_family = AF_INET6,
                     85:        };
                     86: 
                     87:        expected = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01);
                     88:        memcpy(&in.sin_addr, expected.ptr, sizeof(in.sin_addr));
                     89:        a = identification_create_from_sockaddr((sockaddr_t*)&in);
                     90:        ck_assert(ID_IPV4_ADDR == a->get_type(a));
                     91:        encoding = a->get_encoding(a);
                     92:        ck_assert(chunk_equals(expected, encoding));
                     93:        a->destroy(a);
                     94: 
                     95:        expected = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                     96:                                                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
                     97:        memcpy(&in6.sin6_addr, expected.ptr, sizeof(in6.sin6_addr));
                     98:        a = identification_create_from_sockaddr((sockaddr_t*)&in6);
                     99:        ck_assert(ID_IPV6_ADDR == a->get_type(a));
                    100:        encoding = a->get_encoding(a);
                    101:        ck_assert(chunk_equals(expected, encoding));
                    102:        a->destroy(a);
                    103: 
                    104:        in6.sin6_family = AF_UNSPEC;
                    105:        a = identification_create_from_sockaddr((sockaddr_t*)&in6);
                    106:        ck_assert(ID_ANY == a->get_type(a));
                    107:        a->destroy(a);
                    108: }
                    109: END_TEST
                    110: 
                    111: static struct {
                    112:        char *id;
                    113:        id_type_t type;
                    114:        struct {
                    115:                enum {
                    116:                        ENC_CHUNK,
                    117:                        ENC_STRING,
                    118:                        ENC_SIMPLE,
                    119:                } type;
                    120:                union {
                    121:                        chunk_t c;
                    122:                        char *s;
                    123:                } data;
                    124:        } result;
                    125: } string_data[] = {
                    126:        {NULL,                                          ID_ANY,                                 { .type = ENC_CHUNK  }},
                    127:        {"",                                            ID_ANY,                                 { .type = ENC_CHUNK  }},
                    128:        {"%any",                                        ID_ANY,                                 { .type = ENC_CHUNK  }},
                    129:        {"%any6",                                       ID_ANY,                                 { .type = ENC_CHUNK  }},
                    130:        {"0.0.0.0",                                     ID_ANY,                                 { .type = ENC_CHUNK  }},
                    131:        {"0::0",                                        ID_ANY,                                 { .type = ENC_CHUNK  }},
                    132:        {"::",                                          ID_ANY,                                 { .type = ENC_CHUNK  }},
                    133:        {"*",                                           ID_ANY,                                 { .type = ENC_CHUNK  }},
                    134:        {"any",                                         ID_FQDN,                                { .type = ENC_SIMPLE }},
                    135:        {"any6",                                        ID_FQDN,                                { .type = ENC_SIMPLE }},
                    136:        {"0",                                           ID_FQDN,                                { .type = ENC_SIMPLE }},
                    137:        {"**",                                          ID_FQDN,                                { .type = ENC_SIMPLE }},
                    138:        {"192.168.1.1",                         ID_IPV4_ADDR,                   { .type = ENC_CHUNK,
                    139:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
                    140:        {"192.168.",                            ID_FQDN,                                { .type = ENC_SIMPLE }},
                    141:        {".",                                           ID_FQDN,                                { .type = ENC_SIMPLE }},
                    142:        {"192.168.1.1/33",                      ID_FQDN,                                { .type = ENC_SIMPLE }},
                    143:        {"192.168.1.1/32",                      ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    144:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01,0xff,0xff,0xff,0xff)  }},
                    145:        {"192.168.1.1/31",                      ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    146:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x00,0xff,0xff,0xff,0xfe)  }},
                    147:        {"192.168.1.8/30",                      ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    148:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x08,0xff,0xff,0xff,0xfc)  }},
                    149:        {"192.168.1.128/25",            ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    150:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x80,0xff,0xff,0xff,0x80)  }},
                    151:        {"192.168.1.0/24",                      ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    152:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x00,0xff,0xff,0xff,0x00)  }},
                    153:        {"192.168.1.0/23",                      ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    154:                .data.c = chunk_from_chars(0xc0,0xa8,0x00,0x00,0xff,0xff,0xfe,0x00)  }},
                    155:        {"192.168.4.0/22",                      ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    156:                .data.c = chunk_from_chars(0xc0,0xa8,0x04,0x00,0xff,0xff,0xfc,0x00)  }},
                    157:        {"0.0.0.0/0",                           ID_IPV4_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    158:                .data.c = chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)  }},
                    159:        {"192.168.1.0-192.168.1.40",ID_IPV4_ADDR_RANGE,         { .type = ENC_CHUNK,
                    160:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x00,0xc0,0xa8,0x01,0x28)  }},
                    161:        {"0.0.0.0-255.255.255.255",     ID_IPV4_ADDR_RANGE,             { .type = ENC_CHUNK,
                    162:                .data.c = chunk_from_chars(0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff)  }},
                    163:        {"192.168.1.40-192.168.1.0",ID_FQDN,                            { .type = ENC_SIMPLE }},
                    164:        {"fec0::1",                                     ID_IPV6_ADDR,                   { .type = ENC_CHUNK,
                    165:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    166:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01)  }},
                    167:        {"fec0::",                                      ID_IPV6_ADDR,                   { .type = ENC_CHUNK,
                    168:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    169:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00)  }},
                    170:        {"fec0:",                                       ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    171:        {":",                                           ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    172:        {"fec0::1/129",                         ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    173:        {"fec0::1/128",                         ID_IPV6_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    174:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    175:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
                    176:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                    177:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ) }},
                    178:        {"fec0::1/127",                         ID_IPV6_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    179:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    180:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                    181:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                    182:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe ) }},
                    183:        {"fec0::4/126",                         ID_IPV6_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    184:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    185:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
                    186:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                    187:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc ) }},
                    188:        {"fec0::100/120",                       ID_IPV6_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    189:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    190:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
                    191:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                    192:                                                                   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 ) }},
                    193:        {"::/0",                                        ID_IPV6_ADDR_SUBNET,    { .type = ENC_CHUNK,
                    194:                .data.c = chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                    195:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                    196:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                    197:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ) }},
                    198:        {"fec0::1-fec0::4fff",          ID_IPV6_ADDR_RANGE,             { .type = ENC_CHUNK,
                    199:                .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    200:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
                    201:                                                                   0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    202:                                                                   0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0xff ) }},
                    203:        {"fec0::4fff-fec0::1",          ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    204:        {"fec0::1-",                            ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    205:        {"alice@strongswan.org",        ID_RFC822_ADDR,                 { .type = ENC_SIMPLE }},
                    206:        {"alice@strongswan",            ID_RFC822_ADDR,                 { .type = ENC_SIMPLE }},
                    207:        {"alice@",                                      ID_RFC822_ADDR,                 { .type = ENC_SIMPLE }},
                    208:        {"alice",                                       ID_FQDN,                                { .type = ENC_SIMPLE }},
                    209:        {"@",                                           ID_FQDN,                                { .type = ENC_CHUNK }},
                    210:        {" @",                                          ID_RFC822_ADDR,                 { .type = ENC_SIMPLE }},
                    211:        {"@strongswan.org",                     ID_FQDN,                                { .type = ENC_STRING,
                    212:                .data.s = "strongswan.org" }},
                    213:        {"@#deadbeef",                          ID_KEY_ID,                              { .type = ENC_CHUNK,
                    214:                .data.c = chunk_from_chars(0xde,0xad,0xbe,0xef) }},
                    215:        {"@#deadbee",                           ID_KEY_ID,                              { .type = ENC_CHUNK,
                    216:                .data.c = chunk_from_chars(0x0d,0xea,0xdb,0xee) }},
                    217:        {"foo=bar",                                     ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    218:        {"foo=",                                        ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    219:        {"=bar",                                        ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    220:        {"C=",                                          ID_DER_ASN1_DN,                 { .type = ENC_CHUNK,
                    221:                .data.c = chunk_from_chars(0x30,0x0b,0x31,0x09,0x30,0x07,0x06,
                    222:                                                                   0x03,0x55,0x04,0x06,0x13,0x00) }},
                    223:        {"C=CH",                                        ID_DER_ASN1_DN,                 { .type = ENC_CHUNK,
                    224:                .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
                    225:                                                                   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
                    226:        {"C=CH,",                                       ID_DER_ASN1_DN,                 { .type = ENC_CHUNK,
                    227:                .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
                    228:                                                                   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
                    229:        {"C=CH, ",                                      ID_DER_ASN1_DN,                 { .type = ENC_CHUNK,
                    230:                .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
                    231:                                                                   0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
                    232:        {"C=CH, O",                                     ID_KEY_ID,                              { .type = ENC_SIMPLE }},
                    233:        {"IPv4:#c0a80101",                      ID_IPV4_ADDR,                   { .type = ENC_CHUNK,
                    234:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
                    235:        { "email:tester",                       ID_RFC822_ADDR,                 { .type = ENC_STRING,
                    236:                .data.s = "tester" }},
                    237:        {"xmppaddr:bob@strongswan.org", ID_DER_ASN1_GN,         { .type = ENC_CHUNK,
                    238:                .data.c = chunk_from_chars(0xa0,0x20,0x06,0x08,0x2b,0x06,0x01,0x05,
                    239:                                                                   0x05,0x07,0x08,0x05,0xa0,0x14,0x0c,0x12,
                    240:                                                                   0x62,0x6f,0x62,0x40,0x73,0x74,0x72,0x6f,
                    241:                                                                   0x6e,0x67,0x73,0x77,0x61,0x6e,0x2e,0x6f,
                    242:                                                                   0x72,0x67) }},
                    243:        { "{1}:#c0a80101",                      ID_IPV4_ADDR,                   { .type = ENC_CHUNK,
                    244:                .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
                    245:        { "{0x02}:tester",                      ID_FQDN,                                { .type = ENC_STRING,
                    246:                .data.s = "tester" }},
                    247:        { "{99}:somedata",                      99,                                             { .type = ENC_STRING,
                    248:                .data.s = "somedata" }},
                    249: };
                    250: 
                    251: START_TEST(test_from_string)
                    252: {
                    253:        identification_t *a;
                    254:        chunk_t encoding, expected = chunk_empty;
                    255:        char *id;
                    256: 
                    257:        id = string_data[_i].id;
                    258:        a = identification_create_from_string(id);
                    259:        fail_unless(a->get_type(a) == string_data[_i].type,
                    260:                                "type of id '%s' is %N, %N expected", id,
                    261:                                id_type_names, a->get_type(a),
                    262:                                id_type_names, string_data[_i].type);
                    263: 
                    264:        encoding = a->get_encoding(a);
                    265:        switch (string_data[_i].result.type)
                    266:        {
                    267:                case ENC_SIMPLE:
                    268:                        expected = chunk_from_str(string_data[_i].id);
                    269:                        break;
                    270:                case ENC_STRING:
                    271:                        expected = chunk_from_str(string_data[_i].result.data.s);
                    272:                        break;
                    273:                case ENC_CHUNK:
                    274:                        expected = string_data[_i].result.data.c;
                    275:                        break;
                    276:                default:
                    277:                        fail("unexpected result type");
                    278:        }
                    279: 
                    280:        ck_assert(!id || (char*)encoding.ptr != id);
                    281:        if (expected.ptr)
                    282:        {
                    283:                fail_unless(chunk_equals(encoding, expected),
                    284:                                        "parsing '%s' failed\nencoding %B\nexpected %B\n",
                    285:                                        id, &encoding, &expected);
                    286:        }
                    287:        else
                    288:        {
                    289:                ck_assert(encoding.ptr == NULL);
                    290:                ck_assert(encoding.len == 0);
                    291:        }
                    292:        a->destroy(a);
                    293: }
                    294: END_TEST
                    295: 
                    296: /*******************************************************************************
                    297:  * printf_hook
                    298:  */
                    299: 
                    300: static void string_equals(char *a_str, char *b_str)
                    301: {
                    302:        identification_t *b;
                    303:        char buf[128];
                    304: 
                    305:        b = b_str ? identification_create_from_string(b_str) : NULL;
                    306:        snprintf(buf, sizeof(buf), "%Y", b);
                    307:        DESTROY_IF(b);
                    308:        ck_assert_str_eq(a_str, buf);
                    309: }
                    310: 
                    311: static void string_equals_id(char *a_str, identification_t *b)
                    312: {
                    313:        char buf[128];
                    314: 
                    315:        snprintf(buf, sizeof(buf), "%Y", b);
                    316:        DESTROY_IF(b);
                    317:        ck_assert_str_eq(a_str, buf);
                    318: }
                    319: 
                    320: START_TEST(test_printf_hook)
                    321: {
                    322:        string_equals("(null)", NULL);
                    323:        string_equals("%any", "");
                    324:        string_equals("%any", "%any");
                    325:        string_equals("%any", "*");
                    326: 
                    327:        string_equals("192.168.1.1", "192.168.1.1");
                    328:        string_equals_id("(invalid ID_IPV4_ADDR)",
                    329:                        identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty));
                    330:        string_equals("192.168.1.1/32", "192.168.1.1/32");
                    331:        string_equals("192.168.1.2/31", "192.168.1.2/31");
                    332:        string_equals("192.168.1.0/24", "192.168.1.0/24");
                    333:        string_equals("192.168.2.0/23", "192.168.2.0/23");
                    334:        string_equals("0.0.0.0/0", "0.0.0.0/0");
                    335:        string_equals_id("(invalid ID_IPV4_ADDR_SUBNET)",
                    336:                        identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty));
                    337:        string_equals("192.168.1.1-192.168.1.254", "192.168.1.1-192.168.1.254");
                    338:        string_equals("0.0.0.0-255.255.255.255", "0.0.0.0-255.255.255.255");
                    339:        string_equals_id("(invalid ID_IPV4_ADDR_RANGE)",
                    340:                        identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty));
                    341:        string_equals("fec0::1", "fec0::1");
                    342:        string_equals("fec0::1", "fec0:0:0::1");
                    343:        string_equals_id("(invalid ID_IPV6_ADDR)",
                    344:                        identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty));
                    345:        string_equals("fec0::1/128", "fec0::1/128");
                    346:        string_equals("fec0::2/127", "fec0::2/127");
                    347:        string_equals("fec0::100/120", "fec0::100/120");
                    348:        string_equals("::/0", "::/0");
                    349:        string_equals_id("(invalid ID_IPV6_ADDR_SUBNET)",
                    350:                        identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty));
                    351:        string_equals("fec0::1-fec0::4fff", "fec0::1-fec0::4fff");
                    352:        string_equals_id("(invalid ID_IPV6_ADDR_RANGE)",
                    353:                        identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty));
                    354:        string_equals_id("(unknown ID type: 255)",
                    355:                        identification_create_from_encoding(255, chunk_empty));
                    356: 
                    357:        string_equals("moon@strongswan.org", "moon@strongswan.org");
                    358:        string_equals("MOON@STRONGSWAN.ORG", "MOON@STRONGSWAN.ORG");
                    359:        /* non-printable characters */
                    360:        string_equals_id("????@strongswan.org", identification_create_from_encoding(ID_RFC822_ADDR,
                    361:                        chunk_from_chars(0xfa, 0xfb, 0xfc, 0xfd, 0x40, 0x73, 0x74, 0x72,
                    362:                                                         0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
                    363:                                                         0x6f, 0x72, 0x67)));
                    364: 
                    365:        /* not a DN => ID_KEY_ID => no normalization */
                    366:        string_equals("C=CH, AsdF=asdf", "C=CH, AsdF=asdf");
                    367:        string_equals_id("moon@strongswan.org", identification_create_from_encoding(ID_KEY_ID,
                    368:                        chunk_from_str("moon@strongswan.org")));
                    369:        /* non-printable characters */
                    370:        string_equals_id("de:ad:be:ef", identification_create_from_encoding(ID_KEY_ID,
                    371:                        chunk_from_chars(0xde, 0xad, 0xbe, 0xef)));
                    372:        /* printable characters */
                    373:        string_equals_id("ABCDEFGHIJKLMNOPQRS",
                    374:                identification_create_from_encoding(ID_KEY_ID,
                    375:                        chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
                    376:                                                         0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
                    377:                                                         0x51, 0x52, 0x53)));
                    378:        /* ABCDEFGHIJKLMNOPQRST is printable but has the length of a SHA1 hash */
                    379:        string_equals_id("41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54",
                    380:                identification_create_from_encoding(ID_KEY_ID,
                    381:                        chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
                    382:                                                         0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
                    383:                                                         0x51, 0x52, 0x53, 0x54)));
                    384: 
                    385:        string_equals_id("", identification_create_from_encoding(ID_DER_ASN1_DN, chunk_empty));
                    386:        string_equals("C=", "C=");
                    387:        string_equals("C=", "C=,");
                    388:        string_equals("C=", "C=, ");
                    389:        string_equals("C=", "C= , ");
                    390:        string_equals("C=, O=strongSwan", "C=, O=strongSwan");
                    391:        string_equals("C=CH, O=", "C=CH, O=");
                    392:        string_equals("C=CH, O=strongSwan, CN=strongswan.org",
                    393:                                  "C=CH, O=strongSwan, CN=strongswan.org");
                    394:        string_equals("CN=strongswan.org, O=strongSwan, C=CH",
                    395:                                  "cn=strongswan.org, o=strongSwan, c=CH");
                    396:        string_equals("C=CH, O=strongSwan, CN=strongswan.org",
                    397:                                  "C=CH,O=strongSwan,CN=strongswan.org");
                    398:        string_equals("C=CH, O=strongSwan, CN=strongswan.org",
                    399:                                  "/C=CH/O=strongSwan/CN=strongswan.org");
                    400:        string_equals("CN=strongswan.org, O=strongSwan, C=CH",
                    401:                                  "CN=strongswan.org,O=strongSwan,C=CH");
                    402: 
                    403:        string_equals("C=CH, E=moon@strongswan.org, CN=moon",
                    404:                                  "C=CH, email=moon@strongswan.org, CN=moon");
                    405:        string_equals("C=CH, E=moon@strongswan.org, CN=moon",
                    406:                                  "C=CH, emailAddress=moon@strongswan.org, CN=moon");
                    407: 
                    408:        /* C=CH, telexNumber=123 (telexNumber is currently not recognized) */
                    409:        string_equals_id("C=CH, 55:04:15=123", identification_create_from_encoding(ID_DER_ASN1_DN,
                    410:                chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
                    411:                                                 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
                    412:                                                 0x03, 0x55, 0x04, 0x15, 0x13, 0x03, 0x31, 0x32, 0x33)));
                    413:        /* C=CH, O=strongSwan (but instead of a 2nd OID -0x06- we got NULL -0x05) */
                    414:        string_equals_id("C=CH, (invalid ID_DER_ASN1_DN)", identification_create_from_encoding(ID_DER_ASN1_DN,
                    415:                chunk_from_chars(0x30, 0x20, 0x31, 0x1e, 0x30, 0x09, 0x06, 0x03, 0x55,
                    416:                                                 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x11, 0x05,
                    417:                                                 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x73, 0x74, 0x72,
                    418:                                                 0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e)));
                    419:        /* moon@strongswan.org as GN */
                    420:        string_equals_id("(ASN.1 general name)", identification_create_from_encoding(ID_DER_ASN1_GN,
                    421:                chunk_from_chars(0x81, 0x14, 0x6d, 0x6f, 0x6f, 0x6e, 0x40, 0x73, 0x74,
                    422:                                                 0x72, 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
                    423:                                                 0x6f, 0x72, 0x67)));
                    424: }
                    425: END_TEST
                    426: 
                    427: START_TEST(test_printf_hook_width)
                    428: {
                    429:        identification_t *a;
                    430:        char buf[128];
                    431: 
                    432:        a = identification_create_from_string("moon@strongswan.org");
                    433:        snprintf(buf, sizeof(buf), "%25Y", a);
                    434:        ck_assert_str_eq("      moon@strongswan.org", buf);
                    435:        snprintf(buf, sizeof(buf), "%-*Y", 25, a);
                    436:        ck_assert_str_eq("moon@strongswan.org      ", buf);
                    437:        snprintf(buf, sizeof(buf), "%5Y", a);
                    438:        ck_assert_str_eq("moon@strongswan.org", buf);
                    439:        DESTROY_IF(a);
                    440: }
                    441: END_TEST
                    442: 
                    443: /*******************************************************************************
                    444:  * equals
                    445:  */
                    446: 
                    447: static bool id_equals(identification_t *a, char *b_str)
                    448: {
                    449:        identification_t *b;
                    450:        bool equals;
                    451: 
                    452:        b = identification_create_from_string(b_str);
                    453:        equals = a->equals(a, b);
                    454:        ck_assert_int_eq(equals, b->equals(b, a));
                    455:        b->destroy(b);
                    456:        return equals;
                    457: }
                    458: 
                    459: START_TEST(test_equals)
                    460: {
                    461:        identification_t *a;
                    462:        chunk_t encoding, fuzzed;
                    463:        int i;
                    464: 
                    465:        /* this test also tests identification_create_from_string with DNs */
                    466:        a = identification_create_from_string(
                    467:                                                         "C=CH, E=moon@strongswan.org, CN=moon");
                    468: 
                    469:        ck_assert(id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
                    470:        ck_assert(id_equals(a, "C=CH, email=moon@strongswan.org, CN=moon"));
                    471:        ck_assert(id_equals(a, "C=CH, emailAddress=moon@strongswan.org, CN=moon"));
                    472:        ck_assert(id_equals(a, "C==CH , E==moon@strongswan.org , CN==moon"));
                    473:        ck_assert(id_equals(a, "  C=CH, E=moon@strongswan.org, CN=moon  "));
                    474:        ck_assert(id_equals(a, "C=ch, E=moon@STRONGSWAN.ORG, CN=Moon"));
                    475:        ck_assert(id_equals(a, "/C=CH/E=moon@strongswan.org/CN=moon"));
                    476:        ck_assert(id_equals(a, " / C=CH / E=moon@strongswan.org / CN=moon"));
                    477: 
                    478:        ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org/CN=moon"));
                    479:        ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org,CN=moon"));
                    480:        ck_assert(!id_equals(a, "C=CH E=moon@strongswan.org CN=moon"));
                    481:        ck_assert(!id_equals(a, "C=CN, E=moon@strongswan.org, CN=moon"));
                    482:        ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
                    483:        ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
                    484: 
                    485:        encoding = chunk_clone(a->get_encoding(a));
                    486:        a->destroy(a);
                    487: 
                    488:        /* simple fuzzing, increment each byte of encoding */
                    489:        for (i = 0; i < encoding.len; i++)
                    490:        {
                    491:                if (i == 11 || i == 30 || i == 60)
                    492:                {       /* skip ASN.1 type fields, as equals() handles them graceful */
                    493:                        continue;
                    494:                }
                    495:                fuzzed = chunk_clone(encoding);
                    496:                fuzzed.ptr[i]++;
                    497:                a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
                    498:                if (id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"))
                    499:                {
                    500:                        printf("%d %B\n%B\n", i, &fuzzed, &encoding);
                    501:                }
                    502:                ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
                    503:                a->destroy(a);
                    504:                free(fuzzed.ptr);
                    505:        }
                    506: 
                    507:        /* and decrement each byte of encoding */
                    508:        for (i = 0; i < encoding.len; i++)
                    509:        {
                    510:                if (i == 11 || i == 30 || i == 60)
                    511:                {
                    512:                        continue;
                    513:                }
                    514:                fuzzed = chunk_clone(encoding);
                    515:                fuzzed.ptr[i]--;
                    516:                a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
                    517:                ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
                    518:                a->destroy(a);
                    519:                free(fuzzed.ptr);
                    520:        }
                    521:        free(encoding.ptr);
                    522: }
                    523: END_TEST
                    524: 
                    525: START_TEST(test_equals_any)
                    526: {
                    527:        identification_t *a, *b;
                    528: 
                    529:        a = identification_create_from_string("%any");
                    530:        b = identification_create_from_encoding(ID_ANY, chunk_empty);
                    531:        ck_assert(a->equals(a, b));
                    532:        ck_assert(b->equals(b, a));
                    533:        b->destroy(b);
                    534: 
                    535:        b = identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
                    536:        ck_assert(!a->equals(a, b));
                    537:        ck_assert(!b->equals(b, a));
                    538:        a->destroy(a);
                    539:        b->destroy(b);
                    540: }
                    541: END_TEST
                    542: 
                    543: START_TEST(test_equals_binary)
                    544: {
                    545:        identification_t *a, *b;
                    546:        chunk_t encoding;
                    547: 
                    548:        encoding = chunk_from_str("foobar=");
                    549:        /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
                    550:        a = identification_create_from_string("foobar=");
                    551:        ck_assert(a->get_type(a) == ID_KEY_ID);
                    552:        b = identification_create_from_encoding(ID_KEY_ID, encoding);
                    553:        ck_assert(a->equals(a, b));
                    554:        a->destroy(a);
                    555:        b->destroy(b);
                    556: }
                    557: END_TEST
                    558: 
                    559: START_TEST(test_equals_fqdn)
                    560: {
                    561:        identification_t *a;
                    562: 
                    563:        a = identification_create_from_string("ipsec.strongswan.org");
                    564:        ck_assert(id_equals(a, "IPSEC.strongswan.org"));
                    565:        ck_assert(id_equals(a, "ipsec.strongSwan.org"));
                    566:        ck_assert(id_equals(a, "ipsec.strongSwan.ORG"));
                    567:        ck_assert(!id_equals(a, "strongswan.org"));
                    568:        a->destroy(a);
                    569: }
                    570: END_TEST
                    571: 
                    572: START_TEST(test_equals_empty)
                    573: {
                    574:        identification_t *a;
                    575: 
                    576:        a = identification_create_from_encoding(_i, chunk_empty);
                    577: 
                    578:        switch (_i)
                    579:        {
                    580:                case ID_ANY:
                    581:                        ck_assert(id_equals(a, "%any"));
                    582:                        break;
                    583:                case ID_IPV4_ADDR:
                    584:                        ck_assert(!id_equals(a, "192.168.1.1"));
                    585:                        break;
                    586:                case ID_FQDN:
                    587:                        ck_assert(!id_equals(a, "moon.strongswan.org"));
                    588:                        break;
                    589:                case ID_USER_FQDN:
                    590:                        ck_assert(!id_equals(a, "moon@strongswan.org"));
                    591:                        break;
                    592:                case ID_IPV6_ADDR:
                    593:                        ck_assert(!id_equals(a, "fec0::1"));
                    594:                        break;
                    595:                case ID_DER_ASN1_DN:
                    596:                        ck_assert(!id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
                    597:                        break;
                    598:                case ID_KEY_ID:
                    599:                        ck_assert(!id_equals(a, "@#12345678"));
                    600:                        break;
                    601:                case ID_DER_ASN1_GN:
                    602:                case ID_IPV4_ADDR_SUBNET:
                    603:                case ID_IPV6_ADDR_SUBNET:
                    604:                case ID_IPV4_ADDR_RANGE:
                    605:                case ID_IPV6_ADDR_RANGE:
                    606:                        /* currently not tested */
                    607:                        break;
                    608:        }
                    609: 
                    610:        a->destroy(a);
                    611: }
                    612: END_TEST
                    613: 
                    614: /*******************************************************************************
                    615:  * matches
                    616:  */
                    617: 
                    618: static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
                    619: {
                    620:        identification_t *b;
                    621:        id_match_t match;
                    622: 
                    623:        b = identification_create_from_string(b_str);
                    624:        match = a->matches(a, b);
                    625:        b->destroy(b);
                    626:        return match == expected;
                    627: }
                    628: 
                    629: static char* rdn_matching[] = { NULL, "reordered", "relaxed" };
                    630: 
                    631: static struct {
                    632:        char *id;
                    633:        id_match_t match[3];
                    634: } matches_data[] = {
                    635:        /* C=CH, E=moon@strongswan.org, CN=moon */
                    636:        { "C=CH, E=moon@strongswan.org, CN=moon", {
                    637:                ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
                    638:        { "C=CH, email=moon@strongswan.org, CN=moon", {
                    639:                ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
                    640:        { "C=CH, emailAddress=moon@strongswan.org, CN=moon", {
                    641:                ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
                    642:        { "CN=moon, C=CH, E=moon@strongswan.org", {
                    643:                ID_MATCH_NONE, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
                    644:        { "C=CH, E=*@strongswan.org, CN=moon", {
                    645:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
                    646:        { "C=CH, E=*, CN=moon", {
                    647:                ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
                    648:        { "C=CH, E=*, CN=*", {
                    649:                ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1 }},
                    650:        { "C=*, E=*, CN=*", {
                    651:                ID_MATCH_ONE_WILDCARD - 2, ID_MATCH_ONE_WILDCARD - 2, ID_MATCH_ONE_WILDCARD - 2 }},
                    652:        { "C=*, E=*, CN=*, O=BADInc", {
                    653:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
                    654:        { "C=CH, CN=*", {
                    655:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 1 }},
                    656:        { "C=*, E=*", {
                    657:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 2 }},
                    658:        { "C=*, E=a@b.c, CN=*", {
                    659:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
                    660:        { "C=CH, O=strongSwan, E=*, CN=*", {
                    661:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
                    662:        { "", {
                    663:                ID_MATCH_ANY, ID_MATCH_ANY, ID_MATCH_ANY }},
                    664:        { "%any", {
                    665:                ID_MATCH_ANY, ID_MATCH_ANY, ID_MATCH_ANY }},
                    666: };
                    667: 
                    668: START_TEST(test_matches)
                    669: {
                    670:        identification_t *a;
                    671:        int i;
                    672: 
                    673:        if (rdn_matching[_i])
                    674:        {
                    675:                lib->settings->set_str(lib->settings, "%s.rdn_matching",
                    676:                                                           rdn_matching[_i], lib->ns);
                    677:        }
                    678: 
                    679:        a = identification_create_from_string("C=CH, E=moon@strongswan.org, CN=moon");
                    680: 
                    681:        for (i = 0; i < countof(matches_data); i++)
                    682:        {
                    683:                ck_assert(id_matches(a, matches_data[i].id, matches_data[i].match[_i]));
                    684:        }
                    685: 
                    686:        a->destroy(a);
                    687: }
                    688: END_TEST
                    689: 
                    690: static struct {
                    691:        char *id;
                    692:        id_match_t match[3];
                    693: } matches_two_ou_data[] = {
                    694:        /* C=CH, OU=Research, OU=Floor A, CN=moon */
                    695:        { "C=CH, OU=Research, OU=Floor A, CN=moon", {
                    696:                ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
                    697:        { "C=CH, OU=Floor A, CN=moon", {
                    698:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD }},
                    699:        { "C=CH, CN=moon", {
                    700:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 1 }},
                    701:        { "C=CH, OU=*, CN=moon", {
                    702:                ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 1 }},
                    703:        { "C=CH, OU=*, OU=*, CN=moon", {
                    704:                ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1 }},
                    705:        { "C=CH, OU=Research, OU=*, CN=moon", {
                    706:                ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
                    707:        { "C=CH, OU=*, OU=Floor A, CN=moon", {
                    708:                ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
                    709:        { "C=CH, OU=*, OU=Research, CN=moon", {
                    710:                ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
                    711:        { "C=CH, OU=Floor A, OU=*, CN=moon", {
                    712:                ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
                    713:        { "C=CH, OU=Floor A, OU=Research, CN=moon", {
                    714:                ID_MATCH_NONE, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
                    715: };
                    716: 
                    717: START_TEST(test_matches_two_ou)
                    718: {
                    719:        identification_t *a;
                    720:        int i;
                    721: 
                    722:        if (rdn_matching[_i])
                    723:        {
                    724:                lib->settings->set_str(lib->settings, "%s.rdn_matching",
                    725:                                                           rdn_matching[_i], lib->ns);
                    726:        }
                    727: 
                    728:        a = identification_create_from_string("C=CH, OU=Research, OU=Floor A, CN=moon");
                    729: 
                    730:        for (i = 0; i < countof(matches_two_ou_data); i++)
                    731:        {
                    732:                ck_assert(id_matches(a, matches_two_ou_data[i].id, matches_two_ou_data[i].match[_i]));
                    733:        }
                    734: 
                    735:        a->destroy(a);
                    736: }
                    737: END_TEST
                    738: 
                    739: START_TEST(test_matches_any)
                    740: {
                    741:        identification_t *a;
                    742: 
                    743:        a = identification_create_from_string("%any");
                    744: 
                    745:        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    746:        ck_assert(id_matches(a, "", ID_MATCH_ANY));
                    747:        ck_assert(id_matches(a, "*", ID_MATCH_ANY));
                    748:        ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
                    749:        ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
                    750:        a->destroy(a);
                    751: }
                    752: END_TEST
                    753: 
                    754: START_TEST(test_matches_binary)
                    755: {
                    756:        identification_t *a;
                    757: 
                    758:        /* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
                    759:        a = identification_create_from_string("foo=bar");
                    760:        ck_assert(a->get_type(a) == ID_KEY_ID);
                    761:        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    762:        ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
                    763:        ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
                    764:        ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
                    765:        ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
                    766:        ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
                    767:        a->destroy(a);
                    768: }
                    769: END_TEST
                    770: 
                    771: START_TEST(test_matches_range)
                    772: {
                    773:        identification_t *a, *b;
                    774: 
                    775:        /* IPv4 addresses */
                    776:        a = identification_create_from_string("192.168.1.1");
                    777:        ck_assert(a->get_type(a) == ID_IPV4_ADDR);
                    778:        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    779:        ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_MAX_WILDCARDS));
                    780:        ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_PERFECT));
                    781:        ck_assert(id_matches(a, "192.168.1.2", ID_MATCH_NONE));
                    782:        ck_assert(id_matches(a, "192.168.1.1/32", ID_MATCH_PERFECT));
                    783:        ck_assert(id_matches(a, "192.168.1.0/32", ID_MATCH_NONE));
                    784:        ck_assert(id_matches(a, "192.168.1.0/24", ID_MATCH_ONE_WILDCARD));
                    785:        ck_assert(id_matches(a, "192.168.0.0/24", ID_MATCH_NONE));
                    786:        ck_assert(id_matches(a, "192.168.1.1-192.168.1.1", ID_MATCH_PERFECT));
                    787:        ck_assert(id_matches(a, "192.168.1.0-192.168.1.64", ID_MATCH_ONE_WILDCARD));
                    788:        ck_assert(id_matches(a, "192.168.1.2-192.168.1.64", ID_MATCH_NONE));
                    789:        ck_assert(id_matches(a, "192.168.0.240-192.168.1.0", ID_MATCH_NONE));
                    790:        ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
                    791: 
                    792:        /* Malformed IPv4 subnet and range encoding */
                    793:        b = identification_create_from_encoding(ID_IPV4_ADDR_SUBNET, chunk_empty);
                    794:        ck_assert(a->matches(a, b) == ID_MATCH_NONE);
                    795:        b->destroy(b);
                    796:        b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE, chunk_empty);
                    797:        ck_assert(a->matches(a, b) == ID_MATCH_NONE);
                    798:        b->destroy(b);
                    799:        b = identification_create_from_encoding(ID_IPV4_ADDR_RANGE,
                    800:                        chunk_from_chars(0xc0,0xa8,0x01,0x28,0xc0,0xa8,0x01,0x00));
                    801:        ck_assert(a->matches(a, b) == ID_MATCH_NONE);
                    802:        b->destroy(b);
                    803: 
                    804:        a->destroy(a);
                    805: 
                    806:        /* IPv6 addresses */
                    807:        a = identification_create_from_string("fec0::1");
                    808:        ck_assert(a->get_type(a) == ID_IPV6_ADDR);
                    809:        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    810:        ck_assert(id_matches(a, "::/0", ID_MATCH_MAX_WILDCARDS));
                    811:        ck_assert(id_matches(a, "fec0::1", ID_MATCH_PERFECT));
                    812:        ck_assert(id_matches(a, "fec0::2", ID_MATCH_NONE));
                    813:        ck_assert(id_matches(a, "fec0::1/128", ID_MATCH_PERFECT));
                    814:        ck_assert(id_matches(a, "fec0::/128", ID_MATCH_NONE));
                    815:        ck_assert(id_matches(a, "fec0::/120", ID_MATCH_ONE_WILDCARD));
                    816:        ck_assert(id_matches(a, "fec0::100/120", ID_MATCH_NONE));
                    817:        ck_assert(id_matches(a, "fec0::1-fec0::1", ID_MATCH_PERFECT));
                    818:        ck_assert(id_matches(a, "fec0::0-fec0::5", ID_MATCH_ONE_WILDCARD));
                    819:        ck_assert(id_matches(a, "fec0::4001-fec0::4ffe", ID_MATCH_NONE));
                    820:        ck_assert(id_matches(a, "feb0::1-fec0::0", ID_MATCH_NONE));
                    821:        ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
                    822: 
                    823:        /* Malformed IPv6 subnet and range encoding */
                    824:        b = identification_create_from_encoding(ID_IPV6_ADDR_SUBNET, chunk_empty);
                    825:        ck_assert(a->matches(a, b) == ID_MATCH_NONE);
                    826:        b->destroy(b);
                    827:        b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE, chunk_empty);
                    828:        ck_assert(a->matches(a, b) == ID_MATCH_NONE);
                    829:        b->destroy(b);
                    830:        b = identification_create_from_encoding(ID_IPV6_ADDR_RANGE,
                    831:                        chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    832:                                                         0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0xff,
                    833:                                                         0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
                    834:                                                         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 ));
                    835:        ck_assert(a->matches(a, b) == ID_MATCH_NONE);
                    836:        b->destroy(b);
                    837: 
                    838:        a->destroy(a);
                    839: 
                    840:        /* Malformed IPv4 address encoding */
                    841:        a = identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty);
                    842:        ck_assert(id_matches(a, "0.0.0.0/0", ID_MATCH_NONE));
                    843:        ck_assert(id_matches(a, "0.0.0.0-255.255.255.255", ID_MATCH_NONE));
                    844:        a->destroy(a);
                    845: 
                    846:        /* Malformed IPv6 address encoding */
                    847:        a = identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty);
                    848:        ck_assert(id_matches(a, "::/0", ID_MATCH_NONE));
                    849:        ck_assert(id_matches(a, "::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", ID_MATCH_NONE));
                    850:        a->destroy(a);
                    851: }
                    852: END_TEST
                    853: 
                    854: START_TEST(test_matches_string)
                    855: {
                    856:        identification_t *a;
                    857: 
                    858:        a = identification_create_from_string("moon@strongswan.org");
                    859: 
                    860:        ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_PERFECT));
                    861:        ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
                    862:        ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
                    863:        ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
                    864:        /* the following two are parsed as ID_FQDN, so no match */
                    865:        ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
                    866:        ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
                    867:        ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
                    868:        ck_assert(id_matches(a, "**", ID_MATCH_NONE));
                    869:        ck_assert(id_matches(a, "*", ID_MATCH_ANY));
                    870:        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    871:        a->destroy(a);
                    872: 
                    873:        a = identification_create_from_string("vpn.strongswan.org");
                    874: 
                    875:        ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
                    876:        ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
                    877:        ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
                    878:        ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
                    879:        ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
                    880:        ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
                    881:        ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
                    882:        ck_assert(id_matches(a, "**", ID_MATCH_NONE));
                    883:        ck_assert(id_matches(a, "*", ID_MATCH_ANY));
                    884:        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    885:        a->destroy(a);
                    886: }
                    887: END_TEST
                    888: 
                    889: START_TEST(test_matches_empty)
                    890: {
                    891:        identification_t *a;
                    892: 
                    893:        a = identification_create_from_encoding(_i, chunk_empty);
                    894: 
                    895:        switch (_i)
                    896:        {
                    897:                case ID_ANY:
                    898:                        ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
                    899:                        break;
                    900:                case ID_IPV4_ADDR:
                    901:                        ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
                    902:                        break;
                    903:                case ID_FQDN:
                    904:                        ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
                    905:                        break;
                    906:                case ID_USER_FQDN:
                    907:                        ck_assert(id_matches(a, "moon@strongswan.org", ID_MATCH_NONE));
                    908:                        break;
                    909:                case ID_IPV6_ADDR:
                    910:                        ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
                    911:                        break;
                    912:                case ID_DER_ASN1_DN:
                    913:                        ck_assert(id_matches(a, "C=CH, E=moon@strongswan.org, CN=moon",
                    914:                                                                 ID_MATCH_NONE));
                    915:                        break;
                    916:                case ID_KEY_ID:
                    917:                        ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
                    918:                        break;
                    919:                case ID_DER_ASN1_GN:
                    920:                case ID_IPV4_ADDR_SUBNET:
                    921:                case ID_IPV6_ADDR_SUBNET:
                    922:                case ID_IPV4_ADDR_RANGE:
                    923:                case ID_IPV6_ADDR_RANGE:
                    924:                        /* currently not tested */
                    925:                        break;
                    926:        }
                    927: 
                    928:        a->destroy(a);
                    929: }
                    930: END_TEST
                    931: 
                    932: static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
                    933: {
                    934:        identification_t *b;
                    935:        id_match_t match;
                    936: 
                    937:        b = identification_create_from_string(b_str);
                    938:        match = b->matches(b, a);
                    939:        b->destroy(b);
                    940:        return match == expected;
                    941: }
                    942: 
                    943: START_TEST(test_matches_empty_reverse)
                    944: {
                    945:        identification_t *a;
                    946: 
                    947:        a = identification_create_from_encoding(_i, chunk_empty);
                    948: 
                    949:        switch (_i)
                    950:        {
                    951:                case ID_ANY:
                    952:                        ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
                    953:                        break;
                    954:                case ID_IPV4_ADDR:
                    955:                        ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
                    956:                        break;
                    957:                case ID_FQDN:
                    958:                        ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
                    959:                        break;
                    960:                case ID_USER_FQDN:
                    961:                        ck_assert(id_matches_rev(a, "moon@strongswan.org", ID_MATCH_NONE));
                    962:                        break;
                    963:                case ID_IPV6_ADDR:
                    964:                        ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
                    965:                        break;
                    966:                case ID_DER_ASN1_DN:
                    967:                        ck_assert(id_matches_rev(a, "C=CH, E=moon@strongswan.org, CN=moon",
                    968:                                                                         ID_MATCH_NONE));
                    969:                        break;
                    970:                case ID_KEY_ID:
                    971:                        ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
                    972:                        break;
                    973:                case ID_DER_ASN1_GN:
                    974:                case ID_IPV4_ADDR_SUBNET:
                    975:                case ID_IPV6_ADDR_SUBNET:
                    976:                case ID_IPV4_ADDR_RANGE:
                    977:                case ID_IPV6_ADDR_RANGE:
                    978:                        /* currently not tested */
                    979:                        break;
                    980:        }
                    981: 
                    982:        a->destroy(a);
                    983: }
                    984: END_TEST
                    985: 
                    986: /*******************************************************************************
                    987:  * identification hashing
                    988:  */
                    989: 
                    990: static bool id_hash_equals(char *str, char *b_str)
                    991: {
                    992:        identification_t *a, *b;
                    993:        bool success = FALSE;
                    994: 
                    995:        a = identification_create_from_string(str);
                    996:        b = identification_create_from_string(b_str ?: str);
                    997:        success = a->hash(a, 0) == b->hash(b, 0);
                    998:        a->destroy(a);
                    999:        b->destroy(b);
                   1000:        return success;
                   1001: }
                   1002: 
                   1003: START_TEST(test_hash)
                   1004: {
                   1005:        ck_assert(id_hash_equals("moon@strongswan.org", NULL));
                   1006:        ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
                   1007:        ck_assert(id_hash_equals("192.168.1.1", NULL));
                   1008:        ck_assert(id_hash_equals("C=CH", NULL));
                   1009: 
                   1010:        ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
                   1011:        ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
                   1012:        ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
                   1013:        ck_assert(!id_hash_equals("C=CH", "C=DE"));
                   1014:        ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
                   1015: }
                   1016: END_TEST
                   1017: 
                   1018: START_TEST(test_hash_any)
                   1019: {
                   1020:        ck_assert(id_hash_equals("%any", NULL));
                   1021:        ck_assert(id_hash_equals("%any", "0.0.0.0"));
                   1022:        ck_assert(id_hash_equals("%any", "*"));
                   1023:        ck_assert(id_hash_equals("%any", ""));
                   1024: 
                   1025:        ck_assert(!id_hash_equals("%any", "any"));
                   1026: }
                   1027: END_TEST
                   1028: 
                   1029: START_TEST(test_hash_dn)
                   1030: {
                   1031:        identification_t *a, *b;
                   1032: 
                   1033:        /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
                   1034:         * UTF8STRING) */
                   1035:        a = identification_create_from_data(chunk_from_chars(
                   1036:                        0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
                   1037:                        0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
                   1038:                        0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
                   1039:                        0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
                   1040:                        0x53, 0x77, 0x61, 0x6e));
                   1041:        b = identification_create_from_data(chunk_from_chars(
                   1042:                        0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
                   1043:                        0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
                   1044:                        0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
                   1045:                        0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
                   1046:                        0x53, 0x77, 0x61, 0x6e));
                   1047:        ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
                   1048:        ck_assert(a->equals(a, b));
                   1049:        a->destroy(a);
                   1050:        b->destroy(b);
                   1051: }
                   1052: END_TEST
                   1053: 
                   1054: START_TEST(test_hash_inc)
                   1055: {
                   1056:        identification_t *a;
                   1057: 
                   1058:        a = identification_create_from_string("vpn.strongswan.org");
                   1059:        ck_assert(a->hash(a, 0) != a->hash(a, 1));
                   1060:        a->destroy(a);
                   1061: 
                   1062:        a = identification_create_from_string("C=CH, O=strongSwan");
                   1063:        ck_assert(a->hash(a, 0) != a->hash(a, 1));
                   1064:        a->destroy(a);
                   1065: }
                   1066: END_TEST
                   1067: 
                   1068: /*******************************************************************************
                   1069:  * identification part enumeration
                   1070:  */
                   1071: 
                   1072: START_TEST(test_parts)
                   1073: {
                   1074:        identification_t *id;
                   1075:        enumerator_t *enumerator;
                   1076:        id_part_t part;
                   1077:        chunk_t data;
                   1078:        int i = 0;
                   1079: 
                   1080:        id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
                   1081: 
                   1082:        enumerator = id->create_part_enumerator(id);
                   1083:        while (enumerator->enumerate(enumerator, &part, &data))
                   1084:        {
                   1085:                switch (i++)
                   1086:                {
                   1087:                        case 0:
                   1088:                                ck_assert(part == ID_PART_RDN_C &&
                   1089:                                                  chunk_equals(data, chunk_create("CH", 2)));
                   1090:                                break;
                   1091:                        case 1:
                   1092:                                ck_assert(part == ID_PART_RDN_O &&
                   1093:                                                  chunk_equals(data, chunk_from_str("strongSwan")));
                   1094:                                break;
                   1095:                        case 2:
                   1096:                                ck_assert(part == ID_PART_RDN_CN &&
                   1097:                                                  chunk_equals(data, chunk_from_str("tester")));
                   1098:                                break;
                   1099:                        default:
                   1100:                                fail("unexpected identification part %d", part);
                   1101:                }
                   1102:        }
                   1103:        ck_assert_int_eq(i, 3);
                   1104:        enumerator->destroy(enumerator);
                   1105:        id->destroy(id);
                   1106: }
                   1107: END_TEST
                   1108: 
                   1109: /*******************************************************************************
                   1110:  * wildcards
                   1111:  */
                   1112: 
                   1113: static bool id_contains_wildcards(char *string)
                   1114: {
                   1115:        identification_t *id;
                   1116:        bool contains;
                   1117: 
                   1118:        id = identification_create_from_string(string);
                   1119:        contains = id->contains_wildcards(id);
                   1120:        id->destroy(id);
                   1121:        return contains;
                   1122: }
                   1123: 
                   1124: START_TEST(test_contains_wildcards)
                   1125: {
                   1126:        ck_assert(id_contains_wildcards("%any"));
                   1127:        ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
                   1128:        ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
                   1129:        ck_assert(id_contains_wildcards("*@strongswan.org"));
                   1130:        ck_assert(id_contains_wildcards("*.strongswan.org"));
                   1131:        ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
                   1132: }
                   1133: END_TEST
                   1134: 
                   1135: /*******************************************************************************
                   1136:  * clone
                   1137:  */
                   1138: 
                   1139: START_TEST(test_clone)
                   1140: {
                   1141:        identification_t *a, *b;
                   1142:        chunk_t a_enc, b_enc;
                   1143: 
                   1144:        a = identification_create_from_string("moon@strongswan.org");
                   1145:        a_enc = a->get_encoding(a);
                   1146:        b = a->clone(a);
                   1147:        ck_assert(b != NULL);
                   1148:        ck_assert(a != b);
                   1149:        b_enc = b->get_encoding(b);
                   1150:        ck_assert(a_enc.ptr != b_enc.ptr);
                   1151:        ck_assert(chunk_equals(a_enc, b_enc));
                   1152:        a->destroy(a);
                   1153:        b->destroy(b);
                   1154: }
                   1155: END_TEST
                   1156: 
                   1157: Suite *identification_suite_create()
                   1158: {
                   1159:        Suite *s;
                   1160:        TCase *tc;
                   1161: 
                   1162:        s = suite_create("identification");
                   1163: 
                   1164:        tc = tcase_create("create");
                   1165:        tcase_add_test(tc, test_from_encoding);
                   1166:        tcase_add_test(tc, test_from_data);
                   1167:        tcase_add_test(tc, test_from_sockaddr);
                   1168:        tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
                   1169:        suite_add_tcase(s, tc);
                   1170: 
                   1171:        tc = tcase_create("printf_hook");
                   1172:        tcase_add_test(tc, test_printf_hook);
                   1173:        tcase_add_test(tc, test_printf_hook_width);
                   1174:        suite_add_tcase(s, tc);
                   1175: 
                   1176:        tc = tcase_create("equals");
                   1177:        tcase_add_test(tc, test_equals);
                   1178:        tcase_add_test(tc, test_equals_any);
                   1179:        tcase_add_test(tc, test_equals_binary);
                   1180:        tcase_add_test(tc, test_equals_fqdn);
                   1181:        tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
                   1182:        suite_add_tcase(s, tc);
                   1183: 
                   1184:        tc = tcase_create("matches");
                   1185:        tcase_add_loop_test(tc, test_matches, 0, countof(rdn_matching));
                   1186:        tcase_add_loop_test(tc, test_matches_two_ou, 0, countof(rdn_matching));
                   1187:        tcase_add_test(tc, test_matches_any);
                   1188:        tcase_add_test(tc, test_matches_binary);
                   1189:        tcase_add_test(tc, test_matches_range);
                   1190:        tcase_add_test(tc, test_matches_string);
                   1191:        tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
                   1192:        tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
                   1193:        suite_add_tcase(s, tc);
                   1194: 
                   1195:        tc = tcase_create("hash");
                   1196:        tcase_add_test(tc, test_hash);
                   1197:        tcase_add_test(tc, test_hash_any);
                   1198:        tcase_add_test(tc, test_hash_dn);
                   1199:        tcase_add_test(tc, test_hash_inc);
                   1200:        suite_add_tcase(s, tc);
                   1201: 
                   1202:        tc = tcase_create("part enumeration");
                   1203:        tcase_add_test(tc, test_parts);
                   1204:        suite_add_tcase(s, tc);
                   1205: 
                   1206:        tc = tcase_create("wildcards");
                   1207:        tcase_add_test(tc, test_contains_wildcards);
                   1208:        suite_add_tcase(s, tc);
                   1209: 
                   1210:        tc = tcase_create("clone");
                   1211:        tcase_add_test(tc, test_clone);
                   1212:        suite_add_tcase(s, tc);
                   1213: 
                   1214:        return s;
                   1215: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>