diff --git a/Cargo.toml b/Cargo.toml index 6e3d9e205..55171c038 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,7 +118,7 @@ rustls = { version = "0.20", features = ["dangerous_configuration"], optional = tokio-rustls = { version = "0.23", optional = true } webpki-roots = { version = "0.22", optional = true } rustls-native-certs = { version = "0.6", optional = true } -rustls-pemfile = { version = "0.3", optional = true } +rustls-pemfile = { version = "1.0", optional = true } ## cookies cookie_crate = { version = "0.16", package = "cookie", optional = true } diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 16fe87b06..348c8e163 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work. same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright [yyyy] [name of copyright owner] +Copyright 2016 Sean McArthur Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/tls.rs b/src/tls.rs index ce921f668..052fb76b4 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -184,7 +184,7 @@ impl Identity { /// The input should contain a PEM encoded private key /// and at least one PEM encoded certificate. /// - /// Note: The private key must be in RSA or PKCS#8 format. + /// Note: The private key must be in RSA, SEC1 Elliptic Curve or PKCS#8 format. /// /// # Examples /// @@ -210,33 +210,29 @@ impl Identity { let (key, certs) = { let mut pem = Cursor::new(buf); - let certs = rustls_pemfile::certs(&mut pem) - .map_err(|_| TLSError::General(String::from("No valid certificate was found"))) - .map_err(crate::error::builder)? - .into_iter() - .map(rustls::Certificate) - .collect::>(); - pem.set_position(0); - let mut sk = rustls_pemfile::pkcs8_private_keys(&mut pem) - .and_then(|pkcs8_keys| { - if pkcs8_keys.is_empty() { - Err(std::io::Error::new( - std::io::ErrorKind::NotFound, - "No valid private key was found", - )) - } else { - Ok(pkcs8_keys) + let mut sk = Vec::::new(); + let mut certs = Vec::::new(); + + for item in std::iter::from_fn(|| rustls_pemfile::read_one(&mut pem).transpose()) { + match item.map_err(|_| { + crate::error::builder(TLSError::General(String::from( + "Invalid identity PEM file", + ))) + })? { + rustls_pemfile::Item::X509Certificate(cert) => { + certs.push(rustls::Certificate(cert)) + } + rustls_pemfile::Item::PKCS8Key(key) => sk.push(rustls::PrivateKey(key)), + rustls_pemfile::Item::RSAKey(key) => sk.push(rustls::PrivateKey(key)), + rustls_pemfile::Item::ECKey(key) => sk.push(rustls::PrivateKey(key)), + _ => { + return Err(crate::error::builder(TLSError::General(String::from( + "No valid certificate was found", + )))) } - }) - .or_else(|_| { - pem.set_position(0); - rustls_pemfile::rsa_private_keys(&mut pem) - }) - .map_err(|_| TLSError::General(String::from("No valid private key was found"))) - .map_err(crate::error::builder)? - .into_iter() - .map(rustls::PrivateKey) - .collect::>(); + } + } + if let (Some(sk), false) = (sk.pop(), certs.is_empty()) { (sk, certs) } else {