79 lines
2.5 KiB
Rust
79 lines
2.5 KiB
Rust
use crate::data_model::rc::AccessDescription;
|
|
|
|
pub(super) fn encode_access_description_der_for_vcir_ccr_projection(
|
|
access_description: &AccessDescription,
|
|
) -> Result<Vec<u8>, String> {
|
|
let oid = encode_oid_der_for_vcir_ccr_projection(&access_description.access_method_oid)?;
|
|
let uri = encode_tlv_for_vcir_ccr_projection(
|
|
0x86,
|
|
access_description.access_location.as_bytes().to_vec(),
|
|
);
|
|
Ok(encode_sequence_for_vcir_ccr_projection(&[oid, uri]))
|
|
}
|
|
|
|
fn encode_oid_der_for_vcir_ccr_projection(oid: &str) -> Result<Vec<u8>, String> {
|
|
let arcs = oid
|
|
.split('.')
|
|
.map(|part| {
|
|
part.parse::<u64>()
|
|
.map_err(|_| format!("unsupported accessMethod OID: {oid}"))
|
|
})
|
|
.collect::<Result<Vec<_>, _>>()?;
|
|
if arcs.len() < 2 {
|
|
return Err(format!("unsupported accessMethod OID: {oid}"));
|
|
}
|
|
if arcs[0] > 2 || (arcs[0] < 2 && arcs[1] >= 40) {
|
|
return Err(format!("unsupported accessMethod OID: {oid}"));
|
|
}
|
|
let mut body = Vec::new();
|
|
body.push((arcs[0] * 40 + arcs[1]) as u8);
|
|
for arc in &arcs[2..] {
|
|
encode_base128_for_vcir_ccr_projection(*arc, &mut body);
|
|
}
|
|
Ok(encode_tlv_for_vcir_ccr_projection(0x06, body))
|
|
}
|
|
|
|
fn encode_base128_for_vcir_ccr_projection(mut value: u64, out: &mut Vec<u8>) {
|
|
let mut tmp = vec![(value & 0x7F) as u8];
|
|
value >>= 7;
|
|
while value > 0 {
|
|
tmp.push(((value & 0x7F) as u8) | 0x80);
|
|
value >>= 7;
|
|
}
|
|
tmp.reverse();
|
|
out.extend_from_slice(&tmp);
|
|
}
|
|
|
|
fn encode_sequence_for_vcir_ccr_projection(elements: &[Vec<u8>]) -> Vec<u8> {
|
|
let total_len: usize = elements.iter().map(Vec::len).sum();
|
|
let mut buf = Vec::with_capacity(total_len);
|
|
for element in elements {
|
|
buf.extend_from_slice(element);
|
|
}
|
|
encode_tlv_for_vcir_ccr_projection(0x30, buf)
|
|
}
|
|
|
|
fn encode_tlv_for_vcir_ccr_projection(tag: u8, value: Vec<u8>) -> Vec<u8> {
|
|
let mut out = Vec::with_capacity(1 + 9 + value.len());
|
|
out.push(tag);
|
|
encode_length_for_vcir_ccr_projection(value.len(), &mut out);
|
|
out.extend_from_slice(&value);
|
|
out
|
|
}
|
|
|
|
fn encode_length_for_vcir_ccr_projection(len: usize, out: &mut Vec<u8>) {
|
|
if len < 0x80 {
|
|
out.push(len as u8);
|
|
return;
|
|
}
|
|
let mut bytes = Vec::new();
|
|
let mut value = len;
|
|
while value > 0 {
|
|
bytes.push((value & 0xFF) as u8);
|
|
value >>= 8;
|
|
}
|
|
bytes.reverse();
|
|
out.push(0x80 | (bytes.len() as u8));
|
|
out.extend_from_slice(&bytes);
|
|
}
|