dope-tls 0.18.0

TCP TLS streams for dope runtime, shin-backed
Documentation
use std::iter::FusedIterator;

use shin::client::config::OwnedTrustAnchor;

#[derive(Clone, Debug, Default)]
pub struct WebPkiRoots {
    index: usize,
}

impl WebPkiRoots {
    pub const fn new() -> Self {
        Self { index: 0 }
    }
}

impl Iterator for WebPkiRoots {
    type Item = OwnedTrustAnchor;

    fn next(&mut self) -> Option<Self::Item> {
        let anchor = webpki_roots::TLS_SERVER_ROOTS.get(self.index)?;
        self.index += 1;
        Some(OwnedTrustAnchor {
            subject_der: anchor.subject.as_ref().to_vec(),
            spki_der: wrap_sequence(anchor.subject_public_key_info.as_ref()),
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let remaining = webpki_roots::TLS_SERVER_ROOTS.len() - self.index;
        (remaining, Some(remaining))
    }
}

impl ExactSizeIterator for WebPkiRoots {}
impl FusedIterator for WebPkiRoots {}

fn wrap_sequence(inner: &[u8]) -> Vec<u8> {
    let bytes = inner.len().to_be_bytes();
    let start = bytes
        .iter()
        .position(|byte| *byte != 0)
        .unwrap_or(bytes.len() - 1);
    let length = &bytes[start..];
    let header_len = if inner.len() < 128 {
        2
    } else {
        2 + length.len()
    };
    let mut out = Vec::with_capacity(header_len + inner.len());
    out.push(0x30);
    if inner.len() < 128 {
        out.push(inner.len() as u8);
    } else {
        out.push(0x80 | length.len() as u8);
        out.extend_from_slice(length);
    }
    out.extend_from_slice(inner);
    out
}