Closed ameba23 closed 9 months ago
I would love a better certificate setup and to get rid of mkcert. I wish you the best of luck. Here's what I've learned:
Check if your code produces the same fingerprint as mine. That might just be the issue; it was a pain in the butt figuring out what needs to be hashed.
Thank you @kixelated the problem was indeed with the fingerprints. Using your method you linked to gave me a different hash to what i was getting, and using that hash let me successfully make a connection using Chrome.
Using rc-gen::Certificate::serialize_der
appears to give different output than rustls_pemfile::certs
gives - both are der encoding of the same length - but not exactly the same. For the record - rustls_pemfile::certs
is the one which works.
Here is a working example which writes files compatible with the echo example in this repo:
use ring::digest::{digest, SHA256};
use std::{fs::File, io::Write, time::Duration};
use time::OffsetDateTime;
fn main() {
let mut cert_params =
rcgen::CertificateParams::new(vec!["localhost".to_string(), "127.0.0.1".to_string()]);
let now = OffsetDateTime::now_utc();
cert_params.not_before = now;
cert_params.not_after = now + Duration::from_secs(60 * 60 * 24 * 10); // 10 days
cert_params.alg = &rcgen::PKCS_ECDSA_P256_SHA256;
let cert = rcgen::Certificate::from_params(cert_params).unwrap();
let cert_pem = cert.serialize_pem().unwrap();
println!("{}", cert_pem);
let mut file = File::create("localhost.crt").unwrap();
file.write_all(cert_pem.as_bytes()).unwrap();
let priv_pem = cert.serialize_private_key_pem();
println!("{}", priv_pem);
let mut file = File::create("localhost.key").unwrap();
file.write_all(priv_pem.as_bytes()).unwrap();
let mut cert_reader = std::io::BufReader::new(cert_pem.as_bytes());
let certs = rustls_pemfile::certs(&mut cert_reader).unwrap();
let cert_der = certs.first().expect("No certificate found");
let fingerprint = digest(&SHA256, cert_der.as_ref());
let fingerprint_hex = hex::encode(fingerprint.as_ref());
println!("Fingerprint {}", fingerprint_hex);
let mut file = File::create("localhost.hex").unwrap();
file.write_all(fingerprint_hex.as_bytes()).unwrap();
}
I would like to be able to generate a self-signed certificate programmatically from rust, rather than using openssl as in the given example here.
The
rcgen
crate provides a way of doing this, which works fine when usingQuinn
directly with a rust server and client. But using this crate together with the web client using the example here (with Chromium), i get an 'unknown certificate' error when using a self signed certificate generated with the code below.I'm pretty sure there is no issue with the chosen signature algorithm, and i have checked that the method of hashing the certificate gives the same results as with https://github.com/kixelated/webtransport-rs/blob/3153f826549bfa04a220e89c8798f37b822dc39f/webtransport-quinn/cert/generate#L12
So there must be some other issue with the certificate parameters / extensions that make it different from one generated with https://github.com/kixelated/webtransport-rs/blob/3153f826549bfa04a220e89c8798f37b822dc39f/webtransport-quinn/cert/generate#L9
Note that these rcgen certificates do work fine with the rust client example - so it is an issue relating to web /
serverCertificateHashes
.This is maybe an
rcgen
issue rather than awebtransport-quinn
issue.