diff --git a/qrtplib/CMakeLists.txt b/qrtplib/CMakeLists.txt index 60ff3cf98..270f7107f 100644 --- a/qrtplib/CMakeLists.txt +++ b/qrtplib/CMakeLists.txt @@ -50,7 +50,6 @@ set (qrtplib_HEADERS rtpudpv6transmitter.h rtpbyteaddress.h rtpexternaltransmitter.h - rtpsecuresession.h rtpsocketutil.h rtpabortdescriptors.h rtpselect.h @@ -94,7 +93,6 @@ set(qrtplib_SOURCES rtpudpv6transmitter.cpp rtpbyteaddress.cpp rtpexternaltransmitter.cpp - rtpsecuresession.cpp rtpabortdescriptors.cpp rtptcpaddress.cpp rtptcptransmitter.cpp diff --git a/qrtplib/rtpsecuresession.cpp b/qrtplib/rtpsecuresession.cpp deleted file mode 100644 index b2e2228eb..000000000 --- a/qrtplib/rtpsecuresession.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - -*/ - -#include "rtpsecuresession.h" - -#ifdef RTP_SUPPORT_SRTP - -#include "rtprawpacket.h" -#include -#include -#include -#include - -using namespace std; -using namespace jthread; - -namespace qrtplib -{ - -// SRTP library needs to be initialized already! - -RTPSecureSession::RTPSecureSession(RTPRandom *rnd, RTPMemoryManager *mgr) : RTPSession(rnd, mgr) -{ - // Make sure the OnChange... functions will be called - SetChangeIncomingData(true); - SetChangeOutgoingData(true); - m_pSRTPContext = 0; - m_lastSRTPError = 0; -} - -RTPSecureSession::~RTPSecureSession() -{ - if (m_pSRTPContext) - srtp_dealloc(m_pSRTPContext); -} - -int RTPSecureSession::InitializeSRTPContext() -{ -#ifdef RTP_SUPPORT_THREAD - if (!m_srtpLock.IsInitialized()) - { - if (m_srtpLock.Init() < 0) - return ERR_RTP_SECURESESSION_CANTINITMUTEX; - } - - JMutexAutoLock l(m_srtpLock); -#endif // RTP_SUPPORT_THREAD - - if (m_pSRTPContext) - return ERR_RTP_SECURESESSION_CONTEXTALREADYINITIALIZED; - - err_status_t result = srtp_create(&m_pSRTPContext, NULL); - if (result != err_status_ok) - { - m_pSRTPContext = 0; - m_lastSRTPError = (int)result; - return ERR_RTP_SECURESESSION_CANTINITIALIZE_SRTPCONTEXT; - } - - return 0; -} - -int RTPSecureSession::GetLastLibSRTPError() -{ -#ifdef RTP_SUPPORT_THREAD - JMutexAutoLock l(m_srtpLock); -#endif // RTP_SUPPORT_THREAD - - int err = m_lastSRTPError; - m_lastSRTPError = 0; // clear it - - return err; -} - -void RTPSecureSession::SetLastLibSRTPError(int err) -{ -#ifdef RTP_SUPPORT_THREAD - JMutexAutoLock l(m_srtpLock); -#endif // RTP_SUPPORT_THREAD - - m_lastSRTPError = err; -} - -srtp_ctx_t *RTPSecureSession::LockSRTPContext() -{ -#ifdef RTP_SUPPORT_THREAD - m_srtpLock.Lock(); -#endif // RTP_SUPPORT_THREAD - - if (!m_pSRTPContext) - { -#ifdef RTP_SUPPORT_THREAD - m_srtpLock.Unlock(); // Make sure the mutex is not locked on error -#endif // RTP_SUPPORT_THREAD - return 0; - } - - return m_pSRTPContext; -} - -int RTPSecureSession::UnlockSRTPContext() -{ - if (!m_pSRTPContext) - return ERR_RTP_SECURESESSION_CONTEXTNOTINITIALIZED; - -#ifdef RTP_SUPPORT_THREAD - m_srtpLock.Unlock(); -#endif // RTP_SUPPORT_THREAD - return 0; -} - -int RTPSecureSession::encryptData(uint8_t *pData, int &dataLength, bool rtp) -{ - int length = dataLength; - - if (rtp) - { - if (length < (int)sizeof(uint32_t)*3) - return ERR_RTP_SECURESESSION_NOTENOUGHDATATOENCRYPT ; - - err_status_t result = srtp_protect(m_pSRTPContext, (void *)pData, &length); - if (result != err_status_ok) - { - m_lastSRTPError = (int)result; - return ERR_RTP_SECURESESSION_CANTENCRYPTRTPDATA; - } - } - else // rtcp - { - if (length < (int)sizeof(uint32_t)*2) - return ERR_RTP_SECURESESSION_NOTENOUGHDATATOENCRYPT; - - err_status_t result = srtp_protect_rtcp(m_pSRTPContext, (void *)pData, &length); - if (result != err_status_ok) - { - m_lastSRTPError = (int)result; - return ERR_RTP_SECURESESSION_CANTENCRYPTRTCPDATA; - } - } - - dataLength = length; - - return 0; -} - -int RTPSecureSession::OnChangeRTPOrRTCPData(const void *origdata, size_t origlen, bool isrtp, void **senddata, size_t *sendlen) -{ - *senddata = 0; - - if (!origdata || origlen == 0) // Nothing to do in this case, packet can be ignored - return 0; - - srtp_ctx_t *pCtx = LockSRTPContext(); - if (pCtx == 0) - return ERR_RTP_SECURESESSION_CONTEXTNOTINITIALIZED; - - // Need to add some extra bytes, and we'll add a few more to be really safe - uint8_t *pDataCopy = RTPNew(GetMemoryManager(), RTPMEM_TYPE_BUFFER_SRTPDATA) uint8_t [origlen + SRTP_MAX_TRAILER_LEN + 32]; - memcpy(pDataCopy, origdata, origlen); - - int status = 0; - int dataLength = (int)origlen; - - if ((status = encryptData(pDataCopy, dataLength, isrtp)) < 0) - { - UnlockSRTPContext(); - RTPDeleteByteArray(pDataCopy, GetMemoryManager()); - return status; - } - - UnlockSRTPContext(); - - *senddata = pDataCopy; - *sendlen = dataLength; - - return 0; -} - -int RTPSecureSession::decryptRawPacket(RTPRawPacket *rawpack, int *srtpError) -{ - *srtpError = 0; - - uint8_t *pData = rawpack->GetData(); - int dataLength = (int)rawpack->GetDataLength(); - - if (rawpack->IsRTP()) - { - if (dataLength < (int)sizeof(uint32_t)*3) - return ERR_RTP_SECURESESSION_NOTENOUGHDATATODECRYPT; - - err_status_t result = srtp_unprotect(m_pSRTPContext, (void*)pData, &dataLength); - if (result != err_status_ok) - { - *srtpError = result; - return ERR_RTP_SECURESESSION_CANTDECRYPTRTPDATA; - } - } - else // RTCP - { - if (dataLength < (int)sizeof(uint32_t)*2) - return ERR_RTP_SECURESESSION_NOTENOUGHDATATODECRYPT; - - err_status_t result = srtp_unprotect_rtcp(m_pSRTPContext, (void *)pData, &dataLength); - if (result != err_status_ok) - { - *srtpError = result; - return ERR_RTP_SECURESESSION_CANTDECRYPTRTCPDATA; - } - } - - rawpack->ZeroData(); // make sure we don't delete the data we're going to store - rawpack->SetData(pData, (size_t)dataLength); - - return 0; -} - -bool RTPSecureSession::OnChangeIncomingData(RTPRawPacket *rawpack) -{ - if (!rawpack) - return false; - - srtp_ctx_t *pCtx = LockSRTPContext(); - if (pCtx == 0) - { - OnErrorChangeIncomingData(ERR_RTP_SECURESESSION_CONTEXTNOTINITIALIZED, 0); - return false; - } - - int srtpErr = 0; - int status = decryptRawPacket(rawpack, &srtpErr); - UnlockSRTPContext(); - - if (status < 0) - { - OnErrorChangeIncomingData(status, srtpErr); - return false; - } - - return true; -} - -void RTPSecureSession::OnSentRTPOrRTCPData(void *senddata, size_t sendlen, bool isrtp) -{ - JRTPLIB_UNUSED(sendlen); - JRTPLIB_UNUSED(isrtp); - - if (senddata) - RTPDeleteByteArray((uint8_t *)senddata, GetMemoryManager()); -} - -} // end namespace - -#endif // RTP_SUPPORT_SRTP - diff --git a/qrtplib/rtpsecuresession.h b/qrtplib/rtpsecuresession.h deleted file mode 100644 index bdfb8532e..000000000 --- a/qrtplib/rtpsecuresession.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - -*/ - -/** - * \file rtpsecuresession.h - */ - -#ifndef RTPSECURESESSION_H - -#define RTPSECURESESSION_H - -#include "rtpconfig.h" - -#ifdef RTP_SUPPORT_SRTP - -#include "rtpsession.h" - -#ifdef RTP_SUPPORT_THREAD - #include -#endif // RTP_SUPPORT_THREAD - -struct srtp_ctx_t; - -namespace qrtplib -{ - -class RTPCrypt; - -// SRTP library needs to be initialized already! - -/** RTPSession derived class that serves as a base class for an SRTP implementation. - * - * This is an RTPSession derived class that serves as a base class for an SRTP implementation. - * The class sets the RTPSession::SetChangeIncomingData and RTPSession::SetChangeOutgoingData - * flags, and implements RTPSession::OnChangeIncomingData, RTPSession::OnChangeRTPOrRTCPData - * and RTPSession::OnSentRTPOrRTCPData so that encryption and decryption is applied to packets. - * The encryption and decryption will be done using [libsrtp](https://github.com/cisco/libsrtp), - * which must be available at compile time. - * - * Your derived class should call RTPSecureSession::InitializeSRTPContext to initialize a context - * struct of `libsrtp`. When this succeeds, the context can be obtained and used with the - * RTPSecureSession::LockSRTPContext function, which also locks a mutex if thread support was - * available. After you're done using the context yourself (to set encryption parameters for - * SSRCs), you **must** release it again using RTPSecureSession::UnlockSRTPContext. - * - * See `example7.cpp` for an example of how to use this class. - */ -class JRTPLIB_IMPORTEXPORT RTPSecureSession : public RTPSession -{ -public: - /** Constructs an RTPSecureSession instance, see RTPSession::RTPSession - * for more information about the parameters. */ - RTPSecureSession(RTPRandom *rnd = 0, RTPMemoryManager *mgr = 0); - ~RTPSecureSession(); -protected: - /** Initializes the SRTP context, in case of an error it may be useful to inspect - * RTPSecureSession::GetLastLibSRTPError. */ - int InitializeSRTPContext(); - - /** This function locks a mutex and returns the `libsrtp` context that was - * created in RTPSecureSession::InitializeSRTPContext, so that you can further - * use it to specify encryption parameters for various sources; note that you - * **must** release the context again after use with the - * RTPSecureSession::UnlockSRTPContext function. */ - srtp_ctx_t *LockSRTPContext(); - - /** Releases the lock on the SRTP context that was obtained in - * RTPSecureSession::LockSRTPContext. */ - int UnlockSRTPContext(); - - /** Returns (and clears) the last error that was encountered when using a - * `libsrtp` based function. */ - int GetLastLibSRTPError(); - - void SetLastLibSRTPError(int err); - - /** In case the reimplementation of OnChangeIncomingData (which may take place - * in a background thread) encounters an error, this member function will be - * called; implement it in a derived class to receive notification of this. */ - virtual void OnErrorChangeIncomingData(int errcode, int libsrtperrorcode); - - int OnChangeRTPOrRTCPData(const void *origdata, size_t origlen, bool isrtp, void **senddata, size_t *sendlen); - bool OnChangeIncomingData(RTPRawPacket *rawpack); - void OnSentRTPOrRTCPData(void *senddata, size_t sendlen, bool isrtp); -private: - int encryptData(uint8_t *pData, int &dataLength, bool rtp); - int decryptRawPacket(RTPRawPacket *rawpack, int *srtpError); - - srtp_ctx_t *m_pSRTPContext; - int m_lastSRTPError; -#ifdef RTP_SUPPORT_THREAD - jthread::JMutex m_srtpLock; -#endif // RTP_SUPPORT_THREAD -}; - -inline void RTPSecureSession::OnErrorChangeIncomingData(int, int) { } - -} // end namespace - -#endif // RTP_SUPPORT_SRTP - -#endif // RTPSECURESESSION_H -