Support TLS keys in SEC1 format.

This commit is contained in:
Sergio Benitez 2023-03-23 14:18:22 -07:00
parent daa157f872
commit 0a0f540988
8 changed files with 52 additions and 18 deletions

View File

@ -32,7 +32,7 @@ time = { version = "0.3", features = ["formatting", "macros"] }
indexmap = { version = "1.5.2", features = ["std"] } indexmap = { version = "1.5.2", features = ["std"] }
rustls = { version = "0.20", optional = true } rustls = { version = "0.20", optional = true }
tokio-rustls = { version = "0.23.4", optional = true } tokio-rustls = { version = "0.23.4", optional = true }
rustls-pemfile = { version = "1", optional = true } rustls-pemfile = { version = "1.0.2", optional = true }
tokio = { version = "1.6.1", features = ["net", "sync", "time"] } tokio = { version = "1.6.1", features = ["net", "sync", "time"] }
log = "0.4" log = "0.4"
ref-cast = "1.0" ref-cast = "1.0"

View File

@ -20,12 +20,13 @@ pub fn load_private_key(reader: &mut dyn io::BufRead) -> io::Result<PrivateKey>
let private_keys_fn = loop { let private_keys_fn = loop {
header.clear(); header.clear();
if reader.read_line(&mut header)? == 0 { if reader.read_line(&mut header)? == 0 {
return Err(err("failed to find key header; supported formats are: RSA, PKCS8")); return Err(err("failed to find key header; supported formats are: RSA, PKCS8, SEC1"));
} }
break match header.trim_end() { break match header.trim_end() {
"-----BEGIN RSA PRIVATE KEY-----" => rustls_pemfile::rsa_private_keys, "-----BEGIN RSA PRIVATE KEY-----" => rustls_pemfile::rsa_private_keys,
"-----BEGIN PRIVATE KEY-----" => rustls_pemfile::pkcs8_private_keys, "-----BEGIN PRIVATE KEY-----" => rustls_pemfile::pkcs8_private_keys,
"-----BEGIN EC PRIVATE KEY-----" => rustls_pemfile::ec_private_keys,
_ => continue, _ => continue,
}; };
}; };

View File

@ -10,9 +10,10 @@ use indexmap::IndexSet;
/// ///
/// Both `certs` and `key` can be configured as a path or as raw bytes. /// Both `certs` and `key` can be configured as a path or as raw bytes.
/// `certs` must be a DER-encoded X.509 TLS certificate chain, while `key` /// `certs` must be a DER-encoded X.509 TLS certificate chain, while `key`
/// must be a DER-encoded ASN.1 key in either PKCS#8 or PKCS#1 format. /// must be a DER-encoded ASN.1 key in either PKCS#8, PKCS#1, or SEC1
/// When a path is configured in a file, such as `Rocket.toml`, relative /// format. When a path is configured in a file, such as `Rocket.toml`,
/// paths are interpreted as relative to the source file's directory. /// relative paths are interpreted as relative to the source file's
/// directory.
/// ///
/// * `ciphers` /// * `ciphers`
/// ///

View File

@ -17,14 +17,22 @@ mandatory = false
certs = "private/rsa_sha256_cert.pem" certs = "private/rsa_sha256_cert.pem"
key = "private/rsa_sha256_key.pem" key = "private/rsa_sha256_key.pem"
[ecdsa_nistp256_sha256.tls] [ecdsa_nistp256_sha256_pkcs8.tls]
certs = "private/ecdsa_nistp256_sha256_cert.pem" certs = "private/ecdsa_nistp256_sha256_cert.pem"
key = "private/ecdsa_nistp256_sha256_key_pkcs8.pem" key = "private/ecdsa_nistp256_sha256_key_pkcs8.pem"
[ecdsa_nistp384_sha384.tls] [ecdsa_nistp384_sha384_pkcs8.tls]
certs = "private/ecdsa_nistp384_sha384_cert.pem" certs = "private/ecdsa_nistp384_sha384_cert.pem"
key = "private/ecdsa_nistp384_sha384_key_pkcs8.pem" key = "private/ecdsa_nistp384_sha384_key_pkcs8.pem"
[ecdsa_nistp256_sha256_sec1.tls]
certs = "private/ecdsa_nistp256_sha256_cert.pem"
key = "private/ecdsa_nistp256_sha256_key_sec1.pem"
[ecdsa_nistp384_sha384_sec1.tls]
certs = "private/ecdsa_nistp384_sha384_cert.pem"
key = "private/ecdsa_nistp384_sha384_key_sec1.pem"
[ed25519.tls] [ed25519.tls]
certs = "private/ed25519_cert.pem" certs = "private/ed25519_cert.pem"
key = "private/ed25519_key.pem" key = "private/ed25519_key.pem"

View File

@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIM+futAjM1Au19lOdEvCiA2EOjB1LcDE7B3FK2w4S3y2oAoGCCqGSM49
AwEHoUQDQgAEO0C+sMAtX9ka6tIl2hEUO8Hars+x2NZa/MVa9Ciu1TOZZe4U7jtA
ny+WqW4O1AoruAeY2bXQysOTajSKkySvNA==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,6 @@
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDClF5pKlKs9J5iaOAJEHe7v7RfcSt14yMjrp6y1jntK9j9jzTXAGtHC
yWwdW0GYTVmgBwYFK4EEACKhZANiAATZKfDYqkqFHPG8CatHyERcr3QzdI1E+PvT
HaCfwicih43lVQXDFlwSWyk5qKxW5CelnFGwVN9CtPik76l/bRS1zpqcFGQ8qppH
lO/FVewyawyksuR4Mc+YVyd9PZc/iq8=
-----END EC PRIVATE KEY-----

View File

@ -2,7 +2,20 @@ use rocket::local::blocking::Client;
#[test] #[test]
fn hello_world() { fn hello_world() {
let client = Client::tracked(super::rocket()).unwrap(); let profiles = [
"rsa_sha256",
"ecdsa_nistp256_sha256_pkcs8",
"ecdsa_nistp384_sha384_pkcs8",
"ecdsa_nistp256_sha256_sec1",
"ecdsa_nistp384_sha384_sec1",
"ed25519",
];
// TODO: Testing doesn't actually read keys since we don't do TLS locally.
for profile in profiles {
let config = rocket::Config::figment().select(profile);
let client = Client::tracked(super::rocket().configure(config)).unwrap();
let response = client.get("/").dispatch(); let response = client.get("/").dispatch();
assert_eq!(response.into_string(), Some("Hello, world!".into())); assert_eq!(response.into_string(), Some("Hello, world!".into()));
} }
}

View File

@ -246,7 +246,7 @@ Security). To enable TLS support:
```toml,ignore ```toml,ignore
[default.tls] [default.tls]
key = "path/to/key.pem" # Path or bytes to DER-encoded ASN.1 PKCS#1/#8 key. key = "path/to/key.pem" # Path or bytes to DER-encoded ASN.1 PKCS#1/#8 or SEC1 key.
certs = "path/to/certs.pem" # Path or bytes to DER-encoded X.509 TLS cert chain. certs = "path/to/certs.pem" # Path or bytes to DER-encoded X.509 TLS cert chain.
``` ```
@ -254,8 +254,8 @@ The `tls` parameter is expected to be a dictionary that deserializes into a
[`TlsConfig`] structure: [`TlsConfig`] structure:
| key | required | type | | key | required | type |
|------------------------------|-----------|-------------------------------------------------------| |------------------------------|-----------|---------------------------------------------------------------|
| `key` | **_yes_** | Path or bytes to DER-encoded ASN.1 PKCS#1/#8 key. | | `key` | **_yes_** | Path or bytes to DER-encoded ASN.1 PKCS#1/#8 or SEC1 key. |
| `certs` | **_yes_** | Path or bytes to DER-encoded X.509 TLS cert chain. | | `certs` | **_yes_** | Path or bytes to DER-encoded X.509 TLS cert chain. |
| `ciphers` | no | Array of [`CipherSuite`]s to enable. | | `ciphers` | no | Array of [`CipherSuite`]s to enable. |
| `prefer_server_cipher_order` | no | Boolean for whether to [prefer server cipher suites]. | | `prefer_server_cipher_order` | no | Boolean for whether to [prefer server cipher suites]. |