Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions libavformat/whip.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ typedef struct WHIPContext {
char key_buf[MAX_CERTIFICATE_SIZE];
/* The fingerprint of certificate, used in SDP offer. */
char *dtls_fingerprint;
/* remote DTLS cert fingerprint from SDP answer (sha-256). */
char *remote_fingerprint;
/**
* This represents the material used to build the SRTP master key. It is
* generated by DTLS and has the following layout:
Expand Down Expand Up @@ -921,6 +923,17 @@ static int parse_answer(AVFormatContext *s)
ret = AVERROR(ENOMEM);
goto end;
}
} else if (av_strstart(line, "a=fingerprint:", &ptr) && !whip->remote_fingerprint) {
/* SDP a=fingerprint format is "<algo> <hex:hex:...>". Skip
* the algo token, store the hex string for post-handshake compare. */
const char *space = strchr(ptr, ' ');
if (space) {
whip->remote_fingerprint = av_strdup(space + 1);
if (!whip->remote_fingerprint) {
ret = AVERROR(ENOMEM);
goto end;
}
}
} else if (av_strstart(line, "a=candidate:", &ptr) && !whip->ice_protocol) {
if (ptr && av_stristr(ptr, "host")) {
/* Refer to RFC 5245 15.1 */
Expand Down Expand Up @@ -970,6 +983,17 @@ static int parse_answer(AVFormatContext *s)
goto end;
}

/* per RFC 8829/8842, SDP answer MUST carry a=fingerprint and that
* fingerprint MUST match the DTLS peer certificate. Without it, an
* on-path attacker can complete DTLS with an arbitrary self-signed
* certificate and the resulting SRTP session is unauthenticated. */
if (!whip->remote_fingerprint || !strlen(whip->remote_fingerprint)) {
av_log(whip, AV_LOG_ERROR,
"No remote DTLS fingerprint in SDP answer; refusing unauthenticated session\n");
ret = AVERROR(EINVAL);
goto end;
}

if (whip->state < WHIP_STATE_NEGOTIATED)
whip->state = WHIP_STATE_NEGOTIATED;
whip->whip_answer_time = av_gettime_relative();
Expand Down Expand Up @@ -2130,6 +2154,7 @@ static av_cold void whip_deinit(AVFormatContext *s)
ffurl_closep(&whip->dtls_uc);
ffurl_closep(&whip->udp);
av_freep(&whip->dtls_fingerprint);
av_freep(&whip->remote_fingerprint);
}

static int whip_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Expand Down
Loading