M5b plan: task 04, PGP private key blocks too
The private-key rule also refuses a line that starts `-----BEGIN` and ends `PRIVATE KEY BLOCK-----`, OpenPGP's armor header (RFC 9580 section 6.2.1; RFC 4880 section 6.2). The two endings are a given table, PRIVATE_KEY_ENDS; the skeleton's private_key comment names it. A PGP private key block joins the attack corpus, a PGP public key block and a signature the code-work corpus, and the edge test gains an indented PGP header (refused), a PGP public header and a PGP header without its closing dashes (both pass). Checks: the reference passes the gate on titan, 997 tests (unchanged: the cases are inside existing tests), /tmp unchanged around the run; the task's edits applied to a fresh ref-03 copy are byte-identical to the reference; 8 private-key mutations, 4 of them new for PGP, all caught; tag and private-key-header greps over the task and given files are empty; given files pass rustfmt and the 500-line limit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -315,14 +315,18 @@ fn key_run(after: &str, secret: &Secret) -> bool {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// How a private-key block's first line ends: RFC 7468's labels and OpenSSH's (`… PRIVATE KEY`),
|
||||
/// and OpenPGP's armor header (`PGP PRIVATE KEY BLOCK`, RFC 9580 section 6.2.1).
|
||||
const PRIVATE_KEY_ENDS: &[&str] = &["PRIVATE KEY-----", "PRIVATE KEY BLOCK-----"];
|
||||
|
||||
/// The byte offset of the first line whose text, white space aside, starts `-----BEGIN` and
|
||||
/// ends `PRIVATE KEY-----` (RFC 7468's private-key labels, and OpenSSH's).
|
||||
/// ends with one of `PRIVATE_KEY_ENDS`.
|
||||
fn private_key(text: &str) -> Option<usize> {
|
||||
// For each `(at, _)` in `text.match_indices("-----BEGIN")`: `text.split_at_checked(at)?`
|
||||
// gives `(before, from)`; the line up to `at` is `before.rsplit('\n').next()`, and the line
|
||||
// from `at` is `from.split('\n').next()`, each `.unwrap_or_default()`. Return `Some(at)` for
|
||||
// the first `at` where the first line `trim()`s to empty and the second, `trim_end()`ed,
|
||||
// `ends_with("PRIVATE KEY-----")`. `None` if there is none.
|
||||
// the first `at` where the first line `trim()`s to empty and the second, `trim_end()`ed, ends
|
||||
// with one of `PRIVATE_KEY_ENDS` (`.iter().any(|end| line.ends_with(end))`). Else `None`.
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
@@ -267,6 +267,10 @@ fn a_private_key_header_must_be_a_line_of_its_own() {
|
||||
("after a line", format!("key:\n{header}\nMII")),
|
||||
("indented", format!("key: |\n \t {header}\n")),
|
||||
("with trailing spaces", format!("{header} \nMII")),
|
||||
(
|
||||
"a PGP private key block, indented",
|
||||
format!(" {} \n", pem("BEGIN PGP PRIVATE KEY BLOCK")),
|
||||
),
|
||||
] {
|
||||
assert_eq!(rule(&text), Some("secret-private-key"), "{name}");
|
||||
}
|
||||
@@ -278,6 +282,11 @@ fn a_private_key_header_must_be_a_line_of_its_own() {
|
||||
"-----BEGIN RSA PRIVATE KEY".to_string(),
|
||||
),
|
||||
("a public key", pem("BEGIN RSA PUBLIC KEY")),
|
||||
("a PGP public key block", pem("BEGIN PGP PUBLIC KEY BLOCK")),
|
||||
(
|
||||
"a PGP block without the closing dashes",
|
||||
"-----BEGIN PGP PRIVATE KEY BLOCK".to_string(),
|
||||
),
|
||||
("an end line", pem("END RSA PRIVATE KEY")),
|
||||
] {
|
||||
assert_eq!(rule(&text), None, "{name}");
|
||||
|
||||
@@ -285,6 +285,17 @@ fn attacks() -> Vec<(&'static str, String, &'static str)> {
|
||||
),
|
||||
"secret-private-key",
|
||||
),
|
||||
// OpenPGP's armor header, RFC 9580 section 6.2.1.
|
||||
(
|
||||
"a PGP private key block",
|
||||
format!(
|
||||
"{}\n\nlQOYBF{}\n{}",
|
||||
pem("BEGIN PGP PRIVATE KEY BLOCK"),
|
||||
mixed(40),
|
||||
pem("END PGP PRIVATE KEY BLOCK")
|
||||
),
|
||||
"secret-private-key",
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -380,6 +391,17 @@ fn code_work() -> Vec<(&'static str, String)> {
|
||||
pem("END CERTIFICATE")
|
||||
),
|
||||
),
|
||||
(
|
||||
"a PGP public key block and a signature",
|
||||
format!(
|
||||
"{}\n\nmQINBF{}\n{}\n{}\niQIzBA\n{}",
|
||||
pem("BEGIN PGP PUBLIC KEY BLOCK"),
|
||||
mixed(40),
|
||||
pem("END PGP PUBLIC KEY BLOCK"),
|
||||
pem("BEGIN PGP SIGNATURE"),
|
||||
pem("END PGP SIGNATURE")
|
||||
),
|
||||
),
|
||||
(
|
||||
"the private-key header named inside a line",
|
||||
format!(
|
||||
|
||||
Reference in New Issue
Block a user