aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/tls/gnutls_session_pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/tls/gnutls_session_pack.c')
-rw-r--r--src/daemon/https/tls/gnutls_session_pack.c1025
1 files changed, 0 insertions, 1025 deletions
diff --git a/src/daemon/https/tls/gnutls_session_pack.c b/src/daemon/https/tls/gnutls_session_pack.c
deleted file mode 100644
index be80bfb7..00000000
--- a/src/daemon/https/tls/gnutls_session_pack.c
+++ /dev/null
@@ -1,1025 +0,0 @@
1/*
2 * Copyright (C) 2000, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Contains functions that are supposed to pack and unpack session data,
26 * before and after they are sent to the database backend.
27 */
28
29#include <gnutls_int.h>
30#ifdef ENABLE_SRP
31# include <auth_srp.h>
32#endif
33#ifdef ENABLE_PSK
34# include <auth_psk.h>
35#endif
36#include <auth_cert.h>
37#include <gnutls_errors.h>
38#include <gnutls_auth_int.h>
39#include <gnutls_session_pack.h>
40#include <gnutls_datum.h>
41#include <gnutls_num.h>
42
43#define PACK_HEADER_SIZE 1
44#define MAX_SEC_PARAMS 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)+165
45static int pack_certificate_auth_info (MHD_gtls_session_t,
46 MHD_gnutls_datum_t * packed_session);
47static int unpack_certificate_auth_info (MHD_gtls_session_t,
48 const MHD_gnutls_datum_t *
49 packed_session);
50
51static int unpack_security_parameters (MHD_gtls_session_t session,
52 const MHD_gnutls_datum_t *
53 packed_session);
54static int pack_security_parameters (MHD_gtls_session_t session,
55 MHD_gnutls_datum_t * packed_session);
56
57/* Since auth_info structures contain malloced data, this function
58 * is required in order to pack these structures in a vector in
59 * order to store them to the DB.
60 *
61 * packed_session will contain the session data.
62 *
63 * The data will be in a platform independent format.
64 */
65int
66MHD_gtls_session_pack (MHD_gtls_session_t session,
67 MHD_gnutls_datum_t * packed_session)
68{
69 int ret;
70
71 if (packed_session == NULL)
72 {
73 MHD_gnutls_assert ();
74 return GNUTLS_E_INTERNAL_ERROR;
75 }
76
77
78 switch (MHD_gtls_auth_get_type (session))
79 {
80#ifdef ENABLE_SRP
81 case MHD_GNUTLS_CRD_SRP:
82 ret = pack_srp_auth_info (session, packed_session);
83 if (ret < 0)
84 {
85 MHD_gnutls_assert ();
86 return ret;
87 }
88 break;
89#endif
90#ifdef ENABLE_PSK
91 case MHD_GNUTLS_CRD_PSK:
92 ret = pack_psk_auth_info (session, packed_session);
93 if (ret < 0)
94 {
95 MHD_gnutls_assert ();
96 return ret;
97 }
98 break;
99#endif
100 case MHD_GNUTLS_CRD_CERTIFICATE:
101 ret = pack_certificate_auth_info (session, packed_session);
102 if (ret < 0)
103 {
104 MHD_gnutls_assert ();
105 return ret;
106 }
107 break;
108 default:
109 return GNUTLS_E_INTERNAL_ERROR;
110
111 }
112
113 /* Auth_info structures copied. Now copy MHD_gtls_security_param_st.
114 * packed_session must have allocated space for the security parameters.
115 */
116 ret = pack_security_parameters (session, packed_session);
117 if (ret < 0)
118 {
119 MHD_gnutls_assert ();
120 MHD__gnutls_free_datum (packed_session);
121 return ret;
122 }
123
124 return 0;
125}
126
127
128/* Load session data from a buffer.
129 */
130int
131MHD_gtls_session_unpack (MHD_gtls_session_t session,
132 const MHD_gnutls_datum_t * packed_session)
133{
134 int ret;
135
136 if (packed_session == NULL || packed_session->size == 0)
137 {
138 MHD_gnutls_assert ();
139 return GNUTLS_E_INTERNAL_ERROR;
140 }
141
142 if (MHD_gtls_get_auth_info (session) != NULL)
143 {
144 MHD_gtls_free_auth_info (session);
145 }
146
147 switch (packed_session->data[0])
148 {
149#ifdef ENABLE_SRP
150 case MHD_GNUTLS_CRD_SRP:
151 ret = unpack_srp_auth_info (session, packed_session);
152 if (ret < 0)
153 {
154 MHD_gnutls_assert ();
155 return ret;
156 }
157 break;
158#endif
159#ifdef ENABLE_PSK
160 case MHD_GNUTLS_CRD_PSK:
161 ret = unpack_psk_auth_info (session, packed_session);
162 if (ret < 0)
163 {
164 MHD_gnutls_assert ();
165 return ret;
166 }
167 break;
168#endif
169 case MHD_GNUTLS_CRD_CERTIFICATE:
170 ret = unpack_certificate_auth_info (session, packed_session);
171 if (ret < 0)
172 {
173 MHD_gnutls_assert ();
174 return ret;
175 }
176 break;
177 default:
178 MHD_gnutls_assert ();
179 return GNUTLS_E_INTERNAL_ERROR;
180
181 }
182
183 /* Auth_info structures copied. Now copy MHD_gtls_security_param_st.
184 * packed_session must have allocated space for the security parameters.
185 */
186 ret = unpack_security_parameters (session, packed_session);
187 if (ret < 0)
188 {
189 MHD_gnutls_assert ();
190 return ret;
191 }
192
193 return 0;
194}
195
196
197/* Format:
198 * 1 byte the credentials type
199 * 4 bytes the size of the whole structure
200 * DH stuff
201 * 2 bytes the size of secret key in bits
202 * 4 bytes the size of the prime
203 * x bytes the prime
204 * 4 bytes the size of the generator
205 * x bytes the generator
206 * 4 bytes the size of the public key
207 * x bytes the public key
208 * RSA stuff
209 * 4 bytes the size of the modulus
210 * x bytes the modulus
211 * 4 bytes the size of the exponent
212 * x bytes the exponent
213 * CERTIFICATES
214 * 4 bytes the length of the certificate list
215 * 4 bytes the size of first certificate
216 * x bytes the certificate
217 * and so on...
218 */
219static int
220pack_certificate_auth_info (MHD_gtls_session_t session,
221 MHD_gnutls_datum_t * packed_session)
222{
223 unsigned int pos = 0, i;
224 int cert_size, pack_size;
225 cert_auth_info_t info = MHD_gtls_get_auth_info (session);
226
227 if (info)
228 {
229 cert_size = 4;
230
231 for (i = 0; i < info->ncerts; i++)
232 cert_size += 4 + info->raw_certificate_list[i].size;
233
234 pack_size = 2 + 4 + info->dh.prime.size +
235 4 + info->dh.generator.size + 4 + info->dh.public_key.size +
236 4 + info->rsa_export.modulus.size +
237 4 + info->rsa_export.exponent.size + cert_size;
238 }
239 else
240 pack_size = 0;
241
242 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
243
244 /* calculate the size and allocate the data.
245 */
246 packed_session->data =
247 MHD_gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
248
249 if (packed_session->data == NULL)
250 {
251 MHD_gnutls_assert ();
252 return GNUTLS_E_MEMORY_ERROR;
253 }
254
255 packed_session->data[0] = MHD_GNUTLS_CRD_CERTIFICATE;
256 MHD_gtls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
257 pos += 4 + PACK_HEADER_SIZE;
258
259
260 if (pack_size > 0)
261 {
262
263 MHD_gtls_write_uint16 (info->dh.secret_bits,
264 &packed_session->data[pos]);
265 pos += 2;
266
267 MHD_gtls_write_datum32 (&packed_session->data[pos], info->dh.prime);
268 pos += 4 + info->dh.prime.size;
269 MHD_gtls_write_datum32 (&packed_session->data[pos], info->dh.generator);
270 pos += 4 + info->dh.generator.size;
271 MHD_gtls_write_datum32 (&packed_session->data[pos],
272 info->dh.public_key);
273 pos += 4 + info->dh.public_key.size;
274
275 MHD_gtls_write_datum32 (&packed_session->data[pos],
276 info->rsa_export.modulus);
277 pos += 4 + info->rsa_export.modulus.size;
278 MHD_gtls_write_datum32 (&packed_session->data[pos],
279 info->rsa_export.exponent);
280 pos += 4 + info->rsa_export.exponent.size;
281
282 MHD_gtls_write_uint32 (info->ncerts, &packed_session->data[pos]);
283 pos += 4;
284
285 for (i = 0; i < info->ncerts; i++)
286 {
287 MHD_gtls_write_datum32 (&packed_session->data[pos],
288 info->raw_certificate_list[i]);
289 pos += sizeof (uint32_t) + info->raw_certificate_list[i].size;
290 }
291 }
292
293 return 0;
294}
295
296
297/* Upack certificate info.
298 */
299static int
300unpack_certificate_auth_info (MHD_gtls_session_t session,
301 const MHD_gnutls_datum_t * packed_session)
302{
303 int pos = 0, size, ret;
304 unsigned int i = 0, j;
305 size_t pack_size;
306 cert_auth_info_t info;
307
308 if (packed_session->data[0] != MHD_GNUTLS_CRD_CERTIFICATE)
309 {
310 MHD_gnutls_assert ();
311 return GNUTLS_E_INVALID_REQUEST;
312 }
313
314 pack_size = MHD_gtls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
315 pos += PACK_HEADER_SIZE + 4;
316
317 if (pack_size == 0)
318 return 0; /* nothing to be done */
319
320 /* a simple check for integrity */
321 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
322 {
323 MHD_gnutls_assert ();
324 return GNUTLS_E_INVALID_REQUEST;
325 }
326
327 /* client and server have the same auth_info here
328 */
329 ret =
330 MHD_gtls_auth_info_set (session, MHD_GNUTLS_CRD_CERTIFICATE,
331 sizeof (cert_auth_info_st), 1);
332 if (ret < 0)
333 {
334 MHD_gnutls_assert ();
335 return ret;
336 }
337
338 info = MHD_gtls_get_auth_info (session);
339 if (info == NULL)
340 {
341 MHD_gnutls_assert ();
342 return GNUTLS_E_INTERNAL_ERROR;
343 }
344
345 info->dh.secret_bits = MHD_gtls_read_uint16 (&packed_session->data[pos]);
346 pos += 2;
347
348 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
349 pos += 4;
350 ret =
351 MHD__gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
352 if (ret < 0)
353 {
354 MHD_gnutls_assert ();
355 goto error;
356 }
357 pos += size;
358
359 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
360 pos += 4;
361 ret =
362 MHD__gnutls_set_datum (&info->dh.generator, &packed_session->data[pos],
363 size);
364 if (ret < 0)
365 {
366 MHD_gnutls_assert ();
367 goto error;
368 }
369 pos += size;
370
371 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
372 pos += 4;
373 ret =
374 MHD__gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
375 size);
376 if (ret < 0)
377 {
378 MHD_gnutls_assert ();
379 goto error;
380 }
381 pos += size;
382
383 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
384 pos += 4;
385 ret =
386 MHD__gnutls_set_datum (&info->rsa_export.modulus,
387 &packed_session->data[pos], size);
388 if (ret < 0)
389 {
390 MHD_gnutls_assert ();
391 goto error;
392 }
393 pos += size;
394
395 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
396 pos += 4;
397 ret =
398 MHD__gnutls_set_datum (&info->rsa_export.exponent,
399 &packed_session->data[pos], size);
400 if (ret < 0)
401 {
402 MHD_gnutls_assert ();
403 goto error;
404 }
405 pos += size;
406
407 info->ncerts = MHD_gtls_read_uint32 (&packed_session->data[pos]);
408 pos += 4;
409
410 if (info->ncerts > 0)
411 {
412 info->raw_certificate_list =
413 MHD_gnutls_calloc (1, sizeof (MHD_gnutls_datum_t) * info->ncerts);
414 if (info->raw_certificate_list == NULL)
415 {
416 MHD_gnutls_assert ();
417 ret = GNUTLS_E_MEMORY_ERROR;
418 goto error;
419 }
420 }
421
422 for (i = 0; i < info->ncerts; i++)
423 {
424 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
425 pos += sizeof (uint32_t);
426
427 ret =
428 MHD__gnutls_set_datum (&info->raw_certificate_list[i],
429 &packed_session->data[pos], size);
430 pos += size;
431
432 if (ret < 0)
433 {
434 MHD_gnutls_assert ();
435 goto error;
436 }
437 }
438
439
440 return 0;
441
442error:
443 MHD__gnutls_free_datum (&info->dh.prime);
444 MHD__gnutls_free_datum (&info->dh.generator);
445 MHD__gnutls_free_datum (&info->dh.public_key);
446
447 MHD__gnutls_free_datum (&info->rsa_export.modulus);
448 MHD__gnutls_free_datum (&info->rsa_export.exponent);
449
450 for (j = 0; j < i; j++)
451 MHD__gnutls_free_datum (&info->raw_certificate_list[j]);
452
453 MHD_gnutls_free (info->raw_certificate_list);
454
455 return ret;
456
457}
458
459#ifdef ENABLE_SRP
460/* Packs the SRP session authentication data.
461 */
462
463/* Format:
464 * 1 byte the credentials type
465 * 4 bytes the size of the SRP username (x)
466 * x bytes the SRP username
467 */
468static int
469pack_srp_auth_info (MHD_gtls_session_t session,
470 MHD_gnutls_datum_t * packed_session)
471{
472 srp_server_auth_info_t info = MHD_gtls_get_auth_info (session);
473 int pack_size;
474
475 if (info && info->username)
476 pack_size = strlen (info->username) + 1; /* include the terminating null */
477 else
478 pack_size = 0;
479
480 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
481
482 /* calculate the size and allocate the data.
483 */
484 packed_session->data =
485 MHD_gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
486
487 if (packed_session->data == NULL)
488 {
489 MHD_gnutls_assert ();
490 return GNUTLS_E_MEMORY_ERROR;
491 }
492
493 packed_session->data[0] = MHD_GNUTLS_CRD_SRP;
494 MHD_gtls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
495
496 if (pack_size > 0)
497 memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
498 info->username, pack_size + 1);
499
500 return 0;
501}
502
503
504static int
505unpack_srp_auth_info (MHD_gtls_session_t session,
506 const MHD_gnutls_datum_t * packed_session)
507{
508 size_t username_size;
509 int ret;
510 srp_server_auth_info_t info;
511
512 if (packed_session->data[0] != MHD_GNUTLS_CRD_SRP)
513 {
514 MHD_gnutls_assert ();
515 return GNUTLS_E_INVALID_REQUEST;
516 }
517
518 username_size =
519 MHD_gtls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
520
521 if (username_size == 0)
522 return 0; /* nothing to be done */
523
524 /* a simple check for integrity */
525 if (username_size + 4 + PACK_HEADER_SIZE > packed_session->size)
526 {
527 MHD_gnutls_assert ();
528 return GNUTLS_E_INVALID_REQUEST;
529 }
530
531 ret =
532 MHD_gtls_auth_info_set (session, MHD_GNUTLS_CRD_SRP,
533 sizeof (srp_server_auth_info_st), 1);
534 if (ret < 0)
535 {
536 MHD_gnutls_assert ();
537 return ret;
538 }
539
540 info = MHD_gtls_get_auth_info (session);
541 if (info == NULL)
542 {
543 MHD_gnutls_assert ();
544 return GNUTLS_E_INTERNAL_ERROR;
545 }
546
547 memcpy (info->username,
548 &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
549 username_size);
550
551 return 0;
552}
553#endif
554
555
556
557#ifdef ENABLE_PSK
558/* Packs the PSK session authentication data.
559 */
560
561/* Format:
562 * 1 byte the credentials type
563 * 4 bytes the size of the whole structure
564 * 4 bytes the size of the PSK username (x)
565 * x bytes the PSK username
566 * 2 bytes the size of secret key in bits
567 * 4 bytes the size of the prime
568 * x bytes the prime
569 * 4 bytes the size of the generator
570 * x bytes the generator
571 * 4 bytes the size of the public key
572 * x bytes the public key
573 */
574static int
575pack_psk_auth_info (MHD_gtls_session_t session,
576 MHD_gnutls_datum_t * packed_session)
577{
578 psk_auth_info_t info;
579 int pack_size, username_size = 0, pos;
580
581 info = MHD_gtls_get_auth_info (session);
582
583 if (info)
584 {
585 username_size = strlen (info->username) + 1; /* include the terminating null */
586 pack_size = username_size +
587 2 + 4 * 3 + info->dh.prime.size + info->dh.generator.size +
588 info->dh.public_key.size;
589 }
590 else
591 pack_size = 0;
592
593 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
594
595 /* calculate the size and allocate the data.
596 */
597 packed_session->data =
598 MHD_gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
599
600 if (packed_session->data == NULL)
601 {
602 MHD_gnutls_assert ();
603 return GNUTLS_E_MEMORY_ERROR;
604 }
605
606 pos = 0;
607
608 packed_session->data[pos] = MHD_GNUTLS_CRD_PSK;
609 pos++;
610
611 MHD_gtls_write_uint32 (pack_size, &packed_session->data[pos]);
612 pos += 4;
613
614
615 if (pack_size > 0)
616 {
617 MHD_gtls_write_uint32 (username_size, &packed_session->data[pos]);
618 pos += 4;
619
620 memcpy (&packed_session->data[pos], info->username, username_size);
621 pos += username_size;
622
623 MHD_gtls_write_uint16 (info->dh.secret_bits,
624 &packed_session->data[pos]);
625 pos += 2;
626
627 MHD_gtls_write_datum32 (&packed_session->data[pos], info->dh.prime);
628 pos += 4 + info->dh.prime.size;
629 MHD_gtls_write_datum32 (&packed_session->data[pos], info->dh.generator);
630 pos += 4 + info->dh.generator.size;
631 MHD_gtls_write_datum32 (&packed_session->data[pos],
632 info->dh.public_key);
633 pos += 4 + info->dh.public_key.size;
634
635 }
636
637
638 return 0;
639}
640
641static int
642unpack_psk_auth_info (MHD_gtls_session_t session,
643 const MHD_gnutls_datum_t * packed_session)
644{
645 size_t username_size;
646 size_t pack_size;
647 int pos = 0, size, ret;
648 psk_auth_info_t info;
649
650 if (packed_session->data[0] != MHD_GNUTLS_CRD_PSK)
651 {
652 MHD_gnutls_assert ();
653 return GNUTLS_E_INVALID_REQUEST;
654 }
655
656 pack_size = MHD_gtls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
657 pos += PACK_HEADER_SIZE + 4;
658
659
660 if (pack_size == 0)
661 return 0; /* nothing to be done */
662
663 /* a simple check for integrity */
664 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
665 {
666 MHD_gnutls_assert ();
667 return GNUTLS_E_INVALID_REQUEST;
668 }
669
670 /* client and serer have the same auth_info here
671 */
672 ret =
673 MHD_gtls_auth_info_set (session, MHD_GNUTLS_CRD_PSK,
674 sizeof (psk_auth_info_st), 1);
675 if (ret < 0)
676 {
677 MHD_gnutls_assert ();
678 return ret;
679 }
680
681 info = MHD_gtls_get_auth_info (session);
682 if (info == NULL)
683 {
684 MHD_gnutls_assert ();
685 return GNUTLS_E_INTERNAL_ERROR;
686 }
687
688 username_size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
689 pos += 4;
690
691 memcpy (info->username, &packed_session->data[pos], username_size);
692 pos += username_size;
693
694 info->dh.secret_bits = MHD_gtls_read_uint16 (&packed_session->data[pos]);
695 pos += 2;
696
697 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
698 pos += 4;
699 ret =
700 MHD__gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
701 if (ret < 0)
702 {
703 MHD_gnutls_assert ();
704 goto error;
705 }
706 pos += size;
707
708 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
709 pos += 4;
710 ret =
711 MHD__gnutls_set_datum (&info->dh.generator, &packed_session->data[pos],
712 size);
713 if (ret < 0)
714 {
715 MHD_gnutls_assert ();
716 goto error;
717 }
718 pos += size;
719
720 size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
721 pos += 4;
722 ret =
723 MHD__gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
724 size);
725 if (ret < 0)
726 {
727 MHD_gnutls_assert ();
728 goto error;
729 }
730 pos += size;
731
732 return 0;
733
734error:
735 MHD__gnutls_free_datum (&info->dh.prime);
736 MHD__gnutls_free_datum (&info->dh.generator);
737 MHD__gnutls_free_datum (&info->dh.public_key);
738 return ret;
739}
740#endif
741
742
743/* Packs the security parameters.
744 */
745
746/* Format:
747 * 4 bytes the total security data size
748 * 1 byte the entity type (client/server)
749 * 1 byte the key exchange algorithm used
750 * 1 byte the read cipher algorithm
751 * 1 byte the read mac algorithm
752 * 1 byte the read compression algorithm
753 *
754 * 1 byte the write cipher algorithm
755 * 1 byte the write mac algorithm
756 * 1 byte the write compression algorithm
757 *
758 * 1 byte the certificate type
759 * 1 byte the protocol version
760 *
761 * 2 bytes the cipher suite
762 *
763 * 48 bytes the master secret
764 *
765 * 32 bytes the client random
766 * 32 bytes the server random
767 *
768 * 1 byte the session ID size
769 * x bytes the session ID (32 bytes max)
770 *
771 * 4 bytes a timestamp
772 * -------------------
773 * MAX: 165 bytes
774 *
775 * EXTENSIONS:
776 * 2 bytes the record send size
777 * 2 bytes the record recv size
778 *
779 * 1 byte the SRP username size
780 * x bytes the SRP username (MAX_SRP_USERNAME)
781 *
782 * 2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
783 * 1 byte the first name type
784 * 2 bytes the size of the first name
785 * x bytes the first name (MAX_SERVER_NAME_SIZE)
786 * and so on...
787 *
788 * --------------------
789 * MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
790 */
791static int
792pack_security_parameters (MHD_gtls_session_t session,
793 MHD_gnutls_datum_t * packed_session)
794{
795 int pos = 0;
796 size_t len, init, i;
797
798 /* move after the auth info stuff.
799 */
800 init =
801 MHD_gtls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
802 PACK_HEADER_SIZE;
803
804 pos = init + 4; /* make some space to write later the size */
805
806 packed_session->data[pos++] = session->security_parameters.entity;
807 packed_session->data[pos++] = session->security_parameters.kx_algorithm;
808 packed_session->data[pos++] =
809 session->security_parameters.read_bulk_cipher_algorithm;
810 packed_session->data[pos++] =
811 session->security_parameters.read_mac_algorithm;
812 packed_session->data[pos++] =
813 session->security_parameters.read_compression_algorithm;
814 packed_session->data[pos++] =
815 session->security_parameters.write_bulk_cipher_algorithm;
816 packed_session->data[pos++] =
817 session->security_parameters.write_mac_algorithm;
818 packed_session->data[pos++] =
819 session->security_parameters.write_compression_algorithm;
820 packed_session->data[pos++] =
821 session->security_parameters.current_cipher_suite.suite[0];
822 packed_session->data[pos++] =
823 session->security_parameters.current_cipher_suite.suite[1];
824
825 packed_session->data[pos++] = session->security_parameters.cert_type;
826 packed_session->data[pos++] = session->security_parameters.version;
827
828 memcpy (&packed_session->data[pos],
829 session->security_parameters.master_secret, TLS_MASTER_SIZE);
830 pos += TLS_MASTER_SIZE;
831
832 memcpy (&packed_session->data[pos],
833 session->security_parameters.client_random, TLS_RANDOM_SIZE);
834 pos += TLS_RANDOM_SIZE;
835 memcpy (&packed_session->data[pos],
836 session->security_parameters.server_random, TLS_RANDOM_SIZE);
837 pos += TLS_RANDOM_SIZE;
838
839 packed_session->data[pos++] = session->security_parameters.session_id_size;
840 memcpy (&packed_session->data[pos], session->security_parameters.session_id,
841 session->security_parameters.session_id_size);
842 pos += session->security_parameters.session_id_size;
843
844 MHD_gtls_write_uint32 (session->security_parameters.timestamp,
845 &packed_session->data[pos]);
846 pos += 4;
847
848 /* Extensions */
849 MHD_gtls_write_uint16 (session->security_parameters.max_record_send_size,
850 &packed_session->data[pos]);
851 pos += 2;
852
853 MHD_gtls_write_uint16 (session->security_parameters.max_record_recv_size,
854 &packed_session->data[pos]);
855 pos += 2;
856
857 /* SRP */
858 len =
859 strlen ((char *) session->security_parameters.extensions.srp_username);
860 packed_session->data[pos++] = len;
861 memcpy (&packed_session->data[pos],
862 session->security_parameters.extensions.srp_username, len);
863 pos += len;
864
865 MHD_gtls_write_uint16 (session->security_parameters.
866 extensions.server_names_size,
867 &packed_session->data[pos]);
868 pos += 2;
869
870 for (i = 0; i < session->security_parameters.extensions.server_names_size;
871 i++)
872 {
873 packed_session->data[pos++] =
874 session->security_parameters.extensions.server_names[i].type;
875 MHD_gtls_write_uint16 (session->security_parameters.
876 extensions.server_names[i].name_length,
877 &packed_session->data[pos]);
878 pos += 2;
879
880 memcpy (&packed_session->data[pos],
881 session->security_parameters.extensions.server_names[i].name,
882 session->security_parameters.extensions.
883 server_names[i].name_length);
884 pos +=
885 session->security_parameters.extensions.server_names[i].name_length;
886 }
887
888 /* write the total size */
889 MHD_gtls_write_uint32 (pos - init - 4, &packed_session->data[init]);
890 packed_session->size += pos - init;
891
892 return 0;
893}
894
895
896static int
897unpack_security_parameters (MHD_gtls_session_t session,
898 const MHD_gnutls_datum_t * packed_session)
899{
900 size_t pack_size, init, i;
901 int pos = 0, len;
902 time_t timestamp = time (0);
903
904
905 /* skip the auth info stuff */
906 init =
907 MHD_gtls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
908 PACK_HEADER_SIZE;
909
910 pos = init;
911
912 pack_size = MHD_gtls_read_uint32 (&packed_session->data[pos]);
913 pos += 4;
914
915
916 if (pack_size == 0)
917 return GNUTLS_E_INVALID_REQUEST;
918
919 /* a simple check for integrity */
920 if (pack_size > MAX_SEC_PARAMS)
921 {
922 MHD_gnutls_assert ();
923 return GNUTLS_E_INVALID_REQUEST;
924 }
925
926 session->internals.resumed_security_parameters.entity =
927 packed_session->data[pos++];
928 session->internals.resumed_security_parameters.kx_algorithm =
929 packed_session->data[pos++];
930 session->internals.resumed_security_parameters.read_bulk_cipher_algorithm =
931 packed_session->data[pos++];
932 session->internals.resumed_security_parameters.read_mac_algorithm =
933 packed_session->data[pos++];
934 session->internals.resumed_security_parameters.read_compression_algorithm =
935 packed_session->data[pos++];
936 session->internals.resumed_security_parameters.write_bulk_cipher_algorithm =
937 packed_session->data[pos++];
938 session->internals.resumed_security_parameters.write_mac_algorithm =
939 packed_session->data[pos++];
940 session->internals.resumed_security_parameters.write_compression_algorithm =
941 packed_session->data[pos++];
942 session->internals.resumed_security_parameters.
943 current_cipher_suite.suite[0] = packed_session->data[pos++];
944 session->internals.resumed_security_parameters.
945 current_cipher_suite.suite[1] = packed_session->data[pos++];
946
947 session->internals.resumed_security_parameters.cert_type =
948 packed_session->data[pos++];
949 session->internals.resumed_security_parameters.version =
950 packed_session->data[pos++];
951
952 memcpy (session->internals.resumed_security_parameters.master_secret,
953 &packed_session->data[pos], TLS_MASTER_SIZE);
954 pos += TLS_MASTER_SIZE;
955
956 memcpy (session->internals.resumed_security_parameters.client_random,
957 &packed_session->data[pos], TLS_RANDOM_SIZE);
958 pos += TLS_RANDOM_SIZE;
959 memcpy (session->internals.resumed_security_parameters.server_random,
960 &packed_session->data[pos], TLS_RANDOM_SIZE);
961 pos += TLS_RANDOM_SIZE;
962
963 session->internals.resumed_security_parameters.session_id_size =
964 packed_session->data[pos++];
965 memcpy (session->internals.resumed_security_parameters.session_id,
966 &packed_session->data[pos],
967 session->internals.resumed_security_parameters.session_id_size);
968 pos += session->internals.resumed_security_parameters.session_id_size;
969
970 session->internals.resumed_security_parameters.timestamp =
971 MHD_gtls_read_uint32 (&packed_session->data[pos]);
972 pos += 4;
973
974 if (timestamp - session->internals.resumed_security_parameters.timestamp >
975 session->internals.expire_time
976 || session->internals.resumed_security_parameters.timestamp > timestamp)
977 {
978 MHD_gnutls_assert ();
979 return GNUTLS_E_EXPIRED;
980 }
981
982 /* Extensions */
983 session->internals.resumed_security_parameters.max_record_send_size =
984 MHD_gtls_read_uint16 (&packed_session->data[pos]);
985 pos += 2;
986
987 session->internals.resumed_security_parameters.max_record_recv_size =
988 MHD_gtls_read_uint16 (&packed_session->data[pos]);
989 pos += 2;
990
991
992 /* SRP */
993 len = packed_session->data[pos++]; /* srp username length */
994 memcpy (session->internals.resumed_security_parameters.
995 extensions.srp_username, &packed_session->data[pos], len);
996 session->internals.resumed_security_parameters.
997 extensions.srp_username[len] = 0;
998 pos += len;
999
1000 session->internals.resumed_security_parameters.
1001 extensions.server_names_size =
1002 MHD_gtls_read_uint16 (&packed_session->data[pos]);
1003 pos += 2;
1004 for (i = 0;
1005 i <
1006 session->internals.resumed_security_parameters.
1007 extensions.server_names_size; i++)
1008 {
1009 session->internals.resumed_security_parameters.
1010 extensions.server_names[i].type = packed_session->data[pos++];
1011 session->internals.resumed_security_parameters.
1012 extensions.server_names[i].name_length =
1013 MHD_gtls_read_uint16 (&packed_session->data[pos]);
1014 pos += 2;
1015
1016 memcpy (session->internals.resumed_security_parameters.
1017 extensions.server_names[i].name, &packed_session->data[pos],
1018 session->internals.resumed_security_parameters.
1019 extensions.server_names[i].name_length);
1020 pos +=
1021 session->internals.resumed_security_parameters.
1022 extensions.server_names[i].name_length;
1023 }
1024 return 0;
1025}