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

📄 security.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
#if (  OPENSSL_VERSION_NUMBER > 0x009060ffL )//   const EVP_CIPHER* cipher =  EVP_des_ede3_cbc();   const EVP_CIPHER* cipher =  EVP_aes_128_cbc(); #else   //const EVP_CIPHER* cipher = EVP_enc_null();   EVP_CIPHER* cipher =  EVP_des_ede3_cbc();#endif   assert( cipher );#if (OPENSSL_VERSION_NUMBER < 0x0090705fL )#warning PKCS7_encrypt() is broken in OpenSSL 0.9.7d#endif   PKCS7* pkcs7 = PKCS7_encrypt( certs, in, cipher, flags);   if ( !pkcs7 )   {      BIO_free(in);      BIO_free(out);      sk_X509_free(certs);      ErrLog( << "Error creating PKCS7 encrypt object" );      //throw Exception("Can't encrypt",__FILE__,__LINE__);      return 0;   }   DebugLog( << "created PKCS7 encrypt object " );   i2d_PKCS7_bio(out,pkcs7);   BIO_flush(out);   char* outBuf=0;   long size = BIO_get_mem_data(out,&outBuf);   assert( size > 0 );   Data outData(outBuf,size);   assert( (long)outData.size() == size );   InfoLog( << "Encrypted body size is " << outData.size() );   InfoLog( << "Encrypted body is <" << outData.escaped() << ">" );   static char RESIP_ENCRYPT_OUT[] = "resip-encrypt-out";   Security::dumpAsn(RESIP_ENCRYPT_OUT, outData);   Pkcs7Contents* outBody = new Pkcs7Contents( outData );   assert( outBody );   outBody->header(h_ContentType).param( p_smimeType ) = "enveloped-data";   outBody->header(h_ContentType).param( p_name ) = "smime.p7m";   outBody->header(h_ContentDisposition).param( p_handling ) = "required";   outBody->header(h_ContentDisposition).param( p_filename ) = "smime.p7";   outBody->header(h_ContentDisposition).value() =  "attachment" ;   outBody->header(h_ContentTransferEncoding).value() = "binary";   BIO_free(in);   BIO_free(out);   sk_X509_free(certs);   return outBody;}MultipartSignedContents *BaseSecurity::signAndEncrypt( const Data& senderAor, Contents* body, const Data& recipCertName ){   //assert(0);   //return 0;   return sign(senderAor, encrypt(body, recipCertName));}DataBaseSecurity::computeIdentity( const Data& signerDomain, const Data& in ) const{   DebugLog( << "Compute identity for " << in );   if (mDomainPrivateKeys.count(signerDomain) == 0)   {      InfoLog( << "No private key for " << signerDomain );      throw Exception("Missing private key when computing identity",__FILE__,__LINE__);   }   EVP_PKEY* pKey = mDomainPrivateKeys[signerDomain];   assert( pKey );    if ( pKey->type !=  EVP_PKEY_RSA )   {      ErrLog( << "Private key (type=" << pKey->type <<"for "               << signerDomain << " is not of type RSA" );      throw Exception("No RSA private key when computing identity",__FILE__,__LINE__);   }   assert( pKey->type ==  EVP_PKEY_RSA );   RSA* rsa = EVP_PKEY_get1_RSA(pKey);   unsigned char result[4096];   int resultSize = sizeof(result);   assert( resultSize >= RSA_size(rsa) );   SHA1Stream sha;   sha << in;   Data hashRes =  sha.getBin();   DebugLog( << "hash of string is 0x" << hashRes.hex() );#if 1   int r = RSA_sign(NID_sha1, (unsigned char *)hashRes.data(), hashRes.size(),                    result, (unsigned int*)( &resultSize ),            rsa);   assert( r == 1 );#else   resultSize = RSA_private_encrypt(hashResLen, hashRes,                                    result, rsa, RSA_PKCS1_PADDING);   if ( resultSize == -1 )   {      DebugLog( << "Problem doing RSA encrypt for identity");      while (1)      {         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  );         InfoLog( << "Error code = " << code << " file="<<file<<" line=" << line );      }      return Data::Empty;   }#endif   Data res(result,resultSize);   DebugLog( << "rsa encrypt of hash is 0x"<< res.hex() );   Data enc = res.base64encode();   static char IDENTITY_IN[] = "identity-in";   static char IDENTITY_IN_HASH[] = "identity-in-hash";   static char IDENTITY_IN_RSA[] = "identity-in-rsa";   static char IDENTITY_IN_BASE64[] = "identity-in-base64";   Security::dumpAsn(IDENTITY_IN, in );   Security::dumpAsn(IDENTITY_IN_HASH, hashRes );   Security::dumpAsn(IDENTITY_IN_RSA,res);   Security::dumpAsn(IDENTITY_IN_BASE64,enc);   return enc;}boolBaseSecurity::checkIdentity( const Data& signerDomain, const Data& in, const Data& sigBase64, X509* pCert ) const{   X509* cert =  pCert;   if (!cert)   {      if (mDomainCerts.count(signerDomain) == 0)      {         ErrLog( << "No public key for " << signerDomain );         throw Exception("Missing public key when verifying identity",__FILE__,__LINE__);      }      cert = mDomainCerts[signerDomain];   }      DebugLog( << "Check identity for " << in );   DebugLog( << " base64 data is " << sigBase64 );   Data sig = sigBase64.base64decode();   DebugLog( << "decoded sig is 0x"<< sig.hex() );   SHA1Stream sha;   sha << in;   Data hashRes =  sha.getBin();   DebugLog( << "hash of string is 0x" << hashRes.hex() );   EVP_PKEY* pKey = X509_get_pubkey( cert );   assert( pKey );   assert( pKey->type ==  EVP_PKEY_RSA );   RSA* rsa = EVP_PKEY_get1_RSA(pKey);#if 1   int ret = RSA_verify(NID_sha1, (unsigned char *)hashRes.data(),                        hashRes.size(), (unsigned char*)sig.data(), sig.size(),                        rsa);#else   unsigned char result[4096];   int resultSize = sizeof(result);   assert( resultSize >= RSA_size(rsa) );   resultSize = RSA_public_decrypt(sig.size(),(unsigned char*)sig.data(),                                   result, rsa, RSA_PKCS1_PADDING );   assert( resultSize != -1 );   //assert( resultSize == SHA_DIGEST_LENGTH );   Data recievedHash(result,resultSize);   dumpAsn("identity-out-decrypt", recievedHash );   bool ret =  ( computedHash == recievedHash );#endif   DebugLog( << "rsa verify result is " << ret  );   static char IDENTITY_OUT_MSG[] = "identity-out-msg";   static char IDENTITY_OUT_BASE64[] = "identity-out-base64";   static char IDENTITY_OUT_SIG[] = "identity-out-sig";   static char IDENTITY_OUT_HASH[] = "identity-out-hash";   Security::dumpAsn(IDENTITY_OUT_MSG, in );   Security::dumpAsn(IDENTITY_OUT_BASE64,sigBase64);   Security::dumpAsn(IDENTITY_OUT_SIG, sig);   Security::dumpAsn(IDENTITY_OUT_HASH, hashRes );   return (ret != 0);}voidBaseSecurity::checkAndSetIdentity( const SipMessage& msg, const Data& certDer) const{   auto_ptr<SecurityAttributes> sec(new SecurityAttributes);   X509* cert=NULL;      try   {      if ( !certDer.empty() )      {#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)         {            DebugLog(<< "Could not read DER certificate from " << certDer );            cert = NULL;         }      }      if ( certDer.empty() || cert )      {         if ( checkIdentity(msg.header(h_From).uri().host(),                            msg.getCanonicalIdentityString(),                            msg.header(h_Identity).value(),                            cert ) )         {            sec->setIdentity(msg.header(h_From).uri().getAor());            sec->setIdentityStrength(SecurityAttributes::Identity);         }         else         {            sec->setIdentity(msg.header(h_From).uri().getAor());            sec->setIdentityStrength(SecurityAttributes::FailedIdentity);         }      }      else      {         sec->setIdentity(msg.header(h_From).uri().getAor());         sec->setIdentityStrength(SecurityAttributes::FailedIdentity);      }   }   catch (BaseException& e)   {      ErrLog(<<"Caught exception: "<< e);      sec->setIdentity(msg.header(h_From).uri().getAor());      sec->setIdentityStrength(SecurityAttributes::FailedIdentity);   }   msg.setSecurityAttributes(sec);}Contents*BaseSecurity::decrypt( const Data& decryptorAor, const Pkcs7Contents* contents){   DebugLog( << "decryptor Aor: <" << decryptorAor << ">" );   int flags=0;   flags |= PKCS7_BINARY;   // for now, assume that this is only a singed message   assert( contents );   Data text = contents->getBodyData();   DebugLog( << "uncode body = <" << text.escaped() << ">" );   DebugLog( << "uncode body size = " << text.size() );   static char RESIP_ASN_DECRYPT[] = "resip-asn-decrypt";   Security::dumpAsn(RESIP_ASN_DECRYPT, text );   BIO* in = BIO_new_mem_buf( (void*)text.c_str(), text.size());   assert(in);   InfoLog( << "created in BIO");   BIO* out;   out = BIO_new(BIO_s_mem());   assert(out);   InfoLog( << "created out BIO" );   PKCS7* pkcs7 = d2i_PKCS7_bio(in, 0);   if ( !pkcs7 )   {      ErrLog( << "Problems doing decode of PKCS7 object" );      while (1)      {         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  );         InfoLog( << "Error code = " << code << " file=" << file << " line=" << line );      }      BIO_free(in);      BIO_free(out);      return 0;   }   BIO_flush(in);   int type=OBJ_obj2nid(pkcs7->type);   switch (type)   {      case NID_pkcs7_signed:         InfoLog( << "data is pkcs7 signed" );         break;      case NID_pkcs7_signedAndEnveloped:         InfoLog( << "data is pkcs7 signed and enveloped" );         break;      case NID_pkcs7_enveloped:         InfoLog( << "data is pkcs7 enveloped" );         break;      case NID_pkcs7_data:         InfoLog( << "data i pkcs7 data" );         break;      case NID_pkcs7_encrypted:         InfoLog( << "data is pkcs7 encrypted " );         break;      case NID_pkcs7_digest:         InfoLog( << "data is pkcs7 digest" );         break;      default:         InfoLog( << "Unkown pkcs7 type" );         break;   }   STACK_OF(X509)* certs = sk_X509_new_null();   assert( certs );   //   flags |= PKCS7_NOVERIFY;   assert( mRootTlsCerts );   switch (type)   {      case NID_pkcs7_signedAndEnveloped:      {         BIO_free(in);         BIO_free(out);         sk_X509_free(certs);         throw Exception("Signed and enveloped is not supported", __FILE__, __LINE__);      }      break;      case NID_pkcs7_enveloped:      {         if (mUserPrivateKeys.count(decryptorAor) == 0)         {            BIO_free(in);            BIO_free(out);            sk_X509_free(certs);            InfoLog( << "Don't have a private key for " << decryptorAor << " for  PKCS7_decrypt" );            throw Exception("Missing private key", __FILE__, __LINE__);         }         else if (mUserCerts.count(decryptorAor) == 0)         {            BIO_free(in);            BIO_free(out);            sk_X509_free(certs);            InfoLog( << "Don't have a public cert for " << decryptorAor << " for  PKCS7_decrypt" );            throw Exception("Missing cert", __FILE__, __LINE__);         }         EVP_PKEY* privateKey = mUserPrivateKeys[decryptorAor];         X509* publicCert = mUserCerts[decryptorAor];         if ( PKCS7_decrypt(pkcs7, privateKey, publicCert, out, flags ) != 1 )         {            ErrLog( << "Problems doing PKCS7_decrypt" );            while (1)            {               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  );               InfoLog( << "Error code = " << code << " file=" << file << " line=" << line );            }            BIO_free(in);            BIO_free(out);            sk_X509_free(certs);            return 0;         }      }      break;      default:         BIO_free(in);         BIO_free(out);         sk_X509_free(certs);         ErrLog(<< "Got PKCS7 data that could not be handled type=" << type );         throw Exception("Unsupported PKCS7 data type", __FILE__, __LINE__);   }   BIO_flush(out);      BUF_MEM* bufMem;   BIO_get_mem_ptr(out, &bufMem);   int len = bufMem->length;   char* buffer = new char[len];   memcpy(buffer, bufMem->data, len);   BIO_set_close(out, BIO_CLOSE);   BIO_free(in);   BIO_free(out);   sk_X509_free(certs);   // parse out the header information and form new body.   // TODO !jf! this is a really crappy parser - shoudl do proper mime stuff    ParseBuffer pb(buffer, len);   const char* headerStart = pb.position();   // pull out contents type only   pb.skipToChars("Content-Type");   pb.assertNotEof();   pb.skipToChar(Symbols::COLON[0]);   pb.skipChar();   pb.assertNotEof();   pb.skipWhitespace();   const char* typeStart = pb.position();   pb.assertNotEof();   // determine contents-type header buffer   pb.skipToTermCRLF();   pb.assertNotEof();   ParseBuffer subPb(typeStart, pb.position() - typeStart);   Mime contentType;   contentType.parse(subPb);   pb.assertNotEof();   // determine body start   pb.reset(typeStart);   const char* bodyStart = pb.skipToChars(Symbols::CRLFCRLF);   pb.assertNotEof();   bodyStart += 4;   // determine contents body buffer   pb.skipToEnd();   Data tmp;   pb.data(tmp, bodyStart);   // create contents against body   Contents* ret = Contents::createContents(contentType, tmp);   ret->addBuffer(buffer);      // pre-parse headers   ParseBuffer headersPb(headerStart, bodyStart-4-headerStart);   ret->preParseHeaders(headersPb);   InfoLog( << "Got body data of " << ret->getBodyData() );   return ret;}Contents*

⌨️ 快捷键说明

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