diff --git a/Changelog b/Changelog index 152fe4c840..24f079192d 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 2d663300fd..7c0b926407 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 73d02069ea..e052ee6f33 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 b34e099b32..eaef993d09 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 05058d014a..9a657fb440 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 e8d57f283a..44240c1d0f 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 2944d5e1f8..cb6bc7727c 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, \