Mudrit
Cookbook

Inspection & Key Selection

Parse certificate details, filter certificates headlessly, and branch on typed key-management errors — offline, no signing

Before (or instead of) signing, three things a UI or a headless service needs: read a human-readable view of a certificate, pick the right certificate out of several without a human in the loop, and turn a key-management failure into a precise UI decision. None of these recipes sign a PDF, and none touch the network. Each is a self-contained snippet for your own project; see Cookbook for how they're written.

Recipes

RecipeWhat it showsFeature
cert_inspectparse_certificateCertDetails (subject/issuer/validity/key-usage/thumbprints)pfx
cert_filterCertFilter content predicates (rsa_only/exclude_ca/require_non_repudiation/thumbprint_eq/eku_contains)pfx
error_handlingBranch on the typed Error enum (wrong password, WrongPin{..}, PinLocked, Cancelled)pfx

Certificate details

Any Signer — PFX, PKCS#11, Windows store, or your own — exposes its leaf certificate (and chain) as DER via certificate() / chain(). parse_certificate turns that DER into a display-ready CertDetails, backend-agnostic: feed it a PKCS#11 token's cert DER or a Windows-store cert the same way.

use mudrit::{parse_certificate, prelude::*, CertDetails};

let signer = PfxSigner::from_file("signer.pfx", "password")?;

let details: Option<CertDetails> = parse_certificate(signer.certificate());
if let Some(d) = details {
    println!("{}  issuer={}  valid {} .. {}", d.subject_cn, d.issuer_cn, d.not_before, d.not_after);
    println!("key={}  sha256={}", d.public_key, d.sha256);
}

Repo example: cert_inspect — ships with the licensed source bundle. See the Certificates guide.

Choosing the right certificate

A token (or the Windows store) often carries several certificates — a signing cert, an encryption cert, CA/intermediate certs. CertFilter picks exactly the one you want, headlessly, and the same filter type is accepted by Pkcs11Manager::list_certificates, WinStoreKeyStore, and the pickers.

use mudrit::prelude::*;

// realistic headless DSC selector: RSA, not a CA, not-yet-valid excluded
let filter = CertFilter::any().rsa_only(true).exclude_ca(true).exclude_not_yet_valid(true);
let kept   = filter.content_ok(signer.certificate()); // DER-only predicates, no backend needed

// or pin to one exact certificate by thumbprint
let filter = CertFilter::any().thumbprint_eq("AA:BB:CC:...");

content_ok runs the content-only predicates (no backend needed): exclude_ca, require_non_repudiation, exclude_not_yet_valid, rsa_only, eku_contains, thumbprint_eq. CertFilter::default() additionally checks private-key usability, expiry, and signing capability — those are applied by each backend during enumeration, since they sometimes need OS/token APIs.

Repo example: cert_filter (source bundle).

Typed errors, not message strings

mudrit_keystore::Error is a #[non_exhaustive] enum, so a UI can react precisely — a wrong PFX password, a cancelled picker, a token PIN close to locking, a locked PIN.

use mudrit::mudrit_keystore::Error as KsError;

match PfxSigner::from_file("signer.pfx", "wrong-password") {
    Ok(_) => { /* signer ready */ }
    Err(KsError::WrongPassword) => { /* re-prompt for the password */ }
    Err(KsError::WrongPin { final_try: true, .. }) => { /* warn: LAST attempt before lockout */ }
    Err(KsError::WrongPin { count_low: true, .. }) => { /* strong warning, few attempts remain */ }
    Err(KsError::PinLocked) => { /* stop retrying; tell the user to unlock the device */ }
    Err(KsError::Cancelled) => { /* user cancelled the picker — abort quietly */ }
    Err(_other) => { /* `_` arm required: the enum is #[non_exhaustive] */ }
}

Repo example: error_handling (source bundle). See the Errors guide.

Test cert only, fully offline

The source-bundle programs run against the bundled samples/ABC12.pfx test certificate with no network access — supply your own DSC in your project. The error_handling program also accepts optional PKCS#11 arguments to exercise the token PIN paths against a real device, the only path that touches hardware.

Next

On this page