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

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

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