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

📄 security.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
#if defined(HAVE_CONFIG_H)#include "resip/stack/config.hxx"#endif#include <ostream>#include <fstream>#include "resip/stack/Contents.hxx"#include "resip/stack/MultipartSignedContents.hxx"#include "resip/stack/Pkcs7Contents.hxx"#include "resip/stack/PlainContents.hxx"#include "resip/stack/Security.hxx"#include "resip/stack/SecurityAttributes.hxx"#include "resip/stack/Transport.hxx"#include "resip/stack/SipMessage.hxx"#include "rutil/BaseException.hxx"#include "rutil/DataStream.hxx"#include "rutil/Logger.hxx"#include "rutil/Random.hxx"#include "rutil/SHA1Stream.hxx"#include "rutil/Socket.hxx"#include "rutil/Timer.hxx"#include "rutil/ParseBuffer.hxx"#include "rutil/FileSystem.hxx"#include "rutil/WinLeakCheck.hxx"#if defined(USE_SSL)#if !defined(WIN32)#include <sys/types.h>#include <sys/uio.h>#include <sys/fcntl.h>#include <unistd.h>#include <dirent.h>#endif#include <sys/types.h>#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/ossl_typ.h>#include <openssl/x509.h>#include <openssl/x509v3.h>#include <openssl/ssl.h>using namespace resip;using namespace std;#define RESIPROCATE_SUBSYSTEM Subsystem::SIPstatic const Data PEM(".pem");static const Data pemTypePrefixes(  Security::PEMType pType ){   static const Data rootCert("root_cert_");   static const Data domainCert("domain_cert_");   static const Data domainKey("domain_key_");   static const Data userCert("user_cert_");   static const Data userKey("user_key_");   static const Data unknownKey("user_key_");   switch (pType)   {      case  Security::RootCert:         return rootCert;      case  Security::DomainCert:       return domainCert;      case  Security::DomainPrivateKey: return domainKey;      case  Security::UserCert:         return userCert;      case  Security::UserPrivateKey:   return userKey;      default:      {         ErrLog( << "Some unkonw pem type prefix requested" << (int)(pType) );         assert(0);      }   }   return unknownKey;}static DatareadIntoData(const Data& filename){   DebugLog( << "Trying to read file " << filename );      ifstream is;   is.open(filename.c_str(), ios::binary );   if ( !is.is_open() )   {      ErrLog( << "Could not open file " << filename << " for read");      throw BaseSecurity::Exception("Could not read file ",                                     __FILE__,__LINE__);   }      assert(is.is_open());      int length = 0;      // get length of file:#if !defined(__MSL_CPP__) || (__MSL_CPP_ >= 0x00012000)   is.seekg (0, ios::end);   length = is.tellg();   is.seekg (0, ios::beg);#else   // this is a work around for a bug in CodeWarrior 9's implementation of seekg.   // http://groups.google.ca/group/comp.sys.mac.programmer.codewarrior/browse_frm/thread/a4279eb75f3bd55a   FILE * tmpFile = fopen(filename.c_str(), "r+b");   assert(tmpFile != NULL);   fseek(tmpFile, 0, SEEK_END);   length = ftell(tmpFile);   fseek(tmpFile, 0, SEEK_SET);#endif // __MWERKS__      // tellg/tell will return -1 if the stream is bad   if (length == -1)   {      ErrLog( << "Could not seek into file " << filename);      throw BaseSecurity::Exception("Could not seek into file ",                                     __FILE__,__LINE__);   }      // !jf! +1 is a workaround for a bug in Data::c_str() that adds the 0 without   // resizing.    char* buffer = new char [length+1];       // read data as a block:   is.read (buffer,length);      Data target(Data::Take, buffer, length);      is.close();      return target;}static DatagetAor(const Data& filename, const  Security::PEMType &pemType ){   const Data& prefix = pemTypePrefixes( pemType );   return filename.substr(prefix.size(), filename.size() - prefix.size() - PEM.size());}extern "C"{   static int verifyCallback(int iInCode, X509_STORE_CTX *pInStore){   char cBuf1[500];   char cBuf2[500];   X509 *pErrCert;   int iErr = 0;   int iDepth = 0;   pErrCert = X509_STORE_CTX_get_current_cert(pInStore);   iErr = X509_STORE_CTX_get_error(pInStore);   iDepth = X509_STORE_CTX_get_error_depth(pInStore);   if (NULL != pErrCert)      X509_NAME_oneline(X509_get_subject_name(pErrCert),cBuf1,256);   sprintf(cBuf2,", depth=%d %s\n",iDepth,cBuf1);   if(!iInCode)      ErrLog(<< "Error when verifying server's chain of certificates: " << X509_verify_cert_error_string(pInStore->error) << cBuf2 );    return iInCode;} }BaseSecurity::CipherList BaseSecurity::ExportableSuite("!SSLv2:aRSA+AES:aDSS+AES:@STRENGTH:aRSA+3DES:aDSS+3DES:aRSA+RC4+MEDIUM:aDSS+RC4+MEDIUM:aRSA+DES:aDSS+DES:aRSA+RC4:aDSS+RC4");BaseSecurity::CipherList BaseSecurity::StrongestSuite("!SSLv2:aRSA+AES:aDSS+AES:@STRENGTH:aRSA+3DES:aDSS+3DES");Security::Security(const CipherList& cipherSuite) : BaseSecurity(cipherSuite){#ifdef WIN32   mPath = "C:\\sipCerts\\";#else   const char* env=getenv("HOME");   if(env)   {      mPath = env;   }   mPath += "/.sipCerts/";#endif}Security::Security(const Data& directory, const CipherList& cipherSuite) :    BaseSecurity(cipherSuite),    mPath(directory){   // since the preloader won't work otherwise and VERY difficult to figure   // out.    if ( !mPath.postfix(Symbols::SLASH))   {      mPath += Symbols::SLASH;   }}voidSecurity::preload(){#if 1   FileSystem::Directory dir(mPath);   FileSystem::Directory::iterator it(dir);   for (; it != dir.end(); ++it)   {      Data name = *it;                 if (name.postfix(PEM))      {         Data fileName = mPath + name;         bool attemptedToLoad = true;                  DebugLog(<< "Checking to load file " << name );         try         {            if (name.prefix(pemTypePrefixes(UserCert)))            {               addCertPEM( UserCert, getAor(name, UserCert), readIntoData(fileName), false );            }            else if (name.prefix(pemTypePrefixes(UserPrivateKey)))            {               addPrivateKeyPEM( UserPrivateKey, getAor(name, UserPrivateKey), readIntoData(fileName), false);            }            else if (name.prefix(pemTypePrefixes(DomainCert)))            {               addCertPEM( DomainCert, getAor(name, DomainCert), readIntoData(fileName), false);            }            else if (name.prefix(pemTypePrefixes(DomainPrivateKey)))            {               addPrivateKeyPEM( DomainPrivateKey, getAor(name, DomainPrivateKey), readIntoData(fileName), false);            }            else if (name.prefix(pemTypePrefixes(RootCert)))            {               addRootCertPEM(readIntoData(fileName));            }            else            {               DebugLog(<< "PEM file " << name << " does not have appropriate resip prefix, skipping...");               attemptedToLoad = false;            }         }         catch (...)         {              ErrLog(<< "Some problem reading " << fileName );         }                  if(attemptedToLoad)         {            InfoLog(<<"Sucessfully loaded " << fileName );         }      }   }#else   // CJ - TODO - delete this old crap    DIR* dir = opendir( mPath.c_str() );   if (!dir )   {      ErrLog( << "Error reading public key directory  " << mPath );      return;         }   struct dirent * d = 0;   while (1)   {      d = readdir(dir);      if ( !d )      {         break;      }      Data name( d->d_name );      Data fileName = mPath+name;            if (name.postfix(PEM))      {         InfoLog( << "Going to try to read file " << fileName );                  try         {            if (name.prefix(pemTypePrefixes(UserCert)))            {               addCertPEM( UserCert, getAor(name, UserCert), readIntoData(fileName), false );            }            else if (name.prefix(pemTypePrefixes(UserPrivateKey)))            {               addPrivateKeyPEM( UserPrivateKey, getAor(name, UserPrivateKey), readIntoData(fileName), false);            }            else if (name.prefix(pemTypePrefixes(DomainCert)))            {               addCertPEM( DomainCert, getAor(name, DomainCert), readIntoData(fileName), false);            }            else if (name.prefix(pemTypePrefixes(DomainPrivateKey)))            {               addPrivateKeyPEM( DomainPrivateKey, getAor(name, DomainPrivateKey), readIntoData(fileName), false);            }            else if (name.prefix(pemTypePrefixes(RootCert)))            {               addRootCertPEM(readIntoData(fileName));            }         }         catch (...)         {              ErrLog(<< "Some problem reading " << fileName );         }                  InfoLog(<<"Sucessfully loaded " << fileName );      }   }   closedir( dir );#endif}voidSecurity::onReadPEM(const Data& name, PEMType type, Data& buffer) const{   Data filename = mPath + pemTypePrefixes(type) + name + PEM;   InfoLog (<< "Reading PEM file " << filename << " into " << name);   // .dlb. extra copy   buffer = readIntoData(filename);}voidSecurity::onWritePEM(const Data& name, PEMType type, const Data& buffer) const{   Data filename = mPath + pemTypePrefixes(type) + name + PEM;   InfoLog (<< "Writing PEM file " << filename << " for " << name);   ofstream str(filename.c_str(), ios::binary);   if (!str)   {      ErrLog (<< "Can't write to " << filename);      throw BaseSecurity::Exception("Failed opening PEM file", __FILE__,__LINE__);   }   else   {      str.write(buffer.data(), buffer.size());      if (!str)      {         ErrLog (<< "Failed writing to " << filename << " " << buffer.size() << " bytes");         throw BaseSecurity::Exception("Failed writing PEM file", __FILE__,__LINE__);      }   }}voidSecurity::onRemovePEM(const Data& name, PEMType type) const{   assert(0);   // TODO - should delete file }voidBaseSecurity::addCertDER (PEMType type,                           const Data& key,                           const Data& certDER,                           bool write) const{   assert( !certDER.empty() );   X509* cert = 0;#if (OPENSSL_VERSION_NUMBER < 0x0090800fL )   unsigned char* in = (unsigned char*)certDER.data();#else   unsigned const char* in = (unsigned const char*)certDER.data();#endif   if (d2i_X509(&cert,&in,certDER.size()) == 0)   {      ErrLog(<< "Could not read DER certificate from " << certDER );      throw BaseSecurity::Exception("Could not read DER certificate ",                                     __FILE__,__LINE__);   }   addCertX509(type,key,cert,write);}voidBaseSecurity::addCertPEM (PEMType type,                           const Data& name,                           const Data& certPEM,                           bool write) const{   assert( !certPEM.empty() );   X509* cert=NULL;      BIO* in = BIO_new_mem_buf(const_cast<char*>(certPEM.c_str()), -1);   if ( !in )   {      ErrLog(<< "Could not create BIO buffer from '" << certPEM << "'");      throw Exception("Could not create BIO buffer", __FILE__,__LINE__);   }   cert = PEM_read_bio_X509(in,0,0,0);   if (cert == NULL)   {	   ErrLog( << "Could not load X509 cert from '" << certPEM << "'" );	   BIO_free(in); 	   throw Exception("Could not load X509 cert from BIO buffer", __FILE__,__LINE__);   }      addCertX509(type,name,cert,write);      BIO_free(in);}voidBaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) const{   switch (type)   {      case DomainCert:      {         mDomainCerts.insert(std::make_pair(key, cert));      }      break;      case UserCert:      {          mUserCerts.insert(std::make_pair(key, cert));      }      break;      case RootCert:      {         X509_STORE_add_cert(mRootTlsCerts,cert);         X509_STORE_add_cert(mRootSslCerts,cert);         X509_free(cert);      }      break;      default:      {         assert(0);      }   }      if (write)   {      // creates a read/write BIO buffer.      BIO *out = BIO_new(BIO_s_mem());      assert(out);      try      {         int ret = PEM_write_bio_X509(out, cert);         assert(ret);                  BIO_flush(out);         // get content in BIO buffer to our buffer.         char* p = 0;         size_t len = BIO_get_mem_data(out,&p);         assert(p);         assert(len);         Data  buf(Data::Borrow, p, len);                  this->onWritePEM(key, type, buf);      }      catch(...)      {         ErrLog(<<"Caught exception: ");         BIO_free(out);         throw;      }      BIO_free(out);   }}boolBaseSecurity::hasCert (PEMType type, const Data& aor) const{   assert( !aor.empty() );   X509Map& certs = (type == DomainCert ? mDomainCerts : mUserCerts);   X509Map::iterator where = certs.find(aor);   if (where != certs.end())   {      return true;   }      try   {      Data certPEM;      onReadPEM(aor, type, certPEM);      if (certPEM.empty())      {         return false;      }      BaseSecurity*  mutable_this = const_cast<BaseSecurity*>(this);      mutable_this->addCertPEM(type, aor, certPEM, false);   }   catch (...)   {

⌨️ 快捷键说明

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