@@ -33,12 +33,17 @@ use policy_evaluator::{
33
33
use profiling:: activate_memory_profiling;
34
34
use rayon:: prelude:: * ;
35
35
use std:: { fs, net:: SocketAddr , sync:: Arc } ;
36
+ use std:: { fs:: File , io:: BufReader } ;
36
37
use tokio:: {
37
38
sync:: { oneshot, Notify , Semaphore } ,
38
39
time,
39
40
} ;
40
41
use tower_http:: trace:: { self , TraceLayer } ;
41
42
43
+ use rustls:: { server:: WebPkiClientVerifier , RootCertStore , ServerConfig } ;
44
+ use rustls_pemfile:: Item ;
45
+ use rustls_pki_types:: { CertificateDer , PrivateKeyDer } ;
46
+
42
47
// This is required by certificate hot reload when using inotify, which is available only on linux
43
48
#[ cfg( target_os = "linux" ) ]
44
49
use tokio_stream:: StreamExt ;
@@ -286,21 +291,14 @@ impl PolicyServer {
286
291
}
287
292
}
288
293
289
- // Load the ServerConfig to be used by the Policy Server configuring the server
290
- // certificate and mTLS when necessary
291
- //
292
- // RustlsConfig does not offer a function to load the client CA certificate together with the
293
- // service certificates. Therefore, we need to load everything and build the ServerConfig
294
+ /// Load the ServerConfig to be used by the Policy Server configuring the server
295
+ /// certificate and mTLS when necessary
296
+ ///
297
+ /// RustlsConfig does not offer a function to load the client CA certificate together with the
298
+ /// service certificates. Therefore, we need to load everything and build the ServerConfig
294
299
async fn build_tls_server_config ( tls_config : & TlsConfig ) -> Result < rustls:: ServerConfig > {
295
- use std:: { fs:: File , io:: BufReader } ;
296
-
297
- use rustls:: { server:: WebPkiClientVerifier , RootCertStore , ServerConfig } ;
298
- use rustls_pemfile:: Item ;
299
- use rustls_pki_types:: { CertificateDer , PrivateKeyDer } ;
300
-
301
- let cert_file = & mut BufReader :: new ( File :: open ( tls_config. cert_file . clone ( ) ) ?) ;
302
- let key_file = & mut BufReader :: new ( File :: open ( tls_config. key_file . clone ( ) ) ?) ;
303
- let cert: Vec < CertificateDer > = rustls_pemfile:: certs ( cert_file)
300
+ let cert_reader = & mut BufReader :: new ( File :: open ( tls_config. cert_file . clone ( ) ) ?) ;
301
+ let cert: Vec < CertificateDer > = rustls_pemfile:: certs ( cert_reader)
304
302
. filter_map ( |it| {
305
303
if let Err ( ref e) = it {
306
304
warn ! ( "Cannot parse certificate: {e}" ) ;
@@ -312,7 +310,9 @@ async fn build_tls_server_config(tls_config: &TlsConfig) -> Result<rustls::Serve
312
310
if cert. len ( ) > 1 {
313
311
return Err ( anyhow ! ( "Multiple certificates provided in cert file" ) ) ;
314
312
}
315
- let mut key_vec: Vec < Vec < u8 > > = rustls_pemfile:: read_all ( key_file)
313
+
314
+ let key_file_reader = & mut BufReader :: new ( File :: open ( tls_config. key_file . clone ( ) ) ?) ;
315
+ let mut key_vec: Vec < Vec < u8 > > = rustls_pemfile:: read_all ( key_file_reader)
316
316
. filter_map ( |i| match i. ok ( ) ? {
317
317
Item :: Sec1Key ( key) => Some ( key. secret_sec1_der ( ) . to_vec ( ) ) ,
318
318
Item :: Pkcs1Key ( key) => Some ( key. secret_pkcs1_der ( ) . to_vec ( ) ) ,
@@ -332,36 +332,35 @@ async fn build_tls_server_config(tls_config: &TlsConfig) -> Result<rustls::Serve
332
332
let key = PrivateKeyDer :: try_from ( key_vec. pop ( ) . unwrap ( ) )
333
333
. map_err ( |e| anyhow ! ( "Cannot parse server key: {e}" ) ) ?;
334
334
335
- let config = if let Some ( client_ca_cert_file_path ) = tls_config. client_ca_cert_file . clone ( ) {
335
+ if let Some ( client_ca_file ) = tls_config. client_ca_file . clone ( ) {
336
336
// we have the client CA. Therefore, we should enable mTLS.
337
- let client_ca_cert_file = & mut BufReader :: new ( File :: open ( client_ca_cert_file_path ) ?) ;
337
+ let client_ca_reader = & mut BufReader :: new ( File :: open ( client_ca_file ) ?) ;
338
338
339
- let mut ca_certs = RootCertStore :: empty ( ) ;
340
- let client_ca_certs: Vec < _ > = rustls_pemfile:: certs ( client_ca_cert_file )
339
+ let mut store = RootCertStore :: empty ( ) ;
340
+ let client_ca_certs: Vec < _ > = rustls_pemfile:: certs ( client_ca_reader )
341
341
. filter_map ( |it| {
342
342
if let Err ( ref e) = it {
343
343
warn ! ( "Cannot parse client CA certificate: {e}" ) ;
344
344
}
345
345
it. ok ( )
346
346
} )
347
347
. collect ( ) ;
348
- let ( cert_added, cert_ignored) = ca_certs . add_parsable_certificates ( client_ca_certs) ;
348
+ let ( cert_added, cert_ignored) = store . add_parsable_certificates ( client_ca_certs) ;
349
349
info ! (
350
350
client_ca_certs_added = cert_added,
351
351
client_ca_certs_ignored = cert_ignored,
352
352
"Loaded client CA certificates"
353
353
) ;
354
- let client_verifier = WebPkiClientVerifier :: builder ( Arc :: new ( ca_certs ) ) . build ( ) ?;
354
+ let client_verifier = WebPkiClientVerifier :: builder ( Arc :: new ( store ) ) . build ( ) ?;
355
355
356
- ServerConfig :: builder ( )
356
+ return Ok ( ServerConfig :: builder ( )
357
357
. with_client_cert_verifier ( client_verifier)
358
- . with_single_cert ( cert, key) ?
359
- } else {
360
- ServerConfig :: builder ( )
361
- . with_no_client_auth ( )
362
- . with_single_cert ( cert, key) ?
363
- } ;
364
- Ok ( config)
358
+ . with_single_cert ( cert, key) ?) ;
359
+ }
360
+
361
+ Ok ( ServerConfig :: builder ( )
362
+ . with_no_client_auth ( )
363
+ . with_single_cert ( cert, key) ?)
365
364
}
366
365
367
366
/// There's no watching of the certificate files on non-linux platforms
@@ -386,10 +385,6 @@ async fn create_tls_config_and_watch_certificate_changes(
386
385
) -> Result < RustlsConfig > {
387
386
use :: tracing:: error;
388
387
389
- let cert_file_path = tls_config. cert_file . clone ( ) ;
390
- let key_file_path = tls_config. key_file . clone ( ) ;
391
- let client_ca_cert_path = tls_config. client_ca_cert_file . clone ( ) ;
392
-
393
388
let config = build_tls_server_config ( & tls_config) . await ?;
394
389
395
390
let rust_config = RustlsConfig :: from_config ( Arc :: new ( config) ) ;
@@ -399,19 +394,22 @@ async fn create_tls_config_and_watch_certificate_changes(
399
394
inotify:: Inotify :: init ( ) . map_err ( |e| anyhow ! ( "Cannot initialize inotify: {e}" ) ) ?;
400
395
let cert_watch = inotify
401
396
. watches ( )
402
- . add ( cert_file_path. clone ( ) , inotify:: WatchMask :: CLOSE_WRITE )
397
+ . add (
398
+ tls_config. cert_file . clone ( ) ,
399
+ inotify:: WatchMask :: CLOSE_WRITE ,
400
+ )
403
401
. map_err ( |e| anyhow ! ( "Cannot watch certificate file: {e}" ) ) ?;
404
402
let key_watch = inotify
405
403
. watches ( )
406
- . add ( key_file_path . clone ( ) , inotify:: WatchMask :: CLOSE_WRITE )
404
+ . add ( tls_config . key_file . clone ( ) , inotify:: WatchMask :: CLOSE_WRITE )
407
405
. map_err ( |e| anyhow ! ( "Cannot watch key file: {e}" ) ) ?;
408
406
409
407
let mut client_cert_watch = None ;
410
- if let Some ( ref client_cert_file ) = client_ca_cert_path {
408
+ if let Some ( ref client_ca_file ) = tls_config . client_ca_file {
411
409
client_cert_watch = Some (
412
410
inotify
413
411
. watches ( )
414
- . add ( client_cert_file . clone ( ) , inotify:: WatchMask :: CLOSE_WRITE )
412
+ . add ( client_ca_file , inotify:: WatchMask :: CLOSE_WRITE )
415
413
. map_err ( |e| anyhow ! ( "Cannot watch client certificate file: {e}" ) ) ?,
416
414
) ;
417
415
}
0 commit comments