From 1f3d48e2148c864710eaf715ba9fdde09a2726e6 Mon Sep 17 00:00:00 2001 From: XieHan Date: Wed, 12 May 2021 20:49:10 +0800 Subject: [PATCH 1/3] add SSLHandshaker --- src/protocol/SSLWrapper.cc | 60 ++++++++++++++++++++++++++++++++++++++ src/protocol/SSLWrapper.h | 13 +++++++++ 2 files changed, 73 insertions(+) diff --git a/src/protocol/SSLWrapper.cc b/src/protocol/SSLWrapper.cc index 4ceaffaa..64616003 100644 --- a/src/protocol/SSLWrapper.cc +++ b/src/protocol/SSLWrapper.cc @@ -25,6 +25,63 @@ namespace protocol { +int SSLHandshaker::encode(struct iovec vectors[], int max) +{ + BIO *bio = SSL_get_wbio(this->ssl); + char *ptr; + long len; + + if (BIO_reset(bio) <= 0) + return -1; + + if (SSL_do_handshake(this->ssl) < 0) + return -1; + + len = BIO_get_mem_data(bio, &ptr); + if (len > 0) + { + vectors[0].iov_base = ptr; + vectors[0].iov_len = len; + return 1; + } + else if (len == 0) + return 0; + else + return -1; +} + +int SSLHandshaker::append(const void *buf, size_t *size) +{ + BIO *rbio = SSL_get_rbio(this->ssl); + BIO *wbio = SSL_get_wbio(this->ssl); + char *ptr; + long len; + int ret; + + if (BIO_write(rbio, buf, *size) <= 0) + return -1; + + BIO_reset(wbio); + ret = SSL_do_handshake(this->ssl); + if (ret > 0) + return 1; + + ret = SSL_get_error(this->ssl, ret); + if (ret != SSL_ERROR_WANT_READ) + { + if (ret != SSL_ERROR_SYSCALL) + errno = -ret; + + return -1; + } + + len = BIO_get_mem_data(wbio, &ptr); + if (len < 0 || this->feedback(ptr, len) < 0) + return -1; + + return 0; +} + int SSLWrapper::encode(struct iovec vectors[], int max) { BIO *bio = SSL_get_wbio(this->ssl); @@ -37,6 +94,9 @@ int SSLWrapper::encode(struct iovec vectors[], int max) if ((unsigned int)ret > (unsigned int)max) return ret; + if (BIO_reset(bio) <= 0) + return -1; + max = ret; for (iov = vectors; iov < vectors + max; iov++) { diff --git a/src/protocol/SSLWrapper.h b/src/protocol/SSLWrapper.h index 35505542..34774d9a 100644 --- a/src/protocol/SSLWrapper.h +++ b/src/protocol/SSLWrapper.h @@ -25,6 +25,19 @@ namespace protocol { +class SSLHandshaker : public ProtocolMessage +{ +protected: + virtual int encode(struct iovec vectors[], int max); + virtual int append(const void *buf, size_t *size); + +protected: + SSL *ssl; + +public: + SSLHandshaker(SSL *ssl) { this->ssl = ssl; } +}; + class SSLWrapper : public ProtocolMessage { protected: From 86c9097d2e944f31cf1f6beadb1323f0c2cdda75 Mon Sep 17 00:00:00 2001 From: XieHan Date: Wed, 12 May 2021 23:21:34 +0800 Subject: [PATCH 2/3] fix SSLhandshaker::append --- src/protocol/CMakeLists.txt | 1 + src/protocol/SSLWrapper.cc | 63 +++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt index 3ddbaa81..a476c510 100644 --- a/src/protocol/CMakeLists.txt +++ b/src/protocol/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRC HttpMessage.cc RedisMessage.cc HttpUtil.cc + SSLWrapper.cc ) add_library(${PROJECT_NAME} OBJECT ${SRC}) diff --git a/src/protocol/SSLWrapper.cc b/src/protocol/SSLWrapper.cc index 64616003..e717a6b7 100644 --- a/src/protocol/SSLWrapper.cc +++ b/src/protocol/SSLWrapper.cc @@ -27,17 +27,17 @@ namespace protocol int SSLHandshaker::encode(struct iovec vectors[], int max) { - BIO *bio = SSL_get_wbio(this->ssl); + BIO *wbio = SSL_get_wbio(this->ssl); char *ptr; long len; - if (BIO_reset(bio) <= 0) + if (BIO_reset(wbio) <= 0) return -1; if (SSL_do_handshake(this->ssl) < 0) return -1; - len = BIO_get_mem_data(bio, &ptr); + len = BIO_get_mem_data(wbio, &ptr); if (len > 0) { vectors[0].iov_base = ptr; @@ -58,45 +58,62 @@ int SSLHandshaker::append(const void *buf, size_t *size) long len; int ret; - if (BIO_write(rbio, buf, *size) <= 0) + if (BIO_reset(wbio) <= 0) return -1; - BIO_reset(wbio); + ret = BIO_write(rbio, buf, *size); + if (ret <= 0) + return -1; + + *size = ret; ret = SSL_do_handshake(this->ssl); - if (ret > 0) - return 1; - - ret = SSL_get_error(this->ssl, ret); - if (ret != SSL_ERROR_WANT_READ) + if (ret <= 0) { - if (ret != SSL_ERROR_SYSCALL) - errno = -ret; + ret = SSL_get_error(this->ssl, ret); + if (ret != SSL_ERROR_WANT_READ) + { + if (ret != SSL_ERROR_SYSCALL) + errno = -ret; - return -1; + return -1; + } + + ret = 0; } len = BIO_get_mem_data(wbio, &ptr); - if (len < 0 || this->feedback(ptr, len) < 0) - return -1; + if (len >= 0) + { + long n = 0; - return 0; + if (len > 0) + n = this->feedback(ptr, len); + + if (n == len) + return ret; + + if (n >= 0) + errno = EAGAIN; + } + + return -1; } int SSLWrapper::encode(struct iovec vectors[], int max) { - BIO *bio = SSL_get_wbio(this->ssl); + BIO *wbio = SSL_get_wbio(this->ssl); struct iovec *iov; char *ptr; long len; int ret; + if (BIO_reset(wbio) <= 0) + return -1; + ret = this->msg->encode(vectors, max); if ((unsigned int)ret > (unsigned int)max) return ret; - if (BIO_reset(bio) <= 0) - return -1; - max = ret; for (iov = vectors; iov < vectors + max; iov++) { @@ -114,7 +131,7 @@ int SSLWrapper::encode(struct iovec vectors[], int max) } } - len = BIO_get_mem_data(bio, &ptr); + len = BIO_get_mem_data(wbio, &ptr); if (len > 0) { vectors[0].iov_base = ptr; @@ -131,13 +148,13 @@ int SSLWrapper::encode(struct iovec vectors[], int max) int SSLWrapper::append(const void *buf, size_t *size) { - BIO *bio = SSL_get_rbio(this->ssl); + BIO *rbio = SSL_get_rbio(this->ssl); char rbuf[BUFSIZE]; size_t nleft; size_t n; int ret; - ret = BIO_write(bio, buf, *size); + ret = BIO_write(rbio, buf, *size); if (ret <= 0) return -1; From 2a431d479a3d32a0773886d636e14f62d20cbaaf Mon Sep 17 00:00:00 2001 From: XieHan Date: Thu, 13 May 2021 00:50:18 +0800 Subject: [PATCH 3/3] fix SSLHandshaker::encode --- src/protocol/SSLWrapper.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/protocol/SSLWrapper.cc b/src/protocol/SSLWrapper.cc index e717a6b7..3966d472 100644 --- a/src/protocol/SSLWrapper.cc +++ b/src/protocol/SSLWrapper.cc @@ -30,12 +30,23 @@ int SSLHandshaker::encode(struct iovec vectors[], int max) BIO *wbio = SSL_get_wbio(this->ssl); char *ptr; long len; + int ret; if (BIO_reset(wbio) <= 0) return -1; - if (SSL_do_handshake(this->ssl) < 0) - return -1; + ret = SSL_do_handshake(this->ssl); + if (ret <= 0) + { + ret = SSL_get_error(this->ssl, ret); + if (ret != SSL_ERROR_WANT_READ) + { + if (ret != SSL_ERROR_SYSCALL) + errno = -ret; + + return -1; + } + } len = BIO_get_mem_data(wbio, &ptr); if (len > 0)