mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-27 16:00:49 +08:00
refactor: 将 DTLS 本地依赖迁移到 libs 目录
This commit is contained in:
56
libs/dtls/src/extension/extension_server_name.rs
Normal file
56
libs/dtls/src/extension/extension_server_name.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
#[cfg(test)]
|
||||
mod extension_server_name_test;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use super::*;
|
||||
|
||||
const EXTENSION_SERVER_NAME_TYPE_DNSHOST_NAME: u8 = 0;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionServerName {
|
||||
pub(crate) server_name: String,
|
||||
}
|
||||
|
||||
impl ExtensionServerName {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::ServerName
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
//TODO: check how to do cryptobyte?
|
||||
2 + 2 + 1 + 2 + self.server_name.len()
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
//TODO: check how to do cryptobyte?
|
||||
writer.write_u16::<BigEndian>(2 + 1 + 2 + self.server_name.len() as u16)?;
|
||||
writer.write_u16::<BigEndian>(1 + 2 + self.server_name.len() as u16)?;
|
||||
writer.write_u8(EXTENSION_SERVER_NAME_TYPE_DNSHOST_NAME)?;
|
||||
writer.write_u16::<BigEndian>(self.server_name.len() as u16)?;
|
||||
writer.write_all(self.server_name.as_bytes())?;
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
//TODO: check how to do cryptobyte?
|
||||
let _ = reader.read_u16::<BigEndian>()? as usize;
|
||||
let _ = reader.read_u16::<BigEndian>()? as usize;
|
||||
|
||||
let name_type = reader.read_u8()?;
|
||||
if name_type != EXTENSION_SERVER_NAME_TYPE_DNSHOST_NAME {
|
||||
return Err(Error::ErrInvalidSniFormat);
|
||||
}
|
||||
|
||||
let buf_len = reader.read_u16::<BigEndian>()? as usize;
|
||||
let mut buf: Vec<u8> = vec![0u8; buf_len];
|
||||
reader.read_exact(&mut buf)?;
|
||||
|
||||
let server_name = String::from_utf8(buf)?;
|
||||
|
||||
Ok(ExtensionServerName { server_name })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_extension_server_name() -> Result<()> {
|
||||
let extension = ExtensionServerName {
|
||||
server_name: "test.domain".to_owned(),
|
||||
};
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
extension.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_extension = ExtensionServerName::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_extension, extension,
|
||||
"extensionServerName marshal: got {new_extension:?} expected {extension:?}",
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#[cfg(test)]
|
||||
mod extension_supported_elliptic_curves_test;
|
||||
|
||||
use super::*;
|
||||
use crate::curve::named_curve::*;
|
||||
|
||||
const EXTENSION_SUPPORTED_GROUPS_HEADER_SIZE: usize = 6;
|
||||
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 8422 §5.1.1]
|
||||
///
|
||||
/// [RFC 8422 §5.1.1]: https://tools.ietf.org/html/rfc8422#section-5.1.1
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionSupportedEllipticCurves {
|
||||
pub elliptic_curves: Vec<NamedCurve>,
|
||||
}
|
||||
|
||||
impl ExtensionSupportedEllipticCurves {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::SupportedEllipticCurves
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
2 + 2 + self.elliptic_curves.len() * 2
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(2 + 2 * self.elliptic_curves.len() as u16)?;
|
||||
writer.write_u16::<BigEndian>(2 * self.elliptic_curves.len() as u16)?;
|
||||
for v in &self.elliptic_curves {
|
||||
writer.write_u16::<BigEndian>(*v as u16)?;
|
||||
}
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let _ = reader.read_u16::<BigEndian>()?;
|
||||
|
||||
let group_count = reader.read_u16::<BigEndian>()? as usize / 2;
|
||||
let mut elliptic_curves = vec![];
|
||||
for _ in 0..group_count {
|
||||
let elliptic_curve = reader.read_u16::<BigEndian>()?.into();
|
||||
elliptic_curves.push(elliptic_curve);
|
||||
}
|
||||
|
||||
Ok(ExtensionSupportedEllipticCurves { elliptic_curves })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_extension_supported_groups() -> Result<()> {
|
||||
let raw_supported_groups = vec![0x0, 0x4, 0x0, 0x2, 0x0, 0x1d]; // 0x0, 0xa,
|
||||
let parsed_supported_groups = ExtensionSupportedEllipticCurves {
|
||||
elliptic_curves: vec![NamedCurve::X25519],
|
||||
};
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
parsed_supported_groups.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
raw, raw_supported_groups,
|
||||
"extensionSupportedGroups marshal: got {raw:?}, want {raw_supported_groups:?}"
|
||||
);
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_supported_groups = ExtensionSupportedEllipticCurves::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_supported_groups, parsed_supported_groups,
|
||||
"extensionSupportedGroups unmarshal: got {new_supported_groups:?}, want {parsed_supported_groups:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
53
libs/dtls/src/extension/extension_supported_point_formats.rs
Normal file
53
libs/dtls/src/extension/extension_supported_point_formats.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
#[cfg(test)]
|
||||
mod extension_supported_point_formats_test;
|
||||
|
||||
use super::*;
|
||||
|
||||
const EXTENSION_SUPPORTED_POINT_FORMATS_SIZE: usize = 5;
|
||||
|
||||
pub type EllipticCurvePointFormat = u8;
|
||||
|
||||
pub const ELLIPTIC_CURVE_POINT_FORMAT_UNCOMPRESSED: EllipticCurvePointFormat = 0;
|
||||
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 4492 §5.1.2]
|
||||
///
|
||||
/// [RFC 4492 §5.1.2]: https://tools.ietf.org/html/rfc4492#section-5.1.2
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionSupportedPointFormats {
|
||||
pub(crate) point_formats: Vec<EllipticCurvePointFormat>,
|
||||
}
|
||||
|
||||
impl ExtensionSupportedPointFormats {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::SupportedPointFormats
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
2 + 1 + self.point_formats.len()
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(1 + self.point_formats.len() as u16)?;
|
||||
writer.write_u8(self.point_formats.len() as u8)?;
|
||||
for v in &self.point_formats {
|
||||
writer.write_u8(*v)?;
|
||||
}
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let _ = reader.read_u16::<BigEndian>()?;
|
||||
|
||||
let point_format_count = reader.read_u8()? as usize;
|
||||
let mut point_formats = vec![];
|
||||
for _ in 0..point_format_count {
|
||||
let point_format = reader.read_u8()?;
|
||||
point_formats.push(point_format);
|
||||
}
|
||||
|
||||
Ok(ExtensionSupportedPointFormats { point_formats })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_extension_supported_point_formats() -> Result<()> {
|
||||
let raw_extension_supported_point_formats = vec![0x00, 0x02, 0x01, 0x00]; // 0x00, 0x0b,
|
||||
let parsed_extension_supported_point_formats = ExtensionSupportedPointFormats {
|
||||
point_formats: vec![ELLIPTIC_CURVE_POINT_FORMAT_UNCOMPRESSED],
|
||||
};
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
parsed_extension_supported_point_formats.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
raw, raw_extension_supported_point_formats,
|
||||
"extensionSupportedPointFormats marshal: got {raw:?}, want {raw_extension_supported_point_formats:?}"
|
||||
);
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_extension_supported_point_formats =
|
||||
ExtensionSupportedPointFormats::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_extension_supported_point_formats, parsed_extension_supported_point_formats,
|
||||
"extensionSupportedPointFormats unmarshal: got {new_extension_supported_point_formats:?}, want {parsed_extension_supported_point_formats:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#[cfg(test)]
|
||||
mod extension_supported_signature_algorithms_test;
|
||||
|
||||
use super::*;
|
||||
use crate::signature_hash_algorithm::*;
|
||||
|
||||
const EXTENSION_SUPPORTED_SIGNATURE_ALGORITHMS_HEADER_SIZE: usize = 6;
|
||||
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 5246 §7.4.1.4.1]
|
||||
///
|
||||
/// [RFC 5246 §7.4.1.4.1]: https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionSupportedSignatureAlgorithms {
|
||||
pub(crate) signature_hash_algorithms: Vec<SignatureHashAlgorithm>,
|
||||
}
|
||||
|
||||
impl ExtensionSupportedSignatureAlgorithms {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::SupportedSignatureAlgorithms
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
2 + 2 + self.signature_hash_algorithms.len() * 2
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(2 + 2 * self.signature_hash_algorithms.len() as u16)?;
|
||||
writer.write_u16::<BigEndian>(2 * self.signature_hash_algorithms.len() as u16)?;
|
||||
for v in &self.signature_hash_algorithms {
|
||||
writer.write_u8(v.hash as u8)?;
|
||||
writer.write_u8(v.signature as u8)?;
|
||||
}
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let _ = reader.read_u16::<BigEndian>()?;
|
||||
|
||||
let algorithm_count = reader.read_u16::<BigEndian>()? as usize / 2;
|
||||
let mut signature_hash_algorithms = vec![];
|
||||
for _ in 0..algorithm_count {
|
||||
let hash = reader.read_u8()?.into();
|
||||
let signature = reader.read_u8()?.into();
|
||||
signature_hash_algorithms.push(SignatureHashAlgorithm { hash, signature });
|
||||
}
|
||||
|
||||
Ok(ExtensionSupportedSignatureAlgorithms {
|
||||
signature_hash_algorithms,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_extension_supported_signature_algorithms() -> Result<()> {
|
||||
let raw_extension_supported_signature_algorithms =
|
||||
vec![0x00, 0x08, 0x00, 0x06, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03]; //0x00, 0x0d,
|
||||
let parsed_extension_supported_signature_algorithms = ExtensionSupportedSignatureAlgorithms {
|
||||
signature_hash_algorithms: vec![
|
||||
SignatureHashAlgorithm {
|
||||
hash: HashAlgorithm::Sha256,
|
||||
signature: SignatureAlgorithm::Ecdsa,
|
||||
},
|
||||
SignatureHashAlgorithm {
|
||||
hash: HashAlgorithm::Sha384,
|
||||
signature: SignatureAlgorithm::Ecdsa,
|
||||
},
|
||||
SignatureHashAlgorithm {
|
||||
hash: HashAlgorithm::Sha512,
|
||||
signature: SignatureAlgorithm::Ecdsa,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
parsed_extension_supported_signature_algorithms.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
raw, raw_extension_supported_signature_algorithms,
|
||||
"extensionSupportedSignatureAlgorithms marshal: got {raw:?}, want {raw_extension_supported_signature_algorithms:?}"
|
||||
);
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_extension_supported_signature_algorithms =
|
||||
ExtensionSupportedSignatureAlgorithms::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_extension_supported_signature_algorithms,
|
||||
parsed_extension_supported_signature_algorithms,
|
||||
"extensionSupportedSignatureAlgorithms unmarshal: got {new_extension_supported_signature_algorithms:?}, want {parsed_extension_supported_signature_algorithms:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#[cfg(test)]
|
||||
mod extension_use_extended_master_secret_test;
|
||||
|
||||
use super::*;
|
||||
|
||||
const EXTENSION_USE_EXTENDED_MASTER_SECRET_HEADER_SIZE: usize = 4;
|
||||
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 8422]
|
||||
///
|
||||
/// [RFC 8422]: https://tools.ietf.org/html/rfc8422
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionUseExtendedMasterSecret {
|
||||
pub(crate) supported: bool,
|
||||
}
|
||||
|
||||
impl ExtensionUseExtendedMasterSecret {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::UseExtendedMasterSecret
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
// length
|
||||
writer.write_u16::<BigEndian>(0)?;
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let _ = reader.read_u16::<BigEndian>()?;
|
||||
|
||||
Ok(ExtensionUseExtendedMasterSecret { supported: true })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_extension_use_extended_master_secret() -> Result<()> {
|
||||
let raw_extension_use_extended_master_secret = vec![0x00, 0x00];
|
||||
let parsed_extension_use_extended_master_secret =
|
||||
ExtensionUseExtendedMasterSecret { supported: true };
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
parsed_extension_use_extended_master_secret.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
raw, raw_extension_use_extended_master_secret,
|
||||
"extension_use_extended_master_secret marshal: got {raw:?}, want {raw_extension_use_extended_master_secret:?}"
|
||||
);
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_extension_use_extended_master_secret =
|
||||
ExtensionUseExtendedMasterSecret::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_extension_use_extended_master_secret, parsed_extension_use_extended_master_secret,
|
||||
"extension_use_extended_master_secret unmarshal: got {new_extension_use_extended_master_secret:?}, want {parsed_extension_use_extended_master_secret:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
88
libs/dtls/src/extension/extension_use_srtp.rs
Normal file
88
libs/dtls/src/extension/extension_use_srtp.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
#[cfg(test)]
|
||||
mod extension_use_srtp_test;
|
||||
|
||||
use super::*;
|
||||
|
||||
// SRTPProtectionProfile defines the parameters and options that are in effect for the SRTP processing
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 5764 §4.1.2]
|
||||
///
|
||||
/// [RFC 5764 §4.1.2]: https://tools.ietf.org/html/rfc5764#section-4.1.2
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SrtpProtectionProfile {
|
||||
Srtp_Aes128_Cm_Hmac_Sha1_80 = 0x0001,
|
||||
Srtp_Aes128_Cm_Hmac_Sha1_32 = 0x0002,
|
||||
Srtp_Aead_Aes_128_Gcm = 0x0007,
|
||||
Srtp_Aead_Aes_256_Gcm = 0x0008,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
impl From<u16> for SrtpProtectionProfile {
|
||||
fn from(val: u16) -> Self {
|
||||
match val {
|
||||
0x0001 => SrtpProtectionProfile::Srtp_Aes128_Cm_Hmac_Sha1_80,
|
||||
0x0002 => SrtpProtectionProfile::Srtp_Aes128_Cm_Hmac_Sha1_32,
|
||||
0x0007 => SrtpProtectionProfile::Srtp_Aead_Aes_128_Gcm,
|
||||
0x0008 => SrtpProtectionProfile::Srtp_Aead_Aes_256_Gcm,
|
||||
_ => SrtpProtectionProfile::Unsupported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EXTENSION_USE_SRTPHEADER_SIZE: usize = 6;
|
||||
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 8422]
|
||||
///
|
||||
/// [RFC 8422]: https://tools.ietf.org/html/rfc8422
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionUseSrtp {
|
||||
pub(crate) protection_profiles: Vec<SrtpProtectionProfile>,
|
||||
}
|
||||
|
||||
impl ExtensionUseSrtp {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::UseSrtp
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
2 + 2 + self.protection_profiles.len() * 2 + 1
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(
|
||||
2 + /* MKI Length */ 1 + 2 * self.protection_profiles.len() as u16,
|
||||
)?;
|
||||
writer.write_u16::<BigEndian>(2 * self.protection_profiles.len() as u16)?;
|
||||
for v in &self.protection_profiles {
|
||||
writer.write_u16::<BigEndian>(*v as u16)?;
|
||||
}
|
||||
|
||||
/* MKI Length */
|
||||
writer.write_u8(0x00)?;
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let _ = reader.read_u16::<BigEndian>()?;
|
||||
|
||||
let profile_count = reader.read_u16::<BigEndian>()? as usize / 2;
|
||||
let mut protection_profiles = vec![];
|
||||
for _ in 0..profile_count {
|
||||
let protection_profile = reader.read_u16::<BigEndian>()?.into();
|
||||
protection_profiles.push(protection_profile);
|
||||
}
|
||||
|
||||
/* MKI Length */
|
||||
let _ = reader.read_u8()?;
|
||||
|
||||
Ok(ExtensionUseSrtp {
|
||||
protection_profiles,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_extension_use_srtp() -> Result<()> {
|
||||
let raw_use_srtp = vec![0x00, 0x05, 0x00, 0x02, 0x00, 0x01, 0x00]; //0x00, 0x0e,
|
||||
let parsed_use_srtp = ExtensionUseSrtp {
|
||||
protection_profiles: vec![SrtpProtectionProfile::Srtp_Aes128_Cm_Hmac_Sha1_80],
|
||||
};
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
parsed_use_srtp.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
raw, raw_use_srtp,
|
||||
"extensionUseSRTP marshal: got {raw:?}, want {raw_use_srtp:?}"
|
||||
);
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_use_srtp = ExtensionUseSrtp::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_use_srtp, parsed_use_srtp,
|
||||
"extensionUseSRTP unmarshal: got {new_use_srtp:?}, want {parsed_use_srtp:?}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
130
libs/dtls/src/extension/mod.rs
Normal file
130
libs/dtls/src/extension/mod.rs
Normal file
@@ -0,0 +1,130 @@
|
||||
pub mod extension_server_name;
|
||||
pub mod extension_supported_elliptic_curves;
|
||||
pub mod extension_supported_point_formats;
|
||||
pub mod extension_supported_signature_algorithms;
|
||||
pub mod extension_use_extended_master_secret;
|
||||
pub mod extension_use_srtp;
|
||||
pub mod renegotiation_info;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
use extension_server_name::*;
|
||||
use extension_supported_elliptic_curves::*;
|
||||
use extension_supported_point_formats::*;
|
||||
use extension_supported_signature_algorithms::*;
|
||||
use extension_use_extended_master_secret::*;
|
||||
use extension_use_srtp::*;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::extension::renegotiation_info::ExtensionRenegotiationInfo;
|
||||
|
||||
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum ExtensionValue {
|
||||
ServerName = 0,
|
||||
SupportedEllipticCurves = 10,
|
||||
SupportedPointFormats = 11,
|
||||
SupportedSignatureAlgorithms = 13,
|
||||
UseSrtp = 14,
|
||||
UseExtendedMasterSecret = 23,
|
||||
RenegotiationInfo = 65281,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
impl From<u16> for ExtensionValue {
|
||||
fn from(val: u16) -> Self {
|
||||
match val {
|
||||
0 => ExtensionValue::ServerName,
|
||||
10 => ExtensionValue::SupportedEllipticCurves,
|
||||
11 => ExtensionValue::SupportedPointFormats,
|
||||
13 => ExtensionValue::SupportedSignatureAlgorithms,
|
||||
14 => ExtensionValue::UseSrtp,
|
||||
23 => ExtensionValue::UseExtendedMasterSecret,
|
||||
65281 => ExtensionValue::RenegotiationInfo,
|
||||
_ => ExtensionValue::Unsupported,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
pub enum Extension {
|
||||
ServerName(ExtensionServerName),
|
||||
SupportedEllipticCurves(ExtensionSupportedEllipticCurves),
|
||||
SupportedPointFormats(ExtensionSupportedPointFormats),
|
||||
SupportedSignatureAlgorithms(ExtensionSupportedSignatureAlgorithms),
|
||||
UseSrtp(ExtensionUseSrtp),
|
||||
UseExtendedMasterSecret(ExtensionUseExtendedMasterSecret),
|
||||
RenegotiationInfo(ExtensionRenegotiationInfo),
|
||||
}
|
||||
|
||||
impl Extension {
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
match self {
|
||||
Extension::ServerName(ext) => ext.extension_value(),
|
||||
Extension::SupportedEllipticCurves(ext) => ext.extension_value(),
|
||||
Extension::SupportedPointFormats(ext) => ext.extension_value(),
|
||||
Extension::SupportedSignatureAlgorithms(ext) => ext.extension_value(),
|
||||
Extension::UseSrtp(ext) => ext.extension_value(),
|
||||
Extension::UseExtendedMasterSecret(ext) => ext.extension_value(),
|
||||
Extension::RenegotiationInfo(ext) => ext.extension_value(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
let mut len = 2;
|
||||
|
||||
len += match self {
|
||||
Extension::ServerName(ext) => ext.size(),
|
||||
Extension::SupportedEllipticCurves(ext) => ext.size(),
|
||||
Extension::SupportedPointFormats(ext) => ext.size(),
|
||||
Extension::SupportedSignatureAlgorithms(ext) => ext.size(),
|
||||
Extension::UseSrtp(ext) => ext.size(),
|
||||
Extension::UseExtendedMasterSecret(ext) => ext.size(),
|
||||
Extension::RenegotiationInfo(ext) => ext.size(),
|
||||
};
|
||||
|
||||
len
|
||||
}
|
||||
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(self.extension_value() as u16)?;
|
||||
match self {
|
||||
Extension::ServerName(ext) => ext.marshal(writer),
|
||||
Extension::SupportedEllipticCurves(ext) => ext.marshal(writer),
|
||||
Extension::SupportedPointFormats(ext) => ext.marshal(writer),
|
||||
Extension::SupportedSignatureAlgorithms(ext) => ext.marshal(writer),
|
||||
Extension::UseSrtp(ext) => ext.marshal(writer),
|
||||
Extension::UseExtendedMasterSecret(ext) => ext.marshal(writer),
|
||||
Extension::RenegotiationInfo(ext) => ext.marshal(writer),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let extension_value: ExtensionValue = reader.read_u16::<BigEndian>()?.into();
|
||||
match extension_value {
|
||||
ExtensionValue::ServerName => Ok(Extension::ServerName(
|
||||
ExtensionServerName::unmarshal(reader)?,
|
||||
)),
|
||||
ExtensionValue::SupportedEllipticCurves => Ok(Extension::SupportedEllipticCurves(
|
||||
ExtensionSupportedEllipticCurves::unmarshal(reader)?,
|
||||
)),
|
||||
ExtensionValue::SupportedPointFormats => Ok(Extension::SupportedPointFormats(
|
||||
ExtensionSupportedPointFormats::unmarshal(reader)?,
|
||||
)),
|
||||
ExtensionValue::SupportedSignatureAlgorithms => {
|
||||
Ok(Extension::SupportedSignatureAlgorithms(
|
||||
ExtensionSupportedSignatureAlgorithms::unmarshal(reader)?,
|
||||
))
|
||||
}
|
||||
ExtensionValue::UseSrtp => Ok(Extension::UseSrtp(ExtensionUseSrtp::unmarshal(reader)?)),
|
||||
ExtensionValue::UseExtendedMasterSecret => Ok(Extension::UseExtendedMasterSecret(
|
||||
ExtensionUseExtendedMasterSecret::unmarshal(reader)?,
|
||||
)),
|
||||
ExtensionValue::RenegotiationInfo => Ok(Extension::RenegotiationInfo(
|
||||
ExtensionRenegotiationInfo::unmarshal(reader)?,
|
||||
)),
|
||||
_ => Err(Error::ErrInvalidExtensionType),
|
||||
}
|
||||
}
|
||||
}
|
||||
53
libs/dtls/src/extension/renegotiation_info.rs
Normal file
53
libs/dtls/src/extension/renegotiation_info.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
#[cfg(test)]
|
||||
mod renegotiation_info_test;
|
||||
|
||||
use super::*;
|
||||
use crate::error::Error::ErrInvalidPacketLength;
|
||||
|
||||
const RENEGOTIATION_INFO_HEADER_SIZE: usize = 5;
|
||||
|
||||
/// RenegotiationInfo allows a Client/Server to
|
||||
/// communicate their renegotiation support
|
||||
///
|
||||
/// ## Specifications
|
||||
///
|
||||
/// * [RFC 5746]
|
||||
///
|
||||
/// [RFC 5746]: https://tools.ietf.org/html/rfc5746
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ExtensionRenegotiationInfo {
|
||||
pub(crate) renegotiated_connection: u8,
|
||||
}
|
||||
|
||||
impl ExtensionRenegotiationInfo {
|
||||
// TypeValue returns the extension TypeValue
|
||||
pub fn extension_value(&self) -> ExtensionValue {
|
||||
ExtensionValue::RenegotiationInfo
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
/// marshal encodes the extension
|
||||
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
||||
writer.write_u16::<BigEndian>(1)?; //length
|
||||
writer.write_u8(self.renegotiated_connection)?;
|
||||
|
||||
Ok(writer.flush()?)
|
||||
}
|
||||
|
||||
/// Unmarshal populates the extension from encoded data
|
||||
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
||||
let l = reader.read_u16::<BigEndian>()?; //length
|
||||
if l != 1 {
|
||||
return Err(ErrInvalidPacketLength);
|
||||
}
|
||||
|
||||
let renegotiated_connection = reader.read_u8()?;
|
||||
|
||||
Ok(ExtensionRenegotiationInfo {
|
||||
renegotiated_connection,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
use std::io::{BufReader, BufWriter};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_renegotiation_info() -> Result<()> {
|
||||
let extension = ExtensionRenegotiationInfo {
|
||||
renegotiated_connection: 0,
|
||||
};
|
||||
|
||||
let mut raw = vec![];
|
||||
{
|
||||
let mut writer = BufWriter::<&mut Vec<u8>>::new(raw.as_mut());
|
||||
extension.marshal(&mut writer)?;
|
||||
}
|
||||
|
||||
let mut reader = BufReader::new(raw.as_slice());
|
||||
let new_extension = ExtensionRenegotiationInfo::unmarshal(&mut reader)?;
|
||||
|
||||
assert_eq!(
|
||||
new_extension.renegotiated_connection,
|
||||
extension.renegotiated_connection
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user