implemented and tested functionality to create sa_payload from
[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 #include <encoding/payloads/ts_payload.h>
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, sa_chunk2;
100 iterator_t *proposals, *transforms, *attributes;
101 ike_proposal_t *ike_proposals;
102 size_t ike_proposal_count;
103
104 /* first test generic parsing functionality */
105
106 u_int8_t sa_bytes[] = {
107 0x00,0x80,0x00,0x24, /* payload header*/
108 0x00,0x00,0x00,0x20, /* a proposal */
109 0x01,0x02,0x04,0x05,
110 0x01,0x02,0x03,0x04, /* spi */
111 0x00,0x00,0x00,0x14, /* transform */
112 0x07,0x00,0x00,0x03,
113 0x80,0x01,0x00,0x05, /* attribute without length */
114 0x00,0x03,0x00,0x04, /* attribute with length */
115 0x01,0x02,0x03,0x04
116
117
118 };
119
120 sa_chunk.ptr = sa_bytes;
121 sa_chunk.len = sizeof(sa_bytes);
122
123
124 parser = parser_create(sa_chunk);
125 tester->assert_true(tester,(parser != NULL), "parser create check");
126 status = parser->parse_payload(parser, SECURITY_ASSOCIATION, (payload_t**)&sa_payload);
127 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
128 parser->destroy(parser);
129
130 if (status != SUCCESS)
131 {
132 return;
133 }
134
135
136 proposals = sa_payload->create_proposal_substructure_iterator(sa_payload, TRUE);
137 while (proposals->has_next(proposals))
138 {
139 proposal_substructure_t *proposal;
140 proposals->current(proposals, (void**)&proposal);
141 chunk_t spi;
142 u_int8_t spi_should[] = {0x01, 0x02, 0x03, 0x04};
143
144 tester->assert_true(tester,(proposal->get_proposal_number(proposal) == 1),"proposal number");
145 tester->assert_true(tester,(proposal->get_protocol_id(proposal) == 2),"proposal id");
146 spi = proposal->get_spi(proposal);
147 tester->assert_false(tester,(memcmp(&spi_should, spi.ptr, spi.len)),"proposal spi");
148
149 transforms = proposal->create_transform_substructure_iterator(proposal, TRUE);
150 while(transforms->has_next(transforms))
151 {
152 transform_substructure_t *transform;
153 int loopi;
154 transforms->current(transforms, (void**)&transform);
155 tester->assert_true(tester,(transform->get_transform_type(transform) == 7),"transform type");
156 tester->assert_true(tester,(transform->get_transform_id(transform) == 3),"transform id");
157 attributes = transform->create_transform_attribute_iterator(transform, TRUE);
158 loopi = 0;
159 while (attributes->has_next(attributes))
160 {
161 transform_attribute_t *attribute;
162 attributes->current(attributes, (void**)&attribute);
163 if (loopi == 0)
164 {
165 u_int8_t value[] = {0x05, 0x00};
166 chunk_t attribute_value;
167 tester->assert_true(tester,(attribute->get_attribute_type(attribute) == 1),"attribute 1 type");
168 attribute_value = attribute->get_value_chunk(attribute);
169 tester->assert_false(tester,(memcmp(&value, attribute_value.ptr, attribute_value.len)),"attribute 1 value");
170 }
171 if (loopi == 1)
172 {
173 u_int8_t value[] = {0x01, 0x02, 0x03, 0x04};
174 chunk_t attribute_value;
175 tester->assert_true(tester,(attribute->get_attribute_type(attribute) == 3),"attribute 2 type");
176 attribute_value = attribute->get_value_chunk(attribute);
177 tester->assert_false(tester,(memcmp(&value, attribute_value.ptr, attribute_value.len)),"attribute 2 value");
178 }
179 loopi++;
180 }
181 attributes->destroy(attributes);
182 }
183 transforms->destroy(transforms);
184 }
185 proposals->destroy(proposals);
186
187 sa_payload->destroy(sa_payload);
188
189
190
191 /* now test SA functionality after parsing an SA payload*/
192
193 u_int8_t sa_bytes2[] = {
194 0x00,0x00,0x00,0x6C, /* payload header*/
195 0x02,0x00,0x00,0x34, /* a proposal */
196 0x01,0x01,0x00,0x04,
197 0x03,0x00,0x00,0x0C, /* transform 1 */
198 0x01,0x00,0x00,0x01,
199 0x80,0x0E,0x00,0x14, /* keylength attribute with 20 bytes length */
200 0x03,0x00,0x00,0x0C, /* transform 2 */
201 0x02,0x00,0x00,0x01,
202 0x80,0x0E,0x00,0x14, /* keylength attribute with 20 bytes length */
203 0x03,0x00,0x00,0x0C, /* transform 3 */
204 0x03,0x00,0x00,0x01,
205 0x80,0x0E,0x00,0x14, /* keylength attribute with 20 bytes length */
206 0x00,0x00,0x00,0x08, /* transform 4 */
207 0x04,0x00,0x00,0x01,
208 0x00,0x00,0x00,0x34, /* a proposal */
209 0x01,0x01,0x00,0x04,
210 0x03,0x00,0x00,0x0C, /* transform 1 */
211 0x01,0x00,0x00,0x02,
212 0x80,0x0E,0x00,0x10, /* keylength attribute with 16 bytes length */
213 0x03,0x00,0x00,0x0C, /* transform 2 */
214 0x02,0x00,0x00,0x02,
215 0x80,0x0E,0x00,0x10, /* keylength attribute with 16 bytes length */
216 0x03,0x00,0x00,0x0C, /* transform 3 */
217 0x03,0x00,0x00,0x02,
218 0x80,0x0E,0x00,0x10, /* keylength attribute with 16 bytes length */
219 0x00,0x00,0x00,0x08, /* transform 4 */
220 0x04,0x00,0x00,0x02,
221 };
222
223 sa_chunk2.ptr = sa_bytes2;
224 sa_chunk2.len = sizeof(sa_bytes2);
225
226 parser = parser_create(sa_chunk2);
227 tester->assert_true(tester,(parser != NULL), "parser create check");
228 status = parser->parse_payload(parser, SECURITY_ASSOCIATION, (payload_t**)&sa_payload);
229 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
230 parser->destroy(parser);
231
232 if (status != SUCCESS)
233 {
234 return;
235 }
236
237 status = sa_payload->payload_interface.verify(&(sa_payload->payload_interface));
238 tester->assert_true(tester,(status == SUCCESS),"verify call check");
239
240 status = sa_payload->get_ike_proposals (sa_payload, &ike_proposals, &ike_proposal_count);
241 tester->assert_true(tester,(status == SUCCESS),"get ike proposals call check");
242
243 tester->assert_true(tester,(ike_proposal_count == 2),"ike proposal count check");
244 tester->assert_true(tester,(ike_proposals[0].encryption_algorithm == 1),"ike proposal content check");
245 tester->assert_true(tester,(ike_proposals[0].encryption_algorithm_key_length == 20),"ike proposal content check");
246 tester->assert_true(tester,(ike_proposals[0].integrity_algorithm == 1),"ike proposal content check");
247 tester->assert_true(tester,(ike_proposals[0].integrity_algorithm_key_length == 20),"ike proposal content check");
248 tester->assert_true(tester,(ike_proposals[0].pseudo_random_function == 1),"ike proposal content check");
249 tester->assert_true(tester,(ike_proposals[0].pseudo_random_function_key_length == 20),"ike proposal content check");
250 tester->assert_true(tester,(ike_proposals[0].diffie_hellman_group == 1),"ike proposal content check");
251
252 tester->assert_true(tester,(ike_proposals[1].encryption_algorithm == 2),"ike proposal content check");
253 tester->assert_true(tester,(ike_proposals[1].encryption_algorithm_key_length == 16),"ike proposal content check");
254 tester->assert_true(tester,(ike_proposals[1].integrity_algorithm == 2),"ike proposal content check");
255 tester->assert_true(tester,(ike_proposals[1].integrity_algorithm_key_length == 16),"ike proposal content check");
256 tester->assert_true(tester,(ike_proposals[1].pseudo_random_function == 2),"ike proposal content check");
257 tester->assert_true(tester,(ike_proposals[1].pseudo_random_function_key_length == 16),"ike proposal content check");
258 tester->assert_true(tester,(ike_proposals[1].diffie_hellman_group == 2),"ike proposal content check");
259
260
261 if (status == SUCCESS)
262 {
263 allocator_free(ike_proposals);
264 }
265
266 sa_payload->destroy(sa_payload);
267 }
268
269 /*
270 * Described in Header
271 */
272 void test_parser_with_nonce_payload(tester_t *tester)
273 {
274 parser_t *parser;
275 nonce_payload_t *nonce_payload;
276 status_t status;
277 chunk_t nonce_chunk, result;
278
279 u_int8_t nonce_bytes[] = {
280 0x00,0x00,0x00,0x14, /* payload header */
281 0x00,0x01,0x02,0x03, /* 16 Byte nonce */
282 0x04,0x05,0x06,0x07,
283 0x08,0x09,0x0A,0x2B,
284 0x0C,0x0D,0x0E,0x0F
285 };
286
287 nonce_chunk.ptr = nonce_bytes;
288 nonce_chunk.len = sizeof(nonce_bytes);
289
290 parser = parser_create(nonce_chunk);
291 tester->assert_true(tester,(parser != NULL), "parser create check");
292 status = parser->parse_payload(parser, NONCE, (payload_t**)&nonce_payload);
293 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
294 parser->destroy(parser);
295
296 if (status != SUCCESS)
297 {
298 return;
299 }
300 nonce_payload->get_nonce(nonce_payload, &result);
301 tester->assert_true(tester,(result.len == 16), "parsed nonce lenght");
302 tester->assert_false(tester,(memcmp(nonce_bytes + 4, result.ptr, result.len)), "parsed nonce data");
303 nonce_payload->destroy(nonce_payload);
304 allocator_free_chunk(&result);
305 }
306
307 /*
308 * Described in Header
309 */
310 void test_parser_with_id_payload(tester_t *tester)
311 {
312 parser_t *parser;
313 id_payload_t *id_payload;
314 status_t status;
315 chunk_t id_chunk, result;
316
317 u_int8_t id_bytes[] = {
318 0x00,0x00,0x00,0x14, /* payload header */
319 0x05,0x01,0x02,0x03,
320 0x04,0x05,0x06,0x07,/* 12 Byte nonce */
321 0x08,0x09,0x0A,0x2B,
322 0x0C,0x0D,0x0E,0x0F
323 };
324
325 id_chunk.ptr = id_bytes;
326 id_chunk.len = sizeof(id_bytes);
327
328 parser = parser_create(id_chunk);
329 tester->assert_true(tester,(parser != NULL), "parser create check");
330 status = parser->parse_payload(parser, ID_INITIATOR, (payload_t**)&id_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 result = id_payload->get_data(id_payload);
339 tester->assert_true(tester,(id_payload->get_initiator(id_payload) == TRUE), "is IDi payload");
340 tester->assert_true(tester,(id_payload->get_id_type(id_payload) == ID_IPV6_ADDR), "is ID_IPV6_ADDR ID type");
341 tester->assert_true(tester,(result.len == 12), "parsed data lenght");
342 tester->assert_false(tester,(memcmp(id_bytes + 8, result.ptr, result.len)), "parsed nonce data");
343 id_payload->destroy(id_payload);
344 allocator_free_chunk(&result);
345 }
346
347
348 /*
349 * Described in Header
350 */
351 void test_parser_with_ke_payload(tester_t *tester)
352 {
353 parser_t *parser;
354 ke_payload_t *ke_payload;
355 status_t status;
356 chunk_t ke_chunk, result;
357
358 u_int8_t ke_bytes[] = {
359 0x00,0x00,0x00,0x18, /* payload header */
360 0x00,0x03,0x00,0x00, /* dh group 3 */
361 0x01,0x02,0x03,0x03, /* 16 Byte dh data */
362 0x04,0x05,0x06,0x07,
363 0x08,0x09,0x0A,0x2B,
364 0x0C,0x0D,0x0E,0x0F
365 };
366
367 ke_chunk.ptr = ke_bytes;
368 ke_chunk.len = sizeof(ke_bytes);
369
370 parser = parser_create(ke_chunk);
371 tester->assert_true(tester,(parser != NULL), "parser create check");
372 status = parser->parse_payload(parser, KEY_EXCHANGE, (payload_t**)&ke_payload);
373 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
374 parser->destroy(parser);
375
376 if (status != SUCCESS)
377 {
378 return;
379 }
380 tester->assert_true(tester,(ke_payload->get_dh_group_number(ke_payload) == 3), "DH group");
381 result = ke_payload->get_key_exchange_data(ke_payload);
382 tester->assert_true(tester,(result.len == 16), "parsed key lenght");
383 tester->assert_false(tester,(memcmp(ke_bytes + 8, result.ptr, result.len)), "parsed key data");
384 ke_payload->destroy(ke_payload);
385 }
386
387
388 /*
389 * Described in Header
390 */
391 void test_parser_with_notify_payload(tester_t *tester)
392 {
393 parser_t *parser;
394 notify_payload_t *notify_payload;
395 status_t status;
396 chunk_t notify_chunk, result;
397
398 u_int8_t notify_bytes[] = {
399 0x00,0x00,0x00,0x1C, /* payload header */
400 0x03,0x04,0x00,0x01,
401 0x01,0x02,0x03,0x03, /* spi */
402 0x04,0x05,0x06,0x07, /* noti dati */
403 0x08,0x09,0x0A,0x2B,
404 0x0C,0x0D,0x0E,0x0F,
405 0x0C,0x0D,0x0E,0x0F
406 };
407
408 notify_chunk.ptr = notify_bytes;
409 notify_chunk.len = sizeof(notify_bytes);
410
411 parser = parser_create(notify_chunk);
412 tester->assert_true(tester,(parser != NULL), "parser create check");
413 status = parser->parse_payload(parser, NOTIFY, (payload_t**)&notify_payload);
414 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
415 parser->destroy(parser);
416
417 if (status != SUCCESS)
418 {
419 return;
420 }
421 tester->assert_true(tester,(notify_payload->get_protocol_id(notify_payload) == 3), "Protocol id");
422 tester->assert_true(tester,(notify_payload->get_notify_message_type(notify_payload) == 1), "notify message type");
423
424 result = notify_payload->get_spi(notify_payload);
425 tester->assert_false(tester,(memcmp(notify_bytes + 8, result.ptr, result.len)), "parsed spi");
426
427 result = notify_payload->get_notification_data(notify_payload);
428 tester->assert_false(tester,(memcmp(notify_bytes + 12, result.ptr, result.len)), "parsed notification data");
429
430 notify_payload->destroy(notify_payload);
431 }
432
433 /*
434 * Described in Header
435 */
436 void test_parser_with_auth_payload(tester_t *tester)
437 {
438 parser_t *parser;
439 auth_payload_t *auth_payload;
440 status_t status;
441 chunk_t auth_chunk, result;
442
443 u_int8_t auth_bytes[] = {
444 0x00,0x00,0x00,0x14, /* payload header */
445 0x03,0x01,0x02,0x03,
446 0x04,0x05,0x06,0x07,/* 12 Byte nonce */
447 0x08,0x09,0x0A,0x2B,
448 0x0C,0x0D,0x0E,0x0F
449 };
450
451 auth_chunk.ptr = auth_bytes;
452 auth_chunk.len = sizeof(auth_bytes);
453
454 parser = parser_create(auth_chunk);
455 tester->assert_true(tester,(parser != NULL), "parser create check");
456 status = parser->parse_payload(parser, AUTHENTICATION, (payload_t**)&auth_payload);
457 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
458 parser->destroy(parser);
459
460 if (status != SUCCESS)
461 {
462 return;
463 }
464 result = auth_payload->get_data(auth_payload);
465 tester->assert_true(tester,(auth_payload->get_auth_method(auth_payload) == DSS_DIGITAL_SIGNATURE), "is DSS_DIGITAL_SIGNATURE method");
466 tester->assert_true(tester,(result.len == 12), "parsed data lenght");
467 tester->assert_false(tester,(memcmp(auth_bytes + 8, result.ptr, result.len)), "parsed nonce data");
468 auth_payload->destroy(auth_payload);
469 allocator_free_chunk(&result);
470 }
471
472 /*
473 * Described in Header
474 */
475 void test_parser_with_ts_payload(tester_t *tester)
476 {
477 parser_t *parser;
478 ts_payload_t *ts_payload;
479 status_t status;
480 chunk_t ts_chunk;
481 traffic_selector_substructure_t *ts1, *ts2;
482 host_t *start_host1, *start_host2, *end_host1, *end_host2;
483 iterator_t *iterator;
484
485 u_int8_t ts_bytes[] = {
486 /* payload header */
487 0x00,0x00,0x00,0x28,
488 0x02,0x00,0x00,0x00,
489
490 /* traffic selector 1 */
491 0x07,0x00,0x00,0x10,
492 0x01,0xF4,0x01,0xF4,
493 0xC0,0xA8,0x01,0x00,
494 0xC0,0xA8,0x01,0xFF,
495
496 /* traffic selector 2 */
497 0x07,0x03,0x00,0x10,
498 0x00,0x00,0xFF,0xFF,
499 0x00,0x00,0x00,0x00,
500 0xFF,0xFF,0xFF,0xFF,
501 };
502
503 ts_chunk.ptr = ts_bytes;
504 ts_chunk.len = sizeof(ts_bytes);
505
506 parser = parser_create(ts_chunk);
507 tester->assert_true(tester,(parser != NULL), "parser create check");
508 status = parser->parse_payload(parser, TRAFFIC_SELECTOR_RESPONDER, (payload_t**)&ts_payload);
509 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
510 parser->destroy(parser);
511
512 if (status != SUCCESS)
513 {
514 return;
515 }
516
517 iterator = ts_payload->create_traffic_selector_substructure_iterator(ts_payload,TRUE);
518
519 tester->assert_true(tester,(iterator->has_next(iterator)), "has next check");
520
521 /* check first ts */
522 iterator->current(iterator,(void **)&ts1);
523 tester->assert_true(tester,(ts1->get_protocol_id(ts1) == 0), "ip protocol id check");
524 start_host1 = ts1->get_start_host(ts1);
525 end_host1 = ts1->get_end_host(ts1);
526 tester->assert_true(tester,(start_host1->get_port(start_host1) == 500), "start port check");
527 tester->assert_true(tester,(end_host1->get_port(end_host1) == 500), "start port check");
528 tester->assert_true(tester,(memcmp(start_host1->get_address(start_host1),"192.168.1.0",strlen("192.168.1.0")) == 0), "start address check");
529 tester->assert_true(tester,(memcmp(end_host1->get_address(end_host1),"192.168.1.255",strlen("192.168.1.255")) == 0), "end address check");
530
531 start_host1->destroy(start_host1);
532 end_host1->destroy(end_host1);
533
534 tester->assert_true(tester,(iterator->has_next(iterator)), "has next check");
535
536 /* check second ts */
537
538 iterator->current(iterator,(void **)&ts2);
539
540 tester->assert_true(tester,(ts2->get_protocol_id(ts2) == 3), "ip protocol id check");
541 start_host2 = ts2->get_start_host(ts2);
542 end_host2 = ts2->get_end_host(ts2);
543 tester->assert_true(tester,(start_host2->get_port(start_host2) == 0), "start port check");
544 tester->assert_true(tester,(end_host2->get_port(end_host2) == 65535), "start port check");
545 tester->assert_true(tester,(memcmp(start_host2->get_address(start_host2),"0.0.0.0",strlen("0.0.0.0")) == 0), "start address check");
546 tester->assert_true(tester,(memcmp(end_host2->get_address(end_host2),"255.255.255.255",strlen("255.255.255.255")) == 0), "end address check");
547 start_host2->destroy(start_host2);
548 end_host2->destroy(end_host2);
549
550
551
552 tester->assert_false(tester,(iterator->has_next(iterator)), "has next check");
553
554 iterator->destroy(iterator);
555
556 ts_payload->destroy(ts_payload);
557 }