Skip to content

Commit ceaea40

Browse files
committed
ssh-encoding: PEM line width detection (#252)
Uses the line width detection support added to `pem-rfc7468` in RustCrypto/formats#1464 to automatically detect the input line width and parse PEM documents accordingly, which allows support for a wider range of SSH keys which don't use the default 70 chars of line wrapping. Fixes #195
1 parent 476620d commit ceaea40

5 files changed

Lines changed: 24 additions & 8 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ssh-encoding/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ rust-version = "1.60"
1818
[dependencies]
1919
base64ct = { version = "1.4", optional = true }
2020
bytes = { version = "1", optional = true, default-features = false }
21-
pem-rfc7468 = { version = "1.0.0-rc.0", optional = true }
21+
pem-rfc7468 = { version = "1.0.0-rc.1", optional = true }
2222
sha2 = { version = "=0.11.0-pre.4", optional = true, default-features = false }
2323

2424
[dev-dependencies]

ssh-encoding/src/pem/reader.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::LINE_WIDTH;
21
use crate::{Decode, Error, Reader, Result};
32

43
/// Inner PEM decoder.
@@ -14,11 +13,9 @@ pub struct PemReader<'i> {
1413
}
1514

1615
impl<'i> PemReader<'i> {
17-
/// Create a new PEM reader.
18-
///
19-
/// Uses [`LINE_WIDTH`] as the default line width (i.e. 70 chars).
16+
/// Create a new PEM reader which autodetects the line width of the input.
2017
pub fn new(pem: &'i [u8]) -> Result<Self> {
21-
let inner = Inner::new_wrapped(pem, LINE_WIDTH)?;
18+
let inner = Inner::new_detect_wrap(pem)?;
2219
let remaining_len = inner.remaining_len();
2320

2421
Ok(Self {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-----BEGIN OPENSSH PRIVATE KEY-----
2+
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtz
3+
c2gtZWQyNTUxOQAAACCzPq7zfqLffKoBDe/eo04kH2XxtSmk9D7RQyf1xUqrYgAA
4+
AJgAIAxdACAMXQAAAAtzc2gtZWQyNTUxOQAAACCzPq7zfqLffKoBDe/eo04kH2Xx
5+
tSmk9D7RQyf1xUqrYgAAAEC2BsIi0QwW2uFscKTUUXNHLsYX4FxlaSDSblbAj7WR
6+
7bM+rvN+ot98qgEN796jTiQfZfG1KaT0PtFDJ/XFSqtiAAAAEHVzZXJAZXhhbXBs
7+
ZS5jb20BAgMEBQ==
8+
-----END OPENSSH PRIVATE KEY-----

ssh-key/tests/private_key.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const OPENSSH_ECDSA_P521_EXAMPLE: &str = include_str!("examples/id_ecdsa_p521");
3434
/// Ed25519 OpenSSH-formatted private key
3535
const OPENSSH_ED25519_EXAMPLE: &str = include_str!("examples/id_ed25519");
3636

37+
/// Ed25519 OpenSSH-formatted private key with 64-column line wrapping
38+
const OPENSSH_ED25519_64COLS_EXAMPLE: &str = include_str!("examples/id_ed25519.64cols");
39+
3740
/// RSA (3072-bit) OpenSSH-formatted public key
3841
#[cfg(feature = "alloc")]
3942
const OPENSSH_RSA_3072_EXAMPLE: &str = include_str!("examples/id_rsa_3072");
@@ -247,6 +250,14 @@ fn decode_ed25519_openssh() {
247250
assert_eq!(key.comment(), "[email protected]");
248251
}
249252

253+
/// Test alternative PEM line wrappings (64 columns).
254+
#[test]
255+
fn decode_ed25519_openssh_64cols() {
256+
let key = PrivateKey::from_openssh(OPENSSH_ED25519_64COLS_EXAMPLE).unwrap();
257+
let other_key = PrivateKey::from_openssh(OPENSSH_ED25519_EXAMPLE).unwrap();
258+
assert_eq!(key, other_key);
259+
}
260+
250261
#[cfg(feature = "alloc")]
251262
#[test]
252263
fn decode_rsa_3072_openssh() {

0 commit comments

Comments
 (0)