Added class for challenge-response authentication
This commit is contained in:
parent
fdf26d1669
commit
373bed9121
29
include/ChallengeResponse.h
Normal file
29
include/ChallengeResponse.h
Normal 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;
|
||||||
|
};
|
8
include/Crypto_Config.h.example
Normal file
8
include/Crypto_Config.h.example
Normal 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
54
src/ChallengeResponse.cpp
Normal 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;
|
||||||
|
}
|
Loading…
Reference in a new issue