Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ shellitem = "0.2"
# Common USB VID->vendor facts are KNOWLEDGE (forensicnomicon), not reader data.
# Path dep during the coordinated in-flight change; switch to the registry version
# once forensicnomicon publishes the usb_vendors release (bottom-up, ADR-0006).
forensicnomicon-core = { version = "1.4", path = "../../../knowledge/forensicnomicon/crates/core" }
forensicnomicon-core = { version = "1.4" }

[lints]
workspace = true
60 changes: 60 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,64 @@ mod tests {
);
assert_eq!(Stamp::inferred(10).confidence, Confidence::Inferred);
}

/// A connection carrying only the ids the name lookups read. Every other
/// field is empty on purpose: these two methods must not depend on them.
fn connection(vid: Option<u16>, pid: Option<u16>) -> DeviceConnection {
DeviceConnection {
bus: Bus::Usb,
device_class_guid: None,
vid,
pid,
device_serial: None,
serial_is_os_generated: false,
friendly_name: None,
device_instance_id: String::new(),
first_install: None,
last_install: None,
last_arrival: None,
last_removal: None,
parent_id_prefix: None,
volume_guid: None,
drive_letter: None,
volume_serial: None,
disk_signature: None,
dma_capable: false,
mitre: Vec::new(),
source: Provenance {
file: String::new(),
line: 0,
key_path: None,
},
}
}

const IDS: &str = "0781 SanDisk Corp.\n\t5583 Ultra Fit\n";

#[test]
fn vendor_name_resolves_a_known_vid_and_stays_none_otherwise() {
let db = crate::usb_ids::UsbIdDb::parse(IDS);
assert_eq!(
connection(Some(0x0781), None).vendor_name(&db),
Some("SanDisk Corp.")
);
// Unknown vid: the lookup misses rather than inventing a name.
assert_eq!(connection(Some(0xFFFF), None).vendor_name(&db), None);
// Absent vid: nothing to look up.
assert_eq!(connection(None, None).vendor_name(&db), None);
}

#[test]
fn product_name_needs_both_ids() {
let db = crate::usb_ids::UsbIdDb::parse(IDS);
assert_eq!(
connection(Some(0x0781), Some(0x5583)).product_name(&db),
Some("Ultra Fit")
);
// Each half alone falls to the `_ => None` arm: a pid without its vid is
// not a product key, and a vid alone does not name a product.
assert_eq!(connection(Some(0x0781), None).product_name(&db), None);
assert_eq!(connection(None, Some(0x5583)).product_name(&db), None);
assert_eq!(connection(None, None).product_name(&db), None);
}
}
34 changes: 34 additions & 0 deletions core/src/usb_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,38 @@ C 00 (Defined at Interface level)\n\
assert_eq!(db.vendor_name(0x0781), Some("SanDisk Corp."));
assert!(db.vendor_count() >= 20);
}

#[test]
fn interface_lines_are_skipped_not_read_as_products() {
// Two leading tabs is an interface line inside a product. Reading it as
// a product would register 0x0781:0x0000 "Mass Storage" — a device that
// does not exist. Real usb.ids nests these under most storage devices.
let db = UsbIdDb::parse("0781 SanDisk Corp.\n\t5583 Ultra Fit\n\t\t00 Mass Storage\n");
assert_eq!(db.product_name(0x0781, 0x5583), Some("Ultra Fit"));
assert_eq!(db.product_name(0x0781, 0x0000), None);
}

#[test]
fn four_hex_chars_alone_do_not_make_an_id_line() {
// Both lines open with four valid hex characters and are still rejected,
// so they exercise the separator check rather than the hex parse — the
// section headers in FIXTURE (`C 00`) fail earlier, at the hex step.
let db = UsbIdDb::parse("0781 SanDisk Corp.\n0951\tKingston\n");
assert_eq!(db.vendor_count(), 0);
assert!(db.is_empty());
assert_eq!(db.vendor_name(0x0781), None);
}

#[test]
fn a_wider_separator_is_accepted_and_keeps_the_surplus_in_the_name() {
// Current behaviour, asserted so a change is visible rather than silent.
// `parse_id_line`'s doc says "exactly two spaces", but the check reads
// only positions 4..6, so a third space falls into the name and survives
// — `trim_end` does not touch a leading one. usb.ids uses exactly two
// spaces throughout, so no real line reaches this; if the name is ever
// trimmed at the front, this assertion is where it shows up.
let db = UsbIdDb::parse("0abc Three Spaces\n");
assert_eq!(db.vendor_count(), 1);
assert_eq!(db.vendor_name(0x0abc), Some(" Three Spaces"));
}
}
12 changes: 12 additions & 0 deletions supply-chain/audits.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,15 @@
# cargo-vet audits file

[audits]

[[trusted.forensicnomicon-core]]
criteria = "safe-to-deploy"
user-id = 347968 # Albert Hui (h4x0r)
start = "2026-06-28"
end = "2027-08-02"

[[trusted.shellitem]]
criteria = "safe-to-deploy"
user-id = 347968 # Albert Hui (h4x0r)
start = "2026-06-13"
end = "2027-08-02"
4 changes: 0 additions & 4 deletions supply-chain/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ criteria = "safe-to-deploy"
version = "1.8.0"
criteria = "safe-to-deploy"

[[exemptions.forensicnomicon-core]]
version = "1.3.0"
criteria = "safe-to-deploy"

[[exemptions.forensicnomicon-data]]
version = "1.3.1"
criteria = "safe-to-deploy"
Expand Down
14 changes: 14 additions & 0 deletions supply-chain/imports.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@

# cargo-vet imports lock

[[publisher.forensicnomicon-core]]
version = "1.5.0"
when = "2026-07-29"
user-id = 347968
user-login = "h4x0r"
user-name = "Albert Hui"

[[publisher.shellitem]]
version = "0.2.1"
when = "2026-07-25"
user-id = 347968
user-login = "h4x0r"
user-name = "Albert Hui"

[[publisher.unicode-width]]
version = "0.1.14"
when = "2024-09-19"
Expand Down
Loading