summaryrefslogtreecommitdiff
path: root/src/sshkeys.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-03-07 17:07:20 +0200
committerLars Wirzenius <liw@liw.fi>2021-03-07 17:07:20 +0200
commit1e8ba95def26de67f8fd618549d6b8f80a14ddd8 (patch)
treedc4916152d7c1f488174a7297863e89bad8daa03 /src/sshkeys.rs
parent54f0cba69a023ccf0b781dd76a2b370bf6400585 (diff)
downloadvmadm-1e8ba95def26de67f8fd618549d6b8f80a14ddd8.tar.gz
doc: add doc comments to crate
Diffstat (limited to 'src/sshkeys.rs')
-rw-r--r--src/sshkeys.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/sshkeys.rs b/src/sshkeys.rs
index 207f6fe..813a26d 100644
--- a/src/sshkeys.rs
+++ b/src/sshkeys.rs
@@ -1,3 +1,5 @@
+//! Generate SSH host keys and certificates.
+
use std::fs::{read, File, Permissions};
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
@@ -5,31 +7,49 @@ use std::path::Path;
use std::process::Command;
use tempfile::tempdir;
+/// Errors from this module.
#[derive(Debug, thiserror::Error)]
pub enum KeyError {
+ /// Could not generate a new key pair.
#[error("ssh-keygen failed to generate a key: {0}")]
KeyGen(String),
+ /// Error creating a certificate.
#[error("ssh-keygen failed to certify a key: {0}")]
CertError(String),
+ /// I/O error.
#[error(transparent)]
IoError(#[from] std::io::Error),
+ /// Error parsing a string as UTF8.
#[error(transparent)]
Utf8Error(#[from] std::string::FromUtf8Error),
}
+/// Type of SSH key.
pub enum KeyKind {
+ /// RSA key of desired length in bits.
RSA(u32),
+
+ /// DSA of fixed length.
DSA,
+
+ /// ECDSA key of 256 bits.
ECDSA256,
+
+ /// ECDSA key of 384 bits.
ECDSA384,
+
+ /// ECDSA key of 521 bits.
ECDSA521,
+
+ /// Ed25519 key of fixed length.
Ed25519,
}
impl KeyKind {
+ /// Type of key as string for ssh-keygen -t option.
pub fn as_str(&self) -> &str {
match self {
Self::RSA(_) => "rsa",
@@ -41,6 +61,9 @@ impl KeyKind {
}
}
+ /// Number of bits needed for the key.
+ ///
+ /// This is only really meaningful for RSA keys.
pub fn bits(&self) -> u32 {
match self {
Self::RSA(bits) => *bits,
@@ -53,12 +76,14 @@ impl KeyKind {
}
}
+/// A public/private key pair.
pub struct KeyPair {
public: String,
private: String,
}
impl KeyPair {
+ /// Create pair from string representation.
pub fn from_str(public: String, private: String) -> Self {
Self {
private: private,
@@ -66,6 +91,7 @@ impl KeyPair {
}
}
+ /// Generate a new key pair of the desired kind.
pub fn generate(kind: KeyKind) -> Result<Self, KeyError> {
let dirname = tempdir()?;
let private_key = dirname.path().join("key");
@@ -93,9 +119,12 @@ impl KeyPair {
))
}
+ /// Public key of the pair, as a string.
pub fn public(&self) -> &str {
&self.public
}
+
+ /// Private key of the pair, as a string.
pub fn private(&self) -> &str {
&self.private
}
@@ -106,22 +135,30 @@ fn read_string(filename: &Path) -> Result<String, KeyError> {
Ok(String::from_utf8(bytes)?)
}
+/// A key for SSH certificate authority.
+///
+/// This is used for creating host certificates.
pub struct CaKey {
private: String,
}
impl CaKey {
+ /// Create new CA key from a key pair.
pub fn from(pair: KeyPair) -> Self {
Self {
private: pair.private().to_string(),
}
}
+ /// Read CA key from a file.
pub fn from_file(filename: &Path) -> Result<Self, KeyError> {
let private = read_string(filename)?;
Ok(Self { private })
}
+ /// Create a host certificate.
+ ///
+ /// Return as a string.
pub fn certify_host(&self, host_key: &KeyPair, hostname: &str) -> Result<String, KeyError> {
let dirname = tempdir()?;
let ca_key = dirname.path().join("ca");