]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
extensions: use the low-level extension parsing code for hello parsing
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 20 Sep 2017 08:05:53 +0000 (10:05 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 19 Feb 2018 14:29:34 +0000 (15:29 +0100)
That's a step towards unification of TLS-type extension handling
for TLS 1.3.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
37 files changed:
lib/ext/alpn.c
lib/ext/alpn.h
lib/ext/dumbfw.c
lib/ext/dumbfw.h
lib/ext/ecc.c
lib/ext/ecc.h
lib/ext/etm.c
lib/ext/etm.h
lib/ext/ext_master_secret.c
lib/ext/ext_master_secret.h
lib/ext/heartbeat.c
lib/ext/heartbeat.h
lib/ext/key_share.c
lib/ext/key_share.h
lib/ext/max_record.c
lib/ext/max_record.h
lib/ext/post_handshake.c
lib/ext/post_handshake.h
lib/ext/safe_renegotiation.c
lib/ext/safe_renegotiation.h
lib/ext/server_name.c
lib/ext/server_name.h
lib/ext/session_ticket.c
lib/ext/session_ticket.h
lib/ext/signature.c
lib/ext/signature.h
lib/ext/srp.c
lib/ext/srp.h
lib/ext/srtp.c
lib/ext/srtp.h
lib/ext/status_request.c
lib/ext/status_request.h
lib/ext/supported_versions.c
lib/ext/supported_versions.h
lib/extensions.c
lib/extensions.h
lib/gnutls_int.h

index 8c554da51cc39e28bd4b727a7b23ac91f6cb6c4f..59ec3a3b226dd73bc14b951440343a55da71cac5 100644 (file)
@@ -34,7 +34,7 @@ static int _gnutls_alpn_send_params(gnutls_session_t session,
 static void _gnutls_alpn_deinit_data(gnutls_ext_priv_data_t priv);
 
 
-const extension_entry_st ext_mod_alpn = {
+const hello_ext_entry_st ext_mod_alpn = {
        .name = "ALPN",
        .tls_id = 16,
        .gid = GNUTLS_EXTENSION_ALPN,
index 60d5266ef6b76f51762d85e8fb114ec3052d7c55..b04eabd1b2aa05485c363b4bb769557eea3ef0b8 100644 (file)
@@ -34,6 +34,6 @@ typedef struct {
        unsigned flags;
 } alpn_ext_st;
 
-extern const extension_entry_st ext_mod_alpn;
+extern const hello_ext_entry_st ext_mod_alpn;
 
 #endif
index 2c25ea5522e43d6d041f59c471f4265eb2cf9555..3ffeeca5603d80593f18ff1d10793dcb49addba6 100644 (file)
@@ -35,7 +35,7 @@
 static int _gnutls_dumbfw_send_params(gnutls_session_t session,
                                    gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_dumbfw = {
+const hello_ext_entry_st ext_mod_dumbfw = {
        .name = "ClientHello Padding",
        .tls_id = 21,
        .gid = GNUTLS_EXTENSION_DUMBFW,
index a3bd756eb80260e43ab9c37f9c443d5a7b5759c7..6ee30e9f6b195c0f48006e41d65f2b1f74b73d47 100644 (file)
@@ -22,6 +22,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_dumbfw;
+extern const hello_ext_entry_st ext_mod_dumbfw;
 
 #endif
index 1679eda59f6f8f16df1a0eda1f0c41c2383218e0..797046bb2f0539f83ea58e69fd79e9f466bba8ed 100644 (file)
@@ -49,7 +49,7 @@ static int _gnutls_supported_ecc_pf_send_params(gnutls_session_t session,
                                                gnutls_buffer_st *
                                                extdata);
 
-const extension_entry_st ext_mod_supported_ecc = {
+const hello_ext_entry_st ext_mod_supported_ecc = {
        .name = "Negotiated Groups",
        .tls_id = 10,
        .gid = GNUTLS_EXTENSION_SUPPORTED_ECC,
@@ -64,7 +64,7 @@ const extension_entry_st ext_mod_supported_ecc = {
        .cannot_be_overriden = 1
 };
 
-const extension_entry_st ext_mod_supported_ecc_pf = {
+const hello_ext_entry_st ext_mod_supported_ecc_pf = {
        .name = "Supported ECC Point Formats",
        .tls_id = 11,
        .gid = GNUTLS_EXTENSION_SUPPORTED_ECC_PF,
index a3b4311f64f5a86258f18f2611f22ad28bc01449..50074843ef324042190792b20e643c55a171513f 100644 (file)
@@ -24,8 +24,8 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_supported_ecc;
-extern const extension_entry_st ext_mod_supported_ecc_pf;
+extern const hello_ext_entry_st ext_mod_supported_ecc;
+extern const hello_ext_entry_st ext_mod_supported_ecc_pf;
 
 int
 _gnutls_session_supports_group(gnutls_session_t session,
index 0fa9805ea4a3dad5f6506d16c7831f81007bb45d..eda7f457eeeb60b1de29e1f1c2265e66e1fbaab6 100644 (file)
@@ -35,7 +35,7 @@ static int _gnutls_ext_etm_recv_params(gnutls_session_t session,
 static int _gnutls_ext_etm_send_params(gnutls_session_t session,
                                          gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_etm = {
+const hello_ext_entry_st ext_mod_etm = {
        .name = "Encrypt-then-MAC",
        .tls_id = 22,
        .gid = GNUTLS_EXTENSION_ETM,
index 5ceeb618d209ddabab5d2960c3bf600305dc27d9..3a14c662c7e9e15e00e58a523f06d11b840b87ca 100644 (file)
@@ -25,6 +25,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_etm;
+extern const hello_ext_entry_st ext_mod_etm;
 
 #endif
index edbc7f6cd68f51fb200954013adb127c9559eb27..4c3c937426516163ad18af92ae85537cfded359f 100644 (file)
@@ -35,7 +35,7 @@ static int _gnutls_ext_master_secret_recv_params(gnutls_session_t session,
 static int _gnutls_ext_master_secret_send_params(gnutls_session_t session,
                                          gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_ext_master_secret = {
+const hello_ext_entry_st ext_mod_ext_master_secret = {
        .name = "Extended Master Secret",
        .tls_id = 23,
        .gid = GNUTLS_EXTENSION_EXT_MASTER_SECRET,
index 04d20ab3fb826a977819eace4003350315a5a7f2..cfe4d26ff21892785fc94e71620b6cd2d22451ac 100644 (file)
@@ -25,6 +25,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_ext_master_secret;
+extern const hello_ext_entry_st ext_mod_ext_master_secret;
 
 #endif
index 1df9fedd0853104506215c39c2c123d36a6700de..32a3c29c439c2dfb1548655978f71f4365457d45 100644 (file)
@@ -522,7 +522,7 @@ _gnutls_heartbeat_unpack(gnutls_buffer_st * ps,
        return ret;
 }
 
-const extension_entry_st ext_mod_heartbeat = {
+const hello_ext_entry_st ext_mod_heartbeat = {
        .name = "Heartbeat",
        .tls_id = 15,
        .gid = GNUTLS_EXTENSION_HEARTBEAT,
index c304e93a36b56a24aec99aa1bd33a09873e3e01c..f319b87b0211bab2319dc839a644ba09f7c41bee 100644 (file)
@@ -36,7 +36,7 @@
 
 #define HEARTBEAT_DEFAULT_POLICY PEER_NOT_ALLOWED_TO_SEND
 
-extern const extension_entry_st ext_mod_heartbeat;
+extern const hello_ext_entry_st ext_mod_heartbeat;
 
 int _gnutls_heartbeat_handle(gnutls_session_t session, mbuffer_st * bufel);
 int _gnutls_heartbeat_enabled(gnutls_session_t session, int local);
index 5354cdec5527bb8fec164a5f4e2bd1f710a5fdf6..ed95a29765dc2768346ef29df51fd08a4a822d9c 100644 (file)
@@ -43,7 +43,7 @@ static int key_share_recv_params(gnutls_session_t session,
 static int key_share_send_params(gnutls_session_t session,
                                             gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_key_share = {
+const hello_ext_entry_st ext_mod_key_share = {
        .name = "Key Share",
        .tls_id = 40,
        .gid = GNUTLS_EXTENSION_KEY_SHARE,
index 11d6345d00f63031fdcbd35dee483daf3bb24604..7e8fd327a6d8a433161553c506bd5cb6478f2b26 100644 (file)
@@ -25,6 +25,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_key_share;
+extern const hello_ext_entry_st ext_mod_key_share;
 
 #endif
index 4f346514760322e4faa15c5a04810912322a5e2b..5b70aba5f2bbea510c7cc5c8cf8177e4dee1bc0f 100644 (file)
@@ -47,7 +47,7 @@ static int _gnutls_mre_num2record(int num);
 static int _gnutls_mre_record2num(uint16_t record_size);
 
 
-const extension_entry_st ext_mod_max_record_size = {
+const hello_ext_entry_st ext_mod_max_record_size = {
        .name = "Maximum Record Size",
        .tls_id = 1,
        .gid = GNUTLS_EXTENSION_MAX_RECORD_SIZE,
index 27e621e93089659529c7de0c4e14c3b106dfb8bc..cdbe6094d3009bfb8af1fd2a0de3a3d2f1d57e9b 100644 (file)
@@ -25,6 +25,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_max_record_size;
+extern const hello_ext_entry_st ext_mod_max_record_size;
 
 #endif
index bb6cc31c094da3e9d19ceeec6a03ac87c8b54d3b..d4bf3123977c5e1515027103edc5badb67fd84e8 100644 (file)
@@ -36,7 +36,7 @@ static int _gnutls_post_handshake_recv_params(gnutls_session_t session,
 static int _gnutls_post_handshake_send_params(gnutls_session_t session,
                                          gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_post_handshake = {
+const hello_ext_entry_st ext_mod_post_handshake = {
        .name = "Post Handshake Auth",
        .tls_id = 49,
        .gid = GNUTLS_EXTENSION_POST_HANDSHAKE,
index 4f48930521fece67ad66e3d02f4f0431d6dbd422..eb4872ccf4816168857c722b9183a4efabd08232 100644 (file)
@@ -25,6 +25,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_post_handshake;
+extern const hello_ext_entry_st ext_mod_post_handshake;
 
 #endif
index ec2791588f9d7706bc4a0cc8242d9665301ce4eb..6870cf0bd9ef63b0e23d0cfb77ee05cad9895e23 100644 (file)
@@ -31,7 +31,7 @@ static int _gnutls_sr_send_params(gnutls_session_t state,
                                  gnutls_buffer_st *);
 static void _gnutls_sr_deinit_data(gnutls_ext_priv_data_t priv);
 
-const extension_entry_st ext_mod_sr = {
+const hello_ext_entry_st ext_mod_sr = {
        .name = "Safe Renegotiation",
        .tls_id = 65281,
        .gid = GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
index 1838d5a08ef91e61a17abfadb70c47e09ee8d36d..e3f0a81d0471861a5b1673f7de3a54461817adcc 100644 (file)
@@ -38,7 +38,7 @@ typedef struct {
        unsigned int connection_using_safe_renegotiation:1;
 } sr_ext_st;
 
-extern const extension_entry_st ext_mod_sr;
+extern const hello_ext_entry_st ext_mod_sr;
 
 int _gnutls_ext_sr_finished(gnutls_session_t session, void *vdata,
                            size_t vdata_size, int dir);
index ffec574e04b00c8f2e7569606610efa4b070b582..649e4d7d02bda3221a25292ddad2d8e0b0f3325f 100644 (file)
@@ -45,7 +45,7 @@ _gnutls_server_name_set_raw(gnutls_session_t session,
                       gnutls_server_name_type_t type,
                       const void *name, size_t name_length);
 
-const extension_entry_st ext_mod_server_name = {
+const hello_ext_entry_st ext_mod_server_name = {
        .name = "Server Name Indication",
        .tls_id = 0,
        .gid = GNUTLS_EXTENSION_SERVER_NAME,
index 95caa33deb4c7c6875113cb89d20f04ca2dbcf56..9b6085a23d49a2dedb5e467adcb7618fa9006b96 100644 (file)
@@ -31,7 +31,7 @@ typedef struct {
        gnutls_server_name_type_t type;
 } server_name_ext_st;
 
-extern const extension_entry_st ext_mod_server_name;
+extern const hello_ext_entry_st ext_mod_server_name;
 
 unsigned _gnutls_server_name_matches_resumed(gnutls_session_t);
 
index 3564db1445ab44fb78b60e55e2dcd78e1ed4556c..459f39bcdbf00563873a06cedbad93015e1a6359 100644 (file)
@@ -59,7 +59,7 @@ static int session_ticket_pack(gnutls_ext_priv_data_t _priv,
                               gnutls_buffer_st * ps);
 static void session_ticket_deinit_data(gnutls_ext_priv_data_t priv);
 
-const extension_entry_st ext_mod_session_ticket = {
+const hello_ext_entry_st ext_mod_session_ticket = {
        .name = "Session Ticket",
        .tls_id = 35,
        .gid = GNUTLS_EXTENSION_SESSION_TICKET,
index 5c862d28d0038b112c817d3e51e343ea1df68f3d..f82565b07327612e429c72a52cd09c1f121329b1 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_session_ticket;
+extern const hello_ext_entry_st ext_mod_session_ticket;
 
 int _gnutls_send_new_session_ticket(gnutls_session_t session, int again);
 int _gnutls_recv_new_session_ticket(gnutls_session_t session);
index f41c91e46bc495fe1aea5f796f94c96f87925295..1301d821d9fcae2a02971cbbaa4aa44cb01ae0e7 100644 (file)
@@ -49,7 +49,7 @@ static int signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
 static int signature_algorithms_unpack(gnutls_buffer_st * ps,
                                       gnutls_ext_priv_data_t * _priv);
 
-const extension_entry_st ext_mod_sig = {
+const hello_ext_entry_st ext_mod_sig = {
        .name = "Signature Algorithms",
        .tls_id = 13,
        .gid = GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
index 5e8f710c1373e13e029f7f78adfb053c55d18f2b..373af2fa86f07a8ee00916d4b0c6eca06ce62dea 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_sig;
+extern const hello_ext_entry_st ext_mod_sig;
 
 gnutls_sign_algorithm_t
 _gnutls_session_get_sign_algo(gnutls_session_t session,
index 1980e169da319417a3a4c5b4cffb095de6ce57b7..d6f87b5d4c9832c9655f66255cf55c5867faf17e 100644 (file)
@@ -42,7 +42,7 @@ static int _gnutls_srp_recv_params(gnutls_session_t state,
 static int _gnutls_srp_send_params(gnutls_session_t state,
                                   gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_srp = {
+const hello_ext_entry_st ext_mod_srp = {
        .name = "SRP",
        .tls_id = 12,
        .gid = GNUTLS_EXTENSION_SRP,
index 00b8e2ba0efbaf7273d8e93efb106f123892e4c7..a18efc978071cb7bc69da73dc042f3aa3f3ad729 100644 (file)
@@ -30,7 +30,7 @@
 #define IS_SRP_KX(kx) ((kx == GNUTLS_KX_SRP || (kx == GNUTLS_KX_SRP_RSA) || \
          kx == GNUTLS_KX_SRP_DSS)?1:0)
 
-extern const extension_entry_st ext_mod_srp;
+extern const hello_ext_entry_st ext_mod_srp;
 
 typedef struct {
        char *username;
index a513feabd6ce334ed5d85246e34b6ed10a64c371..1931327d65336f995396eee1480ff3a0a2038cf6 100644 (file)
@@ -39,7 +39,7 @@ static int _gnutls_srtp_pack(gnutls_ext_priv_data_t _priv,
 static void _gnutls_srtp_deinit_data(gnutls_ext_priv_data_t priv);
 
 
-const extension_entry_st ext_mod_srtp = {
+const hello_ext_entry_st ext_mod_srtp = {
        .name = "SRTP",
        .tls_id = 14,
        .gid = GNUTLS_EXTENSION_SRTP,
index 7846fa29420ab050491cb24698f82a32e737c8d8..82482e577f7d269e241f9e58cc128c8a359a875b 100644 (file)
@@ -35,6 +35,6 @@ typedef struct {
        unsigned int mki_received;
 } srtp_ext_st;
 
-extern const extension_entry_st ext_mod_srtp;
+extern const hello_ext_entry_st ext_mod_srtp;
 
 #endif
index ae5b6b7298c9b46822aa63996f69a9fa56b9f60f..8a3515d199f6e2c884319810b56b767c575ec3ed 100644 (file)
@@ -529,7 +529,7 @@ _gnutls_status_request_unpack(gnutls_buffer_st * ps,
        return ret;
 }
 
-const extension_entry_st ext_mod_status_request = {
+const hello_ext_entry_st ext_mod_status_request = {
        .name = "OCSP Status Request",
        .tls_id = 5,
        .gid = GNUTLS_EXTENSION_STATUS_REQUEST,
index 81809b1f6510ceae262c8b0bdb958a868f3c961d..f01d54724f5fb501551509d85f1e9dc36013924d 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_status_request;
+extern const hello_ext_entry_st ext_mod_status_request;
 
 int
 _gnutls_send_server_certificate_status(gnutls_session_t session,
index 26d652b037b4cf9d279b84fdec8ff8db5c63377d..5ffb9bb4bac326439e8e549aae335a28022e63d6 100644 (file)
@@ -36,7 +36,7 @@ static int supported_versions_recv_params(gnutls_session_t session,
 static int supported_versions_send_params(gnutls_session_t session,
                                          gnutls_buffer_st * extdata);
 
-const extension_entry_st ext_mod_supported_versions = {
+const hello_ext_entry_st ext_mod_supported_versions = {
        .name = "Supported Versions",
        .tls_id = 43,
        .gid = GNUTLS_EXTENSION_SUPPORTED_VERSIONS,
index 288851c5dbaa4a6530f6a67a174251d49eaa2b2a..7eb0abfbf2aff40ee2b18906da206e25a90dd335 100644 (file)
@@ -25,6 +25,6 @@
 
 #include <extensions.h>
 
-extern const extension_entry_st ext_mod_supported_versions;
+extern const hello_ext_entry_st ext_mod_supported_versions;
 
 #endif
index 8ebf4ab378786b972d9beecbf403439c7bdfd92d..c338f6fc0c1c4ef3a363e4f5e8cb1afbaf76a387 100644 (file)
 #include <ext/dumbfw.h>
 #include <ext/key_share.h>
 #include <ext/etm.h>
+#include "extv.h"
 #include <num.h>
 
 static void
-unset_ext_data(gnutls_session_t session, const struct extension_entry_st *, unsigned idx);
+unset_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *, unsigned idx);
 
-static int ext_register(extension_entry_st * mod);
-static void unset_resumed_ext_data(gnutls_session_t session, const struct extension_entry_st *, unsigned idx);
+static int ext_register(hello_ext_entry_st * mod);
+static void unset_resumed_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *, unsigned idx);
 
-static extension_entry_st const *extfunc[MAX_EXT_TYPES+1] = {
+static hello_ext_entry_st const *extfunc[MAX_EXT_TYPES+1] = {
        &ext_mod_max_record_size,
        &ext_mod_ext_master_secret,
        &ext_mod_supported_versions,
@@ -91,11 +92,11 @@ static extension_entry_st const *extfunc[MAX_EXT_TYPES+1] = {
        NULL
 };
 
-static const extension_entry_st *
+static const hello_ext_entry_st *
 _gnutls_ext_ptr(gnutls_session_t session, extensions_t id, gnutls_ext_parse_type_t parse_type)
 {
        unsigned i;
-       const extension_entry_st *e;
+       const hello_ext_entry_st *e;
 
        for (i=0;i<session->internals.rexts_size;i++) {
                if (session->internals.rexts[i].gid == id) {
@@ -163,127 +164,113 @@ void _gnutls_extension_list_add_sr(gnutls_session_t session)
        _gnutls_extension_list_add(session, &ext_mod_sr, 1);
 }
 
-int
-_gnutls_parse_extensions(gnutls_session_t session,
-                        gnutls_ext_flags_t msg,
-                        gnutls_ext_parse_type_t parse_type,
-                        const uint8_t * data, int data_size)
-{
-       int next, ret;
-       int pos = 0;
-       uint16_t tls_id;
-       extensions_t id;
-       const uint8_t *sdata;
-       const extension_entry_st *ext;
-       uint16_t size;
-
-       if (data_size == 0)
-               return 0;
+typedef struct hello_ext_ctx_st {
+       gnutls_session_t session;
+       gnutls_ext_flags_t msg;
+       gnutls_ext_parse_type_t parse_type;
+       const hello_ext_entry_st *ext; /* used during send */
+} hello_ext_ctx_st;
 
-       DECR_LENGTH_RET(data_size, 2, GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
-       next = _gnutls_read_uint16(data);
-       pos += 2;
-
-       DECR_LENGTH_RET(data_size, next, GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
+static
+int hello_ext_parse(void *_ctx, uint16_t tls_id, const uint8_t *data, int data_size)
+{
+       hello_ext_ctx_st *ctx = _ctx;
+       gnutls_session_t session = ctx->session;
+       const hello_ext_entry_st *ext;
+       unsigned id;
+       int ret;
 
-       if (next == 0 && data_size == 0) /* field is present, but has zero length? Ignore it. */
+       id = tls_id_to_gid(session, tls_id);
+       if (id == 0) { /* skip */
                return 0;
-       else if (data_size > 0) /* forbid unaccounted data */
-               return gnutls_assert_val(GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
-
-       do {
-               DECR_LENGTH_RET(next, 2, GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
-               tls_id = _gnutls_read_uint16(&data[pos]);
-               pos += 2;
-
-               id = tls_id_to_gid(session, tls_id);
-               if (id == 0) {
-                       goto skip;
-               }
+       }
 
-               if (session->security_parameters.entity == GNUTLS_CLIENT) {
-                       if ((ret =
-                            _gnutls_extension_list_check(session, id)) < 0) {
-                               _gnutls_debug_log("EXT[%p]: Received unexpected extension '%s/%d'\n", session,
-                                               gnutls_ext_get_name(tls_id), (int)tls_id);
-                               gnutls_assert();
-                               return ret;
-                       }
+       if (session->security_parameters.entity == GNUTLS_CLIENT) {
+               if ((ret =
+                    _gnutls_extension_list_check(session, id)) < 0) {
+                       _gnutls_debug_log("EXT[%p]: Received unexpected extension '%s/%d'\n", session,
+                                       gnutls_ext_get_name(tls_id), (int)tls_id);
+                       gnutls_assert();
+                       return ret;
                }
+       }
 
- skip:
-               DECR_LENGTH_RET(next, 2, GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
-               size = _gnutls_read_uint16(&data[pos]);
-               pos += 2;
-
-               DECR_LENGTH_RET(next, size, GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
-               sdata = &data[pos];
-               pos += size;
-
-               ext = _gnutls_ext_ptr(session, id, parse_type);
-               if (ext == NULL || ext->recv_func == NULL) {
-                       _gnutls_handshake_log
-                           ("EXT[%p]: Ignoring extension '%s/%d'\n", session,
-                            gnutls_ext_get_name(tls_id), tls_id);
+       ext = _gnutls_ext_ptr(session, id, ctx->parse_type);
+       if (ext == NULL || ext->recv_func == NULL) {
+               _gnutls_handshake_log
+                   ("EXT[%p]: Ignoring extension '%s/%d'\n", session,
+                    gnutls_ext_get_name(tls_id), tls_id);
+               return 0;
+       }
 
-                       continue;
-               }
+       if ((ext->validity & ctx->msg) == 0) {
+               _gnutls_debug_log("EXT[%p]: Received unexpected extension (%s/%d) for '%s'\n", session,
+                                 gnutls_ext_get_name(tls_id), (int)tls_id,
+                                 ext_msg_validity_to_str(ctx->msg));
+               return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
+       }
 
+       if (session->security_parameters.entity == GNUTLS_SERVER) {
+               ret = _gnutls_extension_list_add(session, ext, 1);
+               if (ret == 0)
+                       return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
+       }
 
-               if ((ext->validity & msg) == 0) {
+       _gnutls_handshake_log
+           ("EXT[%p]: Parsing extension '%s/%d' (%d bytes)\n",
+            session, gnutls_ext_get_name(tls_id), tls_id,
+            data_size);
 
-                       _gnutls_debug_log("EXT[%p]: Received unexpected extension (%s/%d) for '%s'\n", session,
-                                         gnutls_ext_get_name(tls_id), (int)tls_id,
-                                         ext_msg_validity_to_str(msg));
-                       return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
-               }
+       if ((ret = ext->recv_func(session, data, data_size)) < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-               if (session->security_parameters.entity == GNUTLS_SERVER) {
-                       ret = _gnutls_extension_list_add(session, ext, 1);
-                       if (ret == 0)
-                               return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
-               }
+       return 0;
+}
 
-               _gnutls_handshake_log
-                   ("EXT[%p]: Parsing extension '%s/%d' (%d bytes)\n",
-                    session, gnutls_ext_get_name(tls_id), tls_id,
-                    size);
+int
+_gnutls_parse_extensions(gnutls_session_t session,
+                        gnutls_ext_flags_t msg,
+                        gnutls_ext_parse_type_t parse_type,
+                        const uint8_t * data, int data_size)
+{
+       int ret;
+       hello_ext_ctx_st ctx;
 
-               if ((ret = ext->recv_func(session, sdata, size)) < 0) {
-                       gnutls_assert();
-                       return ret;
-               }
-       }
-       while (next > 2);
+       ctx.session = session;
+       ctx.msg = msg;
+       ctx.parse_type = parse_type;
 
-       /* forbid leftovers */
-       if (next > 0)
-               return gnutls_assert_val(GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
+       ret = _gnutls_extv_parse(&ctx, hello_ext_parse, data, data_size);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
 
        return 0;
-
 }
 
 static
-int send_extension(gnutls_session_t session, const extension_entry_st *p,
-                  gnutls_buffer_st *extdata,
-                  gnutls_ext_flags_t msg,
-                  gnutls_ext_parse_type_t parse_type)
+int hello_ext_send(void *_ctx, gnutls_buffer_st *buf)
 {
-       int size_pos, appended, ret;
+       hello_ext_ctx_st *ctx = _ctx;
+       int ret;
+       const hello_ext_entry_st *p = ctx->ext;
+       gnutls_session_t session = ctx->session;
+       int appended;
        size_t size_prev;
 
-       if (p->send_func == NULL)
+       if (unlikely(p->send_func == NULL))
                return 0;
 
-       if (parse_type != GNUTLS_EXT_ANY
-           && p->parse_type != parse_type)
+       if (ctx->parse_type != GNUTLS_EXT_ANY
+           && p->parse_type != ctx->parse_type) {
                return 0;
+       }
 
-       if ((msg & p->validity) == 0) {
+       if ((ctx->msg & p->validity) == 0) {
                _gnutls_handshake_log("EXT[%p]: Not sending extension (%s/%d) for '%s'\n", session,
-                                 gnutls_ext_get_name(p->tls_id), (int)p->tls_id,
-                                 ext_msg_validity_to_str(msg));
+                                 p->name, (int)p->tls_id,
+                                 ext_msg_validity_to_str(ctx->msg));
                return 0;
        }
 
@@ -292,97 +279,90 @@ int send_extension(gnutls_session_t session, const extension_entry_st *p,
        ret = _gnutls_extension_list_check(session, p->gid);
 
        if (session->security_parameters.entity == GNUTLS_SERVER) {
-               if (ret < 0) /* not advertized */
+               if (ret < 0) {/* not advertized */
                        return 0;
+               }
        } else {
-               if (ret == 0) /* already sent */
+               if (ret == 0) {/* already sent */
                        return 0;
+               }
        }
 
-       ret = _gnutls_buffer_append_prefix(extdata, 16, p->tls_id);
-       if (ret < 0)
-               return gnutls_assert_val(ret);
 
-       size_pos = extdata->length;
-       ret = _gnutls_buffer_append_prefix(extdata, 16, 0);
-       if (ret < 0)
-               return gnutls_assert_val(ret);
+       size_prev = buf->length;
 
-       size_prev = extdata->length;
-       ret = p->send_func(session, extdata);
+       ret = p->send_func(session, buf);
        if (ret < 0 && ret != GNUTLS_E_INT_RET_0) {
                return gnutls_assert_val(ret);
        }
 
-       /* returning GNUTLS_E_INT_RET_0 means to send an empty
-        * extension of this type.
-        */
-       appended = extdata->length - size_prev;
-
-       if (appended > 0 || ret == GNUTLS_E_INT_RET_0) {
-               if (ret == GNUTLS_E_INT_RET_0)
-                       appended = 0;
+       appended = buf->length - size_prev;
 
-               /* write the real size */
-               _gnutls_write_uint16(appended,
-                                    &extdata->data[size_pos]);
-
-               /* add this extension to the extension list
-                */
-               if (session->security_parameters.entity == GNUTLS_CLIENT)
-                       _gnutls_extension_list_add(session, p, 0);
+       /* add this extension to the extension list, to know which extensions
+        * to expect.
+        */
+       if ((appended > 0 || ret == GNUTLS_E_INT_RET_0) &&
+           session->security_parameters.entity == GNUTLS_CLIENT) {
 
-               _gnutls_handshake_log
-                           ("EXT[%p]: Sending extension %s/%d (%d bytes)\n",
-                            session, p->name, (int)p->tls_id, appended);
-       } else if (appended == 0)
-               extdata->length -= 4;   /* reset type and size */
+               _gnutls_extension_list_add(session, p, 0);
+       }
 
-       return 0;
+       return ret;
 }
 
 int
 _gnutls_gen_extensions(gnutls_session_t session,
-                      gnutls_buffer_st * extdata,
+                      gnutls_buffer_st * buf,
                       gnutls_ext_flags_t msg,
                       gnutls_ext_parse_type_t parse_type)
 {
-       int size;
        int pos, ret;
-       size_t i, init_size = extdata->length;
+       size_t i;
+       hello_ext_ctx_st ctx;
 
-       pos = extdata->length;  /* we will store length later on */
+       ctx.session = session;
+       ctx.msg = msg;
+       ctx.parse_type = parse_type;
 
-       ret = _gnutls_buffer_append_prefix(extdata, 16, 0);
+       ret = _gnutls_extv_append_init(buf);
        if (ret < 0)
                return gnutls_assert_val(ret);
 
+       pos = ret;
+
        for (i=0; i < session->internals.rexts_size; i++) {
-               ret = send_extension(session, &session->internals.rexts[i], extdata, msg, parse_type);
+               ctx.ext = &session->internals.rexts[i];
+               ret = _gnutls_extv_append(buf, session->internals.rexts[i].tls_id,
+                                         &ctx, hello_ext_send);
                if (ret < 0)
                        return gnutls_assert_val(ret);
+
+               if (ret > 0)
+                       _gnutls_handshake_log
+                                   ("EXT[%p]: Sending extension %s/%d (%d bytes)\n",
+                                    session, ctx.ext->name, (int)ctx.ext->tls_id, ret-4);
        }
 
        /* send_extension() ensures we don't send duplicates, in case
         * of overriden extensions */
        for (i = 0; extfunc[i] != NULL; i++) {
-               ret = send_extension(session, extfunc[i], extdata, msg, parse_type);
+               ctx.ext = extfunc[i];
+               ret = _gnutls_extv_append(buf, extfunc[i]->tls_id,
+                                         &ctx, hello_ext_send);
                if (ret < 0)
                        return gnutls_assert_val(ret);
-       }
-
-       /* remove any initial data, and the size of the header */
-       size = extdata->length - init_size - 2;
 
-       if (size > UINT16_MAX) /* sent too many extensions */
-               return gnutls_assert_val(GNUTLS_E_HANDSHAKE_TOO_LARGE);
+               if (ret > 0)
+                       _gnutls_handshake_log
+                                   ("EXT[%p]: Sending extension %s/%d (%d bytes)\n",
+                                    session, ctx.ext->name, (int)ctx.ext->tls_id, ret-4);
+       }
 
-       if (size > 0)
-               _gnutls_write_uint16(size, &extdata->data[pos]);
-       else if (size == 0)
-               extdata->length -= 2;   /* the length bytes */
+       ret = _gnutls_extv_append_final(buf, pos);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
 
-       return size;
+       return 0;
 }
 
 /* Global deinit and init of global extensions */
@@ -404,7 +384,7 @@ void _gnutls_ext_deinit(void)
 }
 
 static
-int ext_register(extension_entry_st * mod)
+int ext_register(hello_ext_entry_st * mod)
 {
        unsigned i = 0;
 
@@ -422,7 +402,7 @@ int ext_register(extension_entry_st * mod)
 }
 
 /* Packing of extension data (for use in resumption) */
-static int pack_extension(gnutls_session_t session, const extension_entry_st *extp,
+static int pack_extension(gnutls_session_t session, const hello_ext_entry_st *extp,
                          gnutls_buffer_st *packed)
 {
        int ret;
@@ -463,7 +443,7 @@ int _gnutls_ext_pack(gnutls_session_t session, gnutls_buffer_st *packed)
        int ret;
        int total_exts_pos;
        int n_exts = 0;
-       const struct extension_entry_st *ext;
+       const struct hello_ext_entry_st *ext;
 
        total_exts_pos = packed->length;
        BUFFER_APPEND_NUM(packed, 0);
@@ -495,7 +475,7 @@ _gnutls_ext_set_resumed_session_data(gnutls_session_t session,
                                     gnutls_ext_priv_data_t data)
 {
        int i;
-       const struct extension_entry_st *ext;
+       const struct hello_ext_entry_st *ext;
 
        ext = _gnutls_ext_ptr(session, id, GNUTLS_EXT_ANY);
 
@@ -521,7 +501,7 @@ int _gnutls_ext_unpack(gnutls_session_t session, gnutls_buffer_st * packed)
        int max_exts = 0;
        extensions_t id;
        int size_for_id, cur_pos;
-       const struct extension_entry_st *ext;
+       const struct hello_ext_entry_st *ext;
 
        BUFFER_POP_NUM(packed, max_exts);
        for (i = 0; i < max_exts; i++) {
@@ -559,7 +539,7 @@ int _gnutls_ext_unpack(gnutls_session_t session, gnutls_buffer_st * packed)
 }
 
 static void
-unset_ext_data(gnutls_session_t session, const struct extension_entry_st *ext, unsigned idx)
+unset_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *ext, unsigned idx)
 {
        if (session->internals.ext_data[idx].set == 0)
                return;
@@ -574,7 +554,7 @@ _gnutls_ext_unset_session_data(gnutls_session_t session,
                                extensions_t id)
 {
        int i;
-       const struct extension_entry_st *ext;
+       const struct hello_ext_entry_st *ext;
 
        ext = _gnutls_ext_ptr(session, id, GNUTLS_EXT_ANY);
 
@@ -586,7 +566,7 @@ _gnutls_ext_unset_session_data(gnutls_session_t session,
        }
 }
 
-static void unset_resumed_ext_data(gnutls_session_t session, const struct extension_entry_st *ext, unsigned idx)
+static void unset_resumed_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *ext, unsigned idx)
 {
        if (session->internals.ext_data[idx].resumed_set == 0)
                return;
@@ -602,7 +582,7 @@ static void unset_resumed_ext_data(gnutls_session_t session, const struct extens
 void _gnutls_ext_free_session_data(gnutls_session_t session)
 {
        unsigned int i;
-       const struct extension_entry_st *ext;
+       const struct hello_ext_entry_st *ext;
 
        for (i = 0; i < MAX_EXT_TYPES; i++) {
                if (!session->internals.ext_data[i].set && !session->internals.ext_data[i].resumed_set)
@@ -624,7 +604,7 @@ _gnutls_ext_set_session_data(gnutls_session_t session, extensions_t id,
                             gnutls_ext_priv_data_t data)
 {
        unsigned int i;
-       const struct extension_entry_st *ext;
+       const struct hello_ext_entry_st *ext;
 
        ext = _gnutls_ext_ptr(session, id, GNUTLS_EXT_ANY);
 
@@ -713,7 +693,7 @@ gnutls_ext_register(const char *name, int id, gnutls_ext_parse_type_t parse_type
                    gnutls_ext_deinit_data_func deinit_func, gnutls_ext_pack_func pack_func,
                    gnutls_ext_unpack_func unpack_func)
 {
-       extension_entry_st *tmp_mod;
+       hello_ext_entry_st *tmp_mod;
        int ret;
        unsigned i;
        unsigned gid = GNUTLS_EXTENSION_MAX+1;
@@ -799,8 +779,8 @@ gnutls_session_ext_register(gnutls_session_t session,
                            gnutls_ext_deinit_data_func deinit_func, gnutls_ext_pack_func pack_func,
                            gnutls_ext_unpack_func unpack_func, unsigned flags)
 {
-       extension_entry_st tmp_mod;
-       extension_entry_st *exts;
+       hello_ext_entry_st tmp_mod;
+       hello_ext_entry_st *exts;
        unsigned i;
        unsigned gid = GNUTLS_EXTENSION_MAX+1;
 
@@ -832,7 +812,7 @@ gnutls_session_ext_register(gnutls_session_t session,
        if (gid > GNUTLS_EXTENSION_MAX_VALUE)
                return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
 
-       memset(&tmp_mod, 0, sizeof(extension_entry_st));
+       memset(&tmp_mod, 0, sizeof(hello_ext_entry_st));
        tmp_mod.free_struct = 1;
        tmp_mod.tls_id = id;
        tmp_mod.gid = gid;
@@ -855,7 +835,7 @@ gnutls_session_ext_register(gnutls_session_t session,
 
        session->internals.rexts = exts;
 
-       memcpy(&session->internals.rexts[session->internals.rexts_size], &tmp_mod, sizeof(extension_entry_st));
+       memcpy(&session->internals.rexts[session->internals.rexts_size], &tmp_mod, sizeof(hello_ext_entry_st));
        session->internals.rexts_size++;
 
        return 0;
index b1a47ecf36ef4e0dff0cfecbe745927ada375fbb..364ec3b349bd0c7a2c9121fed35128d6cab8fafa 100644 (file)
@@ -79,7 +79,7 @@ inline static const char *ext_msg_validity_to_str(gnutls_ext_flags_t msg)
        }
 }
 
-typedef struct extension_entry_st {
+typedef struct hello_ext_entry_st {
        const char *name; /* const overriden when free_struct is set */
        unsigned free_struct;
 
@@ -113,9 +113,9 @@ typedef struct extension_entry_st {
         * gnutls_init(), or modify the TLS protocol in a way that the application
         * cannot control. */
        unsigned cannot_be_overriden;
-} extension_entry_st;
+} hello_ext_entry_st;
 
-int _gnutls_ext_register(extension_entry_st *);
+int _gnutls_ext_register(hello_ext_entry_st *);
 
 void _gnutls_extension_list_add_sr(gnutls_session_t session);
 
@@ -143,7 +143,7 @@ _gnutls_extension_list_check(gnutls_session_t session, extensions_t id)
  */
 inline static
 unsigned _gnutls_extension_list_add(gnutls_session_t session,
-                                   const struct extension_entry_st *e,
+                                   const struct hello_ext_entry_st *e,
                                    unsigned check_dup)
 {
        if (check_dup && _gnutls_extension_list_check(session, e->gid) == 0) {
index 50ffc14ecb1545cc9bf7d54363db438f5a94696a..a010400a5262c98030e0611f1fefe86b1916bf46 100644 (file)
@@ -1138,7 +1138,7 @@ typedef struct {
        struct gnutls_supplemental_entry_st *rsup;
        unsigned rsup_size;
 
-       struct extension_entry_st *rexts;
+       struct hello_ext_entry_st *rexts;
        unsigned rexts_size;
 
        struct {