11mod attestation;
22
33pub use attestation:: { AttestationPlatform , MockAttestation , NoAttestation } ;
4+ use tokio_rustls:: rustls:: server:: WebPkiClientVerifier ;
45
56#[ cfg( test) ]
67mod test_helpers;
@@ -18,6 +19,11 @@ use tokio_rustls::{
1819/// The label used when exporting key material from a TLS session
1920const EXPORTER_LABEL : & [ u8 ; 24 ] = b"EXPORTER-Channel-Binding" ;
2021
22+ pub struct TlsCertAndKey {
23+ pub cert_chain : Vec < CertificateDer < ' static > > ,
24+ pub key : PrivateKeyDer < ' static > ,
25+ }
26+
2127struct Proxy < L , R >
2228where
2329 L : AttestationPlatform ,
@@ -48,20 +54,36 @@ where
4854
4955impl < L : AttestationPlatform , R : AttestationPlatform > ProxyServer < L , R > {
5056 pub async fn new (
51- cert_chain : Vec < CertificateDer < ' static > > ,
52- key : PrivateKeyDer < ' static > ,
57+ cert_and_key : TlsCertAndKey ,
5358 local : impl ToSocketAddrs ,
5459 target : SocketAddr ,
5560 local_attestation_platform : L ,
5661 remote_attestation_platform : R ,
62+ client_auth : bool ,
5763 ) -> Self {
58- let server_config = ServerConfig :: builder ( )
59- . with_no_client_auth ( )
60- . with_single_cert ( cert_chain. clone ( ) , key)
61- . expect ( "Failed to create rustls server config" ) ;
64+ if remote_attestation_platform. is_cvm ( ) && !client_auth {
65+ panic ! ( "Client auth is required when the client is running in a CVM" ) ;
66+ }
67+
68+ let server_config = if client_auth {
69+ let root_store =
70+ RootCertStore :: from_iter ( webpki_roots:: TLS_SERVER_ROOTS . iter ( ) . cloned ( ) ) ;
71+ let verifier = WebPkiClientVerifier :: builder ( Arc :: new ( root_store) )
72+ . build ( )
73+ . expect ( "invalid client verifier" ) ;
74+ ServerConfig :: builder ( )
75+ . with_client_cert_verifier ( verifier)
76+ . with_single_cert ( cert_and_key. cert_chain . clone ( ) , cert_and_key. key )
77+ . expect ( "Failed to create rustls server config" )
78+ } else {
79+ ServerConfig :: builder ( )
80+ . with_no_client_auth ( )
81+ . with_single_cert ( cert_and_key. cert_chain . clone ( ) , cert_and_key. key )
82+ . expect ( "Failed to create rustls server config" )
83+ } ;
6284
6385 Self :: new_with_tls_config (
64- cert_chain,
86+ cert_and_key . cert_chain ,
6587 server_config. into ( ) ,
6688 local,
6789 target,
@@ -187,17 +209,28 @@ where
187209
188210impl < L : AttestationPlatform , R : AttestationPlatform > ProxyClient < L , R > {
189211 pub async fn new (
212+ cert_and_key : Option < TlsCertAndKey > ,
190213 address : impl ToSocketAddrs ,
191214 server_address : SocketAddr ,
192215 server_name : ServerName < ' static > ,
193216 local_attestation_platform : L ,
194217 remote_attestation_platform : R ,
195- cert_chain : Option < Vec < CertificateDer < ' static > > > ,
196218 ) -> Self {
197219 let root_store = RootCertStore :: from_iter ( webpki_roots:: TLS_SERVER_ROOTS . iter ( ) . cloned ( ) ) ;
198- let client_config = ClientConfig :: builder ( )
199- . with_root_certificates ( root_store)
200- . with_no_client_auth ( ) ;
220+
221+ let client_config = if let Some ( ref cert_and_key) = cert_and_key {
222+ ClientConfig :: builder ( )
223+ . with_root_certificates ( root_store)
224+ . with_client_auth_cert (
225+ cert_and_key. cert_chain . clone ( ) ,
226+ cert_and_key. key . clone_key ( ) ,
227+ )
228+ . unwrap ( )
229+ } else {
230+ ClientConfig :: builder ( )
231+ . with_root_certificates ( root_store)
232+ . with_no_client_auth ( )
233+ } ;
201234
202235 Self :: new_with_tls_config (
203236 client_config. into ( ) ,
@@ -206,7 +239,7 @@ impl<L: AttestationPlatform, R: AttestationPlatform> ProxyClient<L, R> {
206239 server_name,
207240 local_attestation_platform,
208241 remote_attestation_platform,
209- cert_chain,
242+ cert_and_key . map ( |c| c . cert_chain ) ,
210243 )
211244 . await
212245 }
0 commit comments