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

📄 tlsconnection.cxx

📁 一个著名的SIP协议栈
💻 CXX
📖 第 1 页 / 共 2 页
字号:
   }

   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:
         {
            StackLog( << "Got TLS read got condition of " << err  );
            return 0;
         }
         break;
         default:
         {
            char buf[256];
            ERR_error_string_n(err,buf,sizeof(buf));
            ErrLog( << "Got TLS read ret=" << bytesRead << " error=" << err  << " " << buf  );
            return -1;
         }
         break;
      }
      assert(0);
   }
   StackLog(<<"SSL bytesRead="<<bytesRead);
   return bytesRead;
#endif // USE_SSL
   return -1;
}


int 
TlsConnection::write( const char* buf, int count )
{
#if defined(USE_SSL)
   assert( mSsl );
   assert( buf );
   int ret;
 
   switch(checkState())
   {
      case Broken:
         return -1;
         break;
      case Up:
         break;
      default:
         return 0;
         break;
   }

   if (!mBio)
   {
      DebugLog( << "Got TLS write bad bio "  );
      return 0;
   }
        
   ret = SSL_write(mSsl,(const char*)buf,count);
   if (ret < 0 )
   {
      int err = SSL_get_error(mSsl,ret);
      switch (err)
      {
         case SSL_ERROR_WANT_READ:
         case SSL_ERROR_WANT_WRITE:
         case SSL_ERROR_NONE:
         {
            StackLog( << "Got TLS write got condition of " << err  );
            return 0;
         }
         break;
         default:
         {
            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  );
               DebugLog( << "Error code = " << code << " file=" << file << " line=" << line );
            }
            ErrLog( << "Got TLS write error=" << err << " ret=" << ret  );
            return -1;
         }
         break;
      }
   }

   Data monkey(Data::Borrow, buf, count);

   StackLog( << "Did TLS write " << ret << " " << count << " " << "[[" << monkey << "]]" );

   return ret;
#endif // USE_SSL
   return -1;
}


bool 
TlsConnection::hasDataToRead() // has data that can be read 
{
#if defined(USE_SSL)
   if (checkState() != Up)
   {
      return false;
   }

   int p = SSL_pending(mSsl);
   //DebugLog(<<"hasDataToRead(): " <<p);
   return (p>0);
#else // USE_SSL
   return false;
#endif 
}


bool 
TlsConnection::isGood() // has data that can be read 
{
#if defined(USE_SSL)
   if ( mBio == 0 )
   {
      return false;
   }

   int mode = SSL_get_shutdown(mSsl);
   if ( mode != 0 ) 
   {
      return false;
   }

#endif       
   return true;
}


const std::list<Data>&
TlsConnection::getPeerNames() const
{
   return mPeerNames;
}

Data
TlsConnection::getPeerNamesData() const
{
   Data peerNamesString;
   for(std::list<Data>::const_iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)
   {
      if(it == mPeerNames.begin())
      {
         peerNamesString += *it;
      }
      else
      {
         peerNamesString += ", " + *it;
      }
   }
   return peerNamesString;
}


void
TlsConnection::computePeerName()
{
#if defined(USE_SSL)
   Data commonName;

   assert(mSsl);

   if (!mBio)
   {
      ErrLog( << "bad bio" );
      return;
   }

   // print session infor       
   SSL_CIPHER *ciph;
   ciph=SSL_get_current_cipher(mSsl);
   InfoLog( << "TLS sessions set up with " 
            <<  SSL_get_version(mSsl) << " "
            <<  SSL_CIPHER_get_version(ciph) << " "
            <<  SSL_CIPHER_get_name(ciph) << " " );

   // get the certificate if other side has one 
   X509* cert = SSL_get_peer_certificate(mSsl);
   if ( !cert )
   {
      DebugLog(<< "No peer certificate in TLS connection" );
      return;
   }

   // check that this certificate is valid 
   if (X509_V_OK != SSL_get_verify_result(mSsl))
   {
      DebugLog(<< "Peer certificate in TLS connection is not valid" );
      X509_free(cert); cert=NULL;
      return;
   }

   // look at the Common Name to find the peerName of the cert 
   X509_NAME* subject = X509_get_subject_name(cert);
   assert(subject);
   int i =-1;
   while( true )
   {
      i = X509_NAME_get_index_by_NID(subject, NID_commonName,i);
      if ( i == -1 )
      {
         break;
      }
      assert( i != -1 );
      X509_NAME_ENTRY* entry = X509_NAME_get_entry(subject,i);
      assert( entry );
      
      ASN1_STRING*	s = X509_NAME_ENTRY_get_data(entry);
      assert( s );
      
      int t = M_ASN1_STRING_type(s);
      int l = M_ASN1_STRING_length(s);
      unsigned char* d = M_ASN1_STRING_data(s);
      Data name(d,l);
      DebugLog( << "got x509 string type=" << t << " len="<< l << " data=" << d );
      assert( name.size() == (unsigned)l );
      
      DebugLog( << "Found common name in cert of " << name );
      
      commonName = name;
   }

#if 0  // junk code to print certificates extentions for debugging 
   int numExt = X509_get_ext_count(cert);
   ErrLog(<< "Got peer certificate with " << numExt << " extentions" );

   for ( int i=0; i<numExt; i++ )
   {
      X509_EXTENSION* ext = X509_get_ext(cert,i);
      assert( ext );
      
      const char* str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
      assert(str);
      DebugLog(<< "Got certificate extention" << str );

      if  ( OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_subject_alt_name )
      {   
         DebugLog(<< "Got subjectAltName extention" );
      }
   }
#endif 

   // Look at the SubjectAltName, and if found, set as peerName
   GENERAL_NAMES* gens;
   gens = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
   for(int i = 0; i < sk_GENERAL_NAME_num(gens); i++)
   {  
      GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i);

      DebugLog(<< "subjectAltName of cert contains type <" << gen->type << ">" );

      if (gen->type == GEN_DNS)
      {
         ASN1_IA5STRING* uri = gen->d.uniformResourceIdentifier;
         int l = uri->length;
         unsigned char* dat = uri->data;
         Data name(dat,l);
         InfoLog(<< "subjectAltName of TLS session cert contains <" << name << ">" );
         
         mPeerNames.push_back(name);
      }
          
      if (gen->type == GEN_EMAIL)
      {
         DebugLog(<< "subjectAltName of cert has EMAIL type" );
      }
          
      if(gen->type == GEN_URI) 
      {
         DebugLog(<< "subjectAltName of cert has GEN_URI type" );
      }
   }
   sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);

   // If there are no peer names from the subjectAltName, then use the commonName
   if(mPeerNames.empty())
   {
       mPeerNames.push_back(commonName);
   }

   // add the certificate to the Security store
   unsigned char* buf = NULL;
   int len = i2d_X509( cert, &buf );
   Data derCert( buf, len );
   for(std::list<Data>::iterator it = mPeerNames.begin(); it != mPeerNames.end(); it++)
   {
      if ( !mSecurity->hasDomainCert( *it ) )
      {
         mSecurity->addDomainCertDER(*it,derCert);
      }
   }
   OPENSSL_free(buf); buf=NULL;

   X509_free(cert); cert=NULL;
#endif // USE_SSL
}

/* ====================================================================
 * The Vovida Software License, Version 1.0 
 * 
 * Copyright (c) 2000-2005 Vovida Networks, Inc.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
 *    and "Vovida Open Communication Application Library (VOCAL)" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact vocal@vovida.org.
 *
 * 4. Products derived from this software may not be called "VOCAL", nor
 *    may "VOCAL" appear in their name, without prior written
 *    permission of Vovida Networks, Inc.
 * 
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by Vovida
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
 * Inc.  For more information on Vovida Networks, Inc., please see
 * <http://www.vovida.org/>.
 *
 */

⌨️ 快捷键说明

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