Guile: Fix `x509-certificate-dn-oid' and related functions.
[gnutls.git] / lib / gnutls_session_pack.c
blob0dbdc13d160333306af70418a80abb3b8b68c0eb
1 /*
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,
21 * USA
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>
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_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 *
50 packed_session);
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.
81 int
82 _gnutls_session_pack (gnutls_session_t session,
83 gnutls_datum_t * packed_session)
85 int ret;
87 if (packed_session == NULL)
89 gnutls_assert ();
90 return GNUTLS_E_INTERNAL_ERROR;
94 switch (gnutls_auth_get_type (session))
96 #ifdef ENABLE_SRP
97 case GNUTLS_CRD_SRP:
98 ret = pack_srp_auth_info (session, packed_session);
99 if (ret < 0)
101 gnutls_assert ();
102 return ret;
104 break;
105 #endif
106 #ifdef ENABLE_PSK
107 case GNUTLS_CRD_PSK:
108 ret = pack_psk_auth_info (session, packed_session);
109 if (ret < 0)
111 gnutls_assert ();
112 return ret;
114 break;
115 #endif
116 #ifdef ENABLE_ANON
117 case GNUTLS_CRD_ANON:
118 ret = pack_anon_auth_info (session, packed_session);
119 if (ret < 0)
121 gnutls_assert ();
122 return ret;
124 break;
125 #endif
126 case GNUTLS_CRD_CERTIFICATE:
127 ret = pack_certificate_auth_info (session, packed_session);
128 if (ret < 0)
130 gnutls_assert ();
131 return ret;
133 break;
134 default:
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);
143 if (ret < 0)
145 gnutls_assert ();
146 _gnutls_free_datum (packed_session);
147 return ret;
150 return 0;
154 /* Load session data from a buffer.
157 _gnutls_session_unpack (gnutls_session_t session,
158 const gnutls_datum_t * packed_session)
160 int ret;
162 if (packed_session == NULL || packed_session->size == 0)
164 gnutls_assert ();
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])
175 #ifdef ENABLE_SRP
176 case GNUTLS_CRD_SRP:
177 ret = unpack_srp_auth_info (session, packed_session);
178 if (ret < 0)
180 gnutls_assert ();
181 return ret;
183 break;
184 #endif
185 #ifdef ENABLE_PSK
186 case GNUTLS_CRD_PSK:
187 ret = unpack_psk_auth_info (session, packed_session);
188 if (ret < 0)
190 gnutls_assert ();
191 return ret;
193 break;
194 #endif
195 #ifdef ENABLE_ANON
196 case GNUTLS_CRD_ANON:
197 ret = unpack_anon_auth_info (session, packed_session);
198 if (ret < 0)
200 gnutls_assert ();
201 return ret;
203 break;
204 #endif
205 case GNUTLS_CRD_CERTIFICATE:
206 ret = unpack_certificate_auth_info (session, packed_session);
207 if (ret < 0)
209 gnutls_assert ();
210 return ret;
212 break;
213 default:
214 gnutls_assert ();
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);
223 if (ret < 0)
225 gnutls_assert ();
226 return ret;
229 return 0;
233 /* Format:
234 * 1 byte the credentials type
235 * 4 bytes the size of the whole structure
236 * DH stuff
237 * 2 bytes the size of secret key in bits
238 * 4 bytes the size of the prime
239 * x bytes 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
244 * RSA stuff
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
249 * CERTIFICATES
250 * 4 bytes the length of the certificate list
251 * 4 bytes the size of first certificate
252 * x bytes the certificate
253 * and so on...
255 static int
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)
266 gnutls_assert ();
267 return GNUTLS_E_INVALID_REQUEST;
270 if (info)
272 cert_size = 4;
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;
282 else
283 pack_size = 0;
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)
294 gnutls_assert ();
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;
303 if (pack_size > 0)
306 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
307 pos += 2;
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]);
324 pos += 4;
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;
334 return 0;
338 /* Upack certificate info.
340 static int
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;
346 size_t pack_size;
347 cert_auth_info_t info;
349 if (packed_session->data[0] != GNUTLS_CRD_CERTIFICATE)
351 gnutls_assert ();
352 return GNUTLS_E_INVALID_REQUEST;
355 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
356 pos += PACK_HEADER_SIZE + 4;
358 if (pack_size == 0)
359 return 0; /* nothing to be done */
361 /* a simple check for integrity */
362 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
364 gnutls_assert ();
365 return GNUTLS_E_INVALID_REQUEST;
368 /* client and server have the same auth_info here
370 ret =
371 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
372 sizeof (cert_auth_info_st), 1);
373 if (ret < 0)
375 gnutls_assert ();
376 return ret;
379 info = _gnutls_get_auth_info (session);
380 if (info == NULL)
382 gnutls_assert ();
383 return GNUTLS_E_INTERNAL_ERROR;
386 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
387 pos += 2;
389 size = _gnutls_read_uint32 (&packed_session->data[pos]);
390 pos += 4;
391 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
392 if (ret < 0)
394 gnutls_assert ();
395 goto error;
397 pos += size;
399 size = _gnutls_read_uint32 (&packed_session->data[pos]);
400 pos += 4;
401 ret =
402 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
403 if (ret < 0)
405 gnutls_assert ();
406 goto error;
408 pos += size;
410 size = _gnutls_read_uint32 (&packed_session->data[pos]);
411 pos += 4;
412 ret =
413 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
414 size);
415 if (ret < 0)
417 gnutls_assert ();
418 goto error;
420 pos += size;
422 size = _gnutls_read_uint32 (&packed_session->data[pos]);
423 pos += 4;
424 ret =
425 _gnutls_set_datum (&info->rsa_export.modulus,
426 &packed_session->data[pos], size);
427 if (ret < 0)
429 gnutls_assert ();
430 goto error;
432 pos += size;
434 size = _gnutls_read_uint32 (&packed_session->data[pos]);
435 pos += 4;
436 ret =
437 _gnutls_set_datum (&info->rsa_export.exponent,
438 &packed_session->data[pos], size);
439 if (ret < 0)
441 gnutls_assert ();
442 goto error;
444 pos += size;
446 info->ncerts = _gnutls_read_uint32 (&packed_session->data[pos]);
447 pos += 4;
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)
455 gnutls_assert ();
456 ret = GNUTLS_E_MEMORY_ERROR;
457 goto error;
461 for (i = 0; i < info->ncerts; i++)
463 size = _gnutls_read_uint32 (&packed_session->data[pos]);
464 pos += sizeof (uint32_t);
466 ret =
467 _gnutls_set_datum (&info->raw_certificate_list[i],
468 &packed_session->data[pos], size);
469 pos += size;
471 if (ret < 0)
473 gnutls_assert ();
474 goto error;
479 return 0;
481 error:
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);
494 return ret;
498 #ifdef ENABLE_SRP
499 /* Packs the SRP session authentication data.
502 /* Format:
503 * 1 byte the credentials type
504 * 4 bytes the size of the SRP username (x)
505 * x bytes the SRP username
507 static int
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);
511 int pack_size;
513 if (info == NULL && session->key->auth_info_size != 0)
515 gnutls_assert ();
516 return GNUTLS_E_INVALID_REQUEST;
519 if (info && info->username)
520 pack_size = strlen (info->username) + 1; /* include the terminating null */
521 else
522 pack_size = 0;
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)
533 gnutls_assert ();
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]);
540 if (pack_size > 0)
541 memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
542 info->username, pack_size + 1);
544 return 0;
548 static int
549 unpack_srp_auth_info (gnutls_session_t session,
550 const gnutls_datum_t * packed_session)
552 size_t username_size;
553 int ret;
554 srp_server_auth_info_t info;
556 if (packed_session->data[0] != GNUTLS_CRD_SRP)
558 gnutls_assert ();
559 return GNUTLS_E_INVALID_REQUEST;
562 username_size =
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)
571 gnutls_assert ();
572 return GNUTLS_E_INVALID_REQUEST;
575 ret =
576 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
577 sizeof (srp_server_auth_info_st), 1);
578 if (ret < 0)
580 gnutls_assert ();
581 return ret;
584 info = _gnutls_get_auth_info (session);
585 if (info == NULL)
587 gnutls_assert ();
588 return GNUTLS_E_INTERNAL_ERROR;
591 memcpy (info->username,
592 &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
593 username_size);
595 return 0;
597 #endif
600 #ifdef ENABLE_ANON
601 /* Packs the ANON session authentication data.
604 /* Format:
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
609 * x bytes 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
615 static int
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);
619 int pos = 0;
620 size_t pack_size;
622 if (info == NULL && session->key->auth_info_size != 0)
624 gnutls_assert ();
625 return GNUTLS_E_INVALID_REQUEST;
628 if (info)
629 pack_size = 2 + 4 * 3 + info->dh.prime.size +
630 info->dh.generator.size + info->dh.public_key.size;
631 else
632 pack_size = 0;
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)
643 gnutls_assert ();
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;
651 if (pack_size > 0)
653 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
654 pos += 2;
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;
665 return 0;
669 static int
670 unpack_anon_auth_info (gnutls_session_t session,
671 const gnutls_datum_t * packed_session)
673 size_t pack_size;
674 int pos = 0, size, ret;
675 anon_auth_info_t info;
677 if (packed_session->data[0] != GNUTLS_CRD_ANON)
679 gnutls_assert ();
680 return GNUTLS_E_INVALID_REQUEST;
683 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
684 pos += PACK_HEADER_SIZE + 4;
687 if (pack_size == 0)
688 return 0; /* nothing to be done */
690 /* a simple check for integrity */
691 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
693 gnutls_assert ();
694 return GNUTLS_E_INVALID_REQUEST;
697 /* client and serer have the same auth_info here
699 ret =
700 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
701 sizeof (anon_auth_info_st), 1);
702 if (ret < 0)
704 gnutls_assert ();
705 return ret;
708 info = _gnutls_get_auth_info (session);
709 if (info == NULL)
711 gnutls_assert ();
712 return GNUTLS_E_INTERNAL_ERROR;
715 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
716 pos += 2;
718 size = _gnutls_read_uint32 (&packed_session->data[pos]);
719 pos += 4;
720 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
721 if (ret < 0)
723 gnutls_assert ();
724 goto error;
726 pos += size;
728 size = _gnutls_read_uint32 (&packed_session->data[pos]);
729 pos += 4;
730 ret =
731 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
732 if (ret < 0)
734 gnutls_assert ();
735 goto error;
737 pos += size;
739 size = _gnutls_read_uint32 (&packed_session->data[pos]);
740 pos += 4;
741 ret =
742 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
743 size);
744 if (ret < 0)
746 gnutls_assert ();
747 goto error;
749 pos += size;
751 return 0;
753 error:
754 _gnutls_free_datum (&info->dh.prime);
755 _gnutls_free_datum (&info->dh.generator);
756 _gnutls_free_datum (&info->dh.public_key);
757 return ret;
759 #endif /* ANON */
761 #ifdef ENABLE_PSK
762 /* Packs the PSK session authentication data.
765 /* Format:
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
772 * x bytes 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
778 static int
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)
788 gnutls_assert ();
789 return GNUTLS_E_INVALID_REQUEST;
792 if (info)
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;
799 else
800 pack_size = 0;
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)
811 gnutls_assert ();
812 return GNUTLS_E_MEMORY_ERROR;
815 pos = 0;
817 packed_session->data[pos] = GNUTLS_CRD_PSK;
818 pos++;
820 _gnutls_write_uint32 (pack_size, &packed_session->data[pos]);
821 pos += 4;
824 if (pack_size > 0)
826 _gnutls_write_uint32 (username_size, &packed_session->data[pos]);
827 pos += 4;
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]);
833 pos += 2;
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;
845 return 0;
848 static int
849 unpack_psk_auth_info (gnutls_session_t session,
850 const gnutls_datum_t * packed_session)
852 size_t username_size;
853 size_t pack_size;
854 int pos = 0, size, ret;
855 psk_auth_info_t info;
857 if (packed_session->data[0] != GNUTLS_CRD_PSK)
859 gnutls_assert ();
860 return GNUTLS_E_INVALID_REQUEST;
863 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
864 pos += PACK_HEADER_SIZE + 4;
867 if (pack_size == 0)
868 return 0; /* nothing to be done */
870 /* a simple check for integrity */
871 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
873 gnutls_assert ();
874 return GNUTLS_E_INVALID_REQUEST;
877 /* client and serer have the same auth_info here
879 ret =
880 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
881 sizeof (psk_auth_info_st), 1);
882 if (ret < 0)
884 gnutls_assert ();
885 return ret;
888 info = _gnutls_get_auth_info (session);
889 if (info == NULL)
891 gnutls_assert ();
892 return GNUTLS_E_INTERNAL_ERROR;
895 username_size = _gnutls_read_uint32 (&packed_session->data[pos]);
896 pos += 4;
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]);
902 pos += 2;
904 size = _gnutls_read_uint32 (&packed_session->data[pos]);
905 pos += 4;
906 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
907 if (ret < 0)
909 gnutls_assert ();
910 goto error;
912 pos += size;
914 size = _gnutls_read_uint32 (&packed_session->data[pos]);
915 pos += 4;
916 ret =
917 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
918 if (ret < 0)
920 gnutls_assert ();
921 goto error;
923 pos += size;
925 size = _gnutls_read_uint32 (&packed_session->data[pos]);
926 pos += 4;
927 ret =
928 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
929 size);
930 if (ret < 0)
932 gnutls_assert ();
933 goto error;
935 pos += size;
937 return 0;
939 error:
940 _gnutls_free_datum (&info->dh.prime);
941 _gnutls_free_datum (&info->dh.generator);
942 _gnutls_free_datum (&info->dh.public_key);
943 return ret;
945 #endif
948 /* Packs the security parameters.
951 /* Format:
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 * -------------------
978 * MAX: 165 bytes
980 * EXTENSIONS:
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)
991 * and so on...
993 * --------------------
994 * MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
996 static int
997 pack_security_parameters (gnutls_session_t session,
998 gnutls_datum_t * packed_session)
1000 int pos = 0;
1001 size_t len, init, i;
1003 /* move after the auth info stuff.
1005 init =
1006 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
1007 PACK_HEADER_SIZE;
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]);
1051 pos += 4;
1053 /* Extensions */
1054 _gnutls_write_uint16 (session->security_parameters.max_record_send_size,
1055 &packed_session->data[pos]);
1056 pos += 2;
1058 _gnutls_write_uint16 (session->security_parameters.max_record_recv_size,
1059 &packed_session->data[pos]);
1060 pos += 2;
1062 /* SRP */
1063 len =
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);
1068 pos += len;
1070 _gnutls_write_uint16 (session->security_parameters.extensions.
1071 server_names_size, &packed_session->data[pos]);
1072 pos += 2;
1074 for (i = 0; i < session->security_parameters.extensions.server_names_size;
1075 i++)
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]);
1082 pos += 2;
1084 memcpy (&packed_session->data[pos],
1085 session->security_parameters.extensions.server_names[i].name,
1086 session->security_parameters.extensions.server_names[i].
1087 name_length);
1088 pos +=
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;
1096 return 0;
1100 static int
1101 unpack_security_parameters (gnutls_session_t session,
1102 const gnutls_datum_t * packed_session)
1104 size_t pack_size, init, i;
1105 int pos = 0, len;
1106 time_t timestamp = time (0);
1109 /* skip the auth info stuff */
1110 init =
1111 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
1112 PACK_HEADER_SIZE;
1114 pos = init;
1116 pack_size = _gnutls_read_uint32 (&packed_session->data[pos]);
1117 pos += 4;
1120 if (pack_size == 0)
1121 return GNUTLS_E_INVALID_REQUEST;
1123 /* a simple check for integrity */
1124 if (pack_size > MAX_SEC_PARAMS)
1126 gnutls_assert ();
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]);
1176 pos += 4;
1178 if (timestamp - session->internals.resumed_security_parameters.timestamp >
1179 session->internals.expire_time
1180 || session->internals.resumed_security_parameters.timestamp > timestamp)
1182 gnutls_assert ();
1183 return GNUTLS_E_EXPIRED;
1186 /* Extensions */
1187 session->internals.resumed_security_parameters.max_record_send_size =
1188 _gnutls_read_uint16 (&packed_session->data[pos]);
1189 pos += 2;
1191 session->internals.resumed_security_parameters.max_record_recv_size =
1192 _gnutls_read_uint16 (&packed_session->data[pos]);
1193 pos += 2;
1196 /* SRP */
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;
1202 pos += len;
1204 session->internals.resumed_security_parameters.extensions.
1205 server_names_size = _gnutls_read_uint16 (&packed_session->data[pos]);
1206 pos += 2;
1207 for (i = 0;
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]);
1217 pos += 2;
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);
1223 pos +=
1224 session->internals.resumed_security_parameters.extensions.
1225 server_names[i].name_length;
1227 return 0;