1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use super::*;
use crate::crypto::crypto_cbc::*;
use crate::prf::*;

#[derive(Clone)]
pub struct CipherSuiteAes256CbcSha {
    cbc: Option<CryptoCbc>,
    rsa: bool,
}

impl CipherSuiteAes256CbcSha {
    const PRF_MAC_LEN: usize = 20;
    const PRF_KEY_LEN: usize = 32;
    const PRF_IV_LEN: usize = 16;

    pub fn new(rsa: bool) -> Self {
        CipherSuiteAes256CbcSha { cbc: None, rsa }
    }
}

impl CipherSuite for CipherSuiteAes256CbcSha {
    fn to_string(&self) -> String {
        if self.rsa {
            "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA".to_owned()
        } else {
            "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA".to_owned()
        }
    }

    fn id(&self) -> CipherSuiteId {
        if self.rsa {
            CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha
        } else {
            CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha
        }
    }

    fn certificate_type(&self) -> ClientCertificateType {
        if self.rsa {
            ClientCertificateType::RsaSign
        } else {
            ClientCertificateType::EcdsaSign
        }
    }

    fn hash_func(&self) -> CipherSuiteHash {
        CipherSuiteHash::Sha256
    }

    fn is_psk(&self) -> bool {
        false
    }

    fn is_initialized(&self) -> bool {
        self.cbc.is_some()
    }

    fn init(
        &mut self,
        master_secret: &[u8],
        client_random: &[u8],
        server_random: &[u8],
        is_client: bool,
    ) -> Result<(), Error> {
        let keys = prf_encryption_keys(
            master_secret,
            client_random,
            server_random,
            CipherSuiteAes256CbcSha::PRF_MAC_LEN,
            CipherSuiteAes256CbcSha::PRF_KEY_LEN,
            CipherSuiteAes256CbcSha::PRF_IV_LEN,
            self.hash_func(),
        )?;

        if is_client {
            self.cbc = Some(CryptoCbc::new(
                &keys.client_write_key,
                &keys.client_write_iv,
                &keys.client_mac_key,
                &keys.server_write_key,
                &keys.server_write_iv,
                &keys.server_mac_key,
            )?);
        } else {
            self.cbc = Some(CryptoCbc::new(
                &keys.server_write_key,
                &keys.server_write_iv,
                &keys.server_mac_key,
                &keys.client_write_key,
                &keys.client_write_iv,
                &keys.client_mac_key,
            )?);
        }

        Ok(())
    }

    fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>, Error> {
        if let Some(cg) = &self.cbc {
            cg.encrypt(pkt_rlh, raw)
        } else {
            Err(Error::ErrOthers(
                "CipherSuite has not been initialized, unable to encrypt".to_owned(),
            ))
        }
    }

    fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>, Error> {
        if let Some(cg) = &self.cbc {
            cg.decrypt(input)
        } else {
            Err(Error::ErrOthers(
                "CipherSuite has not been initialized, unable to decrypt".to_owned(),
            ))
        }
    }
}