diff options
Diffstat (limited to 'extra/yassl/src')
-rw-r--r-- | extra/yassl/src/buffer.cpp | 331 | ||||
-rw-r--r-- | extra/yassl/src/cert_wrapper.cpp | 408 | ||||
-rw-r--r-- | extra/yassl/src/crypto_wrapper.cpp | 998 | ||||
-rw-r--r-- | extra/yassl/src/dummy.cpp | 4 | ||||
-rw-r--r-- | extra/yassl/src/handshake.cpp | 1203 | ||||
-rw-r--r-- | extra/yassl/src/lock.cpp | 87 | ||||
-rw-r--r-- | extra/yassl/src/log.cpp | 146 | ||||
-rwxr-xr-x | extra/yassl/src/make.bat | 42 | ||||
-rw-r--r-- | extra/yassl/src/socket_wrapper.cpp | 261 | ||||
-rw-r--r-- | extra/yassl/src/ssl.cpp | 1782 | ||||
-rw-r--r-- | extra/yassl/src/timer.cpp | 82 | ||||
-rw-r--r-- | extra/yassl/src/yassl.cpp | 229 | ||||
-rw-r--r-- | extra/yassl/src/yassl_error.cpp | 288 | ||||
-rw-r--r-- | extra/yassl/src/yassl_imp.cpp | 2636 | ||||
-rw-r--r-- | extra/yassl/src/yassl_int.cpp | 2705 |
15 files changed, 0 insertions, 11202 deletions
diff --git a/extra/yassl/src/buffer.cpp b/extra/yassl/src/buffer.cpp deleted file mode 100644 index 919aa9c7436..00000000000 --- a/extra/yassl/src/buffer.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* yaSSL buffer header implements input/output buffers to simulate streaming - * with SSL types and sockets - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> // memcpy -#include "runtime.hpp" -#include "buffer.hpp" -#include "yassl_types.hpp" - -namespace yaSSL { - - - - -/* return 0 on check success, always true for NoCheck policy */ -int NoCheck::check(uint, uint) -{ - return 0; -} - -/* return 0 on check success */ -int Check::check(uint i, uint max) -{ - if (i < max) - return 0; - - return -1; -} - - -/* input_buffer operates like a smart c style array with a checking option, - * meant to be read from through [] with AUTO index or read(). - * Should only write to at/near construction with assign() or raw (e.g., recv) - * followed by add_size with the number of elements added by raw write. - * - * Not using vector because need checked []access, offset, and the ability to - * write to the buffer bulk wise and have the correct size - */ - - -input_buffer::input_buffer() - : size_(0), current_(0), buffer_(0), end_(0), error_(0), zero_(0) -{} - - -input_buffer::input_buffer(uint s) - : size_(0), current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s), - error_(0), zero_(0) -{} - - -// with assign -input_buffer::input_buffer(uint s, const byte* t, uint len) - : size_(0), current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s), - error_(0), zero_(0) -{ - assign(t, len); -} - - -input_buffer::~input_buffer() -{ - ysArrayDelete(buffer_); -} - - -// users can pass defualt zero length buffer and then allocate -void input_buffer::allocate(uint s) -{ - if (error_ == 0) { - buffer_ = NEW_YS byte[s]; - end_ = buffer_ + s; - } -} - - -// for passing to raw writing functions at beginning, then use add_size -byte* input_buffer::get_buffer() const -{ - return buffer_; -} - - -// after a raw write user can set NEW_YS size -// if you know the size before the write use assign() -void input_buffer::add_size(uint i) -{ - if (error_ == 0 && check(size_ + i-1, get_capacity()) == 0) - size_ += i; - else - error_ = -1; -} - - -uint input_buffer::get_capacity() const -{ - if (error_ == 0) - return end_ - buffer_; - - return 0; -} - - -uint input_buffer::get_current() const -{ - if (error_ == 0) - return current_; - - return 0; -} - - -uint input_buffer::get_size() const -{ - if (error_ == 0) - return size_; - - return 0; -} - - -uint input_buffer::get_remaining() const -{ - if (error_ == 0) - return size_ - current_; - - return 0; -} - - -int input_buffer::get_error() const -{ - return error_; -} - - -void input_buffer::set_error() -{ - error_ = -1; -} - - -void input_buffer::set_current(uint i) -{ - if (error_ == 0 && check(i ? i - 1 : 0, size_) == 0) - current_ = i; - else - error_ = -1; -} - - -// read only access through [], advance current -// user passes in AUTO index for ease of use -const byte& input_buffer::operator[](uint i) -{ - if (error_ == 0 && check(current_, size_) == 0) - return buffer_[current_++]; - - error_ = -1; - return zero_; -} - - -// end of input test -bool input_buffer::eof() -{ - if (error_ != 0) - return true; - - return current_ >= size_; -} - - -// peek ahead -byte input_buffer::peek() -{ - if (error_ == 0 && check(current_, size_) == 0) - return buffer_[current_]; - - error_ = -1; - return 0; -} - - -// write function, should use at/near construction -void input_buffer::assign(const byte* t, uint s) -{ - if (t && error_ == 0 && check(current_, get_capacity()) == 0) { - add_size(s); - if (error_ == 0) { - memcpy(&buffer_[current_], t, s); - return; // success - } - } - - error_ = -1; -} - - -// use read to query input, adjusts current -void input_buffer::read(byte* dst, uint length) -{ - if (dst && error_ == 0 && check(current_ + length - 1, size_) == 0) { - memcpy(dst, &buffer_[current_], length); - current_ += length; - } else { - error_ = -1; - } -} - - - -/* output_buffer operates like a smart c style array with a checking option. - * Meant to be written to through [] with AUTO index or write(). - * Size (current) counter increases when written to. Can be constructed with - * zero length buffer but be sure to allocate before first use. - * Don't use add write for a couple bytes, use [] instead, way less overhead. - * - * Not using vector because need checked []access and the ability to - * write to the buffer bulk wise and retain correct size - */ - - -output_buffer::output_buffer() - : current_(0), buffer_(0), end_(0) -{} - - -// with allocate -output_buffer::output_buffer(uint s) - : current_(0), buffer_(NEW_YS byte[s]), end_(buffer_ + s) -{} - - -// with assign -output_buffer::output_buffer(uint s, const byte* t, uint len) - : current_(0), buffer_(NEW_YS byte[s]), end_(buffer_+ s) -{ - write(t, len); -} - - -output_buffer::~output_buffer() -{ - ysArrayDelete(buffer_); -} - - -uint output_buffer::get_size() const -{ - return current_; -} - - -uint output_buffer::get_capacity() const -{ - return (uint) (end_ - buffer_); -} - - -void output_buffer::set_current(uint c) -{ - check(c, get_capacity()); - current_ = c; -} - - -// users can pass defualt zero length buffer and then allocate -void output_buffer::allocate(uint s) -{ - buffer_ = NEW_YS byte[s]; end_ = buffer_ + s; -} - - -// for passing to reading functions when finished -const byte* output_buffer::get_buffer() const -{ - return buffer_; -} - - -// allow write access through [], update current -// user passes in AUTO as index for ease of use -byte& output_buffer::operator[](uint i) -{ - check(current_, get_capacity()); - return buffer_[current_++]; -} - - -// end of output test -bool output_buffer::eof() -{ - return current_ >= get_capacity(); -} - - -void output_buffer::write(const byte* t, uint s) -{ - check(current_ + s - 1, get_capacity()); - memcpy(&buffer_[current_], t, s); - current_ += s; -} - - - -} // naemspace - diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp deleted file mode 100644 index 7e2c179f964..00000000000 --- a/extra/yassl/src/cert_wrapper.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* The certificate wrapper source implements certificate management functions - * - */ - -#include "runtime.hpp" -#include "cert_wrapper.hpp" -#include "yassl_int.hpp" -#include "error.hpp" - -#if defined(USE_CML_LIB) - #include "cmapi_cpp.h" -#else - #include "asn.hpp" - #include "file.hpp" -#endif // USE_CML_LIB - - -namespace yaSSL { - - -x509::x509(uint sz) : length_(sz), buffer_(NEW_YS opaque[sz]) -{ -} - - -x509::~x509() -{ - ysArrayDelete(buffer_); -} - - -x509::x509(const x509& that) : length_(that.length_), - buffer_(NEW_YS opaque[length_]) -{ - memcpy(buffer_, that.buffer_, length_); -} - - -void x509::Swap(x509& that) -{ - STL::swap(length_, that.length_); - STL::swap(buffer_, that.buffer_); -} - - -x509& x509::operator=(const x509& that) -{ - x509 temp(that); - Swap(temp); - return *this; -} - - -uint x509::get_length() const -{ - return length_; -} - - -const opaque* x509::get_buffer() const -{ - return buffer_; -} - - -opaque* x509::use_buffer() -{ - return buffer_; -} - - -//CertManager -CertManager::CertManager() - : peerX509_(0), selfX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false), - sendVerify_(false), sendBlankCert_(false), verifyCallback_(0) -{} - - -CertManager::~CertManager() -{ - ysDelete(peerX509_); - ysDelete(selfX509_); - - STL::for_each(signers_.begin(), signers_.end(), del_ptr_zero()) ; - - STL::for_each(peerList_.begin(), peerList_.end(), del_ptr_zero()) ; - - STL::for_each(list_.begin(), list_.end(), del_ptr_zero()) ; -} - - -bool CertManager::verifyPeer() const -{ - return verifyPeer_; -} - - -bool CertManager::verifyNone() const -{ - return verifyNone_; -} - - -bool CertManager::failNoCert() const -{ - return failNoCert_; -} - - -bool CertManager::sendVerify() const -{ - return sendVerify_; -} - - -void CertManager::setVerifyPeer() -{ - verifyPeer_ = true; -} - - -void CertManager::setVerifyNone() -{ - verifyNone_ = true; -} - -bool CertManager::sendBlankCert() const -{ - return sendBlankCert_; -} - - -void CertManager::setFailNoCert() -{ - failNoCert_ = true; -} - - -void CertManager::setSendVerify() -{ - sendVerify_ = true; -} - -void CertManager::setSendBlankCert() -{ - sendBlankCert_ = true; -} - - -void CertManager::setVerifyCallback(VerifyCallback vc) -{ - verifyCallback_ = vc; -} - - -void CertManager::AddPeerCert(x509* x) -{ - peerList_.push_back(x); // take ownership -} - - -void CertManager::CopySelfCert(const x509* x) -{ - if (x) - list_.push_back(NEW_YS x509(*x)); -} - - -// add to signers -int CertManager::CopyCaCert(const x509* x) -{ - TaoCrypt::Source source(x->get_buffer(), x->get_length()); - TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_, - TaoCrypt::CertDecoder::CA); - - if (!cert.GetError().What()) { - const TaoCrypt::PublicKey& key = cert.GetPublicKey(); - signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(), - cert.GetCommonName(), cert.GetHash())); - } - // just don't add, not an error return cert.GetError().What(); - return 0; -} - - -const x509* CertManager::get_cert() const -{ - return list_.front(); -} - - -const opaque* CertManager::get_peerKey() const -{ - return peerPublicKey_.get_buffer(); -} - - -X509* CertManager::get_peerX509() const -{ - return peerX509_; -} - - -X509* CertManager::get_selfX509() const -{ - return selfX509_; -} - - -SignatureAlgorithm CertManager::get_peerKeyType() const -{ - return peerKeyType_; -} - - -SignatureAlgorithm CertManager::get_keyType() const -{ - return keyType_; -} - - -uint CertManager::get_peerKeyLength() const -{ - return peerPublicKey_.get_size(); -} - - -const opaque* CertManager::get_privateKey() const -{ - return privateKey_.get_buffer(); -} - - -uint CertManager::get_privateKeyLength() const -{ - return privateKey_.get_size(); -} - - -// Validate the peer's certificate list, from root to peer (last to first) -int CertManager::Validate() -{ - CertList::reverse_iterator last = peerList_.rbegin(); - size_t count = peerList_.size(); - - while ( count > 1 ) { - TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); - TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); - - if (int err = cert.GetError().What()) - return err; - - const TaoCrypt::PublicKey& key = cert.GetPublicKey(); - signers_.push_back(NEW_YS TaoCrypt::Signer(key.GetKey(), key.size(), - cert.GetCommonName(), cert.GetHash())); - ++last; - --count; - } - - if (count) { - // peer's is at the front - TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); - TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); - - int err = cert.GetError().What(); - if ( err && err != TaoCrypt::SIG_OTHER_E) - return err; - - uint sz = cert.GetPublicKey().size(); - peerPublicKey_.allocate(sz); - peerPublicKey_.assign(cert.GetPublicKey().GetKey(), sz); - - if (cert.GetKeyType() == TaoCrypt::RSAk) - peerKeyType_ = rsa_sa_algo; - else - peerKeyType_ = dsa_sa_algo; - - size_t iSz = strlen(cert.GetIssuer()) + 1; - size_t sSz = strlen(cert.GetCommonName()) + 1; - ASN1_STRING beforeDate, afterDate; - beforeDate.data= (unsigned char *) cert.GetBeforeDate(); - beforeDate.type= cert.GetBeforeDateType(); - beforeDate.length= (int)strlen((char *) beforeDate.data) + 1; - afterDate.data= (unsigned char *) cert.GetAfterDate(); - afterDate.type= cert.GetAfterDateType(); - afterDate.length= (int)strlen((char *) afterDate.data) + 1; - peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(), - sSz, &beforeDate, &afterDate, - cert.GetIssuerCnStart(), cert.GetIssuerCnLength(), - cert.GetSubjectCnStart(), cert.GetSubjectCnLength() - ); - - if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) { - X509_STORE_CTX store; - store.error = err; - store.error_depth = static_cast<int>(count) - 1; - store.current_cert = peerX509_; - - int ok = verifyCallback_(0, &store); - if (ok) return 0; - } - - if (err == TaoCrypt::SIG_OTHER_E) return err; - } - return 0; -} - - -// Set the private key -int CertManager::SetPrivateKey(const x509& key) -{ - privateKey_.allocate(key.get_length()); - privateKey_.assign(key.get_buffer(), key.get_length()); - - // set key type - if (x509* cert = list_.front()) { - TaoCrypt::Source source(cert->get_buffer(), cert->get_length()); - TaoCrypt::CertDecoder cd(source, false); - cd.DecodeToKey(); - if (int err = cd.GetError().What()) - return err; - if (cd.GetKeyType() == TaoCrypt::RSAk) - keyType_ = rsa_sa_algo; - else - keyType_ = dsa_sa_algo; - - size_t iSz = strlen(cd.GetIssuer()) + 1; - size_t sSz = strlen(cd.GetCommonName()) + 1; - ASN1_STRING beforeDate, afterDate; - beforeDate.data= (unsigned char *) cd.GetBeforeDate(); - beforeDate.type= cd.GetBeforeDateType(); - beforeDate.length= (int)strlen((char *) beforeDate.data) + 1; - afterDate.data= (unsigned char *) cd.GetAfterDate(); - afterDate.type= cd.GetAfterDateType(); - afterDate.length= (int)strlen((char *) afterDate.data) + 1; - selfX509_ = NEW_YS X509(cd.GetIssuer(), iSz, cd.GetCommonName(), - sSz, &beforeDate, &afterDate, - cd.GetIssuerCnStart(), cd.GetIssuerCnLength(), - cd.GetSubjectCnStart(), cd.GetSubjectCnLength()); - } - return 0; -} - - -// Store OpenSSL type peer's cert -void CertManager::setPeerX509(X509* x) -{ - if (x == 0) return; - - X509_NAME* issuer = x->GetIssuer(); - X509_NAME* subject = x->GetSubject(); - ASN1_STRING* before = x->GetBefore(); - ASN1_STRING* after = x->GetAfter(); - - peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(), - subject->GetName(), subject->GetLength(), before, after, - issuer->GetCnPosition(), issuer->GetCnLength(), - subject->GetCnPosition(), subject->GetCnLength()); -} - - -#if defined(USE_CML_LIB) - -// Get the peer's certificate, extract and save public key -void CertManager::SetPeerKey() -{ - // first cert is the peer's - x509* main = peerList_.front(); - - Bytes_struct cert; - cert.num = main->get_length(); - cert.data = main->set_buffer(); - - CML::Certificate cm(cert); - const CML::ASN::Cert& raw = cm.base(); - CTIL::CSM_Buffer key = raw.pubKeyInfo.key; - - uint sz; - opaque* key_buffer = reinterpret_cast<opaque*>(key.Get(sz)); - peerPublicKey_.allocate(sz); - peerPublicKey_.assign(key_buffer, sz); -} - - -#endif // USE_CML_LIB - - - -} // namespace diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp deleted file mode 100644 index acafea5005e..00000000000 --- a/extra/yassl/src/crypto_wrapper.cpp +++ /dev/null @@ -1,998 +0,0 @@ -/* - Copyright (c) 2005, 2012, Oracle and/or its affiliates - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - -/* The crypto wrapper source implements the policies for the cipher - * components used by SSL. - * - * The implementation relies on a specfic library, taoCrypt. - */ - -#if !defined(USE_CRYPTOPP_LIB) - -#include "runtime.hpp" -#include "crypto_wrapper.hpp" -#include "cert_wrapper.hpp" - -#include "md5.hpp" -#include "sha.hpp" -#include "ripemd.hpp" -#include "hmac.hpp" -#include "modes.hpp" -#include "des.hpp" -#include "arc4.hpp" -#include "aes.hpp" -#include "rsa.hpp" -#include "dsa.hpp" -#include "dh.hpp" -#include "random.hpp" -#include "file.hpp" -#include "coding.hpp" - - -namespace yaSSL { - - -// MD5 Implementation -struct MD5::MD5Impl { - TaoCrypt::MD5 md5_; - MD5Impl() {} - explicit MD5Impl(const TaoCrypt::MD5& md5) : md5_(md5) {} -}; - - -MD5::MD5() : pimpl_(NEW_YS MD5Impl) {} - - -MD5::~MD5() { ysDelete(pimpl_); } - - -MD5::MD5(const MD5& that) : Digest(), pimpl_(NEW_YS - MD5Impl(that.pimpl_->md5_)) {} - - -MD5& MD5::operator=(const MD5& that) -{ - pimpl_->md5_ = that.pimpl_->md5_; - return *this; -} - - -uint MD5::get_digestSize() const -{ - return MD5_LEN; -} - - -uint MD5::get_padSize() const -{ - return PAD_MD5; -} - - -// Fill out with MD5 digest from in that is sz bytes, out must be >= digest sz -void MD5::get_digest(byte* out, const byte* in, unsigned int sz) -{ - pimpl_->md5_.Update(in, sz); - pimpl_->md5_.Final(out); -} - -// Fill out with MD5 digest from previous updates -void MD5::get_digest(byte* out) -{ - pimpl_->md5_.Final(out); -} - - -// Update the current digest -void MD5::update(const byte* in, unsigned int sz) -{ - pimpl_->md5_.Update(in, sz); -} - - -// SHA Implementation -struct SHA::SHAImpl { - TaoCrypt::SHA sha_; - SHAImpl() {} - explicit SHAImpl(const TaoCrypt::SHA& sha) : sha_(sha) {} -}; - - -SHA::SHA() : pimpl_(NEW_YS SHAImpl) {} - - -SHA::~SHA() { ysDelete(pimpl_); } - - -SHA::SHA(const SHA& that) : Digest(), pimpl_(NEW_YS SHAImpl(that.pimpl_->sha_)) {} - -SHA& SHA::operator=(const SHA& that) -{ - pimpl_->sha_ = that.pimpl_->sha_; - return *this; -} - - -uint SHA::get_digestSize() const -{ - return SHA_LEN; -} - - -uint SHA::get_padSize() const -{ - return PAD_SHA; -} - - -// Fill out with SHA digest from in that is sz bytes, out must be >= digest sz -void SHA::get_digest(byte* out, const byte* in, unsigned int sz) -{ - pimpl_->sha_.Update(in, sz); - pimpl_->sha_.Final(out); -} - - -// Fill out with SHA digest from previous updates -void SHA::get_digest(byte* out) -{ - pimpl_->sha_.Final(out); -} - - -// Update the current digest -void SHA::update(const byte* in, unsigned int sz) -{ - pimpl_->sha_.Update(in, sz); -} - - -// RMD-160 Implementation -struct RMD::RMDImpl { - TaoCrypt::RIPEMD160 rmd_; - RMDImpl() {} - explicit RMDImpl(const TaoCrypt::RIPEMD160& rmd) : rmd_(rmd) {} -}; - - -RMD::RMD() : pimpl_(NEW_YS RMDImpl) {} - - -RMD::~RMD() { ysDelete(pimpl_); } - - -RMD::RMD(const RMD& that) : Digest(), pimpl_(NEW_YS RMDImpl(that.pimpl_->rmd_)) {} - -RMD& RMD::operator=(const RMD& that) -{ - pimpl_->rmd_ = that.pimpl_->rmd_; - return *this; -} - - -uint RMD::get_digestSize() const -{ - return RMD_LEN; -} - - -uint RMD::get_padSize() const -{ - return PAD_RMD; -} - - -// Fill out with RMD digest from in that is sz bytes, out must be >= digest sz -void RMD::get_digest(byte* out, const byte* in, unsigned int sz) -{ - pimpl_->rmd_.Update(in, sz); - pimpl_->rmd_.Final(out); -} - - -// Fill out with RMD digest from previous updates -void RMD::get_digest(byte* out) -{ - pimpl_->rmd_.Final(out); -} - - -// Update the current digest -void RMD::update(const byte* in, unsigned int sz) -{ - pimpl_->rmd_.Update(in, sz); -} - - -// HMAC_MD5 Implementation -struct HMAC_MD5::HMAC_MD5Impl { - TaoCrypt::HMAC<TaoCrypt::MD5> mac_; - HMAC_MD5Impl() {} -}; - - -HMAC_MD5::HMAC_MD5(const byte* secret, unsigned int len) - : pimpl_(NEW_YS HMAC_MD5Impl) -{ - pimpl_->mac_.SetKey(secret, len); -} - - -HMAC_MD5::~HMAC_MD5() { ysDelete(pimpl_); } - - -uint HMAC_MD5::get_digestSize() const -{ - return MD5_LEN; -} - - -uint HMAC_MD5::get_padSize() const -{ - return PAD_MD5; -} - - -// Fill out with MD5 digest from in that is sz bytes, out must be >= digest sz -void HMAC_MD5::get_digest(byte* out, const byte* in, unsigned int sz) -{ - pimpl_->mac_.Update(in, sz); - pimpl_->mac_.Final(out); -} - -// Fill out with MD5 digest from previous updates -void HMAC_MD5::get_digest(byte* out) -{ - pimpl_->mac_.Final(out); -} - - -// Update the current digest -void HMAC_MD5::update(const byte* in, unsigned int sz) -{ - pimpl_->mac_.Update(in, sz); -} - - -// HMAC_SHA Implementation -struct HMAC_SHA::HMAC_SHAImpl { - TaoCrypt::HMAC<TaoCrypt::SHA> mac_; - HMAC_SHAImpl() {} -}; - - -HMAC_SHA::HMAC_SHA(const byte* secret, unsigned int len) - : pimpl_(NEW_YS HMAC_SHAImpl) -{ - pimpl_->mac_.SetKey(secret, len); -} - - -HMAC_SHA::~HMAC_SHA() { ysDelete(pimpl_); } - - -uint HMAC_SHA::get_digestSize() const -{ - return SHA_LEN; -} - - -uint HMAC_SHA::get_padSize() const -{ - return PAD_SHA; -} - - -// Fill out with SHA digest from in that is sz bytes, out must be >= digest sz -void HMAC_SHA::get_digest(byte* out, const byte* in, unsigned int sz) -{ - pimpl_->mac_.Update(in, sz); - pimpl_->mac_.Final(out); -} - -// Fill out with SHA digest from previous updates -void HMAC_SHA::get_digest(byte* out) -{ - pimpl_->mac_.Final(out); -} - - -// Update the current digest -void HMAC_SHA::update(const byte* in, unsigned int sz) -{ - pimpl_->mac_.Update(in, sz); -} - - - -// HMAC_RMD Implementation -struct HMAC_RMD::HMAC_RMDImpl { - TaoCrypt::HMAC<TaoCrypt::RIPEMD160> mac_; - HMAC_RMDImpl() {} -}; - - -HMAC_RMD::HMAC_RMD(const byte* secret, unsigned int len) - : pimpl_(NEW_YS HMAC_RMDImpl) -{ - pimpl_->mac_.SetKey(secret, len); -} - - -HMAC_RMD::~HMAC_RMD() { ysDelete(pimpl_); } - - -uint HMAC_RMD::get_digestSize() const -{ - return RMD_LEN; -} - - -uint HMAC_RMD::get_padSize() const -{ - return PAD_RMD; -} - - -// Fill out with RMD digest from in that is sz bytes, out must be >= digest sz -void HMAC_RMD::get_digest(byte* out, const byte* in, unsigned int sz) -{ - pimpl_->mac_.Update(in, sz); - pimpl_->mac_.Final(out); -} - -// Fill out with RMD digest from previous updates -void HMAC_RMD::get_digest(byte* out) -{ - pimpl_->mac_.Final(out); -} - - -// Update the current digest -void HMAC_RMD::update(const byte* in, unsigned int sz) -{ - pimpl_->mac_.Update(in, sz); -} - - -struct DES::DESImpl { - TaoCrypt::DES_CBC_Encryption encryption; - TaoCrypt::DES_CBC_Decryption decryption; -}; - - -DES::DES() : pimpl_(NEW_YS DESImpl) {} - -DES::~DES() { ysDelete(pimpl_); } - - -void DES::set_encryptKey(const byte* k, const byte* iv) -{ - pimpl_->encryption.SetKey(k, DES_KEY_SZ, iv); -} - - -void DES::set_decryptKey(const byte* k, const byte* iv) -{ - pimpl_->decryption.SetKey(k, DES_KEY_SZ, iv); -} - -// DES encrypt plain of length sz into cipher -void DES::encrypt(byte* cipher, const byte* plain, unsigned int sz) -{ - pimpl_->encryption.Process(cipher, plain, sz); -} - - -// DES decrypt cipher of length sz into plain -void DES::decrypt(byte* plain, const byte* cipher, unsigned int sz) -{ - pimpl_->decryption.Process(plain, cipher, sz); -} - - -struct DES_EDE::DES_EDEImpl { - TaoCrypt::DES_EDE3_CBC_Encryption encryption; - TaoCrypt::DES_EDE3_CBC_Decryption decryption; -}; - - -DES_EDE::DES_EDE() : pimpl_(NEW_YS DES_EDEImpl) {} - -DES_EDE::~DES_EDE() { ysDelete(pimpl_); } - - -void DES_EDE::set_encryptKey(const byte* k, const byte* iv) -{ - pimpl_->encryption.SetKey(k, DES_EDE_KEY_SZ, iv); -} - - -void DES_EDE::set_decryptKey(const byte* k, const byte* iv) -{ - pimpl_->decryption.SetKey(k, DES_EDE_KEY_SZ, iv); -} - - -// 3DES encrypt plain of length sz into cipher -void DES_EDE::encrypt(byte* cipher, const byte* plain, unsigned int sz) -{ - pimpl_->encryption.Process(cipher, plain, sz); -} - - -// 3DES decrypt cipher of length sz into plain -void DES_EDE::decrypt(byte* plain, const byte* cipher, unsigned int sz) -{ - pimpl_->decryption.Process(plain, cipher, sz); -} - - -// Implementation of alledged RC4 -struct RC4::RC4Impl { - TaoCrypt::ARC4::Encryption encryption; - TaoCrypt::ARC4::Decryption decryption; -}; - - -RC4::RC4() : pimpl_(NEW_YS RC4Impl) {} - -RC4::~RC4() { ysDelete(pimpl_); } - - -void RC4::set_encryptKey(const byte* k, const byte*) -{ - pimpl_->encryption.SetKey(k, RC4_KEY_SZ); -} - - -void RC4::set_decryptKey(const byte* k, const byte*) -{ - pimpl_->decryption.SetKey(k, RC4_KEY_SZ); -} - - -// RC4 encrypt plain of length sz into cipher -void RC4::encrypt(byte* cipher, const byte* plain, unsigned int sz) -{ - pimpl_->encryption.Process(cipher, plain, sz); -} - - -// RC4 decrypt cipher of length sz into plain -void RC4::decrypt(byte* plain, const byte* cipher, unsigned int sz) -{ - pimpl_->decryption.Process(plain, cipher, sz); -} - - - -// Implementation of AES -struct AES::AESImpl { - TaoCrypt::AES_CBC_Encryption encryption; - TaoCrypt::AES_CBC_Decryption decryption; - unsigned int keySz_; - - AESImpl(unsigned int ks) : keySz_(ks) {} -}; - - -AES::AES(unsigned int ks) : pimpl_(NEW_YS AESImpl(ks)) {} - -AES::~AES() { ysDelete(pimpl_); } - - -int AES::get_keySize() const -{ - return pimpl_->keySz_; -} - - -void AES::set_encryptKey(const byte* k, const byte* iv) -{ - pimpl_->encryption.SetKey(k, pimpl_->keySz_, iv); -} - - -void AES::set_decryptKey(const byte* k, const byte* iv) -{ - pimpl_->decryption.SetKey(k, pimpl_->keySz_, iv); -} - - -// AES encrypt plain of length sz into cipher -void AES::encrypt(byte* cipher, const byte* plain, unsigned int sz) -{ - pimpl_->encryption.Process(cipher, plain, sz); -} - - -// AES decrypt cipher of length sz into plain -void AES::decrypt(byte* plain, const byte* cipher, unsigned int sz) -{ - pimpl_->decryption.Process(plain, cipher, sz); -} - - -struct RandomPool::RandomImpl { - TaoCrypt::RandomNumberGenerator RNG_; -}; - -RandomPool::RandomPool() : pimpl_(NEW_YS RandomImpl) {} - -RandomPool::~RandomPool() { ysDelete(pimpl_); } - -int RandomPool::GetError() const -{ - return pimpl_->RNG_.GetError(); -} - -void RandomPool::Fill(opaque* dst, uint sz) const -{ - pimpl_->RNG_.GenerateBlock(dst, sz); -} - - -// Implementation of DSS Authentication -struct DSS::DSSImpl { - void SetPublic (const byte*, unsigned int); - void SetPrivate(const byte*, unsigned int); - TaoCrypt::DSA_PublicKey publicKey_; - TaoCrypt::DSA_PrivateKey privateKey_; -}; - - -// Decode and store the public key -void DSS::DSSImpl::SetPublic(const byte* key, unsigned int sz) -{ - TaoCrypt::Source source(key, sz); - publicKey_.Initialize(source); -} - - -// Decode and store the public key -void DSS::DSSImpl::SetPrivate(const byte* key, unsigned int sz) -{ - TaoCrypt::Source source(key, sz); - privateKey_.Initialize(source); - publicKey_ = TaoCrypt::DSA_PublicKey(privateKey_); - -} - - -// Set public or private key -DSS::DSS(const byte* key, unsigned int sz, bool publicKey) - : pimpl_(NEW_YS DSSImpl) -{ - if (publicKey) - pimpl_->SetPublic(key, sz); - else - pimpl_->SetPrivate(key, sz); -} - - -DSS::~DSS() -{ - ysDelete(pimpl_); -} - - -uint DSS::get_signatureLength() const -{ - return pimpl_->publicKey_.SignatureLength(); -} - - -// DSS Sign message of length sz into sig -void DSS::sign(byte* sig, const byte* sha_digest, unsigned int /* shaSz */, - const RandomPool& random) -{ - using namespace TaoCrypt; - - DSA_Signer signer(pimpl_->privateKey_); - signer.Sign(sha_digest, sig, random.pimpl_->RNG_); -} - - -// DSS Verify message of length sz against sig, is it correct? -bool DSS::verify(const byte* sha_digest, unsigned int /* shaSz */, - const byte* sig, unsigned int /* sigSz */) -{ - using namespace TaoCrypt; - - DSA_Verifier ver(pimpl_->publicKey_); - return ver.Verify(sha_digest, sig); -} - - -// Implementation of RSA key interface -struct RSA::RSAImpl { - void SetPublic (const byte*, unsigned int); - void SetPrivate(const byte*, unsigned int); - TaoCrypt::RSA_PublicKey publicKey_; - TaoCrypt::RSA_PrivateKey privateKey_; -}; - - -// Decode and store the public key -void RSA::RSAImpl::SetPublic(const byte* key, unsigned int sz) -{ - TaoCrypt::Source source(key, sz); - publicKey_.Initialize(source); -} - - -// Decode and store the private key -void RSA::RSAImpl::SetPrivate(const byte* key, unsigned int sz) -{ - TaoCrypt::Source source(key, sz); - privateKey_.Initialize(source); - publicKey_ = TaoCrypt::RSA_PublicKey(privateKey_); -} - - -// Set public or private key -RSA::RSA(const byte* key, unsigned int sz, bool publicKey) - : pimpl_(NEW_YS RSAImpl) -{ - if (publicKey) - pimpl_->SetPublic(key, sz); - else - pimpl_->SetPrivate(key, sz); -} - -RSA::~RSA() -{ - ysDelete(pimpl_); -} - - -// get cipher text length, varies on key size -unsigned int RSA::get_cipherLength() const -{ - return pimpl_->publicKey_.FixedCiphertextLength(); -} - - -// get signautre length, varies on key size -unsigned int RSA::get_signatureLength() const -{ - return get_cipherLength(); -} - - -// RSA Sign message of length sz into sig -void RSA::sign(byte* sig, const byte* message, unsigned int sz, - const RandomPool& random) -{ - TaoCrypt::RSAES_Decryptor dec(pimpl_->privateKey_); - dec.SSL_Sign(message, sz, sig, random.pimpl_->RNG_); -} - - -// RSA Verify message of length sz against sig -bool RSA::verify(const byte* message, unsigned int sz, const byte* sig, - unsigned int) -{ - TaoCrypt::RSAES_Encryptor enc(pimpl_->publicKey_); - return enc.SSL_Verify(message, sz, sig); -} - - -// RSA public encrypt plain of length sz into cipher -void RSA::encrypt(byte* cipher, const byte* plain, unsigned int sz, - const RandomPool& random) -{ - - TaoCrypt::RSAES_Encryptor enc(pimpl_->publicKey_); - enc.Encrypt(plain, sz, cipher, random.pimpl_->RNG_); -} - - -// RSA private decrypt cipher of length sz into plain -void RSA::decrypt(byte* plain, const byte* cipher, unsigned int sz, - const RandomPool& random) -{ - TaoCrypt::RSAES_Decryptor dec(pimpl_->privateKey_); - dec.Decrypt(cipher, sz, plain, random.pimpl_->RNG_); -} - - -struct Integer::IntegerImpl { - TaoCrypt::Integer int_; - - IntegerImpl() {} - explicit IntegerImpl(const TaoCrypt::Integer& i) : int_(i) {} -}; - -Integer::Integer() : pimpl_(NEW_YS IntegerImpl) {} - -Integer::~Integer() { ysDelete(pimpl_); } - - - -Integer::Integer(const Integer& other) : pimpl_(NEW_YS - IntegerImpl(other.pimpl_->int_)) -{} - - -Integer& Integer::operator=(const Integer& that) -{ - pimpl_->int_ = that.pimpl_->int_; - - return *this; -} - - -void Integer::assign(const byte* num, unsigned int sz) -{ - pimpl_->int_ = TaoCrypt::Integer(num, sz); -} - - -struct DiffieHellman::DHImpl { - TaoCrypt::DH dh_; - TaoCrypt::RandomNumberGenerator& ranPool_; - byte* publicKey_; - byte* privateKey_; - byte* agreedKey_; - uint pubKeyLength_; - - DHImpl(TaoCrypt::RandomNumberGenerator& r) : ranPool_(r), publicKey_(0), - privateKey_(0), agreedKey_(0), pubKeyLength_(0) {} - ~DHImpl() - { - ysArrayDelete(agreedKey_); - ysArrayDelete(privateKey_); - ysArrayDelete(publicKey_); - } - - DHImpl(const DHImpl& that) : dh_(that.dh_), ranPool_(that.ranPool_), - publicKey_(0), privateKey_(0), agreedKey_(0), pubKeyLength_(0) - { - uint length = dh_.GetByteLength(); - AllocKeys(length, length, length); - } - - void AllocKeys(unsigned int pubSz, unsigned int privSz, unsigned int agrSz) - { - publicKey_ = NEW_YS byte[pubSz]; - privateKey_ = NEW_YS byte[privSz]; - agreedKey_ = NEW_YS byte[agrSz]; - } -}; - - - -/* -// server Side DH, server's view -DiffieHellman::DiffieHellman(const char* file, const RandomPool& random) - : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_)) -{ - using namespace TaoCrypt; - Source source; - FileSource(file, source); - if (source.size() == 0) - return; // TODO add error state, and force check - HexDecoder hd(source); - - pimpl_->dh_.Initialize(source); - - uint length = pimpl_->dh_.GetByteLength(); - - pimpl_->AllocKeys(length, length, length); - pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_, - pimpl_->publicKey_); -} -*/ - - -// server Side DH, client's view -DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g, - unsigned int gSz, const byte* pub, - unsigned int pubSz, const RandomPool& random) - : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_)) -{ - using TaoCrypt::Integer; - - pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref()); - pimpl_->publicKey_ = NEW_YS opaque[pimpl_->pubKeyLength_ = pubSz]; - memcpy(pimpl_->publicKey_, pub, pubSz); -} - - -// Server Side DH, server's view -DiffieHellman::DiffieHellman(const Integer& p, const Integer& g, - const RandomPool& random) -: pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_)) -{ - using TaoCrypt::Integer; - - pimpl_->dh_.Initialize(p.pimpl_->int_, g.pimpl_->int_); - - uint length = pimpl_->dh_.GetByteLength(); - - pimpl_->AllocKeys(length, length, length); - pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_, - pimpl_->publicKey_); -} - -DiffieHellman::~DiffieHellman() { ysDelete(pimpl_); } - - -// Client side and view, use server that for p and g -DiffieHellman::DiffieHellman(const DiffieHellman& that) - : pimpl_(NEW_YS DHImpl(*that.pimpl_)) -{ - pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_, - pimpl_->publicKey_); -} - - -DiffieHellman& DiffieHellman::operator=(const DiffieHellman& that) -{ - pimpl_->dh_ = that.pimpl_->dh_; - pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_, - pimpl_->publicKey_); - return *this; -} - - -void DiffieHellman::makeAgreement(const byte* other, unsigned int otherSz) -{ - pimpl_->dh_.Agree(pimpl_->agreedKey_, pimpl_->privateKey_, other, otherSz); -} - - -uint DiffieHellman::get_agreedKeyLength() const -{ - return pimpl_->dh_.GetByteLength(); -} - - -const byte* DiffieHellman::get_agreedKey() const -{ - return pimpl_->agreedKey_; -} - -uint DiffieHellman::get_publicKeyLength() const -{ - return pimpl_->pubKeyLength_; -} - -const byte* DiffieHellman::get_publicKey() const -{ - return pimpl_->publicKey_; -} - - -void DiffieHellman::set_sizes(int& pSz, int& gSz, int& pubSz) const -{ - using TaoCrypt::Integer; - Integer p = pimpl_->dh_.GetP(); - Integer g = pimpl_->dh_.GetG(); - - pSz = p.ByteCount(); - gSz = g.ByteCount(); - pubSz = pimpl_->dh_.GetByteLength(); -} - - -void DiffieHellman::get_parms(byte* bp, byte* bg, byte* bpub) const -{ - using TaoCrypt::Integer; - Integer p = pimpl_->dh_.GetP(); - Integer g = pimpl_->dh_.GetG(); - - p.Encode(bp, p.ByteCount()); - g.Encode(bg, g.ByteCount()); - memcpy(bpub, pimpl_->publicKey_, pimpl_->dh_.GetByteLength()); -} - - -// convert PEM file to DER x509 type -x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info) -{ - using namespace TaoCrypt; - - char header[80]; - char footer[80]; - - if (type == Cert) { - strncpy(header, "-----BEGIN CERTIFICATE-----", sizeof(header)); - strncpy(footer, "-----END CERTIFICATE-----", sizeof(footer)); - } else { - strncpy(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header)); - strncpy(footer, "-----END RSA PRIVATE KEY-----", sizeof(header)); - } - - long begin = -1; - long end = 0; - bool foundEnd = false; - - char line[80]; - - while(fgets(line, sizeof(line), file)) - if (strncmp(header, line, strlen(header)) == 0) { - begin = ftell(file); - break; - } - - // remove encrypted header if there - if (fgets(line, sizeof(line), file)) { - char encHeader[] = "Proc-Type"; - if (strncmp(encHeader, line, strlen(encHeader)) == 0 && - fgets(line,sizeof(line), file)) { - - char* start = strstr(line, "DES"); - char* finish = strstr(line, ","); - if (!start) - start = strstr(line, "AES"); - - if (!info) return 0; - - if ( start && finish && (start < finish)) { - memcpy(info->name, start, finish - start); - info->name[finish - start] = 0; - memcpy(info->iv, finish + 1, sizeof(info->iv)); - - char* newline = strstr(line, "\r"); - if (!newline) newline = strstr(line, "\n"); - if (newline && (newline > finish)) { - info->ivSz = newline - (finish + 1); - info->set = true; - } - } - begin = ftell(file); - if (fgets(line,sizeof(line), file)) // get blank line - begin = ftell(file); - } - - } - - while(fgets(line, sizeof(line), file)) - if (strncmp(footer, line, strlen(footer)) == 0) { - foundEnd = true; - break; - } - else - end = ftell(file); - - if (begin == -1 || !foundEnd) - return 0; - - input_buffer tmp(end - begin); - fseek(file, begin, SEEK_SET); - size_t bytes = fread(tmp.get_buffer(), end - begin, 1, file); - if (bytes != 1) - return 0; - - Source der(tmp.get_buffer(), end - begin); - Base64Decoder b64Dec(der); - - uint sz = der.size(); - mySTL::auto_ptr<x509> x(NEW_YS x509(sz)); - memcpy(x->use_buffer(), der.get_buffer(), sz); - - return x.release(); -} - - -} // namespace - -#endif // !USE_CRYPTOPP_LIB diff --git a/extra/yassl/src/dummy.cpp b/extra/yassl/src/dummy.cpp deleted file mode 100644 index 19b7fe887cd..00000000000 --- a/extra/yassl/src/dummy.cpp +++ /dev/null @@ -1,4 +0,0 @@ -/* - To make libtool always use a C++ linker when compiling with yaSSL we need - to add a dummy C++ file to the source list. -*/ diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp deleted file mode 100644 index 91d3d6b5914..00000000000 --- a/extra/yassl/src/handshake.cpp +++ /dev/null @@ -1,1203 +0,0 @@ -/* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* The handshake source implements functions for creating and reading - * the various handshake messages. - */ - - - -#include "runtime.hpp" -#include "handshake.hpp" -#include "yassl_int.hpp" - - -namespace yaSSL { - - - -// Build a client hello message from cipher suites and compression method -void buildClientHello(SSL& ssl, ClientHello& hello) -{ - // store for pre master secret - ssl.useSecurity().use_connection().chVersion_ = hello.client_version_; - - ssl.getCrypto().get_random().Fill(hello.random_, RAN_LEN); - if (ssl.getSecurity().get_resuming()) { - hello.id_len_ = ID_LEN; - memcpy(hello.session_id_, ssl.getSecurity().get_resume().GetID(), - ID_LEN); - } - else - hello.id_len_ = 0; - hello.suite_len_ = ssl.getSecurity().get_parms().suites_size_; - memcpy(hello.cipher_suites_, ssl.getSecurity().get_parms().suites_, - hello.suite_len_); - hello.comp_len_ = 1; - - hello.set_length(sizeof(ProtocolVersion) + - RAN_LEN + - hello.id_len_ + sizeof(hello.id_len_) + - hello.suite_len_ + sizeof(hello.suite_len_) + - hello.comp_len_ + sizeof(hello.comp_len_)); -} - - -// Build a server hello message -void buildServerHello(SSL& ssl, ServerHello& hello) -{ - if (ssl.getSecurity().get_resuming()) { - memcpy(hello.random_,ssl.getSecurity().get_connection().server_random_, - RAN_LEN); - memcpy(hello.session_id_, ssl.getSecurity().get_resume().GetID(), - ID_LEN); - } - else { - ssl.getCrypto().get_random().Fill(hello.random_, RAN_LEN); - ssl.getCrypto().get_random().Fill(hello.session_id_, ID_LEN); - } - hello.id_len_ = ID_LEN; - ssl.set_sessionID(hello.session_id_); - - hello.cipher_suite_[0] = ssl.getSecurity().get_parms().suite_[0]; - hello.cipher_suite_[1] = ssl.getSecurity().get_parms().suite_[1]; - hello.compression_method_ = hello.compression_method_; - - hello.set_length(sizeof(ProtocolVersion) + RAN_LEN + ID_LEN + - sizeof(hello.id_len_) + SUITE_LEN + SIZEOF_ENUM); -} - - -// add handshake from buffer into md5 and sha hashes, use handshake header -void hashHandShake(SSL& ssl, const input_buffer& input, uint sz) -{ - const opaque* buffer = input.get_buffer() + input.get_current() - - HANDSHAKE_HEADER; - sz += HANDSHAKE_HEADER; - ssl.useHashes().use_MD5().update(buffer, sz); - ssl.useHashes().use_SHA().update(buffer, sz); -} - - -// locals -namespace { - -// Write a plaintext record to buffer -void buildOutput(output_buffer& buffer, const RecordLayerHeader& rlHdr, - const Message& msg) -{ - buffer.allocate(RECORD_HEADER + rlHdr.length_); - buffer << rlHdr << msg; -} - - -// Write a plaintext record to buffer -void buildOutput(output_buffer& buffer, const RecordLayerHeader& rlHdr, - const HandShakeHeader& hsHdr, const HandShakeBase& shake) -{ - buffer.allocate(RECORD_HEADER + rlHdr.length_); - buffer << rlHdr << hsHdr << shake; -} - - -// Build Record Layer header for Message without handshake header -void buildHeader(SSL& ssl, RecordLayerHeader& rlHeader, const Message& msg) -{ - ProtocolVersion pv = ssl.getSecurity().get_connection().version_; - rlHeader.type_ = msg.get_type(); - rlHeader.version_.major_ = pv.major_; - rlHeader.version_.minor_ = pv.minor_; - rlHeader.length_ = msg.get_length(); -} - - -// Build HandShake and RecordLayer Headers for handshake output -void buildHeaders(SSL& ssl, HandShakeHeader& hsHeader, - RecordLayerHeader& rlHeader, const HandShakeBase& shake) -{ - int sz = shake.get_length(); - - hsHeader.set_type(shake.get_type()); - hsHeader.set_length(sz); - - ProtocolVersion pv = ssl.getSecurity().get_connection().version_; - rlHeader.type_ = handshake; - rlHeader.version_.major_ = pv.major_; - rlHeader.version_.minor_ = pv.minor_; - rlHeader.length_ = sz + HANDSHAKE_HEADER; -} - - -// add handshake from buffer into md5 and sha hashes, exclude record header -void hashHandShake(SSL& ssl, const output_buffer& output, bool removeIV = false) -{ - uint sz = output.get_size() - RECORD_HEADER; - - const opaque* buffer = output.get_buffer() + RECORD_HEADER; - - if (removeIV) { // TLSv1_1 IV - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); - sz -= blockSz; - buffer += blockSz; - } - - ssl.useHashes().use_MD5().update(buffer, sz); - ssl.useHashes().use_SHA().update(buffer, sz); -} - - -// calculate MD5 hash for finished -void buildMD5(SSL& ssl, Finished& fin, const opaque* sender) -{ - - opaque md5_result[MD5_LEN]; - opaque md5_inner[SIZEOF_SENDER + SECRET_LEN + PAD_MD5]; - opaque md5_outer[SECRET_LEN + PAD_MD5 + MD5_LEN]; - - const opaque* master_secret = - ssl.getSecurity().get_connection().master_secret_; - - // make md5 inner - memcpy(md5_inner, sender, SIZEOF_SENDER); - memcpy(&md5_inner[SIZEOF_SENDER], master_secret, SECRET_LEN); - memcpy(&md5_inner[SIZEOF_SENDER + SECRET_LEN], PAD1, PAD_MD5); - - ssl.useHashes().use_MD5().get_digest(md5_result, md5_inner, - sizeof(md5_inner)); - - // make md5 outer - memcpy(md5_outer, master_secret, SECRET_LEN); - memcpy(&md5_outer[SECRET_LEN], PAD2, PAD_MD5); - memcpy(&md5_outer[SECRET_LEN + PAD_MD5], md5_result, MD5_LEN); - - ssl.useHashes().use_MD5().get_digest(fin.set_md5(), md5_outer, - sizeof(md5_outer)); -} - - -// calculate SHA hash for finished -void buildSHA(SSL& ssl, Finished& fin, const opaque* sender) -{ - - opaque sha_result[SHA_LEN]; - opaque sha_inner[SIZEOF_SENDER + SECRET_LEN + PAD_SHA]; - opaque sha_outer[SECRET_LEN + PAD_SHA + SHA_LEN]; - - const opaque* master_secret = - ssl.getSecurity().get_connection().master_secret_; - - // make sha inner - memcpy(sha_inner, sender, SIZEOF_SENDER); - memcpy(&sha_inner[SIZEOF_SENDER], master_secret, SECRET_LEN); - memcpy(&sha_inner[SIZEOF_SENDER + SECRET_LEN], PAD1, PAD_SHA); - - ssl.useHashes().use_SHA().get_digest(sha_result, sha_inner, - sizeof(sha_inner)); - - // make sha outer - memcpy(sha_outer, master_secret, SECRET_LEN); - memcpy(&sha_outer[SECRET_LEN], PAD2, PAD_SHA); - memcpy(&sha_outer[SECRET_LEN + PAD_SHA], sha_result, SHA_LEN); - - ssl.useHashes().use_SHA().get_digest(fin.set_sha(), sha_outer, - sizeof(sha_outer)); -} - - -// sanity checks on encrypted message size -static int sanity_check_message(SSL& ssl, uint msgSz) -{ - uint minSz = 0; - - if (ssl.getSecurity().get_parms().cipher_type_ == block) { - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); - if (msgSz % blockSz) - return -1; - - minSz = ssl.getSecurity().get_parms().hash_size_ + 1; // pad byte too - if (blockSz > minSz) - minSz = blockSz; - - if (ssl.isTLSv1_1()) - minSz += blockSz; // explicit IV - } - else { // stream - minSz = ssl.getSecurity().get_parms().hash_size_; - } - - if (msgSz < minSz) - return -1; - - return 0; -} - - -// decrypt input message in place, store size in case needed later -void decrypt_message(SSL& ssl, input_buffer& input, uint sz) -{ - input_buffer plain(sz); - opaque* cipher = input.get_buffer() + input.get_current(); - - if (sanity_check_message(ssl, sz) != 0) { - ssl.SetError(sanityCipher_error); - return; - } - - ssl.useCrypto().use_cipher().decrypt(plain.get_buffer(), cipher, sz); - memcpy(cipher, plain.get_buffer(), sz); - ssl.useSecurity().use_parms().encrypt_size_ = sz; - - if (ssl.isTLSv1_1()) // IV - input.set_current(input.get_current() + - ssl.getCrypto().get_cipher().get_blockSize()); -} - - -// output operator for input_buffer -output_buffer& operator<<(output_buffer& output, const input_buffer& input) -{ - output.write(input.get_buffer(), input.get_size()); - return output; -} - - -// write headers, handshake hash, mac, pad, and encrypt -void cipherFinished(SSL& ssl, Finished& fin, output_buffer& output) -{ - uint digestSz = ssl.getCrypto().get_digest().get_digestSize(); - uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ; - uint sz = RECORD_HEADER + HANDSHAKE_HEADER + finishedSz + digestSz; - uint pad = 0; - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); - - if (ssl.getSecurity().get_parms().cipher_type_ == block) { - if (ssl.isTLSv1_1()) - sz += blockSz; // IV - sz += 1; // pad byte - pad = (sz - RECORD_HEADER) % blockSz; - pad = blockSz - pad; - sz += pad; - } - - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - buildHeaders(ssl, hsHeader, rlHeader, fin); - rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac - // and pad, hanshake doesn't - input_buffer iv; - if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ - iv.allocate(blockSz); - ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); - iv.add_size(blockSz); - } - uint ivSz = iv.get_size(); - output.allocate(sz); - output << rlHeader << iv << hsHeader << fin; - - hashHandShake(ssl, output, ssl.isTLSv1_1() ? true : false); - opaque digest[SHA_LEN]; // max size - if (ssl.isTLS()) - TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, - output.get_size() - RECORD_HEADER - ivSz, handshake); - else - hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, - output.get_size() - RECORD_HEADER, handshake); - output.write(digest, digestSz); - - if (ssl.getSecurity().get_parms().cipher_type_ == block) - for (uint i = 0; i <= pad; i++) output[AUTO] = pad; // pad byte gets - // pad value too - input_buffer cipher(rlHeader.length_); - ssl.useCrypto().use_cipher().encrypt(cipher.get_buffer(), - output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER); - output.set_current(RECORD_HEADER); - output.write(cipher.get_buffer(), cipher.get_capacity()); -} - - -// build an encrypted data or alert message for output -void buildMessage(SSL& ssl, output_buffer& output, const Message& msg) -{ - uint digestSz = ssl.getCrypto().get_digest().get_digestSize(); - uint sz = RECORD_HEADER + msg.get_length() + digestSz; - uint pad = 0; - uint blockSz = ssl.getCrypto().get_cipher().get_blockSize(); - - if (ssl.getSecurity().get_parms().cipher_type_ == block) { - if (ssl.isTLSv1_1()) // IV - sz += blockSz; - sz += 1; // pad byte - pad = (sz - RECORD_HEADER) % blockSz; - pad = blockSz - pad; - sz += pad; - } - - RecordLayerHeader rlHeader; - buildHeader(ssl, rlHeader, msg); - rlHeader.length_ = sz - RECORD_HEADER; // record header includes mac - // and pad, hanshake doesn't - input_buffer iv; - if (ssl.isTLSv1_1() && ssl.getSecurity().get_parms().cipher_type_== block){ - iv.allocate(blockSz); - ssl.getCrypto().get_random().Fill(iv.get_buffer(), blockSz); - iv.add_size(blockSz); - } - - uint ivSz = iv.get_size(); - output.allocate(sz); - output << rlHeader << iv << msg; - - opaque digest[SHA_LEN]; // max size - if (ssl.isTLS()) - TLS_hmac(ssl, digest, output.get_buffer() + RECORD_HEADER + ivSz, - output.get_size() - RECORD_HEADER - ivSz, msg.get_type()); - else - hmac(ssl, digest, output.get_buffer() + RECORD_HEADER, - output.get_size() - RECORD_HEADER, msg.get_type()); - output.write(digest, digestSz); - - if (ssl.getSecurity().get_parms().cipher_type_ == block) - for (uint i = 0; i <= pad; i++) output[AUTO] = pad; // pad byte gets - // pad value too - input_buffer cipher(rlHeader.length_); - ssl.useCrypto().use_cipher().encrypt(cipher.get_buffer(), - output.get_buffer() + RECORD_HEADER, output.get_size() - RECORD_HEADER); - output.set_current(RECORD_HEADER); - output.write(cipher.get_buffer(), cipher.get_capacity()); -} - - -// build alert message -void buildAlert(SSL& ssl, output_buffer& output, const Alert& alert) -{ - if (ssl.getSecurity().get_parms().pending_ == false) // encrypted - buildMessage(ssl, output, alert); - else { - RecordLayerHeader rlHeader; - buildHeader(ssl, rlHeader, alert); - buildOutput(output, rlHeader, alert); - } -} - - -// build TLS finished message -void buildFinishedTLS(SSL& ssl, Finished& fin, const opaque* sender) -{ - opaque handshake_hash[FINISHED_SZ]; - - ssl.useHashes().use_MD5().get_digest(handshake_hash); - ssl.useHashes().use_SHA().get_digest(&handshake_hash[MD5_LEN]); - - const opaque* side; - if ( strncmp((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) - side = tls_client; - else - side = tls_server; - - PRF(fin.set_md5(), TLS_FINISHED_SZ, - ssl.getSecurity().get_connection().master_secret_, SECRET_LEN, - side, FINISHED_LABEL_SZ, - handshake_hash, FINISHED_SZ); - - fin.set_length(TLS_FINISHED_SZ); // shorter length for TLS -} - - -// compute p_hash for MD5 or SHA-1 for TLSv1 PRF -void p_hash(output_buffer& result, const output_buffer& secret, - const output_buffer& seed, MACAlgorithm hash) -{ - uint len = hash == md5 ? MD5_LEN : SHA_LEN; - uint times = result.get_capacity() / len; - uint lastLen = result.get_capacity() % len; - opaque previous[SHA_LEN]; // max size - opaque current[SHA_LEN]; // max size - mySTL::auto_ptr<Digest> hmac; - - if (lastLen) times += 1; - - if (hash == md5) - hmac.reset(NEW_YS HMAC_MD5(secret.get_buffer(), secret.get_size())); - else - hmac.reset(NEW_YS HMAC_SHA(secret.get_buffer(), secret.get_size())); - // A0 = seed - hmac->get_digest(previous, seed.get_buffer(), seed.get_size());// A1 - uint lastTime = times - 1; - - for (uint i = 0; i < times; i++) { - hmac->update(previous, len); - hmac->get_digest(current, seed.get_buffer(), seed.get_size()); - - if (lastLen && (i == lastTime)) - result.write(current, lastLen); - else { - result.write(current, len); - //memcpy(previous, current, len); - hmac->get_digest(previous, previous, len); - } - } -} - - -// calculate XOR for TLSv1 PRF -void get_xor(byte *digest, uint digLen, output_buffer& md5, - output_buffer& sha) -{ - for (uint i = 0; i < digLen; i++) - digest[i] = md5[AUTO] ^ sha[AUTO]; -} - - -// build MD5 part of certificate verify -void buildMD5_CertVerify(SSL& ssl, byte* digest) -{ - opaque md5_result[MD5_LEN]; - opaque md5_inner[SECRET_LEN + PAD_MD5]; - opaque md5_outer[SECRET_LEN + PAD_MD5 + MD5_LEN]; - - const opaque* master_secret = - ssl.getSecurity().get_connection().master_secret_; - - // make md5 inner - memcpy(md5_inner, master_secret, SECRET_LEN); - memcpy(&md5_inner[SECRET_LEN], PAD1, PAD_MD5); - - ssl.useHashes().use_MD5().get_digest(md5_result, md5_inner, - sizeof(md5_inner)); - - // make md5 outer - memcpy(md5_outer, master_secret, SECRET_LEN); - memcpy(&md5_outer[SECRET_LEN], PAD2, PAD_MD5); - memcpy(&md5_outer[SECRET_LEN + PAD_MD5], md5_result, MD5_LEN); - - ssl.useHashes().use_MD5().get_digest(digest, md5_outer, sizeof(md5_outer)); -} - - -// build SHA part of certificate verify -void buildSHA_CertVerify(SSL& ssl, byte* digest) -{ - opaque sha_result[SHA_LEN]; - opaque sha_inner[SECRET_LEN + PAD_SHA]; - opaque sha_outer[SECRET_LEN + PAD_SHA + SHA_LEN]; - - const opaque* master_secret = - ssl.getSecurity().get_connection().master_secret_; - - // make sha inner - memcpy(sha_inner, master_secret, SECRET_LEN); - memcpy(&sha_inner[SECRET_LEN], PAD1, PAD_SHA); - - ssl.useHashes().use_SHA().get_digest(sha_result, sha_inner, - sizeof(sha_inner)); - - // make sha outer - memcpy(sha_outer, master_secret, SECRET_LEN); - memcpy(&sha_outer[SECRET_LEN], PAD2, PAD_SHA); - memcpy(&sha_outer[SECRET_LEN + PAD_SHA], sha_result, SHA_LEN); - - ssl.useHashes().use_SHA().get_digest(digest, sha_outer, sizeof(sha_outer)); -} - - -} // namespace for locals - - -// some clients still send sslv2 client hello -void ProcessOldClientHello(input_buffer& input, SSL& ssl) -{ - if (input.get_error() || input.get_remaining() < 2) { - ssl.SetError(bad_input); - return; - } - byte b0 = input[AUTO]; - byte b1 = input[AUTO]; - - uint16 sz = ((b0 & 0x7f) << 8) | b1; - - if (sz > input.get_remaining()) { - ssl.SetError(bad_input); - return; - } - - // hashHandShake manually - const opaque* buffer = input.get_buffer() + input.get_current(); - ssl.useHashes().use_MD5().update(buffer, sz); - ssl.useHashes().use_SHA().update(buffer, sz); - - b1 = input[AUTO]; // does this value mean client_hello? - - ClientHello ch; - ch.client_version_.major_ = input[AUTO]; - ch.client_version_.minor_ = input[AUTO]; - - byte len[2]; - - len[0] = input[AUTO]; - len[1] = input[AUTO]; - ato16(len, ch.suite_len_); - - len[0] = input[AUTO]; - len[1] = input[AUTO]; - uint16 sessionLen; - ato16(len, sessionLen); - ch.id_len_ = sessionLen; - - len[0] = input[AUTO]; - len[1] = input[AUTO]; - uint16 randomLen; - ato16(len, randomLen); - - if (input.get_error() || ch.suite_len_ > MAX_SUITE_SZ || - ch.suite_len_ > input.get_remaining() || - sessionLen > ID_LEN || randomLen > RAN_LEN) { - ssl.SetError(bad_input); - return; - } - - int j = 0; - for (uint16 i = 0; i < ch.suite_len_; i += 3) { - byte first = input[AUTO]; - if (first) // sslv2 type - input.read(len, SUITE_LEN); // skip - else { - input.read(&ch.cipher_suites_[j], SUITE_LEN); - j += SUITE_LEN; - } - } - ch.suite_len_ = j; - - if (ch.id_len_) - input.read(ch.session_id_, ch.id_len_); // id_len_ from sessionLen - - if (randomLen < RAN_LEN) - memset(ch.random_, 0, RAN_LEN - randomLen); - input.read(&ch.random_[RAN_LEN - randomLen], randomLen); - - ch.Process(input, ssl); -} - - -// Build a finished message, see 7.6.9 -void buildFinished(SSL& ssl, Finished& fin, const opaque* sender) -{ - // store current states, building requires get_digest which resets state - MD5 md5(ssl.getHashes().get_MD5()); - SHA sha(ssl.getHashes().get_SHA()); - - if (ssl.isTLS()) - buildFinishedTLS(ssl, fin, sender); - else { - buildMD5(ssl, fin, sender); - buildSHA(ssl, fin, sender); - } - - // restore - ssl.useHashes().use_MD5() = md5; - ssl.useHashes().use_SHA() = sha; -} - - -/* compute SSLv3 HMAC into digest see - * buffer is of sz size and includes HandShake Header but not a Record Header - * verify means to check peers hmac -*/ -void hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, - ContentType content, bool verify) -{ - Digest& mac = ssl.useCrypto().use_digest(); - opaque inner[SHA_LEN + PAD_MD5 + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ]; - opaque outer[SHA_LEN + PAD_MD5 + SHA_LEN]; - opaque result[SHA_LEN]; // max possible sizes - uint digestSz = mac.get_digestSize(); // actual sizes - uint padSz = mac.get_padSize(); - uint innerSz = digestSz + padSz + SEQ_SZ + SIZEOF_ENUM + LENGTH_SZ; - uint outerSz = digestSz + padSz + digestSz; - - // data - const opaque* mac_secret = ssl.get_macSecret(verify); - opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; - opaque length[LENGTH_SZ]; - c16toa(sz, length); - c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); - - // make inner - memcpy(inner, mac_secret, digestSz); - memcpy(&inner[digestSz], PAD1, padSz); - memcpy(&inner[digestSz + padSz], seq, SEQ_SZ); - inner[digestSz + padSz + SEQ_SZ] = content; - memcpy(&inner[digestSz + padSz + SEQ_SZ + SIZEOF_ENUM], length, LENGTH_SZ); - - mac.update(inner, innerSz); - mac.get_digest(result, buffer, sz); // append content buffer - - // make outer - memcpy(outer, mac_secret, digestSz); - memcpy(&outer[digestSz], PAD2, padSz); - memcpy(&outer[digestSz + padSz], result, digestSz); - - mac.get_digest(digest, outer, outerSz); -} - - -// TLS type HAMC -void TLS_hmac(SSL& ssl, byte* digest, const byte* buffer, uint sz, - ContentType content, bool verify) -{ - mySTL::auto_ptr<Digest> hmac; - opaque seq[SEQ_SZ] = { 0x00, 0x00, 0x00, 0x00 }; - opaque length[LENGTH_SZ]; - opaque inner[SIZEOF_ENUM + VERSION_SZ + LENGTH_SZ]; // type + version + len - - c16toa(sz, length); - c32toa(ssl.get_SEQIncrement(verify), &seq[sizeof(uint32)]); - - MACAlgorithm algo = ssl.getSecurity().get_parms().mac_algorithm_; - - if (algo == sha) - hmac.reset(NEW_YS HMAC_SHA(ssl.get_macSecret(verify), SHA_LEN)); - else if (algo == rmd) - hmac.reset(NEW_YS HMAC_RMD(ssl.get_macSecret(verify), RMD_LEN)); - else - hmac.reset(NEW_YS HMAC_MD5(ssl.get_macSecret(verify), MD5_LEN)); - - hmac->update(seq, SEQ_SZ); // seq_num - inner[0] = content; // type - inner[SIZEOF_ENUM] = ssl.getSecurity().get_connection().version_.major_; - inner[SIZEOF_ENUM + SIZEOF_ENUM] = - ssl.getSecurity().get_connection().version_.minor_; // version - memcpy(&inner[SIZEOF_ENUM + VERSION_SZ], length, LENGTH_SZ); // length - hmac->update(inner, sizeof(inner)); - hmac->get_digest(digest, buffer, sz); // content -} - - -// compute TLSv1 PRF (pseudo random function using HMAC) -void PRF(byte* digest, uint digLen, const byte* secret, uint secLen, - const byte* label, uint labLen, const byte* seed, uint seedLen) -{ - uint half = (secLen + 1) / 2; - - output_buffer md5_half(half); - output_buffer sha_half(half); - output_buffer labelSeed(labLen + seedLen); - - md5_half.write(secret, half); - sha_half.write(secret + half - secLen % 2, half); - labelSeed.write(label, labLen); - labelSeed.write(seed, seedLen); - - output_buffer md5_result(digLen); - output_buffer sha_result(digLen); - - p_hash(md5_result, md5_half, labelSeed, md5); - p_hash(sha_result, sha_half, labelSeed, sha); - - md5_result.set_current(0); - sha_result.set_current(0); - get_xor(digest, digLen, md5_result, sha_result); -} - - -// build certificate hashes -void build_certHashes(SSL& ssl, Hashes& hashes) -{ - // store current states, building requires get_digest which resets state - MD5 md5(ssl.getHashes().get_MD5()); - SHA sha(ssl.getHashes().get_SHA()); - - if (ssl.isTLS()) { - ssl.useHashes().use_MD5().get_digest(hashes.md5_); - ssl.useHashes().use_SHA().get_digest(hashes.sha_); - } - else { - buildMD5_CertVerify(ssl, hashes.md5_); - buildSHA_CertVerify(ssl, hashes.sha_); - } - - // restore - ssl.useHashes().use_MD5() = md5; - ssl.useHashes().use_SHA() = sha; -} - - - -// do process input requests, return 0 is done, 1 is call again to complete -int DoProcessReply(SSL& ssl) -{ - // wait for input if blocking - if (!ssl.useSocket().wait()) { - ssl.SetError(receive_error); - return 0; - } - uint ready = ssl.getSocket().get_ready(); - if (!ready) - ready= 64; - - // add buffered data if its there - input_buffer* buffered = ssl.useBuffers().TakeRawInput(); - uint buffSz = buffered ? buffered->get_size() : 0; - input_buffer buffer(buffSz + ready); - if (buffSz) { - buffer.assign(buffered->get_buffer(), buffSz); - ysDelete(buffered); - buffered = 0; - } - - // add new data - uint read = ssl.useSocket().receive(buffer.get_buffer() + buffSz, ready); - if (read == static_cast<uint>(-1)) { - ssl.SetError(receive_error); - return 0; - } - buffer.add_size(read); - uint offset = 0; - const MessageFactory& mf = ssl.getFactory().getMessage(); - - // old style sslv2 client hello? - if (ssl.getSecurity().get_parms().entity_ == server_end && - ssl.getStates().getServer() == clientNull) - if (buffer.peek() != handshake) { - ProcessOldClientHello(buffer, ssl); - if (ssl.GetError()) - return 0; - } - - while(!buffer.eof()) { - // each record - RecordLayerHeader hdr; - bool needHdr = false; - - if (static_cast<uint>(RECORD_HEADER) > buffer.get_remaining()) - needHdr = true; - else { - buffer >> hdr; - /* - According to RFC 4346 (see "7.4.1.3. Server Hello"), the Server Hello - packet needs to specify the highest supported TLS version, but not - higher than what client requests. YaSSL highest supported version is - TLSv1.1 (=3.2) - if the client requests a higher version, downgrade it - here to 3.2. - See also Appendix E of RFC 5246 (TLS 1.2) - */ - if (hdr.version_.major_ == 3 && hdr.version_.minor_ > 2) - hdr.version_.minor_ = 2; - ssl.verifyState(hdr); - } - - if (ssl.GetError()) - return 0; - - // make sure we have enough input in buffer to process this record - if (needHdr || hdr.length_ > buffer.get_remaining()) { - // put header in front for next time processing - uint extra = needHdr ? 0 : RECORD_HEADER; - uint sz = buffer.get_remaining() + extra; - ssl.useBuffers().SetRawInput(NEW_YS input_buffer(sz, - buffer.get_buffer() + buffer.get_current() - extra, sz)); - return 1; - } - - while (buffer.get_current() < hdr.length_ + RECORD_HEADER + offset) { - // each message in record, can be more than 1 if not encrypted - if (ssl.GetError()) - return 0; - - if (ssl.getSecurity().get_parms().pending_ == false) { // cipher on - // sanity check for malicious/corrupted/illegal input - if (buffer.get_remaining() < hdr.length_) { - ssl.SetError(bad_input); - return 0; - } - decrypt_message(ssl, buffer, hdr.length_); - if (ssl.GetError()) - return 0; - } - - mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_)); - if (!msg.get()) { - ssl.SetError(factory_error); - return 0; - } - buffer >> *msg; - msg->Process(buffer, ssl); - if (ssl.GetError()) - return 0; - } - offset += hdr.length_ + RECORD_HEADER; - } - return 0; -} - - -// process input requests -void processReply(SSL& ssl) -{ - if (ssl.GetError()) return; - - if (DoProcessReply(ssl)) { - // didn't complete process - if (!ssl.getSocket().IsNonBlocking()) { - // keep trying now, blocking ok - while (!ssl.GetError()) - if (DoProcessReply(ssl) == 0) break; - } - else - // user will have try again later, non blocking - ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); - } -} - - -// send client_hello, no buffering -void sendClientHello(SSL& ssl) -{ - ssl.verifyState(serverNull); - if (ssl.GetError()) return; - - ClientHello ch(ssl.getSecurity().get_connection().version_, - ssl.getSecurity().get_connection().compression_); - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - output_buffer out; - - buildClientHello(ssl, ch); - ssl.set_random(ch.get_random(), client_end); - buildHeaders(ssl, hsHeader, rlHeader, ch); - buildOutput(out, rlHeader, hsHeader, ch); - hashHandShake(ssl, out); - - ssl.Send(out.get_buffer(), out.get_size()); -} - - -// send client key exchange -void sendClientKeyExchange(SSL& ssl, BufferOutput buffer) -{ - ssl.verifyState(serverHelloDoneComplete); - if (ssl.GetError()) return; - - ClientKeyExchange ck(ssl); - ck.build(ssl); - ssl.makeMasterSecret(); - - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - buildHeaders(ssl, hsHeader, rlHeader, ck); - buildOutput(*out.get(), rlHeader, hsHeader, ck); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send server key exchange -void sendServerKeyExchange(SSL& ssl, BufferOutput buffer) -{ - if (ssl.GetError()) return; - ServerKeyExchange sk(ssl); - sk.build(ssl); - if (ssl.GetError()) return; - - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - buildHeaders(ssl, hsHeader, rlHeader, sk); - buildOutput(*out.get(), rlHeader, hsHeader, sk); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send change cipher -void sendChangeCipher(SSL& ssl, BufferOutput buffer) -{ - if (ssl.getSecurity().get_parms().entity_ == server_end) { - if (ssl.getSecurity().get_resuming()) - ssl.verifyState(clientKeyExchangeComplete); - else - ssl.verifyState(clientFinishedComplete); - } - if (ssl.GetError()) return; - - ChangeCipherSpec ccs; - RecordLayerHeader rlHeader; - buildHeader(ssl, rlHeader, ccs); - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - buildOutput(*out.get(), rlHeader, ccs); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send finished -void sendFinished(SSL& ssl, ConnectionEnd side, BufferOutput buffer) -{ - if (ssl.GetError()) return; - - Finished fin; - buildFinished(ssl, fin, side == client_end ? client : server); - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - cipherFinished(ssl, fin, *out.get()); // hashes handshake - - if (ssl.getSecurity().get_resuming()) { - if (side == server_end) - buildFinished(ssl, ssl.useHashes().use_verify(), client); // client - } - else { - if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) - GetSessions().add(ssl); // store session - if (side == client_end) - buildFinished(ssl, ssl.useHashes().use_verify(), server); // server - } - ssl.useSecurity().use_connection().CleanMaster(); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send data -int sendData(SSL& ssl, const void* buffer, int sz) -{ - int sent = 0; - - if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ)) - ssl.SetError(no_error); - - if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { - ssl.SetError(no_error); - ssl.SendWriteBuffered(); - if (!ssl.GetError()) { - // advance sent to prvevious sent + plain size just sent - sent = ssl.useBuffers().prevSent + ssl.useBuffers().plainSz; - } - } - - ssl.verfiyHandShakeComplete(); - if (ssl.GetError()) return -1; - - for (;;) { - int len = min(sz - sent, MAX_RECORD_SIZE); - output_buffer out; - input_buffer tmp; - - Data data; - - if (sent == sz) break; - - if (ssl.CompressionOn()) { - if (Compress(static_cast<const opaque*>(buffer) + sent, len, - tmp) == -1) { - ssl.SetError(compress_error); - return -1; - } - data.SetData(tmp.get_size(), tmp.get_buffer()); - } - else - data.SetData(len, static_cast<const opaque*>(buffer) + sent); - - buildMessage(ssl, out, data); - ssl.Send(out.get_buffer(), out.get_size()); - - if (ssl.GetError()) { - if (ssl.GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { - ssl.useBuffers().plainSz = len; - ssl.useBuffers().prevSent = sent; - } - return -1; - } - sent += len; - } - ssl.useLog().ShowData(sent, true); - return sent; -} - - -// send alert -int sendAlert(SSL& ssl, const Alert& alert) -{ - output_buffer out; - buildAlert(ssl, out, alert); - ssl.Send(out.get_buffer(), out.get_size()); - - return alert.get_length(); -} - - -// process input data -int receiveData(SSL& ssl, Data& data, bool peek) -{ - if (ssl.GetError() == YasslError(SSL_ERROR_WANT_READ)) - ssl.SetError(no_error); - - ssl.verfiyHandShakeComplete(); - if (ssl.GetError()) return -1; - - if (!ssl.HasData()) - processReply(ssl); - - if (peek) - ssl.PeekData(data); - else - ssl.fillData(data); - - ssl.useLog().ShowData(data.get_length()); - if (ssl.GetError()) return -1; - - if (data.get_length() == 0 && ssl.getSocket().WouldBlock()) { - ssl.SetError(YasslError(SSL_ERROR_WANT_READ)); - return SSL_WOULD_BLOCK; - } - return data.get_length(); -} - - -// send server hello -void sendServerHello(SSL& ssl, BufferOutput buffer) -{ - if (ssl.getSecurity().get_resuming()) - ssl.verifyState(clientKeyExchangeComplete); - else - ssl.verifyState(clientHelloComplete); - if (ssl.GetError()) return; - - ServerHello sh(ssl.getSecurity().get_connection().version_, - ssl.getSecurity().get_connection().compression_); - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - - buildServerHello(ssl, sh); - ssl.set_random(sh.get_random(), server_end); - buildHeaders(ssl, hsHeader, rlHeader, sh); - buildOutput(*out.get(), rlHeader, hsHeader, sh); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send server hello done -void sendServerHelloDone(SSL& ssl, BufferOutput buffer) -{ - if (ssl.GetError()) return; - - ServerHelloDone shd; - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - - buildHeaders(ssl, hsHeader, rlHeader, shd); - buildOutput(*out.get(), rlHeader, hsHeader, shd); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send certificate -void sendCertificate(SSL& ssl, BufferOutput buffer) -{ - if (ssl.GetError()) return; - - Certificate cert(ssl.getCrypto().get_certManager().get_cert()); - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - - buildHeaders(ssl, hsHeader, rlHeader, cert); - buildOutput(*out.get(), rlHeader, hsHeader, cert); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send certificate request -void sendCertificateRequest(SSL& ssl, BufferOutput buffer) -{ - if (ssl.GetError()) return; - - CertificateRequest request; - request.Build(); - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - - buildHeaders(ssl, hsHeader, rlHeader, request); - buildOutput(*out.get(), rlHeader, hsHeader, request); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -// send certificate verify -void sendCertificateVerify(SSL& ssl, BufferOutput buffer) -{ - if (ssl.GetError()) return; - - if(ssl.getCrypto().get_certManager().sendBlankCert()) return; - - CertificateVerify verify; - verify.Build(ssl); - if (ssl.GetError()) return; - - RecordLayerHeader rlHeader; - HandShakeHeader hsHeader; - mySTL::auto_ptr<output_buffer> out(NEW_YS output_buffer); - - buildHeaders(ssl, hsHeader, rlHeader, verify); - buildOutput(*out.get(), rlHeader, hsHeader, verify); - hashHandShake(ssl, *out.get()); - - if (buffer == buffered) - ssl.addBuffer(out.release()); - else - ssl.Send(out->get_buffer(), out->get_size()); -} - - -} // namespace diff --git a/extra/yassl/src/lock.cpp b/extra/yassl/src/lock.cpp deleted file mode 100644 index 44cbcc1151f..00000000000 --- a/extra/yassl/src/lock.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - -/* Locking functions - */ - -#include "runtime.hpp" -#include "lock.hpp" - - -namespace yaSSL { - - -#ifdef MULTI_THREADED - #ifdef _WIN32 - - Mutex::Mutex() - { - InitializeCriticalSection(&cs_); - } - - - Mutex::~Mutex() - { - DeleteCriticalSection(&cs_); - } - - - Mutex::Lock::Lock(Mutex& lm) : mutex_(lm) - { - EnterCriticalSection(&mutex_.cs_); - } - - - Mutex::Lock::~Lock() - { - LeaveCriticalSection(&mutex_.cs_); - } - - #else // _WIN32 - - Mutex::Mutex() - { - pthread_mutex_init(&mutex_, 0); - } - - - Mutex::~Mutex() - { - pthread_mutex_destroy(&mutex_); - } - - - Mutex::Lock::Lock(Mutex& lm) : mutex_(lm) - { - pthread_mutex_lock(&mutex_.mutex_); - } - - - Mutex::Lock::~Lock() - { - pthread_mutex_unlock(&mutex_.mutex_); - } - - - #endif // _WIN32 -#endif // MULTI_THREADED - - - -} // namespace yaSSL - diff --git a/extra/yassl/src/log.cpp b/extra/yassl/src/log.cpp deleted file mode 100644 index 5adbe401d7a..00000000000 --- a/extra/yassl/src/log.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - -/* Debug logging functions - */ - - -#include "runtime.hpp" -#include "log.hpp" - -#ifdef YASSL_LOG - #include <time.h> - #include <stdio.h> - #include <string.h> -#endif - - - -namespace yaSSL { - - -#ifdef YASSL_LOG - - enum { MAX_MSG = 81 }; - - Log::Log(const char* str) - { - log_ = fopen(str, "w"); - Trace("********** Logger Attached **********"); - } - - - Log::~Log() - { - Trace("********** Logger Detached **********"); - fclose(log_); - } - - - // Trace a message - void Log::Trace(const char* str) - { - if (!log_) return; - - time_t clicks = time(0); - char timeStr[32]; - - // get rid of newline - strncpy(timeStr, ctime(&clicks), sizeof(timeStr)); - unsigned int len = strlen(timeStr); - timeStr[len - 1] = 0; - - char msg[MAX_MSG]; - - strncpy(msg, timeStr, sizeof(timeStr)); - strncat(msg, ":", 1); - strncat(msg, str, MAX_MSG - sizeof(timeStr) - 2); - strncat(msg, "\n", 1); - msg[MAX_MSG - 1] = 0; - - fputs(msg, log_); - } - - - #if defined(_WIN32) || defined(__MACH__) || defined(__hpux__) - typedef int socklen_t; - #endif - - - // write tcp address - void Log::ShowTCP(socket_t fd, bool ended) - { - sockaddr_in peeraddr; - socklen_t len = sizeof(peeraddr); - if (getpeername(fd, (sockaddr*)&peeraddr, &len) != 0) - return; - - const char* p = reinterpret_cast<const char*>(&peeraddr.sin_addr); - char msg[MAX_MSG]; - char number[16]; - - if (ended) - strncpy(msg, "yaSSL conn DONE w/ peer ", 26); - else - strncpy(msg, "yaSSL conn BEGUN w/ peer ", 26); - for (int i = 0; i < 4; ++i) { - sprintf(number, "%u", static_cast<unsigned short>(p[i])); - strncat(msg, number, 8); - if (i < 3) - strncat(msg, ".", 1); - } - strncat(msg, " port ", 8); - sprintf(number, "%d", htons(peeraddr.sin_port)); - strncat(msg, number, 8); - - msg[MAX_MSG - 1] = 0; - Trace(msg); - } - - - // log processed data - void Log::ShowData(uint bytes, bool sent) - { - char msg[MAX_MSG]; - char number[16]; - - if (sent) - strncpy(msg, "Sent ", 10); - else - strncpy(msg, "Received ", 10); - sprintf(number, "%u", bytes); - strncat(msg, number, 8); - strncat(msg, " bytes of application data", 27); - - msg[MAX_MSG - 1] = 0; - Trace(msg); - } - - -#else // no YASSL_LOG - - - Log::Log(const char*) {} - Log::~Log() {} - void Log::Trace(const char*) {} - void Log::ShowTCP(socket_t, bool) {} - void Log::ShowData(uint, bool) {} - - -#endif // YASSL_LOG -} // namespace diff --git a/extra/yassl/src/make.bat b/extra/yassl/src/make.bat deleted file mode 100755 index da7cc315382..00000000000 --- a/extra/yassl/src/make.bat +++ /dev/null @@ -1,42 +0,0 @@ -REM Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. -REM -REM This program is free software; you can redistribute it and/or modify -REM it under the terms of the GNU General Public License as published by -REM the Free Software Foundation; version 2 of the License. -REM -REM This program is distributed in the hope that it will be useful, -REM but WITHOUT ANY WARRANTY; without even the implied warranty of -REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -REM GNU General Public License for more details. -REM -REM You should have received a copy of the GNU General Public License -REM along with this program; if not, write to the Free Software -REM Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -REM quick and dirty build file for testing different MSDEVs -setlocal - -set myFLAGS= /I../include /I../taocrypt/mySTL /I../taocrypt/include /W3 /c /ZI - -cl %myFLAGS% buffer.cpp -cl %myFLAGS% cert_wrapper.cpp -cl %myFLAGS% crypto_wrapper.cpp -cl %myFLAGS% handshake.cpp - -cl %myFLAGS% lock.cpp -cl %myFLAGS% log.cpp -cl %myFLAGS% socket_wrapper.cpp -cl %myFLAGS% ssl.cpp - -cl %myFLAGS% template_instnt.cpp -cl %myFLAGS% timer.cpp -cl %myFLAGS% yassl.cpp -cl %myFLAGS% yassl_error.cpp - -cl %myFLAGS% yassl_imp.cpp -cl %myFLAGS% yassl_int.cpp - -link.exe -lib /out:yassl.lib buffer.obj cert_wrapper.obj crypto_wrapper.obj handshake.obj lock.obj log.obj socket_wrapper.obj ssl.obj template_instnt.obj timer.obj yassl.obj yassl_error.obj yassl_imp.obj yassl_int.obj - - - diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp deleted file mode 100644 index a9db842d01b..00000000000 --- a/extra/yassl/src/socket_wrapper.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - Copyright (c) 2005, 2012, Oracle and/or its affiliates. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* The socket wrapper source implements a Socket class that hides the - * differences between Berkely style sockets and Windows sockets, allowing - * transparent TCP access. - */ - - -#include "runtime.hpp" -#include "socket_wrapper.hpp" - -#ifndef _WIN32 - #include <errno.h> - #include <netdb.h> - #include <unistd.h> - #include <arpa/inet.h> - #include <netinet/in.h> - #include <sys/ioctl.h> - #include <string.h> - #include <fcntl.h> -#endif // _WIN32 - -#if defined(__sun) || defined(__SCO_VERSION__) - #include <sys/filio.h> -#endif - -#ifdef _WIN32 - const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK; - const int SOCKET_EAGAIN = WSAEWOULDBLOCK; -#else - const int SOCKET_EINVAL = EINVAL; - const int SOCKET_EWOULDBLOCK = EWOULDBLOCK; - const int SOCKET_EAGAIN = EAGAIN; -#endif // _WIN32 - - -namespace { - - -extern "C" long system_recv(void *ptr, void *buf, size_t count, int flags) -{ - yaSSL::socket_t *socket = (yaSSL::socket_t *) ptr; - return ::recv(*socket, reinterpret_cast<char *>(buf), (int)count, flags); -} - - -extern "C" long system_send(void *ptr, const void *buf, size_t count, - int flags) -{ - yaSSL::socket_t *socket = (yaSSL::socket_t *) ptr; - return ::send(*socket, reinterpret_cast<const char *>(buf), (int)count, flags); -} - - -} - - -namespace yaSSL { - - -Socket::Socket(socket_t s) - : socket_(s), wouldBlock_(false), nonBlocking_(false), - ptr_(&socket_), send_func_(system_send), recv_func_(system_recv) -{} - - -void Socket::set_fd(socket_t s) -{ - socket_ = s; -} - - -socket_t Socket::get_fd() const -{ - return socket_; -} - - -Socket::~Socket() -{ - // don't close automatically now -} - - -void Socket::closeSocket() -{ - if (socket_ != INVALID_SOCKET) { -#ifdef _WIN32 - closesocket(socket_); -#else - close(socket_); -#endif - socket_ = INVALID_SOCKET; - } -} - - -uint Socket::get_ready() const -{ -#ifdef _WIN32 - unsigned long ready = 0; - ioctlsocket(socket_, FIONREAD, &ready); -#else - /* - 64-bit Solaris requires the variable passed to - FIONREAD be a 32-bit value. - */ - unsigned int ready = 0; - ioctl(socket_, FIONREAD, &ready); -#endif - - return ready; -} - -void Socket::set_transport_ptr(void *ptr) -{ - ptr_ = ptr; -} - - -void Socket::set_transport_recv_function(yaSSL_recv_func_t recv_func) -{ - recv_func_ = recv_func; -} - - -void Socket::set_transport_send_function(yaSSL_send_func_t send_func) -{ - send_func_ = send_func; -} - - -uint Socket::send(const byte* buf, unsigned int sz, unsigned int &written, - int flags) -{ - const byte* pos = buf; - const byte* end = pos + sz; - - wouldBlock_ = false; - - while (pos != end) - { - int sent = send_func_(ptr_, pos, static_cast<int>(end - pos), flags); - if (sent == -1) - { - if (get_lastError() == SOCKET_EWOULDBLOCK || - get_lastError() == SOCKET_EAGAIN) - { - wouldBlock_ = true; // would have blocked this time only - nonBlocking_ = true; // nonblocking, win32 only way to tell - return 0; - } - return static_cast<uint>(-1); - } - pos += sent; - written += sent; - } - return sz; -} - - -uint Socket::receive(byte* buf, unsigned int sz, int flags) -{ - wouldBlock_ = false; - - int recvd = recv_func_(ptr_, buf, sz, flags); - - // idea to seperate error from would block by arnetheduck@gmail.com - if (recvd == -1) { - if (get_lastError() == SOCKET_EWOULDBLOCK || - get_lastError() == SOCKET_EAGAIN) { - wouldBlock_ = true; // would have blocked this time only - nonBlocking_ = true; // socket nonblocking, win32 only way to tell - return 0; - } - } - else if (recvd == 0) - return static_cast<uint>(-1); - - return recvd; -} - - -// wait if blocking for input, return false for error -bool Socket::wait() -{ - char b; - int recvd = ::recv(socket_, &b, 1, MSG_PEEK); - - if (recvd == -1) { - if (get_lastError() == SOCKET_EWOULDBLOCK || - get_lastError() == SOCKET_EAGAIN) { - wouldBlock_ = true; // would have blocked this time only - nonBlocking_ = true; // socket nonblocking, win32 only way to tell - return 1; - } - } - else if (recvd == 0) - return 0; // Non blocking & no data - - return 1; // Data can be read - -} - - -void Socket::shutDown(int how) -{ - shutdown(socket_, how); -} - - -int Socket::get_lastError() -{ -#ifdef _WIN32 - return WSAGetLastError(); -#else - return errno; -#endif -} - - -bool Socket::WouldBlock() const -{ - return wouldBlock_; -} - - -bool Socket::IsNonBlocking() const -{ - return nonBlocking_; -} - - -void Socket::set_lastError(int errorCode) -{ -#ifdef _WIN32 - WSASetLastError(errorCode); -#else - errno = errorCode; -#endif -} - - -} // namespace diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp deleted file mode 100644 index 03f52863153..00000000000 --- a/extra/yassl/src/ssl.cpp +++ /dev/null @@ -1,1782 +0,0 @@ -/* - Copyright (c) 2005, 2014, Oracle and/or its affiliates. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - -/* SSL source implements all openssl compatibility API functions - * - * TODO: notes are mostly api additions to allow compilation with mysql - * they don't affect normal modes but should be provided for completeness - - * stunnel functions at end of file - */ - - - -/* see man pages for function descriptions */ - -#include "runtime.hpp" -#include "openssl/ssl.h" -#include "handshake.hpp" -#include "yassl_int.hpp" -#include "md5.hpp" // for TaoCrypt MD5 size assert -#include "md4.hpp" // for TaoCrypt MD4 size assert -#include "file.hpp" // for TaoCrypt Source -#include "coding.hpp" // HexDecoder -#include "helpers.hpp" // for placement new hack -#include "rsa.hpp" // for TaoCrypt RSA key decode -#include "dsa.hpp" // for TaoCrypt DSA key decode -#include <stdio.h> -#include <time.h> - -#ifdef _WIN32 - #include <windows.h> // FindFirstFile etc.. -#else - #include <sys/types.h> // file helper - #include <sys/stat.h> // stat - #include <dirent.h> // opendir -#endif - - -namespace yaSSL { - - - -int read_file(SSL_CTX* ctx, const char* file, int format, CertType type) -{ - int ret = SSL_SUCCESS; - - if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM) - return SSL_BAD_FILETYPE; - - if (file == NULL || !file[0]) - return SSL_BAD_FILE; - - FILE* input = fopen(file, "rb"); - if (!input) - return SSL_BAD_FILE; - - if (type == CA) { - // may have a bunch of CAs - x509* ptr; - while ( (ptr = PemToDer(input, Cert)) ) - ctx->AddCA(ptr); - - if (!feof(input)) { - fclose(input); - return SSL_BAD_FILE; - } - } - else { - x509*& x = (type == Cert) ? ctx->certificate_ : ctx->privateKey_; - - if (format == SSL_FILETYPE_ASN1) { - fseek(input, 0, SEEK_END); - long sz = ftell(input); - rewind(input); - x = NEW_YS x509(sz); // takes ownership - size_t bytes = fread(x->use_buffer(), sz, 1, input); - if (bytes != 1) { - fclose(input); - return SSL_BAD_FILE; - } - } - else { - EncryptedInfo info; - x = PemToDer(input, type, &info); - if (!x) { - fclose(input); - return SSL_BAD_FILE; - } - if (info.set) { - // decrypt - char password[80]; - pem_password_cb cb = ctx->GetPasswordCb(); - if (!cb) { - fclose(input); - return SSL_BAD_FILE; - } - int passwordSz = cb(password, sizeof(password), 0, - ctx->GetUserData()); - byte key[AES_256_KEY_SZ]; // max sizes - byte iv[AES_IV_SZ]; - - // use file's salt for key derivation, but not real iv - TaoCrypt::Source source(info.iv, info.ivSz); - TaoCrypt::HexDecoder dec(source); - memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv), - source.size())); - EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password, - passwordSz, 1, key, iv); - - mySTL::auto_ptr<BulkCipher> cipher; - if (strncmp(info.name, "DES-CBC", 7) == 0) - cipher.reset(NEW_YS DES); - else if (strncmp(info.name, "DES-EDE3-CBC", 13) == 0) - cipher.reset(NEW_YS DES_EDE); - else if (strncmp(info.name, "AES-128-CBC", 13) == 0) - cipher.reset(NEW_YS AES(AES_128_KEY_SZ)); - else if (strncmp(info.name, "AES-192-CBC", 13) == 0) - cipher.reset(NEW_YS AES(AES_192_KEY_SZ)); - else if (strncmp(info.name, "AES-256-CBC", 13) == 0) - cipher.reset(NEW_YS AES(AES_256_KEY_SZ)); - else { - fclose(input); - return SSL_BAD_FILE; - } - cipher->set_decryptKey(key, info.iv); - mySTL::auto_ptr<x509> newx(NEW_YS x509(x->get_length())); - cipher->decrypt(newx->use_buffer(), x->get_buffer(), - x->get_length()); - ysDelete(x); - x = newx.release(); - } - } - } - - if (type == PrivateKey && ctx->privateKey_) { - // see if key is valid early - TaoCrypt::Source rsaSource(ctx->privateKey_->get_buffer(), - ctx->privateKey_->get_length()); - TaoCrypt::RSA_PrivateKey rsaKey; - rsaKey.Initialize(rsaSource); - - if (rsaSource.GetError().What()) { - // rsa failed see if DSA works - - TaoCrypt::Source dsaSource(ctx->privateKey_->get_buffer(), - ctx->privateKey_->get_length()); - TaoCrypt::DSA_PrivateKey dsaKey; - dsaKey.Initialize(dsaSource); - - if (dsaSource.GetError().What()) { - // neither worked - ret = SSL_FAILURE; - } - } - } - - fclose(input); - return ret; -} - - -extern "C" { - - -SSL_METHOD* SSLv3_method() -{ - return SSLv3_client_method(); -} - - -SSL_METHOD* SSLv3_server_method() -{ - return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,0)); -} - - -SSL_METHOD* SSLv3_client_method() -{ - return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,0)); -} - - -SSL_METHOD* TLSv1_server_method() -{ - return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,1)); -} - - -SSL_METHOD* TLSv1_client_method() -{ - return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,1)); -} - - -SSL_METHOD* TLSv1_1_server_method() -{ - return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,2)); -} - - -SSL_METHOD* TLSv1_1_client_method() -{ - return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,2)); -} - - -SSL_METHOD* SSLv23_server_method() -{ - // compatibility only, no version 2 support, but does SSL 3 and TLS 1 - return NEW_YS SSL_METHOD(server_end, ProtocolVersion(3,2), true); -} - - -SSL_METHOD* SSLv23_client_method() -{ - // compatibility only, no version 2 support, but does SSL 3 and TLS 1 - // though it sends TLS1 hello not SSLv2 so SSLv3 only servers will decline - // TODO: maybe add support to send SSLv2 hello ??? - return NEW_YS SSL_METHOD(client_end, ProtocolVersion(3,2), true); -} - - -SSL_CTX* SSL_CTX_new(SSL_METHOD* method) -{ - return NEW_YS SSL_CTX(method); -} - - -void SSL_CTX_free(SSL_CTX* ctx) -{ - ysDelete(ctx); -} - - -SSL* SSL_new(SSL_CTX* ctx) -{ - return NEW_YS SSL(ctx); -} - - -void SSL_free(SSL* ssl) -{ - ysDelete(ssl); -} - - -int SSL_set_fd(SSL* ssl, YASSL_SOCKET_T fd) -{ - ssl->useSocket().set_fd(fd); - return SSL_SUCCESS; -} - - -YASSL_SOCKET_T SSL_get_fd(const SSL* ssl) -{ - return ssl->getSocket().get_fd(); -} - - -// if you get an error from connect see note at top of README -int SSL_connect(SSL* ssl) -{ - if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ)) - ssl->SetError(no_error); - - if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { - - ssl->SetError(no_error); - ssl->SendWriteBuffered(); - if (!ssl->GetError()) - ssl->useStates().UseConnect() = - ConnectState(ssl->getStates().GetConnect() + 1); - } - - ClientState neededState; - - switch (ssl->getStates().GetConnect()) { - - case CONNECT_BEGIN : - sendClientHello(*ssl); - if (!ssl->GetError()) - ssl->useStates().UseConnect() = CLIENT_HELLO_SENT; - /* fall through */ - - case CLIENT_HELLO_SENT : - neededState = ssl->getSecurity().get_resuming() ? - serverFinishedComplete : serverHelloDoneComplete; - while (ssl->getStates().getClient() < neededState) { - if (ssl->GetError()) break; - processReply(*ssl); - // if resumption failed, reset needed state - if (neededState == serverFinishedComplete) - if (!ssl->getSecurity().get_resuming()) - neededState = serverHelloDoneComplete; - } - if (!ssl->GetError()) - ssl->useStates().UseConnect() = FIRST_REPLY_DONE; - /* fall through */ - - case FIRST_REPLY_DONE : - if(ssl->getCrypto().get_certManager().sendVerify()) - sendCertificate(*ssl); - - if (!ssl->getSecurity().get_resuming()) - sendClientKeyExchange(*ssl); - - if(ssl->getCrypto().get_certManager().sendVerify()) - sendCertificateVerify(*ssl); - - sendChangeCipher(*ssl); - sendFinished(*ssl, client_end); - ssl->flushBuffer(); - - if (!ssl->GetError()) - ssl->useStates().UseConnect() = FINISHED_DONE; - /* fall through */ - - case FINISHED_DONE : - if (!ssl->getSecurity().get_resuming()) - while (ssl->getStates().getClient() < serverFinishedComplete) { - if (ssl->GetError()) break; - processReply(*ssl); - } - if (!ssl->GetError()) - ssl->useStates().UseConnect() = SECOND_REPLY_DONE; - /* fall through */ - - case SECOND_REPLY_DONE : - ssl->verifyState(serverFinishedComplete); - ssl->useLog().ShowTCP(ssl->getSocket().get_fd()); - - if (ssl->GetError()) { - GetErrors().Add(ssl->GetError()); - return SSL_FATAL_ERROR; - } - return SSL_SUCCESS; - - default : - return SSL_FATAL_ERROR; // unkown state - } -} - - -int SSL_write(SSL* ssl, const void* buffer, int sz) -{ - return sendData(*ssl, buffer, sz); -} - - -int SSL_read(SSL* ssl, void* buffer, int sz) -{ - Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer)); - return receiveData(*ssl, data); -} - - -int SSL_accept(SSL* ssl) -{ - if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ)) - ssl->SetError(no_error); - - if (ssl->GetError() == YasslError(SSL_ERROR_WANT_WRITE)) { - ssl->SetError(no_error); - ssl->SendWriteBuffered(); - if (!ssl->GetError()) - ssl->useStates().UseAccept() = - AcceptState(ssl->getStates().GetAccept() + 1); - } - - switch (ssl->getStates().GetAccept()) { - - case ACCEPT_BEGIN : - processReply(*ssl); - if (!ssl->GetError()) - ssl->useStates().UseAccept() = ACCEPT_FIRST_REPLY_DONE; - /* fall through */ - - case ACCEPT_FIRST_REPLY_DONE : - sendServerHello(*ssl); - - if (!ssl->getSecurity().get_resuming()) { - sendCertificate(*ssl); - - if (ssl->getSecurity().get_connection().send_server_key_) - sendServerKeyExchange(*ssl); - - if(ssl->getCrypto().get_certManager().verifyPeer()) - sendCertificateRequest(*ssl); - - sendServerHelloDone(*ssl); - ssl->flushBuffer(); - } - - if (!ssl->GetError()) - ssl->useStates().UseAccept() = SERVER_HELLO_DONE; - /* fall through */ - - case SERVER_HELLO_DONE : - if (!ssl->getSecurity().get_resuming()) { - while (ssl->getStates().getServer() < clientFinishedComplete) { - if (ssl->GetError()) break; - processReply(*ssl); - } - } - if (!ssl->GetError()) - ssl->useStates().UseAccept() = ACCEPT_SECOND_REPLY_DONE; - /* fall through */ - - case ACCEPT_SECOND_REPLY_DONE : - sendChangeCipher(*ssl); - sendFinished(*ssl, server_end); - ssl->flushBuffer(); - - if (!ssl->GetError()) - ssl->useStates().UseAccept() = ACCEPT_FINISHED_DONE; - /* fall through */ - - case ACCEPT_FINISHED_DONE : - if (ssl->getSecurity().get_resuming()) { - while (ssl->getStates().getServer() < clientFinishedComplete) { - if (ssl->GetError()) break; - processReply(*ssl); - } - } - if (!ssl->GetError()) - ssl->useStates().UseAccept() = ACCEPT_THIRD_REPLY_DONE; - /* fall through */ - - case ACCEPT_THIRD_REPLY_DONE : - ssl->useLog().ShowTCP(ssl->getSocket().get_fd()); - - if (ssl->GetError()) { - GetErrors().Add(ssl->GetError()); - return SSL_FATAL_ERROR; - } - return SSL_SUCCESS; - - default: - return SSL_FATAL_ERROR; // unknown state - } -} - - -int SSL_do_handshake(SSL* ssl) -{ - if (ssl->getSecurity().get_parms().entity_ == client_end) - return SSL_connect(ssl); - else - return SSL_accept(ssl); -} - - -int SSL_clear(SSL* ssl) -{ - GetErrors().Remove(); - - return SSL_SUCCESS; -} - - -int SSL_shutdown(SSL* ssl) -{ - if (!ssl->GetQuietShutdown()) { - Alert alert(warning, close_notify); - sendAlert(*ssl, alert); - } - ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true); - - GetErrors().Remove(); - - return SSL_SUCCESS; -} - - -void SSL_set_quiet_shutdown(SSL *ssl,int mode) -{ - ssl->SetQuietShutdown(mode != 0); -} - - -int SSL_get_quiet_shutdown(SSL *ssl) -{ - return ssl->GetQuietShutdown(); -} - - -/* on by default but allow user to turn off */ -long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode) -{ - if (mode == SSL_SESS_CACHE_OFF) - ctx->SetSessionCacheOff(); - - if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR) - ctx->SetSessionCacheFlushOff(); - - return SSL_SUCCESS; -} - - -SSL_SESSION* SSL_get_session(SSL* ssl) -{ - if (ssl->getSecurity().GetContext()->GetSessionCacheOff()) - return 0; - - return GetSessions().lookup( - ssl->getSecurity().get_connection().sessionID_); -} - - -int SSL_set_session(SSL* ssl, SSL_SESSION* session) -{ - if (ssl->getSecurity().GetContext()->GetSessionCacheOff()) - return SSL_FAILURE; - - ssl->set_session(session); - return SSL_SUCCESS; -} - - -int SSL_session_reused(SSL* ssl) -{ - return ssl->getSecurity().get_resuming(); -} - - -long SSL_SESSION_set_timeout(SSL_SESSION* sess, long t) -{ - if (!sess) - return SSL_ERROR_NONE; - - sess->SetTimeOut(t); - return SSL_SUCCESS; -} - - -long SSL_get_default_timeout(SSL* /*ssl*/) -{ - return DEFAULT_TIMEOUT; -} - - -void SSL_flush_sessions(SSL_CTX *ctx, long /* tm */) -{ - if (ctx->GetSessionCacheOff()) - return; - - GetSessions().Flush(); -} - - -const char* SSL_get_cipher_name(SSL* ssl) -{ - return SSL_get_cipher(ssl); -} - - -const char* SSL_get_cipher(SSL* ssl) -{ - return ssl->getSecurity().get_parms().cipher_name_; -} - - -// SSLv2 only, not implemented -char* SSL_get_shared_ciphers(SSL* /*ssl*/, char* buf, int len) -{ - return strncpy(buf, "Not Implemented, SSLv2 only", len); -} - - -const char* SSL_get_cipher_list(SSL* ssl, int priority) -{ - if (priority < 0 || priority >= MAX_CIPHERS) - return 0; - - if (ssl->getSecurity().get_parms().cipher_list_[priority][0]) - return ssl->getSecurity().get_parms().cipher_list_[priority]; - - return 0; -} - - -int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list) -{ - if (ctx->SetCipherList(list)) - return SSL_SUCCESS; - else - return SSL_FAILURE; -} - - -const char* SSL_get_version(SSL* ssl) -{ - static const char* version3 = "SSLv3"; - static const char* version31 = "TLSv1"; - - return ssl->isTLS() ? version31 : version3; -} - -const char* SSLeay_version(int) -{ - static const char* version = "SSLeay yaSSL compatibility"; - return version; -} - - -int SSL_get_error(SSL* ssl, int /*previous*/) -{ - return ssl->getStates().What(); -} - - - -/* turn on yaSSL zlib compression - returns 0 for success, else error (not built in) - only need to turn on for client, becuase server on by default if built in - but calling for server will tell you whether it's available or not -*/ -int SSL_set_compression(SSL* ssl) /* Chad didn't rename to ya~ because it is prob. bug. */ -{ - return ssl->SetCompression(); -} - - - -X509* SSL_get_peer_certificate(SSL* ssl) -{ - return ssl->getCrypto().get_certManager().get_peerX509(); -} - - -void X509_free(X509* /*x*/) -{ - // peer cert set for deletion during destruction - // no need to delete now -} - - -X509* X509_STORE_CTX_get_current_cert(X509_STORE_CTX* ctx) -{ - return ctx->current_cert; -} - - -int X509_STORE_CTX_get_error(X509_STORE_CTX* ctx) -{ - return ctx->error; -} - - -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX* ctx) -{ - return ctx->error_depth; -} - - -// copy name into buffer, at most sz bytes, if buffer is null -// will malloc buffer, caller responsible for freeing -char* X509_NAME_oneline(X509_NAME* name, char* buffer, int sz) -{ - if (!name->GetName()) return buffer; - - int len = (int)strlen(name->GetName()) + 1; - int copySz = min(len, sz); - - if (!buffer) { - buffer = (char*)malloc(len); - if (!buffer) return buffer; - copySz = len; - } - - if (copySz == 0) - return buffer; - - memcpy(buffer, name->GetName(), copySz - 1); - buffer[copySz - 1] = 0; - - return buffer; -} - - -X509_NAME* X509_get_issuer_name(X509* x) -{ - return x->GetIssuer(); -} - - -X509_NAME* X509_get_subject_name(X509* x) -{ - return x->GetSubject(); -} - - -void SSL_load_error_strings() // compatibility only -{} - - -void SSL_set_connect_state(SSL*) -{ - // already a client by default -} - - -void SSL_set_accept_state(SSL* ssl) -{ - ssl->useSecurity().use_parms().entity_ = server_end; -} - - -long SSL_get_verify_result(SSL*) -{ - // won't get here if not OK - return X509_V_OK; -} - - -long SSL_CTX_sess_set_cache_size(SSL_CTX* /*ctx*/, long /*sz*/) -{ - // unlimited size, can't set for now - return 0; -} - - -long SSL_CTX_get_session_cache_mode(SSL_CTX*) -{ - // always 0, unlimited size for now - return 0; -} - - -long SSL_CTX_set_tmp_dh(SSL_CTX* ctx, DH* dh) -{ - if (ctx->SetDH(*dh)) - return SSL_SUCCESS; - else - return SSL_FAILURE; -} - - -int SSL_CTX_use_certificate_file(SSL_CTX* ctx, const char* file, int format) -{ - return read_file(ctx, file, format, Cert); -} - - -int SSL_CTX_use_PrivateKey_file(SSL_CTX* ctx, const char* file, int format) -{ - return read_file(ctx, file, format, PrivateKey); -} - - -void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc) -{ - if (mode & SSL_VERIFY_PEER) - ctx->setVerifyPeer(); - - if (mode == SSL_VERIFY_NONE) - ctx->setVerifyNone(); - - if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) - ctx->setFailNoCert(); - - ctx->setVerifyCallback(vc); -} - - -int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file, - const char* path) -{ - int ret = SSL_FAILURE; - - if (file) ret = read_file(ctx, file, SSL_FILETYPE_PEM, CA); - - if (ret == SSL_SUCCESS && path) { - // call read_file for each reqular file in path -#ifdef _WIN32 - - WIN32_FIND_DATA FindFileData; - HANDLE hFind; - - const int DELIMITER_SZ = 2; - const int DELIMITER_STAR_SZ = 3; - int pathSz = (int)strlen(path); - int nameSz = pathSz + DELIMITER_STAR_SZ + 1; // plus 1 for terminator - char* name = NEW_YS char[nameSz]; // directory specification - memset(name, 0, nameSz); - strncpy(name, path, nameSz - DELIMITER_STAR_SZ - 1); - strncat(name, "\\*", DELIMITER_STAR_SZ); - - hFind = FindFirstFile(name, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) { - ysArrayDelete(name); - return SSL_BAD_PATH; - } - - do { - if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - int curSz = (int)strlen(FindFileData.cFileName); - if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) { - ysArrayDelete(name); - // plus 1 for terminator - nameSz = pathSz + curSz + DELIMITER_SZ + 1; - name = NEW_YS char[nameSz]; - } - memset(name, 0, nameSz); - strncpy(name, path, nameSz - curSz - DELIMITER_SZ - 1); - strncat(name, "\\", DELIMITER_SZ); - strncat(name, FindFileData.cFileName, - nameSz - pathSz - DELIMITER_SZ - 1); - ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA); - } - } while (ret == SSL_SUCCESS && FindNextFile(hFind, &FindFileData)); - - ysArrayDelete(name); - FindClose(hFind); - -#else // _WIN32 - DIR* dir = opendir(path); - if (!dir) return SSL_BAD_PATH; - - struct dirent* entry; - struct stat buf; - const int DELIMITER_SZ = 1; - int pathSz = (int)strlen(path); - int nameSz = pathSz + DELIMITER_SZ + 1; //plus 1 for null terminator - char* name = NEW_YS char[nameSz]; // directory specification - - while (ret == SSL_SUCCESS && (entry = readdir(dir))) { - int curSz = (int)strlen(entry->d_name); - if (pathSz + curSz + DELIMITER_SZ + 1 > nameSz) { - ysArrayDelete(name); - nameSz = pathSz + DELIMITER_SZ + curSz + 1; - name = NEW_YS char[nameSz]; - } - memset(name, 0, nameSz); - strncpy(name, path, nameSz - curSz - 1); - strncat(name, "/", DELIMITER_SZ); - strncat(name, entry->d_name, nameSz - pathSz - DELIMITER_SZ - 1); - - if (stat(name, &buf) < 0) { - ysArrayDelete(name); - closedir(dir); - return SSL_BAD_STAT; - } - - if (S_ISREG(buf.st_mode)) - ret = read_file(ctx, name, SSL_FILETYPE_PEM, CA); - } - - ysArrayDelete(name); - closedir(dir); - -#endif - } - - return ret; -} - - -int SSL_CTX_set_default_verify_paths(SSL_CTX* /*ctx*/) -{ - // TODO: figure out way to set/store default path, then call load_verify - return SSL_NOT_IMPLEMENTED; -} - - -int SSL_CTX_set_session_id_context(SSL_CTX*, const unsigned char*, - unsigned int) -{ - // No application specific context needed for yaSSL - return SSL_SUCCESS; -} - - -int SSL_CTX_check_private_key(SSL_CTX* /*ctx*/) -{ - // TODO: check private against public for RSA match - return SSL_NOT_IMPLEMENTED; -} - - -// TODO: all session stats -long SSL_CTX_sess_accept(SSL_CTX* ctx) -{ - return ctx->GetStats().accept_; -} - - -long SSL_CTX_sess_connect(SSL_CTX* ctx) -{ - return ctx->GetStats().connect_; -} - - -long SSL_CTX_sess_accept_good(SSL_CTX* ctx) -{ - return ctx->GetStats().acceptGood_; -} - - -long SSL_CTX_sess_connect_good(SSL_CTX* ctx) -{ - return ctx->GetStats().connectGood_; -} - - -long SSL_CTX_sess_accept_renegotiate(SSL_CTX* ctx) -{ - return ctx->GetStats().acceptRenegotiate_; -} - - -long SSL_CTX_sess_connect_renegotiate(SSL_CTX* ctx) -{ - return ctx->GetStats().connectRenegotiate_; -} - - -long SSL_CTX_sess_hits(SSL_CTX* ctx) -{ - return ctx->GetStats().hits_; -} - - -long SSL_CTX_sess_cb_hits(SSL_CTX* ctx) -{ - return ctx->GetStats().cbHits_; -} - - -long SSL_CTX_sess_cache_full(SSL_CTX* ctx) -{ - return ctx->GetStats().cacheFull_; -} - - -long SSL_CTX_sess_misses(SSL_CTX* ctx) -{ - return ctx->GetStats().misses_; -} - - -long SSL_CTX_sess_timeouts(SSL_CTX* ctx) -{ - return ctx->GetStats().timeouts_; -} - - -long SSL_CTX_sess_number(SSL_CTX* ctx) -{ - return ctx->GetStats().number_; -} - - -long SSL_CTX_sess_get_cache_size(SSL_CTX* ctx) -{ - return ctx->GetStats().getCacheSize_; -} -// end session stats TODO: - - -int SSL_CTX_get_verify_mode(SSL_CTX* ctx) -{ - return ctx->GetStats().verifyMode_; -} - - -int SSL_get_verify_mode(SSL* ssl) -{ - return ssl->getSecurity().GetContext()->GetStats().verifyMode_; -} - - -int SSL_CTX_get_verify_depth(SSL_CTX* ctx) -{ - return ctx->GetStats().verifyDepth_; -} - - -int SSL_get_verify_depth(SSL* ssl) -{ - return ssl->getSecurity().GetContext()->GetStats().verifyDepth_; -} - - -long SSL_CTX_set_options(SSL_CTX*, long) -{ - // TDOD: - return SSL_SUCCESS; -} - - -void SSL_CTX_set_info_callback(SSL_CTX*, void (*)()) -{ - // TDOD: -} - - -void OpenSSL_add_all_algorithms() // compatibility only -{} - - -int SSL_library_init() // compatibility only -{ - return 1; -} - - -DH* DH_new(void) -{ - DH* dh = NEW_YS DH; - if (dh) - dh->p = dh->g = 0; - return dh; -} - - -void DH_free(DH* dh) -{ - ysDelete(dh->g); - ysDelete(dh->p); - ysDelete(dh); -} - - -// convert positive big-endian num of length sz into retVal, which may need to -// be created -BIGNUM* BN_bin2bn(const unsigned char* num, int sz, BIGNUM* retVal) -{ - bool created = false; - mySTL::auto_ptr<BIGNUM> bn; - - if (!retVal) { - created = true; - bn.reset(NEW_YS BIGNUM); - retVal = bn.get(); - } - - retVal->assign(num, sz); - - if (created) - return bn.release(); - else - return retVal; -} - - -unsigned long ERR_get_error_line_data(const char**, int*, const char**, int *) -{ - //return SSL_NOT_IMPLEMENTED; - return 0; -} - - -void ERR_print_errors_fp(FILE* /*fp*/) -{ - // need ssl access to implement TODO: - //fprintf(fp, "%s", ssl.get_states().errorString_.c_str()); -} - - -char* ERR_error_string(unsigned long errNumber, char* buffer) -{ - static char* msg = (char*)"Please supply a buffer for error string"; - - if (buffer) { - SetErrorString(YasslError(errNumber), buffer); - return buffer; - } - - return msg; -} - - -const char* X509_verify_cert_error_string(long /* error */) -{ - // TODO: - static const char* msg = "Not Implemented"; - return msg; -} - - -const EVP_MD* EVP_md5(void) -{ - static const char* type = "MD5"; - return type; -} - - -const EVP_CIPHER* EVP_des_ede3_cbc(void) -{ - static const char* type = "DES-EDE3-CBC"; - return type; -} - - -int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md, const byte* salt, - const byte* data, int sz, int count, byte* key, byte* iv) -{ - // only support MD5 for now - if (strncmp(md, "MD5", 3)) return 0; - - int keyLen = 0; - int ivLen = 0; - - // only support CBC DES and AES for now - if (strncmp(type, "DES-CBC", 7) == 0) { - keyLen = DES_KEY_SZ; - ivLen = DES_IV_SZ; - } - else if (strncmp(type, "DES-EDE3-CBC", 12) == 0) { - keyLen = DES_EDE_KEY_SZ; - ivLen = DES_IV_SZ; - } - else if (strncmp(type, "AES-128-CBC", 11) == 0) { - keyLen = AES_128_KEY_SZ; - ivLen = AES_IV_SZ; - } - else if (strncmp(type, "AES-192-CBC", 11) == 0) { - keyLen = AES_192_KEY_SZ; - ivLen = AES_IV_SZ; - } - else if (strncmp(type, "AES-256-CBC", 11) == 0) { - keyLen = AES_256_KEY_SZ; - ivLen = AES_IV_SZ; - } - else - return 0; - - yaSSL::MD5 myMD; - uint digestSz = myMD.get_digestSize(); - byte digest[SHA_LEN]; // max size - - int keyLeft = keyLen; - int ivLeft = ivLen; - int keyOutput = 0; - - while (keyOutput < (keyLen + ivLen)) { - int digestLeft = digestSz; - // D_(i - 1) - if (keyOutput) // first time D_0 is empty - myMD.update(digest, digestSz); - // data - myMD.update(data, sz); - // salt - if (salt) - myMD.update(salt, EVP_SALT_SZ); - myMD.get_digest(digest); - // count - for (int j = 1; j < count; j++) { - myMD.update(digest, digestSz); - myMD.get_digest(digest); - } - - if (keyLeft) { - int store = min(keyLeft, static_cast<int>(digestSz)); - memcpy(&key[keyLen - keyLeft], digest, store); - - keyOutput += store; - keyLeft -= store; - digestLeft -= store; - } - - if (ivLeft && digestLeft) { - int store = min(ivLeft, digestLeft); - memcpy(&iv[ivLen - ivLeft], &digest[digestSz - digestLeft], store); - - keyOutput += store; - ivLeft -= store; - } - } - return keyOutput; -} - - - -void DES_set_key_unchecked(const_DES_cblock* key, DES_key_schedule* schedule) -{ - memcpy(schedule, key, sizeof(const_DES_cblock)); -} - - -void DES_ede3_cbc_encrypt(const byte* input, byte* output, long sz, - DES_key_schedule* ks1, DES_key_schedule* ks2, - DES_key_schedule* ks3, DES_cblock* ivec, int enc) -{ - DES_EDE des; - byte key[DES_EDE_KEY_SZ]; - - memcpy(key, *ks1, DES_BLOCK); - memcpy(&key[DES_BLOCK], *ks2, DES_BLOCK); - memcpy(&key[DES_BLOCK * 2], *ks3, DES_BLOCK); - - if (enc) { - des.set_encryptKey(key, *ivec); - des.encrypt(output, input, sz); - } - else { - des.set_decryptKey(key, *ivec); - des.decrypt(output, input, sz); - } -} - - -// functions for libcurl -int RAND_status() -{ - return 1; /* TaoCrypt provides enough seed */ -} - - -int DES_set_key(const_DES_cblock* key, DES_key_schedule* schedule) -{ - memcpy(schedule, key, sizeof(const_DES_cblock)); - return 1; -} - - -void DES_set_odd_parity(DES_cblock* key) -{ - // not needed now for TaoCrypt -} - - -void DES_ecb_encrypt(DES_cblock* input, DES_cblock* output, - DES_key_schedule* key, int enc) -{ - DES des; - - if (enc) { - des.set_encryptKey(*key, 0); - des.encrypt(*output, *input, DES_BLOCK); - } - else { - des.set_decryptKey(*key, 0); - des.decrypt(*output, *input, DES_BLOCK); - } -} - - -void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX* ctx, void* userdata) -{ - ctx->SetUserData(userdata); -} - - -X509* SSL_get_certificate(SSL* ssl) -{ - return ssl->getCrypto().get_certManager().get_selfX509(); -} - - -EVP_PKEY* SSL_get_privatekey(SSL* ssl) -{ - // only called, not used - return 0; -} - - -void SSL_SESSION_free(SSL_SESSION* session) -{ - // managed by singleton -} - - - -EVP_PKEY* X509_get_pubkey(X509* x) -{ - // called, not used though - return 0; -} - - -int EVP_PKEY_copy_parameters(EVP_PKEY* to, const EVP_PKEY* from) -{ - // called, not used though - return 0; -} - - -void EVP_PKEY_free(EVP_PKEY* pkey) -{ - // never allocated from above -} - - -void ERR_error_string_n(unsigned long e, char *buf, size_t len) -{ - if (len) ERR_error_string(e, buf); -} - - -void ERR_free_strings(void) -{ - // handled internally -} - - -void EVP_cleanup(void) -{ - // nothing to do yet -} - - -ASN1_TIME* X509_get_notBefore(X509* x) -{ - if (x) return x->GetBefore(); - return 0; -} - - -ASN1_TIME* X509_get_notAfter(X509* x) -{ - if (x) return x->GetAfter(); - return 0; -} - - -SSL_METHOD* SSLv2_client_method(void) /* will never work, no v 2 */ -{ - return 0; -} - - -SSL_SESSION* SSL_get1_session(SSL* ssl) /* what's ref count */ -{ - return SSL_get_session(ssl); -} - - -void GENERAL_NAMES_free(STACK_OF(GENERAL_NAME) *x) -{ - // no extension names supported yet -} - - -int sk_GENERAL_NAME_num(STACK_OF(GENERAL_NAME) *x) -{ - // no extension names supported yet - return 0; -} - - -GENERAL_NAME* sk_GENERAL_NAME_value(STACK_OF(GENERAL_NAME) *x, int i) -{ - // no extension names supported yet - return 0; -} - - -unsigned char* ASN1_STRING_data(ASN1_STRING* x) -{ - if (x) return x->data; - return 0; -} - - -int ASN1_STRING_length(ASN1_STRING* x) -{ - if (x) return x->length; - return 0; -} - - -int ASN1_STRING_type(ASN1_STRING *x) -{ - if (x) return x->type; - return 0; -} - - -int X509_NAME_get_index_by_NID(X509_NAME* name,int nid, int lastpos) -{ - int idx = -1; // not found - int cnPos = -1; - - switch (nid) { - case NID_commonName: - cnPos = name->GetCnPosition(); - if (lastpos < cnPos) - idx = cnPos; - break; - } - - return idx; -} - - -ASN1_STRING* X509_NAME_ENTRY_get_data(X509_NAME_ENTRY* ne) -{ - // the same in yaSSL - return ne; -} - - -X509_NAME_ENTRY* X509_NAME_get_entry(X509_NAME* name, int loc) -{ - return name->GetEntry(loc); -} - - -// already formatted, caller responsible for freeing *out -int ASN1_STRING_to_UTF8(unsigned char** out, ASN1_STRING* in) -{ - if (!in) return 0; - - *out = (unsigned char*)malloc(in->length + 1); - if (*out) { - memcpy(*out, in->data, in->length); - (*out)[in->length] = 0; - } - return in->length; -} - - -void* X509_get_ext_d2i(X509* x, int nid, int* crit, int* idx) -{ - // no extensions supported yet - return 0; -} - - -void MD4_Init(MD4_CTX* md4) -{ - // make sure we have a big enough buffer - typedef char ok[sizeof(md4->buffer) >= sizeof(TaoCrypt::MD4) ? 1 : -1]; - (void) sizeof(ok); - - // using TaoCrypt since no dynamic memory allocated - // and no destructor will be called - new (reinterpret_cast<yassl_pointer>(md4->buffer)) TaoCrypt::MD4(); -} - - -void MD4_Update(MD4_CTX* md4, const void* data, unsigned long sz) -{ - reinterpret_cast<TaoCrypt::MD4*>(md4->buffer)->Update( - static_cast<const byte*>(data), static_cast<unsigned int>(sz)); -} - - -void MD4_Final(unsigned char* hash, MD4_CTX* md4) -{ - reinterpret_cast<TaoCrypt::MD4*>(md4->buffer)->Final(hash); -} - - -void MD5_Init(MD5_CTX* md5) -{ - // make sure we have a big enough buffer - typedef char ok[sizeof(md5->buffer) >= sizeof(TaoCrypt::MD5) ? 1 : -1]; - (void) sizeof(ok); - - // using TaoCrypt since no dynamic memory allocated - // and no destructor will be called - new (reinterpret_cast<yassl_pointer>(md5->buffer)) TaoCrypt::MD5(); -} - - -void MD5_Update(MD5_CTX* md5, const void* data, unsigned long sz) -{ - reinterpret_cast<TaoCrypt::MD5*>(md5->buffer)->Update( - static_cast<const byte*>(data), static_cast<unsigned int>(sz)); -} - - -void MD5_Final(unsigned char* hash, MD5_CTX* md5) -{ - reinterpret_cast<TaoCrypt::MD5*>(md5->buffer)->Final(hash); -} - - -int RAND_bytes(unsigned char* buf, int num) -{ - RandomPool ran; - - if (ran.GetError()) return 0; - - ran.Fill(buf, num); - return 1; -} - - -int SSL_peek(SSL* ssl, void* buffer, int sz) -{ - Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer)); - return receiveData(*ssl, data, true); -} - - -int SSL_pending(SSL* ssl) -{ - return ssl->bufferedData(); -} - - -void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb) -{ - ctx->SetPasswordCb(cb); -} - - -int SSLeay_add_ssl_algorithms() // compatibility only -{ - return 1; -} - - -void ERR_remove_state(unsigned long) -{ - if (HasErrors()) - GetErrors().Remove(); -} - - -int ERR_GET_REASON(int l) -{ - return l & 0xfff; -} - - -unsigned long err_helper(bool peek = false) -{ - int ysError = GetErrors().Lookup(peek); - - // translate cert error for libcurl, it uses OpenSSL hex code - switch (ysError) { - case TaoCrypt::SIG_OTHER_E: - return CERTFICATE_ERROR; - break; - default : - return 0; - } - - return 0; // shut up compiler -} - - -unsigned long ERR_peek_error() -{ - return err_helper(true); -} - - -unsigned long ERR_get_error() -{ - return err_helper(); -} - - - // functions for stunnel - - void RAND_screen() - { - // TODO: - } - - - const char* RAND_file_name(char*, size_t) - { - // TODO: - return 0; - } - - - int RAND_write_file(const char*) - { - // TODO: - return 0; - } - - - int RAND_load_file(const char*, long) - { - // TODO: - return 0; - } - - - void RSA_free(RSA*) - { - // TODO: - } - - - RSA* RSA_generate_key(int, unsigned long, void(*)(int, int, void*), void*) - { - // TODO: - return 0; - } - - - int X509_LOOKUP_add_dir(X509_LOOKUP*, const char*, long) - { - // TODO: - return SSL_SUCCESS; - } - - - int X509_LOOKUP_load_file(X509_LOOKUP*, const char*, long) - { - // TODO: - return SSL_SUCCESS; - } - - - X509_LOOKUP_METHOD* X509_LOOKUP_hash_dir(void) - { - // TODO: - return 0; - } - - - X509_LOOKUP_METHOD* X509_LOOKUP_file(void) - { - // TODO: - return 0; - } - - - X509_LOOKUP* X509_STORE_add_lookup(X509_STORE*, X509_LOOKUP_METHOD*) - { - // TODO: - return 0; - } - - - int X509_STORE_get_by_subject(X509_STORE_CTX*, int, X509_NAME*, X509_OBJECT*) - { - // TODO: - return SSL_SUCCESS; - } - - - X509_STORE* X509_STORE_new(void) - { - // TODO: - return 0; - } - - char* SSL_alert_type_string_long(int) - { - // TODO: - return 0; - } - - - char* SSL_alert_desc_string_long(int) - { - // TODO: - return 0; - } - - - char* SSL_state_string_long(SSL*) - { - // TODO: - return 0; - } - - - void SSL_CTX_set_tmp_rsa_callback(SSL_CTX*, RSA*(*)(SSL*, int, int)) - { - // TDOD: - } - - - long SSL_CTX_set_timeout(SSL_CTX*, long) - { - // TDOD: - return SSL_SUCCESS; - } - - - int SSL_CTX_use_certificate_chain_file(SSL_CTX* ctx, const char* file) - { - // For the moment, treat like use_certificate_file - return read_file(ctx, file, SSL_FILETYPE_PEM, Cert); - } - - - int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX*, const char*, int) - { - // TDOD: - return SSL_SUCCESS; - } - - - int SSL_set_rfd(SSL*, int) - { - return SSL_SUCCESS; // TODO: - } - - - int SSL_set_wfd(SSL*, int) - { - return SSL_SUCCESS; // TODO: - } - - - int SSL_want_read(SSL*) - { - return 0; // TODO: - } - - - int SSL_want_write(SSL*) - { - return 0; // TODO: - } - - - void SSL_set_shutdown(SSL*, int) - { - // TODO: - } - - SSL_CIPHER* SSL_get_current_cipher(SSL*) - { - // TODO: - return 0; - } - - - char* SSL_CIPHER_description(SSL_CIPHER*, char*, int) - { - // TODO: - return 0; - } - - // end stunnel needs - - char *yaSSL_ASN1_TIME_to_string(const ASN1_TIME *time, char *buf, size_t len) - { - tm t; - static const char *month_names[12]= - { - "Jan","Feb","Mar","Apr","May","Jun", - "Jul","Aug","Sep","Oct","Nov","Dec" - }; - - TaoCrypt::ASN1_TIME_extract(time->data, time->type, &t); - snprintf(buf, len, "%s %2d %02d:%02d:%02d %d GMT", - month_names[t.tm_mon], t.tm_mday, t.tm_hour, t.tm_min, - t.tm_sec, t.tm_year + 1900); - return buf; - } - - - void yaSSL_transport_set_ptr(SSL *ssl, void *ptr) - { - ssl->useSocket().set_transport_ptr(ptr); - } - - - void yaSSL_transport_set_recv_function(SSL *ssl, yaSSL_recv_func_t func) - { - ssl->useSocket().set_transport_recv_function(func); - } - - - void yaSSL_transport_set_send_function(SSL *ssl, yaSSL_send_func_t func) - { - ssl->useSocket().set_transport_send_function(func); - } - -} // extern "C" -} // namespace diff --git a/extra/yassl/src/timer.cpp b/extra/yassl/src/timer.cpp deleted file mode 100644 index dadb3ebf378..00000000000 --- a/extra/yassl/src/timer.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 2000-2007 MySQL AB - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - -/* timer.cpp implements a high res and low res timer - * -*/ - -#include "runtime.hpp" -#include "timer.hpp" - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN 1 -#include <windows.h> -#else -#include <sys/time.h> -#endif - -namespace yaSSL { - -#ifdef _WIN32 - - timer_d timer() - { - static bool init(false); - static LARGE_INTEGER freq; - - if (!init) { - QueryPerformanceFrequency(&freq); - init = true; - } - - LARGE_INTEGER count; - QueryPerformanceCounter(&count); - - return static_cast<double>(count.QuadPart) / freq.QuadPart; - } - - - uint lowResTimer() - { - return static_cast<uint>(timer()); - } - -#else // _WIN32 - - timer_d timer() - { - struct timeval tv; - gettimeofday(&tv, 0); - - return static_cast<double>(tv.tv_sec) - + static_cast<double>(tv.tv_usec) / 1000000; - } - - - uint lowResTimer() - { - struct timeval tv; - gettimeofday(&tv, 0); - - return tv.tv_sec; - } - - -#endif // _WIN32 -} // namespace yaSSL diff --git a/extra/yassl/src/yassl.cpp b/extra/yassl/src/yassl.cpp deleted file mode 100644 index 89600359401..00000000000 --- a/extra/yassl/src/yassl.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* yaSSL implements external API - */ - -#include "runtime.hpp" -#include "yassl.hpp" -#include "yassl_int.hpp" -#include "handshake.hpp" -#include <stdio.h> - -#include "openssl/ssl.h" // get rid of this - - - -namespace yaSSL { - - - -struct Base { - SSL_METHOD* method_; - SSL_CTX* ctx_; - SSL* ssl_; - - char* ca_; - char* cert_; - char* key_; - - DH* dh_; - - Base() : method_(0), ctx_(0), ssl_(0), ca_(0), cert_(0), key_(0), dh_(0) - {} - - ~Base() - { - if (dh_) DH_free(dh_); - delete[] key_; - delete[] cert_; - delete[] ca_; - SSL_CTX_free(ctx_); // frees method_ too - SSL_free(ssl_); - } -}; - - -void SetDH(Base&); - -void SetUpBase(Base& base, ConnectionEnd end, SOCKET_T s) -{ - base.method_ = new SSL_METHOD(end, ProtocolVersion(3,1)); - base.ctx_ = new SSL_CTX(base.method_); - - if (base.ca_) - if (SSL_CTX_load_verify_locations(base.ctx_, - base.ca_, 0) != SSL_SUCCESS) throw(0); - if (base.cert_) - if (SSL_CTX_use_certificate_file(base.ctx_, - base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0); - if (base.key_) - if (SSL_CTX_use_PrivateKey_file(base.ctx_, base.key_, - SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0); - - if (end == server_end) SetDH(base); - - base.ssl_ = new SSL(base.ctx_); - base.ssl_->useSocket().set_fd(s); -} - - -void SetDH(Base& base) -{ - static unsigned char dh512_p[] = - { - 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, - 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, - 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, - 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, - 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, - 0x47,0x74,0xE8,0x33, - }; - - static unsigned char dh512_g[] = - { - 0x02, - }; - - if ( (base.dh_ = DH_new()) ) { - base.dh_->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0); - base.dh_->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0); - } - if (!base.dh_->p || !base.dh_->g) { - DH_free(base.dh_); - base.dh_ = 0; - } - SSL_CTX_set_tmp_dh(base.ctx_, base.dh_); -} - - -void NewCopy(char*& dst, const char* src) -{ - size_t len = strlen(src) + 1; - dst = new char[len]; - - strncpy(dst, src, len); -} - - -// Client Implementation -struct Client::ClientImpl { - Base base_; -}; - - -Client::Client() : pimpl_(new ClientImpl) -{} - - -Client::~Client() { delete pimpl_; } - - -int Client::Connect(SOCKET_T s) -{ - SetUpBase(pimpl_->base_, client_end, s); - return SSL_connect(pimpl_->base_.ssl_); -} - - -int Client::Write(const void* buffer, int sz) -{ - return sendData(*pimpl_->base_.ssl_, buffer, sz); -} - - -int Client::Read(void* buffer, int sz) -{ - Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer)); - return receiveData(*pimpl_->base_.ssl_, data); -} - - -void Client::SetCA(const char* name) -{ - NewCopy(pimpl_->base_.ca_, name); -} - - -void Client::SetCert(const char* name) -{ - NewCopy(pimpl_->base_.cert_, name); -} - - -void Client::SetKey(const char* name) -{ - NewCopy(pimpl_->base_.key_, name); -} - - - -// Server Implementation -struct Server::ServerImpl { - Base base_; -}; - - -Server::Server() : pimpl_(new ServerImpl) -{} - - -Server::~Server() { delete pimpl_; } - - -int Server::Accept(SOCKET_T s) -{ - SetUpBase(pimpl_->base_, server_end, s); - return SSL_accept(pimpl_->base_.ssl_); -} - - -int Server::Write(const void* buffer, int sz) -{ - return sendData(*pimpl_->base_.ssl_, buffer, sz); -} - - -int Server::Read(void* buffer, int sz) -{ - Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer)); - return receiveData(*pimpl_->base_.ssl_, data); -} - - -void Server::SetCA(const char* name) -{ - NewCopy(pimpl_->base_.ca_, name); -} - - -void Server::SetCert(const char* name) -{ - NewCopy(pimpl_->base_.cert_, name); -} - - -void Server::SetKey(const char* name) -{ - NewCopy(pimpl_->base_.key_, name); -} - - - -} // namespace yaSSL diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp deleted file mode 100644 index bb3825ca972..00000000000 --- a/extra/yassl/src/yassl_error.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - Copyright (c) 2005, 2013, Oracle and/or its affiliates - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* yaSSL error implements and an exception class - */ - -#include "runtime.hpp" -#include "yassl_error.hpp" -#include "error.hpp" // TaoCrypt error numbers -#include "openssl/ssl.h" // SSL_ERROR_WANT_READ -#include <string.h> // strncpy - -#ifdef _MSC_VER - // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy - #pragma warning(disable: 4996) -#endif - -namespace yaSSL { - - -/* may bring back in future -Error::Error(const char* s, YasslError e, Library l) - : mySTL::runtime_error(s), error_(e), lib_(l) -{ -} - - -YasslError Error::get_number() const -{ - return error_; -} - - -Library Error::get_lib() const -{ - - return lib_; -} -*/ - - -void SetErrorString(YasslError error, char* buffer) -{ - using namespace TaoCrypt; - const int max = MAX_ERROR_SZ; // shorthand - int localError = error; // errors from a few enums - - switch (localError) { - - // yaSSL proper errors - case range_error : - strncpy(buffer, "buffer index error, out of range", max); - break; - - case realloc_error : - strncpy(buffer, "trying to realloc a fixed buffer", max); - break; - - case factory_error : - strncpy(buffer, "unknown factory create request", max); - break; - - case unknown_cipher : - strncpy(buffer, "trying to use an unknown cipher", max); - break; - - case prefix_error : - strncpy(buffer, "bad master secret derivation, prefix too big", max); - break; - - case record_layer : - strncpy(buffer, "record layer not ready yet", max); - break; - - case handshake_layer : - strncpy(buffer, "handshake layer not ready yet", max); - break; - - case out_of_order : - strncpy(buffer, "handshake message received in wrong order", max); - break; - - case bad_input : - strncpy(buffer, "bad cipher suite input", max); - break; - - case match_error : - strncpy(buffer, "unable to match a supported cipher suite", max); - break; - - case no_key_file : - strncpy(buffer, "the server needs a private key file", max); - break; - - case verify_error : - strncpy(buffer, "unable to verify peer checksum", max); - break; - - case send_error : - strncpy(buffer, "socket layer send error", max); - break; - - case receive_error : - strncpy(buffer, "socket layer receive error", max); - break; - - case certificate_error : - strncpy(buffer, "unable to process cerificate", max); - break; - - case privateKey_error : - strncpy(buffer, "unable to process private key, bad format", max); - break; - - case badVersion_error : - strncpy(buffer, "protocol version mismatch", max); - break; - - case compress_error : - strncpy(buffer, "compression error", max); - break; - - case decompress_error : - strncpy(buffer, "decompression error", max); - break; - - case pms_version_error : - strncpy(buffer, "bad PreMasterSecret version error", max); - break; - - case sanityCipher_error : - strncpy(buffer, "sanity check on cipher text size error", max); - break; - - case rsaSignFault_error: - strncpy(buffer, "rsa signature fault error", max); - break; - - // openssl errors - case SSL_ERROR_WANT_READ : - strncpy(buffer, "the read operation would block", max); - break; - - case SSL_ERROR_WANT_WRITE : - strncpy(buffer, "the write operation would block", max); - break; - - case CERTFICATE_ERROR : - strncpy(buffer, "Unable to verify certificate", max); - break; - - // TaoCrypt errors - case NO_ERROR_E : - strncpy(buffer, "not in error state", max); - break; - - case WINCRYPT_E : - strncpy(buffer, "bad wincrypt acquire", max); - break; - - case CRYPTGEN_E : - strncpy(buffer, "CryptGenRandom error", max); - break; - - case OPEN_RAN_E : - strncpy(buffer, "unable to use random device", max); - break; - - case READ_RAN_E : - strncpy(buffer, "unable to use random device", max); - break; - - case INTEGER_E : - strncpy(buffer, "ASN: bad DER Integer Header", max); - break; - - case SEQUENCE_E : - strncpy(buffer, "ASN: bad Sequence Header", max); - break; - - case SET_E : - strncpy(buffer, "ASN: bad Set Header", max); - break; - - case VERSION_E : - strncpy(buffer, "ASN: version length not 1", max); - break; - - case SIG_OID_E : - strncpy(buffer, "ASN: signature OID mismatch", max); - break; - - case BIT_STR_E : - strncpy(buffer, "ASN: bad BitString Header", max); - break; - - case UNKNOWN_OID_E : - strncpy(buffer, "ASN: unknown key OID type", max); - break; - - case OBJECT_ID_E : - strncpy(buffer, "ASN: bad Ojbect ID Header", max); - break; - - case TAG_NULL_E : - strncpy(buffer, "ASN: expected TAG NULL", max); - break; - - case EXPECT_0_E : - strncpy(buffer, "ASN: expected 0", max); - break; - - case OCTET_STR_E : - strncpy(buffer, "ASN: bad Octet String Header", max); - break; - - case TIME_E : - strncpy(buffer, "ASN: bad TIME", max); - break; - - case DATE_SZ_E : - strncpy(buffer, "ASN: bad Date Size", max); - break; - - case SIG_LEN_E : - strncpy(buffer, "ASN: bad Signature Length", max); - break; - - case UNKOWN_SIG_E : - strncpy(buffer, "ASN: unknown signature OID", max); - break; - - case UNKOWN_HASH_E : - strncpy(buffer, "ASN: unknown hash OID", max); - break; - - case DSA_SZ_E : - strncpy(buffer, "ASN: bad DSA r or s size", max); - break; - - case BEFORE_DATE_E : - strncpy(buffer, "ASN: before date in the future", max); - break; - - case AFTER_DATE_E : - strncpy(buffer, "ASN: after date in the past", max); - break; - - case SIG_CONFIRM_E : - strncpy(buffer, "ASN: bad self signature confirmation", max); - break; - - case SIG_OTHER_E : - strncpy(buffer, "ASN: bad other signature confirmation", max); - break; - - case CONTENT_E : - strncpy(buffer, "bad content processing", max); - break; - - case PEM_E : - strncpy(buffer, "bad PEM format processing", max); - break; - - default : - strncpy(buffer, "unknown error number", max); - } -} - - - -} // namespace yaSSL diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp deleted file mode 100644 index a4b1b50e10f..00000000000 --- a/extra/yassl/src/yassl_imp.cpp +++ /dev/null @@ -1,2636 +0,0 @@ -/* - Copyright (c) 2005, 2017, Oracle and/or its affiliates. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - -/* yaSSL source implements all SSL.v3 secification structures. - */ - -#include "runtime.hpp" -#include "yassl_int.hpp" -#include "handshake.hpp" - -#include "asn.hpp" // provide crypto wrapper?? -#include <my_attribute.h> - - -namespace yaSSL { - - -namespace { // locals - -bool isTLS(ProtocolVersion pv) -{ - if (pv.major_ >= 3 && pv.minor_ >= 1) - return true; - - return false; -} - - -} // namespace (locals) - - -void hashHandShake(SSL&, const input_buffer&, uint); - - -ProtocolVersion::ProtocolVersion(uint8 maj, uint8 min) - : major_(maj), minor_(min) -{} - - -// construct key exchange with known ssl parms -void ClientKeyExchange::createKey(SSL& ssl) -{ - const ClientKeyFactory& ckf = ssl.getFactory().getClientKey(); - client_key_ = ckf.CreateObject(ssl.getSecurity().get_parms().kea_); - - if (!client_key_) - ssl.SetError(factory_error); -} - - -// construct key exchange with known ssl parms -void ServerKeyExchange::createKey(SSL& ssl) -{ - const ServerKeyFactory& skf = ssl.getFactory().getServerKey(); - server_key_ = skf.CreateObject(ssl.getSecurity().get_parms().kea_); - - if (!server_key_) - ssl.SetError(factory_error); -} - - -// build/set PreMaster secret and encrypt, client side -void EncryptedPreMasterSecret::build(SSL& ssl) -{ - opaque tmp[SECRET_LEN]; - memset(tmp, 0, sizeof(tmp)); - ssl.getCrypto().get_random().Fill(tmp, SECRET_LEN); - ProtocolVersion pv = ssl.getSecurity().get_connection().chVersion_; - tmp[0] = pv.major_; - tmp[1] = pv.minor_; - ssl.set_preMaster(tmp, SECRET_LEN); - - const CertManager& cert = ssl.getCrypto().get_certManager(); - RSA rsa(cert.get_peerKey(), cert.get_peerKeyLength()); - bool tls = ssl.isTLS(); // if TLS, put length for encrypted data - alloc(rsa.get_cipherLength() + (tls ? 2 : 0)); - byte* holder = secret_; - if (tls) { - byte len[2]; - c16toa(rsa.get_cipherLength(), len); - memcpy(secret_, len, sizeof(len)); - holder += 2; - } - rsa.encrypt(holder, tmp, SECRET_LEN, ssl.getCrypto().get_random()); -} - - -// build/set premaster and Client Public key, client side -void ClientDiffieHellmanPublic::build(SSL& ssl) -{ - DiffieHellman& dhServer = ssl.useCrypto().use_dh(); - DiffieHellman dhClient(dhServer); - - uint keyLength = dhClient.get_agreedKeyLength(); // pub and agree same - - alloc(keyLength, true); - dhClient.makeAgreement(dhServer.get_publicKey(), - dhServer.get_publicKeyLength()); - c16toa(keyLength, Yc_); - memcpy(Yc_ + KEY_OFFSET, dhClient.get_publicKey(), keyLength); - - ssl.set_preMaster(dhClient.get_agreedKey(), keyLength); -} - - -// build server exhange, server side -void DH_Server::build(SSL& ssl) -{ - DiffieHellman& dhServer = ssl.useCrypto().use_dh(); - - int pSz, gSz, pubSz; - dhServer.set_sizes(pSz, gSz, pubSz); - dhServer.get_parms(parms_.alloc_p(pSz), parms_.alloc_g(gSz), - parms_.alloc_pub(pubSz)); - - short sigSz = 0; - mySTL::auto_ptr<Auth> auth; - const CertManager& cert = ssl.getCrypto().get_certManager(); - - if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) { - if (cert.get_keyType() != rsa_sa_algo) { - ssl.SetError(privateKey_error); - return; - } - auth.reset(NEW_YS RSA(cert.get_privateKey(), - cert.get_privateKeyLength(), false)); - } - else { - if (cert.get_keyType() != dsa_sa_algo) { - ssl.SetError(privateKey_error); - return; - } - auth.reset(NEW_YS DSS(cert.get_privateKey(), - cert.get_privateKeyLength(), false)); - sigSz += DSS_ENCODED_EXTRA; - } - - sigSz += auth->get_signatureLength(); - if (!sigSz) { - ssl.SetError(privateKey_error); - return; - } - - length_ = 8; // pLen + gLen + YsLen + SigLen - length_ += pSz + gSz + pubSz + sigSz; - - output_buffer tmp(length_); - byte len[2]; - // P - c16toa(pSz, len); - tmp.write(len, sizeof(len)); - tmp.write(parms_.get_p(), pSz); - // G - c16toa(gSz, len); - tmp.write(len, sizeof(len)); - tmp.write(parms_.get_g(), gSz); - // Ys - c16toa(pubSz, len); - tmp.write(len, sizeof(len)); - tmp.write(parms_.get_pub(), pubSz); - - // Sig - byte hash[FINISHED_SZ]; - MD5 md5; - SHA sha; - signature_ = NEW_YS byte[sigSz]; - - const Connection& conn = ssl.getSecurity().get_connection(); - // md5 - md5.update(conn.client_random_, RAN_LEN); - md5.update(conn.server_random_, RAN_LEN); - md5.update(tmp.get_buffer(), tmp.get_size()); - md5.get_digest(hash); - - // sha - sha.update(conn.client_random_, RAN_LEN); - sha.update(conn.server_random_, RAN_LEN); - sha.update(tmp.get_buffer(), tmp.get_size()); - sha.get_digest(&hash[MD5_LEN]); - - if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) { - auth->sign(signature_, hash, sizeof(hash), - ssl.getCrypto().get_random()); - // check for rsa signautre fault - if (!auth->verify(hash, sizeof(hash), signature_, - auth->get_signatureLength())) { - ssl.SetError(rsaSignFault_error); - return; - } - } - else { - auth->sign(signature_, &hash[MD5_LEN], SHA_LEN, - ssl.getCrypto().get_random()); - byte encoded[DSS_SIG_SZ + DSS_ENCODED_EXTRA]; - TaoCrypt::EncodeDSA_Signature(signature_, encoded); - memcpy(signature_, encoded, sizeof(encoded)); - } - - c16toa(sigSz, len); - tmp.write(len, sizeof(len)); - tmp.write(signature_, sigSz); - - // key message - keyMessage_ = NEW_YS opaque[length_]; - memcpy(keyMessage_, tmp.get_buffer(), tmp.get_size()); -} - - -// read PreMaster secret and decrypt, server side -void EncryptedPreMasterSecret::read(SSL& ssl, input_buffer& input) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - const CertManager& cert = ssl.getCrypto().get_certManager(); - RSA rsa(cert.get_privateKey(), cert.get_privateKeyLength(), false); - uint16 cipherLen = rsa.get_cipherLength(); - if (ssl.isTLS()) { - byte len[2]; - len[0] = input[AUTO]; - len[1] = input[AUTO]; - ato16(len, cipherLen); - } - alloc(cipherLen); - input.read(secret_, length_); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - opaque preMasterSecret[SECRET_LEN]; - memset(preMasterSecret, 0, sizeof(preMasterSecret)); - rsa.decrypt(preMasterSecret, secret_, length_, - ssl.getCrypto().get_random()); - - ProtocolVersion pv = ssl.getSecurity().get_connection().chVersion_; - if (pv.major_ != preMasterSecret[0] || pv.minor_ != preMasterSecret[1]) - ssl.SetError(pms_version_error); // continue deriving for timing attack - - ssl.set_preMaster(preMasterSecret, SECRET_LEN); - ssl.makeMasterSecret(); -} - - -EncryptedPreMasterSecret::EncryptedPreMasterSecret() - : secret_(0), length_(0) -{} - - -EncryptedPreMasterSecret::~EncryptedPreMasterSecret() -{ - ysArrayDelete(secret_); -} - - -int EncryptedPreMasterSecret::get_length() const -{ - return length_; -} - - -opaque* EncryptedPreMasterSecret::get_clientKey() const -{ - return secret_; -} - - -void EncryptedPreMasterSecret::alloc(int sz) -{ - length_ = sz; - secret_ = NEW_YS opaque[sz]; -} - - -// read client's public key, server side -void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input) -{ - if (input.get_error() || input.get_remaining() < (uint)LENGTH_SZ) { - ssl.SetError(bad_input); - return; - } - - DiffieHellman& dh = ssl.useCrypto().use_dh(); - - uint16 keyLength; - byte tmp[2]; - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, keyLength); - - if (keyLength < dh.get_agreedKeyLength()/2) { - ssl.SetError(bad_input); - return; - } - - alloc(keyLength); - input.read(Yc_, keyLength); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - dh.makeAgreement(Yc_, keyLength); - - ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength()); - ssl.makeMasterSecret(); -} - - -ClientDiffieHellmanPublic::ClientDiffieHellmanPublic() - : length_(0), Yc_(0) -{} - - -ClientDiffieHellmanPublic::~ClientDiffieHellmanPublic() -{ - ysArrayDelete(Yc_); -} - - -int ClientDiffieHellmanPublic::get_length() const -{ - return length_; -} - - -opaque* ClientDiffieHellmanPublic::get_clientKey() const -{ - return Yc_; -} - - -void ClientDiffieHellmanPublic::alloc(int sz, bool offset) -{ - length_ = sz + (offset ? KEY_OFFSET : 0); - Yc_ = NEW_YS opaque[length_]; -} - - -// read server's p, g, public key and sig, client side -void DH_Server::read(SSL& ssl, input_buffer& input) -{ - if (input.get_error() || input.get_remaining() < (uint)LENGTH_SZ) { - ssl.SetError(bad_input); - return; - } - uint16 length, messageTotal = 6; // pSz + gSz + pubSz - byte tmp[2]; - - // p - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, length); - messageTotal += length; - - input.read(parms_.alloc_p(length), length); - if (input.get_error() || input.get_remaining() < (uint)LENGTH_SZ) { - ssl.SetError(bad_input); - return; - } - - // g - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, length); - messageTotal += length; - - input.read(parms_.alloc_g(length), length); - if (input.get_error() || input.get_remaining() < (uint)LENGTH_SZ) { - ssl.SetError(bad_input); - return; - } - - // pub - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, length); - messageTotal += length; - - input.read(parms_.alloc_pub(length), length); - if (input.get_error() || input.get_remaining() < (uint)LENGTH_SZ) { - ssl.SetError(bad_input); - return; - } - - // save message for hash verify - input_buffer message(messageTotal); - input.set_current(input.get_current() - messageTotal); - input.read(message.get_buffer(), messageTotal); - message.add_size(messageTotal); - if (input.get_error() || input.get_remaining() < (uint)LENGTH_SZ) { - ssl.SetError(bad_input); - return; - } - - // signature - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, length); - - if (length == 0) { - ssl.SetError(bad_input); - return; - } - signature_ = NEW_YS byte[length]; - input.read(signature_, length); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - // verify signature - byte hash[FINISHED_SZ]; - MD5 md5; - SHA sha; - - const Connection& conn = ssl.getSecurity().get_connection(); - // md5 - md5.update(conn.client_random_, RAN_LEN); - md5.update(conn.server_random_, RAN_LEN); - md5.update(message.get_buffer(), message.get_size()); - md5.get_digest(hash); - - // sha - sha.update(conn.client_random_, RAN_LEN); - sha.update(conn.server_random_, RAN_LEN); - sha.update(message.get_buffer(), message.get_size()); - sha.get_digest(&hash[MD5_LEN]); - - const CertManager& cert = ssl.getCrypto().get_certManager(); - - if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) { - RSA rsa(cert.get_peerKey(), cert.get_peerKeyLength()); - if (!rsa.verify(hash, sizeof(hash), signature_, length)) - ssl.SetError(verify_error); - } - else { - byte decodedSig[DSS_SIG_SZ]; - length = TaoCrypt::DecodeDSA_Signature(decodedSig, signature_, length); - - DSS dss(cert.get_peerKey(), cert.get_peerKeyLength()); - if (!dss.verify(&hash[MD5_LEN], SHA_LEN, decodedSig, length)) - ssl.SetError(verify_error); - } - - // save input - ssl.useCrypto().SetDH(NEW_YS DiffieHellman(parms_.get_p(), - parms_.get_pSize(), parms_.get_g(), parms_.get_gSize(), - parms_.get_pub(), parms_.get_pubSize(), - ssl.getCrypto().get_random())); -} - - -DH_Server::DH_Server() - : signature_(0), length_(0), keyMessage_(0) -{} - - -DH_Server::~DH_Server() -{ - ysArrayDelete(keyMessage_); - ysArrayDelete(signature_); -} - - -int DH_Server::get_length() const -{ - return length_; -} - - -opaque* DH_Server::get_serverKey() const -{ - return keyMessage_; -} - - -// set available suites -Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, - ProtocolVersion pv, bool haveDH) : entity_(ce) -{ - pending_ = true; // suite not set yet - strncpy(cipher_name_, "NONE", 5); - - removeDH_ = !haveDH; // only use on server side for set suites - - if (ciphers.setSuites_) { // use user set list - suites_size_ = ciphers.suiteSz_; - memcpy(suites_, ciphers.suites_, ciphers.suiteSz_); - SetCipherNames(); - } - else - SetSuites(pv, ce == server_end && removeDH_); // defaults - -} - - -void Parameters::SetSuites(ProtocolVersion pv, bool removeDH, bool removeRSA, - bool removeDSA) -{ - int i = 0; - // available suites, best first - // when adding more, make sure cipher_names is updated and - // MAX_CIPHERS is big enough - - if (isTLS(pv)) { - if (!removeDH) { - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; - } - if (!removeDSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; - } - } - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_256_CBC_SHA; - } - if (!removeDH) { - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA; - } - if (!removeDSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA; - } - } - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_128_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_256_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_AES_128_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_RSA_WITH_3DES_EDE_CBC_RMD160; - } - if (!removeDH) { - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160; - } - if (!removeDSA) { - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_RMD160; - suites_[i++] = 0x00; - suites_[i++] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160; - } - } - } - - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_RC4_128_SHA; - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_RC4_128_MD5; - - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA; - suites_[i++] = 0x00; - suites_[i++] = SSL_RSA_WITH_DES_CBC_SHA; - } - if (!removeDH) { - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; - } - if (!removeDSA) { - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; - } - if (!removeRSA) { - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_RSA_WITH_DES_CBC_SHA; - } - if (!removeDSA) { - suites_[i++] = 0x00; - suites_[i++] = SSL_DHE_DSS_WITH_DES_CBC_SHA; - } - } - - suites_size_ = i; - - SetCipherNames(); -} - - -void Parameters::SetCipherNames() -{ - const int suites = suites_size_ / 2; - int pos = 0; - - for (int j = 0; j < suites; j++) { - int index = suites_[j*2 + 1]; // every other suite is suite id - size_t len = strlen(cipher_names[index]) + 1; - strncpy(cipher_list_[pos++], cipher_names[index], len); - } - cipher_list_[pos][0] = 0; -} - - -// input operator for RecordLayerHeader, adjust stream -input_buffer& operator>>(input_buffer& input, RecordLayerHeader& hdr) -{ - hdr.type_ = ContentType(input[AUTO]); - hdr.version_.major_ = input[AUTO]; - hdr.version_.minor_ = input[AUTO]; - - // length - byte tmp[2]; - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, hdr.length_); - - return input; -} - - -// output operator for RecordLayerHeader -output_buffer& operator<<(output_buffer& output, const RecordLayerHeader& hdr) -{ - output[AUTO] = hdr.type_; - output[AUTO] = hdr.version_.major_; - output[AUTO] = hdr.version_.minor_; - - // length - byte tmp[2]; - c16toa(hdr.length_, tmp); - output[AUTO] = tmp[0]; - output[AUTO] = tmp[1]; - - return output; -} - - -// virtual input operator for Messages -input_buffer& operator>>(input_buffer& input, Message& msg) -{ - return msg.set(input); -} - -// virtual output operator for Messages -output_buffer& operator<<(output_buffer& output, const Message& msg) -{ - return msg.get(output); -} - - -// input operator for HandShakeHeader -input_buffer& operator>>(input_buffer& input, HandShakeHeader& hs) -{ - hs.type_ = HandShakeType(input[AUTO]); - - hs.length_[0] = input[AUTO]; - hs.length_[1] = input[AUTO]; - hs.length_[2] = input[AUTO]; - - return input; -} - - -// output operator for HandShakeHeader -output_buffer& operator<<(output_buffer& output, const HandShakeHeader& hdr) -{ - output[AUTO] = hdr.type_; - output.write(hdr.length_, sizeof(hdr.length_)); - return output; -} - - -// HandShake Header Processing function -void HandShakeHeader::Process(input_buffer& input, SSL& ssl) -{ - ssl.verifyState(*this); - if (ssl.GetError()) return; - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - const HandShakeFactory& hsf = ssl.getFactory().getHandShake(); - mySTL::auto_ptr<HandShakeBase> hs(hsf.CreateObject(type_)); - if (!hs.get()) { - ssl.SetError(factory_error); - return; - } - - uint len = c24to32(length_); - if (len > input.get_remaining()) { - ssl.SetError(bad_input); - return; - } - hashHandShake(ssl, input, len); - - hs->set_length(len); - input >> *hs; - hs->Process(input, ssl); -} - - -ContentType HandShakeHeader::get_type() const -{ - return handshake; -} - - -uint16 HandShakeHeader::get_length() const -{ - return c24to32(length_); -} - - -HandShakeType HandShakeHeader::get_handshakeType() const -{ - return type_; -} - - -void HandShakeHeader::set_type(HandShakeType hst) -{ - type_ = hst; -} - - -void HandShakeHeader::set_length(uint32 u32) -{ - c32to24(u32, length_); -} - - -input_buffer& HandShakeHeader::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& HandShakeHeader::get(output_buffer& out) const -{ - return out << *this; -} - - - -int HandShakeBase::get_length() const -{ - return length_; -} - - -void HandShakeBase::set_length(int l) -{ - length_ = l; -} - - -// for building buffer's type field -HandShakeType HandShakeBase::get_type() const -{ - return no_shake; -} - - -input_buffer& HandShakeBase::set(input_buffer& in) -{ - return in; -} - - -output_buffer& HandShakeBase::get(output_buffer& out) const -{ - return out; -} - - -void HandShakeBase::Process(input_buffer&, SSL&) -{} - - -input_buffer& HelloRequest::set(input_buffer& in) -{ - return in; -} - - -output_buffer& HelloRequest::get(output_buffer& out) const -{ - return out; -} - - -void HelloRequest::Process(input_buffer&, SSL&) -{} - - -HandShakeType HelloRequest::get_type() const -{ - return hello_request; -} - - -// input operator for CipherSpec -input_buffer& operator>>(input_buffer& input, ChangeCipherSpec& cs) -{ - cs.type_ = CipherChoice(input[AUTO]); - return input; -} - -// output operator for CipherSpec -output_buffer& operator<<(output_buffer& output, const ChangeCipherSpec& cs) -{ - output[AUTO] = cs.type_; - return output; -} - - -ChangeCipherSpec::ChangeCipherSpec() - : type_(change_cipher_spec_choice) -{} - - -input_buffer& ChangeCipherSpec::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& ChangeCipherSpec::get(output_buffer& out) const -{ - return out << *this; -} - - -ContentType ChangeCipherSpec::get_type() const -{ - return change_cipher_spec; -} - - -uint16 ChangeCipherSpec::get_length() const -{ - return SIZEOF_ENUM; -} - - -// CipherSpec processing handler -void ChangeCipherSpec::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - // detect duplicate change_cipher - if (ssl.getSecurity().get_parms().pending_ == false) { - ssl.order_error(); - return; - } - - ssl.useSecurity().use_parms().pending_ = false; - if (ssl.getSecurity().get_resuming()) { - if (ssl.getSecurity().get_parms().entity_ == client_end) - buildFinished(ssl, ssl.useHashes().use_verify(), server); // server - } - else if (ssl.getSecurity().get_parms().entity_ == server_end) - buildFinished(ssl, ssl.useHashes().use_verify(), client); // client -} - - -Alert::Alert(AlertLevel al, AlertDescription ad) - : level_(al), description_(ad) -{} - - -ContentType Alert::get_type() const -{ - return alert; -} - - -uint16 Alert::get_length() const -{ - return SIZEOF_ENUM * 2; -} - - -input_buffer& Alert::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& Alert::get(output_buffer& out) const -{ - return out << *this; -} - - -// input operator for Alert -input_buffer& operator>>(input_buffer& input, Alert& a) -{ - a.level_ = AlertLevel(input[AUTO]); - a.description_ = AlertDescription(input[AUTO]); - - return input; -} - - -// output operator for Alert -output_buffer& operator<<(output_buffer& output, const Alert& a) -{ - output[AUTO] = a.level_; - output[AUTO] = a.description_; - return output; -} - - -// Alert processing handler -void Alert::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - if (ssl.getSecurity().get_parms().pending_ == false) { // encrypted alert - int aSz = get_length(); // alert size already read on input - opaque verify[SHA_LEN]; - const opaque* data = input.get_buffer() + input.get_current() - aSz; - - if (ssl.isTLS()) - TLS_hmac(ssl, verify, data, aSz, alert, true); - else - hmac(ssl, verify, data, aSz, alert, true); - - // read mac and skip fill - int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - opaque mac[SHA_LEN]; - input.read(mac, digestSz); - - if (ssl.getSecurity().get_parms().cipher_type_ == block) { - int ivExtra = 0; - opaque fill __attribute__((unused)); - - if (ssl.isTLSv1_1()) - ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); - int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - - aSz - digestSz; - for (int i = 0; i < padSz; i++) - fill = input[AUTO]; - } - - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - // verify - if (memcmp(mac, verify, digestSz)) { - ssl.SetError(verify_error); - return; - } - } - if (level_ == fatal) { - ssl.useStates().useRecord() = recordNotReady; - ssl.useStates().useHandShake() = handShakeNotReady; - ssl.SetError(YasslError(description_)); - } -} - - -Data::Data() - : length_(0), buffer_(0), write_buffer_(0) -{} - - -Data::Data(uint16 len, opaque* b) - : length_(len), buffer_(b), write_buffer_(0) -{} - - -void Data::SetData(uint16 len, const opaque* buffer) -{ - length_ = len; - write_buffer_ = buffer; -} - -input_buffer& Data::set(input_buffer& in) -{ - return in; -} - - -output_buffer& Data::get(output_buffer& out) const -{ - return out << *this; -} - - -ContentType Data::get_type() const -{ - return application_data; -} - - -uint16 Data::get_length() const -{ - return length_; -} - - -void Data::set_length(uint16 l) -{ - length_ = l; -} - - -opaque* Data::set_buffer() -{ - return buffer_; -} - - -// output operator for Data -output_buffer& operator<<(output_buffer& output, const Data& data) -{ - output.write(data.write_buffer_, data.length_); - return output; -} - - -// check all bytes for equality -static int constant_compare(const byte* a, const byte* b, int len) -{ - int good = 0; - int bad = 0; - - for (int i = 0; i < len; i++) { - if (a[i] == b[i]) - good++; - else - bad++; - } - - if (good == len) - return 0; - else - return 0 - bad; // failure -} - - -// check bytes for pad value -static int pad_check(const byte* input, byte pad, int len) -{ - int good = 0; - int bad = 0; - - for (int i = 0; i < len; i++) { - if (input[i] == pad) - good++; - else - bad++; - } - - if (good == len) - return 0; - else - return 0 - bad; // failure -} - - -// get number of compression rounds -static inline int get_rounds(int pLen, int padLen, int t) -{ - int roundL1 = 1; // round ups - int roundL2 = 1; - - int L1 = COMPRESS_CONSTANT + pLen - t; - int L2 = COMPRESS_CONSTANT + pLen - padLen - 1 - t; - - L1 -= COMPRESS_UPPER; - L2 -= COMPRESS_UPPER; - - if ( (L1 % COMPRESS_LOWER) == 0) - roundL1 = 0; - if ( (L2 % COMPRESS_LOWER) == 0) - roundL2 = 0; - - L1 /= COMPRESS_LOWER; - L2 /= COMPRESS_LOWER; - - L1 += roundL1; - L2 += roundL2; - - return L1 - L2; -} - - -// do compression rounds on dummy data -static inline void compress_rounds(SSL& ssl, int rounds, const byte* dummy) -{ - if (rounds) { - Digest* digest = NULL; - - MACAlgorithm ma = ssl.getSecurity().get_parms().mac_algorithm_; - if (ma == sha) - digest = NEW_YS SHA; - else if (ma == md5) - digest = NEW_YS MD5; - else if (ma == rmd) - digest = NEW_YS RMD; - else - return; - - for (int i = 0; i < rounds; i++) - digest->update(dummy, COMPRESS_LOWER); - - ysDelete(digest); - } -} - - -// timing resistant pad verification -static int timing_verify(SSL& ssl, const byte* input, int padLen, int t, - int pLen) -{ - byte verify[SHA_LEN]; - byte dummy[MAX_PAD_SIZE]; - - memset(dummy, 1, sizeof(dummy)); - - if ( (t + padLen + 1) > pLen) { - pad_check(dummy, (byte)padLen, MAX_PAD_SIZE); - if (ssl.isTLS()) - TLS_hmac(ssl, verify, input, pLen - t, application_data, 1); - else - hmac(ssl, verify, input, pLen - t, application_data, 1); - constant_compare(verify, input + pLen - t, t); - - return -1; - } - - if (pad_check(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) { - pad_check(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1); - if (ssl.isTLS()) - TLS_hmac(ssl, verify, input, pLen - t, application_data, 1); - else - hmac(ssl, verify, input, pLen - t, application_data, 1); - constant_compare(verify, input + pLen - t, t); - - return -1; - } - - pad_check(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1); - if (ssl.isTLS()) - TLS_hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data,1); - else - hmac(ssl, verify, input, pLen - padLen - 1 - t, application_data, 1); - - compress_rounds(ssl, get_rounds(pLen, padLen, t), dummy); - - if (constant_compare(verify, input + (pLen - padLen - 1 - t), t) != 0) - return -1; - - return 0; -} - - -// Process handler for Data -void Data::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - int msgSz = ssl.getSecurity().get_parms().encrypt_size_; - int pad = 0, padSz = 0; - int ivExtra = 0; - int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - const byte* rawData = input.get_buffer() + input.get_current(); - opaque verify[SHA_LEN]; - - if (ssl.getSecurity().get_parms().cipher_type_ == block) { - if (ssl.isTLSv1_1()) // IV - ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); - pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1); - padSz = 1; - - if (ssl.isTLS()) { - if (timing_verify(ssl, rawData, pad,digestSz, msgSz-ivExtra) != 0) { - ssl.SetError(verify_error); - return; - } - } - else { // SSLv3, some don't do this padding right - int sz3 = msgSz - digestSz - pad - 1; - hmac(ssl, verify, rawData, sz3, application_data, true); - if (constant_compare(verify, rawData + sz3, digestSz) != 0) { - ssl.SetError(verify_error); - return; - } - } - } - else { // stream - int streamSz = msgSz - digestSz; - if (ssl.isTLS()) - TLS_hmac(ssl, verify, rawData, streamSz, application_data, true); - else - hmac(ssl, verify, rawData, streamSz, application_data, true); - if (constant_compare(verify, rawData + streamSz, digestSz) != 0) { - ssl.SetError(verify_error); - return; - } - } - - int dataSz = msgSz - ivExtra - digestSz - pad - padSz; - - if (dataSz < 0 || dataSz > (MAX_RECORD_SIZE + COMPRESS_EXTRA)) { - ssl.SetError(bad_input); - return; - } - - // read data - if (dataSz) { // could be compressed - if (ssl.CompressionOn()) { - input_buffer tmp; - if (DeCompress(input, dataSz, tmp) == -1) { - ssl.SetError(decompress_error); - return; - } - ssl.addData(NEW_YS input_buffer(tmp.get_size(), - tmp.get_buffer(), tmp.get_size())); - } - else { - input_buffer* data; - ssl.addData(data = NEW_YS input_buffer(dataSz)); - input.read(data->get_buffer(), dataSz); - data->add_size(dataSz); - } - } - - // advance past mac and fill - input.set_current(input.get_current() + digestSz + pad + padSz); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } -} - - -// virtual input operator for HandShakes -input_buffer& operator>>(input_buffer& input, HandShakeBase& hs) -{ - return hs.set(input); -} - - -// virtual output operator for HandShakes -output_buffer& operator<<(output_buffer& output, const HandShakeBase& hs) -{ - return hs.get(output); -} - - -Certificate::Certificate(const x509* cert) : cert_(cert) -{ - if (cert) - set_length(cert_->get_length() + 2 * CERT_HEADER); // list and cert size - else - set_length(CERT_HEADER); // total blank cert size, just list header -} - - -const opaque* Certificate::get_buffer() const -{ - if (cert_) - return cert_->get_buffer(); - - return NULL; -} - - -// output operator for Certificate -output_buffer& operator<<(output_buffer& output, const Certificate& cert) -{ - uint sz = cert.get_length(); - opaque tmp[CERT_HEADER]; - - if ((int)sz > CERT_HEADER) - sz -= 2 * CERT_HEADER; // actual cert, not including headers - else { - sz = 0; // blank cert case - c32to24(sz, tmp); - output.write(tmp, CERT_HEADER); - - return output; - } - - c32to24(sz + CERT_HEADER, tmp); - output.write(tmp, CERT_HEADER); - c32to24(sz, tmp); - output.write(tmp, CERT_HEADER); - output.write(cert.get_buffer(), sz); - - return output; -} - - -// certificate processing handler -void Certificate::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - CertManager& cm = ssl.useCrypto().use_certManager(); - - uint32 list_sz; - byte tmp[3]; - - if (input.get_remaining() < sizeof(tmp)) { - ssl.SetError(YasslError(bad_input)); - return; - } - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - tmp[2] = input[AUTO]; - c24to32(tmp, list_sz); - - if (list_sz > (uint)MAX_RECORD_SIZE) { // sanity check - ssl.SetError(YasslError(bad_input)); - return; - } - - while (list_sz) { - // cert size - uint32 cert_sz; - - if (input.get_remaining() < sizeof(tmp)) { - ssl.SetError(YasslError(bad_input)); - return; - } - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - tmp[2] = input[AUTO]; - c24to32(tmp, cert_sz); - - if (cert_sz > (uint)MAX_RECORD_SIZE || input.get_remaining() < cert_sz){ - ssl.SetError(YasslError(bad_input)); - return; - } - if (cert_sz) { - x509* myCert; - cm.AddPeerCert(myCert = NEW_YS x509(cert_sz)); - input.read(myCert->use_buffer(), myCert->get_length()); - } - - list_sz -= cert_sz + CERT_HEADER; - } - if (int err = cm.Validate()) - ssl.SetError(YasslError(err)); - else if (ssl.getSecurity().get_parms().entity_ == client_end) - ssl.useStates().useClient() = serverCertComplete; -} - - -Certificate::Certificate() - : cert_(0) -{} - - -input_buffer& Certificate::set(input_buffer& in) -{ - return in; -} - - -output_buffer& Certificate::get(output_buffer& out) const -{ - return out << *this; -} - - -HandShakeType Certificate::get_type() const -{ - return certificate; -} - - -ServerDHParams::ServerDHParams() - : pSz_(0), gSz_(0), pubSz_(0), p_(0), g_(0), Ys_(0) -{} - - -ServerDHParams::~ServerDHParams() -{ - ysArrayDelete(Ys_); - ysArrayDelete(g_); - ysArrayDelete(p_); -} - - -int ServerDHParams::get_pSize() const -{ - return pSz_; -} - - -int ServerDHParams::get_gSize() const -{ - return gSz_; -} - - -int ServerDHParams::get_pubSize() const -{ - return pubSz_; -} - - -const opaque* ServerDHParams::get_p() const -{ - return p_; -} - - -const opaque* ServerDHParams::get_g() const -{ - return g_; -} - - -const opaque* ServerDHParams::get_pub() const -{ - return Ys_; -} - - -opaque* ServerDHParams::alloc_p(int sz) -{ - p_ = NEW_YS opaque[pSz_ = sz]; - return p_; -} - - -opaque* ServerDHParams::alloc_g(int sz) -{ - g_ = NEW_YS opaque[gSz_ = sz]; - return g_; -} - - -opaque* ServerDHParams::alloc_pub(int sz) -{ - Ys_ = NEW_YS opaque[pubSz_ = sz]; - return Ys_; -} - - -int ServerKeyBase::get_length() const -{ - return 0; -} - - -opaque* ServerKeyBase::get_serverKey() const -{ - return 0; -} - - -// input operator for ServerHello -input_buffer& operator>>(input_buffer& input, ServerHello& hello) -{ - // Protocol - hello.server_version_.major_ = input[AUTO]; - hello.server_version_.minor_ = input[AUTO]; - - // Random - input.read(hello.random_, RAN_LEN); - - // Session - hello.id_len_ = input[AUTO]; - if (hello.id_len_ > ID_LEN) { - input.set_error(); - return input; - } - if (hello.id_len_) - input.read(hello.session_id_, hello.id_len_); - - // Suites - hello.cipher_suite_[0] = input[AUTO]; - hello.cipher_suite_[1] = input[AUTO]; - - // Compression - hello.compression_method_ = CompressionMethod(input[AUTO]); - - return input; -} - - -// output operator for ServerHello -output_buffer& operator<<(output_buffer& output, const ServerHello& hello) -{ - // Protocol - output[AUTO] = hello.server_version_.major_; - output[AUTO] = hello.server_version_.minor_; - - // Random - output.write(hello.random_, RAN_LEN); - - // Session - output[AUTO] = hello.id_len_; - output.write(hello.session_id_, ID_LEN); - - // Suites - output[AUTO] = hello.cipher_suite_[0]; - output[AUTO] = hello.cipher_suite_[1]; - - // Compression - output[AUTO] = hello.compression_method_; - - return output; -} - - -// Server Hello processing handler -void ServerHello::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - if (ssl.GetMultiProtocol()) { // SSLv23 support - if (ssl.isTLS() && server_version_.minor_ < 1) - // downgrade to SSLv3 - ssl.useSecurity().use_connection().TurnOffTLS(); - else if (ssl.isTLSv1_1() && server_version_.minor_ == 1) - // downdrage to TLSv1 - ssl.useSecurity().use_connection().TurnOffTLS1_1(); - } - else if (ssl.isTLSv1_1() && server_version_.minor_ < 2) { - ssl.SetError(badVersion_error); - return; - } - else if (ssl.isTLS() && server_version_.minor_ < 1) { - ssl.SetError(badVersion_error); - return; - } - else if (!ssl.isTLS() && (server_version_.major_ == 3 && - server_version_.minor_ >= 1)) { - ssl.SetError(badVersion_error); - return; - } - if (cipher_suite_[0] != 0x00) { - ssl.SetError(unknown_cipher); - return; - } - ssl.set_pending(cipher_suite_[1]); - ssl.set_random(random_, server_end); - if (id_len_) - ssl.set_sessionID(session_id_); - else - ssl.useSecurity().use_connection().sessionID_Set_ = false; - - if (ssl.getSecurity().get_resuming()) { - if (memcmp(session_id_, ssl.getSecurity().get_resume().GetID(), - ID_LEN) == 0) { - ssl.set_masterSecret(ssl.getSecurity().get_resume().GetSecret()); - if (ssl.isTLS()) - ssl.deriveTLSKeys(); - else - ssl.deriveKeys(); - ssl.useStates().useClient() = serverHelloDoneComplete; - return; - } - else { - ssl.useSecurity().set_resuming(false); - ssl.useLog().Trace("server denied resumption"); - } - } - - if (ssl.CompressionOn() && !compression_method_) - ssl.UnSetCompression(); // server isn't supporting yaSSL zlib request - - ssl.useStates().useClient() = serverHelloComplete; -} - - -ServerHello::ServerHello() -{ - memset(random_, 0, RAN_LEN); - memset(session_id_, 0, ID_LEN); -} - - -ServerHello::ServerHello(ProtocolVersion pv, bool useCompression) - : server_version_(pv), - compression_method_(useCompression ? zlib : no_compression) -{ - memset(random_, 0, RAN_LEN); - memset(session_id_, 0, ID_LEN); -} - - -input_buffer& ServerHello::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& ServerHello::get(output_buffer& out) const -{ - return out << *this; -} - - -HandShakeType ServerHello::get_type() const -{ - return server_hello; -} - - -const opaque* ServerHello::get_random() const -{ - return random_; -} - - -// Server Hello Done processing handler -void ServerHelloDone::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - ssl.useStates().useClient() = serverHelloDoneComplete; -} - - -ServerHelloDone::ServerHelloDone() -{ - set_length(0); -} - - -input_buffer& ServerHelloDone::set(input_buffer& in) -{ - return in; -} - - -output_buffer& ServerHelloDone::get(output_buffer& out) const -{ - return out; -} - - -HandShakeType ServerHelloDone::get_type() const -{ - return server_hello_done; -} - - -int ClientKeyBase::get_length() const -{ - return 0; -} - - -opaque* ClientKeyBase::get_clientKey() const -{ - return 0; -} - - -// input operator for Client Hello -input_buffer& operator>>(input_buffer& input, ClientHello& hello) -{ - uint begin = input.get_current(); // could have extensions at end - - // Protocol - hello.client_version_.major_ = input[AUTO]; - hello.client_version_.minor_ = input[AUTO]; - - // Random - input.read(hello.random_, RAN_LEN); - - // Session - hello.id_len_ = input[AUTO]; - if (hello.id_len_) input.read(hello.session_id_, ID_LEN); - - // Suites - byte tmp[2]; - uint16 len; - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, len); - - hello.suite_len_ = min(len, static_cast<uint16>(MAX_SUITE_SZ)); - input.read(hello.cipher_suites_, hello.suite_len_); - if (len > hello.suite_len_) // ignore extra suites - input.set_current(input.get_current() + len - hello.suite_len_); - - // Compression - hello.comp_len_ = input[AUTO]; - hello.compression_methods_ = no_compression; - while (hello.comp_len_--) { - CompressionMethod cm = CompressionMethod(input[AUTO]); - if (cm == zlib) - hello.compression_methods_ = zlib; - } - - uint read = input.get_current() - begin; - uint expected = hello.get_length(); - - // ignore client hello extensions for now - if (read < expected) - input.set_current(input.get_current() + expected - read); - - return input; -} - - -// output operaotr for Client Hello -output_buffer& operator<<(output_buffer& output, const ClientHello& hello) -{ - // Protocol - output[AUTO] = hello.client_version_.major_; - output[AUTO] = hello.client_version_.minor_; - - // Random - output.write(hello.random_, RAN_LEN); - - // Session - output[AUTO] = hello.id_len_; - if (hello.id_len_) output.write(hello.session_id_, ID_LEN); - - // Suites - byte tmp[2]; - c16toa(hello.suite_len_, tmp); - output[AUTO] = tmp[0]; - output[AUTO] = tmp[1]; - output.write(hello.cipher_suites_, hello.suite_len_); - - // Compression - output[AUTO] = hello.comp_len_; - output[AUTO] = hello.compression_methods_; - - return output; -} - - -// Client Hello processing handler -void ClientHello::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - // store version for pre master secret - ssl.useSecurity().use_connection().chVersion_ = client_version_; - - if (client_version_.major_ != 3) { - ssl.SetError(badVersion_error); - return; - } - if (ssl.GetMultiProtocol()) { // SSLv23 support - if (ssl.isTLS() && client_version_.minor_ < 1) { - // downgrade to SSLv3 - ssl.useSecurity().use_connection().TurnOffTLS(); - - ProtocolVersion pv = ssl.getSecurity().get_connection().version_; - bool removeDH = ssl.getSecurity().get_parms().removeDH_; - bool removeRSA = false; - bool removeDSA = false; - - const CertManager& cm = ssl.getCrypto().get_certManager(); - if (cm.get_keyType() == rsa_sa_algo) - removeDSA = true; - else - removeRSA = true; - - // reset w/ SSL suites - ssl.useSecurity().use_parms().SetSuites(pv, removeDH, removeRSA, - removeDSA); - } - else if (ssl.isTLSv1_1() && client_version_.minor_ == 1) - // downgrade to TLSv1, but use same suites - ssl.useSecurity().use_connection().TurnOffTLS1_1(); - } - else if (ssl.isTLSv1_1() && client_version_.minor_ < 2) { - ssl.SetError(badVersion_error); - return; - } - else if (ssl.isTLS() && client_version_.minor_ < 1) { - ssl.SetError(badVersion_error); - return; - } - else if (!ssl.isTLS() && client_version_.minor_ >= 1) { - ssl.SetError(badVersion_error); - return; - } - - ssl.set_random(random_, client_end); - - while (id_len_) { // trying to resume - SSL_SESSION* session = 0; - if (!ssl.getSecurity().GetContext()->GetSessionCacheOff()) - session = GetSessions().lookup(session_id_); - if (!session) { - ssl.useLog().Trace("session lookup failed"); - break; - } - ssl.set_session(session); - ssl.useSecurity().set_resuming(true); - ssl.matchSuite(session->GetSuite(), SUITE_LEN); - if (ssl.GetError()) return; - ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); - ssl.set_masterSecret(session->GetSecret()); - - opaque serverRandom[RAN_LEN]; - ssl.getCrypto().get_random().Fill(serverRandom, sizeof(serverRandom)); - ssl.set_random(serverRandom, server_end); - if (ssl.isTLS()) - ssl.deriveTLSKeys(); - else - ssl.deriveKeys(); - ssl.useStates().useServer() = clientKeyExchangeComplete; - return; - } - ssl.matchSuite(cipher_suites_, suite_len_); - if (ssl.GetError()) return; - ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); - - if (compression_methods_ == zlib) - ssl.SetCompression(); - - ssl.useStates().useServer() = clientHelloComplete; -} - - -input_buffer& ClientHello::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& ClientHello::get(output_buffer& out) const -{ - return out << *this; -} - - -HandShakeType ClientHello::get_type() const -{ - return client_hello; -} - - -const opaque* ClientHello::get_random() const -{ - return random_; -} - - -ClientHello::ClientHello() -{ - memset(random_, 0, RAN_LEN); -} - - -ClientHello::ClientHello(ProtocolVersion pv, bool useCompression) - : client_version_(pv), - compression_methods_(useCompression ? zlib : no_compression) -{ - memset(random_, 0, RAN_LEN); -} - - -// output operator for ServerKeyExchange -output_buffer& operator<<(output_buffer& output, const ServerKeyExchange& sk) -{ - output.write(sk.getKey(), sk.getKeyLength()); - return output; -} - - -// Server Key Exchange processing handler -void ServerKeyExchange::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - createKey(ssl); - if (ssl.GetError()) return; - server_key_->read(ssl, input); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - ssl.useStates().useClient() = serverKeyExchangeComplete; -} - - -ServerKeyExchange::ServerKeyExchange(SSL& ssl) -{ - createKey(ssl); -} - - -ServerKeyExchange::ServerKeyExchange() - : server_key_(0) -{} - - -ServerKeyExchange::~ServerKeyExchange() -{ - ysDelete(server_key_); -} - - -void ServerKeyExchange::build(SSL& ssl) -{ - server_key_->build(ssl); - set_length(server_key_->get_length()); -} - - -const opaque* ServerKeyExchange::getKey() const -{ - return server_key_->get_serverKey(); -} - - -int ServerKeyExchange::getKeyLength() const -{ - return server_key_->get_length(); -} - - -input_buffer& ServerKeyExchange::set(input_buffer& in) -{ - return in; // process does -} - - -output_buffer& ServerKeyExchange::get(output_buffer& out) const -{ - return out << *this; -} - - -HandShakeType ServerKeyExchange::get_type() const -{ - return server_key_exchange; -} - - -// CertificateRequest -CertificateRequest::CertificateRequest() - : typeTotal_(0) -{ - memset(certificate_types_, 0, sizeof(certificate_types_)); -} - - -CertificateRequest::~CertificateRequest() -{ - - STL::for_each(certificate_authorities_.begin(), - certificate_authorities_.end(), - del_ptr_zero()) ; -} - - -void CertificateRequest::Build() -{ - certificate_types_[0] = rsa_sign; - certificate_types_[1] = dss_sign; - - typeTotal_ = 2; - - uint16 authCount = 0; - uint16 authSz = 0; - - for (int j = 0; j < authCount; j++) { - int sz = REQUEST_HEADER + MIN_DIS_SIZE; - DistinguishedName dn; - certificate_authorities_.push_back(dn = NEW_YS byte[sz]); - - opaque tmp[REQUEST_HEADER]; - c16toa(MIN_DIS_SIZE, tmp); - memcpy(dn, tmp, sizeof(tmp)); - - // fill w/ junk for now - memcpy(dn, tmp, MIN_DIS_SIZE); - authSz += sz; - } - - set_length(SIZEOF_ENUM + typeTotal_ + REQUEST_HEADER + authSz); -} - - -input_buffer& CertificateRequest::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& CertificateRequest::get(output_buffer& out) const -{ - return out << *this; -} - - -// input operator for CertificateRequest -input_buffer& operator>>(input_buffer& input, CertificateRequest& request) -{ - // types - request.typeTotal_ = input[AUTO]; - if (request.typeTotal_ > CERT_TYPES) { - input.set_error(); - return input; - } - for (int i = 0; i < request.typeTotal_; i++) - request.certificate_types_[i] = ClientCertificateType(input[AUTO]); - - byte tmp[2]; - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - uint16 sz; - ato16(tmp, sz); - - // authorities - while (sz) { - uint16 dnSz; - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - ato16(tmp, dnSz); - - input.set_current(input.get_current() + dnSz); - - sz -= dnSz + REQUEST_HEADER; - - if (input.get_error()) - break; - } - - return input; -} - - -// output operator for CertificateRequest -output_buffer& operator<<(output_buffer& output, - const CertificateRequest& request) -{ - // types - output[AUTO] = request.typeTotal_; - for (int i = 0; i < request.typeTotal_; i++) - output[AUTO] = request.certificate_types_[i]; - - // authorities - opaque tmp[REQUEST_HEADER]; - c16toa(request.get_length() - SIZEOF_ENUM - - request.typeTotal_ - REQUEST_HEADER, tmp); - output.write(tmp, sizeof(tmp)); - - STL::list<DistinguishedName>::const_iterator first = - request.certificate_authorities_.begin(); - STL::list<DistinguishedName>::const_iterator last = - request.certificate_authorities_.end(); - while (first != last) { - uint16 sz; - ato16(*first, sz); - output.write(*first, sz + REQUEST_HEADER); - - ++first; - } - - return output; -} - - -// CertificateRequest processing handler -void CertificateRequest::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - CertManager& cm = ssl.useCrypto().use_certManager(); - - cm.setSendVerify(); - if (cm.get_cert() == NULL || cm.get_privateKey() == NULL) - cm.setSendBlankCert(); // send blank cert, OpenSSL requires now -} - - -HandShakeType CertificateRequest::get_type() const -{ - return certificate_request; -} - - -// CertificateVerify -CertificateVerify::CertificateVerify() : signature_(0) -{} - - -CertificateVerify::~CertificateVerify() -{ - ysArrayDelete(signature_); -} - - -void CertificateVerify::Build(SSL& ssl) -{ - build_certHashes(ssl, hashes_); - - uint16 sz = 0; - byte len[VERIFY_HEADER]; - mySTL::auto_array<byte> sig; - - // sign - const CertManager& cert = ssl.getCrypto().get_certManager(); - if (cert.get_keyType() == rsa_sa_algo) { - RSA rsa(cert.get_privateKey(), cert.get_privateKeyLength(), false); - - sz = rsa.get_cipherLength() + VERIFY_HEADER; - sig.reset(NEW_YS byte[sz]); - - c16toa(sz - VERIFY_HEADER, len); - memcpy(sig.get(), len, VERIFY_HEADER); - rsa.sign(sig.get() + VERIFY_HEADER, hashes_.md5_, sizeof(Hashes), - ssl.getCrypto().get_random()); - // check for rsa signautre fault - if (!rsa.verify(hashes_.md5_, sizeof(Hashes), sig.get() + VERIFY_HEADER, - rsa.get_cipherLength())) { - ssl.SetError(rsaSignFault_error); - return; - } - } - else { // DSA - DSS dss(cert.get_privateKey(), cert.get_privateKeyLength(), false); - - sz = DSS_SIG_SZ + DSS_ENCODED_EXTRA + VERIFY_HEADER; - sig.reset(NEW_YS byte[sz]); - - c16toa(sz - VERIFY_HEADER, len); - memcpy(sig.get(), len, VERIFY_HEADER); - dss.sign(sig.get() + VERIFY_HEADER, hashes_.sha_, SHA_LEN, - ssl.getCrypto().get_random()); - - byte encoded[DSS_SIG_SZ + DSS_ENCODED_EXTRA]; - TaoCrypt::EncodeDSA_Signature(sig.get() + VERIFY_HEADER, encoded); - memcpy(sig.get() + VERIFY_HEADER, encoded, sizeof(encoded)); - } - set_length(sz); - signature_ = sig.release(); -} - - -input_buffer& CertificateVerify::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& CertificateVerify::get(output_buffer& out) const -{ - return out << *this; -} - - -// input operator for CertificateVerify -input_buffer& operator>>(input_buffer& input, CertificateVerify& request) -{ - byte tmp[VERIFY_HEADER]; - tmp[0] = input[AUTO]; - tmp[1] = input[AUTO]; - - uint16 sz = 0; - ato16(tmp, sz); - request.set_length(sz); - - if (sz == 0) { - input.set_error(); - return input; - } - - request.signature_ = NEW_YS byte[sz]; - input.read(request.signature_, sz); - - return input; -} - - -// output operator for CertificateVerify -output_buffer& operator<<(output_buffer& output, - const CertificateVerify& verify) -{ - output.write(verify.signature_, verify.get_length()); - - return output; -} - - -// CertificateVerify processing handler -void CertificateVerify::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - const Hashes& hashVerify = ssl.getHashes().get_certVerify(); - const CertManager& cert = ssl.getCrypto().get_certManager(); - - if (cert.get_peerKeyType() == rsa_sa_algo) { - RSA rsa(cert.get_peerKey(), cert.get_peerKeyLength()); - - if (!rsa.verify(hashVerify.md5_, sizeof(hashVerify), signature_, - get_length())) - ssl.SetError(verify_error); - } - else { // DSA - byte decodedSig[DSS_SIG_SZ]; - TaoCrypt::DecodeDSA_Signature(decodedSig, signature_, get_length()); - - DSS dss(cert.get_peerKey(), cert.get_peerKeyLength()); - if (!dss.verify(hashVerify.sha_, SHA_LEN, decodedSig, get_length())) - ssl.SetError(verify_error); - } -} - - -HandShakeType CertificateVerify::get_type() const -{ - return certificate_verify; -} - - -// output operator for ClientKeyExchange -output_buffer& operator<<(output_buffer& output, const ClientKeyExchange& ck) -{ - output.write(ck.getKey(), ck.getKeyLength()); - return output; -} - - -// Client Key Exchange processing handler -void ClientKeyExchange::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - createKey(ssl); - if (ssl.GetError()) return; - client_key_->read(ssl, input); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - if (ssl.getCrypto().get_certManager().verifyPeer()) - build_certHashes(ssl, ssl.useHashes().use_certVerify()); - - ssl.useStates().useServer() = clientKeyExchangeComplete; -} - - -ClientKeyExchange::ClientKeyExchange(SSL& ssl) -{ - createKey(ssl); -} - - -ClientKeyExchange::ClientKeyExchange() - : client_key_(0) -{} - - -ClientKeyExchange::~ClientKeyExchange() -{ - ysDelete(client_key_); -} - - -void ClientKeyExchange::build(SSL& ssl) -{ - client_key_->build(ssl); - set_length(client_key_->get_length()); -} - -const opaque* ClientKeyExchange::getKey() const -{ - return client_key_->get_clientKey(); -} - - -int ClientKeyExchange::getKeyLength() const -{ - return client_key_->get_length(); -} - - -input_buffer& ClientKeyExchange::set(input_buffer& in) -{ - return in; -} - - -output_buffer& ClientKeyExchange::get(output_buffer& out) const -{ - return out << *this; -} - - -HandShakeType ClientKeyExchange::get_type() const -{ - return client_key_exchange; -} - - -// input operator for Finished -input_buffer& operator>>(input_buffer& input, Finished&) -{ - /* do in process */ - - return input; -} - -// output operator for Finished -output_buffer& operator<<(output_buffer& output, const Finished& fin) -{ - if (fin.get_length() == FINISHED_SZ) { - output.write(fin.hashes_.md5_, MD5_LEN); - output.write(fin.hashes_.sha_, SHA_LEN); - } - else // TLS_FINISHED_SZ - output.write(fin.hashes_.md5_, TLS_FINISHED_SZ); - - return output; -} - - -// Finished processing handler -void Finished::Process(input_buffer& input, SSL& ssl) -{ - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - // verify hashes - const Finished& verify = ssl.getHashes().get_verify(); - uint finishedSz = ssl.isTLS() ? TLS_FINISHED_SZ : FINISHED_SZ; - - input.read(hashes_.md5_, finishedSz); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - if (memcmp(&hashes_, &verify.hashes_, finishedSz)) { - ssl.SetError(verify_error); - return; - } - - // read verify mac - opaque verifyMAC[SHA_LEN]; - uint macSz = finishedSz + HANDSHAKE_HEADER; - - if (ssl.isTLS()) - TLS_hmac(ssl, verifyMAC, input.get_buffer() + input.get_current() - - macSz, macSz, handshake, true); - else - hmac(ssl, verifyMAC, input.get_buffer() + input.get_current() - macSz, - macSz, handshake, true); - - // read mac and fill - opaque mac[SHA_LEN]; // max size - int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - input.read(mac, digestSz); - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - uint ivExtra = 0; - if (ssl.getSecurity().get_parms().cipher_type_ == block) - if (ssl.isTLSv1_1()) - ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); - - opaque fill __attribute__((unused)); - int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - - HANDSHAKE_HEADER - finishedSz - digestSz; - for (int i = 0; i < padSz; i++) - fill = input[AUTO]; - if (input.get_error()) { - ssl.SetError(bad_input); - return; - } - - // update states - ssl.useStates().useHandShake() = handShakeReady; - if (ssl.getSecurity().get_parms().entity_ == client_end) - ssl.useStates().useClient() = serverFinishedComplete; - else - ssl.useStates().useServer() = clientFinishedComplete; -} - - -Finished::Finished() -{ - set_length(FINISHED_SZ); -} - - -uint8* Finished::set_md5() -{ - return hashes_.md5_; -} - - -uint8* Finished::set_sha() -{ - return hashes_.sha_; -} - - -input_buffer& Finished::set(input_buffer& in) -{ - return in >> *this; -} - - -output_buffer& Finished::get(output_buffer& out) const -{ - return out << *this; -} - - -HandShakeType Finished::get_type() const -{ - return finished; -} - - -void clean(volatile opaque* p, uint sz, RandomPool& ran) -{ - uint i(0); - - for (i = 0; i < sz; ++i) - p[i] = 0; - - ran.Fill(const_cast<opaque*>(p), sz); - - for (i = 0; i < sz; ++i) - p[i] = 0; -} - - - -Connection::Connection(ProtocolVersion v, RandomPool& ran) - : pre_master_secret_(0), sequence_number_(0), peer_sequence_number_(0), - pre_secret_len_(0), send_server_key_(false), master_clean_(false), - TLS_(v.major_ >= 3 && v.minor_ >= 1), - TLSv1_1_(v.major_ >= 3 && v.minor_ >= 2), compression_(false), - version_(v), random_(ran) -{ - memset(sessionID_, 0, sizeof(sessionID_)); -} - - -Connection::~Connection() -{ - CleanMaster(); CleanPreMaster(); ysArrayDelete(pre_master_secret_); -} - - -void Connection::AllocPreSecret(uint sz) -{ - pre_master_secret_ = NEW_YS opaque[pre_secret_len_ = sz]; -} - - -void Connection::TurnOffTLS() -{ - TLS_ = false; - version_.minor_ = 0; -} - - -void Connection::TurnOffTLS1_1() -{ - TLSv1_1_ = false; - version_.minor_ = 1; -} - - -// wipeout master secret -void Connection::CleanMaster() -{ - if (!master_clean_) { - volatile opaque* p = master_secret_; - clean(p, SECRET_LEN, random_); - master_clean_ = true; - } -} - - -// wipeout pre master secret -void Connection::CleanPreMaster() -{ - if (pre_master_secret_) { - volatile opaque* p = pre_master_secret_; - clean(p, pre_secret_len_, random_); - - ysArrayDelete(pre_master_secret_); - pre_master_secret_ = 0; - } -} - - -// Create functions for message factory -Message* CreateCipherSpec() { return NEW_YS ChangeCipherSpec; } -Message* CreateAlert() { return NEW_YS Alert; } -Message* CreateHandShake() { return NEW_YS HandShakeHeader; } -Message* CreateData() { return NEW_YS Data; } - -// Create functions for handshake factory -HandShakeBase* CreateHelloRequest() { return NEW_YS HelloRequest; } -HandShakeBase* CreateClientHello() { return NEW_YS ClientHello; } -HandShakeBase* CreateServerHello() { return NEW_YS ServerHello; } -HandShakeBase* CreateCertificate() { return NEW_YS Certificate; } -HandShakeBase* CreateServerKeyExchange() { return NEW_YS ServerKeyExchange;} -HandShakeBase* CreateCertificateRequest() { return NEW_YS - CertificateRequest; } -HandShakeBase* CreateServerHelloDone() { return NEW_YS ServerHelloDone; } -HandShakeBase* CreateCertificateVerify() { return NEW_YS CertificateVerify;} -HandShakeBase* CreateClientKeyExchange() { return NEW_YS ClientKeyExchange;} -HandShakeBase* CreateFinished() { return NEW_YS Finished; } - -// Create functions for server key exchange factory -ServerKeyBase* CreateRSAServerKEA() { return NEW_YS RSA_Server; } -ServerKeyBase* CreateDHServerKEA() { return NEW_YS DH_Server; } -ServerKeyBase* CreateFortezzaServerKEA() { return NEW_YS Fortezza_Server; } - -// Create functions for client key exchange factory -ClientKeyBase* CreateRSAClient() { return NEW_YS - EncryptedPreMasterSecret; } -ClientKeyBase* CreateDHClient() { return NEW_YS - ClientDiffieHellmanPublic; } -ClientKeyBase* CreateFortezzaClient() { return NEW_YS FortezzaKeys; } - - -// Constructor calls this to Register compile time callbacks -void InitMessageFactory(MessageFactory& mf) -{ - mf.Reserve(4); - mf.Register(alert, CreateAlert); - mf.Register(change_cipher_spec, CreateCipherSpec); - mf.Register(handshake, CreateHandShake); - mf.Register(application_data, CreateData); -} - - -// Constructor calls this to Register compile time callbacks -void InitHandShakeFactory(HandShakeFactory& hsf) -{ - hsf.Reserve(10); - hsf.Register(hello_request, CreateHelloRequest); - hsf.Register(client_hello, CreateClientHello); - hsf.Register(server_hello, CreateServerHello); - hsf.Register(certificate, CreateCertificate); - hsf.Register(server_key_exchange, CreateServerKeyExchange); - hsf.Register(certificate_request, CreateCertificateRequest); - hsf.Register(server_hello_done, CreateServerHelloDone); - hsf.Register(certificate_verify, CreateCertificateVerify); - hsf.Register(client_key_exchange, CreateClientKeyExchange); - hsf.Register(finished, CreateFinished); -} - - -// Constructor calls this to Register compile time callbacks -void InitServerKeyFactory(ServerKeyFactory& skf) -{ - skf.Reserve(3); - skf.Register(rsa_kea, CreateRSAServerKEA); - skf.Register(diffie_hellman_kea, CreateDHServerKEA); - skf.Register(fortezza_kea, CreateFortezzaServerKEA); -} - - -// Constructor calls this to Register compile time callbacks -void InitClientKeyFactory(ClientKeyFactory& ckf) -{ - ckf.Reserve(3); - ckf.Register(rsa_kea, CreateRSAClient); - ckf.Register(diffie_hellman_kea, CreateDHClient); - ckf.Register(fortezza_kea, CreateFortezzaClient); -} - - -} // namespace diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp deleted file mode 100644 index e244761e647..00000000000 --- a/extra/yassl/src/yassl_int.cpp +++ /dev/null @@ -1,2705 +0,0 @@ -/* - Copyright (c) 2005, 2017, Oracle and/or its affiliates. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1335 USA. -*/ - - -/* yaSSL internal source implements SSL supporting types not specified in the - * draft along with type conversion functions. - */ - -#include "runtime.hpp" -#include "yassl_int.hpp" -#include "handshake.hpp" -#include "timer.hpp" - -#ifdef _POSIX_THREADS - #include "pthread.h" -#endif - - -#ifdef HAVE_LIBZ - #include "zlib.h" -#endif - - -#ifdef YASSL_PURE_C - - void* operator new(size_t sz, yaSSL::new_t) - { - void* ptr = malloc(sz ? sz : 1); - if (!ptr) abort(); - - return ptr; - } - - - void operator delete(void* ptr, yaSSL::new_t) - { - if (ptr) free(ptr); - } - - - void* operator new[](size_t sz, yaSSL::new_t nt) - { - return ::operator new(sz, nt); - } - - - void operator delete[](void* ptr, yaSSL::new_t nt) - { - ::operator delete(ptr, nt); - } - - namespace yaSSL { - - new_t ys; // for yaSSL library new - - } - -#endif // YASSL_PURE_C - - -namespace yaSSL { - - - - - - -// convert a 32 bit integer into a 24 bit one -void c32to24(uint32 u32, uint24& u24) -{ - u24[0] = (u32 >> 16) & 0xff; - u24[1] = (u32 >> 8) & 0xff; - u24[2] = u32 & 0xff; -} - - -// convert a 24 bit integer into a 32 bit one -void c24to32(const uint24 u24, uint32& u32) -{ - u32 = 0; - u32 = (u24[0] << 16) | (u24[1] << 8) | u24[2]; -} - - -// convert with return for ease of use -uint32 c24to32(const uint24 u24) -{ - uint32 ret; - c24to32(u24, ret); - - return ret; -} - - -// using a for opaque since underlying type is unsgined char and o is not a -// good leading identifier - -// convert opaque to 16 bit integer -void ato16(const opaque* c, uint16& u16) -{ - u16 = 0; - u16 = (c[0] << 8) | (c[1]); -} - - -// convert (copy) opaque to 24 bit integer -void ato24(const opaque* c, uint24& u24) -{ - u24[0] = c[0]; - u24[1] = c[1]; - u24[2] = c[2]; -} - - -// convert 16 bit integer to opaque -void c16toa(uint16 u16, opaque* c) -{ - c[0] = (u16 >> 8) & 0xff; - c[1] = u16 & 0xff; -} - - -// convert 24 bit integer to opaque -void c24toa(const uint24 u24, opaque* c) -{ - c[0] = u24[0]; - c[1] = u24[1]; - c[2] = u24[2]; -} - - -// convert 32 bit integer to opaque -void c32toa(uint32 u32, opaque* c) -{ - c[0] = (u32 >> 24) & 0xff; - c[1] = (u32 >> 16) & 0xff; - c[2] = (u32 >> 8) & 0xff; - c[3] = u32 & 0xff; -} - - -States::States() : recordLayer_(recordReady), handshakeLayer_(preHandshake), - clientState_(serverNull), serverState_(clientNull), - connectState_(CONNECT_BEGIN), acceptState_(ACCEPT_BEGIN), - what_(no_error) {} - -const RecordLayerState& States::getRecord() const -{ - return recordLayer_; -} - - -const HandShakeState& States::getHandShake() const -{ - return handshakeLayer_; -} - - -const ClientState& States::getClient() const -{ - return clientState_; -} - - -const ServerState& States::getServer() const -{ - return serverState_; -} - - -const ConnectState& States::GetConnect() const -{ - return connectState_; -} - - -const AcceptState& States::GetAccept() const -{ - return acceptState_; -} - - -const char* States::getString() const -{ - return errorString_; -} - - -YasslError States::What() const -{ - return what_; -} - - -RecordLayerState& States::useRecord() -{ - return recordLayer_; -} - - -HandShakeState& States::useHandShake() -{ - return handshakeLayer_; -} - - -ClientState& States::useClient() -{ - return clientState_; -} - - -ServerState& States::useServer() -{ - return serverState_; -} - - -ConnectState& States::UseConnect() -{ - return connectState_; -} - - -AcceptState& States::UseAccept() -{ - return acceptState_; -} - - -char* States::useString() -{ - return errorString_; -} - - -void States::SetError(YasslError ye) -{ - what_ = ye; -} - - -// mark message recvd, check for duplicates, return 0 on success -int States::SetMessageRecvd(HandShakeType hst) -{ - switch (hst) { - case hello_request: - break; // could send more than one - - case client_hello: - if (recvdMessages_.gotClientHello_) - return -1; - recvdMessages_.gotClientHello_ = 1; - break; - - case server_hello: - if (recvdMessages_.gotServerHello_) - return -1; - recvdMessages_.gotServerHello_ = 1; - break; - - case certificate: - if (recvdMessages_.gotCert_) - return -1; - recvdMessages_.gotCert_ = 1; - break; - - case server_key_exchange: - if (recvdMessages_.gotServerKeyExchange_) - return -1; - recvdMessages_.gotServerKeyExchange_ = 1; - break; - - case certificate_request: - if (recvdMessages_.gotCertRequest_) - return -1; - recvdMessages_.gotCertRequest_ = 1; - break; - - case server_hello_done: - if (recvdMessages_.gotServerHelloDone_) - return -1; - recvdMessages_.gotServerHelloDone_ = 1; - break; - - case certificate_verify: - if (recvdMessages_.gotCertVerify_) - return -1; - recvdMessages_.gotCertVerify_ = 1; - break; - - case client_key_exchange: - if (recvdMessages_.gotClientKeyExchange_) - return -1; - recvdMessages_.gotClientKeyExchange_ = 1; - break; - - case finished: - if (recvdMessages_.gotFinished_) - return -1; - recvdMessages_.gotFinished_ = 1; - break; - - - default: - return -1; - - } - - return 0; -} - - -sslFactory::sslFactory() : - messageFactory_(InitMessageFactory), - handShakeFactory_(InitHandShakeFactory), - serverKeyFactory_(InitServerKeyFactory), - clientKeyFactory_(InitClientKeyFactory) -{} - - -const MessageFactory& sslFactory::getMessage() const -{ - return messageFactory_; -} - - -const HandShakeFactory& sslFactory::getHandShake() const -{ - return handShakeFactory_; -} - - -const ServerKeyFactory& sslFactory::getServerKey() const -{ - return serverKeyFactory_; -} - - -const ClientKeyFactory& sslFactory::getClientKey() const -{ - return clientKeyFactory_; -} - - -// extract context parameters and store -SSL::SSL(SSL_CTX* ctx) - : secure_(ctx->getMethod()->getVersion(), crypto_.use_random(), - ctx->getMethod()->getSide(), ctx->GetCiphers(), ctx, - ctx->GetDH_Parms().set_), quietShutdown_(false), has_data_(false) -{ - if (int err = crypto_.get_random().GetError()) { - SetError(YasslError(err)); - return; - } - - CertManager& cm = crypto_.use_certManager(); - cm.CopySelfCert(ctx->getCert()); - - bool serverSide = secure_.use_parms().entity_ == server_end; - - if (ctx->getKey()) { - if (int err = cm.SetPrivateKey(*ctx->getKey())) { - SetError(YasslError(err)); - return; - } - else if (serverSide && ctx->GetCiphers().setSuites_ == 0) { - // remove RSA or DSA suites depending on cert key type - // but don't override user sets - ProtocolVersion pv = secure_.get_connection().version_; - - bool removeDH = secure_.use_parms().removeDH_; - bool removeRSA = false; - bool removeDSA = false; - - if (cm.get_keyType() == rsa_sa_algo) - removeDSA = true; - else - removeRSA = true; - secure_.use_parms().SetSuites(pv, removeDH, removeRSA, removeDSA); - } - } - else if (serverSide) { - SetError(no_key_file); - return; - } - - if (ctx->getMethod()->verifyPeer()) - cm.setVerifyPeer(); - if (ctx->getMethod()->verifyNone()) - cm.setVerifyNone(); - if (ctx->getMethod()->failNoCert()) - cm.setFailNoCert(); - cm.setVerifyCallback(ctx->getVerifyCallback()); - - if (serverSide) - crypto_.SetDH(ctx->GetDH_Parms()); - - const SSL_CTX::CertList& ca = ctx->GetCA_List(); - SSL_CTX::CertList::const_iterator first(ca.begin()); - SSL_CTX::CertList::const_iterator last(ca.end()); - - while (first != last) { - if (int err = cm.CopyCaCert(*first)) { - SetError(YasslError(err)); - return; - } - ++first; - } -} - - -// store pending security parameters from Server Hello -void SSL::set_pending(Cipher suite) -{ - Parameters& parms = secure_.use_parms(); - - switch (suite) { - - case TLS_RSA_WITH_AES_256_CBC_SHA: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = sha; - parms.kea_ = rsa_kea; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = AES_256_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ)); - strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_256_CBC_SHA], - MAX_SUITE_NAME); - break; - - case TLS_RSA_WITH_AES_128_CBC_SHA: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = sha; - parms.kea_ = rsa_kea; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = AES_128_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS AES); - strncpy(parms.cipher_name_, cipher_names[TLS_RSA_WITH_AES_128_CBC_SHA], - MAX_SUITE_NAME); - break; - - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - parms.bulk_cipher_algorithm_ = triple_des; - parms.mac_algorithm_ = sha; - parms.kea_ = rsa_kea; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = DES_EDE_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS DES_EDE); - strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_3DES_EDE_CBC_SHA] - , MAX_SUITE_NAME); - break; - - case SSL_RSA_WITH_DES_CBC_SHA: - parms.bulk_cipher_algorithm_ = des; - parms.mac_algorithm_ = sha; - parms.kea_ = rsa_kea; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = DES_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS DES); - strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_DES_CBC_SHA], - MAX_SUITE_NAME); - break; - - case SSL_RSA_WITH_RC4_128_SHA: - parms.bulk_cipher_algorithm_ = rc4; - parms.mac_algorithm_ = sha; - parms.kea_ = rsa_kea; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = RC4_KEY_SZ; - parms.iv_size_ = 0; - parms.cipher_type_ = stream; - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS RC4); - strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_RC4_128_SHA], - MAX_SUITE_NAME); - break; - - case SSL_RSA_WITH_RC4_128_MD5: - parms.bulk_cipher_algorithm_ = rc4; - parms.mac_algorithm_ = md5; - parms.kea_ = rsa_kea; - parms.hash_size_ = MD5_LEN; - parms.key_size_ = RC4_KEY_SZ; - parms.iv_size_ = 0; - parms.cipher_type_ = stream; - crypto_.setDigest(NEW_YS MD5); - crypto_.setCipher(NEW_YS RC4); - strncpy(parms.cipher_name_, cipher_names[SSL_RSA_WITH_RC4_128_MD5], - MAX_SUITE_NAME); - break; - - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - parms.bulk_cipher_algorithm_ = des; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = DES_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS DES); - strncpy(parms.cipher_name_, cipher_names[SSL_DHE_RSA_WITH_DES_CBC_SHA], - MAX_SUITE_NAME); - break; - - case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - parms.bulk_cipher_algorithm_ = triple_des; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = DES_EDE_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS DES_EDE); - strncpy(parms.cipher_name_, - cipher_names[SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA], MAX_SUITE_NAME); - break; - - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = AES_256_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ)); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_RSA_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME); - break; - - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = AES_128_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS AES); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_RSA_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME); - break; - - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - parms.bulk_cipher_algorithm_ = des; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = DES_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS DES); - strncpy(parms.cipher_name_, cipher_names[SSL_DHE_DSS_WITH_DES_CBC_SHA], - MAX_SUITE_NAME); - break; - - case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - parms.bulk_cipher_algorithm_ = triple_des; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = DES_EDE_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS DES_EDE); - strncpy(parms.cipher_name_, - cipher_names[SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA], MAX_SUITE_NAME); - break; - - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = AES_256_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ)); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_DSS_WITH_AES_256_CBC_SHA], MAX_SUITE_NAME); - break; - - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = sha; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = SHA_LEN; - parms.key_size_ = AES_128_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS SHA); - crypto_.setCipher(NEW_YS AES); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_DSS_WITH_AES_128_CBC_SHA], MAX_SUITE_NAME); - break; - - case TLS_RSA_WITH_AES_256_CBC_RMD160: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = rmd; - parms.kea_ = rsa_kea; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = AES_256_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ)); - strncpy(parms.cipher_name_, - cipher_names[TLS_RSA_WITH_AES_256_CBC_RMD160], MAX_SUITE_NAME); - break; - - case TLS_RSA_WITH_AES_128_CBC_RMD160: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = rmd; - parms.kea_ = rsa_kea; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = AES_128_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS AES); - strncpy(parms.cipher_name_, - cipher_names[TLS_RSA_WITH_AES_128_CBC_RMD160], MAX_SUITE_NAME); - break; - - case TLS_RSA_WITH_3DES_EDE_CBC_RMD160: - parms.bulk_cipher_algorithm_ = triple_des; - parms.mac_algorithm_ = rmd; - parms.kea_ = rsa_kea; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = DES_EDE_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS DES_EDE); - strncpy(parms.cipher_name_, - cipher_names[TLS_RSA_WITH_3DES_EDE_CBC_RMD160], MAX_SUITE_NAME); - break; - - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160: - parms.bulk_cipher_algorithm_ = triple_des; - parms.mac_algorithm_ = rmd; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = DES_EDE_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS DES_EDE); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160], - MAX_SUITE_NAME); - break; - - case TLS_DHE_RSA_WITH_AES_256_CBC_RMD160: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = rmd; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = AES_256_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ)); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_RSA_WITH_AES_256_CBC_RMD160], - MAX_SUITE_NAME); - break; - - case TLS_DHE_RSA_WITH_AES_128_CBC_RMD160: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = rmd; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = rsa_sa_algo; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = AES_128_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS AES); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_RSA_WITH_AES_128_CBC_RMD160], - MAX_SUITE_NAME); - break; - - case TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160: - parms.bulk_cipher_algorithm_ = triple_des; - parms.mac_algorithm_ = rmd; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = DES_EDE_KEY_SZ; - parms.iv_size_ = DES_IV_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS DES_EDE); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160], - MAX_SUITE_NAME); - break; - - case TLS_DHE_DSS_WITH_AES_256_CBC_RMD160: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = rmd; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = AES_256_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS AES(AES_256_KEY_SZ)); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_DSS_WITH_AES_256_CBC_RMD160], - MAX_SUITE_NAME); - break; - - case TLS_DHE_DSS_WITH_AES_128_CBC_RMD160: - parms.bulk_cipher_algorithm_ = aes; - parms.mac_algorithm_ = rmd; - parms.kea_ = diffie_hellman_kea; - parms.sig_algo_ = dsa_sa_algo; - parms.hash_size_ = RMD_LEN; - parms.key_size_ = AES_128_KEY_SZ; - parms.iv_size_ = AES_BLOCK_SZ; - parms.cipher_type_ = block; - secure_.use_connection().send_server_key_ = true; // eph - crypto_.setDigest(NEW_YS RMD); - crypto_.setCipher(NEW_YS AES); - strncpy(parms.cipher_name_, - cipher_names[TLS_DHE_DSS_WITH_AES_128_CBC_RMD160], - MAX_SUITE_NAME); - break; - - default: - SetError(unknown_cipher); - } -} - - -// store peer's random -void SSL::set_random(const opaque* random, ConnectionEnd sender) -{ - if (sender == client_end) - memcpy(secure_.use_connection().client_random_, random, RAN_LEN); - else - memcpy(secure_.use_connection().server_random_, random, RAN_LEN); -} - - -// store client pre master secret -void SSL::set_preMaster(const opaque* pre, uint sz) -{ - uint i(0); // trim leading zeros - uint fullSz(sz); - - while (i++ < fullSz && *pre == 0) { - sz--; - pre++; - } - - if (sz == 0) { - SetError(bad_input); - return; - } - - secure_.use_connection().AllocPreSecret(sz); - memcpy(secure_.use_connection().pre_master_secret_, pre, sz); -} - - -// set yaSSL zlib type compression -int SSL::SetCompression() -{ -#ifdef HAVE_LIBZ - secure_.use_connection().compression_ = true; - return 0; -#else - return -1; // not built in -#endif -} - - -// unset yaSSL zlib type compression -void SSL::UnSetCompression() -{ - secure_.use_connection().compression_ = false; -} - - -// is yaSSL zlib compression on -bool SSL::CompressionOn() const -{ - return secure_.get_connection().compression_; -} - - -// store master secret -void SSL::set_masterSecret(const opaque* sec) -{ - memcpy(secure_.use_connection().master_secret_, sec, SECRET_LEN); -} - -// store server issued id -void SSL::set_sessionID(const opaque* sessionID) -{ - memcpy(secure_.use_connection().sessionID_, sessionID, ID_LEN); - secure_.use_connection().sessionID_Set_ = true; -} - - -// store error -void SSL::SetError(YasslError ye) -{ - states_.SetError(ye); - //strncpy(states_.useString(), e.what(), mySTL::named_exception::NAME_SIZE); - // TODO: add string here -} - - -// set the quiet shutdown mode (close_nofiy not sent or received on shutdown) -void SSL::SetQuietShutdown(bool mode) -{ - quietShutdown_ = mode; -} - - -Buffers& SSL::useBuffers() -{ - return buffers_; -} - - -// locals -namespace { - -// DeriveKeys and MasterSecret helper sets prefix letters -static bool setPrefix(opaque* sha_input, int i) -{ - switch (i) { - case 0: - memcpy(sha_input, "A", 1); - break; - case 1: - memcpy(sha_input, "BB", 2); - break; - case 2: - memcpy(sha_input, "CCC", 3); - break; - case 3: - memcpy(sha_input, "DDDD", 4); - break; - case 4: - memcpy(sha_input, "EEEEE", 5); - break; - case 5: - memcpy(sha_input, "FFFFFF", 6); - break; - case 6: - memcpy(sha_input, "GGGGGGG", 7); - break; - default: - return false; // prefix_error - } - return true; -} - -} // namespcae for locals - - -void SSL::order_error() -{ - SetError(out_of_order); -} - - -// Create and store the master secret see page 32, 6.1 -void SSL::makeMasterSecret() -{ - if (GetError()) return; - - if (isTLS()) - makeTLSMasterSecret(); - else { - opaque sha_output[SHA_LEN]; - - const uint& preSz = secure_.get_connection().pre_secret_len_; - output_buffer md5_input(preSz + SHA_LEN); - output_buffer sha_input(PREFIX + preSz + 2 * RAN_LEN); - - MD5 md5; - SHA sha; - - md5_input.write(secure_.get_connection().pre_master_secret_, preSz); - - for (int i = 0; i < MASTER_ROUNDS; ++i) { - opaque prefix[PREFIX]; - if (!setPrefix(prefix, i)) { - SetError(prefix_error); - return; - } - - sha_input.set_current(0); - sha_input.write(prefix, i + 1); - - sha_input.write(secure_.get_connection().pre_master_secret_,preSz); - sha_input.write(secure_.get_connection().client_random_, RAN_LEN); - sha_input.write(secure_.get_connection().server_random_, RAN_LEN); - sha.get_digest(sha_output, sha_input.get_buffer(), - sha_input.get_size()); - - md5_input.set_current(preSz); - md5_input.write(sha_output, SHA_LEN); - md5.get_digest(&secure_.use_connection().master_secret_[i*MD5_LEN], - md5_input.get_buffer(), md5_input.get_size()); - } - deriveKeys(); - } - secure_.use_connection().CleanPreMaster(); -} - - -// create TLSv1 master secret -void SSL::makeTLSMasterSecret() -{ - opaque seed[SEED_LEN]; - - memcpy(seed, secure_.get_connection().client_random_, RAN_LEN); - memcpy(&seed[RAN_LEN], secure_.get_connection().server_random_, RAN_LEN); - - PRF(secure_.use_connection().master_secret_, SECRET_LEN, - secure_.get_connection().pre_master_secret_, - secure_.get_connection().pre_secret_len_, - master_label, MASTER_LABEL_SZ, - seed, SEED_LEN); - - deriveTLSKeys(); -} - - -// derive mac, write, and iv keys for server and client, see page 34, 6.2.2 -void SSL::deriveKeys() -{ - int length = 2 * secure_.get_parms().hash_size_ + - 2 * secure_.get_parms().key_size_ + - 2 * secure_.get_parms().iv_size_; - int rounds = (length + MD5_LEN - 1 ) / MD5_LEN; - input_buffer key_data(rounds * MD5_LEN); - - opaque sha_output[SHA_LEN]; - opaque md5_input[SECRET_LEN + SHA_LEN]; - opaque sha_input[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN]; - - MD5 md5; - SHA sha; - - memcpy(md5_input, secure_.get_connection().master_secret_, SECRET_LEN); - - for (int i = 0; i < rounds; ++i) { - int j = i + 1; - if (!setPrefix(sha_input, i)) { - SetError(prefix_error); - return; - } - - memcpy(&sha_input[j], secure_.get_connection().master_secret_, - SECRET_LEN); - memcpy(&sha_input[j+SECRET_LEN], - secure_.get_connection().server_random_, RAN_LEN); - memcpy(&sha_input[j + SECRET_LEN + RAN_LEN], - secure_.get_connection().client_random_, RAN_LEN); - sha.get_digest(sha_output, sha_input, - sizeof(sha_input) - KEY_PREFIX + j); - - memcpy(&md5_input[SECRET_LEN], sha_output, SHA_LEN); - md5.get_digest(key_data.get_buffer() + i * MD5_LEN, - md5_input, sizeof(md5_input)); - } - storeKeys(key_data.get_buffer()); -} - - -// derive mac, write, and iv keys for server and client -void SSL::deriveTLSKeys() -{ - int length = 2 * secure_.get_parms().hash_size_ + - 2 * secure_.get_parms().key_size_ + - 2 * secure_.get_parms().iv_size_; - opaque seed[SEED_LEN]; - input_buffer key_data(length); - - memcpy(seed, secure_.get_connection().server_random_, RAN_LEN); - memcpy(&seed[RAN_LEN], secure_.get_connection().client_random_, RAN_LEN); - - PRF(key_data.get_buffer(), length, secure_.get_connection().master_secret_, - SECRET_LEN, key_label, KEY_LABEL_SZ, seed, SEED_LEN); - - storeKeys(key_data.get_buffer()); -} - - -// store mac, write, and iv keys for client and server -void SSL::storeKeys(const opaque* key_data) -{ - int sz = secure_.get_parms().hash_size_; - memcpy(secure_.use_connection().client_write_MAC_secret_, key_data, sz); - int i = sz; - memcpy(secure_.use_connection().server_write_MAC_secret_,&key_data[i], sz); - i += sz; - - sz = secure_.get_parms().key_size_; - memcpy(secure_.use_connection().client_write_key_, &key_data[i], sz); - i += sz; - memcpy(secure_.use_connection().server_write_key_, &key_data[i], sz); - i += sz; - - sz = secure_.get_parms().iv_size_; - memcpy(secure_.use_connection().client_write_IV_, &key_data[i], sz); - i += sz; - memcpy(secure_.use_connection().server_write_IV_, &key_data[i], sz); - - setKeys(); -} - - -// set encrypt/decrypt keys and ivs -void SSL::setKeys() -{ - Connection& conn = secure_.use_connection(); - - if (secure_.get_parms().entity_ == client_end) { - crypto_.use_cipher().set_encryptKey(conn.client_write_key_, - conn.client_write_IV_); - crypto_.use_cipher().set_decryptKey(conn.server_write_key_, - conn.server_write_IV_); - } - else { - crypto_.use_cipher().set_encryptKey(conn.server_write_key_, - conn.server_write_IV_); - crypto_.use_cipher().set_decryptKey(conn.client_write_key_, - conn.client_write_IV_); - } -} - - - -// local functors -namespace yassl_int_cpp_local1 { // for explicit templates - -struct SumData { - uint total_; - SumData() : total_(0) {} - void operator()(input_buffer* data) { total_ += data->get_remaining(); } -}; - - -struct SumBuffer { - uint total_; - SumBuffer() : total_(0) {} - void operator()(output_buffer* buffer) { total_ += buffer->get_size(); } -}; - -} // namespace for locals -using namespace yassl_int_cpp_local1; - - -uint SSL::bufferedData() -{ - return STL::for_each(buffers_.getData().begin(),buffers_.getData().end(), - SumData()).total_; -} - - -// use input buffer to fill data -void SSL::fillData(Data& data) -{ - if (GetError()) return; - uint dataSz = data.get_length(); // input, data size to fill - size_t elements = buffers_.getData().size(); - - data.set_length(0); // output, actual data filled - dataSz = min(dataSz, bufferedData()); - - for (size_t i = 0; i < elements; i++) { - input_buffer* front = buffers_.getData().front(); - uint frontSz = front->get_remaining(); - uint readSz = min(dataSz - data.get_length(), frontSz); - - front->read(data.set_buffer() + data.get_length(), readSz); - data.set_length(data.get_length() + readSz); - - if (readSz == frontSz) { - buffers_.useData().pop_front(); - ysDelete(front); - } - if (data.get_length() == dataSz) - break; - } - - if (buffers_.getData().size() == 0) has_data_ = false; // none left -} - - -// like Fill but keep data in buffer -void SSL::PeekData(Data& data) -{ - if (GetError()) return; - uint dataSz = data.get_length(); // input, data size to fill - size_t elements = buffers_.getData().size(); - - data.set_length(0); // output, actual data filled - dataSz = min(dataSz, bufferedData()); - - Buffers::inputList::iterator front = buffers_.useData().begin(); - - while (elements) { - uint frontSz = (*front)->get_remaining(); - uint readSz = min(dataSz - data.get_length(), frontSz); - uint before = (*front)->get_current(); - - (*front)->read(data.set_buffer() + data.get_length(), readSz); - data.set_length(data.get_length() + readSz); - (*front)->set_current(before); - - if (data.get_length() == dataSz) - break; - - elements--; - front++; - } -} - - -// flush output buffer -void SSL::flushBuffer() -{ - if (GetError()) return; - - uint sz = STL::for_each(buffers_.getHandShake().begin(), - buffers_.getHandShake().end(), - SumBuffer()).total_; - output_buffer out(sz); - size_t elements = buffers_.getHandShake().size(); - - for (size_t i = 0; i < elements; i++) { - output_buffer* front = buffers_.getHandShake().front(); - out.write(front->get_buffer(), front->get_size()); - - buffers_.useHandShake().pop_front(); - ysDelete(front); - } - Send(out.get_buffer(), out.get_size()); -} - - -void SSL::Send(const byte* buffer, uint sz) -{ - unsigned int sent = 0; - - if (socket_.send(buffer, sz, sent) != sz) { - if (socket_.WouldBlock()) { - buffers_.SetOutput(NEW_YS output_buffer(sz - sent, buffer + sent, - sz - sent)); - SetError(YasslError(SSL_ERROR_WANT_WRITE)); - } - else - SetError(send_error); - } -} - - -void SSL::SendWriteBuffered() -{ - output_buffer* out = buffers_.TakeOutput(); - - if (out) { - mySTL::auto_ptr<output_buffer> tmp(out); - Send(out->get_buffer(), out->get_size()); - } -} - - -// get sequence number, if verify get peer's -uint SSL::get_SEQIncrement(bool verify) -{ - if (verify) - return secure_.use_connection().peer_sequence_number_++; - else - return secure_.use_connection().sequence_number_++; -} - - -const byte* SSL::get_macSecret(bool verify) -{ - if ( (secure_.get_parms().entity_ == client_end && !verify) || - (secure_.get_parms().entity_ == server_end && verify) ) - return secure_.get_connection().client_write_MAC_secret_; - else - return secure_.get_connection().server_write_MAC_secret_; -} - - -void SSL::verifyState(const RecordLayerHeader& rlHeader) -{ - if (GetError()) return; - - if (rlHeader.version_.major_ != 3 || rlHeader.version_.minor_ > 2) { - SetError(badVersion_error); - return; - } - - if (states_.getRecord() == recordNotReady || - (rlHeader.type_ == application_data && // data and handshake - states_.getHandShake() != handShakeReady) ) // isn't complete yet - SetError(record_layer); -} - - -void SSL::verifyState(const HandShakeHeader& hsHeader) -{ - if (GetError()) return; - - if (states_.getHandShake() == handShakeNotReady) { - SetError(handshake_layer); - return; - } - - if (states_.SetMessageRecvd(hsHeader.get_handshakeType()) != 0) { - order_error(); - return; - } - - if (secure_.get_parms().entity_ == client_end) - verifyClientState(hsHeader.get_handshakeType()); - else - verifyServerState(hsHeader.get_handshakeType()); -} - - -void SSL::verifyState(ClientState cs) -{ - if (GetError()) return; - if (states_.getClient() != cs) order_error(); -} - - -void SSL::verifyState(ServerState ss) -{ - if (GetError()) return; - if (states_.getServer() != ss) order_error(); -} - - -void SSL::verfiyHandShakeComplete() -{ - if (GetError()) return; - if (states_.getHandShake() != handShakeReady) order_error(); -} - - -void SSL::verifyClientState(HandShakeType hsType) -{ - if (GetError()) return; - - switch(hsType) { - case server_hello : - if (states_.getClient() != serverNull) - order_error(); - break; - case certificate : - if (states_.getClient() != serverHelloComplete) - order_error(); - break; - case server_key_exchange : - if (states_.getClient() != serverCertComplete) - order_error(); - break; - case certificate_request : - if (states_.getClient() != serverCertComplete && - states_.getClient() != serverKeyExchangeComplete) - order_error(); - break; - case server_hello_done : - if (states_.getClient() != serverCertComplete && - states_.getClient() != serverKeyExchangeComplete) - order_error(); - break; - case finished : - if (states_.getClient() != serverHelloDoneComplete || - secure_.get_parms().pending_) // no change - order_error(); // cipher yet - break; - default : - order_error(); - }; -} - - -void SSL::verifyServerState(HandShakeType hsType) -{ - if (GetError()) return; - - switch(hsType) { - case client_hello : - if (states_.getServer() != clientNull) - order_error(); - break; - case certificate : - if (states_.getServer() != clientHelloComplete) - order_error(); - break; - case client_key_exchange : - if (states_.getServer() != clientHelloComplete) - order_error(); - break; - case certificate_verify : - if (states_.getServer() != clientKeyExchangeComplete) - order_error(); - break; - case finished : - if (states_.getServer() != clientKeyExchangeComplete || - secure_.get_parms().pending_) // no change - order_error(); // cipher yet - break; - default : - order_error(); - }; -} - - -// try to find a suite match -void SSL::matchSuite(const opaque* peer, uint length) -{ - if (length == 0 || (length % 2) != 0) { - SetError(bad_input); - return; - } - - // start with best, if a match we are good, Ciphers are at odd index - // since all SSL and TLS ciphers have 0x00 first byte - for (uint i = 1; i < secure_.get_parms().suites_size_; i += 2) - for (uint j = 0; (j + 1) < length; j+= 2) { - if (peer[j] != 0x00) { - continue; // only 0x00 first byte supported - } - - if (secure_.use_parms().suites_[i] == peer[j + 1]) { - secure_.use_parms().suite_[0] = 0x00; - secure_.use_parms().suite_[1] = peer[j + 1]; - return; - } - } - - SetError(match_error); -} - - -void SSL::set_session(SSL_SESSION* s) -{ - if (getSecurity().GetContext()->GetSessionCacheOff()) - return; - - if (s && GetSessions().lookup(s->GetID(), &secure_.use_resume())) { - secure_.set_resuming(true); - crypto_.use_certManager().setPeerX509(s->GetPeerX509()); - } -} - - -const Crypto& SSL::getCrypto() const -{ - return crypto_; -} - - -const Security& SSL::getSecurity() const -{ - return secure_; -} - - -const States& SSL::getStates() const -{ - return states_; -} - - -const sslHashes& SSL::getHashes() const -{ - return hashes_; -} - - -const sslFactory& SSL::getFactory() const -{ - return GetSSL_Factory(); -} - - -const Socket& SSL::getSocket() const -{ - return socket_; -} - - -YasslError SSL::GetError() const -{ - return states_.What(); -} - - -bool SSL::GetQuietShutdown() const -{ - return quietShutdown_; -} - - -bool SSL::GetMultiProtocol() const -{ - return secure_.GetContext()->getMethod()->multipleProtocol(); -} - - -Crypto& SSL::useCrypto() -{ - return crypto_; -} - - -Security& SSL::useSecurity() -{ - return secure_; -} - - -States& SSL::useStates() -{ - return states_; -} - - -sslHashes& SSL::useHashes() -{ - return hashes_; -} - - -Socket& SSL::useSocket() -{ - return socket_; -} - - -Log& SSL::useLog() -{ - return log_; -} - - -bool SSL::isTLS() const -{ - return secure_.get_connection().TLS_; -} - - -bool SSL::isTLSv1_1() const -{ - return secure_.get_connection().TLSv1_1_; -} - - -// is there buffered data available, optimization to remove iteration on buffer -bool SSL::HasData() const -{ - return has_data_; -} - - -void SSL::addData(input_buffer* data) -{ - buffers_.useData().push_back(data); - if (!has_data_) has_data_ = true; -} - - -void SSL::addBuffer(output_buffer* b) -{ - buffers_.useHandShake().push_back(b); -} - - -void SSL_SESSION::CopyX509(X509* x) -{ - if (x == 0) return; - - X509_NAME* issuer = x->GetIssuer(); - X509_NAME* subject = x->GetSubject(); - ASN1_TIME* before = x->GetBefore(); - ASN1_TIME* after = x->GetAfter(); - - peerX509_ = NEW_YS X509(issuer->GetName(), issuer->GetLength(), - subject->GetName(), subject->GetLength(), before, after, - issuer->GetCnPosition(), issuer->GetCnLength(), - subject->GetCnPosition(), subject->GetCnLength()); -} - - -// store connection parameters -SSL_SESSION::SSL_SESSION(const SSL& ssl, RandomPool& ran) - : timeout_(DEFAULT_TIMEOUT), random_(ran), peerX509_(0) -{ - const Connection& conn = ssl.getSecurity().get_connection(); - - memcpy(sessionID_, conn.sessionID_, ID_LEN); - memcpy(master_secret_, conn.master_secret_, SECRET_LEN); - memcpy(suite_, ssl.getSecurity().get_parms().suite_, SUITE_LEN); - - bornOn_ = lowResTimer(); - - CopyX509(ssl.getCrypto().get_certManager().get_peerX509()); -} - - -// for resumption copy in ssl::parameters -SSL_SESSION::SSL_SESSION(RandomPool& ran) - : bornOn_(0), timeout_(0), random_(ran), peerX509_(0) -{ - memset(sessionID_, 0, ID_LEN); - memset(master_secret_, 0, SECRET_LEN); - memset(suite_, 0, SUITE_LEN); -} - - -SSL_SESSION& SSL_SESSION::operator=(const SSL_SESSION& that) -{ - memcpy(sessionID_, that.sessionID_, ID_LEN); - memcpy(master_secret_, that.master_secret_, SECRET_LEN); - memcpy(suite_, that.suite_, SUITE_LEN); - - bornOn_ = that.bornOn_; - timeout_ = that.timeout_; - - if (peerX509_) { - ysDelete(peerX509_); - peerX509_ = 0; - } - CopyX509(that.peerX509_); - - return *this; -} - - -const opaque* SSL_SESSION::GetID() const -{ - return sessionID_; -} - - -const opaque* SSL_SESSION::GetSecret() const -{ - return master_secret_; -} - - -const Cipher* SSL_SESSION::GetSuite() const -{ - return suite_; -} - - -X509* SSL_SESSION::GetPeerX509() const -{ - return peerX509_; -} - - -uint SSL_SESSION::GetBornOn() const -{ - return bornOn_; -} - - -uint SSL_SESSION::GetTimeOut() const -{ - return timeout_; -} - - -void SSL_SESSION::SetTimeOut(uint t) -{ - timeout_ = t; -} - - -extern void clean(volatile opaque*, uint, RandomPool&); - - -// clean up secret data -SSL_SESSION::~SSL_SESSION() -{ - volatile opaque* p = master_secret_; - clean(p, SECRET_LEN, random_); - - ysDelete(peerX509_); -} - - -static Sessions* sessionsInstance = 0; - -Sessions& GetSessions() -{ - if (!sessionsInstance) - sessionsInstance = NEW_YS Sessions; - return *sessionsInstance; -} - - -static sslFactory* sslFactoryInstance = 0; - -sslFactory& GetSSL_Factory() -{ - if (!sslFactoryInstance) - sslFactoryInstance = NEW_YS sslFactory; - return *sslFactoryInstance; -} - - -static Errors* errorsInstance = 0; - -Errors& GetErrors() -{ - if (!errorsInstance) - errorsInstance = NEW_YS Errors; - return *errorsInstance; -} - -bool HasErrors() -{ - return (errorsInstance != 0); -} - - -typedef Mutex::Lock Lock; - - - -void Sessions::add(const SSL& ssl) -{ - if (ssl.getSecurity().get_connection().sessionID_Set_) { - Lock guard(mutex_); - list_.push_back(NEW_YS SSL_SESSION(ssl, random_)); - count_++; - } - - if (count_ > SESSION_FLUSH_COUNT) - if (!ssl.getSecurity().GetContext()->GetSessionCacheFlushOff()) - Flush(); -} - - -Sessions::~Sessions() -{ - STL::for_each(list_.begin(), list_.end(), del_ptr_zero()); -} - - -// locals -namespace yassl_int_cpp_local2 { // for explicit templates - -typedef STL::list<SSL_SESSION*>::iterator sess_iterator; -typedef STL::list<ThreadError>::iterator thr_iterator; - -struct sess_match { - const opaque* id_; - explicit sess_match(const opaque* p) : id_(p) {} - - bool operator()(SSL_SESSION* sess) - { - if ( memcmp(sess->GetID(), id_, ID_LEN) == 0) - return true; - return false; - } -}; - - -THREAD_ID_T GetSelf() -{ -#ifndef _POSIX_THREADS - return GetCurrentThreadId(); -#else - return pthread_self(); -#endif -} - -struct thr_match { - THREAD_ID_T id_; - explicit thr_match() : id_(GetSelf()) {} - - bool operator()(ThreadError thr) - { - if (thr.threadID_ == id_) - return true; - return false; - } -}; - - -} // local namespace -using namespace yassl_int_cpp_local2; - - -// lookup session by id, return a copy if space provided -SSL_SESSION* Sessions::lookup(const opaque* id, SSL_SESSION* copy) -{ - Lock guard(mutex_); - sess_iterator find = STL::find_if(list_.begin(), list_.end(), - sess_match(id)); - if (find != list_.end()) { - uint current = lowResTimer(); - if ( ((*find)->GetBornOn() + (*find)->GetTimeOut()) < current) { - del_ptr_zero()(*find); - list_.erase(find); - return 0; - } - if (copy) - *copy = *(*find); - return *find; - } - return 0; -} - - -// remove a session by id -void Sessions::remove(const opaque* id) -{ - Lock guard(mutex_); - sess_iterator find = STL::find_if(list_.begin(), list_.end(), - sess_match(id)); - if (find != list_.end()) { - del_ptr_zero()(*find); - list_.erase(find); - } -} - - -// flush expired sessions from cache -void Sessions::Flush() -{ - Lock guard(mutex_); - sess_iterator next = list_.begin(); - uint current = lowResTimer(); - - while (next != list_.end()) { - sess_iterator si = next; - ++next; - if ( ((*si)->GetBornOn() + (*si)->GetTimeOut()) < current) { - del_ptr_zero()(*si); - list_.erase(si); - } - } - count_ = 0; // reset flush counter -} - - -// remove a self thread error -void Errors::Remove() -{ - Lock guard(mutex_); - thr_iterator find = STL::find_if(list_.begin(), list_.end(), - thr_match()); - if (find != list_.end()) - list_.erase(find); -} - - -// lookup self error code -int Errors::Lookup(bool peek) -{ - Lock guard(mutex_); - thr_iterator find = STL::find_if(list_.begin(), list_.end(), - thr_match()); - if (find != list_.end()) { - int ret = find->errorID_; - if (!peek) - list_.erase(find); - return ret; - } - else - return 0; -} - - -// add a new error code for self -void Errors::Add(int error) -{ - ThreadError add; - add.errorID_ = error; - add.threadID_ = GetSelf(); - - Remove(); // may have old error - - Lock guard(mutex_); - list_.push_back(add); -} - - -SSL_METHOD::SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv, bool multiProto) - : version_(pv), side_(ce), verifyPeer_(false), verifyNone_(false), - failNoCert_(false), multipleProtocol_(multiProto) -{} - - -ProtocolVersion SSL_METHOD::getVersion() const -{ - return version_; -} - - -ConnectionEnd SSL_METHOD::getSide() const -{ - return side_; -} - - -void SSL_METHOD::setVerifyPeer() -{ - verifyPeer_ = true; -} - - -void SSL_METHOD::setVerifyNone() -{ - verifyNone_ = true; -} - - -void SSL_METHOD::setFailNoCert() -{ - failNoCert_ = true; -} - - -bool SSL_METHOD::verifyPeer() const -{ - return verifyPeer_; -} - - -bool SSL_METHOD::verifyNone() const -{ - return verifyNone_; -} - - -bool SSL_METHOD::failNoCert() const -{ - return failNoCert_; -} - - -bool SSL_METHOD::multipleProtocol() const -{ - return multipleProtocol_; -} - - -SSL_CTX::SSL_CTX(SSL_METHOD* meth) - : method_(meth), certificate_(0), privateKey_(0), passwordCb_(0), - userData_(0), sessionCacheOff_(false), sessionCacheFlushOff_(false), - verifyCallback_(0) -{} - - -SSL_CTX::~SSL_CTX() -{ - ysDelete(method_); - ysDelete(certificate_); - ysDelete(privateKey_); - - STL::for_each(caList_.begin(), caList_.end(), del_ptr_zero()); -} - - -void SSL_CTX::AddCA(x509* ca) -{ - caList_.push_back(ca); -} - - -const SSL_CTX::CertList& -SSL_CTX::GetCA_List() const -{ - return caList_; -} - - -VerifyCallback SSL_CTX::getVerifyCallback() const -{ - return verifyCallback_; -} - - -const x509* SSL_CTX::getCert() const -{ - return certificate_; -} - - -const x509* SSL_CTX::getKey() const -{ - return privateKey_; -} - - -const SSL_METHOD* SSL_CTX::getMethod() const -{ - return method_; -} - - -const Ciphers& SSL_CTX::GetCiphers() const -{ - return ciphers_; -} - - -const DH_Parms& SSL_CTX::GetDH_Parms() const -{ - return dhParms_; -} - - -const Stats& SSL_CTX::GetStats() const -{ - return stats_; -} - - -pem_password_cb SSL_CTX::GetPasswordCb() const -{ - return passwordCb_; -} - - -void SSL_CTX::SetPasswordCb(pem_password_cb cb) -{ - passwordCb_ = cb; -} - - -void* SSL_CTX::GetUserData() const -{ - return userData_; -} - - -bool SSL_CTX::GetSessionCacheOff() const -{ - return sessionCacheOff_; -} - - -bool SSL_CTX::GetSessionCacheFlushOff() const -{ - return sessionCacheFlushOff_; -} - - -void SSL_CTX::SetUserData(void* data) -{ - userData_ = data; -} - - -void SSL_CTX::SetSessionCacheOff() -{ - sessionCacheOff_ = true; -} - - -void SSL_CTX::SetSessionCacheFlushOff() -{ - sessionCacheFlushOff_ = true; -} - - -void SSL_CTX::setVerifyPeer() -{ - method_->setVerifyPeer(); -} - - -void SSL_CTX::setVerifyNone() -{ - method_->setVerifyNone(); -} - - -void SSL_CTX::setFailNoCert() -{ - method_->setFailNoCert(); -} - - -void SSL_CTX::setVerifyCallback(VerifyCallback vc) -{ - verifyCallback_ = vc; -} - - -bool SSL_CTX::SetDH(const DH& dh) -{ - dhParms_.p_ = dh.p->int_; - dhParms_.g_ = dh.g->int_; - - return dhParms_.set_ = true; -} - - -bool SSL_CTX::SetCipherList(const char* list) -{ - if (!list) - return false; - - bool ret = false; - char name[MAX_SUITE_NAME]; - - char needle[] = ":"; - char* haystack = const_cast<char*>(list); - char* prev; - - const int suiteSz = sizeof(cipher_names) / sizeof(cipher_names[0]); - int idx = 0; - - for(;;) { - size_t len; - prev = haystack; - haystack = strstr(haystack, needle); - - if (!haystack) // last cipher - len = min(sizeof(name), strlen(prev)); - else - len = min(sizeof(name), (size_t)(haystack - prev)); - - strncpy(name, prev, len); - name[(len == sizeof(name)) ? len - 1 : len] = 0; - - for (int i = 0; i < suiteSz; i++) - if (strncmp(name, cipher_names[i], sizeof(name)) == 0) { - - ciphers_.suites_[idx++] = 0x00; // first byte always zero - ciphers_.suites_[idx++] = i; - - if (!ret) ret = true; // found at least one - break; - } - if (!haystack) break; - haystack++; - } - - if (ret) { - ciphers_.setSuites_ = true; - ciphers_.suiteSz_ = idx; - } - - return ret; -} - - -void SSL_CTX::IncrementStats(StatsField fd) -{ - - Lock guard(mutex_); - - switch (fd) { - - case Accept: - ++stats_.accept_; - break; - - case Connect: - ++stats_.connect_; - break; - - case AcceptGood: - ++stats_.acceptGood_; - break; - - case ConnectGood: - ++stats_.connectGood_; - break; - - case AcceptRenegotiate: - ++stats_.acceptRenegotiate_; - break; - - case ConnectRenegotiate: - ++stats_.connectRenegotiate_; - break; - - case Hits: - ++stats_.hits_; - break; - - case CbHits: - ++stats_.cbHits_; - break; - - case CacheFull: - ++stats_.cacheFull_; - break; - - case Misses: - ++stats_.misses_; - break; - - case Timeouts: - ++stats_.timeouts_; - break; - - case Number: - ++stats_.number_; - break; - - case GetCacheSize: - ++stats_.getCacheSize_; - break; - - case VerifyMode: - ++stats_.verifyMode_; - break; - - case VerifyDepth: - ++stats_.verifyDepth_; - break; - - default: - break; - } -} - - -Crypto::Crypto() - : digest_(0), cipher_(0), dh_(0) -{} - - -Crypto::~Crypto() -{ - ysDelete(dh_); - ysDelete(cipher_); - ysDelete(digest_); -} - - -const Digest& Crypto::get_digest() const -{ - return *digest_; -} - - -const BulkCipher& Crypto::get_cipher() const -{ - return *cipher_; -} - - -const DiffieHellman& Crypto::get_dh() const -{ - return *dh_; -} - - -const RandomPool& Crypto::get_random() const -{ - return random_; -} - - -const CertManager& Crypto::get_certManager() const -{ - return cert_; -} - - - -Digest& Crypto::use_digest() -{ - return *digest_; -} - - -BulkCipher& Crypto::use_cipher() -{ - return *cipher_; -} - - -DiffieHellman& Crypto::use_dh() -{ - return *dh_; -} - - -RandomPool& Crypto::use_random() -{ - return random_; -} - - -CertManager& Crypto::use_certManager() -{ - return cert_; -} - - - -void Crypto::SetDH(DiffieHellman* dh) -{ - dh_ = dh; -} - - -void Crypto::SetDH(const DH_Parms& dh) -{ - if (dh.set_) - dh_ = NEW_YS DiffieHellman(dh.p_, dh.g_, random_); -} - - -bool Crypto::DhSet() -{ - return dh_ != 0; -} - - -void Crypto::setDigest(Digest* digest) -{ - digest_ = digest; -} - - -void Crypto::setCipher(BulkCipher* c) -{ - cipher_ = c; -} - - -const MD5& sslHashes::get_MD5() const -{ - return md5HandShake_; -} - - -const SHA& sslHashes::get_SHA() const -{ - return shaHandShake_; -} - - -const Finished& sslHashes::get_verify() const -{ - return verify_; -} - - -const Hashes& sslHashes::get_certVerify() const -{ - return certVerify_; -} - - -MD5& sslHashes::use_MD5(){ - return md5HandShake_; -} - - -SHA& sslHashes::use_SHA() -{ - return shaHandShake_; -} - - -Finished& sslHashes::use_verify() -{ - return verify_; -} - - -Hashes& sslHashes::use_certVerify() -{ - return certVerify_; -} - - -Buffers::Buffers() : prevSent(0), plainSz(0), rawInput_(0), output_(0) -{} - - -Buffers::~Buffers() -{ - STL::for_each(handShakeList_.begin(), handShakeList_.end(), - del_ptr_zero()) ; - STL::for_each(dataList_.begin(), dataList_.end(), - del_ptr_zero()) ; - ysDelete(rawInput_); - ysDelete(output_); -} - - -void Buffers::SetOutput(output_buffer* ob) -{ - output_ = ob; -} - - -void Buffers::SetRawInput(input_buffer* ib) -{ - rawInput_ = ib; -} - - -input_buffer* Buffers::TakeRawInput() -{ - input_buffer* ret = rawInput_; - rawInput_ = 0; - - return ret; -} - - -output_buffer* Buffers::TakeOutput() -{ - output_buffer* ret = output_; - output_ = 0; - - return ret; -} - - -const Buffers::inputList& Buffers::getData() const -{ - return dataList_; -} - - -const Buffers::outputList& Buffers::getHandShake() const -{ - return handShakeList_; -} - - -Buffers::inputList& Buffers::useData() -{ - return dataList_; -} - - -Buffers::outputList& Buffers::useHandShake() -{ - return handShakeList_; -} - - -Security::Security(ProtocolVersion pv, RandomPool& ran, ConnectionEnd ce, - const Ciphers& ciphers, SSL_CTX* ctx, bool haveDH) - : conn_(pv, ran), parms_(ce, ciphers, pv, haveDH), resumeSession_(ran), - ctx_(ctx), resuming_(false) -{} - - -const Connection& Security::get_connection() const -{ - return conn_; -} - - -const SSL_CTX* Security::GetContext() const -{ - return ctx_; -} - - -const Parameters& Security::get_parms() const -{ - return parms_; -} - - -const SSL_SESSION& Security::get_resume() const -{ - return resumeSession_; -} - - -bool Security::get_resuming() const -{ - return resuming_; -} - - -Connection& Security::use_connection() -{ - return conn_; -} - - -Parameters& Security::use_parms() -{ - return parms_; -} - - -SSL_SESSION& Security::use_resume() -{ - return resumeSession_; -} - - -void Security::set_resuming(bool b) -{ - resuming_ = b; -} - - -X509_NAME::X509_NAME(const char* n, size_t sz, int pos, int len) - : name_(0), sz_(sz), cnPosition_(pos), cnLen_(len) -{ - if (sz) { - name_ = NEW_YS char[sz]; - memcpy(name_, n, sz); - } - entry_.data = 0; -} - - -X509_NAME::~X509_NAME() -{ - ysArrayDelete(name_); - ysArrayDelete(entry_.data); -} - - -const char* X509_NAME::GetName() const -{ - return name_; -} - - -size_t X509_NAME::GetLength() const -{ - return sz_; -} - - -X509::X509(const char* i, size_t iSz, const char* s, size_t sSz, - ASN1_STRING *b, ASN1_STRING *a, - int issPos, int issLen, - int subPos, int subLen) - : issuer_(i, iSz, issPos, issLen), subject_(s, sSz, subPos, subLen), - beforeDate_((char *) b->data, b->length, b->type), - afterDate_((char *) a->data, a->length, a->type) -{} - - -X509_NAME* X509::GetIssuer() -{ - return &issuer_; -} - - -X509_NAME* X509::GetSubject() -{ - return &subject_; -} - - -ASN1_TIME* X509::GetBefore() -{ - return beforeDate_.GetString(); -} - - -ASN1_TIME* X509::GetAfter() -{ - return afterDate_.GetString(); -} - - -ASN1_STRING* X509_NAME::GetEntry(int i) -{ - if (i < 0 || i >= int(sz_)) - return 0; - - if (i != cnPosition_ || cnLen_ <= 0) // only entry currently supported - return 0; - - if (cnLen_ > int(sz_-i)) // make sure there's room in read buffer - return 0; - - if (entry_.data) - ysArrayDelete(entry_.data); - entry_.data = NEW_YS byte[cnLen_+1]; // max size; - - memcpy(entry_.data, &name_[i], cnLen_); - entry_.data[cnLen_] = 0; - entry_.length = cnLen_; - entry_.type = 0; - - return &entry_; -} - - -StringHolder::StringHolder(const char* str, int sz, byte type) -{ - asnString_.length = sz; - asnString_.data = NEW_YS byte[sz + 1]; - memcpy(asnString_.data, str, sz); - asnString_.type = type; -} - - -StringHolder::~StringHolder() -{ - ysArrayDelete(asnString_.data); -} - - -ASN1_STRING* StringHolder::GetString() -{ - return &asnString_; -} - - -#ifdef HAVE_LIBZ - - void* myAlloc(void* /* opaque */, unsigned int item, unsigned int size) - { - return NEW_YS unsigned char[item * size]; - } - - - void myFree(void* /* opaque */, void* memory) - { - unsigned char* ptr = static_cast<unsigned char*>(memory); - yaSSL::ysArrayDelete(ptr); - } - - - // put size in front of compressed data - int Compress(const byte* in, int sz, input_buffer& buffer) - { - byte tmp[LENGTH_SZ]; - z_stream c_stream; /* compression stream */ - - buffer.allocate(sz + sizeof(uint16) + COMPRESS_EXTRA); - - c_stream.zalloc = myAlloc; - c_stream.zfree = myFree; - c_stream.opaque = (voidpf)0; - - c_stream.next_in = const_cast<byte*>(in); - c_stream.avail_in = sz; - c_stream.next_out = buffer.get_buffer() + sizeof(tmp); - c_stream.avail_out = buffer.get_capacity() - sizeof(tmp); - - if (deflateInit(&c_stream, 8) != Z_OK) return -1; - int err = deflate(&c_stream, Z_FINISH); - deflateEnd(&c_stream); - if (err != Z_OK && err != Z_STREAM_END) return -1; - - c16toa(sz, tmp); - memcpy(buffer.get_buffer(), tmp, sizeof(tmp)); - buffer.add_size(c_stream.total_out + sizeof(tmp)); - - return 0; - } - - - // get uncompressed size in front - int DeCompress(input_buffer& in, int sz, input_buffer& out) - { - byte tmp[LENGTH_SZ]; - - tmp[0] = in[AUTO]; - tmp[1] = in[AUTO]; - - uint16 len; - ato16(tmp, len); - - out.allocate(len); - - z_stream d_stream; /* decompression stream */ - - d_stream.zalloc = myAlloc; - d_stream.zfree = myFree; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = in.get_buffer() + in.get_current(); - d_stream.avail_in = sz - sizeof(tmp); - d_stream.next_out = out.get_buffer(); - d_stream.avail_out = out.get_capacity(); - - if (inflateInit(&d_stream) != Z_OK) return -1; - int err = inflate(&d_stream, Z_FINISH); - inflateEnd(&d_stream); - if (err != Z_OK && err != Z_STREAM_END) return -1; - - out.add_size(d_stream.total_out); - in.set_current(in.get_current() + sz - sizeof(tmp)); - - return 0; - } - - -#else // LIBZ - - // these versions should never get called - int Compress(const byte* in, int sz, input_buffer& buffer) - { - return -1; - } - - - int DeCompress(input_buffer& in, int sz, input_buffer& out) - { - return -1; - } - - -#endif // LIBZ - - -} // namespace - - - -extern "C" void yaSSL_CleanUp() -{ - TaoCrypt::CleanUp(); - yaSSL::ysDelete(yaSSL::sslFactoryInstance); - yaSSL::ysDelete(yaSSL::sessionsInstance); - yaSSL::ysDelete(yaSSL::errorsInstance); - - // In case user calls more than once, prevent seg fault - yaSSL::sslFactoryInstance = 0; - yaSSL::sessionsInstance = 0; - yaSSL::errorsInstance = 0; -} |