- added and tested auth_payload_t class
[strongswan.git] / Source / charon / testcases / parser_test.c
1 /**
2 * @file parser_test.c
3 *
4 * @brief Tests for the parser_t class.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <string.h>
24
25 #include "parser_test.h"
26
27 #include <utils/allocator.h>
28 #include <utils/logger_manager.h>
29 #include <encoding/generator.h>
30 #include <encoding/parser.h>
31 #include <encoding/payloads/encodings.h>
32 #include <encoding/payloads/ike_header.h>
33 #include <encoding/payloads/sa_payload.h>
34 #include <encoding/payloads/nonce_payload.h>
35 #include <encoding/payloads/id_payload.h>
36 #include <encoding/payloads/ke_payload.h>
37 #include <encoding/payloads/notify_payload.h>
38 #include <encoding/payloads/auth_payload.h>
39
40
41
42 /*
43 * Described in Header
44 */
45 void test_parser_with_header_payload(tester_t *tester)
46 {
47 parser_t *parser;
48 ike_header_t *ike_header;
49 status_t status;
50 chunk_t header_chunk;
51
52 u_int8_t header_bytes[] = {
53 0x01,0x00,0x00,0x00,
54 0x00,0x00,0x00,0x00,
55 0x02,0x00,0x00,0x00,
56 0x00,0x00,0x00,0x00,
57 0x03,0x45,0x06,0x28,
58 0x00,0x00,0x00,0x07,
59 0x00,0x00,0x00,0x1C,
60 };
61 header_chunk.ptr = header_bytes;
62 header_chunk.len = sizeof(header_bytes);
63
64
65 parser = parser_create(header_chunk);
66 tester->assert_true(tester,(parser != NULL), "parser create check");
67 status = parser->parse_payload(parser, HEADER, (payload_t**)&ike_header);
68 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
69 parser->destroy(parser);
70
71 if (status != SUCCESS)
72 {
73 return;
74 }
75
76 tester->assert_true(tester,(ike_header->get_initiator_spi(ike_header) == 1),"parsed initiator_spi value");
77 tester->assert_true(tester,(ike_header->get_responder_spi(ike_header) == 2),"parsed responder_spi value");
78 tester->assert_true(tester,(ike_header->payload_interface.get_next_type((payload_t*)ike_header) == 3),"parsed next_payload value");
79 tester->assert_true(tester,(ike_header->get_maj_version(ike_header) == 4),"parsed maj_version value");
80 tester->assert_true(tester,(ike_header->get_min_version(ike_header) == 5),"parsed min_version value");
81 tester->assert_true(tester,(ike_header->get_exchange_type(ike_header) == 6),"parsed exchange_type value");
82 tester->assert_true(tester,(ike_header->get_initiator_flag(ike_header) == TRUE),"parsed flags.initiator value");
83 tester->assert_true(tester,(ike_header->get_version_flag(ike_header) == FALSE),"parsed flags.version value");
84 tester->assert_true(tester,(ike_header->get_response_flag(ike_header) == TRUE),"parsed flags.response value");
85 tester->assert_true(tester,(ike_header->get_message_id(ike_header) == 7),"parsed message_id value");
86 tester->assert_true(tester,(ike_header->payload_interface.get_length((payload_t*)ike_header) == 0x1C),"parsed length value");
87
88 ike_header->destroy(ike_header);
89 }
90
91 /*
92 * Described in Header
93 */
94 void test_parser_with_sa_payload(tester_t *tester)
95 {
96 parser_t *parser;
97 sa_payload_t *sa_payload;
98 status_t status;
99 chunk_t sa_chunk;
100 iterator_t *proposals, *transforms, *attributes;
101
102 u_int8_t sa_bytes[] = {
103 0x00,0x80,0x00,0x24, /* payload header*/
104 0x00,0x00,0x00,0x20, /* a proposal */
105 0x01,0x02,0x04,0x05,
106 0x01,0x02,0x03,0x04, /* spi */
107 0x00,0x00,0x00,0x14, /* transform */
108 0x07,0x00,0x00,0x03,
109 0x80,0x01,0x00,0x05, /* attribute without length */
110 0x00,0x03,0x00,0x04, /* attribute with lenngth */
111 0x01,0x02,0x03,0x04
112
113
114 };
115
116 sa_chunk.ptr = sa_bytes;
117 sa_chunk.len = sizeof(sa_bytes);
118
119
120 parser = parser_create(sa_chunk);
121 tester->assert_true(tester,(parser != NULL), "parser create check");
122 status = parser->parse_payload(parser, SECURITY_ASSOCIATION, (payload_t**)&sa_payload);
123 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
124 parser->destroy(parser);
125
126 if (status != SUCCESS)
127 {
128 return;
129 }
130
131
132 proposals = sa_payload->create_proposal_substructure_iterator(sa_payload, TRUE);
133 while (proposals->has_next(proposals))
134 {
135 proposal_substructure_t *proposal;
136 proposals->current(proposals, (void**)&proposal);
137 chunk_t spi;
138 u_int8_t spi_should[] = {0x01, 0x02, 0x03, 0x04};
139
140 tester->assert_true(tester,(proposal->get_proposal_number(proposal) == 1),"proposal number");
141 tester->assert_true(tester,(proposal->get_protocol_id(proposal) == 2),"proposal id");
142 spi = proposal->get_spi(proposal);
143 tester->assert_false(tester,(memcmp(&spi_should, spi.ptr, spi.len)),"proposal spi");
144
145 transforms = proposal->create_transform_substructure_iterator(proposal, TRUE);
146 while(transforms->has_next(transforms))
147 {
148 transform_substructure_t *transform;
149 int loopi;
150 transforms->current(transforms, (void**)&transform);
151 tester->assert_true(tester,(transform->get_transform_type(transform) == 7),"transform type");
152 tester->assert_true(tester,(transform->get_transform_id(transform) == 3),"transform id");
153 attributes = transform->create_transform_attribute_iterator(transform, TRUE);
154 loopi = 0;
155 while (attributes->has_next(attributes))
156 {
157 transform_attribute_t *attribute;
158 attributes->current(attributes, (void**)&attribute);
159 if (loopi == 0)
160 {
161 u_int8_t value[] = {0x05, 0x00};
162 chunk_t attribute_value;
163 tester->assert_true(tester,(attribute->get_attribute_type(attribute) == 1),"attribute 1 type");
164 attribute_value = attribute->get_value_chunk(attribute);
165 tester->assert_false(tester,(memcmp(&value, attribute_value.ptr, attribute_value.len)),"attribute 1 value");
166 }
167 if (loopi == 1)
168 {
169 u_int8_t value[] = {0x01, 0x02, 0x03, 0x04};
170 chunk_t attribute_value;
171 tester->assert_true(tester,(attribute->get_attribute_type(attribute) == 3),"attribute 2 type");
172 attribute_value = attribute->get_value_chunk(attribute);
173 tester->assert_false(tester,(memcmp(&value, attribute_value.ptr, attribute_value.len)),"attribute 2 value");
174 }
175 loopi++;
176 }
177 attributes->destroy(attributes);
178 }
179 transforms->destroy(transforms);
180 }
181 proposals->destroy(proposals);
182
183 sa_payload->destroy(sa_payload);
184 }
185
186 /*
187 * Described in Header
188 */
189 void test_parser_with_nonce_payload(tester_t *tester)
190 {
191 parser_t *parser;
192 nonce_payload_t *nonce_payload;
193 status_t status;
194 chunk_t nonce_chunk, result;
195
196 u_int8_t nonce_bytes[] = {
197 0x00,0x00,0x00,0x14, /* payload header */
198 0x00,0x01,0x02,0x03, /* 16 Byte nonce */
199 0x04,0x05,0x06,0x07,
200 0x08,0x09,0x0A,0x2B,
201 0x0C,0x0D,0x0E,0x0F
202 };
203
204 nonce_chunk.ptr = nonce_bytes;
205 nonce_chunk.len = sizeof(nonce_bytes);
206
207 parser = parser_create(nonce_chunk);
208 tester->assert_true(tester,(parser != NULL), "parser create check");
209 status = parser->parse_payload(parser, NONCE, (payload_t**)&nonce_payload);
210 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
211 parser->destroy(parser);
212
213 if (status != SUCCESS)
214 {
215 return;
216 }
217 nonce_payload->get_nonce(nonce_payload, &result);
218 tester->assert_true(tester,(result.len == 16), "parsed nonce lenght");
219 tester->assert_false(tester,(memcmp(nonce_bytes + 4, result.ptr, result.len)), "parsed nonce data");
220 nonce_payload->destroy(nonce_payload);
221 allocator_free_chunk(&result);
222 }
223
224 /*
225 * Described in Header
226 */
227 void test_parser_with_id_payload(tester_t *tester)
228 {
229 parser_t *parser;
230 id_payload_t *id_payload;
231 status_t status;
232 chunk_t id_chunk, result;
233
234 u_int8_t id_bytes[] = {
235 0x00,0x00,0x00,0x14, /* payload header */
236 0x05,0x01,0x02,0x03,
237 0x04,0x05,0x06,0x07,/* 12 Byte nonce */
238 0x08,0x09,0x0A,0x2B,
239 0x0C,0x0D,0x0E,0x0F
240 };
241
242 id_chunk.ptr = id_bytes;
243 id_chunk.len = sizeof(id_bytes);
244
245 parser = parser_create(id_chunk);
246 tester->assert_true(tester,(parser != NULL), "parser create check");
247 status = parser->parse_payload(parser, ID_INITIATOR, (payload_t**)&id_payload);
248 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
249 parser->destroy(parser);
250
251 if (status != SUCCESS)
252 {
253 return;
254 }
255 result = id_payload->get_data(id_payload);
256 tester->assert_true(tester,(id_payload->get_initiator(id_payload) == TRUE), "is IDi payload");
257 tester->assert_true(tester,(id_payload->get_id_type(id_payload) == ID_IPV6_ADDR), "is ID_IPV6_ADDR ID type");
258 tester->assert_true(tester,(result.len == 12), "parsed data lenght");
259 tester->assert_false(tester,(memcmp(id_bytes + 8, result.ptr, result.len)), "parsed nonce data");
260 id_payload->destroy(id_payload);
261 allocator_free_chunk(&result);
262 }
263
264
265 /*
266 * Described in Header
267 */
268 void test_parser_with_ke_payload(tester_t *tester)
269 {
270 parser_t *parser;
271 ke_payload_t *ke_payload;
272 status_t status;
273 chunk_t ke_chunk, result;
274
275 u_int8_t ke_bytes[] = {
276 0x00,0x00,0x00,0x18, /* payload header */
277 0x00,0x03,0x00,0x00, /* dh group 3 */
278 0x01,0x02,0x03,0x03, /* 16 Byte dh data */
279 0x04,0x05,0x06,0x07,
280 0x08,0x09,0x0A,0x2B,
281 0x0C,0x0D,0x0E,0x0F
282 };
283
284 ke_chunk.ptr = ke_bytes;
285 ke_chunk.len = sizeof(ke_bytes);
286
287 parser = parser_create(ke_chunk);
288 tester->assert_true(tester,(parser != NULL), "parser create check");
289 status = parser->parse_payload(parser, KEY_EXCHANGE, (payload_t**)&ke_payload);
290 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
291 parser->destroy(parser);
292
293 if (status != SUCCESS)
294 {
295 return;
296 }
297 tester->assert_true(tester,(ke_payload->get_dh_group_number(ke_payload) == 3), "DH group");
298 result = ke_payload->get_key_exchange_data(ke_payload);
299 tester->assert_true(tester,(result.len == 16), "parsed key lenght");
300 tester->assert_false(tester,(memcmp(ke_bytes + 8, result.ptr, result.len)), "parsed key data");
301 ke_payload->destroy(ke_payload);
302 }
303
304
305 /*
306 * Described in Header
307 */
308 void test_parser_with_notify_payload(tester_t *tester)
309 {
310 parser_t *parser;
311 notify_payload_t *notify_payload;
312 status_t status;
313 chunk_t notify_chunk, result;
314
315 u_int8_t notify_bytes[] = {
316 0x00,0x00,0x00,0x1C, /* payload header */
317 0x03,0x04,0x00,0x01,
318 0x01,0x02,0x03,0x03, /* spi */
319 0x04,0x05,0x06,0x07, /* noti dati */
320 0x08,0x09,0x0A,0x2B,
321 0x0C,0x0D,0x0E,0x0F,
322 0x0C,0x0D,0x0E,0x0F
323 };
324
325 notify_chunk.ptr = notify_bytes;
326 notify_chunk.len = sizeof(notify_bytes);
327
328 parser = parser_create(notify_chunk);
329 tester->assert_true(tester,(parser != NULL), "parser create check");
330 status = parser->parse_payload(parser, NOTIFY, (payload_t**)&notify_payload);
331 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
332 parser->destroy(parser);
333
334 if (status != SUCCESS)
335 {
336 return;
337 }
338 tester->assert_true(tester,(notify_payload->get_protocol_id(notify_payload) == 3), "Protocol id");
339 tester->assert_true(tester,(notify_payload->get_notify_message_type(notify_payload) == 1), "notify message type");
340
341 result = notify_payload->get_spi(notify_payload);
342 tester->assert_false(tester,(memcmp(notify_bytes + 8, result.ptr, result.len)), "parsed spi");
343
344 result = notify_payload->get_notification_data(notify_payload);
345 tester->assert_false(tester,(memcmp(notify_bytes + 12, result.ptr, result.len)), "parsed notification data");
346
347 notify_payload->destroy(notify_payload);
348 }
349
350 /*
351 * Described in Header
352 */
353 void test_parser_with_auth_payload(tester_t *tester)
354 {
355 parser_t *parser;
356 auth_payload_t *auth_payload;
357 status_t status;
358 chunk_t auth_chunk, result;
359
360 u_int8_t auth_bytes[] = {
361 0x00,0x00,0x00,0x14, /* payload header */
362 0x03,0x01,0x02,0x03,
363 0x04,0x05,0x06,0x07,/* 12 Byte nonce */
364 0x08,0x09,0x0A,0x2B,
365 0x0C,0x0D,0x0E,0x0F
366 };
367
368 auth_chunk.ptr = auth_bytes;
369 auth_chunk.len = sizeof(auth_bytes);
370
371 parser = parser_create(auth_chunk);
372 tester->assert_true(tester,(parser != NULL), "parser create check");
373 status = parser->parse_payload(parser, AUTHENTICATION, (payload_t**)&auth_payload);
374 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
375 parser->destroy(parser);
376
377 if (status != SUCCESS)
378 {
379 return;
380 }
381 result = auth_payload->get_data(auth_payload);
382 tester->assert_true(tester,(auth_payload->get_auth_method(auth_payload) == DSS_DIGITAL_SIGNATURE), "is DSS_DIGITAL_SIGNATURE method");
383 tester->assert_true(tester,(result.len == 12), "parsed data lenght");
384 tester->assert_false(tester,(memcmp(auth_bytes + 8, result.ptr, result.len)), "parsed nonce data");
385 auth_payload->destroy(auth_payload);
386 allocator_free_chunk(&result);
387 }