2 * Copyright (C) 2000, 2004, 2005, 2007 Free Software Foundation
4 * Author: Nikos Mavroyanopoulos
6 * This file is part of GNUTLS.
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.
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.
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,
25 /* Contains functions that are supposed to pack and unpack session data,
26 * before and after they are sent to the database backend.
29 #include <gnutls_int.h>
31 # include <auth_srp.h>
34 # include <auth_psk.h>
36 #include <auth_anon.h>
37 #include <auth_cert.h>
38 #include <gnutls_errors.h>
39 #include <gnutls_auth_int.h>
40 #include <gnutls_session_pack.h>
41 #include <gnutls_datum.h>
42 #include <gnutls_num.h>
44 #define PACK_HEADER_SIZE 1
45 #define MAX_SEC_PARAMS 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)+165
46 static int pack_certificate_auth_info (gnutls_session_t
,
47 gnutls_datum_t
* packed_session
);
48 static int unpack_certificate_auth_info (gnutls_session_t
,
49 const gnutls_datum_t
*
52 static int unpack_srp_auth_info (gnutls_session_t session
,
53 const gnutls_datum_t
* packed_session
);
54 static int pack_srp_auth_info (gnutls_session_t session
,
55 gnutls_datum_t
* packed_session
);
57 static int unpack_psk_auth_info (gnutls_session_t session
,
58 const gnutls_datum_t
* packed_session
);
59 static int pack_psk_auth_info (gnutls_session_t session
,
60 gnutls_datum_t
* packed_session
);
62 static int unpack_anon_auth_info (gnutls_session_t session
,
63 const gnutls_datum_t
* packed_session
);
64 static int pack_anon_auth_info (gnutls_session_t session
,
65 gnutls_datum_t
* packed_session
);
67 static int unpack_security_parameters (gnutls_session_t session
,
68 const gnutls_datum_t
* packed_session
);
69 static int pack_security_parameters (gnutls_session_t session
,
70 gnutls_datum_t
* packed_session
);
73 /* Since auth_info structures contain malloced data, this function
74 * is required in order to pack these structures in a vector in
75 * order to store them to the DB.
77 * packed_session will contain the session data.
79 * The data will be in a platform independent format.
82 _gnutls_session_pack (gnutls_session_t session
,
83 gnutls_datum_t
* packed_session
)
87 if (packed_session
== NULL
)
90 return GNUTLS_E_INTERNAL_ERROR
;
94 switch (gnutls_auth_get_type (session
))
98 ret
= pack_srp_auth_info (session
, packed_session
);
108 ret
= pack_psk_auth_info (session
, packed_session
);
117 case GNUTLS_CRD_ANON
:
118 ret
= pack_anon_auth_info (session
, packed_session
);
126 case GNUTLS_CRD_CERTIFICATE
:
127 ret
= pack_certificate_auth_info (session
, packed_session
);
135 return GNUTLS_E_INTERNAL_ERROR
;
139 /* Auth_info structures copied. Now copy security_parameters_st.
140 * packed_session must have allocated space for the security parameters.
142 ret
= pack_security_parameters (session
, packed_session
);
146 _gnutls_free_datum (packed_session
);
154 /* Load session data from a buffer.
157 _gnutls_session_unpack (gnutls_session_t session
,
158 const gnutls_datum_t
* packed_session
)
162 if (packed_session
== NULL
|| packed_session
->size
== 0)
165 return GNUTLS_E_INTERNAL_ERROR
;
168 if (session
->key
->auth_info
!= NULL
)
170 _gnutls_free_auth_info (session
);
173 switch (packed_session
->data
[0])
177 ret
= unpack_srp_auth_info (session
, packed_session
);
187 ret
= unpack_psk_auth_info (session
, packed_session
);
196 case GNUTLS_CRD_ANON
:
197 ret
= unpack_anon_auth_info (session
, packed_session
);
205 case GNUTLS_CRD_CERTIFICATE
:
206 ret
= unpack_certificate_auth_info (session
, packed_session
);
215 return GNUTLS_E_INTERNAL_ERROR
;
219 /* Auth_info structures copied. Now copy security_parameters_st.
220 * packed_session must have allocated space for the security parameters.
222 ret
= unpack_security_parameters (session
, packed_session
);
234 * 1 byte the credentials type
235 * 4 bytes the size of the whole structure
237 * 2 bytes the size of secret key in bits
238 * 4 bytes the size of the prime
240 * 4 bytes the size of the generator
241 * x bytes the generator
242 * 4 bytes the size of the public key
243 * x bytes the public key
245 * 4 bytes the size of the modulus
246 * x bytes the modulus
247 * 4 bytes the size of the exponent
248 * x bytes the exponent
250 * 4 bytes the length of the certificate list
251 * 4 bytes the size of first certificate
252 * x bytes the certificate
256 pack_certificate_auth_info (gnutls_session_t session
,
257 gnutls_datum_t
* packed_session
)
259 unsigned int pos
= 0, i
;
260 int cert_size
, pack_size
;
261 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
264 if (info
== NULL
&& session
->key
->auth_info_size
!= 0)
267 return GNUTLS_E_INVALID_REQUEST
;
274 for (i
= 0; i
< info
->ncerts
; i
++)
275 cert_size
+= 4 + info
->raw_certificate_list
[i
].size
;
277 pack_size
= 2 + 4 + info
->dh
.prime
.size
+
278 4 + info
->dh
.generator
.size
+ 4 + info
->dh
.public_key
.size
+
279 4 + info
->rsa_export
.modulus
.size
+
280 4 + info
->rsa_export
.exponent
.size
+ cert_size
;
285 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
287 /* calculate the size and allocate the data.
289 packed_session
->data
=
290 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
292 if (packed_session
->data
== NULL
)
295 return GNUTLS_E_MEMORY_ERROR
;
298 packed_session
->data
[0] = GNUTLS_CRD_CERTIFICATE
;
299 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[PACK_HEADER_SIZE
]);
300 pos
+= 4 + PACK_HEADER_SIZE
;
306 _gnutls_write_uint16 (info
->dh
.secret_bits
, &packed_session
->data
[pos
]);
309 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.prime
);
310 pos
+= 4 + info
->dh
.prime
.size
;
311 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.generator
);
312 pos
+= 4 + info
->dh
.generator
.size
;
313 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.public_key
);
314 pos
+= 4 + info
->dh
.public_key
.size
;
316 _gnutls_write_datum32 (&packed_session
->data
[pos
],
317 info
->rsa_export
.modulus
);
318 pos
+= 4 + info
->rsa_export
.modulus
.size
;
319 _gnutls_write_datum32 (&packed_session
->data
[pos
],
320 info
->rsa_export
.exponent
);
321 pos
+= 4 + info
->rsa_export
.exponent
.size
;
323 _gnutls_write_uint32 (info
->ncerts
, &packed_session
->data
[pos
]);
326 for (i
= 0; i
< info
->ncerts
; i
++)
328 _gnutls_write_datum32 (&packed_session
->data
[pos
],
329 info
->raw_certificate_list
[i
]);
330 pos
+= sizeof (uint32_t) + info
->raw_certificate_list
[i
].size
;
338 /* Upack certificate info.
341 unpack_certificate_auth_info (gnutls_session_t session
,
342 const gnutls_datum_t
* packed_session
)
344 int pos
= 0, size
, ret
;
345 unsigned int i
= 0, j
;
347 cert_auth_info_t info
;
349 if (packed_session
->data
[0] != GNUTLS_CRD_CERTIFICATE
)
352 return GNUTLS_E_INVALID_REQUEST
;
355 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
356 pos
+= PACK_HEADER_SIZE
+ 4;
359 return 0; /* nothing to be done */
361 /* a simple check for integrity */
362 if (pack_size
+ PACK_HEADER_SIZE
+ 4 > packed_session
->size
)
365 return GNUTLS_E_INVALID_REQUEST
;
368 /* client and server have the same auth_info here
371 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
372 sizeof (cert_auth_info_st
), 1);
379 info
= _gnutls_get_auth_info (session
);
383 return GNUTLS_E_INTERNAL_ERROR
;
386 info
->dh
.secret_bits
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
389 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
391 ret
= _gnutls_set_datum (&info
->dh
.prime
, &packed_session
->data
[pos
], size
);
399 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
402 _gnutls_set_datum (&info
->dh
.generator
, &packed_session
->data
[pos
], size
);
410 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
413 _gnutls_set_datum (&info
->dh
.public_key
, &packed_session
->data
[pos
],
422 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
425 _gnutls_set_datum (&info
->rsa_export
.modulus
,
426 &packed_session
->data
[pos
], size
);
434 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
437 _gnutls_set_datum (&info
->rsa_export
.exponent
,
438 &packed_session
->data
[pos
], size
);
446 info
->ncerts
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
449 if (info
->ncerts
> 0)
451 info
->raw_certificate_list
=
452 gnutls_calloc (1, sizeof (gnutls_datum_t
) * info
->ncerts
);
453 if (info
->raw_certificate_list
== NULL
)
456 ret
= GNUTLS_E_MEMORY_ERROR
;
461 for (i
= 0; i
< info
->ncerts
; i
++)
463 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
464 pos
+= sizeof (uint32_t);
467 _gnutls_set_datum (&info
->raw_certificate_list
[i
],
468 &packed_session
->data
[pos
], size
);
482 _gnutls_free_datum (&info
->dh
.prime
);
483 _gnutls_free_datum (&info
->dh
.generator
);
484 _gnutls_free_datum (&info
->dh
.public_key
);
486 _gnutls_free_datum (&info
->rsa_export
.modulus
);
487 _gnutls_free_datum (&info
->rsa_export
.exponent
);
489 for (j
= 0; j
< i
; j
++)
490 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
492 gnutls_free (info
->raw_certificate_list
);
499 /* Packs the SRP session authentication data.
503 * 1 byte the credentials type
504 * 4 bytes the size of the SRP username (x)
505 * x bytes the SRP username
508 pack_srp_auth_info (gnutls_session_t session
, gnutls_datum_t
* packed_session
)
510 srp_server_auth_info_t info
= _gnutls_get_auth_info (session
);
513 if (info
== NULL
&& session
->key
->auth_info_size
!= 0)
516 return GNUTLS_E_INVALID_REQUEST
;
519 if (info
&& info
->username
)
520 pack_size
= strlen (info
->username
) + 1; /* include the terminating null */
524 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
526 /* calculate the size and allocate the data.
528 packed_session
->data
=
529 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
531 if (packed_session
->data
== NULL
)
534 return GNUTLS_E_MEMORY_ERROR
;
537 packed_session
->data
[0] = GNUTLS_CRD_SRP
;
538 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[PACK_HEADER_SIZE
]);
541 memcpy (&packed_session
->data
[PACK_HEADER_SIZE
+ sizeof (uint32_t)],
542 info
->username
, pack_size
+ 1);
549 unpack_srp_auth_info (gnutls_session_t session
,
550 const gnutls_datum_t
* packed_session
)
552 size_t username_size
;
554 srp_server_auth_info_t info
;
556 if (packed_session
->data
[0] != GNUTLS_CRD_SRP
)
559 return GNUTLS_E_INVALID_REQUEST
;
563 _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
565 if (username_size
== 0)
566 return 0; /* nothing to be done */
568 /* a simple check for integrity */
569 if (username_size
+ 4 + PACK_HEADER_SIZE
> packed_session
->size
)
572 return GNUTLS_E_INVALID_REQUEST
;
576 _gnutls_auth_info_set (session
, GNUTLS_CRD_SRP
,
577 sizeof (srp_server_auth_info_st
), 1);
584 info
= _gnutls_get_auth_info (session
);
588 return GNUTLS_E_INTERNAL_ERROR
;
591 memcpy (info
->username
,
592 &packed_session
->data
[PACK_HEADER_SIZE
+ sizeof (uint32_t)],
601 /* Packs the ANON session authentication data.
605 * 1 byte the credentials type
606 * 4 bytes the size of the whole structure
607 * 2 bytes the size of secret key in bits
608 * 4 bytes the size of the prime
610 * 4 bytes the size of the generator
611 * x bytes the generator
612 * 4 bytes the size of the public key
613 * x bytes the public key
616 pack_anon_auth_info (gnutls_session_t session
, gnutls_datum_t
* packed_session
)
618 anon_auth_info_t info
= _gnutls_get_auth_info (session
);
622 if (info
== NULL
&& session
->key
->auth_info_size
!= 0)
625 return GNUTLS_E_INVALID_REQUEST
;
629 pack_size
= 2 + 4 * 3 + info
->dh
.prime
.size
+
630 info
->dh
.generator
.size
+ info
->dh
.public_key
.size
;
634 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
636 /* calculate the size and allocate the data.
638 packed_session
->data
=
639 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
641 if (packed_session
->data
== NULL
)
644 return GNUTLS_E_MEMORY_ERROR
;
647 packed_session
->data
[0] = GNUTLS_CRD_ANON
;
648 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[PACK_HEADER_SIZE
]);
649 pos
+= 4 + PACK_HEADER_SIZE
;
653 _gnutls_write_uint16 (info
->dh
.secret_bits
, &packed_session
->data
[pos
]);
656 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.prime
);
657 pos
+= 4 + info
->dh
.prime
.size
;
658 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.generator
);
659 pos
+= 4 + info
->dh
.generator
.size
;
660 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.public_key
);
661 pos
+= 4 + info
->dh
.public_key
.size
;
670 unpack_anon_auth_info (gnutls_session_t session
,
671 const gnutls_datum_t
* packed_session
)
674 int pos
= 0, size
, ret
;
675 anon_auth_info_t info
;
677 if (packed_session
->data
[0] != GNUTLS_CRD_ANON
)
680 return GNUTLS_E_INVALID_REQUEST
;
683 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
684 pos
+= PACK_HEADER_SIZE
+ 4;
688 return 0; /* nothing to be done */
690 /* a simple check for integrity */
691 if (pack_size
+ PACK_HEADER_SIZE
+ 4 > packed_session
->size
)
694 return GNUTLS_E_INVALID_REQUEST
;
697 /* client and serer have the same auth_info here
700 _gnutls_auth_info_set (session
, GNUTLS_CRD_ANON
,
701 sizeof (anon_auth_info_st
), 1);
708 info
= _gnutls_get_auth_info (session
);
712 return GNUTLS_E_INTERNAL_ERROR
;
715 info
->dh
.secret_bits
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
718 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
720 ret
= _gnutls_set_datum (&info
->dh
.prime
, &packed_session
->data
[pos
], size
);
728 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
731 _gnutls_set_datum (&info
->dh
.generator
, &packed_session
->data
[pos
], size
);
739 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
742 _gnutls_set_datum (&info
->dh
.public_key
, &packed_session
->data
[pos
],
754 _gnutls_free_datum (&info
->dh
.prime
);
755 _gnutls_free_datum (&info
->dh
.generator
);
756 _gnutls_free_datum (&info
->dh
.public_key
);
762 /* Packs the PSK session authentication data.
766 * 1 byte the credentials type
767 * 4 bytes the size of the whole structure
768 * 4 bytes the size of the PSK username (x)
769 * x bytes the PSK username
770 * 2 bytes the size of secret key in bits
771 * 4 bytes the size of the prime
773 * 4 bytes the size of the generator
774 * x bytes the generator
775 * 4 bytes the size of the public key
776 * x bytes the public key
779 pack_psk_auth_info (gnutls_session_t session
, gnutls_datum_t
* packed_session
)
781 psk_auth_info_t info
;
782 int pack_size
, username_size
= 0, pos
;
784 info
= _gnutls_get_auth_info (session
);
786 if (info
== NULL
&& session
->key
->auth_info_size
!= 0)
789 return GNUTLS_E_INVALID_REQUEST
;
794 username_size
= strlen (info
->username
) + 1; /* include the terminating null */
795 pack_size
= username_size
+
796 2 + 4 * 3 + info
->dh
.prime
.size
+ info
->dh
.generator
.size
+
797 info
->dh
.public_key
.size
;
802 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
804 /* calculate the size and allocate the data.
806 packed_session
->data
=
807 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
809 if (packed_session
->data
== NULL
)
812 return GNUTLS_E_MEMORY_ERROR
;
817 packed_session
->data
[pos
] = GNUTLS_CRD_PSK
;
820 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[pos
]);
826 _gnutls_write_uint32 (username_size
, &packed_session
->data
[pos
]);
829 memcpy (&packed_session
->data
[pos
], info
->username
, username_size
);
830 pos
+= username_size
;
832 _gnutls_write_uint16 (info
->dh
.secret_bits
, &packed_session
->data
[pos
]);
835 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.prime
);
836 pos
+= 4 + info
->dh
.prime
.size
;
837 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.generator
);
838 pos
+= 4 + info
->dh
.generator
.size
;
839 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.public_key
);
840 pos
+= 4 + info
->dh
.public_key
.size
;
849 unpack_psk_auth_info (gnutls_session_t session
,
850 const gnutls_datum_t
* packed_session
)
852 size_t username_size
;
854 int pos
= 0, size
, ret
;
855 psk_auth_info_t info
;
857 if (packed_session
->data
[0] != GNUTLS_CRD_PSK
)
860 return GNUTLS_E_INVALID_REQUEST
;
863 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
864 pos
+= PACK_HEADER_SIZE
+ 4;
868 return 0; /* nothing to be done */
870 /* a simple check for integrity */
871 if (pack_size
+ PACK_HEADER_SIZE
+ 4 > packed_session
->size
)
874 return GNUTLS_E_INVALID_REQUEST
;
877 /* client and serer have the same auth_info here
880 _gnutls_auth_info_set (session
, GNUTLS_CRD_PSK
,
881 sizeof (psk_auth_info_st
), 1);
888 info
= _gnutls_get_auth_info (session
);
892 return GNUTLS_E_INTERNAL_ERROR
;
895 username_size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
898 memcpy (info
->username
, &packed_session
->data
[pos
], username_size
);
899 pos
+= username_size
;
901 info
->dh
.secret_bits
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
904 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
906 ret
= _gnutls_set_datum (&info
->dh
.prime
, &packed_session
->data
[pos
], size
);
914 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
917 _gnutls_set_datum (&info
->dh
.generator
, &packed_session
->data
[pos
], size
);
925 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
928 _gnutls_set_datum (&info
->dh
.public_key
, &packed_session
->data
[pos
],
940 _gnutls_free_datum (&info
->dh
.prime
);
941 _gnutls_free_datum (&info
->dh
.generator
);
942 _gnutls_free_datum (&info
->dh
.public_key
);
948 /* Packs the security parameters.
952 * 4 bytes the total security data size
953 * 1 byte the entity type (client/server)
954 * 1 byte the key exchange algorithm used
955 * 1 byte the read cipher algorithm
956 * 1 byte the read mac algorithm
957 * 1 byte the read compression algorithm
959 * 1 byte the write cipher algorithm
960 * 1 byte the write mac algorithm
961 * 1 byte the write compression algorithm
963 * 1 byte the certificate type
964 * 1 byte the protocol version
966 * 2 bytes the cipher suite
968 * 48 bytes the master secret
970 * 32 bytes the client random
971 * 32 bytes the server random
973 * 1 byte the session ID size
974 * x bytes the session ID (32 bytes max)
976 * 4 bytes a timestamp
977 * -------------------
981 * 2 bytes the record send size
982 * 2 bytes the record recv size
984 * 1 byte the SRP username size
985 * x bytes the SRP username (MAX_SRP_USERNAME)
987 * 2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
988 * 1 byte the first name type
989 * 2 bytes the size of the first name
990 * x bytes the first name (MAX_SERVER_NAME_SIZE)
993 * --------------------
994 * MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
997 pack_security_parameters (gnutls_session_t session
,
998 gnutls_datum_t
* packed_session
)
1001 size_t len
, init
, i
;
1003 /* move after the auth info stuff.
1006 _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]) + 4 +
1009 pos
= init
+ 4; /* make some space to write later the size */
1011 packed_session
->data
[pos
++] = session
->security_parameters
.entity
;
1012 packed_session
->data
[pos
++] = session
->security_parameters
.kx_algorithm
;
1013 packed_session
->data
[pos
++] =
1014 session
->security_parameters
.read_bulk_cipher_algorithm
;
1015 packed_session
->data
[pos
++] =
1016 session
->security_parameters
.read_mac_algorithm
;
1017 packed_session
->data
[pos
++] =
1018 session
->security_parameters
.read_compression_algorithm
;
1019 packed_session
->data
[pos
++] =
1020 session
->security_parameters
.write_bulk_cipher_algorithm
;
1021 packed_session
->data
[pos
++] =
1022 session
->security_parameters
.write_mac_algorithm
;
1023 packed_session
->data
[pos
++] =
1024 session
->security_parameters
.write_compression_algorithm
;
1025 packed_session
->data
[pos
++] =
1026 session
->security_parameters
.current_cipher_suite
.suite
[0];
1027 packed_session
->data
[pos
++] =
1028 session
->security_parameters
.current_cipher_suite
.suite
[1];
1030 packed_session
->data
[pos
++] = session
->security_parameters
.cert_type
;
1031 packed_session
->data
[pos
++] = session
->security_parameters
.version
;
1033 memcpy (&packed_session
->data
[pos
],
1034 session
->security_parameters
.master_secret
, TLS_MASTER_SIZE
);
1035 pos
+= TLS_MASTER_SIZE
;
1037 memcpy (&packed_session
->data
[pos
],
1038 session
->security_parameters
.client_random
, TLS_RANDOM_SIZE
);
1039 pos
+= TLS_RANDOM_SIZE
;
1040 memcpy (&packed_session
->data
[pos
],
1041 session
->security_parameters
.server_random
, TLS_RANDOM_SIZE
);
1042 pos
+= TLS_RANDOM_SIZE
;
1044 packed_session
->data
[pos
++] = session
->security_parameters
.session_id_size
;
1045 memcpy (&packed_session
->data
[pos
], session
->security_parameters
.session_id
,
1046 session
->security_parameters
.session_id_size
);
1047 pos
+= session
->security_parameters
.session_id_size
;
1049 _gnutls_write_uint32 (session
->security_parameters
.timestamp
,
1050 &packed_session
->data
[pos
]);
1054 _gnutls_write_uint16 (session
->security_parameters
.max_record_send_size
,
1055 &packed_session
->data
[pos
]);
1058 _gnutls_write_uint16 (session
->security_parameters
.max_record_recv_size
,
1059 &packed_session
->data
[pos
]);
1064 strlen ((char *) session
->security_parameters
.extensions
.srp_username
);
1065 packed_session
->data
[pos
++] = len
;
1066 memcpy (&packed_session
->data
[pos
],
1067 session
->security_parameters
.extensions
.srp_username
, len
);
1070 _gnutls_write_uint16 (session
->security_parameters
.extensions
.
1071 server_names_size
, &packed_session
->data
[pos
]);
1074 for (i
= 0; i
< session
->security_parameters
.extensions
.server_names_size
;
1077 packed_session
->data
[pos
++] =
1078 session
->security_parameters
.extensions
.server_names
[i
].type
;
1079 _gnutls_write_uint16 (session
->security_parameters
.extensions
.
1080 server_names
[i
].name_length
,
1081 &packed_session
->data
[pos
]);
1084 memcpy (&packed_session
->data
[pos
],
1085 session
->security_parameters
.extensions
.server_names
[i
].name
,
1086 session
->security_parameters
.extensions
.server_names
[i
].
1089 session
->security_parameters
.extensions
.server_names
[i
].name_length
;
1092 /* write the total size */
1093 _gnutls_write_uint32 (pos
- init
- 4, &packed_session
->data
[init
]);
1094 packed_session
->size
+= pos
- init
;
1101 unpack_security_parameters (gnutls_session_t session
,
1102 const gnutls_datum_t
* packed_session
)
1104 size_t pack_size
, init
, i
;
1106 time_t timestamp
= time (0);
1109 /* skip the auth info stuff */
1111 _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]) + 4 +
1116 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
1121 return GNUTLS_E_INVALID_REQUEST
;
1123 /* a simple check for integrity */
1124 if (pack_size
> MAX_SEC_PARAMS
)
1127 return GNUTLS_E_INVALID_REQUEST
;
1130 session
->internals
.resumed_security_parameters
.entity
=
1131 packed_session
->data
[pos
++];
1132 session
->internals
.resumed_security_parameters
.kx_algorithm
=
1133 packed_session
->data
[pos
++];
1134 session
->internals
.resumed_security_parameters
.read_bulk_cipher_algorithm
=
1135 packed_session
->data
[pos
++];
1136 session
->internals
.resumed_security_parameters
.read_mac_algorithm
=
1137 packed_session
->data
[pos
++];
1138 session
->internals
.resumed_security_parameters
.read_compression_algorithm
=
1139 packed_session
->data
[pos
++];
1140 session
->internals
.resumed_security_parameters
.write_bulk_cipher_algorithm
=
1141 packed_session
->data
[pos
++];
1142 session
->internals
.resumed_security_parameters
.write_mac_algorithm
=
1143 packed_session
->data
[pos
++];
1144 session
->internals
.resumed_security_parameters
.write_compression_algorithm
=
1145 packed_session
->data
[pos
++];
1146 session
->internals
.resumed_security_parameters
.current_cipher_suite
.
1147 suite
[0] = packed_session
->data
[pos
++];
1148 session
->internals
.resumed_security_parameters
.current_cipher_suite
.
1149 suite
[1] = packed_session
->data
[pos
++];
1151 session
->internals
.resumed_security_parameters
.cert_type
=
1152 packed_session
->data
[pos
++];
1153 session
->internals
.resumed_security_parameters
.version
=
1154 packed_session
->data
[pos
++];
1156 memcpy (session
->internals
.resumed_security_parameters
.master_secret
,
1157 &packed_session
->data
[pos
], TLS_MASTER_SIZE
);
1158 pos
+= TLS_MASTER_SIZE
;
1160 memcpy (session
->internals
.resumed_security_parameters
.client_random
,
1161 &packed_session
->data
[pos
], TLS_RANDOM_SIZE
);
1162 pos
+= TLS_RANDOM_SIZE
;
1163 memcpy (session
->internals
.resumed_security_parameters
.server_random
,
1164 &packed_session
->data
[pos
], TLS_RANDOM_SIZE
);
1165 pos
+= TLS_RANDOM_SIZE
;
1167 session
->internals
.resumed_security_parameters
.session_id_size
=
1168 packed_session
->data
[pos
++];
1169 memcpy (session
->internals
.resumed_security_parameters
.session_id
,
1170 &packed_session
->data
[pos
],
1171 session
->internals
.resumed_security_parameters
.session_id_size
);
1172 pos
+= session
->internals
.resumed_security_parameters
.session_id_size
;
1174 session
->internals
.resumed_security_parameters
.timestamp
=
1175 _gnutls_read_uint32 (&packed_session
->data
[pos
]);
1178 if (timestamp
- session
->internals
.resumed_security_parameters
.timestamp
>
1179 session
->internals
.expire_time
1180 || session
->internals
.resumed_security_parameters
.timestamp
> timestamp
)
1183 return GNUTLS_E_EXPIRED
;
1187 session
->internals
.resumed_security_parameters
.max_record_send_size
=
1188 _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1191 session
->internals
.resumed_security_parameters
.max_record_recv_size
=
1192 _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1197 len
= packed_session
->data
[pos
++]; /* srp username length */
1198 memcpy (session
->internals
.resumed_security_parameters
.extensions
.
1199 srp_username
, &packed_session
->data
[pos
], len
);
1200 session
->internals
.resumed_security_parameters
.extensions
.
1201 srp_username
[len
] = 0;
1204 session
->internals
.resumed_security_parameters
.extensions
.
1205 server_names_size
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1209 session
->internals
.resumed_security_parameters
.extensions
.
1210 server_names_size
; i
++)
1212 session
->internals
.resumed_security_parameters
.extensions
.
1213 server_names
[i
].type
= packed_session
->data
[pos
++];
1214 session
->internals
.resumed_security_parameters
.extensions
.
1215 server_names
[i
].name_length
=
1216 _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1219 memcpy (session
->internals
.resumed_security_parameters
.extensions
.
1220 server_names
[i
].name
, &packed_session
->data
[pos
],
1221 session
->internals
.resumed_security_parameters
.extensions
.
1222 server_names
[i
].name_length
);
1224 session
->internals
.resumed_security_parameters
.extensions
.
1225 server_names
[i
].name_length
;