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