Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 14 additions & 20 deletions ssh-key/src/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -344,50 +344,44 @@ 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<R: Read>(reader: &mut R) -> Result<Self> {
pub fn read_openssh(reader: &mut impl Read) -> Result<Self> {
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<P: AsRef<Path>>(path: P) -> Result<Self> {
pub fn read_openssh_file(path: impl AsRef<Path>) -> Result<Self> {
// 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<W: Write>(&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(())
}

/// Write private key as an OpenSSH-formatted PEM file.
#[cfg(feature = "std")]
pub fn write_openssh_file<P: AsRef<Path>>(
pub fn write_openssh_file(
&self,
path: P,
path: impl AsRef<Path>,
line_ending: LineEnding,
) -> Result<()> {
let pem = self.to_openssh(line_ending)?;
let mut options = File::options();
Comment thread
tarcieri marked this conversation as resolved.

#[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
Expand Down
23 changes: 10 additions & 13 deletions ssh-key/src/public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<R: Read>(reader: &mut R) -> Result<Self> {
pub fn read_openssh(reader: &mut impl Read) -> Result<Self> {
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<P: AsRef<Path>>(path: P) -> Result<Self> {
let input = fs::read_to_string(path)?;
Self::from_openssh(&input)
pub fn read_openssh_file(path: impl AsRef<Path>) -> Result<Self> {
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<W: Write>(&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?

Expand All @@ -269,12 +269,9 @@ impl PublicKey {

/// Write public key as an OpenSSH-formatted file.
#[cfg(feature = "std")]
pub fn write_openssh_file<P: AsRef<Path>>(&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<Path>) -> Result<()> {
let mut file = File::create(path)?;
self.write_openssh(&mut file)
}

/// Get the digital signature [`Algorithm`] used by this key.
Expand Down