Create time class
This commit is contained in:
parent
67169240f9
commit
d13bf67443
@ -4,12 +4,13 @@
|
||||
#include "servo.h"
|
||||
#include "message.h"
|
||||
#include "storage.h"
|
||||
#include "fresh.h"
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
class SesameController: public ServerConnectionCallbacks {
|
||||
|
||||
public:
|
||||
SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, uint8_t remoteDeviceCount);
|
||||
SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, TimeCheck* timeCheck, uint8_t remoteDeviceCount);
|
||||
|
||||
void configure();
|
||||
|
||||
@ -18,6 +19,7 @@ private:
|
||||
ServerConnection* server;
|
||||
ServoController* servo;
|
||||
AsyncWebServer* local;
|
||||
TimeCheck* timeCheck;
|
||||
Storage storage;
|
||||
|
||||
// The buffer to hold a received message while it is read
|
||||
|
117
include/fresh.h
117
include/fresh.h
@ -3,50 +3,81 @@
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
|
||||
/**
|
||||
* @brief Configure an NTP server to get the current time
|
||||
*
|
||||
* @param offsetToGMT The timezone offset in seconds
|
||||
* @param offsetDaylightSavings The daylight savings offset in seconds
|
||||
* @param serverUrl The url of the NTP server
|
||||
*/
|
||||
void configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl);
|
||||
class TimeCheck {
|
||||
|
||||
/**
|
||||
* @brief Print the current time to the serial output
|
||||
*
|
||||
* The time must be initialized by calling `configureNTP()` before use.
|
||||
*/
|
||||
void printLocalTime();
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets the current epoch time
|
||||
*/
|
||||
uint32_t getEpochTime();
|
||||
/**
|
||||
* @brief Create a time checker instance
|
||||
*
|
||||
* Specify the allowed discrepancy between the time of a received message
|
||||
* and the device time (in seconds).
|
||||
*
|
||||
* A stricter (lower) value better prevents against replay attacks,
|
||||
* but may lead to issues when dealing with slow networks and other
|
||||
* routing delays.
|
||||
*
|
||||
* @param offset The allowed time discrepancy in both directions (seconds)
|
||||
*/
|
||||
TimeCheck(uint32_t allowedTimeOffset = 60);
|
||||
|
||||
/**
|
||||
* @brief The allowed time discrepancy (in seconds)
|
||||
*
|
||||
* Specifies the allowed discrepancy between the time of a received message
|
||||
* and the device time (in seconds).
|
||||
*
|
||||
* A stricter (lower) value better prevents against replay attacks,
|
||||
* but may lead to issues when dealing with slow networks and other
|
||||
* routing delays.
|
||||
*
|
||||
* @param offset The offset in both directions (seconds)
|
||||
*/
|
||||
void setMessageTimeAllowedOffset(uint32_t offset);
|
||||
/**
|
||||
* @brief Configure an NTP server to get the current time
|
||||
*
|
||||
* @param offsetToGMT The timezone offset in seconds
|
||||
* @param offsetDaylightSavings The daylight savings offset in seconds
|
||||
* @param serverUrl The url of the NTP server
|
||||
*/
|
||||
void configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl);
|
||||
|
||||
/**
|
||||
* @brief Check wether the time of a message is within the allowed bounds regarding freshness.
|
||||
*
|
||||
* The timestamp is used to ensure 'freshness' of the messages,
|
||||
* i.e. that they are not unreasonably delayed or captured and
|
||||
* later replayed by an attacker.
|
||||
*
|
||||
* @param messageTime The timestamp of the message (seconds since epoch)
|
||||
* @return true The time is within the acceptable offset of the local time
|
||||
* @return false The message time is invalid
|
||||
*/
|
||||
bool isMessageTimeAcceptable(uint32_t messageTime);
|
||||
/**
|
||||
* @brief Print the current time to the serial output
|
||||
*
|
||||
* The time must be initialized by calling `configureNTP()` before use.
|
||||
*/
|
||||
void printLocalTime();
|
||||
|
||||
/**
|
||||
* Gets the current epoch time
|
||||
*/
|
||||
uint32_t getEpochTime();
|
||||
|
||||
/**
|
||||
* @brief The allowed time discrepancy (in seconds)
|
||||
*
|
||||
* Specifies the allowed discrepancy between the time of a received message
|
||||
* and the device time (in seconds).
|
||||
*
|
||||
* A stricter (lower) value better prevents against replay attacks,
|
||||
* but may lead to issues when dealing with slow networks and other
|
||||
* routing delays.
|
||||
*
|
||||
* @param offset The offset in both directions (seconds)
|
||||
*/
|
||||
void setMessageTimeAllowedOffset(uint32_t offset);
|
||||
|
||||
/**
|
||||
* @brief Check wether the time of a message is within the allowed bounds regarding freshness.
|
||||
*
|
||||
* The timestamp is used to ensure 'freshness' of the messages,
|
||||
* i.e. that they are not unreasonably delayed or captured and
|
||||
* later replayed by an attacker.
|
||||
*
|
||||
* @param messageTime The timestamp of the message (seconds since epoch)
|
||||
* @return true The time is within the acceptable offset of the local time
|
||||
* @return false The message time is invalid
|
||||
*/
|
||||
bool isMessageTimeAcceptable(uint32_t messageTime);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief The allowed discrepancy between the time of a received message
|
||||
* and the device time (in seconds)
|
||||
*
|
||||
* A stricter (lower) value better prevents against replay attacks,
|
||||
* but may lead to issues when dealing with slow networks and other
|
||||
* routing delays.
|
||||
*/
|
||||
uint32_t allowedOffset;
|
||||
};
|
@ -3,8 +3,8 @@
|
||||
#include "fresh.h"
|
||||
#include "crypto.h"
|
||||
|
||||
SesameController::SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, uint8_t remoteDeviceCount) :
|
||||
server(server), servo(servo), local(local), storage(remoteDeviceCount) {
|
||||
SesameController::SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, TimeCheck* timeCheck, uint8_t remoteDeviceCount) :
|
||||
server(server), servo(servo), local(local), timeCheck(timeCheck), storage(remoteDeviceCount) {
|
||||
|
||||
// Set up response buffer
|
||||
responseStatus = (SesameEvent*) responseBuffer;
|
||||
@ -99,7 +99,7 @@ SesameEvent SesameController::verifyAndProcessReceivedMessage(AuthenticatedMessa
|
||||
if (!storage.isMessageCounterValid(message->message.id, message->message.device)) {
|
||||
return SesameEvent::MessageCounterInvalid;
|
||||
}
|
||||
if (!isMessageTimeAcceptable(message->message.time)) {
|
||||
if (!timeCheck->isMessageTimeAcceptable(message->message.time)) {
|
||||
return SesameEvent::MessageTimeMismatch;
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ uint16_t SesameController::prepareResponseBuffer(SesameEvent event, uint8_t devi
|
||||
if (!allowMessageResponse(event)) {
|
||||
return 1;
|
||||
}
|
||||
responseMessage->message.time = getEpochTime();
|
||||
responseMessage->message.time = timeCheck->getEpochTime();
|
||||
responseMessage->message.id = storage.getNextMessageCounter(deviceId);
|
||||
responseMessage->message.device = deviceId;
|
||||
if (!authenticateMessage(responseMessage, localKey, keySize)) {
|
||||
|
@ -1,27 +1,17 @@
|
||||
#include "fresh.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Arduino.h> // configTime()
|
||||
#include <time.h>
|
||||
|
||||
/**
|
||||
* @brief The allowed discrepancy between the time of a received message
|
||||
* and the device time (in seconds)
|
||||
*
|
||||
* A stricter (lower) value better prevents against replay attacks,
|
||||
* but may lead to issues when dealing with slow networks and other
|
||||
* routing delays.
|
||||
*/
|
||||
uint32_t allowedOffset = 60;
|
||||
|
||||
void setMessageTimeAllowedOffset(uint32_t offset) {
|
||||
allowedOffset = offset;
|
||||
TimeCheck::TimeCheck(uint32_t allowedTimeOffset) {
|
||||
allowedOffset = allowedTimeOffset;
|
||||
}
|
||||
|
||||
void configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl) {
|
||||
void TimeCheck::configureNTP(int32_t offsetToGMT, int32_t offsetDaylightSavings, const char* serverUrl) {
|
||||
configTime(offsetToGMT, offsetDaylightSavings, serverUrl);
|
||||
}
|
||||
|
||||
void printLocalTime() {
|
||||
void TimeCheck::printLocalTime() {
|
||||
struct tm timeinfo;
|
||||
if (getLocalTime(&timeinfo)) {
|
||||
Serial.println(&timeinfo, "[INFO] Time is %A, %d. %B %Y %H:%M:%S");
|
||||
@ -30,7 +20,7 @@ void printLocalTime() {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t getEpochTime() {
|
||||
uint32_t TimeCheck::getEpochTime() {
|
||||
time_t now;
|
||||
struct tm timeinfo;
|
||||
if (!getLocalTime(&timeinfo)) {
|
||||
@ -41,7 +31,7 @@ uint32_t getEpochTime() {
|
||||
return now;
|
||||
}
|
||||
|
||||
bool isMessageTimeAcceptable(uint32_t t) {
|
||||
bool TimeCheck::isMessageTimeAcceptable(uint32_t t) {
|
||||
uint32_t localTime = getEpochTime();
|
||||
if (localTime == 0) {
|
||||
Serial.println("No epoch time available");
|
||||
|
@ -19,13 +19,15 @@
|
||||
|
||||
/* Global variables */
|
||||
|
||||
TimeCheck timeCheck{};
|
||||
|
||||
ServerConnection server(serverUrl, serverPort, serverPath);
|
||||
|
||||
ServoController servo(pwmTimer, servoFrequency, servoPin);
|
||||
|
||||
AsyncWebServer local(localPort);
|
||||
|
||||
SesameController controller(&server, &servo, &local, remoteDeviceCount);
|
||||
SesameController controller(&server, &servo, &local, &timeCheck, remoteDeviceCount);
|
||||
|
||||
// Forward declare monitoring functions
|
||||
void ensureWiFiConnection(uint32_t time);
|
||||
@ -75,8 +77,8 @@ void ensureWebSocketConnection(uint32_t time) {
|
||||
Serial.println(WiFi.localIP());
|
||||
Serial.println("[INFO] WiFi connected, opening socket");
|
||||
server.connect(serverAccessKey);
|
||||
configureNTP(timeOffsetToGMT, timeOffsetDaylightSavings, ntpServerUrl);
|
||||
printLocalTime();
|
||||
timeCheck.configureNTP(timeOffsetToGMT, timeOffsetDaylightSavings, ntpServerUrl);
|
||||
timeCheck.printLocalTime();
|
||||
local.begin();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user