diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp index eabf054b16c08dd13c6cb93672fa118e8ac11452..41f572972ad7f06aa09f9aeacb2d7ca50bdc0948 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp @@ -135,8 +135,6 @@ void AudioRtpFactory::initAudioRtpSession (SIPCall * ca) _rtpSession = new AudioSrtpSession (&Manager::instance(), ca); _rtpSessionType = Sdes; - - ca->getLocalSDP()->set_srtp_crypto (static_cast<AudioSrtpSession *> (_rtpSession)->getLocalCryptoInfo()); break; default: @@ -260,6 +258,15 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession() } } +void sfl::AudioRtpFactory::initLocalCryptoInfo (SIPCall * ca) +{ + if (_rtpSession && _rtpSessionType && (_rtpSessionType == Sdes)) { + static_cast<AudioSrtpSession *> (_rtpSession)->initLocalCryptoInfo (); + + ca->getLocalSDP()->set_srtp_crypto (static_cast<AudioSrtpSession *> (_rtpSession)->getLocalCryptoInfo()); + } +} + void AudioRtpFactory::setRemoteCryptoInfo (sfl::SdesNegotiator& nego) { if (_rtpSession && _rtpSessionType && (_rtpSessionType == Sdes)) { diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h index b870333fb055a655aa842e8cd1c833511b6a6d70..1b2c5b56f918c3f948ededa4add23e53fcca954b 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h @@ -166,6 +166,8 @@ class AudioRtpFactory */ sfl::AudioZrtpSession * getAudioZrtpSession(); + void initLocalCryptoInfo (SIPCall *ca); + /** * Set remote cryptographic info. Should be called after negotiation in SDP * offer/answer session. diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp index 1054624e58deb7395e275abb504ea15060efd31b..a8d61f5848a91bfebd8754291ed65d1614a70cbb 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp @@ -45,6 +45,7 @@ #include <cerrno> + namespace sfl { @@ -56,9 +57,20 @@ AudioSrtpSession::AudioSrtpSession (ManagerImpl * manager, SIPCall * sipcall) : _localMasterKeyLength (0), _localMasterSaltLength (0), _remoteMasterKeyLength (0), - _remoteMasterSaltLength (0) + _remoteMasterSaltLength (0), + _remoteCryptoCtx (NULL), + _localCryptoCtx (NULL), + _remoteOfferIsSet (false) +{ +} +AudioSrtpSession::~AudioSrtpSession() { +} + +void AudioSrtpSession::initLocalCryptoInfo() +{ + _debug ("AudioSrtp: Set cryptographic info for this rtp session"); // Initialize local Crypto context initializeLocalMasterKey(); @@ -69,13 +81,13 @@ AudioSrtpSession::AudioSrtpSession (ManagerImpl * manager, SIPCall * sipcall) : _localCryptoCtx->deriveSrtpKeys (0); setOutQueueCryptoContext (_localCryptoCtx); -} +} std::vector<std::string> AudioSrtpSession::getLocalCryptoInfo() { - _debug ("Get Cryptographic info from this rtp session"); + _debug ("AudioSrtp: Get Cryptographic info from this rtp session"); std::vector<std::string> crypto_vector; @@ -107,24 +119,40 @@ std::vector<std::string> AudioSrtpSession::getLocalCryptoInfo() void AudioSrtpSession::setRemoteCryptoInfo (sfl::SdesNegotiator& nego) { + if (!_remoteOfferIsSet) { + + _debug ("%s", nego.getKeyInfo().c_str()); + + // Use second crypto suite if key length is 32 bit, default is 80; - _debug ("Set remote Cryptographic info for Srtp"); + if (nego.getAuthTagLength() == "32") { + _localCryptoSuite = 1; + _remoteCryptoSuite = 1; + } - // decode keys - unBase64ConcatenatedKeys (nego.getKeyInfo()); + // decode keys + unBase64ConcatenatedKeys (nego.getKeyInfo()); + + // init crypto content in Srtp session + initializeRemoteCryptoContext(); + setInQueueCryptoContext (_remoteCryptoCtx); + + // initLocalCryptoInfo(); + _remoteOfferIsSet = true; + } - // init crypto content int Srtp session - initializeRemoteCryptoContext(); - setInQueueCryptoContext (_remoteCryptoCtx); } void AudioSrtpSession::initializeLocalMasterKey (void) { + _debug ("AudioSrtp: Init local master key"); // @TODO key may have different length depending on cipher suite _localMasterKeyLength = sfl::CryptoSuites[_localCryptoSuite].masterKeyLength / 8; + _debug ("AudioSrtp: Local master key length %d", _localMasterKeyLength); + // Allocate memory for key unsigned char *random_key = new unsigned char[_localMasterKeyLength]; @@ -136,14 +164,6 @@ void AudioSrtpSession::initializeLocalMasterKey (void) memcpy (_localMasterKey, random_key, _localMasterKeyLength); - /* - printf("Local Master: "); - for(int i = 0; i < _localMasterKeyLength; i++){ - printf("%d", _localMasterKey[i]); - } - printf("\n"); - */ - return; } @@ -156,6 +176,8 @@ void AudioSrtpSession::initializeLocalMasterSalt (void) // Allocate memory for key unsigned char *random_key = new unsigned char[_localMasterSaltLength]; + _debug ("AudioSrtp: Local master salt length %d", _localMasterSaltLength); + // Generate ryptographically strong pseudo-random bytes int err; @@ -164,7 +186,6 @@ void AudioSrtpSession::initializeLocalMasterSalt (void) memcpy (_localMasterSalt, random_key, _localMasterSaltLength); - return; } @@ -172,11 +193,15 @@ void AudioSrtpSession::initializeLocalMasterSalt (void) std::string AudioSrtpSession::getBase64ConcatenatedKeys() { + _debug ("AudioSrtp: Get base64 concatenated keys"); + // compute concatenated master and salt length int concatLength = _localMasterKeyLength + _localMasterSaltLength; uint8 concatKeys[concatLength]; + _debug ("AudioSrtp: Concatenated length %d", concatLength); + // concatenate keys memcpy ( (void*) concatKeys, (void*) _localMasterKey, _localMasterKeyLength); memcpy ( (void*) (concatKeys + _localMasterKeyLength), (void*) _localMasterSalt, _localMasterSaltLength); @@ -196,8 +221,8 @@ std::string AudioSrtpSession::getBase64ConcatenatedKeys() void AudioSrtpSession::unBase64ConcatenatedKeys (std::string base64keys) { - _remoteMasterKeyLength = sfl::CryptoSuites[1].masterKeyLength / 8; - _remoteMasterSaltLength = sfl::CryptoSuites[1].masterSaltLength / 8; + _remoteMasterKeyLength = sfl::CryptoSuites[_remoteCryptoSuite].masterKeyLength / 8; + _remoteMasterSaltLength = sfl::CryptoSuites[_remoteCryptoSuite].masterSaltLength / 8; // length of decoded data data int length; @@ -218,7 +243,14 @@ void AudioSrtpSession::unBase64ConcatenatedKeys (std::string base64keys) void AudioSrtpSession::initializeRemoteCryptoContext (void) { - CryptoSuiteDefinition crypto = sfl::CryptoSuites[_localCryptoSuite]; + _debug ("AudioSrtp: Initialize remote crypto context"); + + CryptoSuiteDefinition crypto = sfl::CryptoSuites[_remoteCryptoSuite]; + + if (_remoteCryptoCtx) { + delete _remoteCryptoCtx; + _remoteCryptoCtx = NULL; + } _remoteCryptoCtx = new ost::CryptoContext (0x0, 0, // roc, @@ -231,15 +263,22 @@ void AudioSrtpSession::initializeRemoteCryptoContext (void) _remoteMasterSaltLength, crypto.encryptionKeyLength / 8, crypto.srtpAuthKeyLength / 8, - 112 / 8, // session salt len + crypto.masterSaltLength / 8, // session salt len crypto.srtpAuthTagLength / 8); } void AudioSrtpSession::initializeLocalCryptoContext (void) { + _debug ("AudioSrtp: Initialize local crypto context"); + CryptoSuiteDefinition crypto = sfl::CryptoSuites[_localCryptoSuite]; + if (_localCryptoCtx) { + delete _localCryptoCtx; + _localCryptoCtx = NULL; + } + _localCryptoCtx = new ost::CryptoContext (OutgoingDataQueue::getLocalSSRC(), 0, // roc, 0L, // keydr, @@ -251,7 +290,7 @@ void AudioSrtpSession::initializeLocalCryptoContext (void) _localMasterSaltLength, crypto.encryptionKeyLength / 8, crypto.srtpAuthKeyLength / 8, - 112 / 8, // session salt len + crypto.masterSaltLength / 8, // session salt len crypto.srtpAuthTagLength / 8); } diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.h b/sflphone-common/src/audio/audiortp/AudioSrtpSession.h index 48e6055df6a6c79caf36b456a8686d546552f6e0..281cff8d9cdd87e60925aec13a902716f3c071c2 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.h @@ -78,28 +78,76 @@ class AudioSrtpSession : public ost::SymmetricRTPSession, public AudioRtpSession { public: + /** + * Constructor for this rtp session + */ AudioSrtpSession (ManagerImpl * manager, SIPCall * sipcall); + ~AudioSrtpSession(); + + /** + * Used to get sdp crypto header to be included in sdp session. This + * method must be called befor setRemoteCryptoInfo in case of an + * outgoing call or after in case of an outgoing call. + */ std::vector<std::string> getLocalCryptoInfo (void); + /** + * Set remote crypto header from incoming sdp offer + */ void setRemoteCryptoInfo (sfl::SdesNegotiator& nego); + /** + * Init local crypto context for outgoing data + * this method must be called before sending first Invite request + * with SDP offer. + */ + void initLocalCryptoInfo (void); + private: + /** + * Init local master key according to current crypto context + * as defined in SdesNegotiator.h + */ void initializeLocalMasterKey (void); + /** + * Init local master salt according to current crypto context + * as defined in SdesNegotiator.h + */ void initializeLocalMasterSalt (void); + /** + * Init remote crypto context in audio srtp session. This method + * must be called after unBase64ConcatenatedKeys. + */ void initializeRemoteCryptoContext (void); + /** + * Init local crypto context in audio srtp session. Make sure remote + * crypto context is set before calling this method for incoming calls. + */ void initializeLocalCryptoContext (void); + /** + * Used to generate local keys to be included in SDP offer/answer. + */ std::string getBase64ConcatenatedKeys(); + /** + * Used to retreive keys from base64 serialization + */ void unBase64ConcatenatedKeys (std::string base64keys); + /** + * Encode input data as base64 + */ char* encodeBase64 (unsigned char *input, int length); + /** + * Decode base64 data + */ char* decodeBase64 (unsigned char *input, int length, int *length_out); /** Default local crypto suite is AES_CM_128_HMAC_SHA1_80*/ @@ -128,9 +176,14 @@ class AudioSrtpSession : public ost::SymmetricRTPSession, public AudioRtpSession /** remote master salt length in byte */ int _remoteMasterSaltLength; + /** Remote srtp crypto context to be set into incoming data queue. */ ost::CryptoContext* _remoteCryptoCtx; + /** Local srtp crypto context to be set into outgoing data queue. */ ost::CryptoContext* _localCryptoCtx; + + /** Used to make sure remote crypto context not initialized wice. */ + bool _remoteOfferIsSet; }; } diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index e903d15b016c2f98fcc30403168e38607b9fb833..8c165cdb47e40da481f60e956e2347bb055831c7 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -602,6 +602,9 @@ bool ManagerImpl::offHoldCall (const CallID& call_id) //Place current call on hold if it isn't if (hasCurrentCall()) { + + _debug ("Manager: Has current call, put on hold"); + // if this is not a conferenceand this and is not a conference participant if (!isConference (current_call_id) && !participToConference ( current_call_id)) { @@ -3925,18 +3928,22 @@ ManagerImpl::getAccount (const AccountID& accountID) { // In our definition, // this is the "direct ip calls account" + /* if (accountID == AccountNULL) { - _debug ("Returns the direct IP account"); + _debug ("Manager: Returns the direct IP account"); return _directIpAccount; } + */ AccountMap::iterator iter = _accountMap.find (accountID); - if (iter == _accountMap.end()) { - return NULL; + if (iter != _accountMap.end()) { + _debug ("Manager: Found account %s", iter->first.c_str()); + return iter->second; } - return iter->second; + _debug ("Manager: Did not found account %s, returning IP2IP account", accountID.c_str()); + return _directIpAccount; } AccountID ManagerImpl::getAccountIdFromNameAndServer ( diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index 3c8be5e9eec5d50ddf3a640a3100618e12e74dce..72f3d27c75903a9f082eb641057864b8803b4423 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -1271,21 +1271,6 @@ class ManagerImpl bool removeCallConfig (const CallID& callID); - /** Associate a new CallID to a AccountID - * Protected by mutex - * @param callID the new CallID not in the list yet - * @param accountID the known accountID present in accountMap - * @return bool True if the new association is create - */ - bool associateCallToAccount (const CallID& callID, const AccountID& accountID); - - /** Remove a CallID/AccountID association - * Protected by mutex - * @param callID the CallID to remove - * @return bool True if association is removed - */ - bool removeCallAccount (const CallID& callID); - /** *Contains a list of account (sip, aix, etc) and their respective voiplink/calls */ AccountMap _accountMap; @@ -1325,6 +1310,21 @@ class ManagerImpl public: + /** Associate a new CallID to a AccountID + * Protected by mutex + * @param callID the new CallID not in the list yet + * @param accountID the known accountID present in accountMap + * @return bool True if the new association is create + */ + bool associateCallToAccount (const CallID& callID, const AccountID& accountID); + + /** Remove a CallID/AccountID association + * Protected by mutex + * @param callID the CallID to remove + * @return bool True if association is removed + */ + bool removeCallAccount (const CallID& callID); + /** * Return a pointer to the instance of the mainbuffer */ diff --git a/sflphone-common/src/sip/SdesNegotiator.cpp b/sflphone-common/src/sip/SdesNegotiator.cpp index 430bf80f059f934382cfc0f197523daf99c1052a..9e85492b49867b046b2f393736edbd9cf741d766 100644 --- a/sflphone-common/src/sip/SdesNegotiator.cpp +++ b/sflphone-common/src/sip/SdesNegotiator.cpp @@ -243,9 +243,21 @@ bool SdesNegotiator::negotiate (void) _cryptoSuite = (*iter_offer)->getCryptoSuite(); _srtpKeyMethod = (*iter_offer)->getSrtpKeyMethod(); _srtpKeyInfo = (*iter_offer)->getSrtpKeyInfo(); - _lifetime = (*iter_offer)->getLifetime(); - _mkiValue = (*iter_offer)->getMkiValue(); - _mkiLength = (*iter_offer)->getMkiLength(); + // TODO why does there return empty strings + // _lifetime = (*iter_offer)->getLifetime(); + // _mkiValue = (*iter_offer)->getMkiValue(); + // _mkiLength = (*iter_offer)->getMkiLength(); + + _authTagLength = _cryptoSuite.substr (_cryptoSuite.size()-2, 2); + + std::cout << "Negotiate tag: " + (*iter_offer)->getTag() << std::endl; + std::cout << "Crypto Suite: " + _cryptoSuite << std::endl; + std::cout << "SRTP Key Method: " + _srtpKeyMethod << std::endl; + std::cout << "SRTP Key Info: " + _srtpKeyInfo << std::endl; + // std::cout << "Lifetime: " + _lifetime << std::endl; + // std::cout << "MKI Value: " + _mkiValue << std::endl; + // std::cout << "MKI Length: " + _mkiLength << std::endl; + std::cout << "Auth tag length: " + _authTagLength << std::endl; } iter_local++; diff --git a/sflphone-common/src/sip/SdesNegotiator.h b/sflphone-common/src/sip/SdesNegotiator.h index 1f11324be039ad70e9485d4c2487c74741af5c6a..f62a597e9d5aac6039c8fd34ac28d51c20586b38 100644 --- a/sflphone-common/src/sip/SdesNegotiator.h +++ b/sflphone-common/src/sip/SdesNegotiator.h @@ -202,6 +202,14 @@ class SdesNegotiator return _mkiLength; } + /** + * Authentication tag lenth + */ + std::string getAuthTagLength (void) { + return _authTagLength; + } + + private: /** * A vector list containing the remote attributes. @@ -242,6 +250,11 @@ class SdesNegotiator */ std::string _mkiLength; + /** + * Authenticvation tag length in byte + */ + std::string _authTagLength; + std::vector<CryptoAttribute *> parse (void); }; } diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index 4691dfc74e9cb9318f5508e48d614561c8a8f1c7..15de6085fbbaaf2088879602fa58a42af88d5828 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -820,6 +820,7 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl) _info ("UserAgent: Creating new rtp session"); call->getAudioRtp()->initAudioRtpConfig (call); call->getAudioRtp()->initAudioRtpSession (call); + call->getAudioRtp()->initLocalCryptoInfo (call); } catch (...) { _error ("UserAgent: Error: Failed to create rtp thread from newOutGoingCall"); } @@ -1737,6 +1738,7 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to) try { call->getAudioRtp()->initAudioRtpConfig (call); call->getAudioRtp()->initAudioRtpSession (call); + call->getAudioRtp()->initLocalCryptoInfo (call); } catch (...) { _debug ("UserAgent: Unable to create RTP Session in new IP2IP call (%s:%d)", __FILE__, __LINE__); } @@ -3353,13 +3355,14 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) localCapabilities.push_back (sfl::CryptoSuites[i]); } + // Mkae sure incoming crypto offer is valid sfl::SdesNegotiator sdesnego (localCapabilities, crypto_offer); if (sdesnego.negotiate()) { - _debug ("UserAgent: SDES negociation successfull \n"); + _debug ("UserAgent: SDES negociation successfull"); nego_success = true; - _debug ("UserAgent: Set remote cryptographic context\n"); + _debug ("UserAgent: Set remote cryptographic context"); try { call->getAudioRtp()->setRemoteCryptoInfo (sdesnego); @@ -3372,7 +3375,7 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) } - // We did not found any crypto context for this media + // We did not found any crypto context for this media, RTP fallback if (!nego_success && call->getAudioRtp()->getAudioRtpType() == sfl::Sdes) { // We did not found any crypto context for this media @@ -3390,13 +3393,7 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) call->getAudioRtp()->initAudioRtpSession (call); } - if (nego_success && call->getAudioRtp()->getAudioRtpType() != sfl::Sdes) { - - // We found a crypto context for this media but Sdes is not - // enabled for this call, make a try using RTP only... - _debug ("UserAgent: SDES not initialized for this call\n"); - } - + // Start audio rtp session. Sdp *sdpSession = call->getLocalSDP(); @@ -3679,7 +3676,6 @@ mod_on_rx_request (pjsip_rx_data *rdata) std::string method_name; std::string request; - _info ("UserAgent: Transaction REQUEST received using transport: %s %s (refcnt=%d)", rdata->tp_info.transport->obj_name, rdata->tp_info.transport->info, @@ -3703,6 +3699,8 @@ mod_on_rx_request (pjsip_rx_data *rdata) // Get the account id of callee from username and server account_id = Manager::instance().getAccountIdFromNameAndServer (userName, server); + _debug ("UserAgent: Account ID for this call, %s", account_id.c_str()); + /* If we don't find any account to receive the call */ if (account_id == AccountNULL) { _debug ("UserAgent: Username %s doesn't match any account, using IP2IP!",userName.c_str()); @@ -3863,6 +3861,9 @@ mod_on_rx_request (pjsip_rx_data *rdata) return false; } + Manager::instance().associateCallToAccount (call->getCallId(), account_id); + + std::string addrToUse, addrSdp ="0.0.0.0"; pjsip_tpselector *tp; @@ -3909,13 +3910,64 @@ mod_on_rx_request (pjsip_rx_data *rdata) // We retrieve the remote sdp offer in the rdata struct to begin the negociation call->getLocalSDP()->set_ip_address (addrSdp); + // Init audio rtp session try { + _debug ("UserAgent: Create RTP session for this call"); call->getAudioRtp()->initAudioRtpConfig (call); call->getAudioRtp()->initAudioRtpSession (call); } catch (...) { _warn ("UserAgent: Error: Failed to create rtp thread from answer"); } + // Retreive crypto offer from body, if any + if (rdata->msg_info.msg->body) { + + char sdpbuffer[1000]; + rdata->msg_info.msg->body->print_body (rdata->msg_info.msg->body, sdpbuffer, 1000); + std::string sdpoffer = std::string (sdpbuffer); + size_t start = sdpoffer.find ("a=crypto:"); + + // Found crypto header in SDP + if (start != std::string::npos) { + + std::string cryptoHeader = sdpoffer.substr (start, (sdpoffer.size() - start) -1); + _debug ("UserAgent: Found incoming crypto offer: %s", cryptoHeader.c_str()); + + CryptoOffer crypto_offer; + crypto_offer.push_back (cryptoHeader); + + bool nego_success = false; + + if (!crypto_offer.empty()) { + + _debug ("UserAgent: Crypto attribute in SDP, init SRTP session"); + + // init local cryptografic capabilities for negotiation + std::vector<sfl::CryptoSuiteDefinition>localCapabilities; + + for (int i = 0; i < 3; i++) { + localCapabilities.push_back (sfl::CryptoSuites[i]); + } + + sfl::SdesNegotiator sdesnego (localCapabilities, crypto_offer); + + if (sdesnego.negotiate()) { + _debug ("UserAgent: SDES negociation successfull \n"); + nego_success = true; + + try { + _debug ("UserAgent: Create RTP session for this call"); + call->getAudioRtp()->setRemoteCryptoInfo (sdesnego); + call->getAudioRtp()->initLocalCryptoInfo (call); + } catch (...) { + _warn ("UserAgent: Error: Failed to create rtp thread from answer"); + } + } + } + } + } + + status = call->getLocalSDP()->receiving_initial_offer (r_sdp, account->getActiveCodecs ()); if (status!=PJ_SUCCESS) { @@ -4551,8 +4603,15 @@ bool setCallAudioLocal (SIPCall* call, std::string localIP) { SIPAccount *account = NULL; + _debug ("UserAgent: Set local media information for this call"); + if (call) { - account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (Manager::instance().getAccountFromCall (call->getCallId ()))); + + AccountID account_id = Manager::instance().getAccountFromCall (call->getCallId ()); + + account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (account_id)); + + // Setting Audio unsigned int callLocalAudioPort = RANDOM_LOCAL_PORT; @@ -4564,10 +4623,9 @@ bool setCallAudioLocal (SIPCall* call, std::string localIP) //localIP = account->getPublishedAddress (); } - _debug (" Setting local ip address: %s", localIP.c_str()); - - _debug (" Setting local audio port to: %d", callLocalAudioPort); - _debug (" Setting local audio port (external) to: %d", callLocalExternAudioPort); + _debug ("UserAgent: Setting local ip address: %s", localIP.c_str()); + _debug ("UserAgent: Setting local audio port to: %d", callLocalAudioPort); + _debug ("UserAgent: Setting local audio port (external) to: %d", callLocalExternAudioPort); // Set local audio port for SIPCall(id) call->setLocalIp (localIP); @@ -4577,9 +4635,13 @@ bool setCallAudioLocal (SIPCall* call, std::string localIP) call->getLocalSDP()->attribute_port_to_all_media (callLocalExternAudioPort); return true; - } + } else { - return false; + _error ("UserAgent: Error: No call found while setting media information for this call"); + + return false; + + } } std::string fetch_header_value (pjsip_msg *msg, std::string field) diff --git a/sflphone-common/test/sdesnegotiatortest.cpp b/sflphone-common/test/sdesnegotiatortest.cpp index fd1f630fe70d3288f722b3e3fbb92a77f188d2d0..df6b3675d2679f185f42315b8c8254dd7e9efa50 100644 --- a/sflphone-common/test/sdesnegotiatortest.cpp +++ b/sflphone-common/test/sdesnegotiatortest.cpp @@ -222,12 +222,14 @@ void SdesNegotiatorTest::testMostSimpleCase() CPPUNIT_ASSERT (negotiator->negotiate() == true); - CPPUNIT_ASSERT (negotiator->getCryptoSuite().compare ("AES_CM_128_HMAC_SHA1_80") == 0); - CPPUNIT_ASSERT (negotiator->getKeyMethod().compare ("inline") == 0); - CPPUNIT_ASSERT (negotiator->getKeyInfo().compare ("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd") == 0); - CPPUNIT_ASSERT (negotiator->getLifeTime().compare ("") == 0); - CPPUNIT_ASSERT (negotiator->getMkiValue().compare ("") == 0); - CPPUNIT_ASSERT (negotiator->getMkiLength().compare ("") == 0); + CPPUNIT_ASSERT (negotiator->getCryptoSuite() == "AES_CM_128_HMAC_SHA1_80"); + CPPUNIT_ASSERT (negotiator->getKeyMethod() == "inline"); + CPPUNIT_ASSERT (negotiator->getKeyInfo() == "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); + CPPUNIT_ASSERT (negotiator->getLifeTime() == ""); + CPPUNIT_ASSERT (negotiator->getMkiValue() == ""); + CPPUNIT_ASSERT (negotiator->getMkiLength() == ""); + CPPUNIT_ASSERT (negotiator->getAuthTagLength() == "80"); + delete capabilities; capabilities = NULL; @@ -236,3 +238,41 @@ void SdesNegotiatorTest::testMostSimpleCase() delete negotiator; negotiator = NULL; } + + +void SdesNegotiatorTest::test32ByteKeyLength() +{ + _debug ("-------------------- SdesNegotiatorTest::test32ByteKeyLength --------------------\n"); + + // Register the local capabilities. + std::vector<sfl::CryptoSuiteDefinition> * capabilities = new std::vector<sfl::CryptoSuiteDefinition>(); + + //Support all the CryptoSuites + for (int i = 0; i < 3; i++) { + capabilities->push_back (sfl::CryptoSuites[i]); + } + + std::string cryptoLine ("a=crypto:1 AES_CM_128_HMAC_SHA1_32 inline:AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); + std::vector<std::string> * cryptoOffer = new std::vector<std::string>(); + cryptoOffer->push_back (cryptoLine); + + sfl::SdesNegotiator * negotiator = new sfl::SdesNegotiator (*capabilities, *cryptoOffer); + + CPPUNIT_ASSERT (negotiator->negotiate() == true); + + CPPUNIT_ASSERT (negotiator->getCryptoSuite() == "AES_CM_128_HMAC_SHA1_32"); + CPPUNIT_ASSERT (negotiator->getKeyMethod() == "inline"); + CPPUNIT_ASSERT (negotiator->getKeyInfo() == "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd"); + CPPUNIT_ASSERT (negotiator->getLifeTime() == ""); + CPPUNIT_ASSERT (negotiator->getMkiValue() == ""); + CPPUNIT_ASSERT (negotiator->getMkiLength() == ""); + CPPUNIT_ASSERT (negotiator->getAuthTagLength() == "32"); + + delete capabilities; + capabilities = NULL; + delete cryptoOffer; + cryptoOffer = NULL; + delete negotiator; + negotiator = NULL; +} + diff --git a/sflphone-common/test/sdesnegotiatortest.h b/sflphone-common/test/sdesnegotiatortest.h index ee5cb339645004f6fffc53caf9f596c7c7f53552..eee9de5b356bf1f420645beae14cf7e3169b218f 100644 --- a/sflphone-common/test/sdesnegotiatortest.h +++ b/sflphone-common/test/sdesnegotiatortest.h @@ -76,6 +76,7 @@ class SdesNegotiatorTest : public CppUnit::TestCase { CPPUNIT_TEST( testKeyParamsPatternWithoutMKI ); CPPUNIT_TEST( testNegotiation ); CPPUNIT_TEST( testMostSimpleCase ); + CPPUNIT_TEST( test32ByteKeyLength ); CPPUNIT_TEST_SUITE_END(); public: @@ -90,7 +91,7 @@ class SdesNegotiatorTest : public CppUnit::TestCase { void testKeyParamsPattern(); - void testKeyParamsPatternCiscoStyle(); + void testKeyParamsPatternCiscoStyle(); void testKeyParamsPatternWithoutMKI(); @@ -100,6 +101,8 @@ class SdesNegotiatorTest : public CppUnit::TestCase { void testMostSimpleCase(); + void test32ByteKeyLength(); + private: sfl::Pattern *pattern;