From 72e7f011b29998d8a3e15eb5b381ef962af5fe5b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 5 Apr 2019 10:30:58 +0300 Subject: Upgrade to 8.0.15 --- mysql/extra/yassl/src/yassl_int.cpp | 2826 ----------------------------------- 1 file changed, 2826 deletions(-) delete mode 100644 mysql/extra/yassl/src/yassl_int.cpp (limited to 'mysql/extra/yassl/src/yassl_int.cpp') diff --git a/mysql/extra/yassl/src/yassl_int.cpp b/mysql/extra/yassl/src/yassl_int.cpp deleted file mode 100644 index a39965c..0000000 --- a/mysql/extra/yassl/src/yassl_int.cpp +++ /dev/null @@ -1,2826 +0,0 @@ -/* Copyright (c) 2005, 2017, 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; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -/* yaSSL internal source implements SSL supporting types not specified in the - * draft along with type conversion functions. - */ - -// First include (the generated) my_config.h, to get correct platform defines. -#include "my_config.h" -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "runtime.hpp" -#include "yassl_int.hpp" -#include "handshake.hpp" -#include "timer.hpp" - -#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 - -/* for the definition of get_tty_password() */ -#include - -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_)) { - // remove RSA or DSA suites depending on cert key type - 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); - } -} - -#ifdef _WIN32 -typedef volatile LONG yassl_pthread_once_t; -#define YASSL_PTHREAD_ONCE_INIT 0 -#define YASSL_PTHREAD_ONCE_INPROGRESS 1 -#define YASSL_PTHREAD_ONCE_DONE 2 - -int yassl_pthread_once(yassl_pthread_once_t *once_control, - void (*init_routine)(void)) -{ - LONG state; - - /* - Do "dirty" read to find out if initialization is already done, to - save an interlocked operation in common case. Memory barriers are ensured by - Visual C++ volatile implementation. - */ - if (*once_control == YASSL_PTHREAD_ONCE_DONE) - return 0; - - state= InterlockedCompareExchange(once_control, YASSL_PTHREAD_ONCE_INPROGRESS, - YASSL_PTHREAD_ONCE_INIT); - - switch(state) - { - case YASSL_PTHREAD_ONCE_INIT: - /* This is initializer thread */ - (*init_routine)(); - *once_control= YASSL_PTHREAD_ONCE_DONE; - break; - - case YASSL_PTHREAD_ONCE_INPROGRESS: - /* init_routine in progress. Wait for its completion */ - while(*once_control == YASSL_PTHREAD_ONCE_INPROGRESS) - { - Sleep(1); - } - break; - case YASSL_PTHREAD_ONCE_DONE: - /* Nothing to do */ - break; - } - return 0; -} -#else -#define yassl_pthread_once_t pthread_once_t -#if defined(PTHREAD_ONCE_INITIALIZER) -#define YASSL_PTHREAD_ONCE_INIT PTHREAD_ONCE_INITIALIZER -#else -#define YASSL_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT -#endif -#define yassl_pthread_once(C,F) pthread_once(C,F) -#endif // _WIN32 - -// 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; -} - - -const char handshake_order[] = "Out of order HandShake Message!"; - - -} // 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 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; -static yassl_pthread_once_t session_created= YASSL_PTHREAD_ONCE_INIT; - -void Session_initialize() -{ - sessionsInstance = NEW_YS Sessions; -} - -extern "C" -{ - static void c_session_initialize() { Session_initialize(); } -} - - -Sessions& GetSessions() -{ - yassl_pthread_once(&session_created, c_session_initialize); - 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; -} - - -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::iterator sess_iterator; -typedef STL::list::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_; -} - - -/** Implement a my_strdup replacement, so we can reuse get_password() */ -extern "C" char *yassl_mysql_strdup(const char *from, int) -{ - return from ? strdup(from) : NULL; -} - - -extern "C" -{ -int -default_password_callback(char * buffer, int size_arg, int rwflag, - void * /* unused: callback_data */) -{ - char *passwd; - size_t passwd_len, size= (size_t) size_arg; - - passwd= ::yassl_mysql_get_tty_password_ext("Enter PEM pass phrase:", - yassl_mysql_strdup); - - if (!passwd) - return 0; - - passwd_len= strlen(passwd); - - if (!passwd_len) - return 0; - - if (size > 0) - { - size_t result_len= size - 1 > passwd_len ? - passwd_len : size - 1; - memcpy(buffer, passwd, result_len); - buffer[result_len]= 0; - } - free(passwd); - return passwd_len; -} -} - -SSL_CTX::SSL_CTX(SSL_METHOD* meth) - : method_(meth), certificate_(0), privateKey_(0), - passwordCb_(default_password_callback), - 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::SetMethod(SSL_METHOD* meth) -{ - if(method_) - ysDelete(method_); - method_= meth; -} - - -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(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(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(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; -} - - -#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION -namespace mySTL { -template yaSSL::yassl_int_cpp_local1::SumData for_each::iterator, yaSSL::yassl_int_cpp_local1::SumData>(mySTL::list::iterator, mySTL::list::iterator, yaSSL::yassl_int_cpp_local1::SumData); -template yaSSL::yassl_int_cpp_local1::SumBuffer for_each::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer>(mySTL::list::iterator, mySTL::list::iterator, yaSSL::yassl_int_cpp_local1::SumBuffer); -template mySTL::list::iterator find_if::iterator, yaSSL::yassl_int_cpp_local2::sess_match>(mySTL::list::iterator, mySTL::list::iterator, yaSSL::yassl_int_cpp_local2::sess_match); -template mySTL::list::iterator find_if::iterator, yaSSL::yassl_int_cpp_local2::thr_match>(mySTL::list::iterator, mySTL::list::iterator, yaSSL::yassl_int_cpp_local2::thr_match); -} -#endif - -- cgit v1.1