Separated cipherspec checking and switching, allowing us to defer the second
authorMartin Willi <martin@revosec.ch>
Fri, 30 Dec 2011 17:29:11 +0000 (18:29 +0100)
committerMartin Willi <martin@revosec.ch>
Sat, 31 Dec 2011 12:14:49 +0000 (13:14 +0100)
src/libtls/tls_fragmentation.c
src/libtls/tls_handshake.h
src/libtls/tls_peer.c
src/libtls/tls_server.c

index c42c16f..0c3da71 100644 (file)
@@ -251,8 +251,9 @@ METHOD(tls_fragmentation_t, process, status_t,
        switch (type)
        {
                case TLS_CHANGE_CIPHER_SPEC:
-                       if (this->handshake->change_cipherspec(this->handshake))
+                       if (this->handshake->cipherspec_changed(this->handshake, TRUE))
                        {
+                               this->handshake->change_cipherspec(this->handshake, TRUE);
                                status = NEED_MORE;
                                break;
                        }
@@ -397,8 +398,9 @@ METHOD(tls_fragmentation_t, build, status_t,
        }
        if (!this->output.len)
        {
-               if (this->handshake->cipherspec_changed(this->handshake))
+               if (this->handshake->cipherspec_changed(this->handshake, FALSE))
                {
+                       this->handshake->change_cipherspec(this->handshake, FALSE);
                        *type = TLS_CHANGE_CIPHER_SPEC;
                        *data = chunk_clone(chunk_from_chars(0x01));
                        return NEED_MORE;
index 4f6af2a..bea0024 100644 (file)
@@ -62,18 +62,19 @@ struct tls_handshake_t {
                                          tls_handshake_type_t *type, bio_writer_t *writer);
 
        /**
-        * Check if the cipher spec for outgoing messages has changed.
+        * Check if the cipher spec should be changed for outgoing messages.
         *
-        * @return                      TRUE if cipher spec changed
+        * @param inbound       TRUE to check for inbound cipherspec change
+        * @return                      TRUE if cipher spec should be changed
         */
-       bool (*cipherspec_changed)(tls_handshake_t *this);
+       bool (*cipherspec_changed)(tls_handshake_t *this, bool inbound);
 
        /**
-        * Change the cipher spec for incoming messages.
+        * Change the cipher for a direction.
         *
-        * @return                      TRUE if cipher spec changed
+        * @param inbound       TRUE to change inbound cipherspec, FALSE for outbound
         */
-       bool (*change_cipherspec)(tls_handshake_t *this);
+       void (*change_cipherspec)(tls_handshake_t *this, bool inbound);
 
        /**
         * Check if the finished message was decoded successfully.
index d3b5ff0..de878c0 100644 (file)
@@ -1042,28 +1042,34 @@ METHOD(tls_handshake_t, build, status_t,
 }
 
 METHOD(tls_handshake_t, cipherspec_changed, bool,
-       private_tls_peer_t *this)
+       private_tls_peer_t *this, bool inbound)
 {
-       if ((this->peer && this->state == STATE_VERIFY_SENT) ||
-          (!this->peer && this->state == STATE_KEY_EXCHANGE_SENT))
+       if (inbound)
        {
-               this->crypto->change_cipher(this->crypto, FALSE);
-               this->state = STATE_CIPHERSPEC_CHANGED_OUT;
-               return TRUE;
+               return this->state == STATE_FINISHED_SENT;
+       }
+       else
+       {
+               if (this->peer)
+               {
+                       return this->state == STATE_VERIFY_SENT;
+               }
+               return this->state == STATE_KEY_EXCHANGE_SENT;
        }
-       return FALSE;
 }
 
-METHOD(tls_handshake_t, change_cipherspec, bool,
-       private_tls_peer_t *this)
+METHOD(tls_handshake_t, change_cipherspec, void,
+       private_tls_peer_t *this, bool inbound)
 {
-       if (this->state == STATE_FINISHED_SENT)
+       this->crypto->change_cipher(this->crypto, inbound);
+       if (inbound)
        {
-               this->crypto->change_cipher(this->crypto, TRUE);
                this->state = STATE_CIPHERSPEC_CHANGED_IN;
-               return TRUE;
        }
-       return FALSE;
+       else
+       {
+               this->state = STATE_CIPHERSPEC_CHANGED_OUT;
+       }
 }
 
 METHOD(tls_handshake_t, finished, bool,
index d69ada8..e446a96 100644 (file)
@@ -956,28 +956,35 @@ METHOD(tls_handshake_t, build, status_t,
 }
 
 METHOD(tls_handshake_t, cipherspec_changed, bool,
-       private_tls_server_t *this)
+       private_tls_server_t *this, bool inbound)
 {
-       if (this->state == STATE_FINISHED_RECEIVED)
+       if (inbound)
        {
-               this->crypto->change_cipher(this->crypto, FALSE);
-               this->state = STATE_CIPHERSPEC_CHANGED_OUT;
-               return TRUE;
+               if (this->peer)
+               {
+                       return this->state == STATE_CERT_VERIFY_RECEIVED;
+               }
+               return this->state == STATE_KEY_EXCHANGE_RECEIVED;
+       }
+       else
+       {
+               return this->state == STATE_FINISHED_RECEIVED;
        }
        return FALSE;
 }
 
-METHOD(tls_handshake_t, change_cipherspec, bool,
-       private_tls_server_t *this)
+METHOD(tls_handshake_t, change_cipherspec, void,
+       private_tls_server_t *this, bool inbound)
 {
-       if ((this->peer && this->state == STATE_CERT_VERIFY_RECEIVED) ||
-          (!this->peer && this->state == STATE_KEY_EXCHANGE_RECEIVED))
+       this->crypto->change_cipher(this->crypto, inbound);
+       if (inbound)
        {
-               this->crypto->change_cipher(this->crypto, TRUE);
                this->state = STATE_CIPHERSPEC_CHANGED_IN;
-               return TRUE;
        }
-       return FALSE;
+       else
+       {
+               this->state = STATE_CIPHERSPEC_CHANGED_OUT;
+       }
 }
 
 METHOD(tls_handshake_t, finished, bool,