Skip to content

Commit

Permalink
Add encrypted private key support
Browse files Browse the repository at this point in the history
  • Loading branch information
obelisk committed Aug 9, 2021
1 parent 448d6e7 commit f288675
Show file tree
Hide file tree
Showing 7 changed files with 443 additions and 42 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Build
run: cargo build --features="yubikey" --examples --verbose
- name: Run tests
run: cargo test --verbose
run: cargo test --features="encrypted-keys" --verbose

ubuntu-build-test-no-yubikey:
runs-on: ubuntu-latest
Expand All @@ -28,4 +28,4 @@ jobs:
- name: Build
run: cargo build --examples --verbose
- name: Run tests
run: cargo test --verbose
run: cargo test --features="encrypted-keys" --verbose
109 changes: 102 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 17 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sshcerts"
version = "0.5.0"
version = "0.6.0"
authors = ["Mitchell Grenier <[email protected]>"]
edition = "2018"
license-file = "LICENSE"
Expand All @@ -13,10 +13,11 @@ categories = ["authentication"]
[features]
default = ["rsa-signing"]

all = ["yubikey", "rsa-signing"]
all = ["encrypted-keys", "rsa-signing", "yubikey"]

yubikey = ["yubikey-piv", "log"]
rsa-signing = ["simple_asn1", "num-bigint"]
encrypted-keys = ["aes", "bcrypt-pbkdf", "ctr"]

[dependencies]
base64 = "0.13"
Expand All @@ -31,6 +32,11 @@ log = {version = "0.4", optional = true}
yubikey-piv = {version = "0.1.0", features = ["untested"], optional = true}
lexical-core = {version = ">0.7.4", optional = true}

# Dependencies for encrypted keys
aes = {version = "0.7", features = ["ctr"], optional = true}
bcrypt-pbkdf = {version = "0.6", optional = true}
ctr = {version = "0.8", optional = true}

[dev-dependencies]
env_logger = "0.8.2"
hex = "0.4.2"
Expand All @@ -49,3 +55,12 @@ required-features = ["yubikey"]
[[example]]
name = "yk-provision"
required-features = ["yubikey"]

[[example]]
name = "ssh-pkey-info"
required-features = ["encrypted-keys"]

[[test]]
name = "privkey-encrypted"
path = "tests/privkey_encrypted.rs"
required-features = ["encrypted-keys"]
35 changes: 35 additions & 0 deletions examples/ssh-pkey-info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::env;

use sshcerts::ssh::PrivateKey;

fn help() {
println!("An SSH Private Key reader based on the sshcerts library");
println!("Usage: ssh-pkey-info <path to file>");
}

fn main() -> Result<(), String> {
let args: Vec<String> = env::args().collect();

if args.len() < 2 {
help();
return Ok(());
}

let path = &args[1];

let passphrase = if args.len() == 3 {
Some(args[2].clone())
} else {
None
};

match PrivateKey::from_path_with_passphrase(path, passphrase) {
Ok(c) => {
println!("{:#}", c);
Ok(())
},
Err(e) => {
Err(format!("{}: Private key at {} not valid", e, &args[1]))
}
}
}
7 changes: 5 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ pub enum Error {
CertificateInvalidSignature,
/// A cryptographic operation failed.
SigningError,
/// An encrypted private key was supplied and is not supported
/// An encrypted private key was provided with no decryption key
EncryptedPrivateKey,
/// An encrypted private key was supplied but the encryption method is not supported
EncryptedPrivateKeyNotSupported,
/// The key type is unknown
UnknownKeyType(String),
Expand All @@ -47,7 +49,8 @@ impl fmt::Display for Error {
Error::KeyTypeMismatch => write!(f, "Key type mismatch"),
Error::CertificateInvalidSignature => write!(f, "Certificate is improperly signed"),
Error::SigningError => write!(f, "Could not sign data"),
Error::EncryptedPrivateKeyNotSupported => write!(f, "Encrypted private keys are not supported"),
Error::EncryptedPrivateKey => write!(f, "Encountered encrypted private key with no decryption key"),
Error::EncryptedPrivateKeyNotSupported => write!(f, "This method of private key encryption is not supported or sshcerts was not compiled with encrypted private key support"),
Error::UnknownKeyType(ref v) => write!(f, "Unknown key type {}", v),
Error::UnknownCurve(ref v) => write!(f, "Unknown curve {}", v),
#[cfg(feature = "yubikey")]
Expand Down
Loading

0 comments on commit f288675

Please sign in to comment.