Skip to content

Commit 0700a45

Browse files
committed
control root hint subjects w/ client verifier builder
1 parent b9af9f8 commit 0700a45

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

@@ -685,6 +685,7 @@ pub struct rustls_web_pki_client_cert_verifier_builder {
685685

686686
pub(crate) struct ClientCertVerifierBuilder {
687687
roots: Arc<RootCertStore>,
688+
root_hint_subjects: Vec<DistinguishedName>,
688689
crls: Vec<CertificateRevocationListDer<'static>>,
689690
revocation_depth: RevocationCheckDepth,
690691
revocation_policy: UnknownStatusPolicy,
@@ -726,6 +727,7 @@ impl rustls_web_pki_client_cert_verifier_builder {
726727
ffi_panic_boundary! {
727728
let store = try_clone_arc!(store);
728729
let builder = ClientCertVerifierBuilder {
730+
root_hint_subjects: store.subjects(),
729731
roots: store,
730732
crls: Vec::default(),
731733
revocation_depth: RevocationCheckDepth::Chain,
@@ -831,6 +833,52 @@ impl rustls_web_pki_client_cert_verifier_builder {
831833
}
832834
}
833835

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+
834882
/// Create a new client certificate verifier from the builder.
835883
///
836884
/// 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 {
860908
if client_verifier_builder.allow_unauthenticated {
861909
builder = builder.allow_unauthenticated();
862910
}
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+
}
863916

864917
let verifier = match builder.build() {
865918
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)