krabka_audit/operator_keys/key_file.rs
1//! One configured `[[operator_keys]]` entry and the key file it names.
2//!
3//! An entry carries the `key_id` that a signed record names, the principal the
4//! key speaks for, and the path to the public key. The file holds a raw
5//! 32-byte Ed25519 public key and nothing else. A file of any other length is
6//! a malformed key, so an encoded key or a trailing newline stops the load.
7
8use {
9 super::OperatorKeyError,
10 std::{
11 fs,
12 path::{Path, PathBuf},
13 },
14};
15
16/// Byte length of a raw Ed25519 public key.
17const ED25519_PUBLIC_KEY_LEN: usize = 32;
18
19/// One `[[operator_keys]]` entry, before its public key file is read.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct OperatorKeyEntry {
22 /// Stable identifier that a signed record names.
23 pub key_id: String,
24 /// The principal this key speaks for.
25 pub principal: String,
26 /// Path to the raw 32-byte Ed25519 public key.
27 pub public_key_path: PathBuf,
28}
29
30pub fn read_public_key(key_id: &str, path: &Path) -> Result<Vec<u8>, OperatorKeyError> {
31 let bytes = fs::read(path).map_err(|source| OperatorKeyError::Unreadable {
32 key_id: key_id.to_owned(),
33 path: path.to_path_buf(),
34 source,
35 })?;
36 if bytes.len() != ED25519_PUBLIC_KEY_LEN {
37 return Err(OperatorKeyError::Malformed {
38 key_id: key_id.to_owned(),
39 path: path.to_path_buf(),
40 found: bytes.len(),
41 });
42 }
43 Ok(bytes)
44}