Merge pull request #173 from djc/rustls-0.20

Upgrade rustls and related dependencies
This commit is contained in:
Lewin Bormann
2022-04-18 18:44:18 -07:00
committed by GitHub
5 changed files with 63 additions and 20 deletions

View File

@@ -28,7 +28,7 @@ required-features = ["hyper-rustls", "service_account"]
[features]
default = ["hyper-rustls", "service_account"]
service_account = ["rustls"]
service_account = ["hyper-rustls", "rustls", "rustls-pemfile"]
[dependencies]
anyhow = "1.0.38"
@@ -37,12 +37,13 @@ base64 = "0.13.0"
futures = "0.3"
http = "0.2"
hyper = { version = "0.14", features = ["client", "server", "tcp", "http2"] }
hyper-rustls = { version = "0.22.1", optional = true }
hyper-rustls = { version = "0.23", optional = true, features = ["http2"] }
hyper-tls = { version = "0.5.0", optional = true }
itertools = "0.10.0"
log = "0.4"
percent-encoding = "2"
rustls = { version = "0.19", optional = true }
rustls = { version = "0.20.4", optional = true }
rustls-pemfile = { version = "0.3", optional = true }
seahash = "4"
serde = {version = "1.0", features = ["derive"]}
serde_json = "1.0"
@@ -55,7 +56,7 @@ httptest = "0.14"
env_logger = "0.7"
tempfile = "3.1"
webbrowser = "0.5"
hyper-rustls = "0.22.1"
hyper-rustls = "0.23"
[workspace]
members = ["examples/test-installed/", "examples/test-svc-acct/", "examples/test-device/", "examples/service_account", "examples/drive_example", "examples/test-adc"]

View File

@@ -31,7 +31,14 @@ async fn main() {
let secret = yup_oauth2::read_service_account_key(google_credentials)
.await
.expect("$GOOGLE_APPLICATION_CREDENTIALS is not a valid service account key");
let client = hyper::Client::builder().build(hyper_rustls::HttpsConnector::with_native_roots());
let client = hyper::Client::builder().build(
hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_only()
.enable_http1()
.enable_http2()
.build(),
);
let authenticator =
yup_oauth2::ServiceAccountAuthenticator::with_client(secret, client.clone())
.build()

View File

@@ -334,14 +334,14 @@ impl ApplicationDefaultCredentialsAuthenticator {
pub async fn builder(
opts: ApplicationDefaultCredentialsFlowOpts,
) -> ApplicationDefaultCredentialsTypes<DefaultHyperClient> {
Self::with_client(DefaultHyperClient, opts).await
Self::with_client(opts, DefaultHyperClient).await
}
/// Use the builder pattern to deduce which model of authenticator should be used and allow providing a hyper client
#[cfg(feature = "service_account")]
pub async fn with_client<C>(
client: C,
opts: ApplicationDefaultCredentialsFlowOpts,
client: C,
) -> ApplicationDefaultCredentialsTypes<C>
where
C: HyperClientBuilder,
@@ -736,6 +736,10 @@ pub trait HyperClientBuilder {
/// Create a hyper::Client
fn build_hyper_client(self) -> hyper::Client<Self::Connector>;
/// Create a `hyper::Client` for tests (HTTPS not required)
#[doc(hidden)]
fn build_test_hyper_client(self) -> hyper::Client<Self::Connector>;
}
#[cfg(feature = "hyper-rustls")]
@@ -777,7 +781,28 @@ impl HyperClientBuilder for DefaultHyperClient {
fn build_hyper_client(self) -> hyper::Client<Self::Connector> {
#[cfg(feature = "hyper-rustls")]
let connector = hyper_rustls::HttpsConnector::with_native_roots();
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_only()
.enable_http1()
.enable_http2()
.build();
#[cfg(all(not(feature = "hyper-rustls"), feature = "hyper-tls"))]
let connector = hyper_tls::HttpsConnector::new();
hyper::Client::builder()
.pool_max_idle_per_host(0)
.build::<_, hyper::Body>(connector)
}
fn build_test_hyper_client(self) -> hyper::Client<Self::Connector> {
#[cfg(feature = "hyper-rustls")]
let connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_or_http()
.enable_http1()
.enable_http2()
.build();
#[cfg(all(not(feature = "hyper-rustls"), feature = "hyper-tls"))]
let connector = hyper_tls::HttpsConnector::new();
@@ -796,6 +821,10 @@ where
fn build_hyper_client(self) -> hyper::Client<C> {
self
}
fn build_test_hyper_client(self) -> hyper::Client<Self::Connector> {
self
}
}
/// How should the acquired tokens be stored?

View File

@@ -21,7 +21,6 @@ use std::io;
use hyper::header;
use rustls::{
self,
internal::pemfile,
sign::{self, SigningKey},
PrivateKey,
};
@@ -39,12 +38,12 @@ fn append_base64<T: AsRef<[u8]> + ?Sized>(s: &T, out: &mut String) {
/// Decode a PKCS8 formatted RSA key.
fn decode_rsa_key(pem_pkcs8: &str) -> Result<PrivateKey, io::Error> {
let private_keys = pemfile::pkcs8_private_keys(&mut pem_pkcs8.as_bytes());
let private_keys = rustls_pemfile::pkcs8_private_keys(&mut pem_pkcs8.as_bytes());
match private_keys {
Ok(mut keys) if !keys.is_empty() => {
keys.truncate(1);
Ok(keys.remove(0))
Ok(rustls::PrivateKey(keys.remove(0)))
}
Ok(_) => Err(io::Error::new(
io::ErrorKind::InvalidInput,
@@ -129,7 +128,7 @@ pub(crate) struct JWTSigner {
impl JWTSigner {
fn new(private_key: &str) -> Result<Self, io::Error> {
let key = decode_rsa_key(private_key)?;
let signing_key = sign::RSASigningKey::new(&key)
let signing_key = sign::RsaSigningKey::new(&key)
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Couldn't initialize signer"))?;
let signer = signing_key
.choose_scheme(&[rustls::SignatureScheme::RSA_PKCS1_SHA256])
@@ -139,7 +138,7 @@ impl JWTSigner {
Ok(JWTSigner { signer })
}
fn sign_claims(&self, claims: &Claims) -> Result<String, rustls::TLSError> {
fn sign_claims(&self, claims: &Claims) -> Result<String, rustls::Error> {
let mut jwt_head = Self::encode_claims(claims);
let signature = self.signer.sign(jwt_head.as_bytes())?;
jwt_head.push('.');
@@ -228,8 +227,14 @@ mod tests {
.await
.unwrap();
let acc = ServiceAccountFlow::new(ServiceAccountFlowOpts { key, subject: None }).unwrap();
let client =
hyper::Client::builder().build(hyper_rustls::HttpsConnector::with_native_roots());
let client = hyper::Client::builder().build(
hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_only()
.enable_http1()
.enable_http2()
.build(),
);
println!(
"{:?}",
acc.token(&client, &["https://www.googleapis.com/auth/pubsub"])

View File

@@ -44,7 +44,7 @@ async fn create_device_flow_auth(server: &Server) -> DefaultAuthenticator {
}
}
DeviceFlowAuthenticator::builder(app_secret)
DeviceFlowAuthenticator::with_client(app_secret, DefaultHyperClient.build_test_hyper_client())
.flow_delegate(Box::new(FD))
.device_code_url(server.url_str("/code"))
.build()
@@ -215,8 +215,9 @@ async fn create_installed_flow_auth(
}
}
let mut builder = InstalledFlowAuthenticator::builder(app_secret, method)
.flow_delegate(Box::new(FD(DefaultHyperClient.build_hyper_client())));
let client = DefaultHyperClient.build_test_hyper_client();
let mut builder = InstalledFlowAuthenticator::with_client(app_secret, method, client.clone())
.flow_delegate(Box::new(FD(client)));
builder = if let Some(filename) = filename {
builder.persist_tokens_to_disk(filename)
@@ -326,7 +327,7 @@ async fn create_service_account_auth(server: &Server) -> DefaultAuthenticator {
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/yup-test-sa-1%40yup-test-243420.iam.gserviceaccount.com"
});
ServiceAccountAuthenticator::builder(key)
ServiceAccountAuthenticator::with_client(key, DefaultHyperClient.build_test_hyper_client())
.build()
.await
.unwrap()
@@ -632,7 +633,7 @@ async fn test_default_application_credentials_from_metadata_server() {
let opts = ApplicationDefaultCredentialsFlowOpts {
metadata_url: Some(server.url("/token").to_string()),
};
let authenticator = match ApplicationDefaultCredentialsAuthenticator::builder(opts).await {
let authenticator = match ApplicationDefaultCredentialsAuthenticator::with_client(opts, DefaultHyperClient.build_test_hyper_client()).await {
ApplicationDefaultCredentialsTypes::InstanceMetadata(auth) => auth.build().await.unwrap(),
_ => panic!("We are not testing service account adc model"),
};