Do not identify malformed object identifiers as valid algorithms (R3.12) (from #609)

This commit is contained in:
Afloat
2026-11-03 20:00:36 +07:00
committed by bflatastic
parent ca0592fe94
commit 3f3aa37bfe
2 changed files with 41 additions and 1 deletions
+13 -1
View File
@@ -88,10 +88,19 @@ pub fn children(data: &[u8], parent: &Tlv) -> Vec<Tlv> {
/// Dotted form of an OBJECT IDENTIFIER's content.
pub fn oid(content: &[u8]) -> String {
if content.is_empty() || content.len() > 64 {
return "invalid".into();
}
let mut parts: Vec<String> = Vec::new();
let mut v: u64 = 0;
let mut first = true;
for &b in content.iter().take(64) {
let mut arc_start = true;
for &b in content {
// DER subidentifiers use the shortest base-128 encoding.
if arc_start && b == 0x80 {
return "invalid".into();
}
arc_start = b & 0x80 == 0;
v = match v.checked_mul(128) {
Some(x) => x | u64::from(b & 0x7f),
None => return "invalid".into(),
@@ -114,6 +123,9 @@ pub fn oid(content: &[u8]) -> String {
v = 0;
}
}
if !arc_start {
return "invalid".into();
}
parts.join(".")
}
@@ -0,0 +1,28 @@
use craft_anything_formats::der::{oid, oid_name};
#[test]
fn unfinished_oid_does_not_alias_a_known_algorithm() {
let mut algorithm = vec![0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 1, 1, 0x0b];
assert_eq!(oid_name(&oid(&algorithm)), Some("sha256WithRSAEncryption"));
algorithm.push(0x80);
assert_eq!(oid(&algorithm), "invalid");
assert!(oid_name(&oid(&algorithm)).is_none());
}
#[test]
fn malformed_and_oversized_oids_are_not_returned_as_prefixes() {
assert_eq!(oid(&[]), "invalid");
assert_eq!(oid(&[0x80, 0x2a]), "invalid");
assert_eq!(oid(&[0x2a, 0x80, 0]), "invalid");
assert_eq!(oid(&[0; 65]), "invalid");
assert_eq!(oid(&[0xff; 11]), "invalid");
}
#[test]
fn complete_oid_arcs_and_the_length_boundary_remain_supported() {
assert_eq!(oid(&[0x88, 0x37, 3]), "2.999.3");
let mut boundary = vec![0x2a];
boundary.resize(64, 0);
assert!(oid(&boundary).starts_with("1.2.0.0."));
assert_eq!(oid(&boundary).split('.').count(), 65);
}