1use serde::{Deserialize, Serialize};
4
5use crate::{
6 connection::ServerName,
7 webpki::{CertificateDer, PrivateKeyDer, RootCertStore},
8};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct TlsClientConfig {
13 server_name: ServerName,
14 root_store: RootCertStore,
16 client_auth: Option<(Vec<CertificateDer>, PrivateKeyDer)>,
19}
20
21impl TlsClientConfig {
22 pub fn builder() -> TlsConfigBuilder {
24 TlsConfigBuilder::default()
25 }
26
27 pub fn server_name(&self) -> &ServerName {
29 &self.server_name
30 }
31
32 pub fn root_store(&self) -> &RootCertStore {
34 &self.root_store
35 }
36
37 pub fn client_auth(&self) -> Option<&(Vec<CertificateDer>, PrivateKeyDer)> {
40 self.client_auth.as_ref()
41 }
42}
43
44#[derive(Debug, Default)]
46pub struct TlsConfigBuilder {
47 server_name: Option<ServerName>,
48 root_store: Option<RootCertStore>,
49 client_auth: Option<(Vec<CertificateDer>, PrivateKeyDer)>,
50}
51
52impl TlsConfigBuilder {
53 pub fn server_name(mut self, server_name: ServerName) -> Self {
55 self.server_name = Some(server_name);
56 self
57 }
58
59 pub fn root_store(mut self, store: RootCertStore) -> Self {
62 self.root_store = Some(store);
63 self
64 }
65
66 pub fn client_auth(mut self, cert_key: (Vec<CertificateDer>, PrivateKeyDer)) -> Self {
79 self.client_auth = Some(cert_key);
80 self
81 }
82
83 pub fn build(self) -> Result<TlsClientConfig, TlsConfigError> {
85 let server_name = self.server_name.ok_or(ErrorRepr::MissingField {
86 field: "server_name",
87 })?;
88
89 let root_store = self.root_store.ok_or(ErrorRepr::MissingField {
90 field: "root_store",
91 })?;
92
93 Ok(TlsClientConfig {
94 server_name,
95 root_store,
96 client_auth: self.client_auth,
97 })
98 }
99}
100
101#[derive(Debug, thiserror::Error)]
103#[error(transparent)]
104pub struct TlsConfigError(#[from] ErrorRepr);
105
106#[derive(Debug, thiserror::Error)]
107#[error("tls config error")]
108enum ErrorRepr {
109 #[error("missing required field: {field}")]
110 MissingField { field: &'static str },
111}