Skip to content

Commit 0b7c359

Browse files
committed
control root hint subjects w/ client verifier builder
1 parent 15aece4 commit 0b7c359

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

@@ -679,6 +679,7 @@ pub struct rustls_web_pki_client_cert_verifier_builder {
679679

680680
pub(crate) struct ClientCertVerifierBuilder {
681681
roots: Arc<RootCertStore>,
682+
root_hint_subjects: Vec<DistinguishedName>,
682683
crls: Vec<CertificateRevocationListDer<'static>>,
683684
revocation_depth: RevocationCheckDepth,
684685
revocation_policy: UnknownStatusPolicy,
@@ -720,6 +721,7 @@ impl rustls_web_pki_client_cert_verifier_builder {
720721
ffi_panic_boundary! {
721722
let store = try_arc_from_ptr!(store);
722723
let builder = ClientCertVerifierBuilder {
724+
root_hint_subjects: store.subjects(),
723725
roots: store,
724726
crls: Vec::default(),
725727
revocation_depth: RevocationCheckDepth::Chain,
@@ -822,6 +824,52 @@ impl rustls_web_pki_client_cert_verifier_builder {
822824
}
823825
}
824826

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+
825873
/// Create a new client certificate verifier from the builder.
826874
///
827875
/// 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 {
849897
if client_verifier_builder.allow_anonymous {
850898
builder = builder.allow_unauthenticated();
851899
}
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+
}
852905

853906
let verifier = match builder.build() {
854907
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 empty `subjects` 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)