You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by sh...@apache.org on 2015/03/07 18:31:31 UTC

trafficserver git commit: TS-3424: SSL Failed decryption failed or bad record mac

Repository: trafficserver
Updated Branches:
  refs/heads/master 523a3baf0 -> 2b48fd327


TS-3424: SSL Failed decryption failed or bad record mac


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/2b48fd32
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/2b48fd32
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/2b48fd32

Branch: refs/heads/master
Commit: 2b48fd327bb3e8a5ae66f5acad9169a08e740ecb
Parents: 523a3ba
Author: shinrich <sh...@yahoo-inc.com>
Authored: Sat Mar 7 11:30:53 2015 -0600
Committer: shinrich <sh...@yahoo-inc.com>
Committed: Sat Mar 7 11:30:53 2015 -0600

----------------------------------------------------------------------
 CHANGES                          |  2 ++
 iocore/net/P_SSLNetVConnection.h |  3 ++
 iocore/net/SSLNetVConnection.cc  | 68 ++++++++++++++---------------------
 3 files changed, 32 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2b48fd32/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index ebae017..ae9a17e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 5.3.0
 
+  *) [TS-3424] SSL Failed: decryption failed or bad record mac.
+
   *) [TS-3425] include conditional headers in origin request, on no cache store
 
   *) [TS-2515] Add statistics for stripe wrap and cache sync.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2b48fd32/iocore/net/P_SSLNetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index be69ee4..c32ecd5 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -165,6 +165,7 @@ public:
     this->handShakeBuffer = new_MIOBuffer();
     this->handShakeReader = this->handShakeBuffer->alloc_reader();
     this->handShakeHolder = this->handShakeReader->clone();
+    this->handShakeBioStored = 0;
   }
   void free_handshake_buffers() {
     if (this->handShakeReader) {
@@ -179,6 +180,7 @@ public:
     this->handShakeReader = NULL;
     this->handShakeHolder = NULL;
     this->handShakeBuffer = NULL;
+    this->handShakeBioStored = 0;
   }
   // Returns true if all the hooks reenabled
   bool callHooks(TSHttpHookID eventId);
@@ -199,6 +201,7 @@ private:
   MIOBuffer *handShakeBuffer;
   IOBufferReader *handShakeHolder;
   IOBufferReader *handShakeReader;
+  int handShakeBioStored;
 
   bool transparentPassThrough;
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/2b48fd32/iocore/net/SSLNetVConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 50f790f..168a9f8 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -360,18 +360,12 @@ SSLNetVConnection::read_raw_data()
 
   char *start = this->handShakeReader->start();
   char *end = this->handShakeReader->end();
+  this->handShakeBioStored = end - start;
 
   // Sets up the buffer as a read only bio target
   // Must be reset on each read
-  BIO *rbio = BIO_new_mem_buf(start, end - start);
+  BIO *rbio = BIO_new_mem_buf(start, this->handShakeBioStored);
   BIO_set_mem_eof_return(rbio, -1);
-  // Assigning directly into the SSL structure
-  // is dirty, but there is no openssl function that only
-  // assigns the read bio.  Originally I was getting and
-  // resetting the same write bio, but that caused the
-  // inserted buffer bios to be freed and then reinserted.
-  //BIO *wbio = SSL_get_wbio(this->ssl);
-  //SSL_set_bio(this->ssl, rbio, wbio);
   SSL_set_rbio(this, rbio);
 
   return r;
@@ -419,8 +413,6 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
   // Continue on if we are still in the handshake
   if (!getSSLHandShakeComplete()) {
     int err;
-    int data_to_read = 0;
-    char *data_ptr = NULL;
 
     if (getSSLClientConnection()) {
       ret = sslStartHandShake(SSL_EVENT_CLIENT, err);
@@ -431,9 +423,10 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
     if (this->handShakeReader) {
       if (this->attributes != HttpProxyPort::TRANSPORT_BLIND_TUNNEL) {
         // Check and consume data that has been read
-        int data_still_to_read = BIO_get_mem_data(SSL_get_rbio(this->ssl), &data_ptr);
-        data_to_read = this->handShakeReader->read_avail();
-        this->handShakeReader->consume(data_to_read - data_still_to_read);
+        if (BIO_eof(SSL_get_rbio(this->ssl))) {
+          this->handShakeReader->consume(this->handShakeBioStored);
+          this->handShakeBioStored = 0;
+        }
       }
       else {
         // Now in blind tunnel. Set things up to read what is in the buffer
@@ -509,34 +502,31 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
   // At this point we are at the post-handshake SSL processing
   // If the read BIO is not already a socket, consider changing it
   if (this->handShakeReader) {
-    if (this->handShakeReader->read_avail() <= 0) {
-      // Switch the read bio over to a socket bio
-      SSL_set_rfd(this->ssl, this->get_socket());
-      this->free_handshake_buffers();
+    // Check out if there is anything left in the current bio
+    if (!BIO_eof(SSL_get_rbio(this->ssl))) {
+      // Still data remaining in the current BIO block
     }
-    else { // There is still data in the buffer to drain
-      char *data_ptr = NULL;
-      int data_still_to_read = BIO_get_mem_data(SSL_get_rbio(this->ssl), &data_ptr);
-      if (data_still_to_read >  0) {
-        // Still data remaining in the current BIO block
-      }
-      else {
-        // reset the block
+    else {
+      // Consume what SSL has read so far.  
+      this->handShakeReader->consume(this->handShakeBioStored);
+      
+      // If we are empty now, switch over
+      if (this->handShakeReader->read_avail() <= 0) {
+        // Switch the read bio over to a socket bio
+        SSL_set_rfd(this->ssl, this->get_socket());
+        this->free_handshake_buffers();
+      } else { 
+        // Setup the next iobuffer block to drain
         char *start = this->handShakeReader->start();
         char *end = this->handShakeReader->end();
+        this->handShakeBioStored = end - start;
+
         // Sets up the buffer as a read only bio target
         // Must be reset on each read
-        BIO *rbio = BIO_new_mem_buf(start, end - start);
+        BIO *rbio = BIO_new_mem_buf(start, this->handShakeBioStored);
         BIO_set_mem_eof_return(rbio, -1);
-        // So assigning directly into the SSL structure
-        // is dirty, but there is no openssl function that only
-        // assigns the read bio.  Originally I was getting and
-        // resetting the same write bio, but that caused the
-        // inserted buffer bios to be freed and then reinserted.
         SSL_set_rbio(this, rbio);
-        //BIO *wbio = SSL_get_wbio(this->ssl);
-        //SSL_set_bio(this->ssl, rbio, wbio);
-      }
+      } 
     }
   }
   // Otherwise, we already replaced the buffer bio with a socket bio
@@ -773,6 +763,7 @@ SSLNetVConnection::SSLNetVConnection():
   handShakeBuffer(NULL),
   handShakeHolder(NULL),
   handShakeReader(NULL),
+  handShakeBioStored(0),
   sslPreAcceptHookState(SSL_HOOKS_INIT),
   sslHandshakeHookState(HANDSHAKE_HOOKS_PRE),
   npnSet(NULL),
@@ -944,15 +935,10 @@ SSLNetVConnection::sslServerHandShakeEvent(int &err)
 
   // All the pre-accept hooks have completed, proceed with the actual accept.
 
-  char *data_ptr = NULL;
-  int data_to_read = BIO_get_mem_data(SSL_get_rbio(this->ssl), &data_ptr);
-  if (data_to_read <= 0) { // If there is not already data in the buffer
+  if (BIO_eof(SSL_get_rbio(this->ssl))) { // No more data in the buffer
     // Read from socket to fill in the BIO buffer with the
     // raw handshake data before calling the ssl accept calls.
-    int64_t data_read;
-    if ((data_read = this->read_raw_data()) > 0) {
-      BIO_get_mem_data(SSL_get_rbio(this->ssl), &data_ptr);
-    }
+    this->read_raw_data();
   }
 
   ssl_error_t ssl_error = SSLAccept(ssl);