Skip to content

Commit 49b4eb9

Browse files
committed
control root hint subjects w/ client verifier builder
1 parent 0671e44 commit 49b4eb9

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

src/cipher.rs

+54-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustls::crypto::ring::{ALL_CIPHER_SUITES, DEFAULT_CIPHER_SUITES};
1515
use rustls::server::danger::ClientCertVerifier;
1616
use rustls::server::WebPkiClientVerifier;
1717
use rustls::sign::CertifiedKey;
18-
use rustls::{RootCertStore, SupportedCipherSuite};
18+
use rustls::{DistinguishedName, RootCertStore, SupportedCipherSuite};
1919
use rustls_pemfile::{certs, crls, pkcs8_private_keys, rsa_private_keys};
2020
use webpki::{RevocationCheckDepth, UnknownStatusPolicy};
2121

@@ -683,6 +683,7 @@ pub struct rustls_web_pki_client_cert_verifier_builder {
683683

684684
pub(crate) struct ClientCertVerifierBuilder {
685685
roots: Arc<RootCertStore>,
686+
root_hint_subjects: Vec<DistinguishedName>,
686687
crls: Vec<CertificateRevocationListDer<'static>>,
687688
revocation_depth: RevocationCheckDepth,
688689
revocation_policy: UnknownStatusPolicy,
@@ -724,6 +725,7 @@ impl rustls_web_pki_client_cert_verifier_builder {
724725
ffi_panic_boundary! {
725726
let store = try_clone_arc!(store);
726727
let builder = ClientCertVerifierBuilder {
728+
root_hint_subjects: store.subjects(),
727729
roots: store,
728730
crls: Vec::default(),
729731
revocation_depth: RevocationCheckDepth::Chain,
@@ -829,6 +831,52 @@ impl rustls_web_pki_client_cert_verifier_builder {
829831
}
830832
}
831833

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+
832880
/// Create a new client certificate verifier from the builder.
833881
///
834882
/// 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 {
858906
if client_verifier_builder.allow_unauthenticated {
859907
builder = builder.allow_unauthenticated();
860908
}
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+
}
861914

862915
let verifier = match builder.build() {
863916
Ok(v) => v,

src/rustls.h

+22
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,28 @@ rustls_result rustls_web_pki_client_cert_verifier_allow_unknown_revocation_statu
10701070
*/
10711071
rustls_result rustls_web_pki_client_cert_verifier_builder_allow_unauthenticated(struct rustls_web_pki_client_cert_verifier_builder *builder);
10721072

1073+
/**
1074+
* Clear the list of trust anchor hint subjects.
1075+
*
1076+
* By default, the client cert verifier will use the subjects provided by the root cert
1077+
* store configured for client authentication. Calling this function will remove these
1078+
* hint subjects, indicating the client should make a free choice of which certificate
1079+
* to send.
1080+
*/
1081+
rustls_result rustls_web_pki_client_cert_verifier_clear_root_hint_subjects(struct rustls_web_pki_client_cert_verifier_builder *builder);
1082+
1083+
/**
1084+
* Add additional distinguished names to the list of trust anchor hint subjects.
1085+
*
1086+
* By default, the client cert verifier will use the subjects provided by the root cert
1087+
* store configured for client authentication. Calling this function will add to these
1088+
* existing hint subjects. Calling this function with an empty `store` will have no
1089+
* effect, use `rustls_web_pki_client_cert_verifier_clear_root_hint_subjects` to clear
1090+
* the subject hints.
1091+
*/
1092+
rustls_result rustls_web_pki_client_cert_verifier_add_root_hint_subjects(struct rustls_web_pki_client_cert_verifier_builder *builder,
1093+
const struct rustls_root_cert_store *store);
1094+
10731095
/**
10741096
* Create a new client certificate verifier from the builder.
10751097
*

0 commit comments

Comments
 (0)