diff options
-rw-r--r-- | lib/abstract_int.h | 2 | ||||
-rw-r--r-- | lib/algorithms.h | 37 | ||||
-rw-r--r-- | lib/algorithms/ciphersuites.c | 6 | ||||
-rw-r--r-- | lib/algorithms/protocols.c | 99 | ||||
-rw-r--r-- | lib/auth/cert.c | 12 | ||||
-rw-r--r-- | lib/auth/rsa.c | 11 | ||||
-rw-r--r-- | lib/auth/srp_rsa.c | 4 | ||||
-rw-r--r-- | lib/ext/signature.c | 8 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 38 | ||||
-rw-r--r-- | lib/gnutls_constate.c | 12 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 79 | ||||
-rw-r--r-- | lib/gnutls_int.h | 29 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 8 | ||||
-rw-r--r-- | lib/gnutls_pubkey.c | 2 | ||||
-rw-r--r-- | lib/gnutls_record.c | 19 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 20 | ||||
-rw-r--r-- | lib/gnutls_state.c | 5 | ||||
-rw-r--r-- | lib/gnutls_ui.c | 6 |
18 files changed, 171 insertions, 226 deletions
diff --git a/lib/abstract_int.h b/lib/abstract_int.h index 3cee52b21f..229a49885a 100644 --- a/lib/abstract_int.h +++ b/lib/abstract_int.h @@ -85,7 +85,7 @@ int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params); int _gnutls_pubkey_compatible_with_sig(gnutls_session_t, gnutls_pubkey_t pubkey, - gnutls_protocol_t ver, gnutls_sign_algorithm_t sign); + const version_entry_st* ver, gnutls_sign_algorithm_t sign); int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey); int _gnutls_pubkey_get_mpis (gnutls_pubkey_t key, diff --git a/lib/algorithms.h b/lib/algorithms.h index 111e030c6e..76888b5a56 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -32,20 +32,47 @@ #define MAX_CIPHERSUITE_SIZE 512 /* Functions for version handling. */ +const version_entry_st* version_to_entry(gnutls_protocol_t c); gnutls_protocol_t _gnutls_version_lowest (gnutls_session_t session); gnutls_protocol_t _gnutls_version_max (gnutls_session_t session); int _gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version); int _gnutls_version_is_supported (gnutls_session_t session, const gnutls_protocol_t version); -void _gnutls_version_to_tls (gnutls_protocol_t ver, uint8_t* major, uint8_t* minor); gnutls_protocol_t _gnutls_version_get (uint8_t major, uint8_t minor); /* Functions for feature checks */ -int _gnutls_version_has_selectable_prf (gnutls_protocol_t version); -int _gnutls_version_has_selectable_sighash (gnutls_protocol_t version); -int _gnutls_version_has_extensions (gnutls_protocol_t version); -int _gnutls_version_has_explicit_iv (gnutls_protocol_t version); +inline static int +_gnutls_version_has_selectable_prf (const version_entry_st* ver) +{ + if (unlikely(ver==NULL)) + return 0; + return ver->selectable_prf; +} + +inline static int +_gnutls_version_has_selectable_sighash (const version_entry_st* ver) +{ + if (unlikely(ver==NULL)) + return 0; + return ver->selectable_sighash; +} + +inline static +int _gnutls_version_has_extensions (const version_entry_st* ver) +{ + if (unlikely(ver==NULL)) + return 0; + return ver->extensions; +} + +inline static +int _gnutls_version_has_explicit_iv (const version_entry_st* ver) +{ + if (unlikely(ver==NULL)) + return 0; + return ver->explicit_iv; +} /* Functions for MACs. */ const mac_entry_st* mac_to_entry(gnutls_mac_algorithm_t c); diff --git a/lib/algorithms/ciphersuites.c b/lib/algorithms/ciphersuites.c index 5a51ec5838..b9a326d288 100644 --- a/lib/algorithms/ciphersuites.c +++ b/lib/algorithms/ciphersuites.c @@ -947,7 +947,7 @@ _gnutls_supported_ciphersuites (gnutls_session_t session, unsigned int i, ret_count, j, z, k=0; const gnutls_cipher_suite_entry * ce; - unsigned int version = gnutls_protocol_get_version( session); + const version_entry_st* version = get_version( session); unsigned int is_dtls = IS_DTLS(session); for (i = 0; i < session->internals.priorities.kx.algorithms; i++) @@ -960,9 +960,9 @@ _gnutls_supported_ciphersuites (gnutls_session_t session, if (ce == NULL) continue; - if (is_dtls == 0 && !(version >= ce->min_version)) + if (is_dtls == 0 && !(version->id >= ce->min_version)) continue; - else if (is_dtls != 0 && !(version >= ce->min_dtls_version)) + else if (is_dtls != 0 && !(version->id >= ce->min_dtls_version)) if (k+2 > max_cipher_suite_size) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c index 927e873b0d..1f7a15804d 100644 --- a/lib/algorithms/protocols.c +++ b/lib/algorithms/protocols.c @@ -25,16 +25,15 @@ #include <gnutls_errors.h> #include <x509/common.h> - /* TLS Versions */ static const version_entry_st sup_versions[] = { - {"SSL3.0", GNUTLS_SSL3, 3, 0, GNUTLS_STREAM, 1}, - {"TLS1.0", GNUTLS_TLS1, 3, 1, GNUTLS_STREAM, 1}, - {"TLS1.1", GNUTLS_TLS1_1, 3, 2, GNUTLS_STREAM, 1}, - {"TLS1.2", GNUTLS_TLS1_2, 3, 3, GNUTLS_STREAM, 1}, - {"DTLS0.9", GNUTLS_DTLS0_9, 1, 0, GNUTLS_DGRAM, 1}, /* Cisco AnyConnect (based on about OpenSSL 0.9.8e) */ - {"DTLS1.0", GNUTLS_DTLS1_0, 254, 255, GNUTLS_DGRAM, 1}, /* 1.1 over datagram */ - {"DTLS1.2", GNUTLS_DTLS1_2, 254, 253, GNUTLS_DGRAM, 1}, /* 1.2 over datagram */ + {"SSL3.0", GNUTLS_SSL3, 3, 0, GNUTLS_STREAM, 1, 0, 0, 0, 0}, + {"TLS1.0", GNUTLS_TLS1, 3, 1, GNUTLS_STREAM, 1, 0, 1, 0, 0}, + {"TLS1.1", GNUTLS_TLS1_1, 3, 2, GNUTLS_STREAM, 1, 1, 1, 0, 0}, + {"TLS1.2", GNUTLS_TLS1_2, 3, 3, GNUTLS_STREAM, 1, 1, 1, 1, 1}, + {"DTLS0.9", GNUTLS_DTLS0_9, 1, 0, GNUTLS_DGRAM, 1, 1, 1, 0, 0}, /* Cisco AnyConnect (based on about OpenSSL 0.9.8e) */ + {"DTLS1.0", GNUTLS_DTLS1_0, 254, 255, GNUTLS_DGRAM, 1, 1, 1, 0, 0}, /* 1.1 over datagram */ + {"DTLS1.2", GNUTLS_DTLS1_2, 254, 253, GNUTLS_DGRAM, 1, 1, 1, 1, 1}, /* 1.2 over datagram */ {0, 0, 0, 0, 0} }; @@ -45,6 +44,12 @@ static const version_entry_st sup_versions[] = { #define GNUTLS_VERSION_ALG_LOOP(a) \ GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; }) +const version_entry_st* version_to_entry(gnutls_protocol_t version) +{ + GNUTLS_VERSION_ALG_LOOP (return p); + return NULL; +} + /* Return the priority of the provided version number */ int _gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version) @@ -187,12 +192,6 @@ _gnutls_version_get (uint8_t major, uint8_t minor) return ret; } -void -_gnutls_version_to_tls (gnutls_protocol_t version, uint8_t* major, uint8_t *minor) -{ - GNUTLS_VERSION_ALG_LOOP (*major = p->major; *minor = p->minor); -} - /* Version Functions */ int @@ -212,75 +211,3 @@ _gnutls_version_is_supported (gnutls_session_t session, return 1; } - -/* This function determines if the version specified has a - cipher-suite selected PRF hash function instead of the old - hardcoded MD5+SHA1. */ -int -_gnutls_version_has_selectable_prf (gnutls_protocol_t version) -{ - switch (version) - { - case GNUTLS_DTLS0_9: - case GNUTLS_DTLS1_0: - case GNUTLS_TLS1_1: - case GNUTLS_TLS1_0: - case GNUTLS_SSL3: - return 0; - default: - return 1; - } -} - -/* This function determines if the version specified has selectable - signature/hash functions for certificate authentification. */ -int -_gnutls_version_has_selectable_sighash (gnutls_protocol_t version) -{ - switch (version) - { - case GNUTLS_DTLS0_9: - case GNUTLS_DTLS1_0: - case GNUTLS_TLS1_1: - case GNUTLS_TLS1_0: - case GNUTLS_SSL3: - return 0; - default: - return 1; - } -} - -/* This function determines if the version specified has support for - TLS extensions. */ -int -_gnutls_version_has_extensions (gnutls_protocol_t version) -{ - switch (version) - { - case GNUTLS_SSL3: - return 0; - default: - /* Versions after TLS 1.0 are required to handle extensions. - * SSL 3.0 also required extensions to be ignored, but - * some earlier draft didn't. - */ - return 1; - } -} - -/* This function determines if the version specified has explicit IVs - (for CBC attack prevention). */ -int -_gnutls_version_has_explicit_iv (gnutls_protocol_t version) -{ - switch (version) - { - case GNUTLS_TLS1_0: - case GNUTLS_SSL3: - return 0; - default: - /* All versions after TLS 1.1 have explicit IV */ - return 1; - } -} - diff --git a/lib/auth/cert.c b/lib/auth/cert.c index b7f2609fc6..589acf5621 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -1456,7 +1456,7 @@ _gnutls_proc_cert_cert_req (gnutls_session_t session, uint8_t * data, int i; gnutls_pk_algorithm_t pk_algos[MAX_CLIENT_SIGN_ALGOS]; int pk_algos_length; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); cred = (gnutls_certificate_credentials_t) _gnutls_get_cred (session, GNUTLS_CRD_CERTIFICATE, NULL); @@ -1562,7 +1562,7 @@ _gnutls_gen_cert_client_crt_vrfy (gnutls_session_t session, int apr_cert_list_length; gnutls_datum_t signature = { NULL, 0 }; gnutls_sign_algorithm_t sign_algo; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); /* find the appropriate certificate */ if ((ret = @@ -1636,7 +1636,7 @@ _gnutls_proc_cert_client_crt_vrfy (gnutls_session_t session, cert_auth_info_t info = _gnutls_get_auth_info (session); gnutls_pcert_st peer_cert; gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); if (info == NULL || info->ncerts == 0) { @@ -1708,7 +1708,7 @@ _gnutls_gen_cert_server_cert_req (gnutls_session_t session, gnutls_certificate_credentials_t cred; int ret; uint8_t tmp_data[CERTTYPE_SIZE]; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); /* Now we need to generate the RDN sequence. This is * already in the CERTIFICATE_CRED structure, to improve @@ -2207,7 +2207,7 @@ gnutls_privkey_t apr_pkey; int apr_cert_list_length; gnutls_datum_t signature = { NULL, 0 }, ddata; gnutls_sign_algorithm_t sign_algo; -gnutls_protocol_t ver = gnutls_protocol_get_version (session); +const version_entry_st* ver = get_version (session); int ret; ddata.data = plain; @@ -2294,7 +2294,7 @@ _gnutls_proc_dhe_signature (gnutls_session_t session, uint8_t * data, ssize_t data_size = _data_size; gnutls_pcert_st peer_cert; gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); if (info == NULL || info->ncerts == 0) { diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c index f71d95a389..4f55fa46d3 100644 --- a/lib/auth/rsa.c +++ b/lib/auth/rsa.c @@ -120,7 +120,7 @@ proc_rsa_client_kx (gnutls_session_t session, uint8_t * data, int randomize_key = 0; ssize_t data_size = _data_size; - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) + if (get_num_version (session) == GNUTLS_SSL3) { /* SSL 3.0 */ @@ -225,7 +225,6 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) gnutls_datum_t sdata; /* data to send */ gnutls_pk_params_st params; int ret; - gnutls_protocol_t ver; if (auth == NULL) { @@ -253,12 +252,10 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) return ret; } - ver = _gnutls_get_adv_version (session); - if (session->internals.rsa_pms_version[0] == 0) { - _gnutls_version_to_tls(ver, &session->key.key.data[0], - &session->key.key.data[1]); + session->key.key.data[0] = _gnutls_get_adv_version_major(session); + session->key.key.data[1] = _gnutls_get_adv_version_minor(session); } else { /* use the version provided */ @@ -285,7 +282,7 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) return gnutls_assert_val(ret); - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) + if (get_num_version (session) == GNUTLS_SSL3) { /* SSL 3.0 */ _gnutls_buffer_replace_data( data, &sdata); diff --git a/lib/auth/srp_rsa.c b/lib/auth/srp_rsa.c index 99511d1d01..1e84d9df39 100644 --- a/lib/auth/srp_rsa.c +++ b/lib/auth/srp_rsa.c @@ -87,7 +87,7 @@ gen_srp_cert_server_kx (gnutls_session_t session, gnutls_buffer_st* data) gnutls_privkey_t apr_pkey; int apr_cert_list_length; gnutls_sign_algorithm_t sign_algo; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); ret = _gnutls_gen_srp_server_kx (session, data); @@ -180,7 +180,7 @@ proc_srp_cert_server_kx (gnutls_session_t session, uint8_t * data, gnutls_pcert_st peer_cert; uint8_t *p; gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); ret = _gnutls_proc_srp_server_kx (session, data, _data_size); if (ret < 0) diff --git a/lib/ext/signature.c b/lib/ext/signature.c index 3710867dee..1d2fb9c518 100644 --- a/lib/ext/signature.c +++ b/lib/ext/signature.c @@ -213,7 +213,7 @@ _gnutls_signature_algorithm_send_params (gnutls_session_t session, { int ret; size_t init_length = extdata->length; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); /* this function sends the client extension data */ if (session->security_parameters.entity == GNUTLS_CLIENT @@ -248,7 +248,7 @@ _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_pcert_st* cert) { unsigned i; int ret; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); sig_ext_st *priv; extension_priv_data_t epriv; unsigned int cert_algo; @@ -295,7 +295,7 @@ _gnutls_session_sign_algo_enabled (gnutls_session_t session, { unsigned i; int ret; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); sig_ext_st *priv; extension_priv_data_t epriv; @@ -407,7 +407,7 @@ gnutls_sign_algorithm_get_requested (gnutls_session_t session, size_t indx, gnutls_sign_algorithm_t * algo) { - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); sig_ext_st *priv; extension_priv_data_t epriv; int ret; diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index 45d04701ff..3da29d476c 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -226,7 +226,9 @@ leave: inline static int -calc_enc_length_block (gnutls_session_t session, int data_size, +calc_enc_length_block (gnutls_session_t session, + const version_entry_st* ver, + int data_size, int hash_size, uint8_t * pad, unsigned auth_cipher, uint16_t blocksize) { @@ -244,8 +246,7 @@ calc_enc_length_block (gnutls_session_t session, int data_size, length = data_size + hash_size + *pad; - if (_gnutls_version_has_explicit_iv - (session->security_parameters.version)) + if (_gnutls_version_has_explicit_iv(ver)) length += blocksize; /* for the IV */ return length; @@ -271,25 +272,22 @@ calc_enc_length_stream (gnutls_session_t session, int data_size, */ static inline int make_preamble (uint8_t * uint64_data, uint8_t type, unsigned int length, - gnutls_protocol_t ver, uint8_t * preamble) + const version_entry_st* ver, uint8_t * preamble) { - uint8_t minor, major; uint8_t *p = preamble; uint16_t c_length; - _gnutls_version_to_tls(ver, &major, &minor); - c_length = _gnutls_conv_uint16 (length); memcpy (p, uint64_data, 8); p += 8; *p = type; p++; - if (ver != GNUTLS_SSL3) + if (ver->id != GNUTLS_SSL3) { /* TLS protocols */ - *p = major; + *p = ver->major; p++; - *p = minor; + *p = ver->minor; p++; } memcpy (p, &c_length, 2); @@ -320,8 +318,8 @@ compressed_to_ciphertext (gnutls_session_t session, unsigned block_algo = _gnutls_cipher_is_block (params->cipher); uint8_t *data_ptr; - int ver = gnutls_protocol_get_version (session); - int explicit_iv = _gnutls_version_has_explicit_iv (session->security_parameters.version); + const version_entry_st* ver = get_version (session); + int explicit_iv = _gnutls_version_has_explicit_iv (ver); int auth_cipher = _gnutls_auth_cipher_is_aead(¶ms->write.cipher_state); uint8_t nonce[MAX_CIPHER_BLOCK_SIZE]; unsigned iv_size; @@ -348,7 +346,7 @@ compressed_to_ciphertext (gnutls_session_t session, return gnutls_assert_val(ret); length_to_encrypt = length = - calc_enc_length_block (session, compressed->size, tag_size, &pad, + calc_enc_length_block (session, ver, compressed->size, tag_size, &pad, auth_cipher, blocksize); } else @@ -473,8 +471,8 @@ compressed_to_ciphertext_new (gnutls_session_t session, unsigned block_algo = _gnutls_cipher_is_block (params->cipher); uint8_t *data_ptr; - int ver = gnutls_protocol_get_version (session); - int explicit_iv = _gnutls_version_has_explicit_iv (session->security_parameters.version); + const version_entry_st* ver = get_version (session); + int explicit_iv = _gnutls_version_has_explicit_iv (ver); int auth_cipher = _gnutls_auth_cipher_is_aead(¶ms->write.cipher_state); uint8_t nonce[MAX_CIPHER_BLOCK_SIZE]; unsigned iv_size; @@ -662,9 +660,9 @@ ciphertext_to_compressed (gnutls_session_t session, unsigned int pad_failed = 0; uint8_t preamble[MAX_PREAMBLE_SIZE]; unsigned int preamble_size; - unsigned int ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); unsigned int tag_size = _gnutls_auth_cipher_tag_len (¶ms->read.cipher_state); - unsigned int explicit_iv = _gnutls_version_has_explicit_iv (session->security_parameters.version); + unsigned int explicit_iv = _gnutls_version_has_explicit_iv (ver); unsigned iv_size; iv_size = _gnutls_cipher_get_iv_size(params->cipher); @@ -767,7 +765,7 @@ ciphertext_to_compressed (gnutls_session_t session, * Note that we access all 256 bytes of ciphertext for padding check * because there is a timing channel in that memory access (in certain CPUs). */ - if (ver != GNUTLS_SSL3) + if (ver->id != GNUTLS_SSL3) for (i = 2; i <= MIN(256, ciphertext->size); i++) { tmp_pad_failed |= (ciphertext->data[ciphertext->size - i] != pad); @@ -843,9 +841,9 @@ ciphertext_to_compressed_new (gnutls_session_t session, int ret; uint8_t preamble[MAX_PREAMBLE_SIZE]; unsigned int preamble_size; - unsigned int ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); unsigned int tag_size = _gnutls_auth_cipher_tag_len (¶ms->read.cipher_state); - unsigned int explicit_iv = _gnutls_version_has_explicit_iv (session->security_parameters.version); + unsigned int explicit_iv = _gnutls_version_has_explicit_iv (ver); unsigned iv_size; iv_size = _gnutls_cipher_get_iv_size(params->cipher); diff --git a/lib/gnutls_constate.c b/lib/gnutls_constate.c index 11b63e7859..ca6d4088d5 100644 --- a/lib/gnutls_constate.c +++ b/lib/gnutls_constate.c @@ -188,8 +188,8 @@ _gnutls_set_keys (gnutls_session_t session, record_parameters_st * params, } static int -_gnutls_init_record_state (record_parameters_st * params, gnutls_protocol_t ver, int read, - record_state_st * state) +_gnutls_init_record_state (record_parameters_st * params, const version_entry_st* ver, + int read, record_state_st * state) { int ret; gnutls_datum_t * iv = NULL; @@ -202,7 +202,7 @@ _gnutls_init_record_state (record_parameters_st * params, gnutls_protocol_t ver, ret = _gnutls_auth_cipher_init (&state->cipher_state, params->cipher, &state->key, iv, - params->mac, &state->mac_secret, (ver==GNUTLS_SSL3)?1:0, 1-read/*1==encrypt*/); + params->mac, &state->mac_secret, (ver->id==GNUTLS_SSL3)?1:0, 1-read/*1==encrypt*/); if (ret < 0 && params->cipher->id != GNUTLS_CIPHER_NULL) return gnutls_assert_val (ret); @@ -304,7 +304,7 @@ _gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch) gnutls_compression_method_t comp_algo; record_parameters_st *params; int ret; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); ret = _gnutls_epoch_get (session, epoch, ¶ms); if (ret < 0) @@ -369,8 +369,7 @@ _gnutls_epoch_set_keys (gnutls_session_t session, uint16_t epoch) dst->compression_method = src->compression_method; \ dst->timestamp = src->timestamp; \ dst->max_record_recv_size = src->max_record_recv_size; \ - dst->max_record_send_size = src->max_record_send_size; \ - dst->version = src->version; + dst->max_record_send_size = src->max_record_send_size static void _gnutls_set_resumed_parameters (gnutls_session_t session) @@ -380,6 +379,7 @@ _gnutls_set_resumed_parameters (gnutls_session_t session) security_parameters_st *dst = &session->security_parameters; CPY_COMMON; + _gnutls_set_current_version(session, src->version); } /* Sets the current connection session to conform with the diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 84d12a17d1..9997365164 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -333,7 +333,7 @@ _gnutls_finished (gnutls_session_t session, int type, void *ret, int sending) else len = session->internals.handshake_hash_buffer_prev_len; - if (!_gnutls_version_has_selectable_prf (gnutls_protocol_get_version(session))) + if (!_gnutls_version_has_selectable_prf (get_version(session))) { rc = _gnutls_hash_fast( GNUTLS_DIG_SHA1, session->internals.handshake_hash_buffer.data, len, &concat[16]); if (rc < 0) @@ -654,6 +654,7 @@ _gnutls_send_finished (gnutls_session_t session, int again) uint8_t *data; int ret; size_t vdata_size = 0; + const version_entry_st* vers; if (again == 0) { @@ -665,7 +666,8 @@ _gnutls_send_finished (gnutls_session_t session, int again) } data = _mbuffer_get_udata_ptr (bufel); - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) + vers = get_version(session); + if (vers->id == GNUTLS_SSL3) { ret = _gnutls_ssl3_finished (session, @@ -728,7 +730,7 @@ _gnutls_recv_finished (gnutls_session_t session) int data_size; int ret; int vrfy_size; - int version = gnutls_protocol_get_version (session); + const version_entry_st* vers = get_version (session); ret = _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_FINISHED, @@ -743,7 +745,7 @@ _gnutls_recv_finished (gnutls_session_t session) vrfy = buf.data; vrfy_size = buf.length; - if (version == GNUTLS_SSL3) + if (vers->id == GNUTLS_SSL3) data_size = 36; else data_size = 12; @@ -755,7 +757,7 @@ _gnutls_recv_finished (gnutls_session_t session) goto cleanup; } - if (version == GNUTLS_SSL3) + if (vers->id == GNUTLS_SSL3) { ret = _gnutls_ssl3_finished (session, @@ -1256,8 +1258,9 @@ _gnutls_handshake_hash_add_recvd (gnutls_session_t session, uint8_t * dataptr, uint32_t datalen) { int ret; + const version_entry_st* vers = get_version (session); - if ((gnutls_protocol_get_version (session) != GNUTLS_DTLS0_9 && + if ((vers->id != GNUTLS_DTLS0_9 && recv_type == GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST) || recv_type == GNUTLS_HANDSHAKE_HELLO_REQUEST) return 0; @@ -1266,7 +1269,7 @@ _gnutls_handshake_hash_add_recvd (gnutls_session_t session, session->internals.handshake_hash_buffer_prev_len = session->internals.handshake_hash_buffer.length; - if (gnutls_protocol_get_version (session) != GNUTLS_DTLS0_9) + if (vers->id != GNUTLS_DTLS0_9) { ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer, header, header_size); @@ -1292,6 +1295,7 @@ _gnutls_handshake_hash_add_sent (gnutls_session_t session, uint8_t * dataptr, uint32_t datalen) { int ret; + const version_entry_st* vers = get_version (session); /* We don't check for GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST because it * is not sent via that channel. @@ -1300,7 +1304,7 @@ _gnutls_handshake_hash_add_sent (gnutls_session_t session, { CHECK_SIZE(datalen); - if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9) + if (vers->id == GNUTLS_DTLS0_9) { /* Old DTLS doesn't include the header in the MAC */ if (datalen < 12) @@ -1834,7 +1838,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) uint8_t *data = NULL; int pos = 0, type; int datalen = 0, ret = 0; - gnutls_protocol_t hver; + const version_entry_st* hver; gnutls_buffer_st extdata; int rehandshake = 0; uint8_t session_id_len = @@ -1878,31 +1882,31 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) session->internals.premaster_set == 0) { if (rehandshake) /* already negotiated version thus version_max == negotiated version */ - hver = session->security_parameters.version; + hver = get_version(session); else /* new handshake. just get the max */ - hver = _gnutls_version_max (session); + hver = version_to_entry(_gnutls_version_max (session)); } else { /* we are resuming a session */ - hver = session->internals.resumed_security_parameters.version; + hver = version_to_entry(session->internals.resumed_security_parameters.version); } - if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0) + if (hver == NULL) { gnutls_assert (); gnutls_free (bufel); return GNUTLS_E_INTERNAL_ERROR; } - _gnutls_version_to_tls(hver, &data[pos], &data[pos+1]); - pos+=2; + data[pos++] = hver->major; + data[pos++] = hver->minor; /* Set the version we advertized as maximum * (RSA uses it). */ - _gnutls_set_adv_version (session, hver); - _gnutls_set_current_version (session, hver); + set_adv_version (session, hver->major, hver->minor); + _gnutls_set_current_version (session, hver->id); if (session->internals.priorities.ssl3_record_version != 0) { @@ -1914,7 +1918,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) */ if (!IS_DTLS(session)) _gnutls_record_set_default_version (session, 3, 0); - else if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9) + else if (hver->id == GNUTLS_DTLS0_9) _gnutls_record_set_default_version (session, 1, 0); else _gnutls_record_set_default_version (session, 254, 255); @@ -1969,7 +1973,7 @@ _gnutls_send_client_hello (gnutls_session_t session, int again) */ if (!session->internals.initial_negotiation_completed && session->security_parameters.entity == GNUTLS_CLIENT && - (gnutls_protocol_get_version (session) == GNUTLS_SSL3 || + (hver->id == GNUTLS_SSL3 || session->internals.priorities.no_extensions != 0)) { ret = @@ -2048,6 +2052,7 @@ _gnutls_send_server_hello (gnutls_session_t session, int again) uint8_t comp; uint8_t session_id_len = session->security_parameters.session_id_size; char buf[2 * TLS_MAX_SESSION_ID_SIZE + 1]; + const version_entry_st* vers; _gnutls_buffer_init(&extdata); @@ -2071,9 +2076,9 @@ _gnutls_send_server_hello (gnutls_session_t session, int again) } data = _mbuffer_get_udata_ptr (bufel); - _gnutls_version_to_tls(session->security_parameters.version, - &data[pos], &data[pos+1]); - pos += 2; + vers = get_version(session); + data[pos++] = vers->major; + data[pos++] = vers->minor; memcpy (&data[pos], session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); @@ -2768,6 +2773,7 @@ send_change_cipher_spec (gnutls_session_t session, int again) uint8_t* data; mbuffer_st * bufel; int ret; + const version_entry_st* vers; if (again == 0) { @@ -2775,7 +2781,9 @@ send_change_cipher_spec (gnutls_session_t session, int again) if (bufel == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9) + vers = get_version (session); + + if (vers->id == GNUTLS_DTLS0_9) _mbuffer_set_uhead_size(bufel, 3); else _mbuffer_set_uhead_size(bufel, 1); @@ -2784,7 +2792,7 @@ send_change_cipher_spec (gnutls_session_t session, int again) data = _mbuffer_get_uhead_ptr (bufel); data[0] = 1; - if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9) + if (vers->id == GNUTLS_DTLS0_9) { _gnutls_write_uint16 (session->internals.dtls.hsk_write_seq, &data[1]); session->internals.dtls.hsk_write_seq++; @@ -2874,6 +2882,7 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init) uint8_t ch; unsigned int ccs_len = 1; unsigned int tleft; + const version_entry_st* vers; ret = handshake_remaining_time(session); if (ret < 0) @@ -2898,7 +2907,9 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init) return gnutls_assert_val(ret); } - if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9) + vers = get_version (session); + + if (vers->id == GNUTLS_DTLS0_9) ccs_len = 3; ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, ccs_len, NULL, @@ -2910,7 +2921,7 @@ _gnutls_recv_handshake_final (gnutls_session_t session, int init) return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9) + if (vers->id == GNUTLS_DTLS0_9) session->internals.dtls.hsk_read_seq++; /* Initialize the connection session (start encryption) - in case of server */ @@ -3410,22 +3421,6 @@ gnutls_handshake_set_max_packet_length (gnutls_session_t session, size_t max) session->internals.max_handshake_data_buffer_size = max; } -void -_gnutls_set_adv_version (gnutls_session_t session, gnutls_protocol_t ver) -{ -uint8_t major, minor; - - _gnutls_version_to_tls(ver, &major, &minor); - set_adv_version (session, major, minor); -} - -gnutls_protocol_t -_gnutls_get_adv_version (gnutls_session_t session) -{ - return _gnutls_version_get (_gnutls_get_adv_version_major (session), - _gnutls_get_adv_version_minor (session)); -} - /** * gnutls_handshake_get_last_in: * @session: is a #gnutls_session_t structure. diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index d9d6ec543d..b6dde229e5 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -483,6 +483,10 @@ typedef struct uint8_t minor; /* defined by the protocol */ transport_t transport; /* Type of transport, stream or datagram */ unsigned int supported:1; /* 0 not supported, > 0 is supported */ + unsigned int explicit_iv:1; + unsigned int extensions:1; /* whether it supports extensions */ + unsigned int selectable_sighash:1; /* whether signatures can be selected */ + unsigned int selectable_prf:1; /* whether the PRF is ciphersuite-defined */ } version_entry_st; @@ -579,6 +583,7 @@ typedef struct * do that? Do they belong in security parameters? */ int do_recv_supplemental, do_send_supplemental; + const version_entry_st* pversion; } security_parameters_st; struct record_state_st @@ -605,8 +610,6 @@ struct record_parameters_st uint16_t epoch; int initialized; -// gnutls_cipher_algorithm_t cipher_algorithm; -// gnutls_mac_algorithm_t mac_algorithm; gnutls_compression_method_t compression_algorithm; const cipher_entry_st* cipher; @@ -1028,25 +1031,21 @@ void _gnutls_free_auth_info (gnutls_session_t session); session->internals.adv_version_major = major; \ session->internals.adv_version_minor = minor -void _gnutls_set_adv_version (gnutls_session_t, gnutls_protocol_t); -gnutls_protocol_t _gnutls_get_adv_version (gnutls_session_t); - int _gnutls_is_secure_mem_null (const void *); -inline static gnutls_protocol_t -_gnutls_protocol_get_version (gnutls_session_t session) +inline static const version_entry_st* +get_version (gnutls_session_t session) { - return session->security_parameters.version; + return session->security_parameters.pversion; } -#define gnutls_protocol_get_version _gnutls_protocol_get_version +#define get_num_version(session) \ + session->security_parameters.version -inline static void -_gnutls_set_current_version (gnutls_session_t session, - gnutls_protocol_t version) -{ - session->security_parameters.version = version; -} +#define _gnutls_set_current_version(s, v) { \ + s->security_parameters.version = v; \ + s->security_parameters.pversion = version_to_entry(v); \ + } #define timespec_sub_ms _gnutls_timespec_sub_ms unsigned int diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 31cff20bb8..a50ed3ec9c 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -110,7 +110,7 @@ generate_normal_master (gnutls_session_t session, gnutls_datum_t *premaster, security_parameters.server_random, 32, buf, sizeof (buf), NULL)); - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) + if (get_num_version (session) == GNUTLS_SSL3) { uint8_t rnd[2 * GNUTLS_RANDOM_SIZE + 1]; @@ -367,7 +367,7 @@ _gnutls_send_client_certificate (gnutls_session_t session, int again) if (again == 0) { - if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 || + if (get_num_version (session) != GNUTLS_SSL3 || session->internals.selected_cert_list_length > 0) { /* TLS 1.0 or SSL 3.0 with a valid certificate @@ -388,7 +388,7 @@ _gnutls_send_client_certificate (gnutls_session_t session, int again) * no certificate alert instead of an * empty certificate. */ - if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 && + if (get_num_version (session) == GNUTLS_SSL3 && session->internals.selected_cert_list_length == 0) { ret = @@ -590,7 +590,7 @@ _gnutls_recv_client_certificate (gnutls_session_t session) */ if (optional != 0 && ret == GNUTLS_E_WARNING_ALERT_RECEIVED && - gnutls_protocol_get_version (session) == GNUTLS_SSL3 && + get_num_version (session) == GNUTLS_SSL3 && gnutls_alert_get (session) == GNUTLS_A_SSL3_NO_CERTIFICATE) { diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 5c82e4c957..a153a7a167 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -1767,7 +1767,7 @@ gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key, */ int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session, gnutls_pubkey_t pubkey, - gnutls_protocol_t ver, + const version_entry_st* ver, gnutls_sign_algorithm_t sign) { unsigned int hash_size; diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index f72deea5dc..5c20214046 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -384,14 +384,15 @@ inline static void copy_record_version (gnutls_session_t session, gnutls_handshake_description_t htype, uint8_t version[2]) { - gnutls_protocol_t lver; + const version_entry_st* lver; if (session->internals.initial_negotiation_completed || htype != GNUTLS_HANDSHAKE_CLIENT_HELLO || session->internals.default_record_version[0] == 0) { - lver = gnutls_protocol_get_version (session); + lver = get_version (session); - _gnutls_version_to_tls(lver, &version[0], &version[1]); + version[0] = lver->major; + version[1] = lver->minor; } else { @@ -647,9 +648,11 @@ inline static int record_check_version (gnutls_session_t session, gnutls_handshake_description_t htype, uint8_t version[2]) { -unsigned vers = gnutls_protocol_get_version (session); -int diff = (vers != - _gnutls_version_get (version[0], version[1])); +const version_entry_st* vers = get_version (session); +int diff = 0; + + if (vers->major != version[0] || vers->minor != version[1]) + diff = 1; if (!IS_DTLS(session)) { @@ -698,14 +701,14 @@ int diff = (vers != return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; } } - else if (vers > GNUTLS_DTLS1_0 && version[0] > 254) + else if (vers->id > GNUTLS_DTLS1_0 && version[0] > 254) { gnutls_assert (); _gnutls_record_log("REC[%p]: INVALID DTLS VERSION PACKET: (%d) %d.%d\n", session, htype, version[0], version[1]); return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; } - else if (vers == GNUTLS_DTLS0_9 && version[0] > 1) + else if (vers->id == GNUTLS_DTLS0_9 && version[0] > 1) { gnutls_assert (); _gnutls_record_log("REC[%p]: INVALID DTLS VERSION PACKET: (%d) %d.%d\n", session, diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c index 59f9762c5d..8a0e229f97 100644 --- a/lib/gnutls_sig.c +++ b/lib/gnutls_sig.c @@ -66,7 +66,7 @@ _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert, int ret; digest_hd_st td_sha; uint8_t concat[MAX_SIG_SIZE]; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); const mac_entry_st* hash_algo; *sign_algo = @@ -171,7 +171,7 @@ sign_tls_hash (gnutls_session_t session, const mac_entry_st* hash_algo, const gnutls_datum_t * hash_concat, gnutls_datum_t * signature) { - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); unsigned int key_usage = 0; /* If our certificate supports signing @@ -233,7 +233,7 @@ es_cleanup: static int verify_tls_hash (gnutls_session_t session, - gnutls_protocol_t ver, gnutls_pcert_st* cert, + const version_entry_st* ver, gnutls_pcert_st* cert, const gnutls_datum_t * hash_concat, gnutls_datum_t * signature, size_t sha1pos, gnutls_sign_algorithm_t sign_algo, @@ -315,7 +315,7 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_pcert_st* cert, digest_hd_st td_md5; digest_hd_st td_sha; uint8_t concat[MAX_SIG_SIZE]; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); gnutls_digest_algorithm_t hash_algo; const mac_entry_st * me; @@ -411,7 +411,7 @@ _gnutls_handshake_verify_crt_vrfy12 (gnutls_session_t session, int ret; uint8_t concat[MAX_HASH_SIZE]; gnutls_datum_t dconcat; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); gnutls_pk_algorithm_t pk = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL); const mac_entry_st *me; @@ -458,7 +458,7 @@ _gnutls_handshake_verify_crt_vrfy (gnutls_session_t session, digest_hd_st td_md5; digest_hd_st td_sha; gnutls_datum_t dconcat; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n", session, gnutls_sign_algorithm_get_name (sign_algo)); @@ -488,7 +488,7 @@ _gnutls_handshake_verify_crt_vrfy (gnutls_session_t session, _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len); _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer_prev_len); - if (ver == GNUTLS_SSL3) + if (ver->id == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) @@ -606,7 +606,7 @@ _gnutls_handshake_sign_crt_vrfy (gnutls_session_t session, uint8_t concat[MAX_SIG_SIZE]; digest_hd_st td_md5; digest_hd_st td_sha; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm(pkey, NULL); if (_gnutls_version_has_selectable_sighash(ver)) @@ -623,7 +623,7 @@ _gnutls_handshake_sign_crt_vrfy (gnutls_session_t session, _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length); - if (ver == GNUTLS_SSL3) + if (ver->id == GNUTLS_SSL3) { ret = _gnutls_generate_master (session, 1); if (ret < 0) @@ -658,7 +658,7 @@ _gnutls_handshake_sign_crt_vrfy (gnutls_session_t session, _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, session->internals.handshake_hash_buffer.length); - if (ver == GNUTLS_SSL3) + if (ver->id == GNUTLS_SSL3) { ret = _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat, session-> diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 01e0a57615..adeb39ac12 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -859,7 +859,7 @@ _gnutls_PRF (gnutls_session_t session, uint8_t s_seed[MAX_SEED_SIZE]; uint8_t o1[MAX_PRF_BYTES], o2[MAX_PRF_BYTES]; int result; - gnutls_protocol_t ver = gnutls_protocol_get_version (session); + const version_entry_st* ver = get_version (session); if (total_bytes > MAX_PRF_BYTES) { @@ -1311,7 +1311,6 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session) return _gnutls_session_ecc_curve_get(session); } -#undef gnutls_protocol_get_version /** * gnutls_protocol_get_version: * @session: is a #gnutls_session_t structure. @@ -1323,7 +1322,7 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session) gnutls_protocol_t gnutls_protocol_get_version (gnutls_session_t session) { - return _gnutls_protocol_get_version(session); + return get_num_version(session); } /** diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index 088f4e4a0c..26335c8d99 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -850,12 +850,12 @@ gnutls_session_get_desc (gnutls_session_t session) type = gnutls_certificate_type_get (session); if (type == GNUTLS_CRT_X509) - snprintf(proto_name, sizeof(proto_name), "%s-PKIX", gnutls_protocol_get_name(_gnutls_protocol_get_version(session))); + snprintf(proto_name, sizeof(proto_name), "%s-PKIX", gnutls_protocol_get_name(get_num_version(session))); else - snprintf(proto_name, sizeof(proto_name), "%s-%s", gnutls_protocol_get_name(_gnutls_protocol_get_version(session)), + snprintf(proto_name, sizeof(proto_name), "%s-%s", gnutls_protocol_get_name(get_num_version(session)), gnutls_certificate_type_get_name(type)); - gnutls_protocol_get_name(_gnutls_protocol_get_version (session)), + gnutls_protocol_get_name(get_num_version (session)), desc = gnutls_malloc(DESC_SIZE); if (desc == NULL) |