diff --git a/ssh-key/src/private.rs b/ssh-key/src/private.rs index 2fb966a2..13ebfdc8 100644 --- a/ssh-key/src/private.rs +++ b/ssh-key/src/private.rs @@ -161,7 +161,7 @@ use rand_core::TryCryptoRng; use rand_core::CryptoRng; #[cfg(feature = "std")] -use std::{fs, path::Path}; +use std::{fs::File, path::Path}; #[cfg(feature = "std")] use std::io::{self, Read, Write}; @@ -344,24 +344,24 @@ impl PrivateKey { SshSig::sign(self, namespace, hash_alg, msg) } - /// Read private key from an OpenSSH-formatted PEM file. + /// Read private key from an OpenSSH-formatted PEM source. #[cfg(feature = "std")] - pub fn read_openssh(reader: &mut R) -> Result { + pub fn read_openssh(reader: &mut impl Read) -> Result { let pem = Zeroizing::new(io::read_to_string(reader)?); Self::from_openssh(&*pem) } /// Read private key from an OpenSSH-formatted PEM file. #[cfg(feature = "std")] - pub fn read_openssh_file>(path: P) -> Result { + pub fn read_openssh_file(path: impl AsRef) -> Result { // TODO(tarcieri): verify file permissions match `UNIX_FILE_PERMISSIONS` - let pem = Zeroizing::new(fs::read_to_string(path)?); - Self::from_openssh(&*pem) + let mut file = File::open(path)?; + Self::read_openssh(&mut file) } /// Write private key as an OpenSSH-formatted PEM file. #[cfg(feature = "std")] - pub fn write_openssh(&self, writer: &mut W, line_ending: LineEnding) -> Result<()> { + pub fn write_openssh(&self, writer: &mut impl Write, line_ending: LineEnding) -> Result<()> { let pem = self.to_openssh(line_ending)?; writer.write_all(pem.as_bytes())?; Ok(()) @@ -369,25 +369,19 @@ impl PrivateKey { /// Write private key as an OpenSSH-formatted PEM file. #[cfg(feature = "std")] - pub fn write_openssh_file>( + pub fn write_openssh_file( &self, - path: P, + path: impl AsRef, line_ending: LineEnding, ) -> Result<()> { - let pem = self.to_openssh(line_ending)?; + let mut options = File::options(); - #[cfg(not(unix))] - fs::write(path, pem.as_bytes())?; #[cfg(unix)] - fs::OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .mode(UNIX_FILE_PERMISSIONS) - .open(path) - .and_then(|mut file| file.write_all(pem.as_bytes()))?; + options.mode(UNIX_FILE_PERMISSIONS); - Ok(()) + let mut file = options.write(true).create(true).truncate(true).open(path)?; + + self.write_openssh(&mut file, line_ending) } /// Attempt to decrypt an encrypted private key using the provided diff --git a/ssh-key/src/public.rs b/ssh-key/src/public.rs index 8af64f6f..9088ec5b 100644 --- a/ssh-key/src/public.rs +++ b/ssh-key/src/public.rs @@ -48,7 +48,7 @@ use { use serde::{Deserialize, Serialize, de, ser}; #[cfg(feature = "std")] -use std::{fs, path::Path}; +use std::{fs::File, path::Path}; #[cfg(feature = "std")] use std::io::{self, Read, Write}; @@ -243,23 +243,23 @@ impl PublicKey { signature.verify(msg) } - /// Read public key from an OpenSSH-formatted file. + /// Read public key from an OpenSSH-formatted source. #[cfg(feature = "std")] - pub fn read_openssh(reader: &mut R) -> Result { + pub fn read_openssh(reader: &mut impl Read) -> Result { let input = io::read_to_string(reader)?; Self::from_openssh(&input) } /// Read public key from an OpenSSH-formatted file. #[cfg(feature = "std")] - pub fn read_openssh_file>(path: P) -> Result { - let input = fs::read_to_string(path)?; - Self::from_openssh(&input) + pub fn read_openssh_file(path: impl AsRef) -> Result { + let mut file = File::open(path)?; + Self::read_openssh(&mut file) } /// Write public key as an OpenSSH-formatted file. #[cfg(feature = "std")] - pub fn write_openssh(&self, writer: &mut W) -> Result<()> { + pub fn write_openssh(&self, writer: &mut impl Write) -> Result<()> { let mut encoded = self.to_openssh()?; encoded.push('\n'); // TODO(tarcieri): OS-specific line endings? @@ -269,12 +269,9 @@ impl PublicKey { /// Write public key as an OpenSSH-formatted file. #[cfg(feature = "std")] - pub fn write_openssh_file>(&self, path: P) -> Result<()> { - let mut encoded = self.to_openssh()?; - encoded.push('\n'); // TODO(tarcieri): OS-specific line endings? - - fs::write(path, encoded.as_bytes())?; - Ok(()) + pub fn write_openssh_file(&self, path: impl AsRef) -> Result<()> { + let mut file = File::create(path)?; + self.write_openssh(&mut file) } /// Get the digital signature [`Algorithm`] used by this key.