- changed creation of iterator
[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/ke_payload.h>
36 #include <encoding/payloads/notify_payload.h>
37
38
39 extern logger_manager_t *global_logger_manager;
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_ke_payload(tester_t *tester)
228 {
229 parser_t *parser;
230 ke_payload_t *ke_payload;
231 status_t status;
232 chunk_t ke_chunk, result;
233
234 u_int8_t ke_bytes[] = {
235 0x00,0x00,0x00,0x18, /* payload header */
236 0x00,0x03,0x00,0x00, /* dh group 3 */
237 0x01,0x02,0x03,0x03, /* 16 Byte dh data */
238 0x04,0x05,0x06,0x07,
239 0x08,0x09,0x0A,0x2B,
240 0x0C,0x0D,0x0E,0x0F
241 };
242
243 ke_chunk.ptr = ke_bytes;
244 ke_chunk.len = sizeof(ke_bytes);
245
246 parser = parser_create(ke_chunk);
247 tester->assert_true(tester,(parser != NULL), "parser create check");
248 status = parser->parse_payload(parser, KEY_EXCHANGE, (payload_t**)&ke_payload);
249 tester->assert_true(tester,(status == SUCCESS),"parse_payload call check");
250 parser->destroy(parser);
251
252 if (status != SUCCESS)
253 {
254 return;
255 }
256 tester->assert_true(tester,(ke_payload->get_dh_group_number(ke_payload) == 3), "DH group");
257 result = ke_payload->get_key_exchange_data(ke_payload);
258 tester->assert_true(tester,(result.len == 16), "parsed key lenght");
259 tester->assert_false(tester,(memcmp(ke_bytes + 8, result.ptr, result.len)), "parsed key data");
260 ke_payload->destroy(ke_payload);
261 }
262
263
264 /*
265 * Described in Header
266 */
267 void test_parser_with_notify_payload(tester_t *tester)
268 {
269 parser_t *parser;
270 notify_payload_t *notify_payload;
271 status_t status;
272 chunk_t notify_chunk, result;
273
274 u_int8_t notify_bytes[] = {
275 0x00,0x00,0x00,0x1C, /* payload header */
276 0x03,0x04,0x00,0x01,
277 0x01,0x02,0x03,0x03, /* spi */
278 0x04,0x05,0x06,0x07, /* noti dati */
279 0x08,0x09,0x0A,0x2B,
280 0x0C,0x0D,0x0E,0x0F,
281 0x0C,0x0D,0x0E,0x0F
282 };
283
284 notify_chunk.ptr = notify_bytes;
285 notify_chunk.len = sizeof(notify_bytes);
286
287 parser = parser_create(notify_chunk);
288 tester->assert_true(tester,(parser != NULL), "parser create check");
289 status = parser->parse_payload(parser, NOTIFY, (payload_t**)&notify_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,(notify_payload->get_protocol_id(notify_payload) == 3), "Protocol id");
298 tester->assert_true(tester,(notify_payload->get_notify_message_type(notify_payload) == 1), "notify message type");
299
300 result = notify_payload->get_spi(notify_payload);
301 tester->assert_false(tester,(memcmp(notify_bytes + 8, result.ptr, result.len)), "parsed spi");
302
303 result = notify_payload->get_notification_data(notify_payload);
304 tester->assert_false(tester,(memcmp(notify_bytes + 12, result.ptr, result.len)), "parsed notification data");
305
306 notify_payload->destroy(notify_payload);
307 }