mirror of
https://github.com/ratspeak/ratdeck.git
synced 2026-08-28 05:24:32 +00:00
identity: import identity from SD card
Ported from PR #39 by domints with imported-key validation and hash derivation fixed.
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
#define SD_PATH_MESSAGES "/ratdeck/messages"
|
||||
#define SD_PATH_CONTACTS "/ratdeck/contacts"
|
||||
#define SD_PATH_IDENTITY "/ratdeck/identity/identity.key"
|
||||
#define SD_PATH_IMPORT_ID "/ratdeck/identity/import.key"
|
||||
|
||||
// --- TCP Client ---
|
||||
#define MAX_TCP_CONNECTIONS 4
|
||||
|
||||
@@ -64,6 +64,44 @@ String IdentityManager::slotKeyPath(int slotNum) const {
|
||||
return String(path);
|
||||
}
|
||||
|
||||
int IdentityManager::importIdentity(const String& displayName) {
|
||||
(void)displayName;
|
||||
if (!_sd || !_sd->isReady()) return -1;
|
||||
if ((int)_slots.size() >= MAX_IDENTITIES) return -1;
|
||||
|
||||
uint8_t buffer[64];
|
||||
size_t bytesRead = 0;
|
||||
if (!_sd->readFile(SD_PATH_IMPORT_ID, buffer, sizeof(buffer), bytesRead) || bytesRead != sizeof(buffer)) {
|
||||
Serial.println("[IDMGR] Failed to read 64-byte import identity from SD");
|
||||
return -1;
|
||||
}
|
||||
|
||||
RNS::Bytes privKey(buffer, sizeof(buffer));
|
||||
RNS::Identity imported(false);
|
||||
if (!imported.load_private_key(privKey)) {
|
||||
Serial.println("[IDMGR] Import identity key failed validation");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int slotNum = (int)_slots.size();
|
||||
String keyPath = slotKeyPath(slotNum);
|
||||
if (!_flash->writeAtomic(keyPath.c_str(), privKey.data(), privKey.size())) {
|
||||
Serial.println("[IDMGR] Failed to save imported identity key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
IdentitySlot slot;
|
||||
slot.hash = imported.hexhash();
|
||||
slot.displayName = "";
|
||||
slot.keyPath = keyPath;
|
||||
slot.active = false;
|
||||
_slots.push_back(slot);
|
||||
|
||||
saveSlotMeta();
|
||||
Serial.printf("[IDMGR] Imported identity %d: %s\n", slotNum, slot.hash.substr(0, 16).c_str());
|
||||
return slotNum;
|
||||
}
|
||||
|
||||
int IdentityManager::createIdentity(const String& displayName) {
|
||||
if ((int)_slots.size() >= MAX_IDENTITIES) return -1;
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ public:
|
||||
// Current active identity index (-1 if none)
|
||||
int activeIndex() const { return _activeIdx; }
|
||||
|
||||
// Import identity from SD card, returns index
|
||||
int importIdentity(const String& displayName = "");
|
||||
|
||||
// Create a new identity, returns index
|
||||
int createIdentity(const String& displayName = "");
|
||||
|
||||
|
||||
@@ -463,6 +463,40 @@ void LvSettingsScreen::buildItems() {
|
||||
_items.push_back(newId);
|
||||
idx++;
|
||||
}
|
||||
if (_sd && _sd->isReady()) {
|
||||
SettingItem importId;
|
||||
importId.label = "Import Identity";
|
||||
importId.type = SettingType::ACTION;
|
||||
importId.formatter = [](int) { return String("[Enter]"); };
|
||||
importId.action = [this, &s]() {
|
||||
if (!_sd || !_sd->isReady()) {
|
||||
if (_ui) _ui->lvStatusBar().showToast("No SD card", 1200);
|
||||
return;
|
||||
}
|
||||
if (!_sd->exists(SD_PATH_IMPORT_ID)) {
|
||||
if (_ui) _ui->lvStatusBar().showToast("Missing import.key", 1200);
|
||||
return;
|
||||
}
|
||||
if (!_idMgr) {
|
||||
if (_ui) _ui->lvStatusBar().showToast("Not available", 1200);
|
||||
return;
|
||||
}
|
||||
if (_idMgr->count() >= 8) {
|
||||
if (_ui) _ui->lvStatusBar().showToast("Identity slots full", 1200);
|
||||
return;
|
||||
}
|
||||
int idx = _idMgr->importIdentity(s.displayName);
|
||||
if (idx >= 0) {
|
||||
if (_ui) _ui->lvStatusBar().showToast("Identity imported", 1200);
|
||||
buildItems();
|
||||
rebuildCategoryList();
|
||||
} else if (_ui) {
|
||||
_ui->lvStatusBar().showToast("Identity import failed", 1200);
|
||||
}
|
||||
};
|
||||
_items.push_back(importId);
|
||||
idx++;
|
||||
}
|
||||
_items.push_back({"Auto Announce", SettingType::INTEGER,
|
||||
[&s]() { return s.announceInterval; }, [&s](int v) { s.announceInterval = v; },
|
||||
[](int v) { return String(v) + "m"; }, 30, 60 * 6, 5}); // 30m - 6h
|
||||
|
||||
Reference in New Issue
Block a user