| Crates.io | hyper-custom-cert |
| lib.rs | hyper-custom-cert |
| version | 0.3.6 |
| created_at | 2025-08-14 21:24:52.852478+00 |
| updated_at | 2025-08-28 19:34:00.652017+00 |
| description | A small, ergonomic HTTP client wrapper around hyper with optional support for custom Root CAs and a dev-only insecure mode for self-signed certificates. |
| homepage | https://docs.rs/hyper-custom-cert |
| repository | https://github.com/seemueller-io/hyper-custom-cert |
| max_upload_size | |
| id | 1795823 |
| size | 145,356 |
A small, ergonomic HTTP client wrapper around hyper with optional support for custom Root CAs and a dev-only insecure mode for self-signed certificates.
native-tlsrustls feature for connecting to services with custom Certificate Authoritiesinsecure-dangerous feature for testing with self-signed certificates (⚠️ NEVER use in production)cargo add hyper-custom-cert
use hyper_custom_cert::HttpClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Uses OS trust store by default - secure for public HTTPS endpoints
let client = HttpClient::new();
// Make requests to publicly trusted endpoints
client.request("https://httpbin.org/get").await?;
Ok(())
}
For connecting to services with custom/private Certificate Authorities:
[dependencies]
hyper-custom-cert = { version = "0.1.0", features = ["rustls"] }
use hyper_custom_cert::HttpClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load your organization's Root CA
let client = HttpClient::builder()
.with_root_ca_file("path/to/your-org-root-ca.pem")
.build();
// Now you can connect to services signed by your custom CA
client.request("https://internal.your-org.com/api").await?;
Ok(())
}
For high-security environments where you want to pin specific certificates:
use hyper_custom_cert::HttpClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// SHA-256 fingerprints of certificates you want to accept
let pin1 = [0x12, 0x34, /* ... 30 more bytes */];
let pin2 = [0xab, 0xcd, /* ... 30 more bytes */];
let client = HttpClient::builder()
.with_pinned_cert_sha256(vec![pin1, pin2])
.build();
// Only accepts connections to certificates matching the pins
client.request("https://secure-api.example.com").await?;
Ok(())
}
WARNING: This mode disables certificate validation. Only use for local development and testing.
[dependencies]
hyper-custom-cert = { version = "0.1.0", features = ["insecure-dangerous"] }
use hyper_custom_cert::HttpClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// ⚠️ EXTREMELY DANGEROUS - Only for local development
let client = HttpClient::builder()
.insecure_accept_invalid_certs(true)
.build();
// Can connect to self-signed certificates (NOT for production!)
client.request("https://localhost:8443").await?;
Ok(())
}
use hyper_custom_cert::HttpClient;
use std::time::Duration;
use std::collections::HashMap;
let mut headers = HashMap::new();
headers.insert("User-Agent".to_string(), "MyApp/1.0".to_string());
let client = HttpClient::builder()
.with_timeout(Duration::from_secs(30))
.with_default_headers(headers)
.with_root_ca_file("custom-ca.pem") // Requires 'rustls' feature
.build();
| Method | Feature Required | Description |
|---|---|---|
new() |
None | Creates client with OS trust store (secure default) |
builder() |
None | Returns a builder for custom configuration |
with_timeout(Duration) |
None | Sets request timeout |
with_default_headers(HashMap) |
None | Sets default headers for all requests |
with_root_ca_pem(&[u8]) |
rustls |
Adds custom CA from PEM bytes |
with_root_ca_file(Path) |
rustls |
Adds custom CA from PEM file |
with_pinned_cert_sha256(Vec<[u8; 32]>) |
rustls |
Enables certificate pinning |
insecure_accept_invalid_certs(bool) |
insecure-dangerous |
⚠️ Disables certificate validation |
with_self_signed_certs() |
insecure-dangerous |
⚠️ Convenience for self-signed certs |
native-tls (Default)hyper-tls, native-tlsrustlshyper-rustls, rustls-pemfilewith_root_ca_pem(), with_root_ca_file(), with_pinned_cert_sha256()insecure-dangerousinsecure_accept_invalid_certs(), with_self_signed_certs()This crate supports WebAssembly targets with important security considerations:
// WASM builds will compile, but certain operations are restricted
#[cfg(target_arch = "wasm32")]
{
let client = HttpClient::new(); // ✅ Works
// Custom CA operations may return WasmNotImplemented errors
}
WASM Limitations:
Browser Certificate Installation:
use hyper_custom_cert::{HttpClient, ClientError};
match client.request("https://example.com").await {
Ok(_) => println!("Request successful"),
Err(ClientError::WasmNotImplemented) => {
println!("This operation isn't supported in WASM");
}
Err(e) => {
println!("Request failed: {}", e);
}
}
native-tls for public endpointsrustls feature when connecting to private CAsinsecure-dangerous: This feature should never be enabled in production// ✅ GOOD: Production configuration
#[cfg(not(debug_assertions))]
let client = HttpClient::new(); // Uses OS trust store
// ✅ GOOD: Development configuration
#[cfg(debug_assertions)]
let client = HttpClient::builder()
.insecure_accept_invalid_certs(true) // Only in debug builds
.build();
See the examples/ directory for complete working examples:
examples/self-signed-certs/ - Comprehensive examples for all modes# Test with default features
cargo test
# Test with rustls features
cargo test --features rustls
# Test with all features (for development)
cargo test --features rustls,insecure-dangerous
# Test WASM compatibility
cargo test --target wasm32-unknown-unknown
cargo test --all-featuresThis project is licensed under either of:
at your option.
For security vulnerabilities, please see SECURITY.md for our responsible disclosure policy.
Remember: This library prioritizes security by default. The insecure-dangerous feature exists solely for development convenience and should never be used in production environments.