Compare commits

...

3 commits

4 changed files with 56 additions and 52 deletions

View file

@ -12,15 +12,25 @@ categories = ["network-programming"]
[dependencies]
base16ct = "0.2.0"
base64ct = "1.6.0"
bytes = "1.7.1"
dashmap = { version = "6.0.1", optional = true }
mime = "0.3.17"
num_enum = "0.7.3"
sha2 = "0.10.8"
num_enum = "0.7.3"
bytes = "1.7.1"
mime = "0.3.17"
url = "2.5.2"
tokio = { version = "1.39.2", features = ["io-util", "net"] }
tokio-rustls = { version = "0.26.0", default-features = false, features = ["ring"] }
url = "2.5.2"
webpki-roots = "0.26.3"
webpki-roots = { version = "0.26.3", optional = true }
dashmap = { version = "6.0.1", optional = true }
[dev-dependencies]
tokio = { version = "1.39.2", features = ["macros", "rt-multi-thread"] }
[features]
webpki = ["dep:webpki-roots"]
file-sscv = ["dep:dashmap", "tokio/fs"]
[[example]]
name = "simple"
@ -30,9 +40,3 @@ path = "examples/simple.rs"
name = "main"
path = "examples/main.rs"
required-features = ["file-sscv"]
[dev-dependencies]
tokio = { version = "1.39.2", features = ["macros", "rt-multi-thread"] }
[features]
file-sscv = ["dep:dashmap", "tokio/fs"]

View file

@ -24,15 +24,21 @@ impl ServerCertVerifier for CustomCertVerifier {
fn verify_server_cert(
&self,
end_entity: &CertificateDer<'_>,
intermediates: &[CertificateDer<'_>],
_intermediates: &[CertificateDer<'_>],
server_name: &ServerName<'_>,
ocsp_response: &[u8],
_ocsp_response: &[u8],
now: UnixTime,
) -> Result<ServerCertVerified, rustls::Error> {
// if webpki CA certs enabled
#[cfg(feature = "webpki")]
if let Some(wv) = &self.webpki_verifier {
match wv.verify_server_cert(end_entity, intermediates, server_name, ocsp_response, now)
{
match wv.verify_server_cert(
end_entity,
_intermediates,
server_name,
_ocsp_response,
now,
) {
Ok(verified) => {
return Ok(verified);
}

View file

@ -7,12 +7,10 @@ use crate::{
Client,
};
use tokio_rustls::rustls::{
self,
client::{danger::ServerCertVerifier, WebPkiServerVerifier},
pki_types::TrustAnchor,
SupportedProtocolVersion,
};
use tokio_rustls::rustls::{self, client::danger::ServerCertVerifier, SupportedProtocolVersion};
#[cfg(feature = "webpki")]
use tokio_rustls::rustls::{client::WebPkiServerVerifier, pki_types::TrustAnchor};
/// Builder for creating configured [`Client`] instance
pub struct ClientBuilder {
@ -58,24 +56,32 @@ impl ClientBuilder {
let tls_config = if let Some(cv) = self.custom_verifier {
tls_config.dangerous().with_custom_certificate_verifier(cv)
} else if let Some(ssv) = self.ss_verifier {
let webpki_verifier = {
#[cfg(feature = "webpki")]
if !self.root_certs.is_empty() {
Some(
WebPkiServerVerifier::builder_with_provider(
Arc::new(self.root_certs),
provider.clone(),
)
.build()
// panics only if roots are empty (that is checked above)
// or CRLs couldn't be parsed (we didn't provide any)
.unwrap(),
)
} else {
None
}
#[cfg(not(feature = "webpki"))]
None
};
tls_config
.dangerous()
.with_custom_certificate_verifier(Arc::new(CustomCertVerifier {
provider: provider.clone(),
webpki_verifier: if !self.root_certs.is_empty() {
Some(
WebPkiServerVerifier::builder_with_provider(
Arc::new(self.root_certs),
provider,
)
.build()
// panics only if roots are empty (that is checked above)
// or CRLs couldn't be parsed (we didn't provide any)
.unwrap(),
)
} else {
None
},
webpki_verifier,
ss_allowed: true,
ss_verifier: ssv,
}))
@ -102,6 +108,7 @@ impl ClientBuilder {
/// Include webpki trust anchors.
/// Not recommended (useless) as most Gemini capsules use self-signed
/// TLS certs and properly configured TOFU policy is enough.
#[cfg(feature = "webpki")]
pub fn with_webpki_roots(mut self) -> Self {
self.root_certs
.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
@ -110,6 +117,7 @@ impl ClientBuilder {
/// Include custom trust anchors.
/// Not recommended (useless), see note for [`ClientBuilder::with_webpki_roots`].
#[cfg(feature = "webpki")]
pub fn with_custom_roots(
mut self,
iter: impl IntoIterator<Item = TrustAnchor<'static>>,

View file

@ -8,7 +8,6 @@ pub use response::Response;
use crate::{error::*, status::*};
use builder::ClientBuilder;
use std::net::ToSocketAddrs;
use std::sync::Arc;
use tokio::{
@ -25,19 +24,6 @@ pub struct Client {
connector: TlsConnector,
}
impl Default for Client {
/// Create a Client with webpki_roots trust anchors and no client auth cert.
/// Will be possibly removed in next versions.
fn default() -> Self {
let roots =
rustls::RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
let config = rustls::ClientConfig::builder()
.with_root_certificates(roots)
.with_no_client_auth();
Client::from(config)
}
}
impl From<rustls::ClientConfig> for Client {
/// Create a Client from a Rustls config.
#[inline]
@ -107,8 +93,8 @@ impl Client {
host: &str,
port: u16,
) -> Result<Response, LibError> {
let addr = (host, port)
.to_socket_addrs()?
let addr = tokio::net::lookup_host((host, port))
.await?
.next()
.ok_or(InvalidUrl::ConvertError)?;