From 0d5595ac602630e36672f587023feb23b41fdb58 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 10 Apr 2013 13:50:59 +0200 Subject: [PATCH] Revert "crypto: use better memory BIO implementation" This change shouldn't have landed in the stable branch. It's a feature, not a bug fix. This reverts commit 58f93ffc4a23aa7240808288acf8cf9f3022abea. This reverts commit 8c8ebe49b62c47b0ac87d697d0bc3515604667c3. This reverts commit ba0f7b8066cb4dc8cb3cd4931e52aa94af40a709. This reverts commit 21f3c5c3670861436392f30da2033cccbc137309. --- node.gyp | 3 +- src/node_crypto.cc | 9 +- src/node_crypto_bio.cc | 321 ----------------------------------------- src/node_crypto_bio.h | 93 ------------ 4 files changed, 5 insertions(+), 421 deletions(-) delete mode 100644 src/node_crypto_bio.cc delete mode 100644 src/node_crypto_bio.h diff --git a/node.gyp b/node.gyp index efeff539f0..fc7e2153f8 100644 --- a/node.gyp +++ b/node.gyp @@ -110,7 +110,6 @@ 'src/node_buffer.h', 'src/node_constants.h', 'src/node_crypto.h', - 'src/node_crypto_bio.h', 'src/node_extensions.h', 'src/node_file.h', 'src/node_http_parser.h', @@ -148,7 +147,7 @@ 'conditions': [ [ 'node_use_openssl=="true"', { 'defines': [ 'HAVE_OPENSSL=1' ], - 'sources': [ 'src/node_crypto.cc', 'src/node_crypto_bio.cc' ], + 'sources': [ 'src/node_crypto.cc' ], 'conditions': [ [ 'node_shared_openssl=="false"', { 'dependencies': [ './deps/openssl/openssl.gyp:openssl' ], diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 1b9c7b6b56..4a02812d58 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -20,7 +20,6 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. #include "node_crypto.h" -#include "node_crypto_bio.h" #include "node_crypto_groups.h" #include "v8.h" @@ -292,7 +291,7 @@ int SecureContext::NewSessionCallback(SSL* s, SSL_SESSION* sess) { // Takes a string or buffer and loads it into a BIO. // Caller responsible for BIO_free-ing the returned object. static BIO* LoadBIO (Handle v) { - BIO *bio = BIO_new(NodeBIO::GetMethod()); + BIO *bio = BIO_new(BIO_s_mem()); if (!bio) return NULL; HandleScope scope; @@ -545,7 +544,7 @@ Handle SecureContext::AddRootCerts(const Arguments& args) { root_cert_store = X509_STORE_new(); for (int i = 0; root_certs[i]; i++) { - BIO *bp = BIO_new(NodeBIO::GetMethod()); + BIO *bp = BIO_new(BIO_s_mem()); if (!BIO_write(bp, root_certs[i], strlen(root_certs[i]))) { BIO_free(bp); @@ -1202,8 +1201,8 @@ Handle Connection::New(const Arguments& args) { bool is_server = args[1]->BooleanValue(); p->ssl_ = SSL_new(sc->ctx_); - p->bio_read_ = BIO_new(NodeBIO::GetMethod()); - p->bio_write_ = BIO_new(NodeBIO::GetMethod()); + p->bio_read_ = BIO_new(BIO_s_mem()); + p->bio_write_ = BIO_new(BIO_s_mem()); SSL_set_app_data(p->ssl_, p); diff --git a/src/node_crypto_bio.cc b/src/node_crypto_bio.cc deleted file mode 100644 index 52e5e78274..0000000000 --- a/src/node_crypto_bio.cc +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -#include "node_crypto_bio.h" -#include "openssl/bio.h" -#include - -namespace node { - -BIO_METHOD NodeBIO::method_ = { - BIO_TYPE_MEM, - "node.js SSL buffer", - NodeBIO::Write, - NodeBIO::Read, - NodeBIO::Puts, - NodeBIO::Gets, - NodeBIO::Ctrl, - NodeBIO::New, - NodeBIO::Free, - NULL -}; - - -int NodeBIO::New(BIO* bio) { - bio->ptr = new NodeBIO(); - - // XXX Why am I doing it?! - bio->shutdown = 1; - bio->init = 1; - bio->num = -1; - - return 1; -} - - -int NodeBIO::Free(BIO* bio) { - if (bio == NULL) return 0; - - if (bio->shutdown) { - if (bio->init && bio->ptr != NULL) { - delete FromBIO(bio); - bio->ptr = NULL; - } - } - - return 1; -} - - -int NodeBIO::Read(BIO* bio, char* out, int len) { - int bytes; - BIO_clear_retry_flags(bio); - - bytes = FromBIO(bio)->Read(out, len); - - if (bytes == 0) { - bytes = bio->num; - if (bytes != 0) { - BIO_set_retry_read(bio); - } - } - - return bytes; -} - - -int NodeBIO::Write(BIO* bio, const char* data, int len) { - BIO_clear_retry_flags(bio); - - FromBIO(bio)->Write(data, len); - - return len; -} - - -int NodeBIO::Puts(BIO* bio, const char* str) { - return Write(bio, str, strlen(str)); -} - - -int NodeBIO::Gets(BIO* bio, char* out, int size) { - NodeBIO* nbio = FromBIO(bio); - - if (nbio->Length() == 0) - return 0; - - int i = nbio->IndexOf('\n', size); - - // Include '\n' - if (i < size) i++; - - // Shift `i` a bit to NULL-terminate string later - if (size == i) i--; - - // Flush read data - nbio->Read(out, i); - - out[i] = 0; - - return i; -} - - -long NodeBIO::Ctrl(BIO* bio, int cmd, long num, void* ptr) { - NodeBIO* nbio; - long ret; - - nbio = FromBIO(bio); - ret = 1; - - switch (cmd) { - case BIO_CTRL_RESET: - nbio->Reset(); - break; - case BIO_CTRL_EOF: - ret = nbio->Length() == 0; - break; - case BIO_C_SET_BUF_MEM_EOF_RETURN: - bio->num = num; - break; - case BIO_CTRL_INFO: - ret = nbio->Length(); - if (ptr != NULL) - *reinterpret_cast(ptr) = NULL; - break; - case BIO_C_SET_BUF_MEM: - assert(0 && "Can't use SET_BUF_MEM_PTR with NodeBIO"); - abort(); - break; - case BIO_C_GET_BUF_MEM_PTR: - assert(0 && "Can't use GET_BUF_MEM_PTR with NodeBIO"); - ret = 0; - break; - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - bio->shutdown = num; - break; - case BIO_CTRL_WPENDING: - ret = 0; - break; - case BIO_CTRL_PENDING: - ret = nbio->Length(); - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - case BIO_CTRL_PUSH: - case BIO_CTRL_POP: - default: - ret = 0; - break; - } - return ret; -} - - -size_t NodeBIO::Read(char* out, size_t size) { - size_t bytes_read = 0; - size_t expected = Length() > size ? size : Length(); - size_t offset = 0; - size_t left = size; - - while (bytes_read < expected) { - assert(read_head_->read_pos_ <= read_head_->write_pos_); - size_t avail = read_head_->write_pos_ - read_head_->read_pos_; - if (avail > left) - avail = left; - - // Copy data - if (out != NULL) - memcpy(out + offset, read_head_->data_ + read_head_->read_pos_, avail); - read_head_->read_pos_ += avail; - - // Move pointers - bytes_read += avail; - offset += avail; - left -= avail; - - // Move to next buffer - if (read_head_->read_pos_ == read_head_->write_pos_) { - read_head_->read_pos_ = 0; - read_head_->write_pos_ = 0; - - // But not get beyond write_head_ - if (bytes_read != expected) - read_head_ = read_head_->next_; - } - } - assert(expected == bytes_read); - length_ -= bytes_read; - - return bytes_read; -} - - -size_t NodeBIO::IndexOf(char delim, size_t limit) { - size_t bytes_read = 0; - size_t max = Length() > limit ? limit : Length(); - size_t left = limit; - Buffer* current = read_head_; - - while (bytes_read < max) { - assert(current->read_pos_ <= current->write_pos_); - size_t avail = current->write_pos_ - current->read_pos_; - if (avail > left) - avail = left; - - // Walk through data - char* tmp = current->data_ + current->read_pos_; - size_t off = 0; - while (off < avail && *tmp != delim) { - off++; - tmp++; - } - - // Move pointers - bytes_read += off; - left -= off; - - // Found `delim` - if (off != avail) { - return bytes_read; - } - - // Move to next buffer - if (current->read_pos_ + avail == kBufferLength) { - current = current->next_; - } - } - assert(max == bytes_read); - - return max; -} - - -void NodeBIO::Write(const char* data, size_t size) { - size_t offset = 0; - size_t left = size; - while (left > 0) { - size_t to_write = left; - assert(write_head_->write_pos_ <= kBufferLength); - size_t avail = kBufferLength - write_head_->write_pos_; - - if (to_write > avail) - to_write = avail; - - // Copy data - memcpy(write_head_->data_ + write_head_->write_pos_, - data + offset, - to_write); - - // Move pointers - left -= to_write; - offset += to_write; - length_ += to_write; - write_head_->write_pos_ += to_write; - assert(write_head_->write_pos_ <= kBufferLength); - - // Go to next buffer if there still are some bytes to write - if (left != 0) { - if (write_head_->write_pos_ == kBufferLength) { - Buffer* next = new Buffer(); - next->next_ = write_head_->next_; - write_head_->next_ = next; - } - write_head_ = write_head_->next_; - } - } - assert(left == 0); -} - - -void NodeBIO::Reset() { - while (read_head_->read_pos_ != read_head_->write_pos_) { - assert(read_head_->write_pos_ > read_head_->read_pos_); - - length_ -= read_head_->write_pos_ - read_head_->read_pos_; - read_head_->write_pos_ = 0; - read_head_->read_pos_ = 0; - - read_head_ = read_head_->next_; - } - write_head_ = read_head_; - assert(length_ == 0); -} - - -NodeBIO::~NodeBIO() { - Buffer* current = head_.next_; - while (current != &head_) { - Buffer* next = current->next_; - delete current; - current = next; - } - - read_head_ = NULL; - write_head_ = NULL; -} - -} // namespace node diff --git a/src/node_crypto_bio.h b/src/node_crypto_bio.h deleted file mode 100644 index 9411b3bce7..0000000000 --- a/src/node_crypto_bio.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -#include "openssl/bio.h" -#include - -namespace node { - -class NodeBIO { - public: - static inline BIO_METHOD* GetMethod() { - return &method_; - } - - static int New(BIO* bio); - static int Free(BIO* bio); - static int Read(BIO* bio, char* out, int len); - static int Write(BIO* bio, const char* data, int len); - static int Puts(BIO* bio, const char* str); - static int Gets(BIO* bio, char* out, int size); - static long Ctrl(BIO* bio, int cmd, long num, void* ptr); - - protected: - static const size_t kBufferLength = 16 * 1024; - - class Buffer { - public: - Buffer() : read_pos_(0), write_pos_(0), next_(NULL) { - } - - size_t read_pos_; - size_t write_pos_; - Buffer* next_; - char data_[kBufferLength]; - }; - - NodeBIO() : length_(0), read_head_(&head_), write_head_(&head_) { - // Loop head - head_.next_ = &head_; - } - - ~NodeBIO(); - - // Read `len` bytes maximum into `out`, return actual number of read bytes - size_t Read(char* out, size_t size); - - // Find first appearance of `delim` in buffer or `limit` if `delim` - // wasn't found. - size_t IndexOf(char delim, size_t limit); - - // Discard all available data - void Reset(); - - // Put `len` bytes from `data` into buffer - void Write(const char* data, size_t size); - - // Return size of buffer in bytes - size_t inline Length() { - return length_; - } - - static inline NodeBIO* FromBIO(BIO* bio) { - assert(bio->ptr != NULL); - return static_cast(bio->ptr); - } - - size_t length_; - Buffer head_; - Buffer* read_head_; - Buffer* write_head_; - - static BIO_METHOD method_; -}; - -} // namespace node