rustytoken/src/storage.rs

128 lines
3.7 KiB
Rust
Raw Normal View History

2023-04-27 03:50:18 +00:00
use arduino_hal::eeprom::Eeprom;
pub const SECRET_KEY_MAX_LEN: u16 = 32;
pub const SECRET_KEY_NAME_LEN: u16 = 16;
pub const SECRET_KEY_FULL_LEN: u16 = SECRET_KEY_MAX_LEN + SECRET_KEY_NAME_LEN;
2023-04-28 05:28:12 +00:00
pub const ENDL: u8 = 0;
2023-04-27 03:50:18 +00:00
pub struct Tokens<'a> {
mem: &'a mut Eeprom,
pub current: Option<u16>,
capacity: u16,
}
impl<'a> Tokens<'a> {
2023-04-28 05:28:12 +00:00
pub fn new(mem: &'a mut Eeprom) -> Self {
2023-04-27 03:50:18 +00:00
let capacity = mem.capacity() / SECRET_KEY_FULL_LEN;
let mut tokens = Tokens {
mem,
capacity,
current: None,
};
tokens.current = tokens.first();
tokens
}
pub fn search_free(&self) -> Option<u16> {
for n in 0..self.capacity {
let index = SECRET_KEY_FULL_LEN * n;
2023-04-28 05:28:12 +00:00
if self.mem.read_byte(index) == ENDL {
2023-04-27 03:50:18 +00:00
return Some(n);
}
}
None
}
fn first(&self) -> Option<u16> {
for n in 0..self.capacity {
let index = SECRET_KEY_FULL_LEN * n;
2023-04-28 05:28:12 +00:00
if self.mem.read_byte(index) != ENDL {
2023-04-27 03:50:18 +00:00
return Some(n);
}
}
return None;
}
pub fn next(&mut self) -> Option<u16> {
let mut index = self.current.unwrap();
for _ in 0..self.capacity {
index = (index + 1) % self.capacity;
2023-04-28 05:28:12 +00:00
if self.mem.read_byte(index * SECRET_KEY_FULL_LEN) != ENDL {
2023-04-27 03:50:18 +00:00
self.current = Some(index);
return Some(index);
}
}
None
}
pub fn prev(&mut self) -> Option<u16> {
todo!();
}
2023-04-27 21:21:17 +00:00
pub fn read(&self, index: u16, name: &mut [u8], key: &mut [u8]) -> Result<(usize, usize), ()> {
2023-04-27 03:50:18 +00:00
name.fill(0);
key.fill(0);
let index_name = index * SECRET_KEY_FULL_LEN;
let index_key = (index * SECRET_KEY_FULL_LEN) + SECRET_KEY_NAME_LEN;
2023-04-27 21:21:17 +00:00
self.mem.read(index_name, name).map_err(|_| ())?;
self.mem.read(index_key, key).map_err(|_| ())?;
let len_name = name
2023-04-27 03:50:18 +00:00
.iter()
.position(|&n| n == 0)
.unwrap_or(SECRET_KEY_NAME_LEN as usize);
let len_key = key
2023-04-27 03:50:18 +00:00
.iter()
.position(|&n| n == 0)
.unwrap_or(SECRET_KEY_MAX_LEN as usize);
2023-04-27 21:21:17 +00:00
Ok((len_name, len_key))
2023-04-27 03:50:18 +00:00
}
2023-04-27 21:21:17 +00:00
pub fn write(&mut self, index: u16, name: &[u8], key: &[u8]) -> Result<u16, ()> {
2023-04-27 03:50:18 +00:00
let index_name = index * SECRET_KEY_FULL_LEN;
let index_key = (index * SECRET_KEY_FULL_LEN) + SECRET_KEY_NAME_LEN;
2023-04-27 21:21:17 +00:00
self.mem.write(index_name, name).map_err(|_| ())?;
self.mem.write(index_key, key).map_err(|_| ())?;
Ok(index)
2023-04-27 03:50:18 +00:00
}
pub fn delete(&mut self, index: u16) -> Option<u16> {
// The Arduino's EEPROM memory has a maximum number of write cycles.
// To keep writes to a minimum, only the first byte of the token name is set to 0
2023-04-28 05:28:12 +00:00
// and wipe all the secret key
let index_token = index * SECRET_KEY_FULL_LEN;
let index_key_start = index_token + SECRET_KEY_NAME_LEN;
let index_key_end = index_key_start + SECRET_KEY_MAX_LEN - 1;
self.mem.write_byte(index_token, ENDL);
for index in index_key_start..index_key_end {
self.mem.write_byte(index, ENDL);
}
2023-04-27 03:50:18 +00:00
Some(index)
}
2023-04-27 21:21:17 +00:00
pub fn soft_wipe_all_tokens(&mut self) -> u8 {
2023-04-27 03:50:18 +00:00
let mut inc = 0;
for n in 0..self.capacity {
let index = SECRET_KEY_FULL_LEN * n;
2023-04-28 05:28:12 +00:00
if self.mem.read_byte(index) != ENDL {
2023-04-27 03:50:18 +00:00
self.delete(index);
inc += 1;
}
}
inc
}
2023-04-27 21:21:17 +00:00
pub fn hard_wipe_all_tokens(&mut self) {
2023-04-28 05:28:12 +00:00
for index in 0..self.mem.capacity() {
self.mem.write_byte(index, ENDL);
}
2023-04-27 21:21:17 +00:00
}
2023-04-27 03:50:18 +00:00
}