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

nordisk/holger

jobs/runner/src/accept.rs

//! **The caller's acceptance check**: the only way a job's result is believed.

use std::path::Path;

use heimdall_core::{JobResult, JobTicket, SignedResult, VerifyingKey};
use holger_errcode::ErrCode;

/// A result that is not believed, by name.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Rejected {
    pub code: &'static ErrCode,
    pub why: String,
}

impl std::fmt::Display for Rejected {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&self.code.tag(&self.why))
    }
}

impl std::error::Error for Rejected {}

/// ★ **Believe `signed`** only when it verifies with the PINNED key
/// ([`heimdall_core::verify`]: the format version, the key id, the signature over
/// Heimdall's canonical encoding, a well-formed result), it is the result of the job
/// `ticket` names (its id and its nonce: a result replayed from another run names
/// another), and `out` holds exactly the outputs it lists, each with its sha256 and size
/// ([`heimdall_core::check_outputs`]). Returns the result.
pub fn accept<'a>(
    signed: &'a SignedResult,
    key: &VerifyingKey,
    ticket: &JobTicket,
    out: &Path,
) -> Result<&'a JobResult, Rejected> {
    use holger_errcode::{SANDBOX_JOB_OUTPUTS_INVALID, SANDBOX_JOB_RESULT_REFUSED};
    let r = heimdall_core::verify(signed, key).map_err(|e| Rejected {
        code: &SANDBOX_JOB_RESULT_REFUSED,
        why: format!("the job's result is not believed: {e}"),
    })?;
    if r.job_id != ticket.job_id || r.nonce != ticket.nonce {
        return Err(Rejected {
            code: &SANDBOX_JOB_RESULT_REFUSED,
            why: format!("the signed result is the one of job {}, not of job {} that was run: a replayed result is not believed", r.job_id, ticket.job_id),
        });
    }
    heimdall_core::check_outputs(r, out).map_err(|e| Rejected {
        code: &SANDBOX_JOB_OUTPUTS_INVALID,
        why: e.to_string(),
    })?;
    Ok(r)
}