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

nordisk/holger

intel/src/lib.rs

//! # holger-intel — offline vulnerability intelligence
//!
//! Holger's secure side never touches the internet, so its advisory database
//! has to cross the airgap the same way a firmware release does:
//!
//! ```text
//!  ONLINE                                     │ AIRGAP │            SECURE
//!  OSV all.zip ─┐                             │        │
//!  NVD 2.0 ─────┼─ normalize ─ AdvisorySet ─ sign ─ USB ─ verify ─ floor ─ audit ─ local DB ─ scan
//!  CISA KEV ────┘   (feeds)      (set)      (bundle)       (import)              (db)     (resolve)
//! ```
//!
//! * **No new format.** An intel bundle IS a `holger.update-bundle/v1`, with
//!   `product = holger.intel/v1` ([`INTEL_PRODUCT`]). The advisory set is its one
//!   payload (`payload/advisories.json`); the per-feed source record is its
//!   `Advisory` evidence. The release manifest hashes every member (SHA-256 +
//!   BLAKE3), the release signature covers the manifest, and the same trust
//!   policy, two-person rule, trusted clock and anti-rollback floor apply.
//! * **Anti-rollback.** `core.sequence` is monotonic per
//!   `(supplier, holger.intel/v1)`; [`import`] refuses a lower sequence, a
//!   same-sequence replay with other bytes and an absent floor without
//!   `first_import`, through `update-bundle`'s `RollbackStore`.
//! * **Fail-closed audit.** [`import`] writes its audit record before the floor
//!   moves and before the new set goes live; a sink that is off or fails refuses
//!   the import and leaves the database as it was.
//! * **Staleness.** The evidence names the bundle sequence and snapshot date;
//!   [`stale::StalenessRule`] warns after N days and blocks after M.
//! * **Offline proof.** [`net::IntelNet::offline`] refuses every URL. The
//!   default build of this crate links no HTTP client at all; `fetch` adds
//!   `ureq` for the online side only.

pub mod bundle;
pub mod db;
pub mod feeds;
pub mod import;
/// The intel a Holger install medium ships (row HOL-INTEL-ON-MEDIA).
pub mod media;
pub mod net;
pub mod resolve;
pub mod set;
/// Scanner signatures (ClamAV, YARA) as a signed bundle (lane HOL-NCSC).
pub mod sigs;
pub mod stale;
pub mod subject;
/// The supply-chain section of the set (Holger 3.2 phase B): popular names per ecosystem.
pub mod supply;

/// The time types the evidence and the staleness rule are written in.
pub use chrono;
/// The verdict engine and advisory model this crate carries, re-exported so a
/// consumer scans with exactly these types.
pub use modgunn;

pub use bundle::{build_bundle, BuildOptions, BuiltBundle, SignerFiles};
pub use db::{InstalledIntel, LocalIntelDb};
pub use feeds::{FeedKind, FeedSpec, RawFeed};
pub use import::{
    commit, import, prepare, ImportAudit, ImportOutcome, ImportRecord, ImportRequest, Prepared,
    PreparedImport, PREPARED_SCHEMA,
};
pub use net::{Fetch, IntelNet, NetError};
pub use resolve::{
    fold_staleness, resolve, resolve_local, scan_against, IntelEvidence, IntelScanner,
    IntelSettings, IntelVerdict, LiveIntel, ResolvedAdvisories,
};
pub use set::{AdvisorySet, IntelAdvisory, SourceRecord};
pub use stale::{Staleness, StalenessRule};
pub use supply::SupplyIntel;

/// The `core.product` every intel bundle carries. The anti-rollback floor is
/// kept per `(supplier, product)`, so this is what makes the intel sequence its
/// own monotonic line, separate from any firmware product.
pub const INTEL_PRODUCT: &str = "holger.intel/v1";

/// The supplier an intel bundle names when the builder is not told another.
pub const DEFAULT_SUPPLIER: &str = "holger-intel";

/// The bundle member that carries the normalized advisory set.
pub const ADVISORIES_REL: &str = "advisories.json";

/// Its media type.
pub const ADVISORIES_MEDIA_TYPE: &str = "application/vnd.holger.intel-advisories+json";

/// The evidence member that records, per feed, where it came from and its hash.
pub const SOURCES_REL: &str = "intel-sources.json";