Skip to main content

holger_intel/
lib.rs

1//! # holger-intel — offline vulnerability intelligence
2//!
3//! Holger's secure side never touches the internet, so its advisory database
4//! has to cross the airgap the same way a firmware release does:
5//!
6//! ```text
7//!  ONLINE                                     │ AIRGAP │            SECURE
8//!  OSV all.zip ─┐                             │        │
9//!  NVD 2.0 ─────┼─ normalize ─ AdvisorySet ─ sign ─ USB ─ verify ─ floor ─ audit ─ local DB ─ scan
10//!  CISA KEV ────┘   (feeds)      (set)      (bundle)       (import)              (db)     (resolve)
11//! ```
12//!
13//! * **No new format.** An intel bundle IS a `holger.update-bundle/v1`, with
14//!   `product = holger.intel/v1` ([`INTEL_PRODUCT`]). The advisory set is its one
15//!   payload (`payload/advisories.json`); the per-feed source record is its
16//!   `Advisory` evidence. The release manifest hashes every member (SHA-256 +
17//!   BLAKE3), the release signature covers the manifest, and the same trust
18//!   policy, two-person rule, trusted clock and anti-rollback floor apply.
19//! * **Anti-rollback.** `core.sequence` is monotonic per
20//!   `(supplier, holger.intel/v1)`; [`import`] refuses a lower sequence, a
21//!   same-sequence replay with other bytes and an absent floor without
22//!   `first_import`, through `update-bundle`'s `RollbackStore`.
23//! * **Fail-closed audit.** [`import`] writes its audit record before the floor
24//!   moves and before the new set goes live; a sink that is off or fails refuses
25//!   the import and leaves the database as it was.
26//! * **Staleness.** The evidence names the bundle sequence and snapshot date;
27//!   [`stale::StalenessRule`] warns after N days and blocks after M.
28//! * **Offline proof.** [`net::IntelNet::offline`] refuses every URL. The
29//!   default build of this crate links no HTTP client at all; `fetch` adds
30//!   `ureq` for the online side only.
31
32pub mod bundle;
33pub mod db;
34pub mod feeds;
35pub mod import;
36pub mod net;
37pub mod resolve;
38pub mod set;
39/// Scanner signatures (ClamAV, YARA) as a signed bundle (lane HOL-NCSC).
40pub mod sigs;
41pub mod stale;
42pub mod subject;
43
44/// The time types the evidence and the staleness rule are written in.
45pub use chrono;
46/// The verdict engine and advisory model this crate carries, re-exported so a
47/// consumer scans with exactly these types.
48pub use modgunn;
49
50pub use bundle::{build_bundle, BuildOptions, BuiltBundle, SignerFiles};
51pub use db::{InstalledIntel, LocalIntelDb};
52pub use feeds::{FeedKind, FeedSpec, RawFeed};
53pub use import::{
54    commit, import, prepare, ImportAudit, ImportOutcome, ImportRecord, ImportRequest, Prepared,
55    PreparedImport, PREPARED_SCHEMA,
56};
57pub use net::{Fetch, IntelNet, NetError};
58pub use resolve::{
59    fold_staleness, resolve, resolve_local, scan_against, IntelEvidence, IntelScanner,
60    IntelSettings, IntelVerdict, LiveIntel, ResolvedAdvisories,
61};
62pub use set::{AdvisorySet, IntelAdvisory, SourceRecord};
63pub use stale::{Staleness, StalenessRule};
64
65/// The `core.product` every intel bundle carries. The anti-rollback floor is
66/// kept per `(supplier, product)`, so this is what makes the intel sequence its
67/// own monotonic line, separate from any firmware product.
68pub const INTEL_PRODUCT: &str = "holger.intel/v1";
69
70/// The supplier an intel bundle names when the builder is not told another.
71pub const DEFAULT_SUPPLIER: &str = "holger-intel";
72
73/// The bundle member that carries the normalized advisory set.
74pub const ADVISORIES_REL: &str = "advisories.json";
75
76/// Its media type.
77pub const ADVISORIES_MEDIA_TYPE: &str = "application/vnd.holger.intel-advisories+json";
78
79/// The evidence member that records, per feed, where it came from and its hash.
80pub const SOURCES_REL: &str = "intel-sources.json";