rustls_jls/jls/
mod.rs

1
2use std::string::String;
3
4use crate::log::trace;
5use crate::msgs::handshake::{ClientExtension, ClientHelloPayload};
6
7#[cfg(feature = "ring")]
8use ring::digest::{digest, SHA256};
9#[cfg(not(feature = "ring"))]
10use aws_lc_rs::digest::{digest, SHA256};
11use alloc::vec::Vec;
12use alloc::vec;
13
14// use aes_gcm to support 512bits long nonce (not supported by ring)
15use aes_gcm::{
16    aead::consts::U32,
17    aes::Aes256,
18    AeadInPlace, // Or `Aes128Gcm`
19    AesGcm,
20    KeyInit,
21};
22
23pub(crate) mod server;
24
25#[derive(Clone,Debug)]
26/// JLS Configuration
27pub struct JlsConfig {
28    /// user password of a JLS peer
29    pub user_pwd: String,
30    /// user iv for a JLS peer
31    pub user_iv: String,
32}
33
34impl Default for JlsConfig {
35    fn default() -> JlsConfig {
36        JlsConfig {
37            user_pwd: "3070111071563328618171495819203123318".into(),
38            user_iv: "3070111071563328618171495819203123318".into(),
39        }
40    }
41}
42
43impl JlsConfig {
44    /// Create a new JlsConfig
45    pub fn new(user_pwd: &str, user_iv: &str) -> JlsConfig {
46        JlsConfig {
47            user_pwd: String::from(user_pwd),
48            user_iv: String::from(user_iv),
49        }
50    }
51
52    /// Build a fake random from a true random with given keyshare
53    pub fn build_fake_random(&self, random: &[u8; 16], auth_data: &[u8]) -> [u8; 32] {
54        let mut iv = self.user_iv.as_bytes().to_vec();
55        iv.extend_from_slice(auth_data);
56        let mut pwd = self.user_pwd.as_bytes().to_vec();
57        pwd.extend_from_slice(auth_data);
58
59        trace!("generate ch iv: {:?}", iv);
60        trace!("generate pwd: {:?}", pwd);
61
62        let iv = digest(&SHA256, iv.as_ref());
63        let pwd = digest(&SHA256, pwd.as_ref());
64
65        let cipher = AesGcm::<Aes256, U32>::new(pwd.as_ref().into());
66
67        let mut buffer = Vec::<u8>::from(random.as_slice());
68        cipher
69            .encrypt_in_place(iv.as_ref().into(), b"", &mut buffer)
70            .unwrap();
71
72        buffer.try_into().unwrap()
73    }
74
75    /// Check if it's a valid fake random
76    pub fn check_fake_random(&self, fake_random: &[u8; 32], auth_data: &[u8]) -> bool {
77        let mut iv = self.user_iv.as_bytes().to_vec();
78        iv.extend_from_slice(auth_data);
79        let mut pwd = self.user_pwd.as_bytes().to_vec();
80        pwd.extend_from_slice(auth_data);
81
82        trace!("check ch iv: {:?}", iv);
83        trace!("check pwd: {:?}", pwd);
84
85        let iv = digest(&SHA256, iv.as_ref());
86        let pwd = digest(&SHA256, pwd.as_ref());
87
88        let cipher = AesGcm::<Aes256, U32>::new(pwd.as_ref().into());
89
90        let mut buffer = Vec::from(fake_random.as_ref());
91
92        let is_valid = cipher
93            .decrypt_in_place(iv.as_ref().into(), b"", &mut buffer)
94            .is_ok();
95        is_valid
96    }
97}
98
99// fill zero in the psk binders field.
100pub(crate) fn set_zero_psk_binders(chp: &mut ClientHelloPayload) {
101    let last_extension = chp.extensions.last_mut();
102    if let Some(ClientExtension::PresharedKey(ref mut offer)) = last_extension {
103        for ii in 0..offer.binders.len() {
104            let len = offer.binders[ii].as_ref().len();
105            offer.binders[0] = vec![0u8; len].into();
106        }
107    }
108}
109