static inline void free_record_state(record_state_st * state, int d) { _gnutls_free_datum(&state->mac_secret); _gnutls_free_datum(&state->IV); _gnutls_free_datum(&state->key); _gnutls_auth_cipher_deinit(&state->cipher_state); if (state->compression_state.handle != NULL) _gnutls_comp_deinit(&state->compression_state, d); }
/** * gnutls_deinit - clear all buffers associated with a session * @session: is a #gnutls_session_t structure. * * This function clears all buffers associated with the @session. * This function will also remove session data from the session * database if the session was terminated abnormally. **/ void gnutls_deinit (gnutls_session_t session) { if (session == NULL) return; /* remove auth info firstly */ _gnutls_free_auth_info (session); _gnutls_handshake_internal_state_clear (session); _gnutls_handshake_io_buffer_clear (session); _gnutls_free_datum (&session->connection_state.read_mac_secret); _gnutls_free_datum (&session->connection_state.write_mac_secret); _gnutls_buffer_clear (&session->internals.ia_data_buffer); _gnutls_buffer_clear (&session->internals.handshake_hash_buffer); _gnutls_buffer_clear (&session->internals.handshake_data_buffer); _gnutls_buffer_clear (&session->internals.application_data_buffer); _gnutls_buffer_clear (&session->internals.record_recv_buffer); _gnutls_buffer_clear (&session->internals.record_send_buffer); gnutls_credentials_clear (session); _gnutls_selected_certs_deinit (session); _gnutls_cipher_deinit (&session->connection_state.read_cipher_state); _gnutls_cipher_deinit (&session->connection_state.write_cipher_state); if (session->connection_state.read_compression_state != NULL) _gnutls_comp_deinit (session->connection_state.read_compression_state, 1); if (session->connection_state.write_compression_state != NULL) _gnutls_comp_deinit (session->connection_state.write_compression_state, 0); _gnutls_free_datum (&session->cipher_specs.server_write_mac_secret); _gnutls_free_datum (&session->cipher_specs.client_write_mac_secret); _gnutls_free_datum (&session->cipher_specs.server_write_IV); _gnutls_free_datum (&session->cipher_specs.client_write_IV); _gnutls_free_datum (&session->cipher_specs.server_write_key); _gnutls_free_datum (&session->cipher_specs.client_write_key); if (session->key != NULL) { _gnutls_mpi_release (&session->key->KEY); _gnutls_mpi_release (&session->key->client_Y); _gnutls_mpi_release (&session->key->client_p); _gnutls_mpi_release (&session->key->client_g); _gnutls_mpi_release (&session->key->u); _gnutls_mpi_release (&session->key->a); _gnutls_mpi_release (&session->key->x); _gnutls_mpi_release (&session->key->A); _gnutls_mpi_release (&session->key->B); _gnutls_mpi_release (&session->key->b); /* RSA */ _gnutls_mpi_release (&session->key->rsa[0]); _gnutls_mpi_release (&session->key->rsa[1]); _gnutls_mpi_release (&session->key->dh_secret); gnutls_free (session->key); session->key = NULL; } gnutls_free (session->internals.srp_username); if (session->internals.srp_password) { memset (session->internals.srp_password, 0, strlen (session->internals.srp_password)); gnutls_free (session->internals.srp_password); } memset (session, 0, sizeof (struct gnutls_session_int)); gnutls_free (session); }
/* Initializes the write connection session * (write encrypted data) */ int _gnutls_write_connection_state_init (gnutls_session_t session) { int mac_size; int rc; _gnutls_uint64zero (session->connection_state.write_sequence_number); /* Update internals from CipherSuite selected. * If we are resuming just copy the connection session */ if (session->internals.resumed == RESUME_FALSE) { rc = _gnutls_set_write_cipher (session, _gnutls_cipher_suite_get_cipher_algo (&session->security_parameters. current_cipher_suite)); if (rc < 0) return rc; rc = _gnutls_set_write_mac (session, _gnutls_cipher_suite_get_mac_algo (&session->security_parameters. current_cipher_suite)); if (rc < 0) return rc; rc = _gnutls_set_kx (session, _gnutls_cipher_suite_get_kx_algo (&session->security_parameters. current_cipher_suite)); if (rc < 0) return rc; rc = _gnutls_set_write_compression (session, session->internals. compression_method); if (rc < 0) return rc; } else { /* RESUME_TRUE */ _gnutls_cpy_write_security_parameters (&session-> security_parameters, &session-> internals. resumed_security_parameters); } rc = _gnutls_set_write_keys (session); if (rc < 0) return rc; _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n", session, _gnutls_cipher_suite_get_name (&session-> security_parameters. current_cipher_suite)); if (_gnutls_compression_is_ok (session->security_parameters.write_compression_algorithm) != 0) { gnutls_assert (); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } if (_gnutls_mac_is_ok (session->security_parameters.write_mac_algorithm) != 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* Free all the previous keys/ sessions etc. */ if (session->connection_state.write_mac_secret.data != NULL) _gnutls_free_datum (&session->connection_state.write_mac_secret); if (session->connection_state.write_cipher_state != NULL) _gnutls_cipher_deinit (session->connection_state.write_cipher_state); if (session->connection_state.write_compression_state != NULL) _gnutls_comp_deinit (session->connection_state. write_compression_state, 0); mac_size = _gnutls_hash_get_algo_len (session->security_parameters. write_mac_algorithm); _gnutls_handshake_log ("HSK[%x]: Initializing internal [write] cipher sessions\n", session); switch (session->security_parameters.entity) { case GNUTLS_SERVER: /* initialize cipher session */ session->connection_state.write_cipher_state = _gnutls_cipher_init (session->security_parameters. write_bulk_cipher_algorithm, &session->cipher_specs. server_write_key, &session->cipher_specs.server_write_IV); if (session->connection_state.write_cipher_state == GNUTLS_CIPHER_FAILED && session->security_parameters. write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* copy mac secrets from cipherspecs, to connection * session. */ if (mac_size > 0) { if (_gnutls_sset_datum (&session->connection_state. write_mac_secret, session->cipher_specs. server_write_mac_secret.data, session->cipher_specs. server_write_mac_secret.size) < 0) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } } break; case GNUTLS_CLIENT: session->connection_state.write_cipher_state = _gnutls_cipher_init (session->security_parameters. write_bulk_cipher_algorithm, &session->cipher_specs. client_write_key, &session->cipher_specs.client_write_IV); if (session->connection_state.write_cipher_state == GNUTLS_CIPHER_FAILED && session->security_parameters. write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* copy mac secret to connection session */ if (mac_size > 0) { if (_gnutls_sset_datum (&session->connection_state. write_mac_secret, session->cipher_specs. client_write_mac_secret.data, session->cipher_specs. client_write_mac_secret.size) < 0) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } } break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } session->connection_state.write_compression_state = _gnutls_comp_init (session->security_parameters. write_compression_algorithm, 0); if (session->connection_state.write_compression_state == GNUTLS_COMP_FAILED) { gnutls_assert (); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } return 0; }