diff options
Diffstat (limited to 'lib/ext/server_name.c')
-rw-r--r-- | lib/ext/server_name.c | 693 |
1 files changed, 340 insertions, 353 deletions
diff --git a/lib/ext/server_name.c b/lib/ext/server_name.c index c78a3c30d0..11240280e1 100644 --- a/lib/ext/server_name.c +++ b/lib/ext/server_name.c @@ -26,29 +26,29 @@ #include "gnutls_num.h" #include <ext/server_name.h> -static int _gnutls_server_name_recv_params (gnutls_session_t session, - const uint8_t * data, - size_t data_size); -static int _gnutls_server_name_send_params (gnutls_session_t session, - gnutls_buffer_st* extdata); +static int _gnutls_server_name_recv_params(gnutls_session_t session, + const uint8_t * data, + size_t data_size); +static int _gnutls_server_name_send_params(gnutls_session_t session, + gnutls_buffer_st * extdata); -static int _gnutls_server_name_unpack (gnutls_buffer_st * ps, - extension_priv_data_t * _priv); -static int _gnutls_server_name_pack (extension_priv_data_t _priv, - gnutls_buffer_st * ps); -static void _gnutls_server_name_deinit_data (extension_priv_data_t priv); +static int _gnutls_server_name_unpack(gnutls_buffer_st * ps, + extension_priv_data_t * _priv); +static int _gnutls_server_name_pack(extension_priv_data_t _priv, + gnutls_buffer_st * ps); +static void _gnutls_server_name_deinit_data(extension_priv_data_t priv); extension_entry_st ext_mod_server_name = { - .name = "SERVER NAME", - .type = GNUTLS_EXTENSION_SERVER_NAME, - .parse_type = GNUTLS_EXT_APPLICATION, - - .recv_func = _gnutls_server_name_recv_params, - .send_func = _gnutls_server_name_send_params, - .pack_func = _gnutls_server_name_pack, - .unpack_func = _gnutls_server_name_unpack, - .deinit_func = _gnutls_server_name_deinit_data, + .name = "SERVER NAME", + .type = GNUTLS_EXTENSION_SERVER_NAME, + .parse_type = GNUTLS_EXT_APPLICATION, + + .recv_func = _gnutls_server_name_recv_params, + .send_func = _gnutls_server_name_send_params, + .pack_func = _gnutls_server_name_pack, + .unpack_func = _gnutls_server_name_unpack, + .deinit_func = _gnutls_server_name_deinit_data, }; /* @@ -61,191 +61,189 @@ extension_entry_st ext_mod_server_name = { * */ static int -_gnutls_server_name_recv_params (gnutls_session_t session, - const uint8_t * data, size_t _data_size) +_gnutls_server_name_recv_params(gnutls_session_t session, + const uint8_t * data, size_t _data_size) { - int i; - const unsigned char *p; - uint16_t len, type; - ssize_t data_size = _data_size; - int server_names = 0; - server_name_ext_st *priv; - extension_priv_data_t epriv; - - if (session->security_parameters.entity == GNUTLS_SERVER) - { - DECR_LENGTH_RET (data_size, 2, 0); - len = _gnutls_read_uint16 (data); - - if (len != data_size) - { - /* This is unexpected packet length, but - * just ignore it, for now. - */ - gnutls_assert (); - return 0; - } - - p = data + 2; - - /* Count all server_names in the packet. */ - while (data_size > 0) - { - DECR_LENGTH_RET (data_size, 1, 0); - p++; - - DECR_LEN (data_size, 2); - len = _gnutls_read_uint16 (p); - p += 2; - - if (len > 0) - { - DECR_LENGTH_RET (data_size, len, 0); - server_names++; - p += len; - } - else - _gnutls_handshake_log - ("HSK[%p]: Received (0) size server name (under attack?)\n", - session); - - } - - /* we cannot accept more server names. - */ - if (server_names > MAX_SERVER_NAME_EXTENSIONS) - { - _gnutls_handshake_log - ("HSK[%p]: Too many server names received (under attack?)\n", - session); - server_names = MAX_SERVER_NAME_EXTENSIONS; - } - - if (server_names == 0) - return 0; /* no names found */ - - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - priv->server_names_size = server_names; - - p = data + 2; - for (i = 0; i < server_names; i++) - { - type = *p; - p++; - - len = _gnutls_read_uint16 (p); - p += 2; - - switch (type) - { - case 0: /* NAME_DNS */ - if (len <= MAX_SERVER_NAME_SIZE) - { - memcpy (priv->server_names[i].name, p, len); - priv->server_names[i].name_length = len; - priv->server_names[i].type = GNUTLS_NAME_DNS; - break; - } - } - - /* move to next record */ - p += len; - } - - epriv.ptr = priv; - _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SERVER_NAME, - epriv); - - } - - return 0; + int i; + const unsigned char *p; + uint16_t len, type; + ssize_t data_size = _data_size; + int server_names = 0; + server_name_ext_st *priv; + extension_priv_data_t epriv; + + if (session->security_parameters.entity == GNUTLS_SERVER) { + DECR_LENGTH_RET(data_size, 2, 0); + len = _gnutls_read_uint16(data); + + if (len != data_size) { + /* This is unexpected packet length, but + * just ignore it, for now. + */ + gnutls_assert(); + return 0; + } + + p = data + 2; + + /* Count all server_names in the packet. */ + while (data_size > 0) { + DECR_LENGTH_RET(data_size, 1, 0); + p++; + + DECR_LEN(data_size, 2); + len = _gnutls_read_uint16(p); + p += 2; + + if (len > 0) { + DECR_LENGTH_RET(data_size, len, 0); + server_names++; + p += len; + } else + _gnutls_handshake_log + ("HSK[%p]: Received (0) size server name (under attack?)\n", + session); + + } + + /* we cannot accept more server names. + */ + if (server_names > MAX_SERVER_NAME_EXTENSIONS) { + _gnutls_handshake_log + ("HSK[%p]: Too many server names received (under attack?)\n", + session); + server_names = MAX_SERVER_NAME_EXTENSIONS; + } + + if (server_names == 0) + return 0; /* no names found */ + + priv = gnutls_calloc(1, sizeof(*priv)); + if (priv == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + priv->server_names_size = server_names; + + p = data + 2; + for (i = 0; i < server_names; i++) { + type = *p; + p++; + + len = _gnutls_read_uint16(p); + p += 2; + + switch (type) { + case 0: /* NAME_DNS */ + if (len <= MAX_SERVER_NAME_SIZE) { + memcpy(priv->server_names[i].name, + p, len); + priv->server_names[i].name_length = + len; + priv->server_names[i].type = + GNUTLS_NAME_DNS; + break; + } + } + + /* move to next record */ + p += len; + } + + epriv.ptr = priv; + _gnutls_ext_set_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + epriv); + + } + + return 0; } /* returns data_size or a negative number on failure */ static int -_gnutls_server_name_send_params (gnutls_session_t session, - gnutls_buffer_st* extdata) +_gnutls_server_name_send_params(gnutls_session_t session, + gnutls_buffer_st * extdata) { - uint16_t len; - unsigned i; - int total_size = 0, ret; - server_name_ext_st *priv; - extension_priv_data_t epriv; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SERVER_NAME, - &epriv); - if (ret < 0) - return 0; - - - /* this function sends the client extension data (dnsname) - */ - if (session->security_parameters.entity == GNUTLS_CLIENT) - { - priv = epriv.ptr; - - if (priv->server_names_size == 0) - return 0; - - /* uint16_t - */ - total_size = 2; - for (i = 0; i < priv->server_names_size; i++) - { - /* count the total size - */ - len = priv->server_names[i].name_length; - - /* uint8_t + uint16_t + size - */ - total_size += 1 + 2 + len; - } - - /* UINT16: write total size of all names - */ - ret = _gnutls_buffer_append_prefix(extdata, 16, total_size - 2); - if (ret < 0) - return gnutls_assert_val(ret); - - for (i = 0; i < priv->server_names_size; i++) - { - - switch (priv->server_names[i].type) - { - case GNUTLS_NAME_DNS: - len = priv->server_names[i].name_length; - if (len == 0) - break; - - /* UINT8: type of this extension - * UINT16: size of the first name - * LEN: the actual server name. - */ - ret = _gnutls_buffer_append_prefix(extdata, 8, 0); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_buffer_append_data_prefix(extdata, 16, priv->server_names[i].name, len); - if (ret < 0) - return gnutls_assert_val(ret); - - break; - default: - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - } - } - - return total_size; + uint16_t len; + unsigned i; + int total_size = 0, ret; + server_name_ext_st *priv; + extension_priv_data_t epriv; + + ret = + _gnutls_ext_get_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + &epriv); + if (ret < 0) + return 0; + + + /* this function sends the client extension data (dnsname) + */ + if (session->security_parameters.entity == GNUTLS_CLIENT) { + priv = epriv.ptr; + + if (priv->server_names_size == 0) + return 0; + + /* uint16_t + */ + total_size = 2; + for (i = 0; i < priv->server_names_size; i++) { + /* count the total size + */ + len = priv->server_names[i].name_length; + + /* uint8_t + uint16_t + size + */ + total_size += 1 + 2 + len; + } + + /* UINT16: write total size of all names + */ + ret = + _gnutls_buffer_append_prefix(extdata, 16, + total_size - 2); + if (ret < 0) + return gnutls_assert_val(ret); + + for (i = 0; i < priv->server_names_size; i++) { + + switch (priv->server_names[i].type) { + case GNUTLS_NAME_DNS: + len = priv->server_names[i].name_length; + if (len == 0) + break; + + /* UINT8: type of this extension + * UINT16: size of the first name + * LEN: the actual server name. + */ + ret = + _gnutls_buffer_append_prefix(extdata, + 8, 0); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = + _gnutls_buffer_append_data_prefix + (extdata, 16, + priv->server_names[i].name, len); + if (ret < 0) + return gnutls_assert_val(ret); + + break; + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + } + } + + return total_size; } /** @@ -277,56 +275,51 @@ _gnutls_server_name_send_params (gnutls_session_t session, * otherwise a negative error code is returned. **/ int -gnutls_server_name_get (gnutls_session_t session, void *data, - size_t * data_length, - unsigned int *type, unsigned int indx) +gnutls_server_name_get(gnutls_session_t session, void *data, + size_t * data_length, + unsigned int *type, unsigned int indx) { - char *_data = data; - server_name_ext_st *priv; - int ret; - extension_priv_data_t epriv; - - if (session->security_parameters.entity == GNUTLS_CLIENT) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SERVER_NAME, - &epriv); - if (ret < 0) - { - gnutls_assert (); - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } - - priv = epriv.ptr; - - if (indx + 1 > priv->server_names_size) - { - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } - - *type = priv->server_names[indx].type; - - if (*data_length > /* greater since we need one extra byte for the null */ - priv->server_names[indx].name_length) - { - *data_length = priv->server_names[indx].name_length; - memcpy (data, priv->server_names[indx].name, *data_length); - - if (*type == GNUTLS_NAME_DNS) /* null terminate */ - _data[(*data_length)] = 0; - - } - else - { - *data_length = priv->server_names[indx].name_length + 1; - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - return 0; + char *_data = data; + server_name_ext_st *priv; + int ret; + extension_priv_data_t epriv; + + if (session->security_parameters.entity == GNUTLS_CLIENT) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = + _gnutls_ext_get_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + &epriv); + if (ret < 0) { + gnutls_assert(); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + priv = epriv.ptr; + + if (indx + 1 > priv->server_names_size) { + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + *type = priv->server_names[indx].type; + + if (*data_length > /* greater since we need one extra byte for the null */ + priv->server_names[indx].name_length) { + *data_length = priv->server_names[indx].name_length; + memcpy(data, priv->server_names[indx].name, *data_length); + + if (*type == GNUTLS_NAME_DNS) /* null terminate */ + _data[(*data_length)] = 0; + + } else { + *data_length = priv->server_names[indx].name_length + 1; + return GNUTLS_E_SHORT_MEMORY_BUFFER; + } + + return 0; } /** @@ -350,123 +343,117 @@ gnutls_server_name_get (gnutls_session_t session, void *data, * otherwise a negative error code is returned. **/ int -gnutls_server_name_set (gnutls_session_t session, - gnutls_server_name_type_t type, - const void *name, size_t name_length) +gnutls_server_name_set(gnutls_session_t session, + gnutls_server_name_type_t type, + const void *name, size_t name_length) { - int server_names, ret; - server_name_ext_st *priv; - extension_priv_data_t epriv; - int set = 0; - - if (session->security_parameters.entity == GNUTLS_SERVER) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - - if (name_length > MAX_SERVER_NAME_SIZE) - return GNUTLS_E_SHORT_MEMORY_BUFFER; - - ret = - _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_SERVER_NAME, - &epriv); - if (ret < 0) - { - set = 1; - } - - if (set != 0) - { - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - epriv.ptr = priv; - } - else - priv = epriv.ptr; - - server_names = priv->server_names_size + 1; - - if (server_names > MAX_SERVER_NAME_EXTENSIONS) - server_names = MAX_SERVER_NAME_EXTENSIONS; - - priv->server_names[server_names - 1].type = type; - memcpy (priv->server_names[server_names - 1].name, name, name_length); - priv->server_names[server_names - 1].name_length = name_length; - - priv->server_names_size = server_names; - - if (set != 0) - _gnutls_ext_set_session_data (session, GNUTLS_EXTENSION_SERVER_NAME, - epriv); - - return 0; + int server_names, ret; + server_name_ext_st *priv; + extension_priv_data_t epriv; + int set = 0; + + if (session->security_parameters.entity == GNUTLS_SERVER) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + if (name_length > MAX_SERVER_NAME_SIZE) + return GNUTLS_E_SHORT_MEMORY_BUFFER; + + ret = + _gnutls_ext_get_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + &epriv); + if (ret < 0) { + set = 1; + } + + if (set != 0) { + priv = gnutls_calloc(1, sizeof(*priv)); + if (priv == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + epriv.ptr = priv; + } else + priv = epriv.ptr; + + server_names = priv->server_names_size + 1; + + if (server_names > MAX_SERVER_NAME_EXTENSIONS) + server_names = MAX_SERVER_NAME_EXTENSIONS; + + priv->server_names[server_names - 1].type = type; + memcpy(priv->server_names[server_names - 1].name, name, + name_length); + priv->server_names[server_names - 1].name_length = name_length; + + priv->server_names_size = server_names; + + if (set != 0) + _gnutls_ext_set_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + epriv); + + return 0; } -static void -_gnutls_server_name_deinit_data (extension_priv_data_t priv) +static void _gnutls_server_name_deinit_data(extension_priv_data_t priv) { - gnutls_free (priv.ptr); + gnutls_free(priv.ptr); } static int -_gnutls_server_name_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps) +_gnutls_server_name_pack(extension_priv_data_t epriv, + gnutls_buffer_st * ps) { - server_name_ext_st *priv = epriv.ptr; - unsigned int i; - int ret; - - BUFFER_APPEND_NUM (ps, priv->server_names_size); - for (i = 0; i < priv->server_names_size; i++) - { - BUFFER_APPEND_NUM (ps, priv->server_names[i].type); - BUFFER_APPEND_PFX4 (ps, priv->server_names[i].name, - priv->server_names[i].name_length); - } - return 0; + server_name_ext_st *priv = epriv.ptr; + unsigned int i; + int ret; + + BUFFER_APPEND_NUM(ps, priv->server_names_size); + for (i = 0; i < priv->server_names_size; i++) { + BUFFER_APPEND_NUM(ps, priv->server_names[i].type); + BUFFER_APPEND_PFX4(ps, priv->server_names[i].name, + priv->server_names[i].name_length); + } + return 0; } static int -_gnutls_server_name_unpack (gnutls_buffer_st * ps, - extension_priv_data_t * _priv) +_gnutls_server_name_unpack(gnutls_buffer_st * ps, + extension_priv_data_t * _priv) { - server_name_ext_st *priv; - unsigned int i; - int ret; - extension_priv_data_t epriv; - - priv = gnutls_calloc (1, sizeof (*priv)); - if (priv == NULL) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - BUFFER_POP_NUM (ps, priv->server_names_size); - for (i = 0; i < priv->server_names_size; i++) - { - BUFFER_POP_NUM (ps, priv->server_names[i].type); - BUFFER_POP_NUM (ps, priv->server_names[i].name_length); - if (priv->server_names[i].name_length > - sizeof (priv->server_names[i].name)) - { - gnutls_assert (); - return GNUTLS_E_PARSING_ERROR; - } - BUFFER_POP (ps, priv->server_names[i].name, - priv->server_names[i].name_length); - } - - epriv.ptr = priv; - *_priv = epriv; - - return 0; - -error: - gnutls_free (priv); - return ret; + server_name_ext_st *priv; + unsigned int i; + int ret; + extension_priv_data_t epriv; + + priv = gnutls_calloc(1, sizeof(*priv)); + if (priv == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + BUFFER_POP_NUM(ps, priv->server_names_size); + for (i = 0; i < priv->server_names_size; i++) { + BUFFER_POP_NUM(ps, priv->server_names[i].type); + BUFFER_POP_NUM(ps, priv->server_names[i].name_length); + if (priv->server_names[i].name_length > + sizeof(priv->server_names[i].name)) { + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; + } + BUFFER_POP(ps, priv->server_names[i].name, + priv->server_names[i].name_length); + } + + epriv.ptr = priv; + *_priv = epriv; + + return 0; + + error: + gnutls_free(priv); + return ret; } |