ytls_extensions/
delegated_credential.rs1use crate::TlsExtError;
4use ytls_typed::SignatureAlgorithm;
5
6pub trait ExtDelegatedCredentialProcessor {
8 fn delegated_credential_signature_algorithm(&mut self, _: SignatureAlgorithm) -> bool;
10}
11
12pub struct TlsExtDelegatedCredential {}
14
15impl TlsExtDelegatedCredential {
16 #[inline]
18 pub fn client_delegated_credential_cb<P: ExtDelegatedCredentialProcessor>(
19 p: &mut P,
20 sig_alg_raw: &[u8],
21 ) -> Result<(), TlsExtError> {
22 if sig_alg_raw.len() < 2 {
23 return Err(TlsExtError::InvalidLength);
24 }
25 let sig_algs_len = u16::from_be_bytes([sig_alg_raw[0], sig_alg_raw[1]]);
26
27 if sig_algs_len == 0 {
28 return Err(TlsExtError::NoData);
29 }
30
31 let remaining = &sig_alg_raw[2..];
32 let expected_len = remaining.len();
33
34 if sig_algs_len as usize != expected_len {
35 return Err(TlsExtError::InvalidLength);
36 }
37
38 let mut sig_algs_i = remaining.chunks(2);
39
40 while let Some(sig_alg) = sig_algs_i.next() {
41 let sig_alg_id = u16::from_be_bytes([sig_alg[0], sig_alg[1]]);
42 p.delegated_credential_signature_algorithm(sig_alg_id.into());
43 }
44 Ok(())
45 }
46}
47
48#[cfg(test)]
49mod test {
50 use super::*;
51 use hex_literal::hex;
52 use rstest::rstest;
53 use ytls_typed::SignatureAlgorithm as Sa;
54
55 #[derive(Debug, Default, PartialEq)]
56 struct Tester {
57 seen: Vec<Sa>,
58 }
59
60 impl ExtDelegatedCredentialProcessor for Tester {
61 fn delegated_credential_signature_algorithm(&mut self, dgsa: Sa) -> bool {
62 self.seen.push(dgsa);
63 true
64 }
65 }
66
67 #[rstest]
68 #[case(
69 "00080403050306030203",
70 Tester { seen: vec![Sa::EcdsaSecp256r1Sha256, Sa::EcdsaSecp384r1Sha384, Sa::EcdsaSecp521r1Sha512, Sa::EcdsaSha1] },
71 Ok(())
72 )]
73 #[case(
74 "",
75 Tester { seen: vec![] },
76 Err(TlsExtError::InvalidLength)
77 )]
78 fn client_delegated_credential_dgsa(
79 #[case] raw_t: &str,
80 #[case] expected_tester: Tester,
81 #[case] expected_res: Result<(), TlsExtError>,
82 ) {
83 let in_raw = hex::decode(raw_t).unwrap();
84 let mut tester = Tester::default();
85 let res = TlsExtDelegatedCredential::client_delegated_credential_cb(&mut tester, &in_raw);
86 assert_eq!(expected_tester, tester);
87 assert_eq!(expected_res, res);
88 }
89}