89 lines
3.1 KiB
Rust
89 lines
3.1 KiB
Rust
use rpki::ccr::{decode_content_info, verify::verify_content_info, verify_against_report_json_path, verify_against_vcir_store_path};
|
|
|
|
#[derive(Debug, Default, PartialEq, Eq)]
|
|
struct Args {
|
|
ccr_path: Option<std::path::PathBuf>,
|
|
report_json: Option<std::path::PathBuf>,
|
|
db_path: Option<std::path::PathBuf>,
|
|
}
|
|
|
|
fn usage() -> &'static str {
|
|
"Usage: ccr_verify --ccr <path> [--report-json <path>] [--db <path>]"
|
|
}
|
|
|
|
fn parse_args(argv: &[String]) -> Result<Args, String> {
|
|
let mut args = Args::default();
|
|
let mut i = 1usize;
|
|
while i < argv.len() {
|
|
match argv[i].as_str() {
|
|
"--help" | "-h" => return Err(usage().to_string()),
|
|
"--ccr" => {
|
|
i += 1;
|
|
let v = argv.get(i).ok_or("--ccr requires a value")?;
|
|
args.ccr_path = Some(v.into());
|
|
}
|
|
"--report-json" => {
|
|
i += 1;
|
|
let v = argv.get(i).ok_or("--report-json requires a value")?;
|
|
args.report_json = Some(v.into());
|
|
}
|
|
"--db" => {
|
|
i += 1;
|
|
let v = argv.get(i).ok_or("--db requires a value")?;
|
|
args.db_path = Some(v.into());
|
|
}
|
|
other => return Err(format!("unknown argument: {other}\n{}", usage())),
|
|
}
|
|
i += 1;
|
|
}
|
|
if args.ccr_path.is_none() {
|
|
return Err(format!("--ccr is required\n{}", usage()));
|
|
}
|
|
Ok(args)
|
|
}
|
|
|
|
fn main() -> Result<(), String> {
|
|
let args = parse_args(&std::env::args().collect::<Vec<_>>())?;
|
|
let ccr_path = args.ccr_path.as_ref().unwrap();
|
|
let bytes = std::fs::read(ccr_path).map_err(|e| format!("read ccr failed: {}: {e}", ccr_path.display()))?;
|
|
let ci = decode_content_info(&bytes).map_err(|e| e.to_string())?;
|
|
let summary = verify_content_info(&ci).map_err(|e| e.to_string())?;
|
|
if let Some(report_json) = args.report_json.as_ref() {
|
|
verify_against_report_json_path(&ci, report_json).map_err(|e| e.to_string())?;
|
|
}
|
|
if let Some(db_path) = args.db_path.as_ref() {
|
|
verify_against_vcir_store_path(&ci, db_path).map_err(|e| e.to_string())?;
|
|
}
|
|
println!("{}", serde_json::to_string_pretty(&summary).map_err(|e| e.to_string())?);
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn parse_args_accepts_all_flags() {
|
|
let argv = vec![
|
|
"ccr_verify".to_string(),
|
|
"--ccr".to_string(),
|
|
"a.ccr".to_string(),
|
|
"--report-json".to_string(),
|
|
"report.json".to_string(),
|
|
"--db".to_string(),
|
|
"db".to_string(),
|
|
];
|
|
let args = parse_args(&argv).expect("parse");
|
|
assert_eq!(args.ccr_path.as_deref(), Some(std::path::Path::new("a.ccr")));
|
|
assert_eq!(args.report_json.as_deref(), Some(std::path::Path::new("report.json")));
|
|
assert_eq!(args.db_path.as_deref(), Some(std::path::Path::new("db")));
|
|
}
|
|
|
|
#[test]
|
|
fn parse_args_rejects_missing_required_ccr() {
|
|
let argv = vec!["ccr_verify".to_string()];
|
|
let err = parse_args(&argv).unwrap_err();
|
|
assert!(err.contains("--ccr is required"), "{err}");
|
|
}
|
|
}
|