code
sip_authenticator.hpp
/*
sip authenticator:authenticate while sip registering
*/
#pragma once
#include <string>
namespace lxz
{
class SIPAuthenticator
{
public:
static std::string GetHA1(const std::string &user, const std::string &realm, const std::string &passwd, std::string algorithm = "", std::string nonce = "", std::string cnonce = "");
static std::string GetHA2(const std::string &method, const std::string °istURI, std::string qop = "", std::string entityBody = "");
static std::string GetResponse(const std::string &HA1, const std::string &HA2, const std::string &nonce, std::string qop = "", int nonceCnt = 0, std::string cnonce = "");
private:
SIPAuthenticator(){};
~SIPAuthenticator(){};
// std::string algorithm_; // MD5(default) or MD5-sess
// std::string qop_; // auth(defalut) or auth-int
};
}
sip_authenticator.cpp
#include "sip_authenticator.hpp"
#include "md5/md5.hpp"
#include "string_ops.hpp"
namespace lxz
{
std::string SIPAuthenticator::GetHA1(const std::string &user, const std::string &realm, const std::string &passwd, std::string algorithm, std::string nonce, std::string cnonce)
{
std::string HA1 = "";
// md5_init
// md5_append
// md5_finish
if (algorithm.empty() || (algorithm == "MD5"))
{
// HA1 = MD5(username:realm:password)
md5::md5_state_t md5_st;
md5::md5_byte_t md5[16] = {0};
std::string src;
src = user;
src += ":";
src += realm;
src += ":";
src += passwd;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src.c_str()), src.size());
md5::md5_finish(&md5_st, md5);
HA1 = lxz::GetHexString((unsigned char *)md5, 16);
}
else if (algorithm == "MD5-sess")
{
// HA1 = MD5(MD5(username:realm:password):nonce:cnonce)
std::string src1;
std::string src2;
md5::md5_state_t md5_st;
md5::md5_byte_t md5[16] = {0};
src1 = user;
src1 += ":";
src1 += realm;
src1 += ":";
src1 += passwd;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src1.c_str()), src1.size());
md5::md5_finish(&md5_st, md5);
src2 = lxz::GetHexString((unsigned char *)md5, 16);
src2 += ":";
src2 += nonce;
src2 += ":";
src2 += cnonce;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src2.c_str()), src2.size());
md5::md5_finish(&md5_st, md5);
HA1 = lxz::GetHexString((unsigned char *)md5, 16);
}
return HA1;
}
std::string SIPAuthenticator::GetHA2(const std::string &method, const std::string °istURI, std::string qop, std::string entityBody)
{
std::string HA2 = "";
if (qop.empty() || (qop == "auth"))
{
// HA2 = MD5(method:digestURI)
std::string src;
md5::md5_state_t md5_st;
md5::md5_byte_t md5[16] = {0};
src = method;
src += ":";
src += degistURI;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src.c_str()), src.size());
md5::md5_finish(&md5_st, md5);
HA2 = lxz::GetHexString((unsigned char *)md5, 16);
}
else if (qop == "auth-int")
{
// HA2 = MD5(method:digestURI:MD5(entityBody))
std::string src1;
std::string src2;
std::string src3;
md5::md5_state_t md5_st;
md5::md5_byte_t md5[16] = {0};
src1 = entityBody;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src1.c_str()), src1.size());
md5::md5_finish(&md5_st, md5);
src2 = lxz::GetHexString((unsigned char *)md5, 16);
src3 = method;
src3 += ":";
src3 += degistURI;
src3 += ":";
src3 += src2;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src3.c_str()), src3.size());
md5::md5_finish(&md5_st, md5);
HA2 = lxz::GetHexString((unsigned char *)md5, 16);
}
return HA2;
}
std::string SIPAuthenticator::GetResponse(const std::string &HA1, const std::string &HA2, const std::string &nonce, std::string qop, int nonceCnt, std::string cnonce)
{
std::string response = "";
md5::md5_state_t md5_st;
md5::md5_byte_t md5[16] = {0};
std::string src;
if (qop.empty())
{
// response = MD5(HA1:nonce:HA2)
src = HA1;
src += ":";
src += nonce;
src += ":";
src += HA2;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src.c_str()), src.size());
md5::md5_finish(&md5_st, md5);
response = lxz::GetHexString((unsigned char *)md5, 16);
}
else if ((qop == "auth") || (qop == "auth-int"))
{
// response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)
src = HA1;
src += ":";
src += nonce;
src += ":";
src += std::to_string(nonceCnt);
src += ":";
src += cnonce;
src += ":";
src += qop;
src += HA2;
md5::md5_init(&md5_st);
md5::md5_append(&md5_st, (md5::md5_byte_t *const)(src.c_str()), src.size());
md5::md5_finish(&md5_st, md5);
response = lxz::GetHexString((unsigned char *)md5, 16);
}
return response;
}
}
demo