documented fix
[gnutls.git] / lib / gnutls_session_pack.c
blob16bdc23a4f7bec6125affcdc05ca50e12eb1a997
1 /*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Contains functions that are supposed to pack and unpack session data,
24 * before and after they are sent to the database backend.
27 #include <gnutls_int.h>
28 #ifdef ENABLE_SRP
29 #include <auth/srp.h>
30 #endif
31 #ifdef ENABLE_PSK
32 #include <auth/psk.h>
33 #endif
34 #include <auth/anon.h>
35 #include <auth/cert.h>
36 #include <gnutls_errors.h>
37 #include <gnutls_auth.h>
38 #include <gnutls_session_pack.h>
39 #include <gnutls_datum.h>
40 #include <gnutls_num.h>
41 #include <gnutls_extensions.h>
42 #include <gnutls_constate.h>
43 #include <algorithms.h>
45 static int pack_certificate_auth_info (gnutls_session_t,
46 gnutls_buffer_st * packed_session);
47 static int unpack_certificate_auth_info (gnutls_session_t,
48 gnutls_buffer_st * packed_session);
50 static int unpack_srp_auth_info (gnutls_session_t session,
51 gnutls_buffer_st * packed_session);
52 static int pack_srp_auth_info (gnutls_session_t session,
53 gnutls_buffer_st * packed_session);
55 static int unpack_psk_auth_info (gnutls_session_t session,
56 gnutls_buffer_st * packed_session);
57 static int pack_psk_auth_info (gnutls_session_t session,
58 gnutls_buffer_st * packed_session);
60 static int unpack_anon_auth_info (gnutls_session_t session,
61 gnutls_buffer_st * packed_session);
62 static int pack_anon_auth_info (gnutls_session_t session,
63 gnutls_buffer_st * packed_session);
65 static int unpack_security_parameters (gnutls_session_t session,
66 gnutls_buffer_st * packed_session);
67 static int pack_security_parameters (gnutls_session_t session,
68 gnutls_buffer_st * packed_session);
71 /* Since auth_info structures contain malloced data, this function
72 * is required in order to pack these structures in a vector in
73 * order to store them to the DB.
75 * packed_session will contain the session data.
77 * The data will be in a platform independent format.
79 int
80 _gnutls_session_pack (gnutls_session_t session,
81 gnutls_datum_t * packed_session)
83 int ret;
84 gnutls_buffer_st sb;
85 uint8_t id;
87 if (packed_session == NULL)
89 gnutls_assert ();
90 return GNUTLS_E_INTERNAL_ERROR;
93 _gnutls_buffer_init (&sb);
95 id = gnutls_auth_get_type (session);
96 BUFFER_APPEND (&sb, &id, 1);
98 switch (id)
100 #ifdef ENABLE_SRP
101 case GNUTLS_CRD_SRP:
102 ret = pack_srp_auth_info (session, &sb);
103 if (ret < 0)
105 gnutls_assert ();
106 goto fail;
108 break;
109 #endif
110 #ifdef ENABLE_PSK
111 case GNUTLS_CRD_PSK:
112 ret = pack_psk_auth_info (session, &sb);
113 if (ret < 0)
115 gnutls_assert ();
116 goto fail;
118 break;
119 #endif
120 #ifdef ENABLE_ANON
121 case GNUTLS_CRD_ANON:
122 ret = pack_anon_auth_info (session, &sb);
123 if (ret < 0)
125 gnutls_assert ();
126 goto fail;
128 break;
129 #endif
130 case GNUTLS_CRD_CERTIFICATE:
131 ret = pack_certificate_auth_info (session, &sb);
132 if (ret < 0)
134 gnutls_assert ();
135 goto fail;
137 break;
138 default:
139 return GNUTLS_E_INTERNAL_ERROR;
143 /* Auth_info structures copied. Now copy security_parameters_st.
144 * packed_session must have allocated space for the security parameters.
146 ret = pack_security_parameters (session, &sb);
147 if (ret < 0)
149 gnutls_assert ();
150 goto fail;
153 ret = _gnutls_ext_pack (session, &sb);
154 if (ret < 0)
156 gnutls_assert ();
157 goto fail;
160 return _gnutls_buffer_to_datum (&sb, packed_session);
162 fail:
163 _gnutls_buffer_clear (&sb);
164 return ret;
168 /* Load session data from a buffer.
171 _gnutls_session_unpack (gnutls_session_t session,
172 const gnutls_datum_t * packed_session)
174 int ret;
175 gnutls_buffer_st sb;
176 uint8_t id;
178 _gnutls_buffer_init (&sb);
180 if (packed_session == NULL || packed_session->size == 0)
182 gnutls_assert ();
183 return GNUTLS_E_INTERNAL_ERROR;
186 ret =
187 _gnutls_buffer_append_data (&sb, packed_session->data,
188 packed_session->size);
189 if (ret < 0)
191 gnutls_assert ();
192 return ret;
195 if (_gnutls_get_auth_info (session) != NULL)
197 _gnutls_free_auth_info (session);
200 BUFFER_POP (&sb, &id, 1);
202 switch (id)
204 #ifdef ENABLE_SRP
205 case GNUTLS_CRD_SRP:
206 ret = unpack_srp_auth_info (session, &sb);
207 if (ret < 0)
209 gnutls_assert ();
210 goto error;
212 break;
213 #endif
214 #ifdef ENABLE_PSK
215 case GNUTLS_CRD_PSK:
216 ret = unpack_psk_auth_info (session, &sb);
217 if (ret < 0)
219 gnutls_assert ();
220 goto error;
222 break;
223 #endif
224 #ifdef ENABLE_ANON
225 case GNUTLS_CRD_ANON:
226 ret = unpack_anon_auth_info (session, &sb);
227 if (ret < 0)
229 gnutls_assert ();
230 return ret;
232 break;
233 #endif
234 case GNUTLS_CRD_CERTIFICATE:
235 ret = unpack_certificate_auth_info (session, &sb);
236 if (ret < 0)
238 gnutls_assert ();
239 goto error;
241 break;
242 default:
243 gnutls_assert ();
244 ret = GNUTLS_E_INTERNAL_ERROR;
245 goto error;
249 /* Auth_info structures copied. Now copy security_parameters_st.
250 * packed_session must have allocated space for the security parameters.
252 ret = unpack_security_parameters (session, &sb);
253 if (ret < 0)
255 gnutls_assert ();
256 goto error;
259 ret = _gnutls_ext_unpack (session, &sb);
260 if (ret < 0)
262 gnutls_assert ();
263 goto error;
266 ret = 0;
268 error:
269 _gnutls_buffer_clear (&sb);
271 return ret;
276 /* Format:
277 * 1 byte the credentials type
278 * 4 bytes the size of the whole structure
279 * DH stuff
280 * 2 bytes the size of secret key in bits
281 * 4 bytes the size of the prime
282 * x bytes the prime
283 * 4 bytes the size of the generator
284 * x bytes the generator
285 * 4 bytes the size of the public key
286 * x bytes the public key
287 * RSA stuff
288 * 4 bytes the size of the modulus
289 * x bytes the modulus
290 * 4 bytes the size of the exponent
291 * x bytes the exponent
292 * CERTIFICATES
293 * 4 bytes the length of the certificate list
294 * 4 bytes the size of first certificate
295 * x bytes the certificate
296 * and so on...
298 static int
299 pack_certificate_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
301 unsigned int i;
302 int cur_size, ret;
303 cert_auth_info_t info = _gnutls_get_auth_info (session);
304 int size_offset;
306 size_offset = ps->length;
307 BUFFER_APPEND_NUM (ps, 0);
308 cur_size = ps->length;
310 if (info)
313 BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
314 BUFFER_APPEND_PFX4 (ps, info->dh.prime.data, info->dh.prime.size);
315 BUFFER_APPEND_PFX4 (ps, info->dh.generator.data,
316 info->dh.generator.size);
317 BUFFER_APPEND_PFX4 (ps, info->dh.public_key.data,
318 info->dh.public_key.size);
319 BUFFER_APPEND_PFX4 (ps, info->rsa_export.modulus.data,
320 info->rsa_export.modulus.size);
321 BUFFER_APPEND_PFX4 (ps, info->rsa_export.exponent.data,
322 info->rsa_export.exponent.size);
324 BUFFER_APPEND_NUM (ps, info->ncerts);
326 for (i = 0; i < info->ncerts; i++)
327 BUFFER_APPEND_PFX4 (ps, info->raw_certificate_list[i].data,
328 info->raw_certificate_list[i].size);
331 /* write the real size */
332 _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);
334 return 0;
338 /* Upack certificate info.
340 static int
341 unpack_certificate_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
343 int ret;
344 unsigned int i = 0, j = 0;
345 size_t pack_size;
346 cert_auth_info_t info = NULL;
348 BUFFER_POP_NUM (ps, pack_size);
350 if (pack_size == 0)
351 return 0; /* nothing to be done */
353 /* client and server have the same auth_info here
355 ret =
356 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
357 sizeof (cert_auth_info_st), 1);
358 if (ret < 0)
360 gnutls_assert ();
361 return ret;
364 info = _gnutls_get_auth_info (session);
365 if (info == NULL)
366 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
368 BUFFER_POP_NUM (ps, info->dh.secret_bits);
370 BUFFER_POP_DATUM (ps, &info->dh.prime);
371 BUFFER_POP_DATUM (ps, &info->dh.generator);
372 BUFFER_POP_DATUM (ps, &info->dh.public_key);
373 BUFFER_POP_DATUM (ps, &info->rsa_export.modulus);
374 BUFFER_POP_DATUM (ps, &info->rsa_export.exponent);
376 BUFFER_POP_NUM (ps, info->ncerts);
378 if (info->ncerts > 0)
380 info->raw_certificate_list =
381 gnutls_calloc (info->ncerts, sizeof (gnutls_datum_t));
382 if (info->raw_certificate_list == NULL)
384 gnutls_assert ();
385 ret = GNUTLS_E_MEMORY_ERROR;
386 goto error;
390 for (i = 0; i < info->ncerts; i++)
392 BUFFER_POP_DATUM (ps, &info->raw_certificate_list[i]);
395 return 0;
397 error:
398 if (info)
400 _gnutls_free_datum (&info->dh.prime);
401 _gnutls_free_datum (&info->dh.generator);
402 _gnutls_free_datum (&info->dh.public_key);
404 _gnutls_free_datum (&info->rsa_export.modulus);
405 _gnutls_free_datum (&info->rsa_export.exponent);
407 for (j = 0; j < i; j++)
408 _gnutls_free_datum (&info->raw_certificate_list[j]);
410 gnutls_free (info->raw_certificate_list);
413 return ret;
417 #ifdef ENABLE_SRP
418 /* Packs the SRP session authentication data.
421 /* Format:
422 * 1 byte the credentials type
423 * 4 bytes the size of the SRP username (x)
424 * x bytes the SRP username
426 static int
427 pack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
429 srp_server_auth_info_t info = _gnutls_get_auth_info (session);
430 int len, ret;
431 int size_offset;
432 size_t cur_size;
433 const char* username = NULL;
435 if (info && info->username)
437 username = info->username;
438 len = strlen (info->username) + 1; /* include the terminating null */
440 else
441 len = 0;
443 size_offset = ps->length;
444 BUFFER_APPEND_NUM (ps, 0);
445 cur_size = ps->length;
447 BUFFER_APPEND_PFX4 (ps, username, len);
449 /* write the real size */
450 _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);
452 return 0;
456 static int
457 unpack_srp_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
459 size_t username_size;
460 int ret;
461 srp_server_auth_info_t info;
463 BUFFER_POP_NUM (ps, username_size);
464 if (username_size > sizeof (info->username))
466 gnutls_assert ();
467 return GNUTLS_E_INTERNAL_ERROR;
470 ret =
471 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
472 sizeof (srp_server_auth_info_st), 1);
473 if (ret < 0)
475 gnutls_assert ();
476 return ret;
479 info = _gnutls_get_auth_info (session);
480 if (info == NULL)
481 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
483 BUFFER_POP (ps, info->username, username_size);
484 if (username_size == 0)
485 info->username[0] = 0;
487 ret = 0;
489 error:
490 return ret;
492 #endif
495 #ifdef ENABLE_ANON
496 /* Packs the ANON session authentication data.
499 /* Format:
500 * 1 byte the credentials type
501 * 4 bytes the size of the whole structure
502 * 2 bytes the size of secret key in bits
503 * 4 bytes the size of the prime
504 * x bytes the prime
505 * 4 bytes the size of the generator
506 * x bytes the generator
507 * 4 bytes the size of the public key
508 * x bytes the public key
510 static int
511 pack_anon_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
513 int cur_size, ret;
514 anon_auth_info_t info = _gnutls_get_auth_info (session);
515 int size_offset;
517 size_offset = ps->length;
518 BUFFER_APPEND_NUM (ps, 0);
519 cur_size = ps->length;
521 if (info)
523 BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
524 BUFFER_APPEND_PFX4 (ps, info->dh.prime.data, info->dh.prime.size);
525 BUFFER_APPEND_PFX4 (ps, info->dh.generator.data,
526 info->dh.generator.size);
527 BUFFER_APPEND_PFX4 (ps, info->dh.public_key.data,
528 info->dh.public_key.size);
531 /* write the real size */
532 _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);
534 return 0;
538 static int
539 unpack_anon_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
541 int ret;
542 size_t pack_size;
543 anon_auth_info_t info = NULL;
545 BUFFER_POP_NUM (ps, pack_size);
547 if (pack_size == 0)
548 return 0; /* nothing to be done */
550 /* client and server have the same auth_info here
552 ret =
553 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
554 sizeof (anon_auth_info_st), 1);
555 if (ret < 0)
557 gnutls_assert ();
558 return ret;
561 info = _gnutls_get_auth_info (session);
562 if (info == NULL)
563 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
565 BUFFER_POP_NUM (ps, info->dh.secret_bits);
567 BUFFER_POP_DATUM (ps, &info->dh.prime);
568 BUFFER_POP_DATUM (ps, &info->dh.generator);
569 BUFFER_POP_DATUM (ps, &info->dh.public_key);
571 return 0;
573 error:
574 if (info)
576 _gnutls_free_datum (&info->dh.prime);
577 _gnutls_free_datum (&info->dh.generator);
578 _gnutls_free_datum (&info->dh.public_key);
581 return ret;
583 #endif /* ANON */
585 #ifdef ENABLE_PSK
586 /* Packs the PSK session authentication data.
589 /* Format:
590 * 1 byte the credentials type
591 * 4 bytes the size of the whole structure
593 * 4 bytes the size of the PSK username (x)
594 * x bytes the PSK username
595 * 2 bytes the size of secret key in bits
596 * 4 bytes the size of the prime
597 * x bytes the prime
598 * 4 bytes the size of the generator
599 * x bytes the generator
600 * 4 bytes the size of the public key
601 * x bytes the public key
603 static int
604 pack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
606 psk_auth_info_t info;
607 int username_len;
608 int hint_len, ret;
609 int size_offset;
610 size_t cur_size;
612 info = _gnutls_get_auth_info (session);
613 if (info == NULL)
614 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
616 if (info->username)
617 username_len = strlen (info->username) + 1; /* include the terminating null */
618 else
619 username_len = 0;
621 if (info->hint)
622 hint_len = strlen (info->hint) + 1; /* include the terminating null */
623 else
624 hint_len = 0;
626 size_offset = ps->length;
627 BUFFER_APPEND_NUM (ps, 0);
628 cur_size = ps->length;
630 BUFFER_APPEND_PFX4 (ps, info->username, username_len);
631 BUFFER_APPEND_PFX4 (ps, info->hint, hint_len);
633 BUFFER_APPEND_NUM (ps, info->dh.secret_bits);
634 BUFFER_APPEND_PFX4 (ps, info->dh.prime.data, info->dh.prime.size);
635 BUFFER_APPEND_PFX4 (ps, info->dh.generator.data, info->dh.generator.size);
636 BUFFER_APPEND_PFX4 (ps, info->dh.public_key.data, info->dh.public_key.size);
638 /* write the real size */
639 _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);
641 return 0;
644 static int
645 unpack_psk_auth_info (gnutls_session_t session, gnutls_buffer_st * ps)
647 size_t username_size, hint_size;
648 int ret;
649 psk_auth_info_t info;
651 ret =
652 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
653 sizeof (psk_auth_info_st), 1);
654 if (ret < 0)
656 gnutls_assert ();
657 return ret;
660 info = _gnutls_get_auth_info (session);
661 if (info == NULL)
662 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
664 BUFFER_POP_NUM (ps, username_size);
665 if (username_size > sizeof (info->username))
667 gnutls_assert ();
668 return GNUTLS_E_INTERNAL_ERROR;
671 BUFFER_POP (ps, info->username, username_size);
673 BUFFER_POP_NUM (ps, hint_size);
674 if (hint_size > sizeof (info->hint))
676 gnutls_assert ();
677 return GNUTLS_E_INTERNAL_ERROR;
679 BUFFER_POP (ps, info->hint, hint_size);
681 BUFFER_POP_NUM (ps, info->dh.secret_bits);
683 BUFFER_POP_DATUM (ps, &info->dh.prime);
684 BUFFER_POP_DATUM (ps, &info->dh.generator);
685 BUFFER_POP_DATUM (ps, &info->dh.public_key);
687 ret = 0;
689 error:
690 _gnutls_free_datum (&info->dh.prime);
691 _gnutls_free_datum (&info->dh.generator);
692 _gnutls_free_datum (&info->dh.public_key);
694 return ret;
696 #endif
699 /* Packs the security parameters.
702 /* Format:
703 * 4 bytes the total security data size
704 * 1 byte the entity type (client/server)
705 * 1 byte the key exchange algorithm used
706 * 1 byte the read cipher algorithm
707 * 1 byte the read mac algorithm
708 * 1 byte the read compression algorithm
710 * 1 byte the write cipher algorithm
711 * 1 byte the write mac algorithm
712 * 1 byte the write compression algorithm
714 * 1 byte the certificate type
715 * 1 byte the protocol version
717 * 2 bytes the cipher suite
719 * 48 bytes the master secret
721 * 32 bytes the client random
722 * 32 bytes the server random
724 * 1 byte the session ID size
725 * x bytes the session ID (32 bytes max)
727 * 4 bytes a timestamp
728 * 4 bytes the ECC curve
729 * -------------------
730 * MAX: 169 bytes
733 static int
734 pack_security_parameters (gnutls_session_t session, gnutls_buffer_st * ps)
737 int ret;
738 int size_offset;
739 size_t cur_size;
740 record_parameters_st *params;
742 if (session->security_parameters.epoch_read
743 != session->security_parameters.epoch_write)
745 gnutls_assert ();
746 return GNUTLS_E_INVALID_REQUEST;
749 ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &params);
750 if (ret < 0)
752 gnutls_assert ();
753 return ret;
756 /* move after the auth info stuff.
758 size_offset = ps->length;
759 BUFFER_APPEND_NUM (ps, 0);
760 cur_size = ps->length;
763 BUFFER_APPEND_NUM (ps, session->security_parameters.entity);
764 BUFFER_APPEND_NUM (ps, session->security_parameters.kx_algorithm);
765 BUFFER_APPEND (ps,
766 session->security_parameters.cipher_suite, 2);
767 BUFFER_APPEND_NUM (ps, session->security_parameters.compression_method);
768 BUFFER_APPEND_NUM (ps, session->security_parameters.cert_type);
769 BUFFER_APPEND_NUM (ps, session->security_parameters.version);
771 BUFFER_APPEND (ps, session->security_parameters.master_secret,
772 GNUTLS_MASTER_SIZE);
773 BUFFER_APPEND (ps, session->security_parameters.client_random,
774 GNUTLS_RANDOM_SIZE);
775 BUFFER_APPEND (ps, session->security_parameters.server_random,
776 GNUTLS_RANDOM_SIZE);
778 BUFFER_APPEND_NUM (ps, session->security_parameters.session_id_size);
779 BUFFER_APPEND (ps, session->security_parameters.session_id,
780 session->security_parameters.session_id_size);
782 BUFFER_APPEND_NUM (ps, session->security_parameters.max_record_send_size);
783 BUFFER_APPEND_NUM (ps, session->security_parameters.max_record_recv_size);
784 BUFFER_APPEND_NUM (ps, session->security_parameters.timestamp);
785 BUFFER_APPEND_NUM (ps, session->security_parameters.ecc_curve);
787 _gnutls_write_uint32 (ps->length - cur_size, ps->data + size_offset);
789 return 0;
792 static int
793 unpack_security_parameters (gnutls_session_t session, gnutls_buffer_st * ps)
795 size_t pack_size;
796 int ret;
797 time_t timestamp = gnutls_time (0);
799 BUFFER_POP_NUM (ps, pack_size);
801 if (pack_size == 0)
802 return GNUTLS_E_INVALID_REQUEST;
804 memset (&session->internals.resumed_security_parameters, 0,
805 sizeof (session->internals.resumed_security_parameters));
807 BUFFER_POP_NUM (ps, session->internals.resumed_security_parameters.entity);
808 BUFFER_POP_NUM (ps,
809 session->internals.resumed_security_parameters.kx_algorithm);
810 BUFFER_POP (ps,
811 session->internals.
812 resumed_security_parameters.cipher_suite, 2);
813 BUFFER_POP_NUM (ps, session->internals.resumed_security_parameters.compression_method);
814 BUFFER_POP_NUM (ps, session->internals.resumed_security_parameters.cert_type);
815 BUFFER_POP_NUM (ps, session->internals.resumed_security_parameters.version);
817 BUFFER_POP (ps,
818 session->internals.resumed_security_parameters.master_secret,
819 GNUTLS_MASTER_SIZE);
821 BUFFER_POP (ps,
822 session->internals.resumed_security_parameters.client_random,
823 GNUTLS_RANDOM_SIZE);
824 BUFFER_POP (ps,
825 session->internals.resumed_security_parameters.server_random,
826 GNUTLS_RANDOM_SIZE);
827 BUFFER_POP_NUM (ps,
828 session->internals.
829 resumed_security_parameters.session_id_size);
831 BUFFER_POP (ps, session->internals.resumed_security_parameters.session_id,
832 session->internals.resumed_security_parameters.session_id_size);
834 BUFFER_POP_NUM (ps,
835 session->internals.
836 resumed_security_parameters.max_record_send_size);
837 BUFFER_POP_NUM (ps,
838 session->internals.
839 resumed_security_parameters.max_record_recv_size);
840 BUFFER_POP_NUM (ps,
841 session->internals.resumed_security_parameters.timestamp);
843 BUFFER_POP_NUM (ps,
844 session->internals.resumed_security_parameters.ecc_curve);
846 if (timestamp - session->internals.resumed_security_parameters.timestamp >
847 session->internals.expire_time
848 || session->internals.resumed_security_parameters.timestamp > timestamp)
850 gnutls_assert ();
851 return GNUTLS_E_EXPIRED;
854 ret = 0;
856 error:
857 return ret;
861 * gnutls_session_set_premaster:
862 * @session: is a #gnutls_session_t structure.
863 * @entity: GNUTLS_SERVER or GNUTLS_CLIENT
864 * @version: the TLS protocol version
865 * @kx: the key exchange method
866 * @cipher: the cipher
867 * @mac: the MAC algorithm
868 * @comp: the compression method
869 * @master: the master key to use
870 * @session_id: the session identifier
872 * This function sets the premaster secret in a session. This is
873 * a function intended for exceptional uses. Do not use this
874 * function unless you are implementing a legacy protocol.
875 * Use gnutls_session_set_data() instead.
877 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
878 * an error code is returned.
881 gnutls_session_set_premaster (gnutls_session_t session, unsigned int entity,
882 gnutls_protocol_t version,
883 gnutls_kx_algorithm_t kx,
884 gnutls_cipher_algorithm_t cipher,
885 gnutls_mac_algorithm_t mac,
886 gnutls_compression_method_t comp,
887 const gnutls_datum_t* master,
888 const gnutls_datum_t * session_id)
890 int ret;
892 memset (&session->internals.resumed_security_parameters, 0,
893 sizeof (session->internals.resumed_security_parameters));
895 session->internals.resumed_security_parameters.entity = entity;
896 session->internals.resumed_security_parameters.kx_algorithm = kx;
898 ret = _gnutls_cipher_suite_get_id(kx, cipher, mac, session->internals.resumed_security_parameters.cipher_suite);
899 if (ret < 0)
900 return gnutls_assert_val(ret);
902 session->internals.resumed_security_parameters.compression_method = comp;
903 session->internals.resumed_security_parameters.cert_type = GNUTLS_CRT_UNKNOWN;
904 session->internals.resumed_security_parameters.version = version;
906 if (master->size != GNUTLS_MASTER_SIZE)
907 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
909 memcpy(session->internals.resumed_security_parameters.master_secret, master->data, master->size);
911 if (session_id->size > GNUTLS_MAX_SESSION_ID)
912 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
914 session->internals.resumed_security_parameters.session_id_size = session_id->size;
915 memcpy(session->internals.resumed_security_parameters.session_id, session_id->data, session_id->size);
917 session->internals.resumed_security_parameters.max_record_send_size =
918 session->internals.resumed_security_parameters.max_record_recv_size = DEFAULT_MAX_RECORD_SIZE;
920 session->internals.resumed_security_parameters.timestamp = time(0);
922 session->internals.resumed_security_parameters.ecc_curve = GNUTLS_ECC_CURVE_INVALID;
924 session->internals.premaster_set = 1;
926 return 0;