diff --git a/Cargo.lock b/Cargo.lock index 68d62f2..89177ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,8 +50,7 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64ct" version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +source = "git+https://github.com/mpalmer/rust-crypto-formats.git?branch=b64ct-decode-empty-at-end#522249156cf318821227e7effbe81d807339dfb7" [[package]] name = "bcrypt-pbkdf" diff --git a/Cargo.toml b/Cargo.toml index 9aee688..a28dffe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ opt-level = 2 # When you remove the last patch.crates-io entry, please re-enable `minimal-versions` # in `.github/workflows/ssh-key.yml` and `.github/workflows/ssh-cipher.yml` +base64ct = { git = "https://github.com/mpalmer/rust-crypto-formats.git", branch = "b64ct-decode-empty-at-end" } p256 = { git = "https://github.com/RustCrypto/elliptic-curves.git" } p384 = { git = "https://github.com/RustCrypto/elliptic-curves.git" } diff --git a/ssh-key/tests/examples/padless_wonder b/ssh-key/tests/examples/padless_wonder new file mode 100644 index 0000000..c351b4f --- /dev/null +++ b/ssh-key/tests/examples/padless_wonder @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS +1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQRx3l5o/ZI7bNGXguxVI/VmDd/SIwUo +nlZHbHSmwBSeHPT7RisjBbiXnS829RrZ2o+Ix34GFtLN7z+SBHViPRVuAAAAmOCDDMLggw +zCAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHHeXmj9kjts0ZeC +7FUj9WYN39IjBSieVkdsdKbAFJ4c9PtGKyMFuJedLzb1Gtnaj4jHfgYW0s3vP5IEdWI9FW +4AAAAgNEF96jnfIuhkq4ECZqNPe98Fv1SFb5evUQAq3/MtkKEAAAAA +-----END OPENSSH PRIVATE KEY----- diff --git a/ssh-key/tests/private_key.rs b/ssh-key/tests/private_key.rs index 9e43137..ead4d9c 100644 --- a/ssh-key/tests/private_key.rs +++ b/ssh-key/tests/private_key.rs @@ -46,6 +46,10 @@ const OPENSSH_RSA_4096_EXAMPLE: &str = include_str!("examples/id_rsa_4096"); #[cfg(feature = "alloc")] const OPENSSH_OPAQUE_EXAMPLE: &str = include_str!("examples/id_opaque"); +/// OpenSSH-formatted private key with no internal or external padding, and no comment +/// Trips a corner case in base64ct +const OPENSSH_PADLESS_WONDER_EXAMPLE: &str = include_str!("examples/padless_wonder"); + /// Get a path into the `tests/scratch` directory. #[cfg(feature = "std")] pub fn scratch_path(filename: &str) -> PathBuf { @@ -129,6 +133,24 @@ fn decode_ecdsa_p256_openssh() { assert_eq!("user@example.com", key.comment()); } +#[cfg(feature = "ecdsa")] +#[test] +fn decode_padless_wonder_openssh() { + let key = PrivateKey::from_openssh(OPENSSH_PADLESS_WONDER_EXAMPLE).unwrap(); + assert_eq!( + Algorithm::Ecdsa { + curve: EcdsaCurve::NistP256 + }, + key.algorithm(), + ); + assert_eq!(Cipher::None, key.cipher()); + assert_eq!(KdfAlg::None, key.kdf().algorithm()); + assert!(key.kdf().is_none()); + + #[cfg(feature = "alloc")] + assert_eq!("", key.comment()); +} + #[cfg(feature = "ecdsa")] #[test] fn decode_ecdsa_p384_openssh() {