aboutsummaryrefslogtreecommitdiffstats
path: root/src/identity.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-07 22:35:09 +0100
committertv <tv@krebsco.de>2026-11-07 22:35:09 +0100
commiteed8f86912f53f549d9f9068f9bdf2c8e23aa0f7 (patch)
treee60c309a16f479bdb684f9307b148604c9ec45dd /src/identity.rs
parentde12c862b3f4e69290c8e93b3b4520024ba458f6 (diff)
access: tokens
ct1 tokens: who, how they logged in, a session, when they expire, and optionally a narrower limit; signed by the issuing node's key and taken by every member (a node ID is its key). Revocation by the registry as it stands when a request comes. Auth plan M2.
Diffstat (limited to 'src/identity.rs')
-rw-r--r--src/identity.rs15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/identity.rs b/src/identity.rs
index 04b7e6f..1012d23 100644
--- a/src/identity.rs
+++ b/src/identity.rs
@@ -88,6 +88,19 @@ pub(crate) fn verify(key: &[u8; 32], message: &[u8], signature: &[u8; 64]) -> bo
.is_ok()
}
+/// The public key of the node with ID `id` (`node_id_of`), if it is one.
+pub(crate) fn public_of(id: &str) -> Option<[u8; KEY_BYTES]> {
+ if !is_node_id(id) {
+ return None;
+ }
+ let hex = id.strip_prefix(NODE_ID_PREFIX)?;
+ let mut key = [0u8; KEY_BYTES];
+ for (i, byte) in key.iter_mut().enumerate() {
+ *byte = u8::from_str_radix(hex.get(2 * i..2 * i + 2)?, 16).ok()?;
+ }
+ Some(key)
+}
+
/// Whether `id` has the form of a node ID.
pub(crate) fn is_node_id(id: &str) -> bool {
id.strip_prefix(NODE_ID_PREFIX).is_some_and(|hex| {
@@ -139,6 +152,8 @@ mod tests {
let other = NodeKey::from_seed([3; KEY_BYTES]);
assert!(!verify(&other.public(), b"message", &signature));
assert_eq!(node_id_of(&key.public()), key.id());
+ assert_eq!(public_of(&key.id()), Some(key.public()));
+ assert_eq!(public_of("continuum:00"), None);
}
#[test]