| Crates.io | attestation-validator |
| lib.rs | attestation-validator |
| version | 0.2.0 |
| created_at | 2025-10-21 15:17:23.22989+00 |
| updated_at | 2025-12-15 11:50:39.822515+00 |
| description | Validates attestation certificate chains and inspects attestation certificates |
| homepage | |
| repository | https://gitlab.archlinux.org/wiktor/attestation-validator |
| max_upload_size | |
| id | 1893998 |
| size | 127,680 |
Validates attestation certificate chains and inspects attestation certificates.
Install it via cargo:
cargo install --locked attestation-validator
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(()) }
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
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]
This project is licensed under either of:
at your option.
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.