Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: rogerhardiman via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: rogerhardiman <code@ffmpeg.org>
Subject: [FFmpeg-devel] [PR] Add Digest Authentication with SHA-256 (PR #21517)
Date: Mon, 19 Jan 2026 14:47:30 -0000
Message-ID: <176883405125.25.1874199887005582740@4457048688e7> (raw)

PR #21517 opened by rogerhardiman
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21517
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21517.patch

Based on a patchwork patch by Aki Sakurai from 2022-09-18, with a change to an 'else if' and a fix to av_hash_freep()
The SHA-256 feature was tested with the open source SharpRTSP Server running in SHA-256 Digest Authentication mode.
Testing of the existing MD5 to ensure no breakages was carried out with my room full of different makes of IP camera including IP cameras from Avigilon, Axis, Bosch, HikVision, Panasonic, and TP-Link.



>From 6dd8e902165fca2feadab9c792ce9b66249ea656 Mon Sep 17 00:00:00 2001
From: Roger Hardiman <software@rjh.org.uk>
Date: Mon, 19 Jan 2026 14:03:57 +0000
Subject: [PATCH] Add Digest Authentication with SHA-256 Tested with SharpRTSP
 Camera Server Example Based on a patchwork patch by Aki Sakurai from
 2022-09-18 with a bug fix to an 'else if' and a bug fix to av_hash_freep()

---
 libavformat/httpauth.c | 81 +++++++++++++++++++++++-------------------
 1 file changed, 45 insertions(+), 36 deletions(-)

diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c
index 9048362509..a93b082154 100644
--- a/libavformat/httpauth.c
+++ b/libavformat/httpauth.c
@@ -25,7 +25,7 @@
 #include "libavutil/mem.h"
 #include "internal.h"
 #include "libavutil/random_seed.h"
-#include "libavutil/md5.h"
+#include "libavutil/hash.h"
 #include "urldecode.h"
 
 static void handle_basic_params(HTTPAuthState *state, const char *key,
@@ -118,22 +118,21 @@ void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,
     }
 }
 
-
-static void update_md5_strings(struct AVMD5 *md5ctx, ...)
+static void update_hash_strings(struct AVHashContext *hashctx, ...)
 {
     va_list vl;
 
-    va_start(vl, md5ctx);
+    va_start(vl, hashctx);
     while (1) {
         const char* str = va_arg(vl, const char*);
         if (!str)
             break;
-        av_md5_update(md5ctx, str, strlen(str));
+        av_hash_update(hashctx, str, strlen(str));
     }
     va_end(vl);
 }
 
-/* Generate a digest reply, according to RFC 2617. */
+/* Generate a digest reply, according to RFC 2617 and RFC 7616. */
 static char *make_digest_auth(HTTPAuthState *state, const char *username,
                               const char *password, const char *uri,
                               const char *method)
@@ -144,55 +143,65 @@ static char *make_digest_auth(HTTPAuthState *state, const char *username,
     char cnonce[17];
     char nc[9];
     int i;
-    char A1hash[33], A2hash[33], response[33];
-    struct AVMD5 *md5ctx;
-    uint8_t hash[16];
+    char A1hash[AV_HASH_MAX_SIZE * 2 + 1], A2hash[AV_HASH_MAX_SIZE * 2 + 1], response[AV_HASH_MAX_SIZE * 2  + 1]; // HEX String plus string terminator
+    struct AVHashContext *hashctx = NULL;
+    uint8_t hash[AV_HASH_MAX_SIZE];
+    const char* algorithm = NULL;
+    int hash_size;
     char *authstr;
 
     digest->nc++;
     snprintf(nc, sizeof(nc), "%08x", digest->nc);
 
+    if(!strcmp(digest->algorithm, "") || !strcmp(digest->algorithm, "MD5") || !strcmp(digest->algorithm, "MD5-sess"))
+        algorithm = "MD5";
+    else if(!strcmp(digest->algorithm, "SHA-256") || !strcmp(digest->algorithm, "SHA-256-sess"))
+        algorithm = "SHA256";
+    else if(!strcmp(digest->algorithm, "SHA-512-256") || !strcmp(digest->algorithm, "SHA-512-256-sess"))
+        algorithm = "SHA512/256";
+
+    if (!algorithm) {
+        /* Unsupported algorithm */
+        return NULL;
+    }
+
     /* Generate a client nonce. */
     for (i = 0; i < 2; i++)
         cnonce_buf[i] = av_get_random_seed();
     ff_data_to_hex(cnonce, (const uint8_t*) cnonce_buf, sizeof(cnonce_buf), 1);
 
-    md5ctx = av_md5_alloc();
-    if (!md5ctx)
+    if(av_hash_alloc(&hashctx, algorithm) < 0)
         return NULL;
 
-    av_md5_init(md5ctx);
-    update_md5_strings(md5ctx, username, ":", state->realm, ":", password, NULL);
-    av_md5_final(md5ctx, hash);
-    ff_data_to_hex(A1hash, hash, 16, 1);
+    hash_size = av_hash_get_size(hashctx);
 
-    if (!strcmp(digest->algorithm, "") || !strcmp(digest->algorithm, "MD5")) {
-    } else if (!strcmp(digest->algorithm, "MD5-sess")) {
-        av_md5_init(md5ctx);
-        update_md5_strings(md5ctx, A1hash, ":", digest->nonce, ":", cnonce, NULL);
-        av_md5_final(md5ctx, hash);
-        ff_data_to_hex(A1hash, hash, 16, 1);
-    } else {
-        /* Unsupported algorithm */
-        av_free(md5ctx);
-        return NULL;
+    av_hash_init (hashctx);
+    update_hash_strings(hashctx, username, ":", state->realm, ":", password, NULL);
+    av_hash_final(hashctx, hash);
+    ff_data_to_hex(A1hash, hash, hash_size, 1);
+
+    if (!strcmp(digest->algorithm, "MD5-sess") || !strcmp(digest->algorithm, "SHA-256-sess") ||  !strcmp(digest->algorithm, "SHA-512-256-sess")) {
+        av_hash_init(hashctx);
+        update_hash_strings(hashctx, A1hash, ":", digest->nonce, ":", cnonce, NULL);
+        av_hash_final(hashctx, hash);
+        ff_data_to_hex(A1hash, hash, hash_size, 1);
     }
 
-    av_md5_init(md5ctx);
-    update_md5_strings(md5ctx, method, ":", uri, NULL);
-    av_md5_final(md5ctx, hash);
-    ff_data_to_hex(A2hash, hash, 16, 1);
+    av_hash_init(hashctx);
+    update_hash_strings(hashctx, method, ":", uri, NULL);
+    av_hash_final(hashctx, hash);
+    ff_data_to_hex(A2hash, hash, hash_size, 1);
 
-    av_md5_init(md5ctx);
-    update_md5_strings(md5ctx, A1hash, ":", digest->nonce, NULL);
+    av_hash_init(hashctx);
+    update_hash_strings(hashctx, A1hash, ":", digest->nonce, NULL);
     if (!strcmp(digest->qop, "auth") || !strcmp(digest->qop, "auth-int")) {
-        update_md5_strings(md5ctx, ":", nc, ":", cnonce, ":", digest->qop, NULL);
+        update_hash_strings(hashctx, ":", nc, ":", cnonce, ":", digest->qop, NULL);
     }
-    update_md5_strings(md5ctx, ":", A2hash, NULL);
-    av_md5_final(md5ctx, hash);
-    ff_data_to_hex(response, hash, 16, 1);
+    update_hash_strings(hashctx, ":", A2hash, NULL);
+    av_hash_final(hashctx, hash);
+    ff_data_to_hex(response, hash, hash_size, 1);
 
-    av_free(md5ctx);
+    av_hash_freep(&hashctx);
 
     if (!strcmp(digest->qop, "") || !strcmp(digest->qop, "auth")) {
     } else if (!strcmp(digest->qop, "auth-int")) {
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

                 reply	other threads:[~2026-01-19 14:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=176883405125.25.1874199887005582740@4457048688e7 \
    --to=ffmpeg-devel@ffmpeg.org \
    --cc=code@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git