attestation-validator 0.2.0

Validates attestation certificate chains and inspects attestation certificates
Documentation
# Attestation Validator

[![CI](https://gitlab.archlinux.org/wiktor/attestation-validator/badges/main/pipeline.svg)](https://gitlab.archlinux.org/wiktor/attestation-validator/badges/main/pipeline.svg)
[![Crates.io](https://img.shields.io/crates/v/attestation-validator)](https://crates.io/crates/attestation-validator)

Validates attestation certificate chains and inspects attestation certificates.

Install it via cargo:

```sh no_run
cargo install --locked attestation-validator
```

## YubiHSM2

Validate and inspect YubiHSM2 attestation certificate:

```sh
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.

```rust
# 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](https://support.yubico.com/hc/en-us/articles/360016649139-YubiKey-5-2-enhancements-to-OpenPGP-3-4-support#h.6dll45vqhv8g) provide cryptographic attestations, which are also supported:

```sh
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:

```text
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](https://crates.io/crates/openpgp-card-tools) instead:

```sh no_run
# 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`](https://developers.yubico.com/yubico-piv-tool/Attestation.html) to generate attestation certificates and retrieve intermediate ones:

```sh no_run
# 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:

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

Which should display the following text:

```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:

  - [Apache License, Version 2.0]https://www.apache.org/licenses/LICENSE-2.0,
  - [MIT license]https://opensource.org/licenses/MIT.

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.