-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Bug Report
Version
│ │ │ │ └── tonic v0.5.2
│ │ │ ├── tonic v0.5.2 (*)
│ │ │ └── tonic-build v0.5.2
│ │ ├── tonic v0.5.2 (*)
Platform
Linux 3.10.0-1160.36.2.el7.x86_64 #1 SMP Wed Jul 21 11:57:15 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Crates
tonic
, with feature tls
enabled.
Description
I tried this code:
Generally, I have wrote a client looks like this:
Usage: tls-test [OPTIONS] --ca-path <CA_PATH> --cert-path <CERT_PATH> --key-path <KEY_PATH>
Options:
-e, --endpoints <ENDPOINTS>
--ca-path <CA_PATH>
--cert-path <CERT_PATH>
--key-path <KEY_PATH>
-h, --help Print help information
Which fills the tls config like:
pub fn tonic_tls_config(&self) -> Option<ClientTlsConfig> {
// This function loads the content from files at `{ca,cert,key}_path`.
let (ca, cert, key) = self.cfg.load_certs().unwrap_or_default();
if ca.is_empty() && cert.is_empty() && key.is_empty() {
return None;
}
let mut cfg = ClientTlsConfig::new();
if !ca.is_empty() {
cfg = cfg.ca_certificate(Certificate::from_pem(ca));
}
if !cert.is_empty() && !key.is_empty() {
cfg = cfg.identity(Identity::from_pem(cert, key));
}
Some(cfg)
}
With a client key file generated by:
openssl ecparam -out "$TEST_DIR/certs/$cluster.key" -name prime256v1 -genkey
I expected to see this happen:
We should be able to connect to the server via the key, or return some error like DNSNameError
which hints the key is invalid.
Instead, this happened:
It returns a error like:
tonic::transport::Error(Transport, PrivateKeyParseError)
Some notes:
By reading the code, I have noticed that we are going to extract key via applying pkcs8_private_keys
and rsa_private_keys
. It seems rustls-pemfile
supports SEC1 EC
keys however doesn't provide something like ec_private_keys
(!).
Perhaps we can use read_once
direcly, so we only need to iterate the key file once and can extract the EC keys:
fn load_rustls_private_key(
mut cursor: std::io::Cursor<&[u8]>,
) -> Result<PrivateKey, crate::Error> {
while let Ok(Some(item)) = rustls_pemfile::read_one(&mut cursor) {
match item {
rustls_pemfile::Item::RSAKey(key)
| rustls_pemfile::Item::PKCS8Key(key)
| rustls_pemfile::Item::ECKey(key) => return Ok(PrivateKey(key)),
_ => continue,
}
}
// Otherwise we have a Private Key parsing problem
Err(Box::new(TlsError::PrivateKeyParseError))
}
-->