@@ -15,7 +15,7 @@ use rustls::crypto::ring::{ALL_CIPHER_SUITES, DEFAULT_CIPHER_SUITES};
15
15
use rustls:: server:: danger:: ClientCertVerifier ;
16
16
use rustls:: server:: WebPkiClientVerifier ;
17
17
use rustls:: sign:: CertifiedKey ;
18
- use rustls:: { RootCertStore , SupportedCipherSuite } ;
18
+ use rustls:: { DistinguishedName , RootCertStore , SupportedCipherSuite } ;
19
19
use rustls_pemfile:: { certs, crls, pkcs8_private_keys, rsa_private_keys} ;
20
20
use webpki:: { RevocationCheckDepth , UnknownStatusPolicy } ;
21
21
@@ -679,6 +679,7 @@ pub struct rustls_web_pki_client_cert_verifier_builder {
679
679
680
680
pub ( crate ) struct ClientCertVerifierBuilder {
681
681
roots : Arc < RootCertStore > ,
682
+ root_hint_subjects : Vec < DistinguishedName > ,
682
683
crls : Vec < CertificateRevocationListDer < ' static > > ,
683
684
revocation_depth : RevocationCheckDepth ,
684
685
revocation_policy : UnknownStatusPolicy ,
@@ -720,6 +721,7 @@ impl rustls_web_pki_client_cert_verifier_builder {
720
721
ffi_panic_boundary ! {
721
722
let store = try_arc_from_ptr!( store) ;
722
723
let builder = ClientCertVerifierBuilder {
724
+ root_hint_subjects: store. subjects( ) ,
723
725
roots: store,
724
726
crls: Vec :: default ( ) ,
725
727
revocation_depth: RevocationCheckDepth :: Chain ,
@@ -822,6 +824,52 @@ impl rustls_web_pki_client_cert_verifier_builder {
822
824
}
823
825
}
824
826
827
+ /// Clear the list of trust anchor hint subjects.
828
+ ///
829
+ /// By default, the client cert verifier will use the subjects provided by the root cert
830
+ /// store configured for client authentication. Calling this function will remove these
831
+ /// hint subjects, indicating the client should make a free choice of which certificate
832
+ /// to send.
833
+ #[ no_mangle]
834
+ pub extern "C" fn rustls_web_pki_client_cert_verifier_clear_root_hint_subjects (
835
+ builder : * mut rustls_web_pki_client_cert_verifier_builder ,
836
+ ) -> rustls_result {
837
+ ffi_panic_boundary ! {
838
+ let client_verifier_builder: & mut Option <ClientCertVerifierBuilder > = try_mut_from_ptr!( builder) ;
839
+ let client_verifier_builder = match client_verifier_builder {
840
+ None => return AlreadyUsed ,
841
+ Some ( v) => v,
842
+ } ;
843
+
844
+ client_verifier_builder. root_hint_subjects. clear( ) ;
845
+ rustls_result:: Ok
846
+ }
847
+ }
848
+
849
+ /// Add additional distinguished names to the list of trust anchor hint subjects.
850
+ ///
851
+ /// By default, the client cert verifier will use the subjects provided by the root cert
852
+ /// store configured for client authentication. Calling this function will add to these
853
+ /// existing hint subjects. Calling this function with empty `subjects` will have no
854
+ /// effect, use `rustls_web_pki_client_cert_verifier_clear_root_hint_subjects` to clear
855
+ /// the subject hints.
856
+ #[ no_mangle]
857
+ pub extern "C" fn rustls_web_pki_client_cert_verifier_add_root_hint_subjects (
858
+ builder : * mut rustls_web_pki_client_cert_verifier_builder ,
859
+ store : * const rustls_root_cert_store ,
860
+ ) -> rustls_result {
861
+ let client_verifier_builder: & mut Option < ClientCertVerifierBuilder > =
862
+ try_mut_from_ptr ! ( builder) ;
863
+ let client_verifier_builder = match client_verifier_builder {
864
+ None => return AlreadyUsed ,
865
+ Some ( v) => v,
866
+ } ;
867
+
868
+ let store = try_arc_from_ptr ! ( store) ;
869
+ client_verifier_builder. root_hint_subjects = store. subjects ( ) ;
870
+ rustls_result:: Ok
871
+ }
872
+
825
873
/// Create a new client certificate verifier from the builder.
826
874
///
827
875
/// The builder is consumed and cannot be used again, but must still be freed.
@@ -849,6 +897,11 @@ impl rustls_web_pki_client_cert_verifier_builder {
849
897
if client_verifier_builder. allow_anonymous {
850
898
builder = builder. allow_unauthenticated( ) ;
851
899
}
900
+ if client_verifier_builder. root_hint_subjects. is_empty( ) {
901
+ builder = builder. clear_root_hint_subjects( ) ;
902
+ } else {
903
+ builder = builder. add_root_hint_subjects( client_verifier_builder. root_hint_subjects) ;
904
+ }
852
905
853
906
let verifier = match builder. build( ) {
854
907
Ok ( v) => v,
0 commit comments