Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/gunnar

crates/gunnar-server/tests/re_enrol_same_key.rs

//! **L1 (estate-box check 3, release-3 recharge): the twin's key enrolled AGAIN is not a new
//! key.**
//!
//! After a recharge the new main is restored from the twin's log, which already names
//! `gunnar-twin` and the twin's key. The front's pairing door certifies the twin against the new
//! main and enrols that same key again (`Access.AddKey`, the door's `tolerate`s "already
//! there"). The plane answered `FAILED_PRECONDITION principal gunnar-twin already holds 1
//! key(s), so adding another needs gunnar-twin's own attestation` — for the key it ALREADY
//! holds — so the certification never took again: 20+ attempts, each a `BecomeTwin`, and the
//! twin never re-pinned the new main (MEASURED: attempts 12–23, 02:54–02:59). The key a
//! principal already holds is `ALREADY_EXISTS`; a DIFFERENT key still needs the attestation.

use std::sync::Arc;

use gunnar_grpc::{ControlError, ControlPlane as _};
use gunnar_server::stores::ServerStores;
use gunnar_server::CoreControlPlane;

fn key_line() -> String {
    let pem = gunnar_core::mint_ed25519().expect("mint");
    let key = gunnar_core::ssh_key::PrivateKey::from_openssh(std::str::from_utf8(&pem).unwrap())
        .expect("parse");
    key.public_key().to_openssh().expect("public line")
}

#[test]
fn the_key_a_principal_already_holds_is_already_there_and_another_still_needs_its_word() {
    let d = tempfile::tempdir().unwrap();
    let stores = Arc::new(ServerStores::open(d.path()).unwrap());
    let plane = CoreControlPlane::new(Arc::clone(&stores));
    plane
        .add_principal(
            "gunnar-twin",
            "gunnar-twin",
            gunnar_proto::PrincipalKind::Machine,
        )
        .expect("the principal");
    let twin_key = key_line();
    plane
        .add_key(
            "gunnar-twin",
            &twin_key,
            "the twin's key",
            None,
            "console",
            None,
        )
        .expect("the first key needs nobody's word");
    match plane.add_key(
        "gunnar-twin",
        &twin_key,
        "the twin's key, enrolled again",
        None,
        "console",
        None,
    ) {
        Err(ControlError::AlreadyExists(_)) => {}
        other => panic!(
            "the same key again must be ALREADY_EXISTS (the door tolerates it), got {other:?}"
        ),
    }
    assert_eq!(
        plane.list_keys(Some("gunnar-twin")).unwrap().len(),
        1,
        "nothing was added"
    );
    match plane.add_key(
        "gunnar-twin",
        &key_line(),
        "a stranger's key",
        None,
        "console",
        None,
    ) {
        Err(ControlError::FailedPrecondition(why)) => assert!(why.contains("attestation"), "{why}"),
        other => panic!("another key still needs the holder's attestation, got {other:?}"),
    }
}