reSIProcate/DialogUsageManager  9680
EncryptionManager.cxx
Go to the documentation of this file.
00001 
00002 #if defined(HAVE_CONFIG_H)
00003   #include "config.h"
00004 #endif
00005 
00006 #include "resip/dum/ssl/EncryptionManager.hxx"
00007 
00008 #include "resip/stack/ssl/Security.hxx"
00009 
00010 #include <cassert>
00011 #include <list>
00012 #include "rutil/BaseException.hxx"
00013 #include "resip/stack/SipMessage.hxx"
00014 #include "resip/stack/Helper.hxx"
00015 #include "resip/dum/BaseUsage.hxx"
00016 #include "resip/dum/Handles.hxx"
00017 #include "resip/dum/DialogUsageManager.hxx"
00018 #include "resip/stack/Contents.hxx"
00019 #include "resip/stack/MultipartSignedContents.hxx"
00020 #include "resip/stack/MultipartMixedContents.hxx"
00021 #include "resip/stack/MultipartAlternativeContents.hxx"
00022 #include "resip/stack/MultipartRelatedContents.hxx"
00023 #include "resip/stack/Pkcs7Contents.hxx"
00024 #include "resip/dum/RemoteCertStore.hxx"
00025 #include "resip/stack/SecurityAttributes.hxx"
00026 #include "resip/dum/CertMessage.hxx"
00027 #include "resip/dum/TargetCommand.hxx"
00028 #include "resip/dum/DumDecrypted.hxx"
00029 #include "resip/dum/DumFeature.hxx"
00030 #include "resip/dum/DumFeatureChain.hxx"
00031 #include "resip/dum/OutgoingEvent.hxx"
00032 #include "resip/dum/DumHelper.hxx"
00033 #include "rutil/Logger.hxx"
00034 #include "rutil/ParseBuffer.hxx"
00035 #include "rutil/WinLeakCheck.hxx"
00036 
00037 #if defined(USE_SSL)
00038 
00039 using namespace resip;
00040 using namespace std;
00041 
00042 #define RESIPROCATE_SUBSYSTEM Subsystem::DUM
00043 
00044 static bool isAckOrCancelOrBye(const SipMessage& msg)
00045 {
00046    MethodTypes method = msg.header(h_RequestLine).getMethod();
00047    return (method == ACK || method == CANCEL || method == BYE);
00048 }
00049 
00050 EncryptionManager::Exception::Exception(const Data& msg, const Data& file, const int line)
00051    : BaseException(msg,file,line)
00052 {
00053 }
00054 
00055 EncryptionManager::EncryptionManager(DialogUsageManager& dum, TargetCommand::Target& target)
00056    : DumFeature(dum, target)
00057 {
00058 }
00059 
00060 EncryptionManager::~EncryptionManager()
00061 {
00062    for (list<Request*>::iterator it = mRequests.begin(); it != mRequests.end(); ++it)
00063    {
00064       delete *it;
00065    }
00066    mRequests.clear();
00067 }
00068 
00069 void EncryptionManager::setRemoteCertStore(std::auto_ptr<RemoteCertStore> store)
00070 {
00071    ErrLog(<< "Async currently is not supported");
00072    assert(0);
00073    //mRemoteCertStore = store;
00074 }
00075 
00076 DumFeature::ProcessingResult EncryptionManager::process(Message* msg)
00077 {
00078    SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg);
00079 
00080    if (sipMsg)
00081    {
00082       if (sipMsg->getContents())
00083       {
00084          if (decrypt(sipMsg))
00085          {
00086             DebugLog(<< "Decrypted message:" << sipMsg << endl);
00087             return DumFeature::FeatureDone;
00088          }
00089          else
00090          {
00091             return DumFeature::EventTaken;
00092          }
00093       }
00094       else
00095       {
00096          return DumFeature::FeatureDone;
00097       }
00098    }
00099 
00100    OutgoingEvent* event = dynamic_cast<OutgoingEvent*>(msg);
00101    if (event)
00102    {
00103       if (!event->message()->getContents())
00104       {
00105          return DumFeature::FeatureDone;
00106       }
00107 
00108       if (!event->message()->getSecurityAttributes() ||
00109           event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel() == SecurityAttributes::None || 
00110           event->message()->getSecurityAttributes()->encryptionPerformed())
00111       {
00112          return DumFeature::FeatureDone;
00113       }
00114       
00115       Data senderAor;
00116       Data recipAor;
00117       if (event->message()->isRequest())
00118       {
00119          senderAor = event->message()->header(h_From).uri().getAor();
00120          recipAor = event->message()->header(h_To).uri().getAor();
00121       }
00122       else
00123       {
00124          senderAor = event->message()->header(h_To).uri().getAor();
00125          recipAor = event->message()->header(h_From).uri().getAor();
00126       }
00127 
00128       Contents* contents = event->message()->getContents();
00129       bool setContents = true;
00130       bool noCerts = false;
00131 
00132       switch (event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel())
00133       {
00134          case SecurityAttributes::None:
00135             setContents = false;
00136             break;
00137          case SecurityAttributes::Encrypt:
00138             contents = encrypt(event->message(), recipAor, &noCerts);
00139             break;
00140          case SecurityAttributes::Sign:
00141             contents = sign(event->message(), senderAor, &noCerts);
00142             break;
00143          case SecurityAttributes::SignAndEncrypt:
00144             contents = signAndEncrypt(event->message(), senderAor, recipAor, &noCerts);
00145             break;
00146       }
00147 
00148       if (contents)
00149       {
00150          if (setContents)
00151          {
00152             event->message()->setContents(auto_ptr<Contents>(contents));
00153             DumHelper::setEncryptionPerformed(*event->message());
00154          }
00155          return DumFeature::FeatureDone;
00156       }
00157       else
00158       {
00159          if (noCerts)
00160          {
00161             return DumFeature::ChainDoneAndEventDone;
00162          }
00163          else
00164          {
00165             //event->releaseMessage();
00166             return DumFeature::EventTaken;
00167          }
00168       }
00169    }
00170 
00171    // Todo: change CertMessage to DumFeatureMessage.
00172    CertMessage* certMsg = dynamic_cast<CertMessage*>(msg);
00173    if (certMsg)
00174    {
00175       EncryptionManager::Result result = processCertMessage(certMsg);
00176       if (result == Complete)
00177       {
00178          return DumFeature::FeatureDone;
00179       }
00180       else
00181       {
00182          delete msg;
00183          return DumFeature::EventTaken;
00184       }
00185    }
00186 
00187    return DumFeature::FeatureDone;
00188 }
00189 
00190 EncryptionManager::Result EncryptionManager::processCertMessage(CertMessage* message)
00191 {
00192    InfoLog( << "Received a cert message: " << *message << endl);
00193    Result ret = Pending;
00194    list<Request*>::iterator it;
00195    for (it = mRequests.begin(); it != mRequests.end(); ++it)
00196    {
00197       if ((*it)->getId() == message->id().mId) break;
00198    }
00199 
00200    if (it != mRequests.end())
00201    {
00202       InfoLog ( << "Processing the cert message" << endl);
00203       ret = (*it)->received(message->success(), message->id().mType, message->id().mAor, message->body());
00204       if (Complete == ret)
00205       {
00206          delete *it;
00207          mRequests.erase(it);
00208       }
00209    }
00210 
00211    return ret;
00212 }
00213 
00214 Contents* EncryptionManager::sign(SharedPtr<SipMessage> msg, 
00215                                   const Data& senderAor,
00216                                   bool* noCerts)
00217 {
00218    Sign* request = new Sign(mDum, mRemoteCertStore.get(), msg, senderAor, *this);
00219    Contents* contents;
00220    *noCerts = false;
00221    bool async = request->sign(&contents, noCerts);
00222    if (async)
00223    {
00224       InfoLog(<< "Async sign" << endl);
00225       //request->setTaken();
00226       mRequests.push_back(request);
00227    }
00228    else
00229    {
00230       delete request;
00231    }
00232    return contents;
00233 }
00234 
00235 Contents* EncryptionManager::encrypt(SharedPtr<SipMessage> msg,
00236                                      const Data& recipientAor,
00237                                      bool* noCerts)
00238 {
00239    Encrypt* request = new Encrypt(mDum, mRemoteCertStore.get(), msg, recipientAor, *this);
00240    Contents* contents;
00241    *noCerts = false;
00242    bool async = request->encrypt(&contents, noCerts);
00243    if (async)
00244    {
00245       InfoLog(<< "Async encrypt" << endl);
00246       //request->setTaken();
00247       mRequests.push_back(request);
00248    }
00249    else
00250    {
00251       delete request;
00252    }
00253    return contents;
00254 }
00255 
00256 Contents* EncryptionManager::signAndEncrypt(SharedPtr<SipMessage> msg,
00257                                             const Data& senderAor,
00258                                             const Data& recipAor,
00259                                             bool* noCerts)
00260 {
00261    SignAndEncrypt* request = new SignAndEncrypt(mDum, mRemoteCertStore.get(), msg, senderAor, recipAor, *this);
00262    Contents* contents;
00263    *noCerts = false;
00264    bool async = request->signAndEncrypt(&contents, noCerts);
00265    if (!async)
00266    {
00267       delete request;
00268    }
00269    else
00270    {
00271       InfoLog(<< "Async sign and encrypt" << endl);
00272       //request->setTaken();
00273       mRequests.push_back(request);
00274    }
00275    return contents;
00276 }
00277 
00278 bool EncryptionManager::decrypt(SipMessage* msg)
00279 {
00280    Decrypt* request = new Decrypt(mDum, mRemoteCertStore.get(), msg, *this);
00281    bool ret = true;
00282    
00283    Helper::ContentsSecAttrs csa;
00284    ret = request->decrypt(csa);
00285 
00286    if (ret)
00287    {
00288       if (csa.mContents.get())
00289       {
00290          msg->setContents(csa.mContents);
00291          
00292          if (csa.mAttributes.get()) 
00293          {
00294             // Security Attributes might already exist on the message if the Identity Handler is enabled
00295             // if so, ensure we maintain the Identity Strength
00296             const SecurityAttributes *origSecurityAttributes = msg->getSecurityAttributes();
00297             if(origSecurityAttributes)
00298             {
00299                 csa.mAttributes->setIdentityStrength(origSecurityAttributes->getIdentityStrength());
00300             }
00301             msg->setSecurityAttributes(csa.mAttributes);
00302          }
00303       }
00304       else
00305       {
00306          // no valid contents.
00307          request->handleInvalidContents();
00308 
00309          if (msg->isRequest() && !isAckOrCancelOrBye(*msg))
00310          {
00311             ret = false;
00312          }
00313       }
00314       delete request;
00315    }   
00316    else
00317    {
00318       InfoLog(<< "Async decrypt" << endl);
00319       mRequests.push_back(request);
00320    }
00321    
00322    return ret;
00323 }
00324 
00325 EncryptionManager::Request::Request(DialogUsageManager& dum,
00326                                     RemoteCertStore* store,
00327                                     SharedPtr<SipMessage> msg,
00328                                     DumFeature& feature)
00329     : mDum(dum),
00330      mStore(store),
00331      mMsgToEncrypt(msg),
00332      mPendingRequests(0),
00333      mFeature(feature)
00334      //mTaken(false)
00335 {
00336 }
00337 
00338 EncryptionManager::Request::~Request()
00339 {
00340    /*
00341    if (mTaken)
00342    {
00343       delete mMsg;
00344    }
00345    */
00346 }
00347 
00348 void EncryptionManager::Request::response415()
00349 {
00350    SipMessage* response = Helper::makeResponse(*mMsgToEncrypt, 415);
00351    mDum.post(response);
00352    InfoLog(<< "Generated 415" << endl);
00353 }
00354 
00355 EncryptionManager::Sign::Sign(DialogUsageManager& dum,
00356                               RemoteCertStore* store,
00357                               SharedPtr<SipMessage> msg, 
00358                               const Data& senderAor,
00359                               DumFeature& feature)
00360    : Request(dum, store, msg, feature),
00361      mSenderAor(senderAor)
00362 {
00363 }
00364 
00365 EncryptionManager::Sign::~Sign()
00366 {
00367 }
00368 
00369 bool EncryptionManager::Sign::sign(Contents** contents, bool* noCerts)
00370 {
00371    *contents = 0;
00372    *noCerts = false;
00373    bool async = false;
00374 
00375    MultipartSignedContents* msc = 0;
00376    bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor);
00377    bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor);
00378 
00379    if (!missingCert && !missingKey)
00380    {
00381       InfoLog(<< "Signing message" << endl);
00382       msc =  mDum.getSecurity()->sign(mSenderAor, mMsgToEncrypt->getContents());
00383       *contents = msc;
00384    }
00385    else
00386    {
00387       if (mStore)
00388       {
00389          if (missingCert)
00390          {
00391             InfoLog(<< "Fetching cert for " << mSenderAor << endl);
00392             ++mPendingRequests;
00393             MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert);
00394             mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
00395          }
00396          if (missingKey)
00397          {
00398             InfoLog(<< "Fetching private key for " << mSenderAor << endl);
00399             ++mPendingRequests;
00400             MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey);
00401             mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
00402          }
00403          async = true;
00404       }
00405       else
00406       {
00407          InfoLog(<< "No remote cert store installed" << endl);
00408          *noCerts = true;
00409          response415();
00410       }
00411    }
00412 
00413    return async;
00414 }
00415 
00416 EncryptionManager::Result EncryptionManager::Sign::received(bool success, 
00417                                                             MessageId::Type type,
00418                                                             const Data& aor, 
00419                                                             const Data& data)
00420 {
00421    assert(mSenderAor==aor);
00422    assert(mPendingRequests>0&&mPendingRequests<=2);
00423    Result result = Pending;
00424 
00425    if (success)
00426    {
00427       if (type == MessageId::UserCert)
00428       {
00429          InfoLog(<< "Adding cert for: " << aor << endl);
00430          mDum.getSecurity()->addUserCertDER(aor, data);
00431       }
00432       else
00433       {
00434          InfoLog(<< "Adding private key for " << aor << endl);
00435          mDum.getSecurity()->addUserPrivateKeyDER(aor, data);
00436       }         
00437       if (--mPendingRequests == 0)
00438       {
00439          InfoLog(<< "Signing message" << endl);
00440          MultipartSignedContents* msc = mDum.getSecurity()->sign(aor, mMsgToEncrypt->getContents());
00441          mMsgToEncrypt->setContents(auto_ptr<Contents>(msc));
00442          DumHelper::setEncryptionPerformed(*mMsgToEncrypt);
00443          OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt);
00444          //mTaken = false;
00445          mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event)));
00446          result = Complete;
00447       }
00448    }
00449    else
00450    {
00451       InfoLog(<< "Failed to fetch " << ((type==MessageId::UserCert)? "cert " : "private key ") << "for " << aor <<endl);
00452       response415();
00453       result = Complete;
00454    }
00455    return result;
00456 }
00457 
00458 EncryptionManager::Encrypt::Encrypt(DialogUsageManager& dum, 
00459                                     RemoteCertStore* store, 
00460                                     SharedPtr<SipMessage> msg, 
00461                                     const Data& recipientAor,
00462                                     DumFeature& feature)
00463    : Request(dum, store, msg, feature),
00464      mRecipientAor(recipientAor)
00465 {
00466 }
00467 
00468 EncryptionManager::Encrypt::~Encrypt()
00469 {
00470 }
00471 
00472 bool EncryptionManager::Encrypt::encrypt(Contents** contents, bool* noCerts)
00473 {
00474    *contents = 0;
00475    *noCerts = false;
00476    bool async = false;
00477 
00478    if (mDum.getSecurity()->hasUserCert(mRecipientAor))
00479    {
00480       InfoLog(<< "Encrypting message" << endl);
00481       MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(mMsgToEncrypt->getContents());
00482       if (alt)
00483       {
00484          // encrypt the last part.
00485          MultipartMixedContents::Parts parts = alt->parts();
00486          Contents* last = mDum.getSecurity()->encrypt(parts.back(), mRecipientAor);
00487          if (last)
00488          {
00489             MultipartAlternativeContents* mac = new MultipartAlternativeContents(*alt);
00490             delete mac->parts().back();
00491             mac->parts().pop_back();
00492             mac->parts().push_back(last);
00493             *contents = mac;
00494          }
00495       }
00496       else
00497       {
00498          *contents =  mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), mRecipientAor);
00499       }
00500    }
00501    else
00502    {
00503       if (mStore)
00504       {
00505          InfoLog(<< "Fetching cert for " << mRecipientAor << endl);
00506          ++mPendingRequests;
00507          MessageId id(mMsgToEncrypt->getTransactionId(), mRecipientAor, MessageId::UserCert);
00508          mStore->fetch(mRecipientAor, MessageId::UserCert, id, mDum);
00509          async = true;
00510       }
00511       else
00512       {
00513          InfoLog(<< "No remote cert store installed" << endl);
00514          *noCerts = true;
00515          response415();
00516       }
00517    }
00518    return async;
00519 }
00520 
00521 EncryptionManager::Result EncryptionManager::Encrypt::received(bool success, 
00522                                                                MessageId::Type type,
00523                                                                const Data& aor, 
00524                                                                const Data& data)
00525 {
00526    assert(mRecipientAor==aor);
00527    assert(type==MessageId::UserCert);
00528    assert(mPendingRequests==1);
00529    if (success)
00530    {
00531       InfoLog(<< "Adding user cert for " << aor << endl);
00532       mDum.getSecurity()->addUserCertDER(aor, data);
00533       --mPendingRequests;
00534       InfoLog(<< "Encrypting message" << endl);
00535       Pkcs7Contents* encrypted = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), aor);
00536       mMsgToEncrypt->setContents(auto_ptr<Contents>(encrypted));
00537       DumHelper::setEncryptionPerformed(*mMsgToEncrypt);
00538       OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt);
00539       //mTaken = false;
00540       mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event)));      
00541    }
00542    else
00543    {
00544       InfoLog(<< "Failed to fetch cert for " << aor << endl);
00545       response415();
00546    }
00547    return Complete;
00548 }
00549 
00550 EncryptionManager::SignAndEncrypt::SignAndEncrypt(DialogUsageManager& dum, 
00551                                                   RemoteCertStore* store, 
00552                                                   SharedPtr<SipMessage> msg, 
00553                                                   const Data& senderAor, 
00554                                                   const Data& recipientAor,
00555                                                   DumFeature& feature)
00556    : Request(dum, store, msg, feature),
00557      mSenderAor(senderAor),
00558      mRecipientAor(recipientAor)
00559 {
00560 }
00561 
00562 EncryptionManager::SignAndEncrypt::~SignAndEncrypt()
00563 {
00564 }
00565 
00566 bool EncryptionManager::SignAndEncrypt::signAndEncrypt(Contents** contents, bool* noCerts)
00567 {
00568    *contents = 0;
00569    *noCerts = false;
00570    bool async = false;
00571    bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor);
00572    bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor);
00573    bool missingRecipCert = !mDum.getSecurity()->hasUserCert(mRecipientAor);
00574 
00575    if (!missingCert && !missingKey && !missingRecipCert)
00576    {
00577       InfoLog(<< "Encrypting and signing message" << endl);
00578       *contents = doWork();
00579    }
00580    else
00581    {
00582       if (mStore)
00583       {
00584          if (missingCert)
00585          {
00586             InfoLog(<< "Fetching cert for " << mSenderAor << endl);
00587             ++mPendingRequests;
00588             MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert);
00589             mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
00590          }
00591          if (missingKey)
00592          {
00593             InfoLog(<< "Fetching private key for " << mSenderAor << endl);
00594             ++mPendingRequests;
00595             MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey);
00596             mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
00597          }
00598          if (missingRecipCert)
00599          {
00600             InfoLog(<< "Fetching cert for " << mRecipientAor << endl);
00601             ++mPendingRequests;
00602             MessageId id(mMsgToEncrypt->getTransactionId(), mRecipientAor, MessageId::UserCert);
00603             mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
00604          }
00605          async = true;
00606       }
00607       else
00608       {
00609          InfoLog(<< "No remote cert store installed" << endl);
00610          *noCerts = true;
00611          response415();
00612       }
00613    }
00614 
00615    return async;
00616 }
00617 
00618 EncryptionManager::Result EncryptionManager::SignAndEncrypt::received(bool success, 
00619                                                                       MessageId::Type type,
00620                                                                       const Data& aor, 
00621                                                                       const Data& data)
00622 {
00623    assert(mPendingRequests>0&&mPendingRequests<=3);
00624    Result result = Pending;
00625    if (success)
00626    {
00627       if (type == MessageId::UserCert)
00628       {
00629          assert(aor==mSenderAor||aor==mRecipientAor);
00630          InfoLog(<< "Adding user cert for " << aor << endl);
00631          mDum.getSecurity()->addUserCertDER(aor, data);
00632       }
00633       else
00634       {
00635          assert(aor==mSenderAor);
00636          InfoLog(<< "Adding private key for " << aor << endl);
00637          mDum.getSecurity()->addUserPrivateKeyDER(aor, data);
00638       }
00639 
00640       if (--mPendingRequests == 0)
00641       {
00642          InfoLog(<< "Encrypting and signing message" << endl);
00643          Contents* contents = doWork();
00644          mMsgToEncrypt->setContents(auto_ptr<Contents>(contents));
00645          DumHelper::setEncryptionPerformed(*mMsgToEncrypt);
00646          OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt);
00647          //mTaken = false;
00648          mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr<Message>(event)));
00649          result = Complete;
00650       }
00651    }
00652    else
00653    {
00654       InfoLog(<< "Failed to fetch cert for " << aor << endl);
00655       response415();
00656       result = Complete;
00657    }
00658    return result;
00659 }
00660 
00661 Contents* EncryptionManager::SignAndEncrypt::doWork()
00662 {
00663    Contents* contents = 0;
00664    MultipartAlternativeContents* mac = dynamic_cast<MultipartAlternativeContents*>(mMsgToEncrypt->getContents());
00665    if (mac)
00666    {
00667       MultipartMixedContents::Parts parts = mac->parts();
00668       Pkcs7Contents* pkcs7 = mDum.getSecurity()->encrypt(parts.back(), mRecipientAor);
00669       if (pkcs7)
00670       {
00671          MultipartAlternativeContents* alt = new MultipartAlternativeContents(*mac);
00672          delete alt->parts().back();
00673          alt->parts().pop_back();
00674          alt->parts().push_back(pkcs7);
00675          contents = alt;
00676       }
00677    }
00678    else
00679    {
00680       contents = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents() , mRecipientAor);
00681    }
00682 
00683    if (contents)
00684    {
00685       contents = mDum.getSecurity()->sign(mSenderAor, contents);
00686    }
00687 
00688    return contents;
00689 }
00690 
00691 EncryptionManager::Decrypt::Decrypt(DialogUsageManager& dum,
00692                                     RemoteCertStore* store, 
00693                                     SipMessage* msg,
00694                                     DumFeature& feature)
00695    : Request(dum, store, SharedPtr<SipMessage>(), feature),
00696      mIsEncrypted(false),
00697      mMsgToDecrypt(msg),
00698      mMessageTaken(false)
00699 {
00700    if (msg->isResponse())
00701    {
00702       mDecryptor = msg->header(h_From).uri().getAor();
00703       mSigner = msg->header(h_To).uri().getAor();
00704    }
00705    else
00706    {
00707       mDecryptor = msg->header(h_To).uri().getAor();
00708       mSigner = msg->header(h_From).uri().getAor();
00709    }
00710 }
00711 
00712 EncryptionManager::Decrypt::~Decrypt()
00713 {
00714    if (mMessageTaken)
00715    {
00716       delete mMsgToDecrypt;
00717    }
00718 }
00719 
00720 bool EncryptionManager::Decrypt::decrypt(Helper::ContentsSecAttrs& csa)
00721 {
00722    bool noDecryptionKey = false;
00723 
00724    if (!dynamic_cast<Pkcs7Contents*>(mMsgToDecrypt->getContents()))
00725    {
00726       mOriginalMsgContents = Data(mMsgToDecrypt->getContents()->getHeaderField().getBuffer(), mMsgToDecrypt->getContents()->getHeaderField().getLength());
00727       mOriginalMsgContentsType = mMsgToDecrypt->getContents()->getType();
00728    }
00729    else
00730    {
00731       mIsEncrypted = true;
00732    }
00733 
00734    if (isEncrypted())
00735    {
00736       bool missingDecryptorCert = !mDum.getSecurity()->hasUserCert(mDecryptor);
00737       bool missingDecryptorKey = !mDum.getSecurity()->hasUserPrivateKey(mDecryptor);
00738       if (missingDecryptorCert || missingDecryptorKey)
00739       {
00740          if (mStore)
00741          {
00742             if (missingDecryptorCert)
00743             {
00744                InfoLog(<< "Fetching user cert for " << mDecryptor << endl);
00745                ++mPendingRequests;
00746                MessageId id(mMsgToDecrypt->getTransactionId(), mDecryptor, MessageId::UserCert);
00747                mStore->fetch(mDecryptor, MessageId::UserCert, id, mDum);
00748             }
00749 
00750             if (missingDecryptorKey)
00751             {
00752                InfoLog(<< "Fetching private key for " << mDecryptor << endl);
00753                ++mPendingRequests;
00754                MessageId id(mMsgToDecrypt->getTransactionId(), mDecryptor, MessageId::UserPrivateKey);
00755                mStore->fetch(mDecryptor, MessageId::UserPrivateKey, id, mDum);
00756             }
00757             mMessageTaken = true;
00758             return false;
00759          }
00760          else
00761          {
00762             InfoLog(<< "No remote cert store installed" << endl);
00763             noDecryptionKey = true;
00764          }
00765       }
00766    }
00767 
00768    if (isSigned(noDecryptionKey))
00769    {
00770       if (!mDum.getSecurity()->hasUserCert(mSigner))
00771       {
00772          if (mStore)
00773          {
00774             InfoLog(<< "Fetching user cert for " << mSigner << endl);
00775             ++mPendingRequests;
00776             MessageId id(mMsgToDecrypt->getTransactionId(), mSigner, MessageId::UserCert);
00777             mStore->fetch(mSigner, MessageId::UserCert, id, mDum);
00778             mMessageTaken = true;
00779             return false;
00780          }
00781          else
00782          {
00783             InfoLog(<< "No remote cert store installed" << endl);
00784          }
00785       }
00786    }
00787 
00788    csa = getContents(mMsgToDecrypt, *mDum.getSecurity(), noDecryptionKey);
00789    return true;
00790 }
00791 
00792 EncryptionManager::Result EncryptionManager::Decrypt::received(bool success, 
00793                                                                MessageId::Type type, 
00794                                                                const Data& aor, 
00795                                                                const Data& data)
00796 {
00797    Result result = Complete;
00798    assert(mPendingRequests>0 && mPendingRequests<=2);
00799    if (success)
00800    {
00801       if (aor == mSigner)
00802       {
00803          assert(MessageId::UserCert == type);
00804          assert(mPendingRequests==1);
00805          --mPendingRequests;
00806          InfoLog(<< "Adding user cert for " << aor << endl);
00807          mDum.getSecurity()->addUserCertDER(aor, data);
00808       }
00809       else
00810       {
00811          assert(aor == mDecryptor);
00812          if (MessageId::UserCert == type)
00813          {
00814             InfoLog(<< "Adding user cert for " << aor << endl);
00815             mDum.getSecurity()->addUserCertDER(aor, data);
00816          }
00817          else
00818          {
00819             InfoLog(<< "Adding private key for " << aor << endl);
00820             mDum.getSecurity()->addUserPrivateKeyDER(aor, data);
00821          }
00822 
00823          if (--mPendingRequests == 0)
00824          {
00825             if (isSigned(false))
00826             {
00827                if (!mDum.getSecurity()->hasUserCert(mSigner))
00828                {
00829                   InfoLog(<< "Fetching user cert for " << mSigner << endl);
00830                   ++mPendingRequests;
00831                   MessageId id(mMsgToDecrypt->getTransactionId(), mSigner, MessageId::UserCert);
00832                   mStore->fetch(mSigner, MessageId::UserCert, id, mDum);
00833                   result = Pending;
00834                }
00835             }
00836          }
00837          else
00838          {
00839             result = Pending;
00840          }
00841       }
00842    }
00843    else
00844    {
00845       InfoLog(<< "Failed to fetch cert for " << aor << endl);
00846    }
00847 
00848    if (Complete == result)
00849    {
00850       Helper::ContentsSecAttrs csa;
00851       csa = getContents(mMsgToDecrypt, *mDum.getSecurity(), 
00852                         (!mDum.getSecurity()->hasUserCert(mDecryptor) || !mDum.getSecurity()->hasUserPrivateKey(mDecryptor)));
00853 
00854 
00855       if (csa.mContents.get())
00856       {
00857          csa.mContents->checkParsed();
00858          mMsgToDecrypt->setContents(csa.mContents);
00859          
00860          if (csa.mAttributes.get()) 
00861          {
00862             mMsgToDecrypt->setSecurityAttributes(csa.mAttributes);
00863          }         
00864       }
00865       else
00866       {
00867          // no valid contents.
00868          ErrLog(<< "No valid contents in message received" << endl);
00869          handleInvalidContents();
00870 
00871          if (mMsgToDecrypt->isRequest() && !isAckOrCancelOrBye(*mMsgToDecrypt))
00872          {
00873             return result;
00874          }
00875       }      
00876 
00877       // Todo: make CertMessage DumFeatureMessage and get rid of DumDecrypted.
00878       // Currently the message will not be processed by 
00879       // any features in the chain after EncryptionManager.
00880       DumDecrypted* decrypted = new DumDecrypted(*mMsgToDecrypt);
00881       mDum.post(decrypted);
00882    }
00883 
00884    return result;
00885 }
00886 
00887 bool EncryptionManager::Decrypt::isEncrypted()
00888 {
00889    Contents* contents = mMsgToDecrypt->getContents();
00890    return isEncryptedRecurse(&contents);
00891 }
00892 
00893 bool EncryptionManager::Decrypt::isSigned(bool noDecryptionKey)
00894 {
00895    Contents* contents = mMsgToDecrypt->getContents();
00896    return isSignedRecurse(&contents, mDecryptor, noDecryptionKey);
00897 }
00898 
00899 bool EncryptionManager::Decrypt::isEncryptedRecurse(Contents** contents)
00900 {
00901    InvalidContents* ic;
00902    if ((ic = dynamic_cast<InvalidContents*>(*contents)))
00903    {
00904       return false;
00905    }
00906 
00907    Pkcs7Contents* pk;
00908    if ((pk = dynamic_cast<Pkcs7Contents*>(*contents)))
00909    {
00910       return true;
00911    }
00912 
00913    MultipartSignedContents* mps;
00914    if ((mps = dynamic_cast<MultipartSignedContents*>(*contents)))
00915    {
00916       try
00917       {
00918          mps->parts();
00919       }
00920       catch (BaseException& e)
00921       {
00922          // structure of multipart is bad. this is unrecoverable error,
00923          // replace the whole multipart contents with an InvalidContents.
00924          ErrLog(<< e.name() << endl << e.getMessage());
00925 
00926          if (*contents == mMsgToDecrypt->getContents())
00927          {
00928             mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(mps)));
00929          }
00930          else
00931          {
00932             *contents = createInvalidContents(mps);
00933             delete mps;
00934          }
00935          return false;
00936       }
00937 
00938       return isEncryptedRecurse(&(*(mps->parts().begin())));
00939    }
00940 
00941    MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(*contents);
00942    if (alt)
00943    {
00944       try
00945       {
00946          alt->parts();
00947       }
00948       catch (BaseException& e)
00949       {
00950          ErrLog(<< e.name() << endl << e.getMessage());
00951          if (*contents == mMsgToDecrypt->getContents())
00952          {
00953             mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(alt)));
00954          }
00955          else
00956          {
00957             *contents = createInvalidContents(alt);
00958             delete alt;
00959          }
00960          return false;
00961       }
00962 
00963       for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin();
00964            i != alt->parts().rend(); ++i)
00965       {
00966          if (isEncryptedRecurse(&(*i)))
00967          {
00968             return true;
00969          }
00970       }
00971 
00972       return false;
00973    }
00974 
00975    if (dynamic_cast<MultipartMixedContents*>(*contents))
00976    {
00977       return false;
00978    }
00979 
00980    return false;
00981 }
00982 
00983 bool EncryptionManager::Decrypt::isSignedRecurse(Contents** contents,
00984                                                  const Data& decryptorAor,
00985                                                  bool noDecryptionKey)
00986 {
00987    InvalidContents* ic;
00988    if ((ic = dynamic_cast<InvalidContents*>(*contents)))
00989    {
00990       return false;
00991    }
00992 
00993    Pkcs7Contents* pk;
00994    if ((pk = dynamic_cast<Pkcs7Contents*>(*contents)))
00995    {
00996       if (noDecryptionKey) 
00997       {
00998          return false;
00999       }
01000 
01001       Contents* decrypted = mDum.getSecurity()->decrypt(decryptorAor, pk);
01002       bool ret = false;
01003       
01004       if (decrypted)
01005       {
01006          if (*contents == mMsgToDecrypt->getContents())
01007          {
01008             mOriginalMsgContents = Data(decrypted->getHeaderField().getBuffer(), decrypted->getHeaderField().getLength());
01009             mOriginalMsgContentsType = decrypted->getType();
01010          }
01011          
01012          try
01013          {
01014             decrypted->checkParsed();
01015             if (isMultipart(decrypted))
01016             {
01017                if (dynamic_cast<MultipartSignedContents*>(decrypted))
01018                {
01019                   ret = true;
01020                }
01021                else
01022                {
01023                   if (*contents == mMsgToDecrypt->getContents())
01024                   {
01025                      mMsgToDecrypt->setContents(auto_ptr<Contents>(decrypted));
01026                      *contents = mMsgToDecrypt->getContents();
01027                   }
01028                   else
01029                   {
01030                      *contents = decrypted;
01031                      delete pk;
01032                   }
01033                   return isSignedRecurse(contents, decryptorAor, noDecryptionKey);
01034                }
01035             }
01036          }
01037          catch (BaseException& e)
01038          {
01039             ErrLog(<< e.name() << endl << e.getMessage());
01040 
01041             if (*contents == mMsgToDecrypt->getContents())
01042             {
01043                mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(decrypted)));
01044             }
01045             else
01046             {
01047                *contents = createInvalidContents(decrypted);
01048                delete pk;
01049             }
01050          }
01051 
01052          delete decrypted;
01053       }
01054 
01055       return ret;
01056    }
01057 
01058    MultipartSignedContents* mps;
01059    if ((mps = dynamic_cast<MultipartSignedContents*>(*contents)))
01060    {
01061       return true;
01062    }
01063 
01064    MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(*contents);
01065    if (alt)
01066    {
01067       try
01068       {
01069          alt->parts();
01070       }
01071       catch (BaseException& e)
01072       {
01073          // structure of multipart is bad. this is unrecoverable error,
01074          // replace the whole multipart contents with an InvalidContents.
01075          ErrLog(<< e.name() << endl << e.getMessage());
01076 
01077          if (*contents == mMsgToDecrypt->getContents())
01078          {
01079             mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(alt)));
01080          }
01081          else
01082          {
01083             *contents = createInvalidContents(alt);
01084             delete alt;
01085          }
01086 
01087          return false;
01088       }
01089 
01090       for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin();
01091            i != alt->parts().rend(); ++i)
01092       {
01093          if (isSignedRecurse(&(*i), decryptorAor, noDecryptionKey))
01094          {
01095             return true;
01096          }
01097       }
01098 
01099       return false;
01100    }
01101 
01102    if (dynamic_cast<MultipartMixedContents*>(*contents))
01103    {
01104       return false;
01105    }
01106 
01107    return false;
01108 }
01109 
01110 Helper::ContentsSecAttrs EncryptionManager::Decrypt::getContents(SipMessage* message,
01111                                                                  Security& security,
01112                                                                  bool noDecryptionKey)
01113 {
01114    SecurityAttributes* attr = new SecurityAttributes;
01115    attr->setIdentity(message->header(h_From).uri().getAor());
01116    Contents* contents = message->getContents();
01117    if (contents)
01118    {
01119       contents = getContentsRecurse(&contents, security, noDecryptionKey, attr);
01120    }
01121 
01122    if (contents)
01123    {
01124       if (mIsEncrypted)
01125       {
01126          attr->setEncrypted();
01127       }
01128    }
01129 
01130    std::auto_ptr<Contents> c(contents);
01131    std::auto_ptr<SecurityAttributes> a(attr);
01132    return Helper::ContentsSecAttrs(c, a);
01133 }
01134 
01135 Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree,
01136                                                          Security& security,
01137                                                          bool noDecryptionKey,
01138                                                          SecurityAttributes* attributes)
01139 {
01140    InvalidContents* ic;
01141    if ((ic = dynamic_cast<InvalidContents*>(*tree)))
01142    {
01143       return 0;
01144    }
01145 
01146    Pkcs7Contents* pk;
01147    if ((pk = dynamic_cast<Pkcs7Contents*>(*tree)))
01148    {
01149       if (noDecryptionKey) 
01150       {
01151          return 0;
01152       }
01153 
01154       Contents* contents = security.decrypt(mDecryptor, pk);
01155       if (contents)
01156       {
01157          if (*tree == mMsgToDecrypt->getContents())
01158          {
01159             mOriginalMsgContents = Data(contents->getHeaderField().getBuffer(), contents->getHeaderField().getLength());
01160             mOriginalMsgContentsType = contents->getType();
01161          }
01162 
01163          try
01164          {
01165             contents->checkParsed();
01166             if (isMultipart(contents))
01167             {
01168                if (*tree == mMsgToDecrypt->getContents())
01169                {
01170                   mMsgToDecrypt->setContents(auto_ptr<Contents>(contents));
01171                   *tree = mMsgToDecrypt->getContents();
01172                }
01173                else
01174                {
01175                   *tree = contents;
01176                   delete pk;
01177                }
01178 
01179                return getContentsRecurse(tree, security, noDecryptionKey, attributes);
01180             }
01181             else
01182             {
01183                attributes->setEncrypted();
01184             }
01185          }
01186          catch (BaseException& e)
01187          {
01188             ErrLog(<< e.name() << endl << e.getMessage());
01189 
01190             if (*tree == mMsgToDecrypt->getContents())
01191             {
01192                mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(contents)));
01193             }
01194             else
01195             {
01196                *tree = createInvalidContents(contents);
01197                delete pk;
01198             }
01199 
01200             delete contents;
01201             return 0;
01202          }
01203       }
01204 
01205       return contents;
01206    }
01207 
01208    MultipartSignedContents* mps;
01209    if ((mps = dynamic_cast<MultipartSignedContents*>(*tree)))
01210    {
01211       Data signer;
01212       SignatureStatus sigStatus = SignatureIsBad;
01213       Contents* tmp = security.checkSignature(mps, &signer, &sigStatus);
01214       Contents* contents = getContentsRecurse(&tmp,
01215                                               security, noDecryptionKey, attributes);
01216       attributes->setSigner(signer);
01217       attributes->setSignatureStatus(sigStatus);
01218       return contents;
01219    }
01220 
01221    MultipartAlternativeContents* alt;
01222    if ((alt = dynamic_cast<MultipartAlternativeContents*>(*tree)))
01223    {
01224       try
01225       {
01226          alt->parts();
01227       }
01228       catch (BaseException& e)
01229       {
01230          // structure of multipart is bad. this is an unrecoverable error,
01231          // replace the whole multipart contents with an InvalidContents.
01232          ErrLog(<< e.name() << endl << e.getMessage());
01233 
01234          if (*tree == mMsgToDecrypt->getContents())
01235          {
01236             mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(alt)));
01237          }
01238          else
01239          {
01240             *tree = createInvalidContents(alt);
01241             delete alt;
01242          }
01243 
01244          return 0;
01245       }
01246 
01247       for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin();
01248            i != alt->parts().rend(); ++i)
01249       {
01250          Contents* contents = getContentsRecurse(&(*i), security, noDecryptionKey, attributes);
01251          if (contents)
01252          {
01253             return contents;
01254          }
01255       }
01256 
01257       return 0;
01258    }
01259 
01260    MultipartMixedContents* mult;
01261    if ((mult = dynamic_cast<MultipartMixedContents*>(*tree)))
01262    {
01263       try
01264       {
01265          mult->parts();
01266       }
01267       catch (BaseException& e)
01268       {
01269          // structure of multipart is bad. this is unrecoverable error,
01270          // replace the whole multipart contents with an InvalidContents.
01271          ErrLog(<< e.name() << endl << e.getMessage());
01272 
01273          if (*tree == mMsgToDecrypt->getContents())
01274          {
01275             mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(mult)));
01276          }
01277          else
01278          {
01279             *tree = createInvalidContents(mult);
01280             delete mult;
01281          }
01282 
01283          return 0;
01284       }
01285 
01286       // for now, the multipart/mixed is returned untouched.
01287       return mult->clone();
01288    }
01289 
01290    Contents* ret = 0;
01291 
01292    try
01293    {
01294       (*tree)->checkParsed();
01295       ret = (*tree)->clone();
01296    }
01297    catch (BaseException& e)
01298    {
01299       ErrLog(<< e.name() << endl << e.getMessage());
01300 
01301       if (*tree == mMsgToDecrypt->getContents())
01302       {
01303          mMsgToDecrypt->setContents(auto_ptr<Contents>(createInvalidContents(*tree)));
01304       }
01305       else
01306       {
01307          Contents* tmp = *tree;
01308          *tree = createInvalidContents(*tree);
01309          delete tmp;
01310       }
01311    }
01312 
01313    return ret;
01314 
01315 }
01316 
01317 // Todo: move to DumHelper.
01318 InvalidContents*
01319 EncryptionManager::Decrypt::createInvalidContents(Contents* orig)
01320 {
01321    Data original(orig->getHeaderField().getBuffer(), orig->getHeaderField().getLength());
01322    return new InvalidContents(original, orig->getType());
01323 }
01324 
01325 bool
01326 EncryptionManager::Decrypt::isMultipart(Contents* contents)
01327 {
01328    return (
01329       dynamic_cast<MultipartSignedContents*>(contents) ||
01330       dynamic_cast<MultipartAlternativeContents*>(contents) ||
01331       dynamic_cast<MultipartMixedContents*>(contents)
01332       );
01333 }
01334 
01335 void
01336 EncryptionManager::Decrypt::handleInvalidContents()
01337 {
01338    if (mMsgToDecrypt->isRequest())
01339    {
01340       if (isAckOrCancelOrBye(*mMsgToDecrypt))
01341       {
01342          DebugLog(<< "No valid contents in the request" << endl);
01343          InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType);
01344          mMsgToDecrypt->setContents(auto_ptr<Contents>(invalid));
01345       }
01346       else
01347       {
01348          DebugLog(<< "No valid contents in the request -- reject with 400" << endl);
01349          SipMessage response;
01350          Helper::makeResponse(response, *mMsgToDecrypt, 400, Data::Empty, mMsgToDecrypt->header(h_RequestLine).uri().host() , "Invalid message body");
01351          mDum.getSipStack().send(response);
01352       }
01353    }
01354    else
01355    {
01356       DebugLog(<< "No valid contents in the response" << endl);
01357       InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType);
01358       mMsgToDecrypt->setContents(auto_ptr<Contents>(invalid));
01359    }
01360 }
01361 
01362 #endif
01363 
01364 /* ====================================================================
01365  * The Vovida Software License, Version 1.0 
01366  * 
01367  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
01368  * 
01369  * Redistribution and use in source and binary forms, with or without
01370  * modification, are permitted provided that the following conditions
01371  * are met:
01372  * 
01373  * 1. Redistributions of source code must retain the above copyright
01374  *    notice, this list of conditions and the following disclaimer.
01375  * 
01376  * 2. Redistributions in binary form must reproduce the above copyright
01377  *    notice, this list of conditions and the following disclaimer in
01378  *    the documentation and/or other materials provided with the
01379  *    distribution.
01380  * 
01381  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
01382  *    and "Vovida Open Communication Application Library (VOCAL)" must
01383  *    not be used to endorse or promote products derived from this
01384  *    software without prior written permission. For written
01385  *    permission, please contact vocal@vovida.org.
01386  *
01387  * 4. Products derived from this software may not be called "VOCAL", nor
01388  *    may "VOCAL" appear in their name, without prior written
01389  *    permission of Vovida Networks, Inc.
01390  * 
01391  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
01392  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
01393  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
01394  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
01395  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
01396  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
01397  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
01398  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
01399  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
01400  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
01401  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
01402  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
01403  * DAMAGE.
01404  * 
01405  * ====================================================================
01406  * 
01407  * This software consists of voluntary contributions made by Vovida
01408  * Networks, Inc. and many individuals on behalf of Vovida Networks,
01409  * Inc.  For more information on Vovida Networks, Inc., please see
01410  * <http://www.vovida.org/>.
01411  *
01412  */