diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp index 921e4a908b01d13809be65b7173e545811bda122..1a2c14ff79fa740e01e4853b410ce5bb7bf1e1a0 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp @@ -26,6 +26,7 @@ #include "manager.h" #include "account.h" #include "sip/sipcall.h" +#include "sip/SdesNegotiator.h" #include <assert.h> @@ -198,10 +199,10 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession() } } -void AudioRtpFactory::setRemoteCryptoInfo() + void AudioRtpFactory::setRemoteCryptoInfo(sfl::SdesNegotiator& nego) { - if ( (_rtpSessionType != NULL) && (_rtpSessionType != Sdes)) { - static_cast<AudioSrtpSession *> (_rtpSession)->setRemoteCryptoInfo(); + if ( (_rtpSessionType != NULL) && (_rtpSessionType == Sdes)) { + static_cast<AudioSrtpSession *> (_rtpSession)->setRemoteCryptoInfo(nego); } else { throw AudioRtpFactoryException(); diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h index 421498010694d26912652cfbec442c02790b2a7f..5165cbffc199b0544e9f47304aa245787c795fd2 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h @@ -22,7 +22,11 @@ #include <stdexcept> #include <cc++/thread.h> +#include "sip/SdesNegotiator.h" + +class SdesNegotiator; class SIPCall; + namespace sfl { class AudioZrtpSession; class AudioSrtpSession; @@ -97,7 +101,7 @@ namespace sfl { * Set remote cryptographic info. Should be called after negotiation in SDP * offer/answer session. */ - void setRemoteCryptoInfo(); + void setRemoteCryptoInfo(sfl::SdesNegotiator& nego); private: void * _rtpSession; diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp index 44e23dd9b29142a8e477bbf46e93c4c983575cdb..0c62c1a9d15ab74487c5a409eaafbf2dc6677f92 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp @@ -47,15 +47,15 @@ AudioSrtpSession::AudioSrtpSession (ManagerImpl * manager, SIPCall * sipcall) : AudioRtpSession<AudioSrtpSession> (manager, sipcall) { _debug ("***************** AudioSrtpSession initialized *********************"); - initializeMasterKey(); - initializeMasterSalt(); - initializeInputCryptoContext(); - initializeOutputCryptoContext(); + initializeLocalMasterKey(); + initializeLocalMasterSalt(); + // initializeRemoteCryptoContext(); + initializeLocalCryptoContext(); - _outputCryptoCtx->deriveSrtpKeys(0); + _localCryptoCtx->deriveSrtpKeys(0); - setInQueueCryptoContext(_inputCryptoCtx); - setOutQueueCryptoContext(_outputCryptoCtx); + // setInQueueCryptoContext(_remoteCryptoCtx); + setOutQueueCryptoContext(_localCryptoCtx); } @@ -71,7 +71,7 @@ std::string AudioSrtpSession::getLocalCryptoInfo() { // format srtp keys as the following // inline:16/14/NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj/2^20/1:32 std::string srtp_keys = "inline:"; - srtp_keys.append("16/14/"); + // srtp_keys.append("16/14/"); srtp_keys += getBase64ConcatenatedKeys(); srtp_keys.append("/2^20/1:32"); @@ -86,30 +86,33 @@ std::string AudioSrtpSession::getLocalCryptoInfo() { } -void AudioSrtpSession::setRemoteCryptoInfo() { +void AudioSrtpSession::setRemoteCryptoInfo(sfl::SdesNegotiator& nego) { _debug("Set remote Cryptographic info for this rtp session"); + unBase64ConcatenatedKeys(nego.getKeyInfo()); + + initializeRemoteCryptoContext(); } -void AudioSrtpSession::initializeMasterKey(void) +void AudioSrtpSession::initializeLocalMasterKey(void) { - _masterKeyLength = 16; + _localMasterKeyLength = 16; for(int i = 0; i < 16; i++) - _masterKey[i] = mk[i]; + _localMasterKey[i] = mk[i]; return; } -void AudioSrtpSession::initializeMasterSalt(void) +void AudioSrtpSession::initializeLocalMasterSalt(void) { - _masterSaltLength = 14; + _localMasterSaltLength = 14; for(int i = 0; i < 14; i++) - _masterSalt[i] = ms[i]; + _localMasterSalt[i] = ms[i]; return; @@ -121,8 +124,8 @@ std::string AudioSrtpSession::getBase64ConcatenatedKeys() // concatenate master and salt uint8 concatenated[30]; - memcpy((void*)concatenated, (void*)_masterKey, 16); - memcpy((void*)(concatenated+16), (void*)_masterSalt, 14); + memcpy((void*)concatenated, (void*)_localMasterKey, 16); + memcpy((void*)(concatenated+16), (void*)_localMasterSalt, 14); // encode concatenated keys in base64 char *output = encodeBase64((unsigned char*)concatenated, 30); @@ -135,19 +138,42 @@ std::string AudioSrtpSession::getBase64ConcatenatedKeys() } -void AudioSrtpSession::initializeInputCryptoContext(void) + void AudioSrtpSession::unBase64ConcatenatedKeys(std::string base64keys) +{ + + char *output = decodeBase64((unsigned char*)base64keys.c_str(), base64keys.size()); + + uint8 finally[30]; + memcpy((void*)finally, (void*)output, 30); + + printf("Master: "); + for(int i = 0; i < 16; i++) { + printf("%i", finally[i]); + } + printf("\n"); + printf("Salt: "); + for(int i = 16; i < 30; i++) { + printf("%i", finally[i]); + } + printf("\n"); + + free(output); +} + + +void AudioSrtpSession::initializeRemoteCryptoContext(void) { // this one does not works // inputCryptoCtx = new ost::CryptoContext(IncomingDataQueue::getLocalSSRCNetwork(), - _inputCryptoCtx = new ost::CryptoContext(0x0, + _remoteCryptoCtx = new ost::CryptoContext(0x0, 0, // roc, 0L, // keydr, SrtpEncryptionAESCM, // encryption algo SrtpAuthenticationSha1Hmac, // authtication algo - _masterKey, // Master Key + _remoteMasterKey, // Master Key 128 / 8, // Master Key length - _masterSalt, // Master Salt + _remoteMasterSalt, // Master Salt 112 / 8, // Master Salt length 128 / 8, // encryption keyl 160 / 8, // authentication key len @@ -157,19 +183,19 @@ void AudioSrtpSession::initializeInputCryptoContext(void) } -void AudioSrtpSession::initializeOutputCryptoContext(void) +void AudioSrtpSession::initializeLocalCryptoContext(void) { // this one works // outputCryptoCtx = new ost::CryptoContext(OutgoingDataQueue::getLocalSSRC(), - _outputCryptoCtx = new ost::CryptoContext(OutgoingDataQueue::getLocalSSRC(), + _localCryptoCtx = new ost::CryptoContext(OutgoingDataQueue::getLocalSSRC(), 0, // roc, 0L, // keydr, SrtpEncryptionAESCM, // encryption algo SrtpAuthenticationSha1Hmac, // authtication algo - _masterKey, // Master Key + _localMasterKey, // Master Key 128 / 8, // Master Key length - _masterSalt, // Master Salt + _localMasterSalt, // Master Salt 112 / 8, // Master Salt length 128 / 8, // encryption keyl 160 / 8, // authentication key len diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.h b/sflphone-common/src/audio/audiortp/AudioSrtpSession.h index a41a90361b3ab200047cfa7f389500b410ce20a0..9055d07c31cd09d9c362da51946ad12e461f306b 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.h @@ -20,9 +20,11 @@ #define __SFL_AUDIO_SRTP_SESSION_H__ #include "AudioRtpSession.h" +#include "sip/SdesNegotiator.h" #include <ccrtp/CryptoContext.h> +class SdesNegotiator; class ManagerImpl; class SIPCall; @@ -44,35 +46,45 @@ namespace sfl { std::string getLocalCryptoInfo(void); - void setRemoteCryptoInfo(void); + void setRemoteCryptoInfo(sfl::SdesNegotiator& nego); private: - void initializeMasterKey(void); + void initializeLocalMasterKey(void); - void initializeMasterSalt(void); + void initializeLocalMasterSalt(void); - void initializeInputCryptoContext(void); + void initializeRemoteCryptoContext(void); - void initializeOutputCryptoContext(void); + void initializeLocalCryptoContext(void); std::string getBase64ConcatenatedKeys(); + void unBase64ConcatenatedKeys(std::string base64keys); + char* encodeBase64(unsigned char *input, int length); char* decodeBase64(unsigned char *input, int length); - uint8 _masterKey[16]; + uint8 _localMasterKey[16]; + + int _localMasterKeyLength; + + uint8 _localMasterSalt[14]; + + int _localMasterSaltLength; + + uint8 _remoteMasterKey[16]; - int _masterKeyLength; + int _remoteMasterKeyLength; - uint8 _masterSalt[14]; + uint8 _remoteMasterSalt[14]; - int _masterSaltLength; + int _remoteMasterSaltLength; - ost::CryptoContext* _inputCryptoCtx; + ost::CryptoContext* _remoteCryptoCtx; - ost::CryptoContext* _outputCryptoCtx; + ost::CryptoContext* _localCryptoCtx; }; } diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index 9c0fba7f7dd8fba4a96e053c3048bbbf27d1650b..e173e0bd1874ddb474a96281de5fd764075aae14 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -3214,34 +3214,38 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) call->getLocalSDP()->set_media_transport_info_from_remote_sdp (remote_sdp); // Get the crypto attribute containing srtp's cryptographic context (keys, cipher) - pjmedia_sdp_attr *attribute; + pjmedia_sdp_attr *attribute = NULL; call->getLocalSDP()->get_remote_sdp_crypto_from_offer(remote_sdp, &attribute); - - - // create remote cryptografic offer - std::vector<std::string> remoteOffer; + if(attribute) { - std::string attr(attribute->value.ptr, attribute->value.slen); + _debug("Crypto attribute in SDP: init Srtp session"); - remoteOffer.push_back(attr); + // create remote cryptografic offer + std::vector<std::string> remoteOffer; - std::vector<sfl::CryptoSuiteDefinition>localCapabilities; - for(int i = 0; i < 3; i++) { - localCapabilities.push_back(sfl::CryptoSuites[i]); - } + // @TODO parser expects attribute names to be present, should not + std::string attr(attribute->value.ptr, attribute->value.slen); + std::string full_attr = "a=crypto:"; + full_attr += attr; + + remoteOffer.push_back(full_attr); - sfl::SdesNegotiator sdesnego(localCapabilities, remoteOffer); + std::vector<sfl::CryptoSuiteDefinition>localCapabilities; + for(int i = 0; i < 3; i++) { + localCapabilities.push_back(sfl::CryptoSuites[i]); + } - sdesnego.negotiate(); + sfl::SdesNegotiator sdesnego(localCapabilities, remoteOffer); + + if(sdesnego.negotiate()) { + _debug("******************** Negociation Is Successfull *********************\n"); - if(sdesnego.negotiate()) { - _debug("******************** Negociation Is Successfull *********************\n"); + call->getAudioRtp()->setRemoteCryptoInfo(sdesnego); + } - call->getAudioRtp()->setRemoteCryptoInfo(); } - try { call->setAudioStart (true); call->getAudioRtp()->start();