Added class for challenge-response authentication

This commit is contained in:
Thomas Kolb 2019-11-25 22:00:48 +01:00
parent fdf26d1669
commit 373bed9121
3 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,29 @@
#pragma once
#include <string>
class ChallengeResponse
{
public:
const unsigned long NONCE_LIFETIME_MS = 3000;
ChallengeResponse(const std::string &pw);
bool verify(const std::string &hash);
/*!
* Initiate a new challenge-response round.
*
* Updates the internal state and returns the nonce to be sent to the client.
* The challenge must be answered within NONCE_LIFETIME_MS milliseconds.
*
* \returns The nonce.
*/
uint32_t nonce(void);
private:
std::string m_passwd;
uint32_t m_currentNonce;
unsigned long m_expireTime;
};

View File

@ -0,0 +1,8 @@
#pragma once
namespace crypto
{
// replace these with your own values!
static const char * const HTTP_PASSWORD = "secure!1";
static const char * const SALT = "1234567890abcdefghijklmnopqrstuv";
}

54
src/ChallengeResponse.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <sstream>
#include <algorithm>
#include <Arduino.h> // for esp_random() and millis()
#include <mbedtls/sha256.h>
#include "ChallengeResponse.h"
#include "Crypto_Config.h"
ChallengeResponse::ChallengeResponse(const std::string &pw)
: m_passwd(pw), m_expireTime(0)
{
}
bool ChallengeResponse::verify(const std::string &hash)
{
if(millis() > m_expireTime) {
// challenge timed out
return false;
}
std::ostringstream refResponse;
refResponse << m_passwd << ":" << m_currentNonce << ":" << crypto::SALT;
// calculate hash of reference response
uint8_t sha256sum[32];
mbedtls_sha256_ret(reinterpret_cast<const unsigned char*>(refResponse.str().data()),
refResponse.str().length(), sha256sum, 0);
// convert hash to hex
std::ostringstream hexHash;
for(size_t i = 0; i < 32; i++) {
static const char *conv = "0123456789abcdef";
uint8_t b = sha256sum[i];
hexHash << conv[(b >> 4)];
hexHash << conv[(b &0x0F)];
}
std::string lowerHash;
std::transform(hash.begin(), hash.end(), lowerHash.begin(),
[](char c) { return std::tolower(c);});
return hexHash.str() == hash;
}
uint32_t ChallengeResponse::nonce(void)
{
m_currentNonce = esp_random();
m_expireTime = millis() + NONCE_LIFETIME_MS;
return m_currentNonce;
}