reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
EncryptionManager.cxx
Go to the documentation of this file.
1
2#if defined(HAVE_CONFIG_H)
3 #include "config.h"
4#endif
5
7
9
10#include "rutil/ResipAssert.h"
11#include <list>
16#include "resip/dum/Handles.hxx"
33#include "rutil/Logger.hxx"
34#include "rutil/ParseBuffer.hxx"
36
37#include <utility>
38
39#if defined(USE_SSL)
40
41using namespace resip;
42using namespace std;
43
44#define RESIPROCATE_SUBSYSTEM Subsystem::DUM
45
46static bool isAckOrCancelOrBye(const SipMessage& msg)
47{
48 const MethodTypes method = msg.header(h_RequestLine).getMethod();
49 return (method == ACK || method == CANCEL || method == BYE);
50}
51
52EncryptionManager::Exception::Exception(const Data& msg, const Data& file, const int line)
53 : BaseException(msg,file,line)
54{
55}
56
61
63{
64 for (list<Request*>::iterator it = mRequests.begin(); it != mRequests.end(); ++it)
65 {
66 delete *it;
67 }
68 mRequests.clear();
69}
70
71void EncryptionManager::setRemoteCertStore(std::unique_ptr<RemoteCertStore> store)
72{
73 ErrLog(<< "Async currently is not supported");
74 resip_assert(0);
75 //mRemoteCertStore = store;
76}
77
79{
80 SipMessage* sipMsg = dynamic_cast<SipMessage*>(msg);
81
82 if (sipMsg)
83 {
84 if (sipMsg->getContents())
85 {
86 if (decrypt(sipMsg))
87 {
88 DebugLog(<< "Decrypted message:" << sipMsg << endl);
90 }
91 else
92 {
94 }
95 }
96 else
97 {
99 }
100 }
101
102 OutgoingEvent* const event = dynamic_cast<OutgoingEvent*>(msg);
103 if (event)
104 {
105 if (!event->message()->getContents())
106 {
108 }
109
110 if (!event->message()->getSecurityAttributes() ||
111 event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel() == SecurityAttributes::None ||
112 event->message()->getSecurityAttributes()->encryptionPerformed())
113 {
115 }
116
117 Data senderAor;
118 Data recipAor;
119 if (event->message()->isRequest())
120 {
121 senderAor = event->message()->header(h_From).uri().getAor();
122 recipAor = event->message()->header(h_To).uri().getAor();
123 }
124 else
125 {
126 senderAor = event->message()->header(h_To).uri().getAor();
127 recipAor = event->message()->header(h_From).uri().getAor();
128 }
129
130 Contents* contents = event->message()->getContents();
131 bool setContents = true;
132 bool noCerts = false;
133
134 switch (event->message()->getSecurityAttributes()->getOutgoingEncryptionLevel())
135 {
137 setContents = false;
138 break;
140 contents = encrypt(event->message(), recipAor, &noCerts);
141 break;
143 contents = sign(event->message(), senderAor, &noCerts);
144 break;
146 contents = signAndEncrypt(event->message(), senderAor, recipAor, &noCerts);
147 break;
148 }
149
150 if (contents)
151 {
152 if (setContents)
153 {
154 event->message()->setContents(unique_ptr<Contents>(contents));
155 DumHelper::setEncryptionPerformed(*event->message());
156 }
158 }
159 else
160 {
161 if (noCerts)
162 {
164 }
165 else
166 {
167 //event->releaseMessage();
169 }
170 }
171 }
172
173 // Todo: change CertMessage to DumFeatureMessage.
174 CertMessage* certMsg = dynamic_cast<CertMessage*>(msg);
175 if (certMsg)
176 {
177 const EncryptionManager::Result result = processCertMessage(certMsg);
178 if (result == Complete)
179 {
181 }
182 else
183 {
184 delete msg;
186 }
187 }
188
190}
191
192EncryptionManager::Result EncryptionManager::processCertMessage(CertMessage* message)
193{
194 InfoLog( << "Received a cert message: " << *message << endl);
195 Result ret = Pending;
196 list<Request*>::iterator it;
197 for (it = mRequests.begin(); it != mRequests.end(); ++it)
198 {
199 if ((*it)->getId() == message->id().mId) break;
200 }
201
202 if (it != mRequests.end())
203 {
204 InfoLog ( << "Processing the cert message" << endl);
205 ret = (*it)->received(message->success(), message->id().mType, message->id().mAor, message->body());
206 if (Complete == ret)
207 {
208 delete *it;
209 mRequests.erase(it);
210 }
211 }
212
213 return ret;
214}
215
216Contents* EncryptionManager::sign(std::shared_ptr<SipMessage> msg,
217 const Data& senderAor,
218 bool* noCerts)
219{
220 Sign* request = new Sign(mDum, mRemoteCertStore.get(), msg, senderAor, *this);
221 Contents* contents;
222 *noCerts = false;
223 bool async = request->sign(&contents, noCerts);
224 if (async)
225 {
226 InfoLog(<< "Async sign" << endl);
227 //request->setTaken();
228 mRequests.push_back(request);
229 }
230 else
231 {
232 delete request;
233 }
234 return contents;
235}
236
237Contents* EncryptionManager::encrypt(std::shared_ptr<SipMessage> msg,
238 const Data& recipientAor,
239 bool* noCerts)
240{
241 Encrypt* request = new Encrypt(mDum, mRemoteCertStore.get(), msg, recipientAor, *this);
242 Contents* contents;
243 *noCerts = false;
244 bool async = request->encrypt(&contents, noCerts);
245 if (async)
246 {
247 InfoLog(<< "Async encrypt" << endl);
248 //request->setTaken();
249 mRequests.push_back(request);
250 }
251 else
252 {
253 delete request;
254 }
255 return contents;
256}
257
258Contents* EncryptionManager::signAndEncrypt(std::shared_ptr<SipMessage> msg,
259 const Data& senderAor,
260 const Data& recipAor,
261 bool* noCerts)
262{
263 SignAndEncrypt* request = new SignAndEncrypt(mDum, mRemoteCertStore.get(), msg, senderAor, recipAor, *this);
264 Contents* contents;
265 *noCerts = false;
266 bool async = request->signAndEncrypt(&contents, noCerts);
267 if (!async)
268 {
269 delete request;
270 }
271 else
272 {
273 InfoLog(<< "Async sign and encrypt" << endl);
274 //request->setTaken();
275 mRequests.push_back(request);
276 }
277 return contents;
278}
279
280bool EncryptionManager::decrypt(SipMessage* msg)
281{
282 Decrypt* request = new Decrypt(mDum, mRemoteCertStore.get(), msg, *this);
283
285 bool ret = request->decrypt(csa);
286
287 if (ret)
288 {
289 if (csa.mContents)
290 {
291 msg->setContents(std::move(csa.mContents));
292
293 if (csa.mAttributes)
294 {
295 // Security Attributes might already exist on the message if the Identity Handler is enabled
296 // if so, ensure we maintain the Identity Strength
297 const SecurityAttributes *origSecurityAttributes = msg->getSecurityAttributes();
298 if(origSecurityAttributes)
299 {
300 csa.mAttributes->setIdentityStrength(origSecurityAttributes->getIdentityStrength());
301 }
302 msg->setSecurityAttributes(std::move(csa.mAttributes));
303 }
304 }
305 else
306 {
307 // no valid contents.
308 request->handleInvalidContents();
309
310 if (msg->isRequest() && !isAckOrCancelOrBye(*msg))
311 {
312 ret = false;
313 }
314 }
315 delete request;
316 }
317 else
318 {
319 InfoLog(<< "Async decrypt" << endl);
320 mRequests.push_back(request);
321 }
322
323 return ret;
324}
325
326EncryptionManager::Request::Request(DialogUsageManager& dum,
327 RemoteCertStore* store,
328 std::shared_ptr<SipMessage> msg,
329 DumFeature& feature)
330 : mDum(dum),
331 mStore(store),
332 mMsgToEncrypt(msg),
333 mPendingRequests(0),
334 mFeature(feature)
335 //mTaken(false)
336{
337}
338
339EncryptionManager::Request::~Request()
340{
341 /*
342 if (mTaken)
343 {
344 delete mMsg;
345 }
346 */
347}
348
349void EncryptionManager::Request::response415()
350{
351 SipMessage* response = Helper::makeResponse(*mMsgToEncrypt, 415);
352 mDum.post(response);
353 InfoLog(<< "Generated 415" << endl);
354}
355
356EncryptionManager::Sign::Sign(DialogUsageManager& dum,
357 RemoteCertStore* store,
358 std::shared_ptr<SipMessage> msg,
359 const Data& senderAor,
360 DumFeature& feature)
361 : Request(dum, store, msg, feature),
362 mSenderAor(senderAor)
363{
364}
365
366bool EncryptionManager::Sign::sign(Contents** contents, bool* noCerts)
367{
368 *contents = 0;
369 *noCerts = false;
370 bool async = false;
371
373 bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor);
374 bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor);
375
376 if (!missingCert && !missingKey)
377 {
378 InfoLog(<< "Signing message" << endl);
379 msc = mDum.getSecurity()->sign(mSenderAor, mMsgToEncrypt->getContents());
380 *contents = msc;
381 }
382 else
383 {
384 if (mStore)
385 {
386 if (missingCert)
387 {
388 InfoLog(<< "Fetching cert for " << mSenderAor << endl);
389 ++mPendingRequests;
390 MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert);
391 mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
392 }
393 if (missingKey)
394 {
395 InfoLog(<< "Fetching private key for " << mSenderAor << endl);
396 ++mPendingRequests;
397 MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey);
398 mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
399 }
400 async = true;
401 }
402 else
403 {
404 InfoLog(<< "No remote cert store installed" << endl);
405 *noCerts = true;
406 response415();
407 }
408 }
409
410 return async;
411}
412
413EncryptionManager::Result EncryptionManager::Sign::received(bool success,
414 MessageId::Type type,
415 const Data& aor,
416 const Data& data)
417{
418 resip_assert(mSenderAor==aor);
419 resip_assert(mPendingRequests>0&&mPendingRequests<=2);
420 Result result = Pending;
421
422 if (success)
423 {
424 if (type == MessageId::UserCert)
425 {
426 InfoLog(<< "Adding cert for: " << aor << endl);
427 mDum.getSecurity()->addUserCertDER(aor, data);
428 }
429 else
430 {
431 InfoLog(<< "Adding private key for " << aor << endl);
432 mDum.getSecurity()->addUserPrivateKeyDER(aor, data);
433 }
434 if (--mPendingRequests == 0)
435 {
436 InfoLog(<< "Signing message" << endl);
437 MultipartSignedContents* msc = mDum.getSecurity()->sign(aor, mMsgToEncrypt->getContents());
438 mMsgToEncrypt->setContents(unique_ptr<Contents>(msc));
439 DumHelper::setEncryptionPerformed(*mMsgToEncrypt);
440 OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt);
441 //mTaken = false;
442 mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), unique_ptr<Message>(event)));
443 result = Complete;
444 }
445 }
446 else
447 {
448 InfoLog(<< "Failed to fetch " << ((type==MessageId::UserCert)? "cert " : "private key ") << "for " << aor <<endl);
449 response415();
450 result = Complete;
451 }
452 return result;
453}
454
455EncryptionManager::Encrypt::Encrypt(DialogUsageManager& dum,
456 RemoteCertStore* store,
457 std::shared_ptr<SipMessage> msg,
458 const Data& recipientAor,
459 DumFeature& feature)
460 : Request(dum, store, msg, feature),
461 mRecipientAor(recipientAor)
462{
463}
464
465bool EncryptionManager::Encrypt::encrypt(Contents** contents, bool* noCerts)
466{
467 *contents = 0;
468 *noCerts = false;
469 bool async = false;
470
471 if (mDum.getSecurity()->hasUserCert(mRecipientAor))
472 {
473 InfoLog(<< "Encrypting message" << endl);
474 MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(mMsgToEncrypt->getContents());
475 if (alt)
476 {
477 // encrypt the last part.
479 Contents* last = mDum.getSecurity()->encrypt(parts.back(), mRecipientAor);
480 if (last)
481 {
483 delete mac->parts().back();
484 mac->parts().pop_back();
485 mac->parts().push_back(last);
486 *contents = mac;
487 }
488 }
489 else
490 {
491 *contents = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), mRecipientAor);
492 }
493 }
494 else
495 {
496 if (mStore)
497 {
498 InfoLog(<< "Fetching cert for " << mRecipientAor << endl);
499 ++mPendingRequests;
500 MessageId id(mMsgToEncrypt->getTransactionId(), mRecipientAor, MessageId::UserCert);
501 mStore->fetch(mRecipientAor, MessageId::UserCert, id, mDum);
502 async = true;
503 }
504 else
505 {
506 InfoLog(<< "No remote cert store installed" << endl);
507 *noCerts = true;
508 response415();
509 }
510 }
511 return async;
512}
513
514EncryptionManager::Result EncryptionManager::Encrypt::received(bool success,
515 MessageId::Type type,
516 const Data& aor,
517 const Data& data)
518{
519 resip_assert(mRecipientAor==aor);
521 resip_assert(mPendingRequests==1);
522 if (success)
523 {
524 InfoLog(<< "Adding user cert for " << aor << endl);
525 mDum.getSecurity()->addUserCertDER(aor, data);
526 --mPendingRequests;
527 InfoLog(<< "Encrypting message" << endl);
528 Pkcs7Contents* encrypted = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), aor);
529 mMsgToEncrypt->setContents(unique_ptr<Contents>(encrypted));
530 DumHelper::setEncryptionPerformed(*mMsgToEncrypt);
531 OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt);
532 //mTaken = false;
533 mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), unique_ptr<Message>(event)));
534 }
535 else
536 {
537 InfoLog(<< "Failed to fetch cert for " << aor << endl);
538 response415();
539 }
540 return Complete;
541}
542
543EncryptionManager::SignAndEncrypt::SignAndEncrypt(DialogUsageManager& dum,
544 RemoteCertStore* store,
545 std::shared_ptr<SipMessage> msg,
546 const Data& senderAor,
547 const Data& recipientAor,
548 DumFeature& feature)
549 : Request(dum, store, msg, feature),
550 mSenderAor(senderAor),
551 mRecipientAor(recipientAor)
552{
553}
554
555bool EncryptionManager::SignAndEncrypt::signAndEncrypt(Contents** contents, bool* noCerts)
556{
557 *contents = 0;
558 *noCerts = false;
559 bool async = false;
560 bool missingCert = !mDum.getSecurity()->hasUserCert(mSenderAor);
561 bool missingKey = !mDum.getSecurity()->hasUserPrivateKey(mSenderAor);
562 bool missingRecipCert = !mDum.getSecurity()->hasUserCert(mRecipientAor);
563
564 if (!missingCert && !missingKey && !missingRecipCert)
565 {
566 InfoLog(<< "Encrypting and signing message" << endl);
567 *contents = doWork();
568 }
569 else
570 {
571 if (mStore)
572 {
573 if (missingCert)
574 {
575 InfoLog(<< "Fetching cert for " << mSenderAor << endl);
576 ++mPendingRequests;
577 MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserCert);
578 mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
579 }
580 if (missingKey)
581 {
582 InfoLog(<< "Fetching private key for " << mSenderAor << endl);
583 ++mPendingRequests;
584 MessageId id(mMsgToEncrypt->getTransactionId(), mSenderAor, MessageId::UserPrivateKey);
585 mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
586 }
587 if (missingRecipCert)
588 {
589 InfoLog(<< "Fetching cert for " << mRecipientAor << endl);
590 ++mPendingRequests;
591 MessageId id(mMsgToEncrypt->getTransactionId(), mRecipientAor, MessageId::UserCert);
592 mStore->fetch(mSenderAor, MessageId::UserCert, id, mDum);
593 }
594 async = true;
595 }
596 else
597 {
598 InfoLog(<< "No remote cert store installed" << endl);
599 *noCerts = true;
600 response415();
601 }
602 }
603
604 return async;
605}
606
607EncryptionManager::Result EncryptionManager::SignAndEncrypt::received(bool success,
608 MessageId::Type type,
609 const Data& aor,
610 const Data& data)
611{
612 resip_assert(mPendingRequests>0&&mPendingRequests<=3);
613 Result result = Pending;
614 if (success)
615 {
616 if (type == MessageId::UserCert)
617 {
618 resip_assert(aor==mSenderAor||aor==mRecipientAor);
619 InfoLog(<< "Adding user cert for " << aor << endl);
620 mDum.getSecurity()->addUserCertDER(aor, data);
621 }
622 else
623 {
624 resip_assert(aor==mSenderAor);
625 InfoLog(<< "Adding private key for " << aor << endl);
626 mDum.getSecurity()->addUserPrivateKeyDER(aor, data);
627 }
628
629 if (--mPendingRequests == 0)
630 {
631 InfoLog(<< "Encrypting and signing message" << endl);
632 Contents* contents = doWork();
633 mMsgToEncrypt->setContents(unique_ptr<Contents>(contents));
634 DumHelper::setEncryptionPerformed(*mMsgToEncrypt);
635 OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt);
636 //mTaken = false;
637 mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), unique_ptr<Message>(event)));
638 result = Complete;
639 }
640 }
641 else
642 {
643 InfoLog(<< "Failed to fetch cert for " << aor << endl);
644 response415();
645 result = Complete;
646 }
647 return result;
648}
649
650Contents* EncryptionManager::SignAndEncrypt::doWork()
651{
652 Contents* contents = 0;
653 MultipartAlternativeContents* mac = dynamic_cast<MultipartAlternativeContents*>(mMsgToEncrypt->getContents());
654 if (mac)
655 {
657 Pkcs7Contents* pkcs7 = mDum.getSecurity()->encrypt(parts.back(), mRecipientAor);
658 if (pkcs7)
659 {
661 delete alt->parts().back();
662 alt->parts().pop_back();
663 alt->parts().push_back(pkcs7);
664 contents = alt;
665 }
666 }
667 else
668 {
669 contents = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents() , mRecipientAor);
670 }
671
672 if (contents)
673 {
674 contents = mDum.getSecurity()->sign(mSenderAor, contents);
675 }
676
677 return contents;
678}
679
680EncryptionManager::Decrypt::Decrypt(DialogUsageManager& dum,
681 RemoteCertStore* store,
682 SipMessage* msg,
683 DumFeature& feature)
684 : Request(dum, store, nullptr, feature),
685 mIsEncrypted(false),
686 mMsgToDecrypt(msg),
687 mMessageTaken(false)
688{
689 if (msg->isResponse())
690 {
691 mDecryptor = msg->header(h_From).uri().getAor();
692 mSigner = msg->header(h_To).uri().getAor();
693 }
694 else
695 {
696 mDecryptor = msg->header(h_To).uri().getAor();
697 mSigner = msg->header(h_From).uri().getAor();
698 }
699}
700
701EncryptionManager::Decrypt::~Decrypt()
702{
703 if (mMessageTaken)
704 {
705 delete mMsgToDecrypt;
706 }
707}
708
709bool EncryptionManager::Decrypt::decrypt(Helper::ContentsSecAttrs& csa)
710{
711 bool noDecryptionKey = false;
712
713 if (!dynamic_cast<Pkcs7Contents*>(mMsgToDecrypt->getContents()))
714 {
715 mOriginalMsgContents = Data(mMsgToDecrypt->getContents()->getHeaderField().getBuffer(), mMsgToDecrypt->getContents()->getHeaderField().getLength());
716 mOriginalMsgContentsType = mMsgToDecrypt->getContents()->getType();
717 }
718 else
719 {
720 mIsEncrypted = true;
721 }
722
723 if (isEncrypted())
724 {
725 bool missingDecryptorCert = !mDum.getSecurity()->hasUserCert(mDecryptor);
726 bool missingDecryptorKey = !mDum.getSecurity()->hasUserPrivateKey(mDecryptor);
727 if (missingDecryptorCert || missingDecryptorKey)
728 {
729 if (mStore)
730 {
731 if (missingDecryptorCert)
732 {
733 InfoLog(<< "Fetching user cert for " << mDecryptor << endl);
734 ++mPendingRequests;
735 MessageId id(mMsgToDecrypt->getTransactionId(), mDecryptor, MessageId::UserCert);
736 mStore->fetch(mDecryptor, MessageId::UserCert, id, mDum);
737 }
738
739 if (missingDecryptorKey)
740 {
741 InfoLog(<< "Fetching private key for " << mDecryptor << endl);
742 ++mPendingRequests;
743 MessageId id(mMsgToDecrypt->getTransactionId(), mDecryptor, MessageId::UserPrivateKey);
744 mStore->fetch(mDecryptor, MessageId::UserPrivateKey, id, mDum);
745 }
746 mMessageTaken = true;
747 return false;
748 }
749 else
750 {
751 InfoLog(<< "No remote cert store installed" << endl);
752 noDecryptionKey = true;
753 }
754 }
755 }
756
757 if (isSigned(noDecryptionKey))
758 {
759 if (!mDum.getSecurity()->hasUserCert(mSigner))
760 {
761 if (mStore)
762 {
763 InfoLog(<< "Fetching user cert for " << mSigner << endl);
764 ++mPendingRequests;
765 MessageId id(mMsgToDecrypt->getTransactionId(), mSigner, MessageId::UserCert);
766 mStore->fetch(mSigner, MessageId::UserCert, id, mDum);
767 mMessageTaken = true;
768 return false;
769 }
770 else
771 {
772 InfoLog(<< "No remote cert store installed" << endl);
773 }
774 }
775 }
776
777 csa = getContents(mMsgToDecrypt, *mDum.getSecurity(), noDecryptionKey);
778 return true;
779}
780
781EncryptionManager::Result EncryptionManager::Decrypt::received(bool success,
782 MessageId::Type type,
783 const Data& aor,
784 const Data& data)
785{
786 Result result = Complete;
787 resip_assert(mPendingRequests>0 && mPendingRequests<=2);
788 if (success)
789 {
790 if (aor == mSigner)
791 {
793 resip_assert(mPendingRequests==1);
794 --mPendingRequests;
795 InfoLog(<< "Adding user cert for " << aor << endl);
796 mDum.getSecurity()->addUserCertDER(aor, data);
797 }
798 else
799 {
800 resip_assert(aor == mDecryptor);
801 if (MessageId::UserCert == type)
802 {
803 InfoLog(<< "Adding user cert for " << aor << endl);
804 mDum.getSecurity()->addUserCertDER(aor, data);
805 }
806 else
807 {
808 InfoLog(<< "Adding private key for " << aor << endl);
809 mDum.getSecurity()->addUserPrivateKeyDER(aor, data);
810 }
811
812 if (--mPendingRequests == 0)
813 {
814 if (isSigned(false))
815 {
816 if (!mDum.getSecurity()->hasUserCert(mSigner))
817 {
818 InfoLog(<< "Fetching user cert for " << mSigner << endl);
819 ++mPendingRequests;
820 MessageId id(mMsgToDecrypt->getTransactionId(), mSigner, MessageId::UserCert);
821 mStore->fetch(mSigner, MessageId::UserCert, id, mDum);
822 result = Pending;
823 }
824 }
825 }
826 else
827 {
828 result = Pending;
829 }
830 }
831 }
832 else
833 {
834 InfoLog(<< "Failed to fetch cert for " << aor << endl);
835 }
836
837 if (Complete == result)
838 {
840 csa = getContents(mMsgToDecrypt, *mDum.getSecurity(),
841 (!mDum.getSecurity()->hasUserCert(mDecryptor) || !mDum.getSecurity()->hasUserPrivateKey(mDecryptor)));
842
843
844 if (csa.mContents)
845 {
846 csa.mContents->checkParsed();
847 mMsgToDecrypt->setContents(std::move(csa.mContents));
848
849 if (csa.mAttributes)
850 {
851 mMsgToDecrypt->setSecurityAttributes(std::move(csa.mAttributes));
852 }
853 }
854 else
855 {
856 // no valid contents.
857 ErrLog(<< "No valid contents in message received" << endl);
858 handleInvalidContents();
859
860 if (mMsgToDecrypt->isRequest() && !isAckOrCancelOrBye(*mMsgToDecrypt))
861 {
862 return result;
863 }
864 }
865
866 // Todo: make CertMessage DumFeatureMessage and get rid of DumDecrypted.
867 // Currently the message will not be processed by
868 // any features in the chain after EncryptionManager.
869 DumDecrypted* decrypted = new DumDecrypted(*mMsgToDecrypt);
870 mDum.post(decrypted);
871 }
872
873 return result;
874}
875
876bool EncryptionManager::Decrypt::isEncrypted()
877{
878 Contents* contents = mMsgToDecrypt->getContents();
879 return isEncryptedRecurse(&contents);
880}
881
882bool EncryptionManager::Decrypt::isSigned(bool noDecryptionKey)
883{
884 Contents* contents = mMsgToDecrypt->getContents();
885 return isSignedRecurse(&contents, mDecryptor, noDecryptionKey);
886}
887
888bool EncryptionManager::Decrypt::isEncryptedRecurse(Contents** contents)
889{
890 InvalidContents* ic;
891 if ((ic = dynamic_cast<InvalidContents*>(*contents)))
892 {
893 return false;
894 }
895
896 Pkcs7Contents* pk;
897 if ((pk = dynamic_cast<Pkcs7Contents*>(*contents)))
898 {
899 return true;
900 }
901
903 if ((mps = dynamic_cast<MultipartSignedContents*>(*contents)))
904 {
905 // Look at the parts through the const overload. The mutable one runs
906 // the non-const checkParsed(), which marks the body DIRTY, and this
907 // function only wants to know what kind of body it is. Once the body
908 // is DIRTY, BaseSecurity::checkSignature() no longer has the bytes that
909 // arrived and has to fall back to a re-encoding.
910 const MultipartSignedContents* constMps = mps;
911 try
912 {
913 constMps->parts();
914 }
915 catch (const BaseException& e)
916 {
917 // structure of multipart is bad. this is unrecoverable error,
918 // replace the whole multipart contents with an InvalidContents.
919 ErrLog(<< e.name() << endl << e.getMessage());
920
921 if (*contents == mMsgToDecrypt->getContents())
922 {
923 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(mps)));
924 }
925 else
926 {
927 *contents = createInvalidContents(mps);
928 delete mps;
929 }
930 return false;
931 }
932
933 // front() below needs a part to hand out.
934 if (constMps->parts().empty())
935 {
936 return false;
937 }
938
939 // Recurse through a local pointer and write back only if the callee
940 // really replaced the part, which it does for a malformed one. Handing
941 // out a mutable iterator up front would mark the body DIRTY even when
942 // nothing changes, for the same reason as above.
943 Contents* firstPart = constMps->parts().front();
944 Contents* const beforeRecurse = firstPart;
945 const bool encrypted = isEncryptedRecurse(&firstPart);
946 if (firstPart != beforeRecurse)
947 {
948 mps->parts().front() = firstPart;
949 }
950 return encrypted;
951 }
952
953 MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(*contents);
954 if (alt)
955 {
956 try
957 {
958 alt->parts();
959 }
960 catch (const BaseException& e)
961 {
962 ErrLog(<< e.name() << endl << e.getMessage());
963 if (*contents == mMsgToDecrypt->getContents())
964 {
965 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(alt)));
966 }
967 else
968 {
969 *contents = createInvalidContents(alt);
970 delete alt;
971 }
972 return false;
973 }
974
975 for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin();
976 i != alt->parts().rend(); ++i)
977 {
978 if (isEncryptedRecurse(&(*i)))
979 {
980 return true;
981 }
982 }
983
984 return false;
985 }
986
987 if (dynamic_cast<MultipartMixedContents*>(*contents))
988 {
989 return false;
990 }
991
992 return false;
993}
994
995bool EncryptionManager::Decrypt::isSignedRecurse(Contents** contents,
996 const Data& decryptorAor,
997 bool noDecryptionKey)
998{
999 InvalidContents* ic;
1000 if ((ic = dynamic_cast<InvalidContents*>(*contents)))
1001 {
1002 return false;
1003 }
1004
1005 Pkcs7Contents* pk;
1006 if ((pk = dynamic_cast<Pkcs7Contents*>(*contents)))
1007 {
1008 if (noDecryptionKey)
1009 {
1010 return false;
1011 }
1012
1013 Contents* decrypted = mDum.getSecurity()->decrypt(decryptorAor, pk);
1014 bool ret = false;
1015
1016 if (decrypted)
1017 {
1018 if (*contents == mMsgToDecrypt->getContents())
1019 {
1020 mOriginalMsgContents = Data(decrypted->getHeaderField().getBuffer(), decrypted->getHeaderField().getLength());
1021 mOriginalMsgContentsType = decrypted->getType();
1022 }
1023
1024 try
1025 {
1026 decrypted->checkParsed();
1027 if (isMultipart(decrypted))
1028 {
1029 if (dynamic_cast<MultipartSignedContents*>(decrypted))
1030 {
1031 ret = true;
1032 }
1033 else
1034 {
1035 if (*contents == mMsgToDecrypt->getContents())
1036 {
1037 mMsgToDecrypt->setContents(unique_ptr<Contents>(decrypted));
1038 *contents = mMsgToDecrypt->getContents();
1039 }
1040 else
1041 {
1042 *contents = decrypted;
1043 delete pk;
1044 }
1045 return isSignedRecurse(contents, decryptorAor, noDecryptionKey);
1046 }
1047 }
1048 }
1049 catch (const BaseException& e)
1050 {
1051 ErrLog(<< e.name() << endl << e.getMessage());
1052
1053 if (*contents == mMsgToDecrypt->getContents())
1054 {
1055 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(decrypted)));
1056 }
1057 else
1058 {
1059 *contents = createInvalidContents(decrypted);
1060 delete pk;
1061 }
1062 }
1063
1064 delete decrypted;
1065 }
1066
1067 return ret;
1068 }
1069
1071 if ((mps = dynamic_cast<MultipartSignedContents*>(*contents)))
1072 {
1073 return true;
1074 }
1075
1076 MultipartAlternativeContents* alt = dynamic_cast<MultipartAlternativeContents*>(*contents);
1077 if (alt)
1078 {
1079 try
1080 {
1081 alt->parts();
1082 }
1083 catch (const BaseException& e)
1084 {
1085 // structure of multipart is bad. this is unrecoverable error,
1086 // replace the whole multipart contents with an InvalidContents.
1087 ErrLog(<< e.name() << endl << e.getMessage());
1088
1089 if (*contents == mMsgToDecrypt->getContents())
1090 {
1091 mMsgToDecrypt->setContents(unique_ptr<Contents>(createInvalidContents(alt)));
1092 }
1093 else
1094 {
1095 *contents = createInvalidContents(alt);
1096 delete alt;
1097 }
1098
1099 return false;
1100 }
1101
1102 for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin();
1103 i != alt->parts().rend(); ++i)
1104 {
1105 if (isSignedRecurse(&(*i), decryptorAor, noDecryptionKey))
1106 {
1107 return true;
1108 }
1109 }
1110
1111 return false;
1112 }
1113
1114 if (dynamic_cast<MultipartMixedContents*>(*contents))
1115 {
1116 return false;
1117 }
1118
1119 return false;
1120}
1121
1122Helper::ContentsSecAttrs EncryptionManager::Decrypt::getContents(SipMessage* message,
1123 Security& security,
1124 bool noDecryptionKey)
1125{
1127 attr->setIdentity(message->header(h_From).uri().getAor());
1128 Contents* contents = message->getContents();
1129 if (contents)
1130 {
1131 contents = getContentsRecurse(&contents, security, noDecryptionKey, attr);
1132 }
1133
1134 if (contents)
1135 {
1136 if (mIsEncrypted)
1137 {
1138 attr->setEncrypted();
1139 }
1140 }
1141
1142 std::unique_ptr<Contents> c(contents);
1143 std::unique_ptr<SecurityAttributes> a(attr);
1144 return Helper::ContentsSecAttrs(std::move(c), std::move(a));
1145}
1146
1147Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree,
1148 Security& security,
1149 bool noDecryptionKey,
1150 SecurityAttributes* attributes)
1151{
1152 InvalidContents* ic;
1153 if ((ic = dynamic_cast<InvalidContents*>(*tree)))
1154 {
1155 return 0;
1156 }
1157
1158 Pkcs7Contents* pk;
1159 if ((pk = dynamic_cast<Pkcs7Contents*>(*tree)))
1160 {
1161 if (noDecryptionKey)
1162 {
1163 return 0;
1164 }
1165
1166 Contents* contents = security.decrypt(mDecryptor, pk);
1167 if (contents)
1168 {
1169 if (*tree == mMsgToDecrypt->getContents())
1170 {
1171 mOriginalMsgContents = Data(contents->getHeaderField().getBuffer(), contents->getHeaderField().getLength());
1172 mOriginalMsgContentsType = contents->getType();
1173 }
1174
1175 try
1176 {
1177 contents->checkParsed();
1178 if (isMultipart(contents))
1179 {
1180 if (*tree == mMsgToDecrypt->getContents())
1181 {
1182 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(contents));
1183 *tree = mMsgToDecrypt->getContents();
1184 }
1185 else
1186 {
1187 *tree = contents;
1188 delete pk;
1189 }
1190
1191 return getContentsRecurse(tree, security, noDecryptionKey, attributes);
1192 }
1193 else
1194 {
1195 attributes->setEncrypted();
1196 }
1197 }
1198 catch (const BaseException& e)
1199 {
1200 ErrLog(<< e.name() << endl << e.getMessage());
1201
1202 if (*tree == mMsgToDecrypt->getContents())
1203 {
1204 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(contents)));
1205 }
1206 else
1207 {
1208 *tree = createInvalidContents(contents);
1209 delete pk;
1210 }
1211
1212 delete contents;
1213 return 0;
1214 }
1215 }
1216
1217 return contents;
1218 }
1219
1221 if ((mps = dynamic_cast<MultipartSignedContents*>(*tree)))
1222 {
1223 Data signer;
1224 SignatureStatus sigStatus = SignatureIsBad;
1225 Contents* tmp = security.checkSignature(mps, &signer, &sigStatus);
1226 Contents* contents = getContentsRecurse(&tmp,
1227 security, noDecryptionKey, attributes);
1228 attributes->setSigner(signer);
1229 attributes->setSignatureStatus(sigStatus);
1230 return contents;
1231 }
1232
1234 if ((alt = dynamic_cast<MultipartAlternativeContents*>(*tree)))
1235 {
1236 try
1237 {
1238 alt->parts();
1239 }
1240 catch (const BaseException& e)
1241 {
1242 // structure of multipart is bad. this is an unrecoverable error,
1243 // replace the whole multipart contents with an InvalidContents.
1244 ErrLog(<< e.name() << endl << e.getMessage());
1245
1246 if (*tree == mMsgToDecrypt->getContents())
1247 {
1248 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(alt)));
1249 }
1250 else
1251 {
1252 *tree = createInvalidContents(alt);
1253 delete alt;
1254 }
1255
1256 return 0;
1257 }
1258
1259 for (MultipartAlternativeContents::Parts::reverse_iterator i = alt->parts().rbegin();
1260 i != alt->parts().rend(); ++i)
1261 {
1262 Contents* contents = getContentsRecurse(&(*i), security, noDecryptionKey, attributes);
1263 if (contents)
1264 {
1265 return contents;
1266 }
1267 }
1268
1269 return 0;
1270 }
1271
1273 if ((mult = dynamic_cast<MultipartMixedContents*>(*tree)))
1274 {
1275 try
1276 {
1277 mult->parts();
1278 }
1279 catch (const BaseException& e)
1280 {
1281 // structure of multipart is bad. this is unrecoverable error,
1282 // replace the whole multipart contents with an InvalidContents.
1283 ErrLog(<< e.name() << endl << e.getMessage());
1284
1285 if (*tree == mMsgToDecrypt->getContents())
1286 {
1287 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(mult)));
1288 }
1289 else
1290 {
1291 *tree = createInvalidContents(mult);
1292 delete mult;
1293 }
1294
1295 return 0;
1296 }
1297
1298 // for now, the multipart/mixed is returned untouched.
1299 return mult->clone();
1300 }
1301
1302 Contents* ret = 0;
1303
1304 try
1305 {
1306 (*tree)->checkParsed();
1307 ret = (*tree)->clone();
1308 }
1309 catch (const BaseException& e)
1310 {
1311 ErrLog(<< e.name() << endl << e.getMessage());
1312
1313 if (*tree == mMsgToDecrypt->getContents())
1314 {
1315 mMsgToDecrypt->setContents(std::unique_ptr<Contents>(createInvalidContents(*tree)));
1316 }
1317 else
1318 {
1319 Contents* tmp = *tree;
1320 *tree = createInvalidContents(*tree);
1321 delete tmp;
1322 }
1323 }
1324
1325 return ret;
1326
1327}
1328
1329// Todo: move to DumHelper.
1331EncryptionManager::Decrypt::createInvalidContents(Contents* orig)
1332{
1333 Data original(orig->getHeaderField().getBuffer(), orig->getHeaderField().getLength());
1334 return new InvalidContents(original, orig->getType());
1335}
1336
1337bool
1338EncryptionManager::Decrypt::isMultipart(Contents* contents)
1339{
1340 return (
1341 dynamic_cast<MultipartSignedContents*>(contents) ||
1342 dynamic_cast<MultipartAlternativeContents*>(contents) ||
1343 dynamic_cast<MultipartMixedContents*>(contents)
1344 );
1345}
1346
1347void
1348EncryptionManager::Decrypt::handleInvalidContents()
1349{
1350 if (mMsgToDecrypt->isRequest())
1351 {
1352 if (isAckOrCancelOrBye(*mMsgToDecrypt))
1353 {
1354 DebugLog(<< "No valid contents in the request" << endl);
1355 InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType);
1356 mMsgToDecrypt->setContents(unique_ptr<Contents>(invalid));
1357 }
1358 else
1359 {
1360 DebugLog(<< "No valid contents in the request -- reject with 400" << endl);
1361 SipMessage response;
1362 Helper::makeResponse(response, *mMsgToDecrypt, 400, Data::Empty, mMsgToDecrypt->header(h_RequestLine).uri().host() , "Invalid message body");
1363 mDum.getSipStack().send(response);
1364 }
1365 }
1366 else
1367 {
1368 DebugLog(<< "No valid contents in the response" << endl);
1369 InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType);
1370 mMsgToDecrypt->setContents(unique_ptr<Contents>(invalid));
1371 }
1372}
1373
1374#endif
1375
1376/* ====================================================================
1377 * The Vovida Software License, Version 1.0
1378 *
1379 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
1380 *
1381 * Redistribution and use in source and binary forms, with or without
1382 * modification, are permitted provided that the following conditions
1383 * are met:
1384 *
1385 * 1. Redistributions of source code must retain the above copyright
1386 * notice, this list of conditions and the following disclaimer.
1387 *
1388 * 2. Redistributions in binary form must reproduce the above copyright
1389 * notice, this list of conditions and the following disclaimer in
1390 * the documentation and/or other materials provided with the
1391 * distribution.
1392 *
1393 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
1394 * and "Vovida Open Communication Application Library (VOCAL)" must
1395 * not be used to endorse or promote products derived from this
1396 * software without prior written permission. For written
1397 * permission, please contact vocal@vovida.org.
1398 *
1399 * 4. Products derived from this software may not be called "VOCAL", nor
1400 * may "VOCAL" appear in their name, without prior written
1401 * permission of Vovida Networks, Inc.
1402 *
1403 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
1404 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1405 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
1406 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
1407 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
1408 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
1409 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1410 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1411 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1412 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1413 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1414 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1415 * DAMAGE.
1416 *
1417 * ====================================================================
1418 *
1419 * This software consists of voluntary contributions made by Vovida
1420 * Networks, Inc. and many individuals on behalf of Vovida Networks,
1421 * Inc. For more information on Vovida Networks, Inc., please see
1422 * <http://www.vovida.org/>.
1423 *
1424 */
static bool isAckOrCancelOrBye(const SipMessage &msg)
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
The abstract base-class for all exceptions thrown by resip code.
const Data & getMessage() const noexcept
virtual const char * name() const noexcept=0
Contents * checkSignature(MultipartSignedContents *, Data *signedBy, SignatureStatus *sigStat)
Contents * decrypt(const Data &decryptorAor, const Pkcs7Contents *)
bool success() const
const MessageId & id() const
const Data & body() const
Base class for all SIP body types.
Definition Contents.hxx:51
virtual Contents * getContents()
access to wrapped contents (signed, encrypted)
Definition Contents.hxx:100
const Mime & getType() const
getter for mime type of message
Definition Contents.hxx:118
virtual Contents * clone() const =0
returns a copy of a Contents object
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
static const Data Empty
Constant that represents a zero-length data.
Definition Data.hxx:882
DialogUsageManager & mDum
static void setEncryptionPerformed(SipMessage &message)
Definition DumHelper.cxx:20
Exception(const Data &msg, const Data &file, int line)
virtual DumFeature::ProcessingResult process(Message *msg)
EncryptionManager(DialogUsageManager &dum, TargetCommand::Target &target)
void setRemoteCertStore(std::unique_ptr< RemoteCertStore > store)
const char * getBuffer() const
static void makeResponse(SipMessage &response, const SipMessage &request, int responseCode, const Data &reason=Data::Empty, const Data &hostname=Data::Empty, const Data &warning=Data::Empty)
Make a response to a provided request.
Definition Helper.cxx:412
SIP body type to represent an invalid content type (MIME content-type Invalid/Invalid).
void checkParsed() const
HeaderFieldValue & getHeaderField()
The base-class used for message-passing.
Definition Message.hxx:21
SIP body type for holding Multipart-Alternative body contents (MIME content-type multipart/alternativ...
SIP body type for holding Multipart-Mixed body contents (MIME content-type multipart/mixed).
virtual Contents * clone() const
duplicate an MultipartMixedContents object
SIP body type for holding Multipart-Signed body contents (MIME content-type multipart/signed).
SIP body type for holding PKCS7 contents (MIME content-type application/pkcs7-mime).
MethodTypes getMethod() const
const Uri & uri() const
IdentityStrength getIdentityStrength() const
void setIdentity(const Data &identity)
void setSignatureStatus(SignatureStatus status)
void setSigner(const Data &signer)
Represents a SIP message.
void setContents(const Contents *contents)
Set the contents of the message.
bool isRequest() const
Returns true if message is a request, false otherwise.
Contents * getContents() const
Retrieves the body of a SIP message.
void setSecurityAttributes(std::unique_ptr< SecurityAttributes >) noexcept
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool isResponse() const
Returns true if message is a response, false otherwise.
const SecurityAttributes * getSecurityAttributes() const noexcept
Data getAor() const
Definition Uri.cxx:1095
dcm! – add UnusedChecking(_enum) below;
RequestLineType h_RequestLine
Definition Headers.cxx:347
std::unique_ptr< Contents > mContents
Definition Helper.hxx:607
std::unique_ptr< SecurityAttributes > mAttributes
Definition Helper.hxx:608