* [FFmpeg-devel] [PR] Add Digest Authentication with SHA-256 (PR #21517)
@ 2026-01-19 14:47 rogerhardiman via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: rogerhardiman via ffmpeg-devel @ 2026-01-19 14:47 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: rogerhardiman
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-01-19 14:48 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-19 14:47 [FFmpeg-devel] [PR] Add Digest Authentication with SHA-256 (PR #21517) rogerhardiman via ffmpeg-devel
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