aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/sshsig.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-09 02:49:25 +0000
committertv <tv@krebsco.de>2026-11-09 02:49:25 +0000
commitc2e566599aed088973b5a5be2bb04ee69cee5c7a (patch)
tree11fb923c99318f6e927bcaff65ed918865b6ab54 /src/access/sshsig.rs
parent51c7a4c2588b3f4064ba116276796741b3170de6 (diff)
access: keep an SSH key's comment
A key's line was stored as the key alone (`ssh-ed25519 <base64>`), whatever comment it came with, both from `PUT /auth/keys/<name>` and from `--bootstrap-keys`. Now its comment is kept after it (`PublicKey::kept_line`), the spaces between its words made one. The comment checks nothing: every use of a key parses the line, and the parse reads the key alone.
Diffstat (limited to 'src/access/sshsig.rs')
-rw-r--r--src/access/sshsig.rs19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/access/sshsig.rs b/src/access/sshsig.rs
index 6091528..799cb87 100644
--- a/src/access/sshsig.rs
+++ b/src/access/sshsig.rs
@@ -65,6 +65,19 @@ impl PublicKey {
format!("{KEY_TYPE} {}", BASE64.encode(self.blob()))
}
+ /// `line` (`ssh-ed25519 <base64> [comment]`) as a registry keeps it: the key as
+ /// `line` makes it, then its comment, if any, as it was (its spaces between words
+ /// made one). The comment is for whoever reads it: the key alone checks a signature.
+ pub(crate) fn kept_line(line: &str) -> Result<String, String> {
+ let key = Self::parse(line)?;
+ let comment: Vec<&str> = line.split_whitespace().skip(2).collect();
+ Ok(if comment.is_empty() {
+ key.line()
+ } else {
+ format!("{} {}", key.line(), comment.join(" "))
+ })
+ }
+
/// Its fingerprint, as `ssh-keygen -l` shows it: `SHA256:` and the base64 of its
/// encoding's SHA-256, unpadded.
pub(crate) fn fingerprint(&self) -> String {
@@ -244,6 +257,12 @@ DNg4vBWp1j1gLRiBMOF+gwYNegDg==
assert!(verify(OPENSSH_SIGNATURE, "unittest", b"This is a test").is_err());
assert_eq!(PublicKey::parse(&key.line()), Ok(key));
assert!(key.fingerprint().starts_with("SHA256:"));
+ // Kept with its comment, which doesn't change the key.
+ let commented =
+ PublicKey::kept_line(&format!("{} alice@laptop 2026", key.line())).unwrap();
+ assert_eq!(commented, format!("{} alice@laptop 2026", key.line()));
+ assert_eq!(PublicKey::parse(&commented), Ok(key));
+ assert_eq!(PublicKey::kept_line(&key.line()), Ok(key.line()));
}
/// What `sign` makes checks, and reads as `ssh-keygen` writes it.