⎇ d0638350bf39c350b2d1d1858a8c8eb962240fa5
03_ukupacha/agora/agora-cli/examples/verificar_concesiones.rs
History
Who touched what
raw
feat: agora standalone — front-door de identidad federada y grafo de confianza
1//! Verifica las `*.cap.obj` de un directorio con la MISMA regla que el kernel:
2//! (1) la firma Ed25519 cierra sobre `mensaje_capacidad(bytecode, permisos)` y
3//! (2) el autor habita el `AGORA_AUTH_RING`. Da la prueba dura de que las
4//! concesiones de la ceremonia validan sin tener que bootear en estricto.
5//!
6//! cargo run -p agora-cli --example verificar_concesiones -- <dir> <pk0_hex> [pk1_hex pk2_hex]
7
8use std::path::Path;
9
10fn hex32(s: &str) -> [u8; 32] {
11 let s = s.trim();
12 let mut out = [0u8; 32];
13 for (i, b) in out.iter_mut().enumerate() {
14 *b = u8::from_str_radix(&s[i * 2..i * 2 + 2], 16).expect("hex de 64 chars");
15 }
16 out
17}
18
19fn main() {
20 let mut args = std::env::args().skip(1);
21 let dir = args.next().expect("uso: <dir> <pk0_hex> [pk1 pk2]");
22 let anillo: Vec<[u8; 32]> = args.map(|a| hex32(&a)).collect();
23 assert!(!anillo.is_empty(), "pasa al menos la pubkey del slot 0");
24
25 let mut ok = 0;
26 let mut fail = 0;
27 let mut entradas: Vec<_> = std::fs::read_dir(&dir)
28 .expect("dir de concesiones")
29 .flatten()
30 .map(|e| e.path())
31 .filter(|p| p.extension().map(|x| x == "obj").unwrap_or(false))
32 .collect();
33 entradas.sort();
34
35 for path in &entradas {
36 let nombre = path.file_stem().unwrap().to_string_lossy();
37 let bytes = std::fs::read(path).expect("leer .cap.obj");
38 // .cap.obj = Objeto{ datos: ConcesionCapacidad serializada }.
39 let obj = format::Objeto::deserializar(&bytes).expect("Objeto");
40 let c = format::ConcesionCapacidad::deserializar(&obj.datos).expect("ConcesionCapacidad");
41
42 let firma_ok = agora_channel::verificar_capacidad(&c).is_ok();
43 let autor_en_anillo = anillo.iter().any(|pk| *pk == c.autor);
44
45 let veredicto = if firma_ok && autor_en_anillo { "✓ ACEPTA" } else { "✗ RECHAZA" };
46 println!(
47 "{veredicto:10} {nombre:12} permisos={:#09b} firma={} autor_en_anillo={}",
48 c.permisos, firma_ok, autor_en_anillo
49 );
50 if firma_ok && autor_en_anillo {
51 ok += 1;
52 } else {
53 fail += 1;
54 }
55 }
56 println!("\n{ok} aceptadas · {fail} rechazadas · anillo con {} slot(s)", anillo.len());
57 if fail > 0 {
58 std::process::exit(1);
59 }
60 let _ = Path::new(&dir);
61}