ESPSomfy-RTS/src/ApiToken.h
cjkas 97d8a90da8 fix: review findings on the token key
- Load the token key in Web::startup(), before either web server starts,
  so no token can be made with the all-zero key; log a failed
  pref.begin().
- createAPIToken checks mbedtls' return codes. On a failure it leaves
  the token empty, which tokenMatches never accepts, instead of hex
  from uninitialised stack.
- API_TOKEN_SIZE in ApiToken.h replaces the five char[65] buffers; the
  HMAC's description moves to createAPIToken, with the None form.
- handleLogin builds the candidate token once and compares it once.
- e2e: the serverId test skips on `secured` like its neighbours, names
  its values, and says it assumes the device sees this PC's address.
- KNOWN_ISSUES keeps #81, which #108 removes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 20:39:08 +01:00

28 lines
1 KiB
C

#ifndef apitoken_h
#define apitoken_h
#include <stddef.h>
#include <stdint.h>
// The token key's size: 32 random bytes the device makes on first boot and
// keeps in NVS. It never leaves the device.
#define API_TOKEN_KEY_SIZE 32
// A token's buffer: an HMAC-SHA256 in hex and its terminator.
#define API_TOKEN_SIZE 65
// True when given is the expected token. It takes the same time whatever
// given holds, so the time doesn't tell how much of a guess was right. Only
// expected's length shows, and every token has the same one. An empty
// expected token, which is what a failed HMAC leaves, matches nothing.
inline bool tokenMatches(const char *expected, const char *given) {
if(!expected || !given || !expected[0]) return false;
uint8_t diff = 0;
for(size_t i = 0; expected[i]; i++) {
diff |= (uint8_t)(expected[i] ^ *given);
// A shorter given compares its terminator with the rest of expected.
if(*given) given++;
}
// A longer given doesn't match either.
diff |= (uint8_t)*given;
return diff == 0;
}
#endif