pub(crate) fn der_length(len: usize) -> Vec<u8> {
if len < 0x80 {
return vec![len as u8];
}
let be = len.to_be_bytes();
let start = be.iter().position(|&b| b != 0).unwrap_or(be.len() - 1);
let sig = &be[start..];
let mut out = Vec::with_capacity(1 + sig.len());
out.push(0x80 | sig.len() as u8);
out.extend_from_slice(sig);
out
}
pub(crate) fn der_tag(tag: u8, content: &[u8]) -> Vec<u8> {
let mut out = Vec::with_capacity(1 + 4 + content.len());
out.push(tag);
out.extend(der_length(content.len()));
out.extend_from_slice(content);
out
}
pub(crate) fn der_sequence(content: &[u8]) -> Vec<u8> {
der_tag(0x30, content)
}
pub(crate) fn der_set(content: &[u8]) -> Vec<u8> {
der_tag(0x31, content)
}
pub(crate) fn der_oid(oid_bytes: &[u8]) -> Vec<u8> {
der_tag(0x06, oid_bytes)
}
pub(crate) fn der_octet_string(data: &[u8]) -> Vec<u8> {
der_tag(0x04, data)
}
pub(crate) fn der_integer(n: u8) -> Vec<u8> {
vec![0x02, 0x01, n]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn length_short_long_forms() {
assert_eq!(der_length(0), vec![0x00]);
assert_eq!(der_length(0x7F), vec![0x7F]);
assert_eq!(der_length(0x80), vec![0x81, 0x80]);
assert_eq!(der_length(0xFF), vec![0x81, 0xFF]);
assert_eq!(der_length(0x0100), vec![0x82, 0x01, 0x00]);
assert_eq!(der_length(0xFFFF), vec![0x82, 0xFF, 0xFF]);
assert_eq!(der_length(0x010000), vec![0x83, 0x01, 0x00, 0x00]);
assert_eq!(der_length(0xFF_FFFF), vec![0x83, 0xFF, 0xFF, 0xFF]);
}
#[test]
fn length_above_16mib_is_not_truncated() {
assert_eq!(der_length(0x0100_0000), vec![0x84, 0x01, 0x00, 0x00, 0x00]);
assert_eq!(der_length(0xFFFF_FFFF), vec![0x84, 0xFF, 0xFF, 0xFF, 0xFF]);
assert_eq!(der_length(0x01_0000_0000), vec![0x85, 0x01, 0x00, 0x00, 0x00, 0x00]);
for &n in &[0x80usize, 0x1234, 0x12_3456, 0x1234_5678, 0x12_3456_789A] {
let enc = der_length(n);
let nbytes = (enc[0] & 0x7F) as usize;
let mut v = 0usize;
for &b in &enc[1..=nbytes] {
v = (v << 8) | b as usize;
}
assert_eq!(v, n, "der_length round-trip failed for {n:#x}");
}
}
#[test]
fn tag_wrappers() {
assert_eq!(der_sequence(&[0xAA]), vec![0x30, 0x01, 0xAA]);
assert_eq!(der_set(&[0xBB]), vec![0x31, 0x01, 0xBB]);
assert_eq!(der_oid(&[0x2A]), vec![0x06, 0x01, 0x2A]);
assert_eq!(der_octet_string(&[1, 2]), vec![0x04, 0x02, 1, 2]);
assert_eq!(der_integer(0), vec![0x02, 0x01, 0x00]);
assert_eq!(der_integer(3), vec![0x02, 0x01, 0x03]);
}
#[test]
fn nested_sequence_length_is_correct() {
let inner = der_octet_string(&[0u8; 130]);
let seq = der_sequence(&inner);
assert_eq!(seq[0], 0x30);
assert_eq!(&seq[1..3], &[0x81, 0x85]);
assert_eq!(seq.len(), 3 + inner.len());
}
}