1use crate::error::Result;
2use crate::resolve::MaterialWatcher;
3use crate::types::{authorize_any, AuthorizeSpiffeId};
4use crate::verifier::SpiffeClientCertVerifier;
5use rustls::server::ResolvesServerCert;
6use rustls::ServerConfig;
7use spiffe::{TrustDomain, X509Source};
8use std::sync::Arc;
9
10#[derive(Clone)]
14pub struct ServerConfigOptions {
15 pub trust_domain: TrustDomain,
17
18 pub authorize_client: AuthorizeSpiffeId,
23}
24
25impl ServerConfigOptions {
26 pub fn allow_any(trust_domain: TrustDomain) -> Self {
31 Self {
32 trust_domain,
33 authorize_client: authorize_any(),
34 }
35 }
36}
37
38pub struct ServerConfigBuilder {
59 source: Arc<X509Source>,
60 opts: ServerConfigOptions,
61}
62
63impl ServerConfigBuilder {
64 pub fn new(source: Arc<X509Source>, opts: ServerConfigOptions) -> Self {
66 Self { source, opts }
67 }
68
69 pub async fn build(self) -> Result<ServerConfig> {
71 crate::crypto::ensure_crypto_provider_installed();
72
73 let watcher = MaterialWatcher::new(self.source, self.opts.trust_domain).await?;
74
75 let resolver: Arc<dyn ResolvesServerCert> =
76 Arc::new(resolve_server::SpiffeServerCertResolver {
77 watcher: watcher.clone(),
78 });
79
80 let verifier = Arc::new(SpiffeClientCertVerifier::new(
81 Arc::new(watcher.clone()),
82 self.opts.authorize_client,
83 )?);
84
85 let cfg = ServerConfig::builder()
86 .with_client_cert_verifier(verifier)
87 .with_cert_resolver(resolver);
88
89 Ok(cfg)
90 }
91}
92
93mod resolve_server {
94 use crate::resolve::MaterialWatcher;
95 use rustls::server::ResolvesServerCert;
96 use rustls::sign::CertifiedKey;
97 use std::sync::Arc;
98
99 #[derive(Clone, Debug)]
100 pub(crate) struct SpiffeServerCertResolver {
101 pub watcher: MaterialWatcher,
102 }
103
104 impl ResolvesServerCert for SpiffeServerCertResolver {
105 fn resolve(
106 &self,
107 _client_hello: rustls::server::ClientHello<'_>,
108 ) -> Option<Arc<CertifiedKey>> {
109 Some(self.watcher.current().certified_key.clone())
110 }
111 }
112}