- changed creation of iterator
[strongswan.git] / Source / charon / encoding / payloads / encryption_payload.c
1 /**
2 * @file encryption_payload.c
3 *
4 * @brief Implementation of encryption_payload_t.
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 /* offsetof macro */
24 #include <stddef.h>
25
26 #include "encryption_payload.h"
27
28 #include <encoding/payloads/encodings.h>
29 #include <utils/allocator.h>
30 #include <utils/linked_list.h>
31 #include <encoding/generator.h>
32 #include <encoding/parser.h>
33 #include <utils/iterator.h>
34 #include <utils/randomizer.h>
35 #include <transforms/signers/signer.h>
36
37
38
39
40 typedef struct private_encryption_payload_t private_encryption_payload_t;
41
42 /**
43 * Private data of an encryption_payload_t' Object.
44 *
45 */
46 struct private_encryption_payload_t {
47 /**
48 * Public encryption_payload_t interface.
49 */
50 encryption_payload_t public;
51
52 /**
53 * There is no next payload for an encryption payload,
54 * since encryption payload MUST be the last one.
55 * next_payload means here the first payload of the
56 * contained, encrypted payload.
57 */
58 u_int8_t next_payload;
59
60 /**
61 * Critical flag.
62 */
63 bool critical;
64
65 /**
66 * Length of this payload
67 */
68 u_int16_t payload_length;
69
70 /**
71 * Initialization vector.
72 */
73 chunk_t iv;
74
75 /**
76 * Integrity checksum.
77 */
78 chunk_t checksum;
79
80 /**
81 * Chunk containing the iv, data, padding,
82 * and (an eventually not calculated) signature.
83 */
84 chunk_t encrypted;
85
86 /**
87 * Chunk containing the data in decrypted (unpadded) form.
88 */
89 chunk_t decrypted;
90
91 /**
92 * Signer set by set_signer.
93 */
94 signer_t *signer;
95
96 /**
97 * Contained payloads of this encrpytion_payload.
98 */
99 linked_list_t *payloads;
100
101 /**
102 * @brief Computes the length of this payload.
103 *
104 * @param this calling private_encryption_payload_t object
105 */
106 void (*compute_length) (private_encryption_payload_t *this);
107
108 /**
109 * @brief Generate payloads (unencrypted) in chunk decrypted.
110 *
111 * @param this calling private_encryption_payload_t object
112 */
113 void (*generate) (private_encryption_payload_t *this);
114 status_t (*parse) (private_encryption_payload_t *this);
115 };
116
117 /**
118 * Encoding rules to parse or generate a IKEv2-Encryption Payload.
119 *
120 * The defined offsets are the positions in a object of type
121 * private_encryption_payload_t.
122 *
123 */
124 encoding_rule_t encryption_payload_encodings[] = {
125 /* 1 Byte next payload type, stored in the field next_payload */
126 { U_INT_8, offsetof(private_encryption_payload_t, next_payload) },
127 /* the critical bit */
128 { FLAG, offsetof(private_encryption_payload_t, critical) },
129 /* 7 Bit reserved bits, nowhere stored */
130 { RESERVED_BIT, 0 },
131 { RESERVED_BIT, 0 },
132 { RESERVED_BIT, 0 },
133 { RESERVED_BIT, 0 },
134 { RESERVED_BIT, 0 },
135 { RESERVED_BIT, 0 },
136 { RESERVED_BIT, 0 },
137 /* Length of the whole encryption payload*/
138 { PAYLOAD_LENGTH, offsetof(private_encryption_payload_t, payload_length) },
139 /* encrypted data, stored in a chunk. contains iv, data, padding */
140 { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) },
141 };
142
143 /*
144 1 2 3
145 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
146 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147 ! Next Payload !C! RESERVED ! Payload Length !
148 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
149 ! Initialization Vector !
150 ! (length is block size for encryption algorithm) !
151 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152 ! Encrypted IKE Payloads !
153 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154 ! ! Padding (0-255 octets) !
155 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
156 ! ! Pad Length !
157 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158 ~ Integrity Checksum Data ~
159 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160 */
161
162 /**
163 * Implementation of payload_t.verify.
164 */
165 static status_t verify(private_encryption_payload_t *this)
166 {
167 // int proposal_number = 1;
168 status_t status;
169 // iterator_t *iterator;
170 // bool first = TRUE;
171 //
172 // if (this->critical)
173 // {
174 // /* critical bit set! */
175 // return FAILED;
176 // }
177 //
178 // /* check proposal numbering */
179 // status = this->proposals->create_iterator(this->proposals,&iterator,TRUE);
180 // if (status != SUCCESS)
181 // {
182 // return status;
183 // }
184 //
185 // while(iterator->has_next(iterator))
186 // {
187 // proposal_substructure_t *current_proposal;
188 // status = iterator->current(iterator,(void **)&current_proposal);
189 // {
190 // break;
191 // }
192 // if (current_proposal->get_proposal_number(current_proposal) > proposal_number)
193 // {
194 // if (first)
195 // {
196 // /* first number must be 1 */
197 // status = FAILED;
198 // break;
199 // }
200 //
201 // if (current_proposal->get_proposal_number(current_proposal) != (proposal_number + 1))
202 // {
203 // /* must be only one more then previous proposal */
204 // status = FAILED;
205 // break;
206 // }
207 // }
208 // else if (current_proposal->get_proposal_number(current_proposal) < proposal_number)
209 // {
210 // iterator->destroy(iterator);
211 // /* must not be smaller then proceeding one */
212 // status = FAILED;
213 // break;
214 // }
215 // first = FALSE;
216 // }
217 //
218 // iterator->destroy(iterator);
219 return status;
220 }
221
222 /**
223 * Implementation of payload_t.destroy.
224 */
225 static void destroy(private_encryption_payload_t *this)
226 {
227 /* all proposals are getting destroyed */
228 while (this->payloads->get_count(this->payloads) > 0)
229 {
230 payload_t *current_payload;
231 this->payloads->remove_last(this->payloads,(void **)&current_payload);
232 current_payload->destroy(current_payload);
233 }
234 this->payloads->destroy(this->payloads);
235
236 allocator_free(this->iv.ptr);
237 allocator_free(this->encrypted.ptr);
238 allocator_free(this->decrypted.ptr);
239 allocator_free(this->checksum.ptr);
240 allocator_free(this);
241 }
242
243 /**
244 * Implementation of payload_t.get_encoding_rules.
245 */
246 static void get_encoding_rules(private_encryption_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
247 {
248 *rules = encryption_payload_encodings;
249 *rule_count = sizeof(encryption_payload_encodings) / sizeof(encoding_rule_t);
250 }
251
252 /**
253 * Implementation of payload_t.get_type.
254 */
255 static payload_type_t get_type(private_encryption_payload_t *this)
256 {
257 return ENCRYPTED;
258 }
259
260 /**
261 * Implementation of payload_t.get_next_type.
262 */
263 static payload_type_t get_next_type(private_encryption_payload_t *this)
264 {
265 /* returns first contained payload here */
266 return (this->next_payload);
267 }
268
269 /**
270 * Implementation of payload_t.set_next_type.
271 */
272 static void set_next_type(private_encryption_payload_t *this, payload_type_t type)
273 {
274 /* set next type is not allowed, since this payload MUST be the last one
275 * and so nothing is done in here*/
276 }
277
278 /**
279 * Implementation of payload_t.get_length.
280 */
281 static size_t get_length(private_encryption_payload_t *this)
282 {
283 this->compute_length(this);
284 return this->payload_length;
285 }
286
287 /**
288 * Implementation of payload_t.create_payload_iterator.
289 */
290 static iterator_t *create_payload_iterator (private_encryption_payload_t *this, bool forward)
291 {
292 return (this->payloads->create_iterator(this->payloads, forward));
293 }
294
295 /**
296 * Implementation of payload_t.add_payload.
297 */
298 static void add_payload(private_encryption_payload_t *this, payload_t *payload)
299 {
300 payload_t *last_payload;
301 if (this->payloads->get_count(this->payloads) > 0)
302 {
303 this->payloads->get_last(this->payloads,(void **) &last_payload);
304 }
305
306 if (this->payloads->get_count(this->payloads) == 1)
307 {
308 this->next_payload = payload->get_type(payload);
309 }
310 else
311 {
312 last_payload->set_next_type(last_payload, payload->get_type(payload));
313 }
314 payload->set_next_type(payload, NO_PAYLOAD);
315 this->compute_length(this);
316 }
317
318 /**
319 * Implementation of encryption_payload_t.encrypt.
320 */
321 static status_t encrypt(private_encryption_payload_t *this, crypter_t *crypter)
322 {
323 chunk_t iv, padding, concatenated;
324 randomizer_t *randomizer;
325 status_t status;
326
327 if (this->signer == NULL)
328 {
329 return INVALID_STATE;
330 }
331
332 /* for random data in iv and padding */
333 randomizer = randomizer_create();
334
335 /* build payload chunk */
336 this->generate(this);
337
338 /* build padding */
339 padding.len = (this->decrypted.len + 1) % crypter->get_block_size(crypter);
340 status = randomizer->allocate_pseudo_random_bytes(randomizer, padding.len, &padding);
341 if (status != SUCCESS)
342 {
343 randomizer->destroy(randomizer);
344 return status;
345 }
346
347 /* concatenate payload data, padding, padding len */
348 concatenated.len = this->decrypted.len + padding.len + 1;
349 concatenated.ptr = allocator_alloc(concatenated.len);
350
351 memcpy(concatenated.ptr, this->decrypted.ptr, this->decrypted.len);
352 memcpy(concatenated.ptr + this->decrypted.len, padding.ptr, padding.len);
353 *(concatenated.ptr + concatenated.len - 1) = padding.len;
354
355
356 /* build iv */
357 iv.len = crypter->get_block_size(crypter);
358 randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
359 randomizer->destroy(randomizer);
360
361 /* encrypt concatenated chunk */
362 allocator_free(this->encrypted.ptr);
363 status = crypter->encrypt(crypter, iv, concatenated, &(this->encrypted));
364 allocator_free(padding.ptr);
365 allocator_free(concatenated.ptr);
366 allocator_free(iv.ptr);
367 if (status != SUCCESS)
368 {
369 return status;
370 }
371
372 /* append an empty signature */
373 this->encrypted.len += this->signer->get_block_size(this->signer);
374 allocator_realloc(this->encrypted.ptr, this->encrypted.len);
375 return SUCCESS;
376 }
377
378 /**
379 * Implementation of encryption_payload_t.encrypt.
380 */
381 static status_t decrypt(private_encryption_payload_t *this, crypter_t *crypter)
382 {
383 chunk_t iv, concatenated;
384 u_int8_t padding_length;
385 status_t status;
386
387 if (this->signer == NULL)
388 {
389 return INVALID_STATE;
390 }
391
392 /* get IV */
393 iv.len = crypter->get_block_size(crypter);
394 iv.ptr = this->encrypted.ptr;
395
396 /* point concatenated to data + padding + padding_length*/
397 concatenated.ptr = this->encrypted.ptr + iv.len;
398 concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
399
400 /* check the size of input:
401 * concatenated must be at least on block_size of crypter
402 */
403 if (concatenated.len < iv.len)
404 {
405 return FAILED;
406 }
407
408 /* free previus data, if any */
409 allocator_free(this->decrypted.ptr);
410
411 status = crypter->decrypt(crypter, iv, concatenated, &(this->decrypted));
412 if (status != SUCCESS)
413 {
414 return FAILED;
415 }
416
417 /* get padding length, sits just bevore signature */
418 padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
419 this->decrypted.len -= padding_length;
420
421 /* check size again */
422 if (padding_length > concatenated.len || this->decrypted.len < 0)
423 {
424 /* decryption failed :-/ */
425 return FAILED;
426 }
427
428 /* free padding */
429 this->decrypted.ptr = allocator_realloc(this->decrypted.ptr, this->decrypted.len);
430 if (this->decrypted.ptr == NULL)
431 {
432 return OUT_OF_RES;
433 }
434
435 return SUCCESS;
436 }
437
438 /**
439 * Implementation of encryption_payload_t.set_signer.
440 */
441 static void set_signer(private_encryption_payload_t *this, signer_t* signer)
442 {
443 this->signer = signer;
444 }
445
446 /**
447 * Implementation of encryption_payload_t.build_signature.
448 */
449 static status_t build_signature(private_encryption_payload_t *this, chunk_t data)
450 {
451 chunk_t data_without_sig = data;
452 chunk_t sig;
453
454 if (this->signer == NULL)
455 {
456 return INVALID_STATE;
457 }
458
459 sig.len = this->signer->get_block_size(this->signer);
460 data_without_sig.len -= sig.len;
461 sig.ptr = data.ptr + data_without_sig.len;
462 this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
463 return SUCCESS;
464 }
465
466 /**
467 * Implementation of encryption_payload_t.verify_signature.
468 */
469 static status_t verify_signature(private_encryption_payload_t *this, chunk_t data)
470 {
471 chunk_t sig, data_without_sig;
472 bool valid;
473
474 if (this->signer == NULL)
475 {
476 return INVALID_STATE;
477 }
478 /* find signature in data chunk */
479 sig.len = this->signer->get_block_size(this->signer);
480 if (data.len <= sig.len)
481 {
482 return FAILED;
483 }
484 sig.ptr = data.ptr + data.len - sig.len;
485
486 /* verify it */
487 data_without_sig.len = data.len - sig.len;
488 data_without_sig.ptr = data.ptr;
489 this->signer->verify_signature(this->signer, data_without_sig, sig, &valid);
490
491 if (!valid)
492 {
493 return FAILED;
494 }
495
496 return SUCCESS;
497 }
498
499 /**
500 * Implementation of private_encryption_payload_t.generate.
501 */
502 static void generate(private_encryption_payload_t *this)
503 {
504 payload_t *current_payload, *next_payload;
505 generator_t *generator;
506 iterator_t *iterator;
507
508 /* create iterator */
509 iterator = this->payloads->create_iterator(this->payloads, TRUE);
510
511 /* get first payload */
512 if (iterator->has_next(iterator))
513 {
514 iterator->current(iterator, (void**)&current_payload);
515 this->next_payload = current_payload->get_type(current_payload);
516 }
517 else
518 {
519 /* no paylads? */
520 allocator_free(this->decrypted.ptr);
521 this->decrypted = CHUNK_INITIALIZER;
522 iterator->destroy(iterator);
523 return;
524 }
525
526 generator = generator_create();
527
528 /* build all payload, except last */
529 while(iterator->has_next(iterator))
530 {
531 iterator->current(iterator, (void**)&next_payload);
532 current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
533
534 generator->generate_payload(generator, current_payload);
535 current_payload = next_payload;
536 }
537 iterator->destroy(iterator);
538
539 /* build last payload */
540 current_payload->set_next_type(current_payload, NO_PAYLOAD);
541 generator->generate_payload(generator, current_payload);
542
543 /* free already generated data */
544 allocator_free(this->decrypted.ptr);
545
546 generator->write_to_chunk(generator, &(this->decrypted));
547 generator->destroy(generator);
548 }
549
550 /**
551 * Implementation of private_encryption_payload_t.parse.
552 */
553 static status_t parse(private_encryption_payload_t *this)
554 {
555 parser_t *parser;
556 status_t status;
557 payload_type_t current_payload_type;
558
559 /* check if there is decrypted data */
560 if (this->decrypted.ptr == NULL)
561 {
562 return INVALID_STATE;
563 }
564
565 /* build a parser on the decrypted data */
566 parser = parser_create(this->decrypted);
567
568 current_payload_type = this->next_payload;
569 /* parse all payloads */
570 while (current_payload_type != NO_PAYLOAD)
571 {
572 payload_t *current_payload;
573
574 status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
575 if (status != SUCCESS)
576 {
577 return PARSE_ERROR;
578 }
579
580 status = current_payload->verify(current_payload);
581 if (status != SUCCESS)
582 {
583 return VERIFY_ERROR;
584 }
585
586 /* get next payload type */
587 current_payload_type = current_payload->get_next_type(current_payload);
588
589 this->payloads->insert_last(this->payloads,current_payload);
590 }
591 return SUCCESS;
592 }
593
594 /**
595 * Implementation of private_encryption_payload_t.compute_length.
596 */
597 static void compute_length(private_encryption_payload_t *this)
598 {
599 iterator_t *iterator;
600 size_t length = ENCRYPTION_PAYLOAD_HEADER_LENGTH;
601 iterator = this->payloads->create_iterator(this->payloads, TRUE);
602
603 while (iterator->has_next(iterator))
604 {
605 payload_t *current_payload;
606 iterator->current(iterator, (void **) &current_payload);
607 length += current_payload->get_length(current_payload);
608 }
609 iterator->destroy(iterator);
610
611 this->payload_length = length;
612
613 }
614
615 /*
616 * Described in header
617 */
618 encryption_payload_t *encryption_payload_create()
619 {
620 private_encryption_payload_t *this = allocator_alloc_thing(private_encryption_payload_t);
621
622 /* payload_t interface functions */
623 this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
624 this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
625 this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
626 this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
627 this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
628 this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
629 this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
630
631 /* public functions */
632 this->public.create_payload_iterator = (iterator_t * (*) (encryption_payload_t *,bool)) create_payload_iterator;
633 this->public.add_payload = (void (*) (encryption_payload_t *,payload_t *)) add_payload;
634 this->public.encrypt = (status_t (*) (encryption_payload_t *, crypter_t*)) encrypt;
635 this->public.decrypt = (status_t (*) (encryption_payload_t *, crypter_t*)) decrypt;
636 this->public.set_signer = (void (*) (encryption_payload_t *,signer_t*)) set_signer;
637 this->public.build_signature = (status_t (*) (encryption_payload_t*, chunk_t)) build_signature;
638 this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature;
639 this->public.destroy = (void (*) (encryption_payload_t *)) destroy;
640
641 /* private functions */
642 this->compute_length = compute_length;
643 this->generate = generate;
644 this->parse = parse;
645
646 /* set default values of the fields */
647 this->critical = TRUE;
648 this->next_payload = NO_PAYLOAD;
649 this->payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH;
650 this->iv = CHUNK_INITIALIZER;
651 this->encrypted = CHUNK_INITIALIZER;
652 this->decrypted = CHUNK_INITIALIZER;
653 this->checksum = CHUNK_INITIALIZER;
654 this->signer = NULL;
655 this->payloads = linked_list_create();
656
657 return (&(this->public));
658 }
659
660