1use crate::error::Result;
2use crate::resolve::MaterialWatcher;
3use crate::types::{AuthorizeSpiffeId, authorize_any};
4use crate::verifier::SpiffeClientCertVerifier;
5use rustls::ServerConfig;
6use rustls::server::ResolvesServerCert;
7use spiffe::{TrustDomain, X509Source};
8use std::sync::Arc;
9
10#[derive(Clone)]
12pub struct ServerConfigOptions {
13 pub trust_domain: TrustDomain,
15
16 pub authorize_client: AuthorizeSpiffeId,
20}
21
22impl ServerConfigOptions {
23 pub fn allow_any(trust_domain: TrustDomain) -> Self {
27 Self {
28 trust_domain,
29 authorize_client: authorize_any(),
30 }
31 }
32}
33
34pub struct ServerConfigBuilder {
43 source: Arc<X509Source>,
44 opts: ServerConfigOptions,
45}
46
47impl ServerConfigBuilder {
48 pub fn new(source: Arc<X509Source>, opts: ServerConfigOptions) -> Self {
50 Self { source, opts }
51 }
52
53 pub async fn build(self) -> Result<ServerConfig> {
55 let watcher = MaterialWatcher::new(self.source, self.opts.trust_domain).await?;
58 let mat = watcher.current();
59
60 let resolver: Arc<dyn ResolvesServerCert> =
61 Arc::new(resolve_server::SpiffeServerCertResolver { watcher });
62
63 let verifier = Arc::new(SpiffeClientCertVerifier::new(
64 mat.roots.clone(),
65 self.opts.authorize_client,
66 )?);
67
68 let cfg = ServerConfig::builder()
69 .with_client_cert_verifier(verifier)
70 .with_cert_resolver(resolver);
71
72 Ok(cfg)
73 }
74}
75
76mod resolve_server {
77 use crate::resolve::MaterialWatcher;
78 use rustls::server::ResolvesServerCert;
79 use rustls::sign::CertifiedKey;
80 use std::sync::Arc;
81
82 #[derive(Clone, Debug)]
83 pub(crate) struct SpiffeServerCertResolver {
84 pub watcher: MaterialWatcher,
85 }
86
87 impl ResolvesServerCert for SpiffeServerCertResolver {
88 fn resolve(
89 &self,
90 _client_hello: rustls::server::ClientHello<'_>,
91 ) -> Option<Arc<CertifiedKey>> {
92 Some(self.watcher.current().certified_key.clone())
93 }
94 }
95}