2 * Copyright (C) 2000, 2004, 2005, 2007, 2008 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
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 (_gnutls_get_auth_info(session
) != 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
);
267 for (i
= 0; i
< info
->ncerts
; i
++)
268 cert_size
+= 4 + info
->raw_certificate_list
[i
].size
;
270 pack_size
= 2 + 4 + info
->dh
.prime
.size
+
271 4 + info
->dh
.generator
.size
+ 4 + info
->dh
.public_key
.size
+
272 4 + info
->rsa_export
.modulus
.size
+
273 4 + info
->rsa_export
.exponent
.size
+ cert_size
;
278 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
280 /* calculate the size and allocate the data.
282 packed_session
->data
=
283 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
285 if (packed_session
->data
== NULL
)
288 return GNUTLS_E_MEMORY_ERROR
;
291 packed_session
->data
[0] = GNUTLS_CRD_CERTIFICATE
;
292 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[PACK_HEADER_SIZE
]);
293 pos
+= 4 + PACK_HEADER_SIZE
;
299 _gnutls_write_uint16 (info
->dh
.secret_bits
, &packed_session
->data
[pos
]);
302 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.prime
);
303 pos
+= 4 + info
->dh
.prime
.size
;
304 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.generator
);
305 pos
+= 4 + info
->dh
.generator
.size
;
306 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.public_key
);
307 pos
+= 4 + info
->dh
.public_key
.size
;
309 _gnutls_write_datum32 (&packed_session
->data
[pos
],
310 info
->rsa_export
.modulus
);
311 pos
+= 4 + info
->rsa_export
.modulus
.size
;
312 _gnutls_write_datum32 (&packed_session
->data
[pos
],
313 info
->rsa_export
.exponent
);
314 pos
+= 4 + info
->rsa_export
.exponent
.size
;
316 _gnutls_write_uint32 (info
->ncerts
, &packed_session
->data
[pos
]);
319 for (i
= 0; i
< info
->ncerts
; i
++)
321 _gnutls_write_datum32 (&packed_session
->data
[pos
],
322 info
->raw_certificate_list
[i
]);
323 pos
+= sizeof (uint32_t) + info
->raw_certificate_list
[i
].size
;
331 /* Upack certificate info.
334 unpack_certificate_auth_info (gnutls_session_t session
,
335 const gnutls_datum_t
* packed_session
)
337 int pos
= 0, size
, ret
;
338 unsigned int i
= 0, j
;
340 cert_auth_info_t info
;
342 if (packed_session
->data
[0] != GNUTLS_CRD_CERTIFICATE
)
345 return GNUTLS_E_INVALID_REQUEST
;
348 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
349 pos
+= PACK_HEADER_SIZE
+ 4;
352 return 0; /* nothing to be done */
354 /* a simple check for integrity */
355 if (pack_size
+ PACK_HEADER_SIZE
+ 4 > packed_session
->size
)
358 return GNUTLS_E_INVALID_REQUEST
;
361 /* client and server have the same auth_info here
364 _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
365 sizeof (cert_auth_info_st
), 1);
372 info
= _gnutls_get_auth_info (session
);
376 return GNUTLS_E_INTERNAL_ERROR
;
379 info
->dh
.secret_bits
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
382 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
384 ret
= _gnutls_set_datum (&info
->dh
.prime
, &packed_session
->data
[pos
], size
);
392 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
395 _gnutls_set_datum (&info
->dh
.generator
, &packed_session
->data
[pos
], size
);
403 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
406 _gnutls_set_datum (&info
->dh
.public_key
, &packed_session
->data
[pos
],
415 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
418 _gnutls_set_datum (&info
->rsa_export
.modulus
,
419 &packed_session
->data
[pos
], size
);
427 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
430 _gnutls_set_datum (&info
->rsa_export
.exponent
,
431 &packed_session
->data
[pos
], size
);
439 info
->ncerts
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
442 if (info
->ncerts
> 0)
444 info
->raw_certificate_list
=
445 gnutls_calloc (1, sizeof (gnutls_datum_t
) * info
->ncerts
);
446 if (info
->raw_certificate_list
== NULL
)
449 ret
= GNUTLS_E_MEMORY_ERROR
;
454 for (i
= 0; i
< info
->ncerts
; i
++)
456 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
457 pos
+= sizeof (uint32_t);
460 _gnutls_set_datum (&info
->raw_certificate_list
[i
],
461 &packed_session
->data
[pos
], size
);
475 _gnutls_free_datum (&info
->dh
.prime
);
476 _gnutls_free_datum (&info
->dh
.generator
);
477 _gnutls_free_datum (&info
->dh
.public_key
);
479 _gnutls_free_datum (&info
->rsa_export
.modulus
);
480 _gnutls_free_datum (&info
->rsa_export
.exponent
);
482 for (j
= 0; j
< i
; j
++)
483 _gnutls_free_datum (&info
->raw_certificate_list
[j
]);
485 gnutls_free (info
->raw_certificate_list
);
492 /* Packs the SRP session authentication data.
496 * 1 byte the credentials type
497 * 4 bytes the size of the SRP username (x)
498 * x bytes the SRP username
501 pack_srp_auth_info (gnutls_session_t session
, gnutls_datum_t
* packed_session
)
503 srp_server_auth_info_t info
= _gnutls_get_auth_info (session
);
506 if (info
&& info
->username
)
507 pack_size
= strlen (info
->username
) + 1; /* include the terminating null */
511 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
513 /* calculate the size and allocate the data.
515 packed_session
->data
=
516 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
518 if (packed_session
->data
== NULL
)
521 return GNUTLS_E_MEMORY_ERROR
;
524 packed_session
->data
[0] = GNUTLS_CRD_SRP
;
525 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[PACK_HEADER_SIZE
]);
528 memcpy (&packed_session
->data
[PACK_HEADER_SIZE
+ sizeof (uint32_t)],
529 info
->username
, pack_size
+ 1);
536 unpack_srp_auth_info (gnutls_session_t session
,
537 const gnutls_datum_t
* packed_session
)
539 size_t username_size
;
541 srp_server_auth_info_t info
;
543 if (packed_session
->data
[0] != GNUTLS_CRD_SRP
)
546 return GNUTLS_E_INVALID_REQUEST
;
550 _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
552 if (username_size
== 0)
553 return 0; /* nothing to be done */
555 /* a simple check for integrity */
556 if (username_size
+ 4 + PACK_HEADER_SIZE
> packed_session
->size
)
559 return GNUTLS_E_INVALID_REQUEST
;
563 _gnutls_auth_info_set (session
, GNUTLS_CRD_SRP
,
564 sizeof (srp_server_auth_info_st
), 1);
571 info
= _gnutls_get_auth_info (session
);
575 return GNUTLS_E_INTERNAL_ERROR
;
578 memcpy (info
->username
,
579 &packed_session
->data
[PACK_HEADER_SIZE
+ sizeof (uint32_t)],
588 /* Packs the ANON session authentication data.
592 * 1 byte the credentials type
593 * 4 bytes the size of the whole structure
594 * 2 bytes the size of secret key in bits
595 * 4 bytes the size of the prime
597 * 4 bytes the size of the generator
598 * x bytes the generator
599 * 4 bytes the size of the public key
600 * x bytes the public key
603 pack_anon_auth_info (gnutls_session_t session
, gnutls_datum_t
* packed_session
)
605 anon_auth_info_t info
= _gnutls_get_auth_info (session
);
610 pack_size
= 2 + 4 * 3 + info
->dh
.prime
.size
+
611 info
->dh
.generator
.size
+ info
->dh
.public_key
.size
;
615 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
617 /* calculate the size and allocate the data.
619 packed_session
->data
=
620 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
622 if (packed_session
->data
== NULL
)
625 return GNUTLS_E_MEMORY_ERROR
;
628 packed_session
->data
[0] = GNUTLS_CRD_ANON
;
629 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[PACK_HEADER_SIZE
]);
630 pos
+= 4 + PACK_HEADER_SIZE
;
634 _gnutls_write_uint16 (info
->dh
.secret_bits
, &packed_session
->data
[pos
]);
637 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.prime
);
638 pos
+= 4 + info
->dh
.prime
.size
;
639 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.generator
);
640 pos
+= 4 + info
->dh
.generator
.size
;
641 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.public_key
);
642 pos
+= 4 + info
->dh
.public_key
.size
;
651 unpack_anon_auth_info (gnutls_session_t session
,
652 const gnutls_datum_t
* packed_session
)
655 int pos
= 0, size
, ret
;
656 anon_auth_info_t info
;
658 if (packed_session
->data
[0] != GNUTLS_CRD_ANON
)
661 return GNUTLS_E_INVALID_REQUEST
;
664 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
665 pos
+= PACK_HEADER_SIZE
+ 4;
669 return 0; /* nothing to be done */
671 /* a simple check for integrity */
672 if (pack_size
+ PACK_HEADER_SIZE
+ 4 > packed_session
->size
)
675 return GNUTLS_E_INVALID_REQUEST
;
678 /* client and serer have the same auth_info here
681 _gnutls_auth_info_set (session
, GNUTLS_CRD_ANON
,
682 sizeof (anon_auth_info_st
), 1);
689 info
= _gnutls_get_auth_info (session
);
693 return GNUTLS_E_INTERNAL_ERROR
;
696 info
->dh
.secret_bits
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
699 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
701 ret
= _gnutls_set_datum (&info
->dh
.prime
, &packed_session
->data
[pos
], size
);
709 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
712 _gnutls_set_datum (&info
->dh
.generator
, &packed_session
->data
[pos
], size
);
720 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
723 _gnutls_set_datum (&info
->dh
.public_key
, &packed_session
->data
[pos
],
735 _gnutls_free_datum (&info
->dh
.prime
);
736 _gnutls_free_datum (&info
->dh
.generator
);
737 _gnutls_free_datum (&info
->dh
.public_key
);
743 /* Packs the PSK session authentication data.
747 * 1 byte the credentials type
748 * 4 bytes the size of the whole structure
749 * 4 bytes the size of the PSK username (x)
750 * x bytes the PSK username
751 * 2 bytes the size of secret key in bits
752 * 4 bytes the size of the prime
754 * 4 bytes the size of the generator
755 * x bytes the generator
756 * 4 bytes the size of the public key
757 * x bytes the public key
760 pack_psk_auth_info (gnutls_session_t session
, gnutls_datum_t
* packed_session
)
762 psk_auth_info_t info
;
763 int pack_size
, username_size
= 0, hint_size
= 0, pos
;
765 info
= _gnutls_get_auth_info (session
);
769 username_size
= strlen (info
->username
) + 1; /* include the terminating null */
770 hint_size
= strlen (info
->hint
) + 1; /* include the terminating null */
771 pack_size
= username_size
+ hint_size
+
772 2 + 4 * 3 + info
->dh
.prime
.size
+ info
->dh
.generator
.size
+
773 info
->dh
.public_key
.size
;
778 packed_session
->size
= PACK_HEADER_SIZE
+ pack_size
+ sizeof (uint32_t);
780 /* calculate the size and allocate the data.
782 packed_session
->data
=
783 gnutls_malloc (packed_session
->size
+ MAX_SEC_PARAMS
);
785 if (packed_session
->data
== NULL
)
788 return GNUTLS_E_MEMORY_ERROR
;
793 packed_session
->data
[pos
] = GNUTLS_CRD_PSK
;
796 _gnutls_write_uint32 (pack_size
, &packed_session
->data
[pos
]);
802 _gnutls_write_uint32 (username_size
, &packed_session
->data
[pos
]);
805 memcpy (&packed_session
->data
[pos
], info
->username
, username_size
);
806 pos
+= username_size
;
808 _gnutls_write_uint32 (hint_size
, &packed_session
->data
[pos
]);
811 memcpy (&packed_session
->data
[pos
], info
->hint
, hint_size
);
814 _gnutls_write_uint16 (info
->dh
.secret_bits
, &packed_session
->data
[pos
]);
817 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.prime
);
818 pos
+= 4 + info
->dh
.prime
.size
;
819 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.generator
);
820 pos
+= 4 + info
->dh
.generator
.size
;
821 _gnutls_write_datum32 (&packed_session
->data
[pos
], info
->dh
.public_key
);
822 pos
+= 4 + info
->dh
.public_key
.size
;
830 unpack_psk_auth_info (gnutls_session_t session
,
831 const gnutls_datum_t
* packed_session
)
833 size_t username_size
, hint_size
;
835 int pos
= 0, size
, ret
;
836 psk_auth_info_t info
;
838 if (packed_session
->data
[0] != GNUTLS_CRD_PSK
)
841 return GNUTLS_E_INVALID_REQUEST
;
844 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]);
845 pos
+= PACK_HEADER_SIZE
+ 4;
849 return 0; /* nothing to be done */
851 /* a simple check for integrity */
852 if (pack_size
+ PACK_HEADER_SIZE
+ 4 > packed_session
->size
)
855 return GNUTLS_E_INVALID_REQUEST
;
858 /* client and serer have the same auth_info here
861 _gnutls_auth_info_set (session
, GNUTLS_CRD_PSK
,
862 sizeof (psk_auth_info_st
), 1);
869 info
= _gnutls_get_auth_info (session
);
873 return GNUTLS_E_INTERNAL_ERROR
;
876 username_size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
879 memcpy (info
->username
, &packed_session
->data
[pos
], username_size
);
880 pos
+= username_size
;
882 hint_size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
885 memcpy (info
->hint
, &packed_session
->data
[pos
], hint_size
);
888 info
->dh
.secret_bits
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
891 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
893 ret
= _gnutls_set_datum (&info
->dh
.prime
, &packed_session
->data
[pos
], size
);
901 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
904 _gnutls_set_datum (&info
->dh
.generator
, &packed_session
->data
[pos
], size
);
912 size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
915 _gnutls_set_datum (&info
->dh
.public_key
, &packed_session
->data
[pos
],
927 _gnutls_free_datum (&info
->dh
.prime
);
928 _gnutls_free_datum (&info
->dh
.generator
);
929 _gnutls_free_datum (&info
->dh
.public_key
);
935 /* Packs the security parameters.
939 * 4 bytes the total security data size
940 * 1 byte the entity type (client/server)
941 * 1 byte the key exchange algorithm used
942 * 1 byte the read cipher algorithm
943 * 1 byte the read mac algorithm
944 * 1 byte the read compression algorithm
946 * 1 byte the write cipher algorithm
947 * 1 byte the write mac algorithm
948 * 1 byte the write compression algorithm
950 * 1 byte the certificate type
951 * 1 byte the protocol version
953 * 2 bytes the cipher suite
955 * 48 bytes the master secret
957 * 32 bytes the client random
958 * 32 bytes the server random
960 * 1 byte the session ID size
961 * x bytes the session ID (32 bytes max)
963 * 4 bytes a timestamp
964 * -------------------
968 * 2 bytes the record send size
969 * 2 bytes the record recv size
971 * 1 byte the SRP username size
972 * x bytes the SRP username (MAX_SRP_USERNAME)
974 * 2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
975 * 1 byte the first name type
976 * 2 bytes the size of the first name
977 * x bytes the first name (MAX_SERVER_NAME_SIZE)
980 * --------------------
981 * MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
984 pack_security_parameters (gnutls_session_t session
,
985 gnutls_datum_t
* packed_session
)
990 /* move after the auth info stuff.
993 _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]) + 4 +
996 pos
= init
+ 4; /* make some space to write later the size */
998 packed_session
->data
[pos
++] = session
->security_parameters
.entity
;
999 packed_session
->data
[pos
++] = session
->security_parameters
.kx_algorithm
;
1000 packed_session
->data
[pos
++] =
1001 session
->security_parameters
.read_bulk_cipher_algorithm
;
1002 packed_session
->data
[pos
++] =
1003 session
->security_parameters
.read_mac_algorithm
;
1004 packed_session
->data
[pos
++] =
1005 session
->security_parameters
.read_compression_algorithm
;
1006 packed_session
->data
[pos
++] =
1007 session
->security_parameters
.write_bulk_cipher_algorithm
;
1008 packed_session
->data
[pos
++] =
1009 session
->security_parameters
.write_mac_algorithm
;
1010 packed_session
->data
[pos
++] =
1011 session
->security_parameters
.write_compression_algorithm
;
1012 packed_session
->data
[pos
++] =
1013 session
->security_parameters
.current_cipher_suite
.suite
[0];
1014 packed_session
->data
[pos
++] =
1015 session
->security_parameters
.current_cipher_suite
.suite
[1];
1017 packed_session
->data
[pos
++] = session
->security_parameters
.cert_type
;
1018 packed_session
->data
[pos
++] = session
->security_parameters
.version
;
1020 memcpy (&packed_session
->data
[pos
],
1021 session
->security_parameters
.master_secret
, TLS_MASTER_SIZE
);
1022 pos
+= TLS_MASTER_SIZE
;
1024 memcpy (&packed_session
->data
[pos
],
1025 session
->security_parameters
.client_random
, TLS_RANDOM_SIZE
);
1026 pos
+= TLS_RANDOM_SIZE
;
1027 memcpy (&packed_session
->data
[pos
],
1028 session
->security_parameters
.server_random
, TLS_RANDOM_SIZE
);
1029 pos
+= TLS_RANDOM_SIZE
;
1031 packed_session
->data
[pos
++] = session
->security_parameters
.session_id_size
;
1032 memcpy (&packed_session
->data
[pos
], session
->security_parameters
.session_id
,
1033 session
->security_parameters
.session_id_size
);
1034 pos
+= session
->security_parameters
.session_id_size
;
1036 _gnutls_write_uint32 (session
->security_parameters
.timestamp
,
1037 &packed_session
->data
[pos
]);
1041 _gnutls_write_uint16 (session
->security_parameters
.max_record_send_size
,
1042 &packed_session
->data
[pos
]);
1045 _gnutls_write_uint16 (session
->security_parameters
.max_record_recv_size
,
1046 &packed_session
->data
[pos
]);
1051 strlen ((char *) session
->security_parameters
.extensions
.srp_username
);
1052 packed_session
->data
[pos
++] = len
;
1053 memcpy (&packed_session
->data
[pos
],
1054 session
->security_parameters
.extensions
.srp_username
, len
);
1057 _gnutls_write_uint16 (session
->security_parameters
.extensions
.
1058 server_names_size
, &packed_session
->data
[pos
]);
1061 for (i
= 0; i
< session
->security_parameters
.extensions
.server_names_size
;
1064 packed_session
->data
[pos
++] =
1065 session
->security_parameters
.extensions
.server_names
[i
].type
;
1066 _gnutls_write_uint16 (session
->security_parameters
.extensions
.
1067 server_names
[i
].name_length
,
1068 &packed_session
->data
[pos
]);
1071 memcpy (&packed_session
->data
[pos
],
1072 session
->security_parameters
.extensions
.server_names
[i
].name
,
1073 session
->security_parameters
.extensions
.server_names
[i
].
1076 session
->security_parameters
.extensions
.server_names
[i
].name_length
;
1079 /* write the total size */
1080 _gnutls_write_uint32 (pos
- init
- 4, &packed_session
->data
[init
]);
1081 packed_session
->size
+= pos
- init
;
1088 unpack_security_parameters (gnutls_session_t session
,
1089 const gnutls_datum_t
* packed_session
)
1091 size_t pack_size
, init
, i
;
1093 time_t timestamp
= time (0);
1096 /* skip the auth info stuff */
1098 _gnutls_read_uint32 (&packed_session
->data
[PACK_HEADER_SIZE
]) + 4 +
1103 pack_size
= _gnutls_read_uint32 (&packed_session
->data
[pos
]);
1108 return GNUTLS_E_INVALID_REQUEST
;
1110 /* a simple check for integrity */
1111 if (pack_size
> MAX_SEC_PARAMS
)
1114 return GNUTLS_E_INVALID_REQUEST
;
1117 session
->internals
.resumed_security_parameters
.entity
=
1118 packed_session
->data
[pos
++];
1119 session
->internals
.resumed_security_parameters
.kx_algorithm
=
1120 packed_session
->data
[pos
++];
1121 session
->internals
.resumed_security_parameters
.read_bulk_cipher_algorithm
=
1122 packed_session
->data
[pos
++];
1123 session
->internals
.resumed_security_parameters
.read_mac_algorithm
=
1124 packed_session
->data
[pos
++];
1125 session
->internals
.resumed_security_parameters
.read_compression_algorithm
=
1126 packed_session
->data
[pos
++];
1127 session
->internals
.resumed_security_parameters
.write_bulk_cipher_algorithm
=
1128 packed_session
->data
[pos
++];
1129 session
->internals
.resumed_security_parameters
.write_mac_algorithm
=
1130 packed_session
->data
[pos
++];
1131 session
->internals
.resumed_security_parameters
.write_compression_algorithm
=
1132 packed_session
->data
[pos
++];
1133 session
->internals
.resumed_security_parameters
.current_cipher_suite
.
1134 suite
[0] = packed_session
->data
[pos
++];
1135 session
->internals
.resumed_security_parameters
.current_cipher_suite
.
1136 suite
[1] = packed_session
->data
[pos
++];
1138 session
->internals
.resumed_security_parameters
.cert_type
=
1139 packed_session
->data
[pos
++];
1140 session
->internals
.resumed_security_parameters
.version
=
1141 packed_session
->data
[pos
++];
1143 memcpy (session
->internals
.resumed_security_parameters
.master_secret
,
1144 &packed_session
->data
[pos
], TLS_MASTER_SIZE
);
1145 pos
+= TLS_MASTER_SIZE
;
1147 memcpy (session
->internals
.resumed_security_parameters
.client_random
,
1148 &packed_session
->data
[pos
], TLS_RANDOM_SIZE
);
1149 pos
+= TLS_RANDOM_SIZE
;
1150 memcpy (session
->internals
.resumed_security_parameters
.server_random
,
1151 &packed_session
->data
[pos
], TLS_RANDOM_SIZE
);
1152 pos
+= TLS_RANDOM_SIZE
;
1154 session
->internals
.resumed_security_parameters
.session_id_size
=
1155 packed_session
->data
[pos
++];
1156 memcpy (session
->internals
.resumed_security_parameters
.session_id
,
1157 &packed_session
->data
[pos
],
1158 session
->internals
.resumed_security_parameters
.session_id_size
);
1159 pos
+= session
->internals
.resumed_security_parameters
.session_id_size
;
1161 session
->internals
.resumed_security_parameters
.timestamp
=
1162 _gnutls_read_uint32 (&packed_session
->data
[pos
]);
1165 if (timestamp
- session
->internals
.resumed_security_parameters
.timestamp
>
1166 session
->internals
.expire_time
1167 || session
->internals
.resumed_security_parameters
.timestamp
> timestamp
)
1170 return GNUTLS_E_EXPIRED
;
1174 session
->internals
.resumed_security_parameters
.max_record_send_size
=
1175 _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1178 session
->internals
.resumed_security_parameters
.max_record_recv_size
=
1179 _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1184 len
= packed_session
->data
[pos
++]; /* srp username length */
1185 memcpy (session
->internals
.resumed_security_parameters
.extensions
.
1186 srp_username
, &packed_session
->data
[pos
], len
);
1187 session
->internals
.resumed_security_parameters
.extensions
.
1188 srp_username
[len
] = 0;
1191 session
->internals
.resumed_security_parameters
.extensions
.
1192 server_names_size
= _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1196 session
->internals
.resumed_security_parameters
.extensions
.
1197 server_names_size
; i
++)
1199 session
->internals
.resumed_security_parameters
.extensions
.
1200 server_names
[i
].type
= packed_session
->data
[pos
++];
1201 session
->internals
.resumed_security_parameters
.extensions
.
1202 server_names
[i
].name_length
=
1203 _gnutls_read_uint16 (&packed_session
->data
[pos
]);
1206 memcpy (session
->internals
.resumed_security_parameters
.extensions
.
1207 server_names
[i
].name
, &packed_session
->data
[pos
],
1208 session
->internals
.resumed_security_parameters
.extensions
.
1209 server_names
[i
].name_length
);
1211 session
->internals
.resumed_security_parameters
.extensions
.
1212 server_names
[i
].name_length
;