Create storage class

This commit is contained in:
Christoph Hagen
2023-08-09 13:13:38 +02:00
parent a4cab0931f
commit 67169240f9
8 changed files with 162 additions and 130 deletions

View File

@ -3,18 +3,22 @@
#include "server.h"
#include "servo.h"
#include "message.h"
#include "storage.h"
#include <ESPAsyncWebServer.h>
class SesameController: public ServerConnectionCallbacks {
public:
SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local);
SesameController(ServerConnection* server, ServoController* servo, AsyncWebServer* local, uint8_t remoteDeviceCount);
void configure();
private:
ServerConnection* server;
ServoController* servo;
AsyncWebServer* local;
Storage storage;
// The buffer to hold a received message while it is read
uint8_t receivedMessageBuffer[AUTHENTICATED_MESSAGE_SIZE];
@ -37,6 +41,5 @@ private:
uint16_t prepareResponseBuffer(SesameEvent event, uint8_t deviceId = 0);
void sendPreparedLocalResponse(AsyncWebServerRequest *request);
void sendLocalResponse(AsyncWebServerRequest *request, SesameEvent event, uint8_t deviceId = 0);
void sendPreparedServerResponse();
};

View File

@ -3,11 +3,6 @@
#include <stdint.h>
#include "config.h"
/**
* @brief The size of the message counter in bytes (uint32_t)
*/
#define MESSAGE_COUNTER_SIZE sizeof(uint32_t)
/**
* @brief Configure an NTP server to get the current time
*
@ -54,64 +49,4 @@ void setMessageTimeAllowedOffset(uint32_t offset);
* @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 Initialize the use of the message counter API
*
* The message counter is stored in EEPROM, which must be initialized before use.
*
* @note The ESP32 does not have a true EEPROM,
* which is emulated using a section of the flash memory.
*/
void prepareMessageCounterUsage();
/**
* @brief Get the expected count for the next message.
*
* The counter is stored in EEPROM to persist across restarts
*
* @return The next counter to use by the remote
*/
uint32_t getNextMessageCounter(uint8_t deviceId);
/**
* @brief Print info about the current message counter to the serial output
*
*/
void printMessageCounters();
bool isDeviceIdValid(uint8_t deviceId);
/**
* @brief Check if a received counter is valid
*
* The counter is valid if it is larger than the previous counter
* (larger or equal to the next expected counter).
*
* @param counter The counter to check
* @return true The counter is valid
* @return false The counter belongs to an old message
*/
bool isMessageCounterValid(uint32_t counter, uint8_t deviceId);
/**
* @brief Mark a counter of a message as used.
*
* The counter value is stored in EEPROM to persist across restarts.
*
* All messages with counters lower than the given one will become invalid.
*
* @param counter The counter used in the last message.
*/
void didUseMessageCounter(uint32_t counter, uint8_t deviceId);
/**
* @brief Reset the message counter.
*
* @warning The counter should never be reset in production environments,
* and only together with a new secret key. Otherwise old messages may be
* used for replay attacks.
*
*/
void resetMessageCounters();
bool isMessageTimeAcceptable(uint32_t messageTime);

View File

@ -53,6 +53,8 @@ typedef struct {
} Message;
constexpr size_t messageCounterSize = sizeof(uint32_t);
/**
* @brief An authenticated message by the mobile device to command unlocking.
*

83
include/storage.h Normal file
View File

@ -0,0 +1,83 @@
#pragma once
#include <stdint.h>
class Storage {
public:
Storage(uint8_t remoteDeviceCount) : remoteDeviceCount(remoteDeviceCount) { };
/**
* @brief Initialize the use of the message counter API
*
* The message counter is stored in EEPROM, which must be initialized before use.
*
* @note The ESP32 does not have a true EEPROM,
* which is emulated using a section of the flash memory.
*/
void configure();
/**
* @brief Check if a device ID is allowed
*
* @param deviceId The ID to check
* @return true The id is valid
* @return false The id is invalid
*/
bool isDeviceIdValid(uint8_t deviceId);
/**
* @brief Check if a received counter is valid
*
* The counter is valid if it is larger than the previous counter
* (larger or equal to the next expected counter).
*
* @param counter The counter to check
* @return true The counter is valid
* @return false The counter belongs to an old message
*/
bool isMessageCounterValid(uint32_t counter, uint8_t deviceId);
/**
* @brief Mark a counter of a message as used.
*
* The counter value is stored in EEPROM to persist across restarts.
*
* All messages with counters lower than the given one will become invalid.
*
* @param counter The counter used in the last message.
*/
void didUseMessageCounter(uint32_t counter, uint8_t deviceId);
/**
* @brief Get the expected count for the next message.
*
* The counter is stored in EEPROM to persist across restarts
*
* @return The next counter to use by the remote
*/
uint32_t getNextMessageCounter(uint8_t deviceId);
/**
* @brief Print info about the current message counter to the serial output
*
*/
void printMessageCounters();
/**
* @brief Reset the message counter.
*
* @warning The counter should never be reset in production environments,
* and only together with a new secret key. Otherwise old messages may be
* used for replay attacks.
*
*/
void resetMessageCounters();
private:
uint8_t remoteDeviceCount;
void setMessageCounter(uint32_t counter, uint8_t deviceId);
};