Skip to content

Commit

Permalink
verifier: Refactor reusable bits verifier-cli into a library.
Browse files Browse the repository at this point in the history
  • Loading branch information
flihp committed Dec 23, 2023
1 parent afb06ff commit f1aa508
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 31 deletions.
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions verifier-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ p384 = { workspace = true, default-features = true }
pem-rfc7468 = { workspace = true, features = ["alloc", "std"] }
sha3.workspace = true
tempfile.workspace = true
verifier.path = "../verifier"
x509-cert = { workspace = true, default-features = true }
36 changes: 5 additions & 31 deletions verifier-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

mod pki_path;

use anyhow::{anyhow, Context, Result};
use attest_data::{Attestation, Nonce};
use clap::{Parser, Subcommand, ValueEnum};
use ed25519_dalek::{Signature, Verifier, VerifyingKey};
use env_logger::Builder;
use log::{debug, error, info, warn, LevelFilter};
use pem_rfc7468::{LineEnding, PemLabel};
use pki_path::PkiPathSignatureVerifier;
use sha3::{Digest, Sha3_256};
use std::{
fmt::{self, Debug, Formatter},
Expand All @@ -21,6 +17,7 @@ use std::{
process::{Command, Output},
};
use tempfile::NamedTempFile;
use verifier::PkiPathSignatureVerifier;
use x509_cert::{
der::{Decode, DecodePem},
Certificate, PkiPath,
Expand Down Expand Up @@ -479,33 +476,16 @@ fn main() -> Result<()> {
log,
nonce,
} => {
// To verify an attestation we need to extract and construct a few
// things before we can verify the attestation:
// - signature: the attestation produced by the RoT when
// `alias_priv` is used to sign `message`
let attestation = fs::read(attestation)?;
let (attestation, _): (Attestation, _) =
hubpack::deserialize(&attestation).map_err(|e| {
anyhow!("Failed to deserialize Attestation: {}", e)
})?;
let signature = match attestation {
Attestation::Ed25519(s) => Signature::from_bytes(&s.0),
};

// - log_data: the hubpack encoded measurement log `hubpack(log)`
let log = fs::read(log)?;
// - nonce: nonce provided to RoT when the attestation provided
// was collected
let nonce = fs::read(nonce)?;

// - message: the data that's signed by the RoT to produce an
// attestation `sha3_256(log_data | nonce)`
let mut message = Sha3_256::new();
message.update(log);
message.update(nonce);
let message = message.finalize();
let nonce: Nonce = fs::read(nonce)?.try_into()?;

// - verifier: public key / `alias_pub` from pair used to sign the attestation
let alias = fs::read(alias_cert)?;
let alias = match pem_rfc7468::decode_vec(&alias) {
Ok((l, v)) => {
Expand All @@ -521,16 +501,10 @@ fn main() -> Result<()> {
alias
}
};

let alias = Certificate::from_der(&alias)?;
let alias = alias
.tbs_certificate
.subject_public_key_info
.subject_public_key
.as_bytes()
.ok_or_else(|| anyhow!("Invalid / unaligned public key"))?;

let verifying_key = VerifyingKey::from_bytes(alias.try_into()?)?;
verifying_key.verify(message.as_slice(), &signature)?;

verifier::verify_attestation(&alias, &attestation, &log, &nonce)?;
}
AttestCommand::VerifyCertChain {
cert_chain,
Expand Down
18 changes: 18 additions & 0 deletions verifier/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "verifier"
version = "0.1.0"
edition = "2021"
description = "a library crate implementing the attestation verifier"
license = "MPL-2.0"

[dependencies]
anyhow = { workspace = true, features = ["std"] }
attest-data = { path = "../attest-data", features = ["std"] }
const-oid = { workspace = true, features = ["db"] }
ed25519-dalek = { workspace = true, features = ["std"] }
env_logger.workspace = true
log.workspace = true
p384 = { workspace = true, default-features = true }
pem-rfc7468 = { workspace = true, features = ["alloc", "std"] }
sha3.workspace = true
x509-cert = { workspace = true, default-features = true }
37 changes: 37 additions & 0 deletions verifier-cli/src/pki_path.rs → verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use anyhow::{anyhow, Result};
use attest_data::{Attestation, Nonce};
use const_oid::db::{rfc5912::ID_EC_PUBLIC_KEY, rfc8410::ID_ED_25519};
use sha3::{Digest, Sha3_256};
use x509_cert::{der::Encode, Certificate, PkiPath};

/// Unit-like struct with a single non-member associated function. This
Expand Down Expand Up @@ -225,3 +227,38 @@ impl PkiPathSignatureVerifier {
}
}
}

pub fn verify_attestation(
alias: &Certificate,
attestation: &Attestation,
log: &[u8],
nonce: &Nonce,
) -> Result<()> {
use ed25519_dalek::{Signature, Verifier, VerifyingKey};

// To verify an attestation we need to extract and construct a few
// things before we can verify the attestation:
// - signature: the attestation produced by the RoT when
// `alias_priv` is used to sign `message`
let signature = match attestation {
Attestation::Ed25519(s) => Signature::from_bytes(&s.0),
};

// - message: the data that's signed by the RoT to produce an
// attestation `sha3_256(log | nonce)`
let mut message = Sha3_256::new();
message.update(log);
message.update(nonce);
let message = message.finalize();

let alias = alias
.tbs_certificate
.subject_public_key_info
.subject_public_key
.as_bytes()
.ok_or_else(|| anyhow!("Invalid / unaligned public key"))?;

let verifying_key = VerifyingKey::from_bytes(alias.try_into()?)?;
verifying_key.verify(message.as_slice(), &signature)?;
todo!("verify_attestation");
}

0 comments on commit f1aa508

Please sign in to comment.