⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlsconnection.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include "resip/stack/TlsConnection.hxx"#include "resip/stack/Security.hxx"#include "rutil/Logger.hxx"#include "resip/stack/Uri.hxx"#include "rutil/Socket.hxx"#if defined(USE_SSL)#include <openssl/e_os2.h>#include <openssl/evp.h>#include <openssl/crypto.h>#include <openssl/err.h>#include <openssl/pem.h>#include <openssl/pkcs7.h>#include <openssl/x509v3.h>#include <openssl/ssl.h>#endifusing namespace resip;#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORTTlsConnection::TlsConnection( Transport* transport, const Tuple& tuple,                               Socket fd, Security* security,                               bool server, Data domain,  SecurityTypes::SSLType sslType ,                              Compression &compression) :   Connection(transport,tuple, fd, compression),   mServer(server),   mSecurity(security),   mSslType( sslType ),   mDomain(domain){#if defined(USE_SSL)   InfoLog (<< "Creating TLS connection for domain "             << mDomain             << " " << tuple             << " on " << fd);   mSsl = NULL;   mBio= NULL;     if (mServer)   {      DebugLog( << "Trying to form TLS connection - acting as server" );      if ( mDomain.empty() )      {         ErrLog(<< "Tranport was not created with a server domain so can not act as server" );          throw Security::Exception("Trying to act as server but no domain specified",                                   __FILE__,__LINE__);      }   }   else   {      DebugLog( << "Trying to form TLS connection - acting as client" );   }   assert( mSecurity );   SSL_CTX* ctx=NULL;   if ( mSslType ==  SecurityTypes::SSLv23 )   {      ctx = mSecurity->getSslCtx();   }   else   {      ctx = mSecurity->getTlsCtx();   }      assert(ctx);      mSsl = SSL_new(ctx);   assert(mSsl);   if ( mServer )   {      assert( mSecurity );      X509* cert = mSecurity->getDomainCert(mDomain); //mDomainCerts[mDomain];      if (!cert)      {         ErrLog(<< "Don't have certificate for domain " << mDomain );      }            if( !SSL_use_certificate(mSsl, cert) )      {         throw Security::Exception("SSL_use_certificate failed",                                   __FILE__,__LINE__);      }            EVP_PKEY* pKey = mSecurity->getDomainKey(mDomain); //mDomainPrivateKeys[mDomain];      if (!pKey)      {         ErrLog(<< "Don't have private key for domain " << mDomain );      }      if ( !SSL_use_PrivateKey(mSsl, pKey) )      {         throw Security::Exception("SSL_use_PrivateKey failed.",                                   __FILE__,__LINE__);      }   }      mBio = BIO_new_socket(fd,0/*close flag*/);   assert( mBio );      SSL_set_bio( mSsl, mBio, mBio );   mTlsState = mServer ? Accepting : Connecting;#endif // USE_SSL   }TlsConnection::~TlsConnection(){#if defined(USE_SSL)   SSL_shutdown(mSsl);   SSL_free(mSsl);#endif // USE_SSL   }const char*TlsConnection::fromState(TlsConnection::TlsState s){   switch(s)   {      case Handshaking: return "Handshaking"; break;      case Accepting: return "Accepting"; break;      case Broken: return "Broken"; break;      case Connecting: return "Connecting"; break;      case Up: return "Up"; break;   }   return "????";}TlsConnection::TlsStateTlsConnection::checkState(){#if defined(USE_SSL)   //DebugLog(<<"state is " << fromTlsState(mTlsState));   if (mTlsState == Up || mTlsState == Broken)   {      return mTlsState;   }      int ok=0;      ERR_clear_error();      if (mTlsState != Handshaking)   {      if (mTlsState == Accepting)      {         ok = SSL_accept(mSsl);      }      else      {         ok = SSL_connect(mSsl);         //StackLog( << "TLS SSL_connect - state = " << fromTlsState(mTlsState) );      }      if ( ok <= 0 )      {         int err = SSL_get_error(mSsl,ok);         char buf[256];         ERR_error_string_n(err,buf,sizeof(buf));//          StackLog( << "TLS error in " //                    << (char*)( (mTlsState == Accepting) ? (char*)"accept" : (char*)"connect" )//                    << " ok=" << ok << " err=" << err << " " << buf );                   switch (err)         {            case SSL_ERROR_WANT_READ:               //StackLog( << "TLS connection want read" );               return mTlsState;            case SSL_ERROR_WANT_WRITE:               //StackLog( << "TLS connection want write" );               return mTlsState;            case SSL_ERROR_WANT_CONNECT:               //StackLog( << "TLS connection want connect" );               return mTlsState;#if  ( OPENSSL_VERSION_NUMBER >= 0x0090702fL )            case SSL_ERROR_WANT_ACCEPT:               //StackLog( << "TLS connection want accept" );               return mTlsState;#endif         }	            ErrLog( << "TLS connection failed "                 << "ok=" << ok << " err=" << err << " " << buf );                  switch (err)         {            case SSL_ERROR_NONE:                ErrLog( <<" (SSL Error none)" );               break;            case SSL_ERROR_SSL:                ErrLog( <<" (SSL Error ssl)" );               break;            case SSL_ERROR_WANT_READ:                ErrLog( <<" (SSL Error want read)" );                break;            case SSL_ERROR_WANT_WRITE:                ErrLog( <<" (SSL Error want write)" );                break;            case SSL_ERROR_WANT_X509_LOOKUP:                ErrLog( <<" (SSL Error want x509 lookup)" );                break;            case SSL_ERROR_SYSCALL:                ErrLog( <<" (SSL Error want syscall)" );                ErrLog( <<"Error may be because trying ssl connection to tls server" );                break;            case SSL_ERROR_WANT_CONNECT:                ErrLog( <<" (SSL Error want connect)" );                break;#if ( OPENSSL_VERSION_NUMBER >= 0x0090702fL )            case SSL_ERROR_WANT_ACCEPT:                ErrLog( <<" (SSL Error want accept)" );                break;#endif         }         while (true)         {            const char* file;            int line;                        unsigned long code = ERR_get_error_line(&file,&line);            if ( code == 0 )            {               break;            }                        char buf[256];            ERR_error_string_n(code,buf,sizeof(buf));            ErrLog( << buf  );            ErrLog( << "Error code = "                      << code << " file=" << file << " line=" << line );         }                  mTlsState = Broken;         mBio = 0;         mFailureReason = TransportFailure::Failure;         ErrLog (<< "Couldn't TLS connect");         return mTlsState;      }            InfoLog( << "TLS connected" );       mTlsState = Handshaking;   }   InfoLog( << "TLS handshake starting" );    ok = SSL_do_handshake(mSsl);         if ( ok <= 0 )   {      int err = SSL_get_error(mSsl,ok);      char buf[256];      ERR_error_string_n(err,buf,sizeof(buf));               switch (err)      {         case SSL_ERROR_WANT_READ:            StackLog( << "TLS handshake want read" );            return mTlsState;         case SSL_ERROR_WANT_WRITE:            StackLog( << "TLS handshake want write" );            return mTlsState;         default:            ErrLog( << "TLS handshake failed "                    << "ok=" << ok << " err=" << err << " " << buf );            mBio = NULL;            mTlsState = Broken;            mFailureReason = TransportFailure::CertValidationFailure;                     return mTlsState;      }   }   // force peer name to get checked and perhaps cert loaded   computePeerName();   //post-connection verification: check that certificate name matches domain name   if (!mServer)   {      bool matches = false;      for(std::list<Data>::iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)      {         if(isEqualNoCase(*it, who().getTargetDomain()))         {             matches=true;             break;         }      }      if(!matches)      {         mTlsState = Broken;         mBio = 0;         ErrLog (<< "Certificate name mismatch: trying to connect to <"                  << who().getTargetDomain()                 << "> remote cert domain(s) are <"                  << getPeerNamesData() << ">" );         mFailureReason = TransportFailure::CertNameMismatch;                  return mTlsState;      }   }   InfoLog( << "TLS handshake done for peer " << getPeerNamesData());    mTlsState = Up;   ensureWritable();   #endif // USE_SSL      return mTlsState;}      int TlsConnection::read(char* buf, int count ){#if defined(USE_SSL)   assert( mSsl );    assert( buf );   switch(checkState())   {      case Broken:         return -1;         break;      case Up:         break;      default:         return 0;         break;   }   if (!mBio)   {      DebugLog( << "Got TLS read bad bio  " );      return 0;   }         if ( !isGood() )   {      return -1;   }   int bytesRead = SSL_read(mSsl,buf,count);   StackLog(<< "SSL_read returned " << bytesRead << " bytes [" << Data(Data::Borrow, buf, bytesRead) << "]");   if (bytesRead > 0 && SSL_pending(mSsl))   {      int restBytes = SSL_pending(mSsl);      char* buffer = getWriteBufferForExtraBytes(restBytes);      StackLog(<< "reading remaining buffered bytes");      restBytes = SSL_read(mSsl, buffer, SSL_pending(mSsl));      StackLog(<< "SSL_read returned  " << restBytes << " bytes [" << Data(Data::Borrow, buffer, restBytes) << "]");      if (restBytes>0)      {         bytesRead += restBytes;      }      else      {         bytesRead = restBytes;      }   }   if (bytesRead <= 0)   {      int err = SSL_get_error(mSsl,bytesRead);      switch (err)      {         case SSL_ERROR_WANT_READ:         case SSL_ERROR_WANT_WRITE:         case SSL_ERROR_NONE:         {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -