[libav-commits] rtsp: Support decryption of SRTP signalled via RFC 4568 (SDES)

Martin Storsjö git at libav.org
Tue Jan 15 11:15:22 CET 2013


Module: libav
Branch: master
Commit: 424da308302bef604844d3110a39f2f03bf5358e

Author:    Martin Storsjö <martin at martin.st>
Committer: Martin Storsjö <martin at martin.st>
Date:      Sat Oct 20 23:18:01 2012 +0300

rtsp: Support decryption of SRTP signalled via RFC 4568 (SDES)

This only takes care of decrypting incoming packets; the outgoing
RTCP packets are not encrypted. This is enough for some use cases,
and signalling crypto keys for use with outgoing RTCP packets
doesn't fit as simply into the API. If the SDP demuxer is hooked
up with custom IO, the return packets can be encrypted e.g. via the
SRTP protocol.

If the SRTP keys aren't available within the SDP, the decryption
can be handled externally as well (when using custom IO).

Signed-off-by: Martin Storsjö <martin at martin.st>

---

 Changelog             |    1 +
 libavformat/Makefile  |    3 ++-
 libavformat/rtpdec.c  |   14 +++++++++++++-
 libavformat/rtpdec.h  |    6 ++++++
 libavformat/rtsp.c    |   12 ++++++++++++
 libavformat/rtsp.h    |    3 +++
 libavformat/version.h |    2 +-
 7 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/Changelog b/Changelog
index 152fe4c..24f0791 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,7 @@ version 9:
 - av_basename and av_dirname
 - adobe and limelight publisher authentication in RTMP
 - VDPAU hardware acceleration through normal hwaccel
+- SRTP support
 
 
 version 9_beta3:
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 2d66330..7c0b926 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -40,7 +40,8 @@ OBJS-$(CONFIG_RTPDEC)                    += rdt.o                       \
                                             rtpdec_qt.o                 \
                                             rtpdec_svq3.o               \
                                             rtpdec_vp8.o                \
-                                            rtpdec_xiph.o
+                                            rtpdec_xiph.o               \
+                                            srtp.o
 OBJS-$(CONFIG_RTPENC_CHAIN)              += rtpenc_chain.o rtp.o
 
 # muxers/demuxers
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 73d0206..e052ee6 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -26,6 +26,7 @@
 #include "avformat.h"
 #include "mpegts.h"
 #include "network.h"
+#include "srtp.h"
 #include "url.h"
 #include "rtpdec.h"
 #include "rtpdec_formats.h"
@@ -543,6 +544,13 @@ void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
     s->handler                  = handler;
 }
 
+void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
+                             const char *params)
+{
+    if (!ff_srtp_set_crypto(&s->srtp, suite, params))
+        s->srtp_enabled = 1;
+}
+
 /**
  * This was the second switch in rtp_parse packet.
  * Normalizes time, if required, sets stream_index, etc.
@@ -876,7 +884,10 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
 int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
                         uint8_t **bufptr, int len)
 {
-    int rv = rtp_parse_one_packet(s, pkt, bufptr, len);
+    int rv;
+    if (s->srtp_enabled && bufptr && ff_srtp_decrypt(&s->srtp, *bufptr, &len) < 0)
+        return -1;
+    rv = rtp_parse_one_packet(s, pkt, bufptr, len);
     s->prev_ret = rv;
     while (rv == AVERROR(EAGAIN) && has_next_packet(s))
         rv = rtp_parse_queued_packet(s, pkt);
@@ -889,6 +900,7 @@ void ff_rtp_parse_close(RTPDemuxContext *s)
     if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {
         ff_mpegts_parse_close(s->ts);
     }
+    ff_srtp_free(&s->srtp);
     av_free(s);
 }
 
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index b34e099..eaef993 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -27,6 +27,7 @@
 #include "avformat.h"
 #include "rtp.h"
 #include "url.h"
+#include "srtp.h"
 
 typedef struct PayloadContext PayloadContext;
 typedef struct RTPDynamicProtocolHandler RTPDynamicProtocolHandler;
@@ -43,6 +44,8 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
                                    int payload_type, int queue_size);
 void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
                                        RTPDynamicProtocolHandler *handler);
+void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
+                             const char *params);
 int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
                         uint8_t **buf, int len);
 void ff_rtp_parse_close(RTPDemuxContext *s);
@@ -163,6 +166,9 @@ struct RTPDemuxContext {
     /* used to send back RTCP RR */
     char hostname[256];
 
+    int srtp_enabled;
+    struct SRTPContext srtp;
+
     /** Statistics for this stream (used by RTCP receiver reports) */
     RTPStatistics statistics;
 
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 05058d0..9a657fb 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -479,6 +479,14 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
                    s->nb_streams > 0) {
             st = s->streams[s->nb_streams - 1];
             st->codec->sample_rate = atoi(p);
+        } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
+            // RFC 4568
+            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+            get_word(buf1, sizeof(buf1), &p); // ignore tag
+            get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
+            p += strspn(p, SPACE_CHARS);
+            if (av_strstart(p, "inline:", &p))
+                get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
         } else {
             if (rt->server_type == RTSP_SERVER_WMS)
                 ff_wms_parse_sdp_a_line(s, p);
@@ -652,6 +660,10 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
                                               rtsp_st->dynamic_protocol_context,
                                               rtsp_st->dynamic_handler);
         }
+        if (rtsp_st->crypto_suite[0])
+            ff_rtp_parse_set_crypto(rtsp_st->transport_priv,
+                                    rtsp_st->crypto_suite,
+                                    rtsp_st->crypto_params);
     }
 
     return 0;
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index e8d57f2..44240c1 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -440,6 +440,9 @@ typedef struct RTSPStream {
 
     /** Enable sending RTCP feedback messages according to RFC 4585 */
     int feedback;
+
+    char crypto_suite[40];
+    char crypto_params[100];
 } RTSPStream;
 
 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
diff --git a/libavformat/version.h b/libavformat/version.h
index 2944d5e..cb6bc77 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
 #define LIBAVFORMAT_VERSION_MINOR 20
-#define LIBAVFORMAT_VERSION_MICRO  4
+#define LIBAVFORMAT_VERSION_MICRO  5
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \



More information about the libav-commits mailing list