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 <shinr...@yahoo-inc.com> Authored: Sat Mar 7 11:30:53 2015 -0600 Committer: shinrich <shinr...@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);