Skip to content

Commit

Permalink
Added basic support of crypto-attribute RFC 4568 to SDP, see #56
Browse files Browse the repository at this point in the history
Signed-off-by:doe300 <[email protected]>
  • Loading branch information
doe300 committed Jun 29, 2016
1 parent 143723f commit f7ed27b
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 25 deletions.
16 changes: 15 additions & 1 deletion include/sip/SDPMessageHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
#ifndef SDPMESSAGEHANDLER_H
#define SDPMESSAGEHANDLER_H

#include <memory>
#include <stdlib.h>
#include <exception>

#include "configuration.h"
#include "KeyValuePairs.h"
#include "PayloadType.h"
#include "crypto/CryptographicContext.h"
#include "sip/SupportedFormats.h"

namespace ohmcomm
Expand Down Expand Up @@ -74,6 +76,8 @@ namespace ohmcomm
static const std::string SDP_ATTRIBUTE_FMTP;
//specifies RTCP-port, if not consecutive to RTP-port, see RFC 3605
static const std::string SDP_ATTRIBUTE_RTCP;
//SDES cryptographic extension, RFC 4568
static const std::string SDP_ATTRIBUTE_CRYPTO;

static const std::string SDP_MEDIA_RTP;
static const std::string SDP_MEDIA_SRTP;
Expand Down Expand Up @@ -131,9 +135,11 @@ namespace ohmcomm
*
* \param media An optional list of media-descriptions to use, defaults to the list of supported formats
*
* \param cryptoContext An optional cryptographic context to use. When set, SRTP is supported in the media-description
*
* \return the generated SDP session-description
*/
static std::string createSessionDescription(const std::string& localUserName, const NetworkConfiguration& config, const std::vector<MediaDescription>& media = {});
static std::string createSessionDescription(const std::string& localUserName, const NetworkConfiguration& config, const std::vector<MediaDescription>& media = {}, const std::shared_ptr<ohmcomm::crypto::CryptographicContext> cryptoContext = nullptr);

/*!
* Ready the session description from the given message and returns it
Expand Down Expand Up @@ -193,6 +199,14 @@ namespace ohmcomm
* \return whether the given encoding is supported
*/
static bool isEncodingSupported(const std::string& encoding);

/*!
* Generates the media-line for the given protocol (RTP/SRTP) and available media-descriptions.
* If no media-descriptions are given, the SupportedFormats are used instead.
*
* \since 1.0
*/
static std::string generateMediaLine(const NetworkConfiguration& config, const std::string protocol, const std::vector<MediaDescription>& media = {});
};
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/crypto/DummyCryptoSuite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,14 @@ std::string CryptoSuite::hashMD5(const std::string& input)
{
throw std::runtime_error("No crypto library configured!");
}

std::vector<unsigned char> CryptoSuite::createHMAC_SHA1(const void* buffer, const unsigned int bufferSize, const std::shared_ptr<CryptographicContext> cryptoContext)
{
throw std::runtime_error("No crypto library configured!");
}

bool CryptoSuite::verifyHMAC_SHA1(const void* hmacBuffer, const unsigned int hmacBufferSize, const void* buffer, const unsigned int bufferSize, const std::shared_ptr<CryptographicContext> cryptoContext)
{
throw std::runtime_error("No crypto library configured!");
}
#endif
68 changes: 44 additions & 24 deletions src/sip/SDPMessageHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

using namespace ohmcomm::sip;

//clang seems to need the static char-fields to be declared for linker to find them
constexpr char SessionDescription::SDP_VERSION;
constexpr char SessionDescription::SDP_ORIGIN;
constexpr char SessionDescription::SDP_SESSION_NAME;
Expand All @@ -27,14 +26,15 @@ constexpr char SessionDescription::SDP_ATTRIBUTE;
const std::string SessionDescription::SDP_ATTRIBUTE_RTPMAP("rtpmap");
const std::string SessionDescription::SDP_ATTRIBUTE_FMTP("fmtp");
const std::string SessionDescription::SDP_ATTRIBUTE_RTCP("rtcp");
const std::string SessionDescription::SDP_ATTRIBUTE_CRYPTO("crypto");
const std::string SessionDescription::SDP_MEDIA_RTP("RTP/AVP");
const std::string SessionDescription::SDP_MEDIA_SRTP("RTP/SAVP");

SDPMessageHandler::SDPMessageHandler()
{
}

std::string SDPMessageHandler::createSessionDescription(const std::string& localUserName, const ohmcomm::NetworkConfiguration& config, const std::vector<MediaDescription>& media)
std::string SDPMessageHandler::createSessionDescription(const std::string& localUserName, const ohmcomm::NetworkConfiguration& config, const std::vector<MediaDescription>& media, const std::shared_ptr<ohmcomm::crypto::CryptographicContext> cryptoContext)
{
ohmcomm::rtp::NTPTimestamp now = ohmcomm::rtp::NTPTimestamp::now();
std::string localIP = Utility::getLocalIPAddress(Utility::getNetworkType(config.remoteIPAddress));
Expand Down Expand Up @@ -121,25 +121,7 @@ std::string SDPMessageHandler::createSessionDescription(const std::string& local
// (SRTP over UDP)
//<fmt> is a media format description [...] If the <proto> sub-field is "RTP/AVP" or "RTP/SAVP" the <fmt> sub-fields contain RTP payload type numbers
// we support Opus and PCM, so we send these payload-types
std::string mediaLine = std::string("m=audio ").append(std::to_string(config.localPort)).append(" RTP/AVP ");
if(media.empty())
{
//suggest all supported media-types
for(const SupportedFormat& format : SupportedFormats::getFormats())
{
mediaLine.append(std::to_string(format.payloadType)).append(" ");
}
}
else
{
//set only selected media
for(const MediaDescription& format : media)
{
mediaLine.append(std::to_string(format.payloadType)).append(" ");
}
}
lines.push_back(mediaLine);
//XXX media for SRTP
lines.push_back(generateMediaLine(config, SessionDescription::SDP_MEDIA_RTP, media));

//Attributes
//a=<attribute> or a=<attribute>:<value>
Expand Down Expand Up @@ -221,10 +203,17 @@ std::string SDPMessageHandler::createSessionDescription(const std::string& local
// - FEC_KEY: Master Key for FEC when the FEC stream is sent to a separate address and/or port.
// - WSH: Window Size Hint.
// - Extensions: Extension parameters can be defined.
if(false) //XXX if SRTP is enabled
if(cryptoContext)
{
lines.push_back(std::string("a=crypto:0 ").append(""/* XXX Algorithm*/).append(" inline:").append(""/*XXX Key*/)
.append(" "/*XXX session-params*/));
//media for SRTP
lines.push_back(generateMediaLine(config, SessionDescription::SDP_MEDIA_SRTP, media));
//XXX are additional rtpmap-attributes required??

const std::string inlineKey = ohmcomm::Utility::encodeBase64(std::string(cryptoContext->masterKey.data(), cryptoContext->masterKey.size()) + std::string(cryptoContext->masterSalt.data(), cryptoContext->masterSalt.size()));

lines.push_back(std::string("a=crypto:1 ").append(cryptoContext->cryptoMode.name).append(" inline:").append(inlineKey)
.append(" "/*session-params*/));

}

std::string result("");
Expand Down Expand Up @@ -465,3 +454,34 @@ bool SDPMessageHandler::isEncodingSupported(const std::string& encoding)
}
return false;
}

std::string SDPMessageHandler::generateMediaLine(const NetworkConfiguration& config, const std::string protocol, const std::vector<MediaDescription>& media)
{
//Media Descriptions
//m=<media> <port> <proto> <fmt> ...
//<media> is the media type. Currently defined media are "audio", "video", "text", "application", and "message"
//<port> is the transport port to which the media stream is sent [...] such as the RTP Control Protocol (RTCP)
// port MAY be derived algorithmically
//<proto> is the transport protocol "udp", "RTP/AVP" (RTP with Audio/Video Profile forMinimal Control over UDP), "RTP/SAVP"
// (SRTP over UDP)
//<fmt> is a media format description [...] If the <proto> sub-field is "RTP/AVP" or "RTP/SAVP" the <fmt> sub-fields contain RTP payload type numbers
// we support Opus and PCM, so we send these payload-types
std::string mediaLine = std::string("m=audio ").append(std::to_string(config.localPort)).append(" ").append(protocol).append(" ");
if(media.empty())
{
//suggest all supported media-types
for(const SupportedFormat& format : SupportedFormats::getFormats())
{
mediaLine.append(std::to_string(format.payloadType)).append(" ");
}
}
else
{
//set only selected media
for(const MediaDescription& format : media)
{
mediaLine.append(std::to_string(format.payloadType)).append(" ");
}
}
return mediaLine;
}

0 comments on commit f7ed27b

Please sign in to comment.