diff options
author | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2015-07-20 23:52:30 +0000 |
---|---|---|
committer | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2015-07-20 23:52:30 +0000 |
commit | 00320dad4cc1a77d9b0f33fc801d3928e0076dac (patch) | |
tree | 0905f9b1b01ceaa64a6f11f7e63a98aff976f802 /regress/lib | |
parent | 484a61a40f69196a63b292c3c497a1d536571ef7 (diff) |
Add radius(3) library. This will be used by RADIUS server and client
programs to manipulate RADIUS packets. Mainly written by UMEZAWA
Takeshi.
fix and suggestion deraadt
ok deraadt
Diffstat (limited to 'regress/lib')
-rw-r--r-- | regress/lib/libradius/Makefile | 22 | ||||
-rw-r--r-- | regress/lib/libradius/incs.h | 28 | ||||
-rw-r--r-- | regress/lib/libradius/main.c | 45 | ||||
-rw-r--r-- | regress/lib/libradius/test00.c | 32 | ||||
-rw-r--r-- | regress/lib/libradius/test01.c | 97 | ||||
-rw-r--r-- | regress/lib/libradius/test02.c | 56 | ||||
-rw-r--r-- | regress/lib/libradius/test03.c | 45 | ||||
-rw-r--r-- | regress/lib/libradius/test04.c | 77 | ||||
-rw-r--r-- | regress/lib/libradius/test05.c | 23 | ||||
-rw-r--r-- | regress/lib/libradius/test06.c | 22 | ||||
-rw-r--r-- | regress/lib/libradius/test10.c | 42 | ||||
-rw-r--r-- | regress/lib/libradius/test11.c | 38 | ||||
-rw-r--r-- | regress/lib/libradius/test20.c | 51 | ||||
-rw-r--r-- | regress/lib/libradius/test21.c | 79 | ||||
-rw-r--r-- | regress/lib/libradius/test22.c | 75 | ||||
-rw-r--r-- | regress/lib/libradius/test23.c | 70 | ||||
-rw-r--r-- | regress/lib/libradius/test24.c | 50 | ||||
-rw-r--r-- | regress/lib/libradius/test25.c | 84 |
18 files changed, 936 insertions, 0 deletions
diff --git a/regress/lib/libradius/Makefile b/regress/lib/libradius/Makefile new file mode 100644 index 00000000000..60dde7b1e11 --- /dev/null +++ b/regress/lib/libradius/Makefile @@ -0,0 +1,22 @@ +# $OpenBSD: Makefile,v 1.1 2015/07/20 23:52:29 yasuoka Exp $ + +PROG= radius_test +REGRESS_TARGETS= run-radius_test + +SRCS= main.c +SRCS+= test00.c test01.c test02.c test03.c test04.c test05.c test06.c +SRCS+= test10.c test11.c +SRCS+= test20.c test21.c test22.c test23.c test24.c test25.c + +CFLAGS+= -std=gnu99 -Wall -g -O0 +LDFLAGS+= -g + +DPADD+= ${LIBRADIUS} ${LIBCRYPTO} +LDADD+= -lradius -lcrypto + +NOMAN= #defined + +run-radius_test: radius_test + ./radius_test + +.include <bsd.regress.mk> diff --git a/regress/lib/libradius/incs.h b/regress/lib/libradius/incs.h new file mode 100644 index 00000000000..01a9b9e83bb --- /dev/null +++ b/regress/lib/libradius/incs.h @@ -0,0 +1,28 @@ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <radius.h> + +typedef void (*testfunc)(void); + +void check_failed(const char *expr, const char *file, int line); +void add_test(testfunc fn, const char *name); + +#define CHECK(x) \ + do { if (!(x)) check_failed(#x, __FILE__, __LINE__); } while(0) + +#define ADD_TEST(fn) \ +extern void fn(void); \ +__attribute__((__constructor__)) \ +void fn ## _add(void) \ +{ \ + add_test(fn, #fn); \ +} diff --git a/regress/lib/libradius/main.c b/regress/lib/libradius/main.c new file mode 100644 index 00000000000..3a35ff63e62 --- /dev/null +++ b/regress/lib/libradius/main.c @@ -0,0 +1,45 @@ +#include "incs.h" + +#define TEST_MAX 100 + +struct test_entry { + testfunc func; + const char *name; +} entries[TEST_MAX]; + +int ntests = 0; + +int test_entry_cmp(const void *a, const void *b) +{ + return strcmp( + ((struct test_entry *)a)->name, + ((struct test_entry *)b)->name); +} + +int main(void) +{ + srandom(time(NULL)); + + qsort(entries, ntests, sizeof(struct test_entry), test_entry_cmp); + + for (int i = 0; i < ntests; i++) { + fprintf(stderr, "running test %s\n", entries[i].name); + entries[i].func(); + } + + fprintf(stderr, "tests are successfully completed.\n"); + return 0; +} + +void check_failed(const char *expr, const char *file, int line) +{ + fprintf(stderr, "CHECK FAILED: %s at file %s line %d\n", expr, file, line); + exit(1); +} + +void add_test(testfunc fn, const char *name) +{ + entries[ntests].func = fn; + entries[ntests].name = name; + ntests++; +} diff --git a/regress/lib/libradius/test00.c b/regress/lib/libradius/test00.c new file mode 100644 index 00000000000..69133553da9 --- /dev/null +++ b/regress/lib/libradius/test00.c @@ -0,0 +1,32 @@ +#include "incs.h" + +/* + * basic header operation + */ + +void test00(void) +{ + RADIUS_PACKET *packet; + uint8_t code; + uint8_t id; + const uint8_t *pdata; + uint8_t authenticator[16]; + + code = random(); + id = random(); + packet = radius_new_request_packet(code); + radius_set_id(packet, id); + pdata = (const uint8_t *)radius_get_data(packet); + CHECK(pdata[0] == code); + CHECK(radius_get_code(packet) == code); + CHECK(pdata[1] == id); + CHECK(radius_get_id(packet) == id); + CHECK(((pdata[2] << 8) | pdata[3]) == 20); + CHECK(radius_get_length(packet) == 20); + + CHECK(radius_get_authenticator_retval(packet) == pdata + 4); + radius_get_authenticator(packet, authenticator); + CHECK(memcmp(authenticator, radius_get_authenticator_retval(packet), 16) == 0); +} + +ADD_TEST(test00) diff --git a/regress/lib/libradius/test01.c b/regress/lib/libradius/test01.c new file mode 100644 index 00000000000..1365429dc96 --- /dev/null +++ b/regress/lib/libradius/test01.c @@ -0,0 +1,97 @@ +#include "incs.h" + +/* + * put/get/has attributes + */ + +void test01(void) +{ + RADIUS_PACKET *packet; + uint8_t buf[256]; + size_t len; + const void *ptr; + + static const uint8_t data0[] = { 0xfe, 0xdc, 0xba, 0x98 }; + static const uint8_t data1[] = { 0x76, 0x54, 0x32 }; + static const uint8_t data2[] = { 0x0f, 0x1e, 0x2d, 0x3c }; + static const uint8_t data3[] = { 0x4b, 0x5a, 0x69 }; + static const uint8_t attrs[] = { + 10, 6, 0xfe, 0xdc, 0xba, 0x98, + 20, 5, 0x76, 0x54, 0x32, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 300/256, 300%256, 40, 6, 0x0f, 0x1e, 0x2d, 0x3c, + RADIUS_TYPE_VENDOR_SPECIFIC, 11, 0, 0, 500/256, 500%256, 60, 5, 0x4b, 0x5a, 0x69, + 20, 6, 0x0f, 0x1e, 0x2d, 0x3c, + RADIUS_TYPE_VENDOR_SPECIFIC, 11, 0, 0, 300/256, 300%256, 40, 5, 0x76, 0x54, 0x32, + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + radius_put_raw_attr(packet, 10, data0, sizeof(data0)); + radius_put_raw_attr(packet, 20, data1, sizeof(data1)); + radius_put_vs_raw_attr(packet, 300, 40, data2, sizeof(data2)); + radius_put_vs_raw_attr(packet, 500, 60, data3, sizeof(data3)); + radius_put_raw_attr(packet, 20, data2, sizeof(data2)); + radius_put_vs_raw_attr(packet, 300, 40, data1, sizeof(data1)); + + CHECK(radius_get_length(packet) == sizeof(attrs) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs, sizeof(attrs)) == 0); + + len = sizeof(buf); + CHECK(radius_get_raw_attr(packet, 10, buf, &len) == 0); + CHECK(len == sizeof(data0)); + CHECK(memcmp(buf, data0, len) == 0); + + len = sizeof(buf); + CHECK(radius_get_raw_attr(packet, 20, buf, &len) == 0); + CHECK(len == sizeof(data1)); + CHECK(memcmp(buf, data1, len) == 0); + + len = sizeof(buf); + CHECK(radius_get_vs_raw_attr(packet, 300, 40, buf, &len) == 0); + CHECK(len == sizeof(data2)); + CHECK(memcmp(buf, data2, len) == 0); + + len = sizeof(buf); + CHECK(radius_get_vs_raw_attr(packet, 500, 60, buf, &len) == 0); + CHECK(len == sizeof(data3)); + CHECK(memcmp(buf, data3, len) == 0); + + len = 2; + CHECK(radius_get_raw_attr(packet, 10, buf, &len) == 0); + CHECK(len == 2); + CHECK(memcmp(buf, data0, len) == 0); + + len = 2; + CHECK(radius_get_vs_raw_attr(packet, 300, 40, buf, &len) == 0); + CHECK(len == 2); + CHECK(memcmp(buf, data2, len) == 0); + + len = sizeof(buf); + CHECK(radius_get_raw_attr(packet, 90, buf, &len) != 0); + CHECK(radius_get_vs_raw_attr(packet, 300, 90, buf, &len) != 0); + CHECK(radius_get_vs_raw_attr(packet, 900, 40, buf, &len) != 0); + + len = 0; + CHECK(radius_get_raw_attr_ptr(packet, 10, &ptr, &len) == 0); + CHECK(len == 4); + CHECK(ptr == radius_get_data(packet) + 20 + 0 + 2); + + len = 0; + CHECK(radius_get_vs_raw_attr_ptr(packet, 500, 60, &ptr, &len) == 0); + CHECK(len == 3); + CHECK(ptr == radius_get_data(packet) + 20 + 23 + 8); + + CHECK(radius_get_raw_attr_ptr(packet, 90, &ptr, &len) != 0); + CHECK(radius_get_vs_raw_attr_ptr(packet, 300, 90, &ptr, &len) != 0); + CHECK(radius_get_vs_raw_attr_ptr(packet, 900, 40, &ptr, &len) != 0); + + CHECK(radius_has_attr(packet, 10)); + CHECK(radius_has_attr(packet, 20)); + CHECK(radius_has_vs_attr(packet, 300, 40)); + CHECK(radius_has_vs_attr(packet, 500, 60)); + CHECK(!radius_has_attr(packet, 90)); + CHECK(!radius_has_vs_attr(packet, 300, 90)); + CHECK(!radius_has_vs_attr(packet, 900, 40)); +} + +ADD_TEST(test01) diff --git a/regress/lib/libradius/test02.c b/regress/lib/libradius/test02.c new file mode 100644 index 00000000000..c09276d2c27 --- /dev/null +++ b/regress/lib/libradius/test02.c @@ -0,0 +1,56 @@ +#include "incs.h" + +/* + * set attributes + */ + +void test02(void) +{ + RADIUS_PACKET *packet; + + static const uint8_t data0[] = { 0xfe, 0xdc, 0xba, 0x98 }; + static const uint8_t data1[] = { 0x76, 0x54, 0x32, 0x10 }; + static const uint8_t data2[] = { 0x0f, 0x1e, 0x2d, 0x3c }; + static const uint8_t data3[] = { 0x4b, 0x5a, 0x69, 0x78, 0xff }; + static const uint8_t attrs_beforeset[] = { + 10, 6, 0xfe, 0xdc, 0xba, 0x98, + 10, 6, 0x76, 0x54, 0x32, 0x10, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 20, 30, 6, 0x76, 0x54, 0x32, 0x10, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 20, 30, 6, 0xfe, 0xdc, 0xba, 0x98, + }; + static const uint8_t attrs_afterset[] = { + 10, 6, 0x0f, 0x1e, 0x2d, 0x3c, + 10, 6, 0x76, 0x54, 0x32, 0x10, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 20, 30, 6, 0x0f, 0x1e, 0x2d, 0x3c, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 20, 30, 6, 0xfe, 0xdc, 0xba, 0x98, + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + radius_put_raw_attr(packet, 10, data0, sizeof(data0)); + radius_put_raw_attr(packet, 10, data1, sizeof(data1)); + radius_put_vs_raw_attr(packet, 20, 30, data1, sizeof(data1)); + radius_put_vs_raw_attr(packet, 20, 30, data0, sizeof(data0)); + + CHECK(radius_get_length(packet) == sizeof(attrs_beforeset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_beforeset, sizeof(attrs_beforeset)) == 0); + + CHECK(radius_set_raw_attr(packet, 10, data2, sizeof(data2)) == 0); + CHECK(radius_set_vs_raw_attr(packet, 20, 30, data2, sizeof(data2)) == 0); + + CHECK(radius_get_length(packet) == sizeof(attrs_afterset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_afterset, sizeof(attrs_afterset)) == 0); + + CHECK(radius_set_raw_attr(packet, 10, data3, sizeof(data2) - 1) != 0); + CHECK(radius_set_raw_attr(packet, 10, data3, sizeof(data2) + 1) != 0); + CHECK(radius_set_vs_raw_attr(packet, 20, 30, data3, sizeof(data2) - 1) != 0); + CHECK(radius_set_vs_raw_attr(packet, 20, 30, data3, sizeof(data2) + 1) != 0); + + CHECK(radius_get_length(packet) == sizeof(attrs_afterset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_afterset, sizeof(attrs_afterset)) == 0); + + CHECK(radius_set_raw_attr(packet, 90, data3, sizeof(data3)) != 0); + CHECK(radius_set_vs_raw_attr(packet, 900, 90, data3, sizeof(data3)) != 0); +} + +ADD_TEST(test02) diff --git a/regress/lib/libradius/test03.c b/regress/lib/libradius/test03.c new file mode 100644 index 00000000000..576d2ef825c --- /dev/null +++ b/regress/lib/libradius/test03.c @@ -0,0 +1,45 @@ +#include "incs.h" + +/* + * del attributes + */ + +void test03(void) +{ + RADIUS_PACKET *packet; + + static const uint8_t data0[] = { 0xfe, 0xdc, 0xba, 0x98 }; + static const uint8_t data1[] = { 0x76, 0x54, 0x32, 0x10 }; + static const uint8_t data2[] = { 0x0f, 0x1e, 0x2d, 0x3c }; + static const uint8_t data3[] = { 0x4b, 0x5a, 0x69, 0x67 }; + static const uint8_t attrs_afterdel[] = { + 80, 6, 0x0f, 0x1e, 0x2d, 0x3c, + 80, 6, 0x0f, 0x1e, 0x2d, 0x3c, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 70, 60, 6, 0x0f, 0x1e, 0x2d, 0x3c, + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + radius_put_raw_attr(packet, 10, data0, sizeof(data0)); + radius_put_raw_attr(packet, 80, data2, sizeof(data2)); + radius_put_raw_attr(packet, 10, data1, sizeof(data1)); + radius_put_raw_attr(packet, 80, data2, sizeof(data2)); + radius_put_vs_raw_attr(packet, 20, 30, data1, sizeof(data1)); + radius_put_vs_raw_attr(packet, 20, 30, data0, sizeof(data0)); + radius_put_vs_raw_attr(packet, 70, 60, data2, sizeof(data2)); + radius_put_vs_raw_attr(packet, 20, 30, data3, sizeof(data3)); + + CHECK(radius_del_attr_all(packet, 10) == 0); + CHECK(radius_del_vs_attr_all(packet, 20, 30) == 0); + + CHECK(radius_get_length(packet) == sizeof(attrs_afterdel) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_afterdel, sizeof(attrs_afterdel)) == 0); + + CHECK(radius_del_attr_all(packet, 90) == 0); + CHECK(radius_del_vs_attr_all(packet, 90, 90) == 0); + + CHECK(radius_get_length(packet) == sizeof(attrs_afterdel) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_afterdel, sizeof(attrs_afterdel)) == 0); +} + +ADD_TEST(test03) diff --git a/regress/lib/libradius/test04.c b/regress/lib/libradius/test04.c new file mode 100644 index 00000000000..d868a226404 --- /dev/null +++ b/regress/lib/libradius/test04.c @@ -0,0 +1,77 @@ +#include "incs.h" + +/* + * put/get cat attributes + */ + +void test04(void) +{ + RADIUS_PACKET *packet; + uint8_t buf[1024]; + size_t len; + uint8_t *p; + +#define ATTRLEN (256 + 256 + 103) + uint8_t data0[ATTRLEN]; + uint8_t data1[ATTRLEN]; + uint8_t data2[] = { 0x10, 0x20, 0x30, 0x40 }; + uint8_t data3[] = { 0x10, 0x20, 0x30, 0x40, 0x10, 0x20, 0x30, 0x40 }; + uint8_t attrs[2048]; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + for (int i = 0; i < ATTRLEN; i++) + data0[i] = random(); + for (int i = 0; i < ATTRLEN; i++) + data1[i] = random(); + + p = attrs; + *p++ = 20; *p++ = 6; + memcpy(p, data2, 4); p += 4; + + *p++ = 10; *p++ = 255; + memcpy(p, data0, 253); p += 253; + *p++ = 10; *p++ = 255; + memcpy(p, data0 + 253, 253); p += 253; + *p++ = 10; *p++ = ATTRLEN-253*2+2; + memcpy(p, data0 + 253*2, ATTRLEN-253*2); p += ATTRLEN-253*2; + + *p++ = RADIUS_TYPE_VENDOR_SPECIFIC; *p++ = 255; + *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 20; *p++ = 30; *p++ = 249; + memcpy(p, data1, 247); p += 247; + *p++ = RADIUS_TYPE_VENDOR_SPECIFIC; *p++ = 255; + *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 20; *p++ = 30; *p++ = 249; + memcpy(p, data1 + 247, 247); p += 247; + *p++ = RADIUS_TYPE_VENDOR_SPECIFIC; *p++ = ATTRLEN-247*2+8; + *p++ = 0; *p++ = 0; *p++ = 0; *p++ = 20; *p++ = 30; *p++ = ATTRLEN-247*2+2; + memcpy(p, data1 + 247*2, ATTRLEN-247*2); p += ATTRLEN-247*2; + + *p++ = 20; *p++ = 6; + memcpy(p, data2, 4); p += 4; + + + radius_put_raw_attr(packet, 20, data2, sizeof(data2)); + radius_put_raw_attr_cat(packet, 10, data0, ATTRLEN); + radius_put_vs_raw_attr_cat(packet, 20, 30, data1, ATTRLEN); + radius_put_raw_attr(packet, 20, data2, sizeof(data2)); + + CHECK(radius_get_length(packet) == 20 + (p-attrs)); + CHECK(memcmp(radius_get_data(packet) + 20, attrs, p-attrs) == 0); + + len = sizeof(buf); + CHECK(radius_get_raw_attr_cat(packet, 10, buf, &len) == 0); + CHECK(len == ATTRLEN); + CHECK(memcmp(buf, data0, len) == 0); + + len = sizeof(buf); + CHECK(radius_get_vs_raw_attr_cat(packet, 20, 30, buf, &len) == 0); + CHECK(len == ATTRLEN); + CHECK(memcmp(buf, data1, len) == 0); + + len = sizeof(buf); + CHECK(radius_get_raw_attr_cat(packet, 20,buf, &len) == 0); + CHECK(len == sizeof(data3)); + CHECK(memcmp(buf, data3, len) == 0); +} + +ADD_TEST(test04) diff --git a/regress/lib/libradius/test05.c b/regress/lib/libradius/test05.c new file mode 100644 index 00000000000..b5e9173af6d --- /dev/null +++ b/regress/lib/libradius/test05.c @@ -0,0 +1,23 @@ +#include "incs.h" + +/* + * request/response association + */ + +void test05(void) +{ + RADIUS_PACKET *req0, *req1, *resp; + + req0 = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + req1 = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + CHECK(radius_get_request_packet(req0) == NULL); + CHECK(radius_get_request_packet(req1) == NULL); + + resp = radius_new_response_packet(RADIUS_CODE_ACCESS_ACCEPT, req0); + CHECK(radius_get_request_packet(resp) == req0); + + radius_set_request_packet(resp, req1); + CHECK(radius_get_request_packet(resp) == req1); +} + +ADD_TEST(test05) diff --git a/regress/lib/libradius/test06.c b/regress/lib/libradius/test06.c new file mode 100644 index 00000000000..e947e8c0ce6 --- /dev/null +++ b/regress/lib/libradius/test06.c @@ -0,0 +1,22 @@ +#include "incs.h" + +/* + * + */ + +void test06(void) +{ + RADIUS_PACKET *pkt; + u_char data[] = { + RADIUS_CODE_ACCESS_ACCEPT, 0x01, 0, 20, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + }; + pkt = radius_convert_packet(data, sizeof(data)); + CHECK(pkt != NULL); + CHECK(!radius_has_attr(pkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR)); + CHECK(!radius_put_uint32_attr(pkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR, 1)); + //CHECK(memcmp(radius_get_data(pkt), data, sizeof(data)) == 0); + radius_delete_packet(pkt); +} + +ADD_TEST(test06) diff --git a/regress/lib/libradius/test10.c b/regress/lib/libradius/test10.c new file mode 100644 index 00000000000..34727d93288 --- /dev/null +++ b/regress/lib/libradius/test10.c @@ -0,0 +1,42 @@ +#include "incs.h" + +#include <openssl/md5.h> + +/* + * response authenticator + */ + +void test10(void) +{ + RADIUS_PACKET *request; + RADIUS_PACKET *response; + MD5_CTX ctx; + + uint8_t responsedata[] = { + RADIUS_CODE_ACCESS_ACCEPT, 0x7f, 0, 31, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* auth */ + 10, 11, 'f', 'o', 'o', 'b', 'a', 'r', 'b', 'a', 'z', + }; + + request = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + radius_set_id(request, 0x7f); + response = radius_new_response_packet(RADIUS_CODE_ACCESS_ACCEPT, request); + radius_put_string_attr(response, 10, "foobarbaz"); + radius_set_response_authenticator(response, "sharedsecret"); + + MD5_Init(&ctx); + MD5_Update(&ctx, responsedata, 4); + MD5_Update(&ctx, radius_get_authenticator_retval(request), 16); + MD5_Update(&ctx, responsedata + 20, sizeof(responsedata) - 20); + MD5_Update(&ctx, "sharedsecret", 12); + MD5_Final(responsedata + 4, &ctx); + + CHECK(radius_get_length(response) == sizeof(responsedata)); + CHECK(memcmp(radius_get_data(response), responsedata, sizeof(responsedata)) == 0); + CHECK(radius_check_response_authenticator(response, "sharedsecret") == 0); + + radius_set_raw_attr(response, 10, "zapzapzap", 9); + CHECK(radius_check_response_authenticator(response, "sharedsecret") != 0); +} + +ADD_TEST(test10) diff --git a/regress/lib/libradius/test11.c b/regress/lib/libradius/test11.c new file mode 100644 index 00000000000..0317a696363 --- /dev/null +++ b/regress/lib/libradius/test11.c @@ -0,0 +1,38 @@ +#include "incs.h" + +#include <openssl/md5.h> + +/* + * accounting request authenticator + */ + +void test11(void) +{ + RADIUS_PACKET *packet; + MD5_CTX ctx; + + uint8_t packetdata[] = { + RADIUS_CODE_ACCOUNTING_REQUEST, 0x7f, 0, 31, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* auth */ + 10, 11, 'f', 'o', 'o', 'b', 'a', 'r', 'b', 'a', 'z', + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCOUNTING_REQUEST); + radius_set_id(packet, 0x7f); + radius_put_string_attr(packet, 10, "foobarbaz"); + radius_set_accounting_request_authenticator(packet, "sharedsecret"); + + MD5_Init(&ctx); + MD5_Update(&ctx, packetdata, sizeof(packetdata)); + MD5_Update(&ctx, "sharedsecret", 12); + MD5_Final(packetdata + 4, &ctx); + + CHECK(radius_get_length(packet) == sizeof(packetdata)); + CHECK(memcmp(radius_get_data(packet), packetdata, sizeof(packetdata)) == 0); + CHECK(radius_check_accounting_request_authenticator(packet, "sharedsecret") == 0); + + radius_set_raw_attr(packet, 10, "zapzapzap", 9); + CHECK(radius_check_accounting_request_authenticator(packet, "sharedsecret") != 0); +} + +ADD_TEST(test11) diff --git a/regress/lib/libradius/test20.c b/regress/lib/libradius/test20.c new file mode 100644 index 00000000000..592a9d1e1a3 --- /dev/null +++ b/regress/lib/libradius/test20.c @@ -0,0 +1,51 @@ +#include "incs.h" + +/* + * string attributes + */ + +void test20(void) +{ + RADIUS_PACKET *packet; + char buf[256]; + + static const uint8_t attrs[] = { + 10, 12, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', + RADIUS_TYPE_VENDOR_SPECIFIC, 17, 0, 0, 0, 20, 30, 11, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', + 40, 7, 'z', 'x', 'c', 'v', 0, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 50, 60, 6, 'b', 'n', 0, 'm', + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + radius_put_string_attr(packet, 10, "qwertyuiop"); + radius_put_vs_string_attr(packet, 20, 30, "asdfghjkl"); + radius_put_raw_attr(packet, 40, "zxcv\0", 5); + radius_put_vs_raw_attr(packet, 50, 60, "bn\0m", 4); + + CHECK(radius_get_length(packet) == sizeof(attrs) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs, sizeof(attrs)) == 0); + + CHECK(radius_get_string_attr(packet, 10, buf, sizeof(buf)) == 0); + CHECK(strcmp(buf, "qwertyuiop") == 0); + + CHECK(radius_get_vs_string_attr(packet, 20, 30, buf, sizeof(buf)) == 0); + CHECK(strcmp(buf, "asdfghjkl") == 0); + + CHECK(radius_get_string_attr(packet, 40, buf, sizeof(buf)) != 0); + CHECK(radius_get_vs_string_attr(packet, 50, 60, buf, sizeof(buf)) != 0); + + CHECK(radius_get_string_attr(packet, 10, buf, 4) == 0); + CHECK(strcmp(buf, "qwe") == 0); + + CHECK(radius_get_vs_string_attr(packet, 20, 30, buf, 5) == 0); + CHECK(strcmp(buf, "asdf") == 0); + + CHECK(radius_get_string_attr(packet, 10, buf, 0) == 0); + CHECK(buf[0] != 0); + + CHECK(radius_get_vs_string_attr(packet, 20, 30, buf, 0) == 0); + CHECK(buf[0] != 0); +} + +ADD_TEST(test20) diff --git a/regress/lib/libradius/test21.c b/regress/lib/libradius/test21.c new file mode 100644 index 00000000000..10b7e2f5fc9 --- /dev/null +++ b/regress/lib/libradius/test21.c @@ -0,0 +1,79 @@ +#include "incs.h" + +/* + * integer (uint16_t, uint32_t, uint64_t) attributes + */ + +void test21(void) +{ + RADIUS_PACKET *packet; + uint16_t v16; + uint32_t v32; + uint64_t v64; + + static const uint8_t attrs_beforeset[] = { + 1, 3, 0, + 10, 4, 0x12, 0x34, + RADIUS_TYPE_VENDOR_SPECIFIC, 10, 0, 0, 0, 20, 30, 4, 0x43, 0x21, + 40, 6, 0x13, 0x57, 0x9b, 0xdf, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 50, 60, 6, 0x24, 0x68, 0xac, 0xe0, + 70, 10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + RADIUS_TYPE_VENDOR_SPECIFIC, 16, 0, 0, 0, 80, 90, 10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + static const uint8_t attrs_afterset[] = { + 1, 3, 0, + 10, 4, 0x43, 0x21, + RADIUS_TYPE_VENDOR_SPECIFIC, 10, 0, 0, 0, 20, 30, 4, 0x12, 0x34, + 40, 6, 0x24, 0x68, 0xac, 0xe0, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 50, 60, 6, 0x13, 0x57, 0x9b, 0xdf, + 70, 10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + RADIUS_TYPE_VENDOR_SPECIFIC, 16, 0, 0, 0, 80, 90, 10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + radius_put_raw_attr(packet, 1, "", 1); /* padding for UNalignment */ + radius_put_uint16_attr(packet, 10, 0x1234); + radius_put_vs_uint16_attr(packet, 20, 30, 0x4321); + radius_put_uint32_attr(packet, 40, 0x13579bdfU); + radius_put_vs_uint32_attr(packet, 50, 60, 0x2468ace0U); + radius_put_uint64_attr(packet, 70, 0x0123456789abcdefULL); + radius_put_vs_uint64_attr(packet, 80, 90, 0xfedcba9876543210ULL); + + CHECK(radius_get_length(packet) == sizeof(attrs_beforeset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_beforeset, sizeof(attrs_beforeset)) == 0); + + CHECK(radius_get_uint16_attr(packet, 10, &v16) == 0); + CHECK(v16 == 0x1234); + CHECK(radius_get_vs_uint16_attr(packet, 20, 30, &v16) == 0); + CHECK(v16 == 0x4321); + + CHECK(radius_get_uint32_attr(packet, 40, &v32) == 0); + CHECK(v32 == 0x13579bdfU); + CHECK(radius_get_vs_uint32_attr(packet, 50, 60, &v32) == 0); + CHECK(v32 == 0x2468ace0U); + + CHECK(radius_get_uint64_attr(packet, 70, &v64) == 0); + CHECK(v64 == 0x0123456789abcdefULL); + CHECK(radius_get_vs_uint64_attr(packet, 80, 90, &v64) == 0); + CHECK(v64 == 0xfedcba9876543210ULL); + + CHECK(radius_set_uint16_attr(packet, 10, 0x4321) == 0); + CHECK(radius_set_vs_uint16_attr(packet, 20, 30, 0x1234) == 0); + CHECK(radius_set_uint32_attr(packet, 40, 0x2468ace0U) == 0); + CHECK(radius_set_vs_uint32_attr(packet, 50, 60, 0x13579bdfU) == 0); + CHECK(radius_set_uint64_attr(packet, 70, 0xfedcba9876543210ULL) == 0); + CHECK(radius_set_vs_uint64_attr(packet, 80, 90, 0x0123456789abcdefULL) == 0); + + CHECK(radius_get_length(packet) == sizeof(attrs_afterset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_afterset, sizeof(attrs_afterset)) == 0); + + CHECK(radius_get_uint16_attr(packet, 40, &v16) != 0); + CHECK(radius_get_vs_uint16_attr(packet, 50, 60, &v16) != 0); + CHECK(radius_get_uint32_attr(packet, 70, &v32) != 0); + CHECK(radius_get_vs_uint32_attr(packet, 80, 90, &v32) != 0); + CHECK(radius_get_uint64_attr(packet, 10, &v64) != 0); + CHECK(radius_get_vs_uint64_attr(packet, 20, 30, &v64) != 0); +} + +ADD_TEST(test21) diff --git a/regress/lib/libradius/test22.c b/regress/lib/libradius/test22.c new file mode 100644 index 00000000000..75f78f78cc0 --- /dev/null +++ b/regress/lib/libradius/test22.c @@ -0,0 +1,75 @@ +#include "incs.h" + +#include <arpa/inet.h> + +/* + * inernet address (struct in_addr, struct in6_addr) attributes + */ + +void test22(void) +{ + RADIUS_PACKET *packet; + struct in_addr in4a; + struct in6_addr in6a, in6b; + + static const uint8_t attrs_beforeset[] = { + 1, 3, 0, + 10, 6, 192, 168, 0, 1, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 20, 30, 6, 10, 20, 30, 40, + 40, 18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + RADIUS_TYPE_VENDOR_SPECIFIC, 24, 0, 0, 0, 50, 60, 18, 0x3f, 0xff, 0x0e, 0xca, 0x86, 0x42, 0xfd, 0xb9, 0x75, 0x31, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, + }; + static const uint8_t attrs_afterset[] = { + 1, 3, 0, + 10, 6, 10, 20, 30, 40, + RADIUS_TYPE_VENDOR_SPECIFIC, 12, 0, 0, 0, 20, 30, 6, 192, 168, 0, 1, + 40, 18, 0x3f, 0xff, 0x0e, 0xca, 0x86, 0x42, 0xfd, 0xb9, 0x75, 0x31, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, + RADIUS_TYPE_VENDOR_SPECIFIC, 24, 0, 0, 0, 50, 60, 18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + radius_put_raw_attr(packet, 1, "", 1); /* padding for UNalignment */ + in4a.s_addr = inet_addr("192.168.0.1"); + radius_put_ipv4_attr(packet, 10, in4a); + in4a.s_addr = inet_addr("10.20.30.40"); + radius_put_vs_ipv4_attr(packet, 20, 30, in4a); + inet_pton(AF_INET6, "2001:0db8:dead:beef:1234:5678:9abc:def0", &in6a); + radius_put_ipv6_attr(packet, 40, &in6a); + inet_pton(AF_INET6, "3fff:0eca:8642:fdb9:7531:fedc:ba98:7654", &in6a); + radius_put_vs_ipv6_attr(packet, 50, 60, &in6a); + + CHECK(radius_get_length(packet) == sizeof(attrs_beforeset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_beforeset, sizeof(attrs_beforeset)) == 0); + + CHECK(radius_get_ipv4_attr(packet, 10, &in4a) == 0); + CHECK(in4a.s_addr == inet_addr("192.168.0.1")); + CHECK(radius_get_vs_ipv4_attr(packet, 20, 30, &in4a) == 0); + CHECK(in4a.s_addr == inet_addr("10.20.30.40")); + + CHECK(radius_get_ipv6_attr(packet, 40, &in6b) == 0); + inet_pton(AF_INET6, "2001:0db8:dead:beef:1234:5678:9abc:def0", &in6a); + CHECK(memcmp(&in6b, &in6a, sizeof(struct in6_addr)) == 0); + CHECK(radius_get_vs_ipv6_attr(packet, 50, 60, &in6b) == 0); + inet_pton(AF_INET6, "3fff:0eca:8642:fdb9:7531:fedc:ba98:7654", &in6a); + CHECK(memcmp(&in6b, &in6a, sizeof(struct in6_addr)) == 0); + + in4a.s_addr = inet_addr("10.20.30.40"); + radius_set_ipv4_attr(packet, 10, in4a); + in4a.s_addr = inet_addr("192.168.0.1"); + radius_set_vs_ipv4_attr(packet, 20, 30, in4a); + inet_pton(AF_INET6, "3fff:0eca:8642:fdb9:7531:fedc:ba98:7654", &in6a); + radius_set_ipv6_attr(packet, 40, &in6a); + inet_pton(AF_INET6, "2001:0db8:dead:beef:1234:5678:9abc:def0", &in6a); + radius_set_vs_ipv6_attr(packet, 50, 60, &in6a); + + CHECK(radius_get_length(packet) == sizeof(attrs_afterset) + 20); + CHECK(memcmp(radius_get_data(packet) + 20, attrs_afterset, sizeof(attrs_afterset)) == 0); + + CHECK(radius_get_ipv4_attr(packet, 40, &in4a) != 0); + CHECK(radius_get_vs_ipv4_attr(packet, 50, 60, &in4a) != 0); + CHECK(radius_get_ipv6_attr(packet, 10, &in6b) != 0); + CHECK(radius_get_vs_ipv6_attr(packet, 20, 30, &in6b) != 0); +} + +ADD_TEST(test22) diff --git a/regress/lib/libradius/test23.c b/regress/lib/libradius/test23.c new file mode 100644 index 00000000000..3085a581237 --- /dev/null +++ b/regress/lib/libradius/test23.c @@ -0,0 +1,70 @@ +#include "incs.h" + +#include <openssl/hmac.h> + +/* + * Message-Authenticator attribute + */ + +void test23(void) +{ + RADIUS_PACKET *packet; + RADIUS_PACKET *response; + HMAC_CTX ctx; + + uint8_t packetdata[] = { + RADIUS_CODE_ACCESS_REQUEST, 0x7f, 0, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* auth */ + 10, 10, 'h', 'o', 'g', 'e', 'f', 'u', 'g', 'a', + RADIUS_TYPE_MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + uint8_t responsedata[] = { + RADIUS_CODE_ACCESS_ACCEPT, 0x7f, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* auth */ + 10, 11, 'f', 'o', 'o', 'b', 'a', 'r', 'b', 'a', 'z', + RADIUS_TYPE_MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + radius_set_id(packet, 0x7f); + radius_put_string_attr(packet, 10, "hogefuga"); + radius_put_message_authenticator(packet, "sharedsecret"); + + radius_get_authenticator(packet, packetdata + 4); + HMAC(EVP_md5(), "sharedsecret", 12, packetdata, sizeof(packetdata), packetdata + sizeof(packetdata) - 16, NULL); + + CHECK(radius_get_length(packet) == sizeof(packetdata)); + CHECK(memcmp(radius_get_data(packet), packetdata, sizeof(packetdata)) == 0); + CHECK(radius_check_message_authenticator(packet, "sharedsecret") == 0); + + response = radius_new_response_packet(RADIUS_CODE_ACCESS_ACCEPT, packet); + radius_put_string_attr(response, 10, "foobarbaz"); + radius_put_message_authenticator(response, "sharedsecret"); + + radius_get_authenticator(response, responsedata + 4); + HMAC_Init(&ctx, "sharedsecret", 12, EVP_md5()); + HMAC_Update(&ctx, responsedata, 4); + HMAC_Update(&ctx, packetdata + 4, 16); + HMAC_Update(&ctx, responsedata + 20, sizeof(responsedata) - 20); + HMAC_Final(&ctx, responsedata + sizeof(responsedata) - 16, NULL); + HMAC_cleanup(&ctx); + + CHECK(radius_get_length(response) == sizeof(responsedata)); + CHECK(memcmp(radius_get_data(response), responsedata, sizeof(responsedata)) == 0); + CHECK(radius_check_message_authenticator(response, "sharedsecret") == 0); + + radius_set_raw_attr(packet, 10, "hogefuge", 8); + CHECK(radius_check_message_authenticator(packet, "sharedsecret") != 0); + radius_set_raw_attr(response, 10, "zapzapzap", 9); + CHECK(radius_check_message_authenticator(response, "sharedsecret") != 0); + + radius_set_raw_attr(packet, 10, "hogefuga", 8); + radius_set_id(packet, 0xff); + radius_set_message_authenticator(packet, "sharedsecret"); + packetdata[1] = 0xff; + memset(packetdata + sizeof(packetdata) - 16, 0, 16); + HMAC(EVP_md5(), "sharedsecret", 12, packetdata, sizeof(packetdata), packetdata + sizeof(packetdata) - 16, NULL); + CHECK(memcmp(radius_get_data(packet), packetdata, sizeof(packetdata)) == 0); +} + +ADD_TEST(test23) diff --git a/regress/lib/libradius/test24.c b/regress/lib/libradius/test24.c new file mode 100644 index 00000000000..c85391b5f9e --- /dev/null +++ b/regress/lib/libradius/test24.c @@ -0,0 +1,50 @@ +#include "incs.h" + +#include <openssl/hmac.h> + +/* + * User-Password attribute + */ + +void test24(void) +{ + uint8_t cipher[256],cipher1[256]; + size_t clen; + char plain[256]; + RADIUS_PACKET *packet; + + uint8_t ra[16] = { + 0xf3, 0xa4, 0x7a, 0x1f, 0x6a, 0x6d, 0x76, 0x71, 0x0b, 0x94, 0x7a, 0xb9, 0x30, 0x41, 0xa0, 0x39, + }; + + uint8_t encryptedpass[16] = { + 0x33, 0x65, 0x75, 0x73, 0x77, 0x82, 0x89, 0xb5, 0x70, 0x88, 0x5e, 0x15, 0x08, 0x48, 0x25, 0xc5, + }; + + clen = sizeof(cipher); + CHECK(radius_encrypt_user_password_attr(cipher, &clen, "challenge", ra, "xyzzy5461") == 0); + CHECK(clen == 16); + CHECK(memcmp(cipher, encryptedpass, 16) == 0); + + CHECK(radius_decrypt_user_password_attr(plain, sizeof(plain), cipher, clen, ra, "xyzzy5461") == 0); + CHECK(strcmp(plain, "challenge") == 0); + + clen = 15; + CHECK(radius_encrypt_user_password_attr(cipher, &clen, "challenge", ra, "xyzzy5461") != 0); + CHECK(radius_decrypt_user_password_attr(plain, 16, cipher, 16, ra, "xyzzy5461") != 0); + CHECK(radius_decrypt_user_password_attr(plain, 256, cipher, 17, ra, "xyzzy5461") != 0); + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + CHECK(radius_put_user_password_attr(packet, "foobarbaz", "sharedsecret") == 0); + clen = sizeof(cipher1); + CHECK(radius_get_raw_attr(packet, RADIUS_TYPE_USER_PASSWORD, cipher1, &clen) == 0); + CHECK(clen == 16); + radius_encrypt_user_password_attr(cipher, &clen, "foobarbaz", radius_get_authenticator_retval(packet), "sharedsecret"); + CHECK(memcmp(cipher1, cipher, 16) == 0); + + CHECK(radius_get_user_password_attr(packet, plain, sizeof(plain), "sharedsecret") == 0); + CHECK(strcmp(plain, "foobarbaz") == 0); +} + +ADD_TEST(test24) diff --git a/regress/lib/libradius/test25.c b/regress/lib/libradius/test25.c new file mode 100644 index 00000000000..0e9a57324b6 --- /dev/null +++ b/regress/lib/libradius/test25.c @@ -0,0 +1,84 @@ +#include "incs.h" + +/* + * MS-MPPE-{Send,Recv}-Key attribute + */ + +void test25(void) +{ + uint8_t ra[] = { + 0x67, 0x8a, 0xe6, 0xed, 0x69, 0x6e, 0x1b, 0xd1, 0x0a, 0xe2, 0xfe, 0xa1, 0x05, 0xd4, 0x6a, 0x56, + }; + uint8_t encrypted[] = { + 0x80, 0x36, + 0xf4, 0xab, 0xbe, 0x21, 0x17, 0xfb, 0x3e, 0x4a, 0x78, 0x74, 0xdc, 0xe9, 0x1c, 0x5b, 0x04, 0x49, + 0x8e, 0xc7, 0x72, 0x0f, 0x16, 0x86, 0x88, 0x56, 0x2d, 0xbc, 0x88, 0xe2, 0x1c, 0xab, 0x62, 0x71, + }; + uint8_t plainkey[] = { + 0xfc, 0x6e, 0xa4, 0x18, 0x37, 0x3d, 0x8e, 0x90, 0xc1, 0x36, 0xfa, 0xe3, 0x73, 0x5e, 0x37, 0xd1, + }; + uint8_t plainkey2[] = { + 0x86, 0xfe, 0x22, 0x0e, 0x76, 0x24, 0xba, 0x2a, 0x10, 0x05, 0xf6, 0xbf, 0x9b, 0x55, 0xe0, 0xb2, + }; + + uint8_t plain[256]; + size_t plen; + uint8_t cipher[256]; + size_t clen; + RADIUS_PACKET *packet, *response; + + plen = sizeof(plain); + CHECK(radius_decrypt_mppe_key_attr(plain, &plen, encrypted, sizeof(encrypted), ra, "hogehogefugafuga") == 0); + CHECK(plen == 16); + CHECK(memcmp(plain, plainkey, 16) == 0); + + clen = sizeof(cipher); + CHECK(radius_encrypt_mppe_key_attr(cipher, &clen, plainkey, 16, ra, "hogehogefugafuga") == 0); + CHECK(clen == 34); + memset(plain, 0, sizeof(plain)); + plen = sizeof(plain); + CHECK(radius_decrypt_mppe_key_attr(plain, &plen, cipher, clen, ra, "hogehogefugafuga") == 0); + CHECK(plen == 16); + CHECK(memcmp(plain, plainkey, 16) == 0); + + clen = 33; + CHECK(radius_encrypt_mppe_key_attr(cipher, &clen, plainkey, 16, ra, "hogehogefugafuga") != 0); + plen = 15; + CHECK(radius_decrypt_mppe_key_attr(plain, &plen, cipher, 34, ra, "hogehogefugafuga") != 0); + plen = 16; + CHECK(radius_decrypt_mppe_key_attr(plain, &plen, cipher, 33, ra, "hogehogefugafuga") != 0); + + packet = radius_new_request_packet(RADIUS_CODE_ACCESS_REQUEST); + + CHECK(radius_put_mppe_send_key_attr(packet, plainkey, sizeof(plainkey), "sharedsecret") == 0); + clen = sizeof(cipher); + CHECK(radius_get_vs_raw_attr(packet, RADIUS_VENDOR_MICROSOFT, RADIUS_VTYPE_MPPE_SEND_KEY, cipher, &clen) == 0); + CHECK(clen == 34); + plen = sizeof(plain); + CHECK(radius_decrypt_mppe_key_attr(plain, &plen, cipher, clen, radius_get_authenticator_retval(packet), "sharedsecret") == 0); + CHECK(plen == 16); + CHECK(memcmp(plain, plainkey, plen) == 0); + memset(plain, 0, sizeof(plain)); + plen = sizeof(plain); + CHECK(radius_get_mppe_send_key_attr(packet, plain, &plen, "sharedsecret") == 0); + CHECK(plen == 16); + CHECK(memcmp(plain, plainkey, plen) == 0); + + response = radius_new_response_packet(RADIUS_CODE_ACCESS_ACCEPT, packet); + + CHECK(radius_put_mppe_recv_key_attr(response, plainkey2, sizeof(plainkey2), "sharedsecret") == 0); + clen = sizeof(cipher); + CHECK(radius_get_vs_raw_attr(response, RADIUS_VENDOR_MICROSOFT, RADIUS_VTYPE_MPPE_RECV_KEY, cipher, &clen) == 0); + CHECK(clen == 34); + plen = sizeof(plain); + CHECK(radius_decrypt_mppe_key_attr(plain, &plen, cipher, clen, radius_get_authenticator_retval(packet), "sharedsecret") == 0); + CHECK(plen == 16); + CHECK(memcmp(plain, plainkey2, plen) == 0); + memset(plain, 0, sizeof(plain)); + plen = sizeof(plain); + CHECK(radius_get_mppe_recv_key_attr(response, plain, &plen, "sharedsecret") == 0); + CHECK(plen == 16); + CHECK(memcmp(plain, plainkey2, plen) == 0); +} + +ADD_TEST(test25) |