@@ -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
@@ -683,6 +683,7 @@ pub struct rustls_web_pki_client_cert_verifier_builder {
683
683
684
684
pub ( crate ) struct ClientCertVerifierBuilder {
685
685
roots : Arc < RootCertStore > ,
686
+ root_hint_subjects : Vec < DistinguishedName > ,
686
687
crls : Vec < CertificateRevocationListDer < ' static > > ,
687
688
revocation_depth : RevocationCheckDepth ,
688
689
revocation_policy : UnknownStatusPolicy ,
@@ -724,6 +725,7 @@ impl rustls_web_pki_client_cert_verifier_builder {
724
725
ffi_panic_boundary ! {
725
726
let store = try_clone_arc!( store) ;
726
727
let builder = ClientCertVerifierBuilder {
728
+ root_hint_subjects: store. subjects( ) ,
727
729
roots: store,
728
730
crls: Vec :: default ( ) ,
729
731
revocation_depth: RevocationCheckDepth :: Chain ,
@@ -829,6 +831,52 @@ impl rustls_web_pki_client_cert_verifier_builder {
829
831
}
830
832
}
831
833
834
+ /// Clear the list of trust anchor hint subjects.
835
+ ///
836
+ /// By default, the client cert verifier will use the subjects provided by the root cert
837
+ /// store configured for client authentication. Calling this function will remove these
838
+ /// hint subjects, indicating the client should make a free choice of which certificate
839
+ /// to send.
840
+ #[ no_mangle]
841
+ pub extern "C" fn rustls_web_pki_client_cert_verifier_clear_root_hint_subjects (
842
+ builder : * mut rustls_web_pki_client_cert_verifier_builder ,
843
+ ) -> rustls_result {
844
+ ffi_panic_boundary ! {
845
+ let client_verifier_builder: & mut Option <ClientCertVerifierBuilder > = try_mut_from_ptr!( builder) ;
846
+ let client_verifier_builder = match client_verifier_builder {
847
+ None => return AlreadyUsed ,
848
+ Some ( v) => v,
849
+ } ;
850
+
851
+ client_verifier_builder. root_hint_subjects. clear( ) ;
852
+ rustls_result:: Ok
853
+ }
854
+ }
855
+
856
+ /// Add additional distinguished names to the list of trust anchor hint subjects.
857
+ ///
858
+ /// By default, the client cert verifier will use the subjects provided by the root cert
859
+ /// store configured for client authentication. Calling this function will add to these
860
+ /// existing hint subjects. Calling this function with an empty `store` will have no
861
+ /// effect, use `rustls_web_pki_client_cert_verifier_clear_root_hint_subjects` to clear
862
+ /// the subject hints.
863
+ #[ no_mangle]
864
+ pub extern "C" fn rustls_web_pki_client_cert_verifier_add_root_hint_subjects (
865
+ builder : * mut rustls_web_pki_client_cert_verifier_builder ,
866
+ store : * const rustls_root_cert_store ,
867
+ ) -> rustls_result {
868
+ let client_verifier_builder: & mut Option < ClientCertVerifierBuilder > =
869
+ try_mut_from_ptr ! ( builder) ;
870
+ let client_verifier_builder = match client_verifier_builder {
871
+ None => return AlreadyUsed ,
872
+ Some ( v) => v,
873
+ } ;
874
+
875
+ let store = try_clone_arc ! ( store) ;
876
+ client_verifier_builder. root_hint_subjects = store. subjects ( ) ;
877
+ rustls_result:: Ok
878
+ }
879
+
832
880
/// Create a new client certificate verifier from the builder.
833
881
///
834
882
/// The builder is consumed and cannot be used again, but must still be freed.
@@ -858,6 +906,11 @@ impl rustls_web_pki_client_cert_verifier_builder {
858
906
if client_verifier_builder. allow_unauthenticated {
859
907
builder = builder. allow_unauthenticated( ) ;
860
908
}
909
+ if client_verifier_builder. root_hint_subjects. is_empty( ) {
910
+ builder = builder. clear_root_hint_subjects( ) ;
911
+ } else {
912
+ builder = builder. add_root_hint_subjects( client_verifier_builder. root_hint_subjects) ;
913
+ }
861
914
862
915
let verifier = match builder. build( ) {
863
916
Ok ( v) => v,
0 commit comments