mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-28 00:10:50 +08:00
refactor: 将 DTLS 本地依赖迁移到 libs 目录
This commit is contained in:
112
libs/dtls/src/cipher_suite/cipher_suite_aes_128_ccm.rs
Normal file
112
libs/dtls/src/cipher_suite/cipher_suite_aes_128_ccm.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use super::*;
|
||||
use crate::client_certificate_type::ClientCertificateType;
|
||||
use crate::crypto::crypto_ccm::{CryptoCcm, CryptoCcmTagLen};
|
||||
use crate::prf::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CipherSuiteAes128Ccm {
|
||||
ccm: Option<CryptoCcm>,
|
||||
client_certificate_type: ClientCertificateType,
|
||||
id: CipherSuiteId,
|
||||
psk: bool,
|
||||
crypto_ccm_tag_len: CryptoCcmTagLen,
|
||||
}
|
||||
|
||||
impl CipherSuiteAes128Ccm {
|
||||
const PRF_MAC_LEN: usize = 0;
|
||||
const PRF_KEY_LEN: usize = 16;
|
||||
const PRF_IV_LEN: usize = 4;
|
||||
|
||||
pub fn new(
|
||||
client_certificate_type: ClientCertificateType,
|
||||
id: CipherSuiteId,
|
||||
psk: bool,
|
||||
crypto_ccm_tag_len: CryptoCcmTagLen,
|
||||
) -> Self {
|
||||
CipherSuiteAes128Ccm {
|
||||
ccm: None,
|
||||
client_certificate_type,
|
||||
id,
|
||||
psk,
|
||||
crypto_ccm_tag_len,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CipherSuite for CipherSuiteAes128Ccm {
|
||||
fn to_string(&self) -> String {
|
||||
format!("{}", self.id)
|
||||
}
|
||||
|
||||
fn id(&self) -> CipherSuiteId {
|
||||
self.id
|
||||
}
|
||||
|
||||
fn certificate_type(&self) -> ClientCertificateType {
|
||||
self.client_certificate_type
|
||||
}
|
||||
|
||||
fn hash_func(&self) -> CipherSuiteHash {
|
||||
CipherSuiteHash::Sha256
|
||||
}
|
||||
|
||||
fn is_psk(&self) -> bool {
|
||||
self.psk
|
||||
}
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
self.ccm.is_some()
|
||||
}
|
||||
|
||||
fn init(
|
||||
&mut self,
|
||||
master_secret: &[u8],
|
||||
client_random: &[u8],
|
||||
server_random: &[u8],
|
||||
is_client: bool,
|
||||
) -> Result<()> {
|
||||
let keys = prf_encryption_keys(
|
||||
master_secret,
|
||||
client_random,
|
||||
server_random,
|
||||
CipherSuiteAes128Ccm::PRF_MAC_LEN,
|
||||
CipherSuiteAes128Ccm::PRF_KEY_LEN,
|
||||
CipherSuiteAes128Ccm::PRF_IV_LEN,
|
||||
self.hash_func(),
|
||||
)?;
|
||||
|
||||
if is_client {
|
||||
self.ccm = Some(CryptoCcm::new(
|
||||
&self.crypto_ccm_tag_len,
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
));
|
||||
} else {
|
||||
self.ccm = Some(CryptoCcm::new(
|
||||
&self.crypto_ccm_tag_len,
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
|
||||
let ccm = self.ccm.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to encrypt".to_owned(),
|
||||
))?;
|
||||
ccm.encrypt(pkt_rlh, raw)
|
||||
}
|
||||
|
||||
fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>> {
|
||||
let ccm = self.ccm.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to decrypt".to_owned(),
|
||||
))?;
|
||||
ccm.decrypt(input)
|
||||
}
|
||||
}
|
||||
107
libs/dtls/src/cipher_suite/cipher_suite_aes_128_gcm_sha256.rs
Normal file
107
libs/dtls/src/cipher_suite/cipher_suite_aes_128_gcm_sha256.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use super::*;
|
||||
use crate::crypto::crypto_gcm::*;
|
||||
use crate::prf::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CipherSuiteAes128GcmSha256 {
|
||||
gcm: Option<CryptoGcm>,
|
||||
rsa: bool,
|
||||
}
|
||||
|
||||
impl CipherSuiteAes128GcmSha256 {
|
||||
const PRF_MAC_LEN: usize = 0;
|
||||
const PRF_KEY_LEN: usize = 16;
|
||||
const PRF_IV_LEN: usize = 4;
|
||||
|
||||
pub fn new(rsa: bool) -> Self {
|
||||
CipherSuiteAes128GcmSha256 { gcm: None, rsa }
|
||||
}
|
||||
}
|
||||
|
||||
impl CipherSuite for CipherSuiteAes128GcmSha256 {
|
||||
fn to_string(&self) -> String {
|
||||
if self.rsa {
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256".to_owned()
|
||||
} else {
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn id(&self) -> CipherSuiteId {
|
||||
if self.rsa {
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256
|
||||
} else {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256
|
||||
}
|
||||
}
|
||||
|
||||
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.gcm.is_some()
|
||||
}
|
||||
|
||||
fn init(
|
||||
&mut self,
|
||||
master_secret: &[u8],
|
||||
client_random: &[u8],
|
||||
server_random: &[u8],
|
||||
is_client: bool,
|
||||
) -> Result<()> {
|
||||
let keys = prf_encryption_keys(
|
||||
master_secret,
|
||||
client_random,
|
||||
server_random,
|
||||
CipherSuiteAes128GcmSha256::PRF_MAC_LEN,
|
||||
CipherSuiteAes128GcmSha256::PRF_KEY_LEN,
|
||||
CipherSuiteAes128GcmSha256::PRF_IV_LEN,
|
||||
self.hash_func(),
|
||||
)?;
|
||||
|
||||
if is_client {
|
||||
self.gcm = Some(CryptoGcm::new(
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
));
|
||||
} else {
|
||||
self.gcm = Some(CryptoGcm::new(
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.gcm.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to encrypt".to_owned(),
|
||||
))?;
|
||||
cg.encrypt(pkt_rlh, raw)
|
||||
}
|
||||
|
||||
fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.gcm.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to decrypt".to_owned(),
|
||||
))?;
|
||||
cg.decrypt(input)
|
||||
}
|
||||
}
|
||||
107
libs/dtls/src/cipher_suite/cipher_suite_aes_256_cbc_sha.rs
Normal file
107
libs/dtls/src/cipher_suite/cipher_suite_aes_256_cbc_sha.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
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<()> {
|
||||
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_mac_key,
|
||||
&keys.server_write_key,
|
||||
&keys.server_mac_key,
|
||||
)?);
|
||||
} else {
|
||||
self.cbc = Some(CryptoCbc::new(
|
||||
&keys.server_write_key,
|
||||
&keys.server_mac_key,
|
||||
&keys.client_write_key,
|
||||
&keys.client_mac_key,
|
||||
)?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.cbc.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to encrypt".to_owned(),
|
||||
))?;
|
||||
cg.encrypt(pkt_rlh, raw)
|
||||
}
|
||||
|
||||
fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.cbc.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to decrypt".to_owned(),
|
||||
))?;
|
||||
cg.decrypt(input)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
use super::*;
|
||||
use crate::crypto::crypto_chacha20::*;
|
||||
use crate::prf::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CipherSuiteChaCha20Poly1305Sha256 {
|
||||
rsa: bool,
|
||||
cipher: Option<CryptoChaCha20>,
|
||||
}
|
||||
|
||||
impl CipherSuiteChaCha20Poly1305Sha256 {
|
||||
const PRF_MAC_LEN: usize = 0;
|
||||
const PRF_KEY_LEN: usize = 32;
|
||||
const PRF_IV_LEN: usize = 12;
|
||||
|
||||
pub fn new(rsa: bool) -> Self {
|
||||
CipherSuiteChaCha20Poly1305Sha256 { rsa, cipher: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl CipherSuite for CipherSuiteChaCha20Poly1305Sha256 {
|
||||
fn to_string(&self) -> String {
|
||||
if self.rsa {
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256".to_owned()
|
||||
} else {
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn id(&self) -> CipherSuiteId {
|
||||
if self.rsa {
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_ChaCha20_Poly1305_Sha256
|
||||
} else {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_ChaCha20_Poly1305_Sha256
|
||||
}
|
||||
}
|
||||
|
||||
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.cipher.is_some()
|
||||
}
|
||||
|
||||
fn init(
|
||||
&mut self,
|
||||
master_secret: &[u8],
|
||||
client_random: &[u8],
|
||||
server_random: &[u8],
|
||||
is_client: bool,
|
||||
) -> Result<()> {
|
||||
let keys = prf_encryption_keys(
|
||||
master_secret,
|
||||
client_random,
|
||||
server_random,
|
||||
CipherSuiteChaCha20Poly1305Sha256::PRF_MAC_LEN,
|
||||
CipherSuiteChaCha20Poly1305Sha256::PRF_KEY_LEN,
|
||||
CipherSuiteChaCha20Poly1305Sha256::PRF_IV_LEN,
|
||||
self.hash_func(),
|
||||
)?;
|
||||
|
||||
if is_client {
|
||||
self.cipher = Some(CryptoChaCha20::new(
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
));
|
||||
} else {
|
||||
self.cipher = Some(CryptoChaCha20::new(
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.cipher.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to encrypt".to_owned(),
|
||||
))?;
|
||||
cg.encrypt(pkt_rlh, raw)
|
||||
}
|
||||
|
||||
fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.cipher.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to decrypt".to_owned(),
|
||||
))?;
|
||||
cg.decrypt(input)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
use super::*;
|
||||
use crate::cipher_suite::cipher_suite_aes_128_ccm::CipherSuiteAes128Ccm;
|
||||
use crate::crypto::crypto_ccm::CryptoCcmTagLen;
|
||||
|
||||
pub fn new_cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm() -> CipherSuiteAes128Ccm {
|
||||
CipherSuiteAes128Ccm::new(
|
||||
ClientCertificateType::EcdsaSign,
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm,
|
||||
false,
|
||||
CryptoCcmTagLen::CryptoCcmTagLength,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
use super::*;
|
||||
use crate::cipher_suite::cipher_suite_aes_128_ccm::CipherSuiteAes128Ccm;
|
||||
use crate::crypto::crypto_ccm::CryptoCcmTagLen;
|
||||
|
||||
pub fn new_cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8() -> CipherSuiteAes128Ccm {
|
||||
CipherSuiteAes128Ccm::new(
|
||||
ClientCertificateType::EcdsaSign,
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm_8,
|
||||
false,
|
||||
CryptoCcmTagLen::CryptoCcm8TagLength,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
use super::*;
|
||||
use crate::cipher_suite::cipher_suite_aes_128_ccm::CipherSuiteAes128Ccm;
|
||||
use crate::crypto::crypto_ccm::CryptoCcmTagLen;
|
||||
|
||||
pub fn new_cipher_suite_tls_psk_with_aes_128_ccm() -> CipherSuiteAes128Ccm {
|
||||
CipherSuiteAes128Ccm::new(
|
||||
ClientCertificateType::Unsupported,
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Ccm,
|
||||
true,
|
||||
CryptoCcmTagLen::CryptoCcmTagLength,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
use super::*;
|
||||
use crate::cipher_suite::cipher_suite_aes_128_ccm::CipherSuiteAes128Ccm;
|
||||
use crate::crypto::crypto_ccm::CryptoCcmTagLen;
|
||||
|
||||
pub fn new_cipher_suite_tls_psk_with_aes_128_ccm8() -> CipherSuiteAes128Ccm {
|
||||
CipherSuiteAes128Ccm::new(
|
||||
ClientCertificateType::Unsupported,
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Ccm_8,
|
||||
true,
|
||||
CryptoCcmTagLen::CryptoCcm8TagLength,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
use super::*;
|
||||
use crate::crypto::crypto_gcm::*;
|
||||
use crate::prf::*;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct CipherSuiteTlsPskWithAes128GcmSha256 {
|
||||
gcm: Option<CryptoGcm>,
|
||||
}
|
||||
|
||||
impl CipherSuiteTlsPskWithAes128GcmSha256 {
|
||||
const PRF_MAC_LEN: usize = 0;
|
||||
const PRF_KEY_LEN: usize = 16;
|
||||
const PRF_IV_LEN: usize = 4;
|
||||
}
|
||||
|
||||
impl CipherSuite for CipherSuiteTlsPskWithAes128GcmSha256 {
|
||||
fn to_string(&self) -> String {
|
||||
"TLS_PSK_WITH_AES_128_GCM_SHA256".to_owned()
|
||||
}
|
||||
|
||||
fn id(&self) -> CipherSuiteId {
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Gcm_Sha256
|
||||
}
|
||||
|
||||
fn certificate_type(&self) -> ClientCertificateType {
|
||||
ClientCertificateType::Unsupported
|
||||
}
|
||||
|
||||
fn hash_func(&self) -> CipherSuiteHash {
|
||||
CipherSuiteHash::Sha256
|
||||
}
|
||||
|
||||
fn is_psk(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
self.gcm.is_some()
|
||||
}
|
||||
|
||||
fn init(
|
||||
&mut self,
|
||||
master_secret: &[u8],
|
||||
client_random: &[u8],
|
||||
server_random: &[u8],
|
||||
is_client: bool,
|
||||
) -> Result<()> {
|
||||
let keys = prf_encryption_keys(
|
||||
master_secret,
|
||||
client_random,
|
||||
server_random,
|
||||
CipherSuiteTlsPskWithAes128GcmSha256::PRF_MAC_LEN,
|
||||
CipherSuiteTlsPskWithAes128GcmSha256::PRF_KEY_LEN,
|
||||
CipherSuiteTlsPskWithAes128GcmSha256::PRF_IV_LEN,
|
||||
self.hash_func(),
|
||||
)?;
|
||||
|
||||
if is_client {
|
||||
self.gcm = Some(CryptoGcm::new(
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
));
|
||||
} else {
|
||||
self.gcm = Some(CryptoGcm::new(
|
||||
&keys.server_write_key,
|
||||
&keys.server_write_iv,
|
||||
&keys.client_write_key,
|
||||
&keys.client_write_iv,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.gcm.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to encrypt".to_owned(),
|
||||
))?;
|
||||
cg.encrypt(pkt_rlh, raw)
|
||||
}
|
||||
|
||||
fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>> {
|
||||
let cg = self.gcm.as_ref().ok_or(Error::Other(
|
||||
"CipherSuite has not been initialized, unable to decrypt".to_owned(),
|
||||
))?;
|
||||
cg.decrypt(input)
|
||||
}
|
||||
}
|
||||
287
libs/dtls/src/cipher_suite/mod.rs
Normal file
287
libs/dtls/src/cipher_suite/mod.rs
Normal file
@@ -0,0 +1,287 @@
|
||||
pub mod cipher_suite_aes_128_ccm;
|
||||
pub mod cipher_suite_aes_128_gcm_sha256;
|
||||
pub mod cipher_suite_aes_256_cbc_sha;
|
||||
pub mod cipher_suite_chacha20_poly1305_sha256;
|
||||
pub mod cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm;
|
||||
pub mod cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8;
|
||||
pub mod cipher_suite_tls_psk_with_aes_128_ccm;
|
||||
pub mod cipher_suite_tls_psk_with_aes_128_ccm8;
|
||||
pub mod cipher_suite_tls_psk_with_aes_128_gcm_sha256;
|
||||
|
||||
use std::fmt;
|
||||
use std::marker::{Send, Sync};
|
||||
|
||||
use cipher_suite_aes_128_gcm_sha256::*;
|
||||
use cipher_suite_aes_256_cbc_sha::*;
|
||||
use cipher_suite_chacha20_poly1305_sha256::*;
|
||||
use cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm::*;
|
||||
use cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8::*;
|
||||
use cipher_suite_tls_psk_with_aes_128_ccm::*;
|
||||
use cipher_suite_tls_psk_with_aes_128_ccm8::*;
|
||||
use cipher_suite_tls_psk_with_aes_128_gcm_sha256::*;
|
||||
|
||||
use super::client_certificate_type::*;
|
||||
use super::error::*;
|
||||
use super::record_layer::record_layer_header::*;
|
||||
|
||||
// CipherSuiteID is an ID for our supported CipherSuites
|
||||
// Supported Cipher Suites
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum CipherSuiteId {
|
||||
// AES-128-CCM
|
||||
Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm = 0xc0ac,
|
||||
Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm_8 = 0xc0ae,
|
||||
|
||||
// AES-128-GCM-SHA256
|
||||
Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256 = 0xc02b,
|
||||
Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256 = 0xc02f,
|
||||
|
||||
// AES-256-CBC-SHA
|
||||
Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha = 0xc00a,
|
||||
Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha = 0xc014,
|
||||
|
||||
Tls_Psk_With_Aes_128_Ccm = 0xc0a4,
|
||||
Tls_Psk_With_Aes_128_Ccm_8 = 0xc0a8,
|
||||
Tls_Psk_With_Aes_128_Gcm_Sha256 = 0x00a8,
|
||||
|
||||
// CHACHA20_POLY1305_SHA256
|
||||
Tls_Ecdhe_Rsa_With_ChaCha20_Poly1305_Sha256 = 0xcca8,
|
||||
Tls_Ecdhe_Ecdsa_With_ChaCha20_Poly1305_Sha256 = 0xcca9,
|
||||
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
impl fmt::Display for CipherSuiteId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm => {
|
||||
write!(f, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm_8 => {
|
||||
write!(f, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256 => {
|
||||
write!(f, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256 => {
|
||||
write!(f, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha => {
|
||||
write!(f, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha => {
|
||||
write!(f, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA")
|
||||
}
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Ccm => write!(f, "TLS_PSK_WITH_AES_128_CCM"),
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Ccm_8 => write!(f, "TLS_PSK_WITH_AES_128_CCM_8"),
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Gcm_Sha256 => {
|
||||
write!(f, "TLS_PSK_WITH_AES_128_GCM_SHA256")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_ChaCha20_Poly1305_Sha256 => {
|
||||
write!(f, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_ChaCha20_Poly1305_Sha256 => {
|
||||
write!(f, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256")
|
||||
}
|
||||
|
||||
_ => write!(f, "Unsupported CipherSuiteID"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for CipherSuiteId {
|
||||
fn from(val: u16) -> Self {
|
||||
match val {
|
||||
// AES-128-CCM
|
||||
0xc0ac => CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm,
|
||||
0xc0ae => CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm_8,
|
||||
|
||||
// AES-128-GCM-SHA256
|
||||
0xc02b => CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256,
|
||||
0xc02f => CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256,
|
||||
|
||||
// AES-256-CBC-SHA
|
||||
0xc00a => CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha,
|
||||
0xc014 => CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha,
|
||||
|
||||
0xc0a4 => CipherSuiteId::Tls_Psk_With_Aes_128_Ccm,
|
||||
0xc0a8 => CipherSuiteId::Tls_Psk_With_Aes_128_Ccm_8,
|
||||
0x00a8 => CipherSuiteId::Tls_Psk_With_Aes_128_Gcm_Sha256,
|
||||
|
||||
// CHACHA20_POLY1305_SHA256
|
||||
0xcca8 => CipherSuiteId::Tls_Ecdhe_Rsa_With_ChaCha20_Poly1305_Sha256,
|
||||
0xcca9 => CipherSuiteId::Tls_Ecdhe_Ecdsa_With_ChaCha20_Poly1305_Sha256,
|
||||
|
||||
_ => CipherSuiteId::Unsupported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for CipherSuiteId {
|
||||
fn from(val: &str) -> Self {
|
||||
match val {
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CCM" => CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm,
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm_8
|
||||
}
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256
|
||||
}
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256
|
||||
}
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha
|
||||
}
|
||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha
|
||||
}
|
||||
"TLS_PSK_WITH_AES_128_CCM" => CipherSuiteId::Tls_Psk_With_Aes_128_Ccm,
|
||||
"TLS_PSK_WITH_AES_128_CCM_8" => CipherSuiteId::Tls_Psk_With_Aes_128_Ccm_8,
|
||||
"TLS_PSK_WITH_AES_128_GCM_SHA256" => CipherSuiteId::Tls_Psk_With_Aes_128_Gcm_Sha256,
|
||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_ChaCha20_Poly1305_Sha256
|
||||
}
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_ChaCha20_Poly1305_Sha256
|
||||
}
|
||||
_ => CipherSuiteId::Unsupported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum CipherSuiteHash {
|
||||
Sha256,
|
||||
}
|
||||
|
||||
impl CipherSuiteHash {
|
||||
pub(crate) fn size(&self) -> usize {
|
||||
match *self {
|
||||
CipherSuiteHash::Sha256 => 32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CipherSuite {
|
||||
fn to_string(&self) -> String;
|
||||
fn id(&self) -> CipherSuiteId;
|
||||
fn certificate_type(&self) -> ClientCertificateType;
|
||||
fn hash_func(&self) -> CipherSuiteHash;
|
||||
fn is_psk(&self) -> bool;
|
||||
fn is_initialized(&self) -> bool;
|
||||
|
||||
// Generate the internal encryption state
|
||||
fn init(
|
||||
&mut self,
|
||||
master_secret: &[u8],
|
||||
client_random: &[u8],
|
||||
server_random: &[u8],
|
||||
is_client: bool,
|
||||
) -> Result<()>;
|
||||
|
||||
fn encrypt(&self, pkt_rlh: &RecordLayerHeader, raw: &[u8]) -> Result<Vec<u8>>;
|
||||
fn decrypt(&self, input: &[u8]) -> Result<Vec<u8>>;
|
||||
}
|
||||
|
||||
// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
|
||||
// A cipher_suite is a specific combination of key agreement, cipher and MAC
|
||||
// function.
|
||||
pub fn cipher_suite_for_id(id: CipherSuiteId) -> Result<Box<dyn CipherSuite + Send + Sync>> {
|
||||
match id {
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm => {
|
||||
Ok(Box::new(new_cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm()))
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Ccm_8 => Ok(Box::new(
|
||||
new_cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8(),
|
||||
)),
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_128_Gcm_Sha256 => {
|
||||
Ok(Box::new(CipherSuiteAes128GcmSha256::new(false)))
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_128_Gcm_Sha256 => {
|
||||
Ok(Box::new(CipherSuiteAes128GcmSha256::new(true)))
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_Aes_256_Cbc_Sha => {
|
||||
Ok(Box::new(CipherSuiteAes256CbcSha::new(true)))
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_Aes_256_Cbc_Sha => {
|
||||
Ok(Box::new(CipherSuiteAes256CbcSha::new(false)))
|
||||
}
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Ccm => {
|
||||
Ok(Box::new(new_cipher_suite_tls_psk_with_aes_128_ccm()))
|
||||
}
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Ccm_8 => {
|
||||
Ok(Box::new(new_cipher_suite_tls_psk_with_aes_128_ccm8()))
|
||||
}
|
||||
CipherSuiteId::Tls_Psk_With_Aes_128_Gcm_Sha256 => {
|
||||
Ok(Box::<CipherSuiteTlsPskWithAes128GcmSha256>::default())
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Rsa_With_ChaCha20_Poly1305_Sha256 => {
|
||||
Ok(Box::new(CipherSuiteChaCha20Poly1305Sha256::new(true)))
|
||||
}
|
||||
CipherSuiteId::Tls_Ecdhe_Ecdsa_With_ChaCha20_Poly1305_Sha256 => {
|
||||
Ok(Box::new(CipherSuiteChaCha20Poly1305Sha256::new(false)))
|
||||
}
|
||||
|
||||
_ => Err(Error::ErrInvalidCipherSuite),
|
||||
}
|
||||
}
|
||||
|
||||
// CipherSuites we support in order of preference
|
||||
pub(crate) fn default_cipher_suites() -> Vec<Box<dyn CipherSuite + Send + Sync>> {
|
||||
vec![
|
||||
Box::new(CipherSuiteAes128GcmSha256::new(false)),
|
||||
Box::new(CipherSuiteAes256CbcSha::new(false)),
|
||||
Box::new(CipherSuiteAes128GcmSha256::new(true)),
|
||||
Box::new(CipherSuiteAes256CbcSha::new(true)),
|
||||
Box::new(CipherSuiteChaCha20Poly1305Sha256::new(false)),
|
||||
]
|
||||
}
|
||||
|
||||
fn all_cipher_suites() -> Vec<Box<dyn CipherSuite + Send + Sync>> {
|
||||
vec![
|
||||
Box::new(new_cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm()),
|
||||
Box::new(new_cipher_suite_tls_ecdhe_ecdsa_with_aes_128_ccm8()),
|
||||
Box::new(CipherSuiteAes128GcmSha256::new(false)),
|
||||
Box::new(CipherSuiteAes128GcmSha256::new(true)),
|
||||
Box::new(CipherSuiteAes256CbcSha::new(false)),
|
||||
Box::new(CipherSuiteAes256CbcSha::new(true)),
|
||||
Box::new(new_cipher_suite_tls_psk_with_aes_128_ccm()),
|
||||
Box::new(new_cipher_suite_tls_psk_with_aes_128_ccm8()),
|
||||
Box::<CipherSuiteTlsPskWithAes128GcmSha256>::default(),
|
||||
Box::new(CipherSuiteChaCha20Poly1305Sha256::new(false)),
|
||||
Box::new(CipherSuiteChaCha20Poly1305Sha256::new(true)),
|
||||
]
|
||||
}
|
||||
|
||||
fn cipher_suites_for_ids(ids: &[CipherSuiteId]) -> Result<Vec<Box<dyn CipherSuite + Send + Sync>>> {
|
||||
let mut cipher_suites = vec![];
|
||||
for id in ids {
|
||||
cipher_suites.push(cipher_suite_for_id(*id)?);
|
||||
}
|
||||
Ok(cipher_suites)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_cipher_suites(
|
||||
user_selected_suites: &[CipherSuiteId],
|
||||
exclude_psk: bool,
|
||||
exclude_non_psk: bool,
|
||||
) -> Result<Vec<Box<dyn CipherSuite + Send + Sync>>> {
|
||||
let cipher_suites = if !user_selected_suites.is_empty() {
|
||||
cipher_suites_for_ids(user_selected_suites)?
|
||||
} else {
|
||||
default_cipher_suites()
|
||||
};
|
||||
|
||||
let filtered_cipher_suites: Vec<Box<dyn CipherSuite + Send + Sync>> = cipher_suites
|
||||
.into_iter()
|
||||
.filter(|c| !((exclude_psk && c.is_psk()) || (exclude_non_psk && !c.is_psk())))
|
||||
.collect();
|
||||
|
||||
if filtered_cipher_suites.is_empty() {
|
||||
Err(Error::ErrNoAvailableCipherSuites)
|
||||
} else {
|
||||
Ok(filtered_cipher_suites)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user