Stuck on implementing Actix-web + rustls with SNI or something similar

Hello everyone, I am really stuck and I have absolutely no clue what exactly I have to do in order to make somehow let config = ServerConfig::builder() work with multiple domains (certificates to be precise). It has method .with_cert_resolver() but I am not sure, and I didn't find any documentation as well or article (neither the GPTs have a clue), how to use this method. Please any direction or help will be very helpful. I almost ported a whole http server implementation from C# to Rust, and this is the final part. :smiling_face_with_tear:

I found that actix-net/actix-tls/examples/accept-rustls.rs at master ยท actix/actix-net (github.com) but still I am not exactly aware how can I dynamically change certs based on the incoming domain or other factors.

Never done this myself before, but I assume you'd have to use rustls::ConfigBuilder::with_cert_resolver instead of with_single_cert in this line of the example.

Actually after breaking my head I found the holly grail code using ResolvesServerCert:

impl ResolvesServerCert for CustomCertResolver {
    fn resolve(&self, client_hello: ClientHello) -> Option<Arc<CertifiedKey>> {
        match client_hello.server_name() {
            Some(sni) => {
                let file_name = sni.replace(".", "");

                let cert_file = &mut BufReader::new(File::open("LOC\\file_name ").unwrap());
                let private_key_file = &mut BufReader::new(File::open("LOC\\file_name ").unwrap());

                let certs = rustls_pemfile::certs(cert_file)
                    .collect::<Result<Vec<_>, _>>()
                    .unwrap();

                let private_key = rustls_pemfile::private_key(private_key_file)
                    .unwrap()
                    .unwrap();

                let certified_key = CertifiedKey {
                    cert: certs,
                    key: any_supported_type(&private_key).unwrap(),
                    ocsp: None
                };

                Some(Arc::new(certified_key))
            }
            None => None, // No SNI information provided
        }
    }
}

and the struct (nothing fancy)

#[derive(Debug)]

struct CustomCertResolver;

and the ServerConfig code:

fn load_rustls_config() -> ServerConfig {
    let config = ServerConfig::builder()
        .with_no_client_auth()
        .with_cert_resolver(Arc::new(CustomCertResolver));

    return config;
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.