]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
session resumption: lift the limitation of calling gnutls_session_get_data*() on...
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 31 Mar 2016 07:40:09 +0000 (09:40 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 31 Mar 2016 11:28:49 +0000 (13:28 +0200)
This allows of obtaining the session data required for proper session resumption
from any available session. This brings the API in par with expectations of its
users.

Resolves #79

lib/gnutls_int.h
lib/session.c
lib/state.c

index cae335209792ed1e42bcb4d4c5c9e97b2a91730d..484bea6edd7e796ccb91c2cb5fd63a601084d182 100644 (file)
@@ -789,6 +789,7 @@ typedef struct {
        bool resumed;   /* RESUME_TRUE or FALSE - if we are resuming a session */
        bool resumption_requested;      /* non-zero if resumption was requested by client */
        security_parameters_st resumed_security_parameters;
+       gnutls_datum_t resumption_data; /* copy of input to gnutls_session_set_data() */
 
        /* These buffers are used in the handshake
         * protocol only. freed using _gnutls_handshake_io_buffer_clear();
index 549b759e58bfcd3efb0b43f1687d349665763e8f..4fd0abac124b71a3b7ac9510d5f61d192e62e5c7 100644 (file)
@@ -34,8 +34,6 @@
  * Returns all session parameters needed to be stored to support resumption.
  * The client should call this, and store the returned session data. A session
  * may be resumed later by calling gnutls_session_set_data().  
- * This function must be called after a successful (full) handshake. It should
- * not be used in already resumed sessions --see gnutls_session_is_resumed().
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
  *   an error code is returned.
@@ -48,12 +46,7 @@ gnutls_session_get_data(gnutls_session_t session,
        gnutls_datum_t psession;
        int ret;
 
-       if (session->internals.resumable == RESUME_FALSE)
-               return GNUTLS_E_INVALID_SESSION;
-
-       psession.data = session_data;
-
-       ret = _gnutls_session_pack(session, &psession);
+       ret = gnutls_session_get_data2(session, &psession);
        if (ret < 0) {
                gnutls_assert();
                return ret;
@@ -84,8 +77,6 @@ gnutls_session_get_data(gnutls_session_t session,
  * Returns all session parameters needed to be stored to support resumption.
  * The client should call this, and store the returned session data. A session
  * may be resumed later by calling gnutls_session_set_data().  
- * This function must be called after a successful (full) handshake. It should
- * not be used in already resumed sessions --see gnutls_session_is_resumed().
  *
  * The returned @data are allocated and must be released using gnutls_free().
  *
@@ -93,13 +84,21 @@ gnutls_session_get_data(gnutls_session_t session,
  *   an error code is returned.
  **/
 int
-gnutls_session_get_data2(gnutls_session_t session, gnutls_datum_t * data)
+gnutls_session_get_data2(gnutls_session_t session, gnutls_datum_t *data)
 {
 
        int ret;
 
        if (data == NULL) {
-               return GNUTLS_E_INVALID_REQUEST;
+               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+       }
+
+       if (gnutls_session_is_resumed(session) && session->internals.resumption_data.data) {
+               ret = _gnutls_set_datum(data, session->internals.resumption_data.data, session->internals.resumption_data.size);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+
+               return 0;
        }
 
        if (session->internals.resumable == RESUME_FALSE)
@@ -220,6 +219,10 @@ gnutls_session_set_data(gnutls_session_t session,
 
        session->internals.resumption_requested = 1;
 
+       if (session->internals.resumption_data.data != NULL)
+               gnutls_free(session->internals.resumption_data.data);
+       _gnutls_set_datum(&session->internals.resumption_data, session_data, session_data_size);
+
        return 0;
 }
 
index 2c8738c462a2b693664e49ec4ce2b64225196062..d312da9edc3a03007afdbdea20cd2e05b98b8c18 100644 (file)
@@ -504,6 +504,8 @@ void gnutls_deinit(gnutls_session_t session)
        _mbuffer_head_clear(&session->internals.record_recv_buffer);
        _mbuffer_head_clear(&session->internals.record_send_buffer);
 
+       _gnutls_free_datum(&session->internals.resumption_data);
+
        gnutls_credentials_clear(session);
        _gnutls_selected_certs_deinit(session);