refactor: 将 DTLS 本地依赖迁移到 libs 目录

This commit is contained in:
mofeng-git
2026-10-01 22:46:36 +08:00
parent 2f60e61dd5
commit 4f59e78179
99 changed files with 2 additions and 2 deletions

View 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 })
}
}

View File

@@ -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(())
}

View File

@@ -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 })
}
}

View File

@@ -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(())
}

View 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 })
}
}

View File

@@ -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(())
}

View File

@@ -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,
})
}
}

View File

@@ -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(())
}

View File

@@ -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 })
}
}

View File

@@ -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(())
}

View 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,
})
}
}

View File

@@ -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(())
}

View 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),
}
}
}

View 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,
})
}
}

View File

@@ -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(())
}