Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for EC private keys #804

Merged
merged 4 commits into from Feb 19, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions kube-client/Cargo.toml
Expand Up @@ -52,8 +52,8 @@ futures = { version = "0.3.17", optional = true }
pem = { version = "1.0.1", optional = true }
openssl = { version = "0.10.36", optional = true }
tokio-native-tls = { version = "0.3.0", optional = true }
rustls = { version = "0.20.1", features = ["dangerous_configuration"], optional = true }
rustls-pemfile = { version = "0.2.1", optional = true }
rustls = { version = "0.20.3", features = ["dangerous_configuration"], optional = true }
rustls-pemfile = { version = "0.3.0", optional = true }
bytes = { version = "1.1.0", optional = true }
tokio = { version = "1.14.0", features = ["time", "signal", "sync"], optional = true }
kube-core = { path = "../kube-core", version = "^0.69.0"}
Expand Down
12 changes: 8 additions & 4 deletions kube-client/src/client/tls.rs
Expand Up @@ -107,6 +107,10 @@ pub mod rustls_tls {
#[error("invalid private key: {0}")]
InvalidPrivateKey(#[source] rustls::Error),

/// Unknown private key format
#[error("unknown private key format")]
UnknownPrivateKeyFormat,

// Using type-erased error to avoid depending on webpki
/// Failed to add a root certificate
#[error("failed to add a root certificate: {0}")]
Expand Down Expand Up @@ -153,25 +157,25 @@ pub mod rustls_tls {
Ok(root_store)
}

// TODO Support EC Private Key to support k3d. Need to convert to PKCS#8 or RSA (PKCS#1).
// `openssl pkcs8 -topk8 -nocrypt -in ec.pem -out pkcs8.pem`
// https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations#EC_Private_Key_File_Formats
fn client_auth(data: &[u8]) -> Result<(Vec<Certificate>, PrivateKey), Error> {
use rustls_pemfile::Item;

let mut cert_chain = Vec::new();
let mut pkcs8_key = None;
let mut rsa_key = None;
let mut ec_key = None;
let mut reader = std::io::Cursor::new(data);
for item in rustls_pemfile::read_all(&mut reader).map_err(Error::InvalidIdentityPem)? {
match item {
Item::X509Certificate(cert) => cert_chain.push(Certificate(cert)),
Item::PKCS8Key(key) => pkcs8_key = Some(PrivateKey(key)),
Item::RSAKey(key) => rsa_key = Some(PrivateKey(key)),
Item::ECKey(key) => ec_key = Some(PrivateKey(key)),
_ => return Err(Error::UnknownPrivateKeyFormat),
}
}

let private_key = pkcs8_key.or(rsa_key).ok_or(Error::MissingPrivateKey)?;
let private_key = pkcs8_key.or(rsa_key).or(ec_key).ok_or(Error::MissingPrivateKey)?;
if cert_chain.is_empty() {
return Err(Error::MissingCertificate);
}
Expand Down