Skip to main content

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}