pub(crate) fn extract_subject_public_key_info(cert_der: &[u8]) -> Result<Vec<u8>, String> {
let (cert_body, _) = read_tlv(cert_der, 0)?; let tbs_outer = cert_body.value;
let (tbs, _) = read_tlv(tbs_outer, 0)?;
let mut pos = 0usize;
if tbs.value.first() == Some(&0xA0) {
let (_, next) = read_tlv(tbs.value, pos)?;
pos = next;
}
for _ in 0..5 {
let (_, next) = read_tlv(tbs.value, pos)?;
pos = next;
}
let (spki, _) = read_tlv(tbs.value, pos)?;
Ok(spki.whole.to_vec())
}
struct Tlv<'a> {
whole: &'a [u8],
value: &'a [u8],
}
fn read_tlv(data: &[u8], pos: usize) -> Result<(Tlv<'_>, usize), String> {
if pos >= data.len() {
return Err("unexpected end of DER data".to_string());
}
let tag_start = pos;
let mut p = pos + 1; let len_byte = *data.get(p).ok_or("unexpected end of DER data reading length")?;
p += 1;
let (value_len, header_len) = if len_byte & 0x80 == 0 {
(len_byte as usize, p - tag_start)
} else {
let n_bytes = (len_byte & 0x7f) as usize;
if n_bytes == 0 || n_bytes > 4 {
return Err("unsupported DER length encoding".to_string());
}
let len_bytes = data.get(p..p + n_bytes).ok_or("truncated DER length")?;
let mut len = 0usize;
for b in len_bytes {
len = (len << 8) | (*b as usize);
}
p += n_bytes;
(len, p - tag_start)
};
let value_start = tag_start + header_len;
let value_end = value_start.checked_add(value_len).ok_or("DER length overflow")?;
let value = data.get(value_start..value_end).ok_or("DER value runs past end of input")?;
let whole = &data[tag_start..value_end];
Ok((Tlv { whole, value }, value_end))
}