From c2e566599aed088973b5a5be2bb04ee69cee5c7a Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 9 Nov 2026 02:49:25 +0000 Subject: access: keep an SSH key's comment A key's line was stored as the key alone (`ssh-ed25519 `), whatever comment it came with, both from `PUT /auth/keys/` 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. --- src/access/sshsig.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/access/sshsig.rs') 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 [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 { + 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. -- cgit v1.3.1