Version 2.3.13.
[gnutls.git] / lib / gnutls_constate.c
blobb929483ae2fa2f6abb0db170bbca87cc10645a1d
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 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,
21 * USA
25 /* Functions that are supposed to run after the handshake procedure is
26 * finished. These functions activate the established security parameters.
29 #include <gnutls_int.h>
30 #include <gnutls_constate.h>
31 #include <gnutls_errors.h>
32 #include <gnutls_kx.h>
33 #include <gnutls_algorithms.h>
34 #include <gnutls_num.h>
35 #include <gnutls_datum.h>
36 #include <gnutls_state.h>
38 static const char keyexp[] = "key expansion";
39 static const int keyexp_length = sizeof (keyexp) - 1;
41 static const char ivblock[] = "IV block";
42 static const int ivblock_length = sizeof (ivblock) - 1;
44 static const char cliwrite[] = "client write key";
45 static const int cliwrite_length = sizeof (cliwrite) - 1;
47 static const char servwrite[] = "server write key";
48 static const int servwrite_length = sizeof (servwrite) - 1;
50 #define EXPORT_FINAL_KEY_SIZE 16
52 /* This function is to be called after handshake, when master_secret,
53 * client_random and server_random have been initialized.
54 * This function creates the keys and stores them into pending session.
55 * (session->cipher_specs)
57 int
58 _gnutls_set_keys (gnutls_session_t session, int hash_size, int IV_size,
59 int key_size, int export_flag)
62 /* FIXME: This function is too long
64 opaque *key_block;
65 opaque rnd[2 * TLS_RANDOM_SIZE];
66 opaque rrnd[2 * TLS_RANDOM_SIZE];
67 int pos, ret;
68 int block_size;
69 char buf[65];
71 if (session->cipher_specs.generated_keys != 0)
73 /* keys have already been generated.
74 * reset generated_keys and exit normally.
76 session->cipher_specs.generated_keys = 0;
77 return 0;
80 block_size = 2 * hash_size + 2 * key_size;
81 if (export_flag == 0)
82 block_size += 2 * IV_size;
84 key_block = gnutls_secure_malloc (block_size);
85 if (key_block == NULL)
87 gnutls_assert ();
88 return GNUTLS_E_MEMORY_ERROR;
91 memcpy (rnd, session->security_parameters.server_random, TLS_RANDOM_SIZE);
92 memcpy (&rnd[TLS_RANDOM_SIZE],
93 session->security_parameters.client_random, TLS_RANDOM_SIZE);
95 memcpy (rrnd, session->security_parameters.client_random, TLS_RANDOM_SIZE);
96 memcpy (&rrnd[TLS_RANDOM_SIZE],
97 session->security_parameters.server_random, TLS_RANDOM_SIZE);
99 if (session->security_parameters.version == GNUTLS_SSL3)
100 { /* SSL 3 */
101 ret =
102 _gnutls_ssl3_generate_random (session->
103 security_parameters.
104 master_secret,
105 TLS_MASTER_SIZE, rnd,
106 2 * TLS_RANDOM_SIZE,
107 block_size, key_block);
109 else
110 { /* TLS 1.0 */
111 ret =
112 _gnutls_PRF (session, session->security_parameters.master_secret,
113 TLS_MASTER_SIZE, keyexp, keyexp_length,
114 rnd, 2 * TLS_RANDOM_SIZE, block_size, key_block);
117 if (ret < 0)
119 gnutls_assert ();
120 gnutls_free (key_block);
121 return ret;
124 _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size,
125 _gnutls_bin2hex (key_block, block_size, buf,
126 sizeof (buf)));
128 pos = 0;
129 if (hash_size > 0)
131 if (_gnutls_sset_datum
132 (&session->cipher_specs.client_write_mac_secret,
133 &key_block[pos], hash_size) < 0)
135 gnutls_free (key_block);
136 return GNUTLS_E_MEMORY_ERROR;
138 pos += hash_size;
140 if (_gnutls_sset_datum
141 (&session->cipher_specs.server_write_mac_secret,
142 &key_block[pos], hash_size) < 0)
144 gnutls_free (key_block);
145 return GNUTLS_E_MEMORY_ERROR;
147 pos += hash_size;
150 if (key_size > 0)
152 opaque *client_write_key, *server_write_key;
153 int client_write_key_size, server_write_key_size;
154 int free_keys = 0;
156 if (export_flag == 0)
158 client_write_key = &key_block[pos];
159 client_write_key_size = key_size;
161 pos += key_size;
163 server_write_key = &key_block[pos];
164 server_write_key_size = key_size;
166 pos += key_size;
169 else
170 { /* export */
171 free_keys = 1;
173 client_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
174 if (client_write_key == NULL)
176 gnutls_assert ();
177 gnutls_free (key_block);
178 return GNUTLS_E_MEMORY_ERROR;
181 server_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
182 if (server_write_key == NULL)
184 gnutls_assert ();
185 gnutls_free (key_block);
186 gnutls_free (client_write_key);
187 return GNUTLS_E_MEMORY_ERROR;
190 /* generate the final keys */
192 if (session->security_parameters.version == GNUTLS_SSL3)
193 { /* SSL 3 */
194 ret =
195 _gnutls_ssl3_hash_md5 (&key_block[pos],
196 key_size, rrnd,
197 2 * TLS_RANDOM_SIZE,
198 EXPORT_FINAL_KEY_SIZE,
199 client_write_key);
202 else
203 { /* TLS 1.0 */
204 ret =
205 _gnutls_PRF (session, &key_block[pos], key_size,
206 cliwrite, cliwrite_length,
207 rrnd,
208 2 * TLS_RANDOM_SIZE,
209 EXPORT_FINAL_KEY_SIZE, client_write_key);
212 if (ret < 0)
214 gnutls_assert ();
215 gnutls_free (key_block);
216 gnutls_free (server_write_key);
217 gnutls_free (client_write_key);
218 return ret;
221 client_write_key_size = EXPORT_FINAL_KEY_SIZE;
222 pos += key_size;
224 if (session->security_parameters.version == GNUTLS_SSL3)
225 { /* SSL 3 */
226 ret =
227 _gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
228 rnd, 2 * TLS_RANDOM_SIZE,
229 EXPORT_FINAL_KEY_SIZE,
230 server_write_key);
232 else
233 { /* TLS 1.0 */
234 ret =
235 _gnutls_PRF (session, &key_block[pos], key_size,
236 servwrite, servwrite_length,
237 rrnd, 2 * TLS_RANDOM_SIZE,
238 EXPORT_FINAL_KEY_SIZE, server_write_key);
241 if (ret < 0)
243 gnutls_assert ();
244 gnutls_free (key_block);
245 gnutls_free (server_write_key);
246 gnutls_free (client_write_key);
247 return ret;
250 server_write_key_size = EXPORT_FINAL_KEY_SIZE;
251 pos += key_size;
254 if (_gnutls_sset_datum
255 (&session->cipher_specs.client_write_key,
256 client_write_key, client_write_key_size) < 0)
258 gnutls_free (key_block);
259 gnutls_free (server_write_key);
260 gnutls_free (client_write_key);
261 return GNUTLS_E_MEMORY_ERROR;
263 _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",
264 client_write_key_size,
265 _gnutls_bin2hex (client_write_key,
266 client_write_key_size, buf,
267 sizeof (buf)));
269 if (_gnutls_sset_datum
270 (&session->cipher_specs.server_write_key,
271 server_write_key, server_write_key_size) < 0)
273 gnutls_free (key_block);
274 gnutls_free (server_write_key);
275 gnutls_free (client_write_key);
276 return GNUTLS_E_MEMORY_ERROR;
279 _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",
280 server_write_key_size,
281 _gnutls_bin2hex (server_write_key,
282 server_write_key_size, buf,
283 sizeof (buf)));
285 if (free_keys != 0)
287 gnutls_free (server_write_key);
288 gnutls_free (client_write_key);
293 /* IV generation in export and non export ciphers.
295 if (IV_size > 0 && export_flag == 0)
297 if (_gnutls_sset_datum
298 (&session->cipher_specs.client_write_IV, &key_block[pos],
299 IV_size) < 0)
301 gnutls_free (key_block);
302 return GNUTLS_E_MEMORY_ERROR;
304 pos += IV_size;
306 if (_gnutls_sset_datum
307 (&session->cipher_specs.server_write_IV, &key_block[pos],
308 IV_size) < 0)
310 gnutls_free (key_block);
311 return GNUTLS_E_MEMORY_ERROR;
313 pos += IV_size;
316 else if (IV_size > 0 && export_flag != 0)
318 opaque *iv_block = gnutls_malloc (IV_size * 2);
319 if (iv_block == NULL)
321 gnutls_assert ();
322 gnutls_free (key_block);
323 return GNUTLS_E_MEMORY_ERROR;
326 if (session->security_parameters.version == GNUTLS_SSL3)
327 { /* SSL 3 */
328 ret = _gnutls_ssl3_hash_md5 ("", 0,
329 rrnd, TLS_RANDOM_SIZE * 2,
330 IV_size, iv_block);
332 if (ret < 0)
334 gnutls_assert ();
335 gnutls_free (key_block);
336 gnutls_free (iv_block);
337 return ret;
340 ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
341 TLS_RANDOM_SIZE * 2,
342 IV_size, &iv_block[IV_size]);
345 else
346 { /* TLS 1.0 */
347 ret = _gnutls_PRF (session, "", 0,
348 ivblock, ivblock_length, rrnd,
349 2 * TLS_RANDOM_SIZE, IV_size * 2, iv_block);
352 if (ret < 0)
354 gnutls_assert ();
355 gnutls_free (iv_block);
356 gnutls_free (key_block);
357 return ret;
360 if (_gnutls_sset_datum
361 (&session->cipher_specs.client_write_IV, iv_block, IV_size) < 0)
363 gnutls_free (iv_block);
364 gnutls_free (key_block);
365 return GNUTLS_E_MEMORY_ERROR;
368 if (_gnutls_sset_datum
369 (&session->cipher_specs.server_write_IV,
370 &iv_block[IV_size], IV_size) < 0)
372 gnutls_free (iv_block);
373 gnutls_free (key_block);
374 return GNUTLS_E_MEMORY_ERROR;
377 gnutls_free (iv_block);
380 gnutls_free (key_block);
382 session->cipher_specs.generated_keys = 1;
384 return 0;
388 _gnutls_set_read_keys (gnutls_session_t session)
390 int hash_size;
391 int IV_size;
392 int key_size, export_flag;
393 gnutls_cipher_algorithm_t algo;
394 gnutls_mac_algorithm_t mac_algo;
396 mac_algo = session->security_parameters.read_mac_algorithm;
397 algo = session->security_parameters.read_bulk_cipher_algorithm;
399 hash_size = _gnutls_hash_get_algo_len (mac_algo);
400 IV_size = _gnutls_cipher_get_iv_size (algo);
401 key_size = gnutls_cipher_get_key_size (algo);
402 export_flag = _gnutls_cipher_get_export_flag (algo);
404 return _gnutls_set_keys (session, hash_size, IV_size, key_size,
405 export_flag);
409 _gnutls_set_write_keys (gnutls_session_t session)
411 int hash_size;
412 int IV_size;
413 int key_size, export_flag;
414 gnutls_cipher_algorithm_t algo;
415 gnutls_mac_algorithm_t mac_algo;
417 mac_algo = session->security_parameters.write_mac_algorithm;
418 algo = session->security_parameters.write_bulk_cipher_algorithm;
420 hash_size = _gnutls_hash_get_algo_len (mac_algo);
421 IV_size = _gnutls_cipher_get_iv_size (algo);
422 key_size = gnutls_cipher_get_key_size (algo);
423 export_flag = _gnutls_cipher_get_export_flag (algo);
425 return _gnutls_set_keys (session, hash_size, IV_size, key_size,
426 export_flag);
429 #define CPY_COMMON dst->entity = src->entity; \
430 dst->kx_algorithm = src->kx_algorithm; \
431 memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(cipher_suite_st)); \
432 memcpy( dst->master_secret, src->master_secret, TLS_MASTER_SIZE); \
433 memcpy( dst->client_random, src->client_random, TLS_RANDOM_SIZE); \
434 memcpy( dst->server_random, src->server_random, TLS_RANDOM_SIZE); \
435 memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \
436 dst->session_id_size = src->session_id_size; \
437 dst->cert_type = src->cert_type; \
438 dst->timestamp = src->timestamp; \
439 dst->max_record_recv_size = src->max_record_recv_size; \
440 dst->max_record_send_size = src->max_record_send_size; \
441 dst->version = src->version; \
442 memcpy( &dst->extensions, &src->extensions, sizeof(tls_ext_st)); \
443 memcpy( &dst->inner_secret, &src->inner_secret, TLS_MASTER_SIZE);
445 static void
446 _gnutls_cpy_read_security_parameters (security_parameters_st *
447 dst, security_parameters_st * src)
449 CPY_COMMON;
451 dst->read_bulk_cipher_algorithm = src->read_bulk_cipher_algorithm;
452 dst->read_mac_algorithm = src->read_mac_algorithm;
453 dst->read_compression_algorithm = src->read_compression_algorithm;
456 static void
457 _gnutls_cpy_write_security_parameters (security_parameters_st *
458 dst, security_parameters_st * src)
460 CPY_COMMON;
462 dst->write_bulk_cipher_algorithm = src->write_bulk_cipher_algorithm;
463 dst->write_mac_algorithm = src->write_mac_algorithm;
464 dst->write_compression_algorithm = src->write_compression_algorithm;
467 /* Sets the current connection session to conform with the
468 * Security parameters(pending session), and initializes encryption.
469 * Actually it initializes and starts encryption ( so it needs
470 * secrets and random numbers to have been negotiated)
471 * This is to be called after sending the Change Cipher Spec packet.
474 _gnutls_connection_state_init (gnutls_session_t session)
476 int ret;
478 /* Setup the master secret
480 if ((ret = _gnutls_generate_master (session, 0), 0) < 0)
482 gnutls_assert ();
483 return ret;
487 return 0;
491 /* Initializes the read connection session
492 * (read encrypted data)
495 _gnutls_read_connection_state_init (gnutls_session_t session)
497 int mac_size;
498 int rc;
500 _gnutls_uint64zero (session->connection_state.read_sequence_number);
502 /* Update internals from CipherSuite selected.
503 * If we are resuming just copy the connection session
505 if (session->internals.resumed == RESUME_FALSE)
507 rc = _gnutls_set_read_cipher (session,
508 _gnutls_cipher_suite_get_cipher_algo
509 (&session->security_parameters.
510 current_cipher_suite));
511 if (rc < 0)
512 return rc;
513 rc = _gnutls_set_read_mac (session,
514 _gnutls_cipher_suite_get_mac_algo
515 (&session->security_parameters.
516 current_cipher_suite));
517 if (rc < 0)
518 return rc;
520 rc = _gnutls_set_kx (session,
521 _gnutls_cipher_suite_get_kx_algo
522 (&session->security_parameters.
523 current_cipher_suite));
524 if (rc < 0)
525 return rc;
527 rc = _gnutls_set_read_compression (session,
528 session->internals.
529 compression_method);
530 if (rc < 0)
531 return rc;
533 else
534 { /* RESUME_TRUE */
535 _gnutls_cpy_read_security_parameters (&session->
536 security_parameters,
537 &session->
538 internals.
539 resumed_security_parameters);
543 rc = _gnutls_set_read_keys (session);
544 if (rc < 0)
545 return rc;
547 _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n",
548 session, _gnutls_cipher_suite_get_name (&session->
549 security_parameters.
550 current_cipher_suite));
552 if (_gnutls_compression_is_ok
553 (session->security_parameters.read_compression_algorithm) != 0)
555 gnutls_assert ();
556 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
559 if (_gnutls_mac_is_ok
560 (session->security_parameters.read_mac_algorithm) != 0)
562 gnutls_assert ();
563 return GNUTLS_E_INTERNAL_ERROR;
566 /* Free all the previous keys/ sessions etc.
568 if (session->connection_state.read_mac_secret.data != NULL)
569 _gnutls_free_datum (&session->connection_state.read_mac_secret);
571 _gnutls_cipher_deinit (&session->connection_state.read_cipher_state);
573 if (session->connection_state.read_compression_state != NULL)
574 _gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
577 mac_size =
578 _gnutls_hash_get_algo_len (session->security_parameters.
579 read_mac_algorithm);
581 _gnutls_handshake_log
582 ("HSK[%x]: Initializing internal [read] cipher sessions\n", session);
584 switch (session->security_parameters.entity)
586 case GNUTLS_SERVER:
587 /* initialize cipher session
589 rc = _gnutls_cipher_init (&session->connection_state.read_cipher_state,
590 session->security_parameters.read_bulk_cipher_algorithm,
591 &session->cipher_specs.client_write_key,
592 &session->cipher_specs.client_write_IV);
593 if (rc < 0 && session->security_parameters.
594 read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
596 gnutls_assert ();
597 return rc;
600 /* copy mac secrets from cipherspecs, to connection
601 * session.
603 if (mac_size > 0)
605 if (_gnutls_sset_datum (&session->connection_state.
606 read_mac_secret,
607 session->cipher_specs.
608 client_write_mac_secret.data,
609 session->cipher_specs.
610 client_write_mac_secret.size) < 0)
612 gnutls_assert ();
613 return GNUTLS_E_MEMORY_ERROR;
618 break;
620 case GNUTLS_CLIENT:
621 rc = _gnutls_cipher_init (&session->connection_state.read_cipher_state,
622 session->security_parameters.read_bulk_cipher_algorithm,
623 &session->cipher_specs.server_write_key,
624 &session->cipher_specs.server_write_IV);
626 if (rc < 0 && session->security_parameters.
627 read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
629 gnutls_assert ();
630 return GNUTLS_E_INTERNAL_ERROR;
634 /* copy mac secret to connection session
636 if (mac_size > 0)
638 if (_gnutls_sset_datum (&session->connection_state.
639 read_mac_secret,
640 session->cipher_specs.
641 server_write_mac_secret.data,
642 session->cipher_specs.
643 server_write_mac_secret.size) < 0)
645 gnutls_assert ();
646 return GNUTLS_E_MEMORY_ERROR;
650 break;
652 default: /* this check is useless */
653 gnutls_assert ();
654 return GNUTLS_E_INTERNAL_ERROR;
657 session->connection_state.read_compression_state =
658 _gnutls_comp_init (session->security_parameters.
659 read_compression_algorithm, 1);
661 if (session->connection_state.read_compression_state == GNUTLS_COMP_FAILED)
663 gnutls_assert ();
664 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
667 return 0;
672 /* Initializes the write connection session
673 * (write encrypted data)
676 _gnutls_write_connection_state_init (gnutls_session_t session)
678 int mac_size;
679 int rc;
681 _gnutls_uint64zero (session->connection_state.write_sequence_number);
683 /* Update internals from CipherSuite selected.
684 * If we are resuming just copy the connection session
686 if (session->internals.resumed == RESUME_FALSE)
688 rc = _gnutls_set_write_cipher (session,
689 _gnutls_cipher_suite_get_cipher_algo
690 (&session->security_parameters.
691 current_cipher_suite));
692 if (rc < 0)
693 return rc;
694 rc = _gnutls_set_write_mac (session,
695 _gnutls_cipher_suite_get_mac_algo
696 (&session->security_parameters.
697 current_cipher_suite));
698 if (rc < 0)
699 return rc;
701 rc = _gnutls_set_kx (session,
702 _gnutls_cipher_suite_get_kx_algo
703 (&session->security_parameters.
704 current_cipher_suite));
705 if (rc < 0)
706 return rc;
708 rc = _gnutls_set_write_compression (session,
709 session->internals.
710 compression_method);
711 if (rc < 0)
712 return rc;
714 else
715 { /* RESUME_TRUE */
716 _gnutls_cpy_write_security_parameters (&session->
717 security_parameters,
718 &session->
719 internals.
720 resumed_security_parameters);
723 rc = _gnutls_set_write_keys (session);
724 if (rc < 0)
725 return rc;
727 _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n", session,
728 _gnutls_cipher_suite_get_name (&session->
729 security_parameters.
730 current_cipher_suite));
732 if (_gnutls_compression_is_ok
733 (session->security_parameters.write_compression_algorithm) != 0)
735 gnutls_assert ();
736 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
739 if (_gnutls_mac_is_ok
740 (session->security_parameters.write_mac_algorithm) != 0)
742 gnutls_assert ();
743 return GNUTLS_E_INTERNAL_ERROR;
748 /* Free all the previous keys/ sessions etc.
750 if (session->connection_state.write_mac_secret.data != NULL)
751 _gnutls_free_datum (&session->connection_state.write_mac_secret);
753 _gnutls_cipher_deinit (&session->connection_state.write_cipher_state);
755 if (session->connection_state.write_compression_state != NULL)
756 _gnutls_comp_deinit (session->connection_state.
757 write_compression_state, 0);
759 mac_size =
760 _gnutls_hash_get_algo_len (session->security_parameters.
761 write_mac_algorithm);
763 _gnutls_handshake_log
764 ("HSK[%x]: Initializing internal [write] cipher sessions\n", session);
766 switch (session->security_parameters.entity)
768 case GNUTLS_SERVER:
769 /* initialize cipher session
771 rc = _gnutls_cipher_init (
772 &session->connection_state.write_cipher_state,
773 session->security_parameters.
774 write_bulk_cipher_algorithm,
775 &session->cipher_specs.
776 server_write_key,
777 &session->cipher_specs.server_write_IV);
779 if (rc < 0 && session->security_parameters.
780 write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
782 gnutls_assert ();
783 return GNUTLS_E_INTERNAL_ERROR;
787 /* copy mac secrets from cipherspecs, to connection
788 * session.
790 if (mac_size > 0)
792 if (_gnutls_sset_datum (&session->connection_state.
793 write_mac_secret,
794 session->cipher_specs.
795 server_write_mac_secret.data,
796 session->cipher_specs.
797 server_write_mac_secret.size) < 0)
799 gnutls_assert ();
800 return GNUTLS_E_MEMORY_ERROR;
806 break;
808 case GNUTLS_CLIENT:
809 rc = _gnutls_cipher_init (&session->connection_state.write_cipher_state,
810 session->security_parameters.
811 write_bulk_cipher_algorithm,
812 &session->cipher_specs.
813 client_write_key,
814 &session->cipher_specs.client_write_IV);
816 if (rc < 0 && session->security_parameters.
817 write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
819 gnutls_assert ();
820 return GNUTLS_E_INTERNAL_ERROR;
823 /* copy mac secret to connection session
825 if (mac_size > 0)
827 if (_gnutls_sset_datum (&session->connection_state.
828 write_mac_secret,
829 session->cipher_specs.
830 client_write_mac_secret.data,
831 session->cipher_specs.
832 client_write_mac_secret.size) < 0)
834 gnutls_assert ();
835 return GNUTLS_E_MEMORY_ERROR;
839 break;
841 default:
842 gnutls_assert ();
843 return GNUTLS_E_INTERNAL_ERROR;
847 session->connection_state.write_compression_state =
848 _gnutls_comp_init (session->security_parameters.
849 write_compression_algorithm, 0);
851 if (session->connection_state.write_compression_state == GNUTLS_COMP_FAILED)
853 gnutls_assert ();
854 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
857 return 0;
860 /* Sets the specified cipher into the pending session
863 _gnutls_set_read_cipher (gnutls_session_t session,
864 gnutls_cipher_algorithm_t algo)
867 if (_gnutls_cipher_is_ok (algo) == 0)
869 if (_gnutls_cipher_priority (session, algo) < 0)
871 gnutls_assert ();
872 return GNUTLS_E_UNWANTED_ALGORITHM;
875 session->security_parameters.read_bulk_cipher_algorithm = algo;
878 else
880 gnutls_assert ();
881 return GNUTLS_E_INTERNAL_ERROR;
884 return 0;
889 _gnutls_set_write_cipher (gnutls_session_t session,
890 gnutls_cipher_algorithm_t algo)
893 if (_gnutls_cipher_is_ok (algo) == 0)
895 if (_gnutls_cipher_priority (session, algo) < 0)
897 gnutls_assert ();
898 return GNUTLS_E_UNWANTED_ALGORITHM;
901 session->security_parameters.write_bulk_cipher_algorithm = algo;
904 else
906 gnutls_assert ();
907 return GNUTLS_E_INTERNAL_ERROR;
910 return 0;
915 /* Sets the specified algorithm into pending compression session
918 _gnutls_set_read_compression (gnutls_session_t session,
919 gnutls_compression_method_t algo)
922 if (_gnutls_compression_is_ok (algo) == 0)
924 session->security_parameters.read_compression_algorithm = algo;
926 else
928 gnutls_assert ();
929 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
931 return 0;
936 _gnutls_set_write_compression (gnutls_session_t session,
937 gnutls_compression_method_t algo)
940 if (_gnutls_compression_is_ok (algo) == 0)
942 session->security_parameters.write_compression_algorithm = algo;
944 else
946 gnutls_assert ();
947 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
949 return 0;
953 /* Sets the specified kx algorithm into pending session
956 _gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo)
959 if (_gnutls_kx_is_ok (algo) == 0)
961 session->security_parameters.kx_algorithm = algo;
963 else
965 gnutls_assert ();
966 return GNUTLS_E_INTERNAL_ERROR;
968 if (_gnutls_kx_priority (session, algo) < 0)
970 gnutls_assert ();
971 /* we shouldn't get here */
972 return GNUTLS_E_UNWANTED_ALGORITHM;
975 return 0;
979 /* Sets the specified mac algorithm into pending session */
981 _gnutls_set_read_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
984 if (_gnutls_mac_is_ok (algo) == 0)
986 session->security_parameters.read_mac_algorithm = algo;
988 else
990 gnutls_assert ();
991 return GNUTLS_E_INTERNAL_ERROR;
993 if (_gnutls_mac_priority (session, algo) < 0)
995 gnutls_assert ();
996 return GNUTLS_E_UNWANTED_ALGORITHM;
1000 return 0;
1005 _gnutls_set_write_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
1008 if (_gnutls_mac_is_ok (algo) == 0)
1010 session->security_parameters.write_mac_algorithm = algo;
1012 else
1014 gnutls_assert ();
1015 return GNUTLS_E_INTERNAL_ERROR;
1017 if (_gnutls_mac_priority (session, algo) < 0)
1019 gnutls_assert ();
1020 return GNUTLS_E_UNWANTED_ALGORITHM;
1024 return 0;