Certificates
Inspect certificates with parse_certificate and CertDetails, then narrow a listing with CertFilter's predicates
Two jobs sit in front of every signature: inspect a certificate to show the user what they are about to sign with, and filter a store or token down to the right certificate. Both are always available — no backend feature required.
Inspect — parse_certificate → CertDetails
parse_certificate(der) parses a DER certificate into the display-ready fields a "view certificate"
UI shows, or None if the bytes are not a valid certificate.
use mudrit_keystore::{parse_certificate, CertDetails};
if let Some(d) = parse_certificate(signer.certificate()) {
println!("Subject : {}", d.subject_cn);
println!("Issuer : {}", d.issuer_cn);
println!("Valid : {} → {}", d.not_before, d.not_after);
println!("Usage : {}", d.key_usage.join(", "));
println!("SHA-256 : {}", d.sha256);
}CertDetails fields:
| Field | Contents |
|---|---|
subject, subject_cn, subject_org | Full subject DN, plus the parsed CN and O |
issuer, issuer_cn | Full issuer DN, plus its CN |
serial | Hex serial number |
version, signature_algorithm | Certificate version and signing algorithm (friendly name) |
not_before, not_after | Validity window |
public_key | Key description, e.g. RSA 2048-bit or EC (elliptic curve) |
key_usage | KeyUsage bits, e.g. Digital Signature, Non-Repudiation |
extended_key_usage | EKU entries (friendly names where known) |
san | Subject Alternative Names (email / DNS / URI / directory) |
sha1, sha256 | Thumbprints (colon-separated hex) |
Filter — CertFilter
CertFilter decides which certificates a picker or listing includes. Start from one of two bases and
chain the predicates:
CertFilter::default()— usable, in-date, end-entity RSA keys: excludes broken/missing keysets, expired or not-yet-valid certs, CA certs, and non-RSA keys. (Does not force signing-only or non-repudiation; chain those on.)CertFilter::any()— no filtering: every certificate in the store, CA certs, expired and non-RSA included.
use mudrit_keystore::CertFilter;
let f = CertFilter::default()
.signing_only(true)
.issuer_contains("Capricorn")
.require_non_repudiation(true);Every predicate:
| Predicate | Keeps certificates that… |
|---|---|
require_private_key(v) | have a private-key reference (cheap check) |
require_usable_key(v) | have an actually usable private key (opens it; skips "keyset missing" certs) |
exclude_expired(v) | are inside their notBefore..notAfter window |
signing_only(v) | permit digital-signature / non-repudiation by KeyUsage (no-KeyUsage certs kept) |
subject_contains(s) | have a subject containing s |
issuer_contains(s) | have an issuer containing s |
exclude_ca(v) | are not CA certs (BasicConstraints cA=TRUE or KeyUsage keyCertSign) |
require_non_repudiation(v) | assert the nonRepudiation KeyUsage bit |
exclude_not_yet_valid(v) | do not have a notBefore in the future |
rsa_only(v) | are RSA (excludes ECDSA and other key types) |
eku_contains(oid) | have an Extended Key Usage containing the OID substring oid |
thumbprint_eq(hex) | match this SHA-1 or SHA-256 thumbprint (case / : / space insensitive) |
Indian dual-key DSCs — pick the Signature cert
An Indian DSC token typically carries two certificates: a Signature certificate (asserting the
nonRepudiation KeyUsage bit) and an Encryption certificate. For signing you want the first.
require_non_repudiation(true) keeps only the certificate whose KeyUsage asserts nonRepudiation —
the legally-binding "signature" bit — so it selects the Signature cert over the Encryption one.
Where predicates are applied
The content-only predicates (exclude_ca, require_non_repudiation, exclude_not_yet_valid,
rsa_only, eku_contains, thumbprint_eq) are evaluated purely from the certificate DER by
content_ok(der). Expiry, KeyUsage signing, subject/issuer substrings, and private-key presence
need OS/token APIs, so each backend applies those itself during enumeration.