Skip to content

Commit

Permalink
Fix wrong encoding of large tags (Closes #43)
Browse files Browse the repository at this point in the history
  • Loading branch information
chifflier committed Jul 30, 2024
1 parent 64502e4 commit f9ea57f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
32 changes: 23 additions & 9 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,19 +352,33 @@ impl ToDer for (Class, bool, Tag) {
let b0 = (*class as u8) << 6;
let b0 = b0 | if *constructed { 0b10_0000 } else { 0 };
if tag.0 > 30 {
let mut val = tag.0;

const BUF_SZ: usize = 8;
let mut buffer = [0u8; BUF_SZ];
let mut current_index = BUF_SZ - 1;

// first byte: class+constructed+0x1f
let b0 = b0 | 0b1_1111;
let mut sz = writer.write(&[b0])?;
let mut val = tag.0;
loop {
if val <= 127 {
sz += writer.write(&[val as u8])?;
return Ok(sz);
} else {
let b = (val & 0b0111_1111) as u8 | 0b1000_0000;
sz += writer.write(&[b])?;
val >>= 7;

// now write bytes from right (last) to left

// last encoded byte
buffer[current_index] = (val & 0x7f) as u8;
val >>= 7;

while val > 0 {
current_index -= 1;
if current_index == 0 {
return Err(SerializeError::InvalidLength);
}
buffer[current_index] = (val & 0x7f) as u8 | 0x80;
val >>= 7;
}

sz += writer.write(&buffer[current_index..])?;
Ok(sz)
} else {
let b0 = b0 | (tag.0 as u8);
let sz = writer.write(&[b0])?;
Expand Down
14 changes: 14 additions & 0 deletions tests/issue-43-encoding-large-tags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use asn1_rs::{Any, FromDer, Integer, Tag, ToDer};

#[test]
fn encode_large_tag() {
const EXPECTED_TAG: u32 = 0x41424344;
let data = Integer::from(1).to_der_vec().unwrap();
let any = &Any::from_tag_and_data(Tag::from(EXPECTED_TAG), &data);
let tmp = any.to_der_vec().unwrap();

let expect = Tag::from(EXPECTED_TAG);
let actual = Any::from_der(&tmp).unwrap().1.tag();

assert_eq!(expect, actual, "expected tag {expect}, found tag {actual}");
}
2 changes: 1 addition & 1 deletion tests/to_der.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn to_der_tag() {
let v = (Class::Universal, false, Tag(0x1a1a))
.to_der_vec()
.expect("serialization failed");
assert_eq!(&v, &[0b1_1111, 0x9a, 0x34]);
assert_eq!(&v, &[0b1_1111, 0xb4, 0x1a]);
}

#[test]
Expand Down

0 comments on commit f9ea57f

Please sign in to comment.