attestation-validator

Crates.ioattestation-validator
lib.rsattestation-validator
version0.2.0
created_at2025-10-21 15:17:23.22989+00
updated_at2025-12-15 11:50:39.822515+00
descriptionValidates attestation certificate chains and inspects attestation certificates
homepage
repositoryhttps://gitlab.archlinux.org/wiktor/attestation-validator
max_upload_size
id1893998
size127,680
Heiko Schaefer (hko-s)

documentation

README

Attestation Validator

CI Crates.io

Validates attestation certificate chains and inspects attestation certificates.

Install it via cargo:

cargo install --locked attestation-validator

YubiHSM2

Validate and inspect YubiHSM2 attestation certificate:

attestation-validator src/yubico/yubihsm2-attest-ca-crt-pem src/yubico/intermediate-pem hsm-attestation-cert.cer hsm-attestation-pem

Each filename represents the next link in the chain. The entire chain is validated, and the extensions of the final certificate are displayed.

# fn main() -> testresult::TestResult {
use std::io::Cursor;
use std::fs::File;

use attestation_validator::Validator;
use attestation_validator::yubico::yubihsm2::{ROOT_CA_PEM, INTERMEDIATE_PEM, YubiHsmAttestation};

let mut validator = Validator::default();
validator.add_from_pem(Cursor::new(ROOT_CA_PEM))?;
validator.add_from_pem(Cursor::new(INTERMEDIATE_PEM))?;

let binding = std::fs::read("hsm-attestation-cert.cer")?;
validator.add_from_der(binding)?;

validator.add_from_pem(File::open("hsm-attestation-pem")?)?;

eprintln!(
    "Extensions: {:#?}",
    YubiHsmAttestation::new(&validator.leaf_extensions()?)?
);

eprintln!("Raw public key (DER): {:?}", validator.leaf_public_key()?);
# Ok(()) }

Yubikey OpenPGP

Yubikeys with firmware version 5.2 or later provide cryptographic attestations, which are also supported:

attestation-validator src/yubico/yubico-opgp-ca-1-pem openpgp-card-pem key-statement-pem

After successful validation, the tool outputs a summary of the attestation:

OpenPGP Attestation: Yubikey OpenPGP Attestation for device with serial number 15422467
Firmware version: 5.2.7
Cardholder's name: Kwapisiewicz<<Wiktor
Key source: Generated on device
Key fingerprint: 0c7c54912fd932bcdf13726a767ce224db311b3c
Key generated 1693222243 seconds from the Unix Epoch
Number of signatures made: 1
User Interaction Flag: Touch permanent
Device form factor: USB-C Keychain

Raw public key (DER): [48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0, 35, 202, 154, 6, 98, 200, 28, 76, 24, 186, 86, 56, 6, 34, 47, 157, 23, 58, 224, 104, 48, 208, 213, 230, 50, 150, 106, 230, 204, 96, 102, 61]

Retrieving attestation statements from the card is outside the scope of this crate. Use OpenPGP Card tools instead:

# retrieve token-specific attestation certificate
oct attestation cert > openpgp-card-pem

# the statement needs to be generated only once
oct attestation generate --key SIG

# retrieve the generated statement
oct attestation statement --key SIG > key-statement-pem

Yubikey PIV

PIV applet on Yubikeys can also attest keys. Use yubico-piv-tool to generate attestation certificates and retrieve intermediate ones:

# retrieve token-specific attestation certificate
yubico-piv-tool --action=read-certificate --slot=f9 --out SlotF9Intermediate.pem

# generate attestation certificate
yubico-piv-tool --action=attest --slot=9c --out Slot9Cattestation.pem

Then, the attestation can be validated and displayed via:

attestation-validator src/yubico/yubico-piv-ca-1-pem SlotF9Intermediate-pem Slot9Cattestation-pem

Which should display the following text:

PIV Attestation: Yubikey PIV Attestation for device with serial number 15422467
Firmware version: 5.2.7
PIN Policy: Always
Touch Policy: Never
Device form factor: USB-C Keychain

Raw public key (DER): [48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 3, 1, 7, 3, 66, 0, 4, 13, 27, 211, 90, 222, 70, 12, 190, 142, 83, 139, 10, 166, 40, 48, 202, 197, 78, 203, 27, 241, 157, 173, 194, 88, 45, 72, 48, 172, 96, 41, 149, 128, 184, 254, 101, 107, 86, 165, 246, 21, 137, 83, 223, 166, 217, 242, 175, 217, 2, 109, 158, 3, 32, 32, 2, 252, 106, 130, 254, 206, 62, 137, 60]

License

This project is licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 0

cargo fmt