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