rtsp_auth/Authenticator: Convert to new hashing API

This commit is contained in:
Peter Keresztes Schmidt 2021-05-25 23:58:10 +02:00
parent 837b32ccff
commit 62f60b76d6
2 changed files with 26 additions and 59 deletions

View File

@ -18,9 +18,9 @@
#include "zm_rtsp_auth.h" #include "zm_rtsp_auth.h"
#include "zm_crypt.h"
#include "zm_logger.h" #include "zm_logger.h"
#include "zm_utils.h" #include "zm_utils.h"
#include <cassert>
#include <cstring> #include <cstring>
#include <utility> #include <utility>
@ -119,74 +119,49 @@ std::string Authenticator::getAuthHeader(const std::string &method, const std::s
} }
std::string Authenticator::computeDigestResponse(const std::string &method, const std::string &uri) { std::string Authenticator::computeDigestResponse(const std::string &method, const std::string &uri) {
#if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
// The "response" field is computed as: // The "response" field is computed as:
// md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>)) // md5(md5(<username>:<realm>:<password>):<nonce>:md5(<cmd>:<url>))
constexpr size_t md5len = 16; char md5HexBuf[zm::crypto::MD5::DIGEST_LENGTH * 2 + 1];
uint8 md5buf[md5len];
char md5HexBuf[md5len * 2 + 1];
// Step 1: md5(<username>:<realm>:<password>) // Step 1: md5(<username>:<realm>:<password>)
std::string ha1Data = username() + ":" + realm() + ":" + password(); std::string ha1Data = username() + ":" + realm() + ":" + password();
Debug( 2, "HA1 pre-md5: %s", ha1Data.c_str() ); Debug(2, "HA1 pre-md5: %s", ha1Data.c_str());
#if HAVE_DECL_MD5
MD5((unsigned char*)ha1Data.c_str(), ha1Data.length(), md5buf); zm::crypto::MD5::Digest md5_digest = zm::crypto::MD5::GetDigestOf(ha1Data);
#elif HAVE_DECL_GNUTLS_FINGERPRINT for (size_t j = 0; j < md5_digest.size(); j++) {
gnutls_datum_t md5dataha1 = {(unsigned char *) ha1Data.c_str(), (unsigned int) ha1Data.length()}; sprintf(&md5HexBuf[2 * j], "%02x", md5_digest[j]);
size_t md5_len_tmp = md5len;
gnutls_fingerprint(GNUTLS_DIG_MD5, &md5dataha1, md5buf, &md5_len_tmp);
assert(md5_len_tmp == md5len);
#endif
for ( unsigned int j = 0; j < md5len; j++ ) {
sprintf(&md5HexBuf[2*j], "%02x", md5buf[j] );
} }
md5HexBuf[md5len*2]='\0'; md5HexBuf[md5_digest.size() * 2] = '\0';
std::string ha1Hash = md5HexBuf; std::string ha1Hash = md5HexBuf;
// Step 2: md5(<cmd>:<url>) // Step 2: md5(<cmd>:<url>)
std::string ha2Data = method + ":" + uri; std::string ha2Data = method + ":" + uri;
Debug( 2, "HA2 pre-md5: %s", ha2Data.c_str() ); Debug(2, "HA2 pre-md5: %s", ha2Data.c_str());
#if HAVE_DECL_MD5
MD5((unsigned char*)ha2Data.c_str(), ha2Data.length(), md5buf ); md5_digest = zm::crypto::MD5::GetDigestOf(ha2Data);
#elif HAVE_DECL_GNUTLS_FINGERPRINT for (size_t j = 0; j < md5_digest.size(); j++) {
gnutls_datum_t md5dataha2 = {(unsigned char *) ha2Data.c_str(), (unsigned int) ha2Data.length()}; sprintf(&md5HexBuf[2 * j], "%02x", md5_digest[j]);
md5_len_tmp = md5len;
gnutls_fingerprint(GNUTLS_DIG_MD5, &md5dataha2, md5buf, &md5_len_tmp);
assert(md5_len_tmp == md5len);
#endif
for ( unsigned int j = 0; j < md5len; j++ ) {
sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] );
} }
md5HexBuf[md5len*2]='\0'; md5HexBuf[md5_digest.size() * 2] = '\0';
std::string ha2Hash = md5HexBuf; std::string ha2Hash = md5HexBuf;
// Step 3: md5(ha1:<nonce>:ha2) // Step 3: md5(ha1:<nonce>:ha2)
std::string digestData = ha1Hash + ":" + nonce(); std::string digestData = ha1Hash + ":" + nonce();
if ( ! fQop.empty() ) { if (!fQop.empty()) {
digestData += ":" + stringtf("%08x", nc) + ":"+fCnonce + ":" + fQop; digestData += ":" + stringtf("%08x", nc) + ":" + fCnonce + ":" + fQop;
nc ++; nc++;
// if qop was specified, then we have to include t and a cnonce and an nccount // if qop was specified, then we have to include t and a cnonce and an nccount
} }
digestData += ":" + ha2Hash; digestData += ":" + ha2Hash;
Debug( 2, "pre-md5: %s", digestData.c_str() ); Debug(2, "pre-md5: %s", digestData.c_str());
#if HAVE_DECL_MD5
MD5((unsigned char*)digestData.c_str(), digestData.length(), md5buf); md5_digest = zm::crypto::MD5::GetDigestOf(digestData);
#elif HAVE_DECL_GNUTLS_FINGERPRINT for (size_t j = 0; j < md5_digest.size(); j++) {
gnutls_datum_t md5datadigest = {(unsigned char *) digestData.c_str(), (unsigned int) digestData.length()}; sprintf(&md5HexBuf[2 * j], "%02x", md5_digest[j]);
md5_len_tmp = md5len;
gnutls_fingerprint(GNUTLS_DIG_MD5, &md5datadigest, md5buf, &md5_len_tmp);
assert(md5_len_tmp == md5len);
#endif
for ( unsigned int j = 0; j < md5len; j++ ) {
sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] );
} }
md5HexBuf[md5len*2]='\0'; md5HexBuf[md5_digest.size() * 2] = '\0';
return md5HexBuf; return md5HexBuf;
#else // HAVE_DECL_MD5
Error("You need to build with gnutls or openssl installed to use digest authentication");
return 0;
#endif // HAVE_DECL_MD5
} }
void Authenticator::checkAuthResponse(const std::string &response) { void Authenticator::checkAuthResponse(const std::string &response) {

View File

@ -22,14 +22,6 @@
#include "zm_config.h" #include "zm_config.h"
#include <string> #include <string>
#if HAVE_GNUTLS_GNUTLS_H
#include <gnutls/gnutls.h>
#endif
#if HAVE_LIBCRYPTO
#include <openssl/md5.h>
#endif // HAVE_LIBCRYPTO
namespace zm { namespace zm {
enum AuthMethod { AUTH_UNDEFINED = 0, AUTH_BASIC = 1, AUTH_DIGEST = 2 }; enum AuthMethod { AUTH_UNDEFINED = 0, AUTH_BASIC = 1, AUTH_DIGEST = 2 };