📄 encryptionmanager.cxx
字号:
#include <cassert>#include <list>#include "rutil/BaseException.hxx"#include "resip/stack/SipMessage.hxx"#include "resip/stack/Helper.hxx"#include "resip/dum/BaseUsage.hxx"#include "resip/dum/Handles.hxx"#include "resip/dum/DialogUsageManager.hxx"#include "resip/stack/Security.hxx"#include "resip/stack/Contents.hxx"#include "resip/stack/MultipartSignedContents.hxx"#include "resip/stack/MultipartMixedContents.hxx"#include "resip/stack/MultipartAlternativeContents.hxx"#include "resip/stack/MultipartRelatedContents.hxx"#include "resip/stack/Pkcs7Contents.hxx"#include "resip/dum/RemoteCertStore.hxx"#include "resip/stack/SecurityAttributes.hxx"#include "resip/dum/CertMessage.hxx"#include "resip/dum/TargetCommand.hxx"#include "resip/dum/EncryptionManager.hxx"#include "resip/dum/DumDecrypted.hxx"#include "resip/dum/DumFeature.hxx"#include "resip/dum/DumFeatureChain.hxx"#include "resip/dum/OutgoingEvent.hxx"#include "resip/dum/DumHelper.hxx"#include "rutil/Logger.hxx"#include "rutil/ParseBuffer.hxx"#include "rutil/WinLeakCheck.hxx"#if defined(USE_SSL)using namespace resip;using namespace std;#define RESIPROCATE_SUBSYSTEM Subsystem::DUMstatic bool isAckOrCancelOrBye(const SipMessage& msg){ MethodTypes method = msg.header(h_RequestLine).getMethod(); return (method == ACK || method == CANCEL || method == BYE);}EncryptionManager::Exception::Exception(const Data& msg, const Data& file, const int line) : BaseException(msg,file,line){}EncryptionManager::EncryptionManager(DialogUsageManager& dum, TargetCommand::Target& target) : DumFeature(dum, target){}EncryptionManager::~EncryptionManager(){ for (list<Request*>::iterator it = mRequests.begin(); it != mRequests.end(); ++it) { delete *it; } mRequests.clear();}void EncryptionManager::setRemoteCertStore(std::auto_ptr<RemoteCertStore> store){ ErrLog(<< "Async currently is not supported"); assert(0); //mRemoteCertStore = store;}DumFeature::ProcessingResult EncryptionManager::process(Message* msg){ SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg); if (sipMsg) { if (sipMsg->getContents()) { if (decrypt(sipMsg)) { DebugLog(<< "Decrypted message:" << sipMsg << endl); return DumFeature::FeatureDone; } else { return DumFeature::EventTaken; } } else { return DumFeature::FeatureDone; } } OutgoingEvent* event = dynamic_cast<OutgoingEvent*>(msg); if (event) { if (!event->message()->getContents()) { return DumFeature::FeatureDone; } if (!event->message()->getSecurityAttributes() || event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel() == SecurityAttributes::None || event->message()->getSecurityAttributes()->encryptionPerformed()) { return DumFeature::FeatureDone; } Data senderAor; Data recipAor; if (event->message()->isRequest()) { senderAor = event->message()->header(h_From).uri().getAor(); recipAor = event->message()->header(h_To).uri().getAor(); } else { senderAor = event->message()->header(h_To).uri().getAor(); recipAor = event->message()->header(h_From).uri().getAor(); } Contents* contents = event->message()->getContents(); bool setContents = true; bool noCerts = false; switch (event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel()) { case SecurityAttributes::None: setContents = false; break; case SecurityAttributes::Encrypt: contents = encrypt(event->message(), recipAor, &noCerts); break; case SecurityAttributes::Sign: contents = sign(event->message(), senderAor, &noCerts); break; case SecurityAttributes::SignAndEncrypt: contents = signAndEncrypt(event->message(), senderAor, recipAor, &noCerts); break; } if (contents) { if (setContents) { event->message()->setContents(auto_ptr<Contents>(contents)); DumHelper::setEncryptionPerformed(*event->message()); } return DumFeature::FeatureDone; } else { if (noCerts) { return DumFeature::ChainDoneAndEventDone; } else { //event->releaseMessage(); return DumFeature::EventTaken; } } } // Todo: change CertMessage to DumFeatureMessage. CertMessage* certMsg = dynamic_cast<CertMessage*>(msg); if (certMsg) { EncryptionManager::Result result = processCertMessage(certMsg); if (result == Complete) { return DumFeature::FeatureDone; } else { delete msg; return DumFeature::EventTaken; } } return DumFeature::FeatureDone;}EncryptionManager::Result EncryptionManager::processCertMessage(CertMessage* message){ InfoLog( << "Received a cert message: " << *message << endl); Result ret = Pending; list<Request*>::iterator it; for (it = mRequests.begin(); it != mRequests.end(); ++it) { if ((*it)->getId() == message->id().mId) break; } if (it != mRequests.end()) { InfoLog ( << "Processing the cert message" << endl); ret = (*it)->received(message->success(), message->id().mType, message->id().mAor, message->body()); if (Complete == ret) { delete *it; mRequests.erase(it); } } return ret;}Contents* EncryptionManager::sign(SharedPtr<SipMessage> msg, const Data& senderAor, bool* noCerts){ Sign* request = new Sign(mDum, mRemoteCertStore.get(), msg, senderAor, *this); Contents* contents; *noCerts = false; bool async = request->sign(&contents, noCerts); if (async) { InfoLog(<< "Async sign" << endl); //request->setTaken(); mRequests.push_back(request); } else { delete request; } return contents;}Contents* EncryptionManager::encrypt(SharedPtr<SipMessage> msg, const Data& recipientAor, bool* noCerts){ Encrypt* request = new Encrypt(mDum, mRemoteCertStore.get(), msg, recipientAor, *this); Contents* contents; *noCerts = false; bool async = request->encrypt(&contents, noCerts); if (async) { InfoLog(<< "Async encrypt" << endl); //request->setTaken(); mRequests.push_back(request); } else { delete request; } return contents;}Contents* EncryptionManager::signAndEncrypt(SharedPtr<SipMessage> msg, const Data& senderAor, const Data& recipAor, bool* noCerts){ SignAndEncrypt* request = new SignAndEncrypt(mDum, mRemoteCertStore.get(), msg, senderAor, recipAor, *this); Contents* contents; *noCerts = false; bool async = request->signAndEncrypt(&contents, noCerts); if (!async) { delete request; } else { InfoLog(<< "Async sign and encrypt" << endl); //request->setTaken(); mRequests.push_back(request); } return contents;}bool EncryptionManager::decrypt(SipMessage* msg){ Decrypt* request = new Decrypt(mDum, mRemoteCertStore.get(), msg, *this); bool ret = true; Helper::ContentsSecAttrs csa; ret = request->decrypt(csa); if (ret) { if (csa.mContents.get()) { msg->setContents(csa.mContents); if (csa.mAttributes.get()) { // Security Attributes might already exist on the message if the Identity Handler is enabled // if so, ensure we maintain the Identity Strength const SecurityAttributes *origSecurityAttributes = msg->getSecurityAttributes(); if(origSecurityAttributes) { csa.mAttributes->setIdentityStrength(origSecurityAttributes->getIdentityStrength()); } msg->setSecurityAttributes(csa.mAttributes); } } else { // no valid contents. request->handleInvalidContents(); if (msg->isRequest() && !isAckOrCancelOrBye(*msg)) { ret = false; } } delete request; } else { InfoLog(<< "Async decrypt" << endl); mRequests.push_back(request); } return ret;}EncryptionManager::Request::Request(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, DumFeature& feature) : mDum(dum), mStore(store), mMsgToEncrypt(msg), mPendingRequests(0), mFeature(feature) //mTaken(false){}EncryptionManager::Request::~Request(){ /* if (mTaken) { delete mMsg; } */}void EncryptionManager::Request::response415(){ SipMessage* response = Helper::makeResponse(*mMsgToEncrypt, 415); mDum.post(response); InfoLog(<< "Generated 415" << endl);}EncryptionManager::Sign::Sign(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, const Data& senderAor, DumFeature& feature) : Request(dum, store, msg, feature), mSenderAor(senderAor){}EncryptionManager::Sign::~Sign(){}bool EncryptionManager::Sign::sign(Contents** contents, bool* noCerts){ *contents = 0; *noCerts = false; bool async = false; MultipartSignedContents* msc = 0; bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor); bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor); if (!missingCert && !missingKey) { InfoLog(<< "Signing message" << endl); msc = mDum.getSecurity()->sign(mSenderAor, mMsgToEncrypt->getContents()); *contents = msc; } else { if (mStore) { if (missingCert) { InfoLog(<< "Fetching cert for " << mSenderAor << endl); ++mPendingRequests; MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert); mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); } if (missingKey) { InfoLog(<< "Fetching private key for " << mSenderAor << endl); ++mPendingRequests; MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey); mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum); } async = true; } else { InfoLog(<< "No remote cert store installed" << endl); *noCerts = true; response415(); } } return async;}EncryptionManager::Result EncryptionManager::Sign::received(bool success, MessageId::Type type, const Data& aor, const Data& data){ assert(mSenderAor==aor); assert(mPendingRequests>0&&mPendingRequests<=2); Result result = Pending; if (success) { if (type == MessageId::UserCert) { InfoLog(<< "Adding cert for: " << aor << endl); mDum.getSecurity()->addUserCertDER(aor, data); } else { InfoLog(<< "Adding private key for " << aor << endl); mDum.getSecurity()->addUserPrivateKeyDER(aor, data); } if (--mPendingRequests == 0) { InfoLog(<< "Signing message" << endl); MultipartSignedContents* msc = mDum.getSecurity()->sign(aor, mMsgToEncrypt->getContents()); mMsgToEncrypt->setContents(auto_ptr<Contents>(msc)); DumHelper::setEncryptionPerformed(*mMsgToEncrypt); OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); //mTaken = false; mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event))); result = Complete; } } else { InfoLog(<< "Failed to fetch " << ((type==MessageId::UserCert)? "cert " : "private key ") << "for " << aor <<endl); response415(); result = Complete; } return result;}EncryptionManager::Encrypt::Encrypt(DialogUsageManager& dum, RemoteCertStore* store, SharedPtr<SipMessage> msg, const Data& recipientAor, DumFeature& feature) : Request(dum, store, msg, feature), mRecipientAor(recipientAor){}EncryptionManager::Encrypt::~Encrypt(){}bool EncryptionManager::Encrypt::encrypt(Contents** contents, bool* noCerts){ *contents = 0; *noCerts = false; bool async = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -