webrtc_dtls/extension/
mod.rs

1pub mod extension_server_name;
2pub mod extension_supported_elliptic_curves;
3pub mod extension_supported_point_formats;
4pub mod extension_supported_signature_algorithms;
5pub mod extension_use_extended_master_secret;
6pub mod extension_use_srtp;
7pub mod renegotiation_info;
8
9use std::io::{Read, Write};
10
11use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
12use extension_server_name::*;
13use extension_supported_elliptic_curves::*;
14use extension_supported_point_formats::*;
15use extension_supported_signature_algorithms::*;
16use extension_use_extended_master_secret::*;
17use extension_use_srtp::*;
18
19use crate::error::*;
20use crate::extension::renegotiation_info::ExtensionRenegotiationInfo;
21
22// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
23#[derive(Clone, Debug, PartialEq, Eq)]
24pub enum ExtensionValue {
25    ServerName = 0,
26    SupportedEllipticCurves = 10,
27    SupportedPointFormats = 11,
28    SupportedSignatureAlgorithms = 13,
29    UseSrtp = 14,
30    UseExtendedMasterSecret = 23,
31    RenegotiationInfo = 65281,
32    Unsupported,
33}
34
35impl From<u16> for ExtensionValue {
36    fn from(val: u16) -> Self {
37        match val {
38            0 => ExtensionValue::ServerName,
39            10 => ExtensionValue::SupportedEllipticCurves,
40            11 => ExtensionValue::SupportedPointFormats,
41            13 => ExtensionValue::SupportedSignatureAlgorithms,
42            14 => ExtensionValue::UseSrtp,
43            23 => ExtensionValue::UseExtendedMasterSecret,
44            65281 => ExtensionValue::RenegotiationInfo,
45            _ => ExtensionValue::Unsupported,
46        }
47    }
48}
49
50#[derive(PartialEq, Eq, Debug, Clone)]
51pub enum Extension {
52    ServerName(ExtensionServerName),
53    SupportedEllipticCurves(ExtensionSupportedEllipticCurves),
54    SupportedPointFormats(ExtensionSupportedPointFormats),
55    SupportedSignatureAlgorithms(ExtensionSupportedSignatureAlgorithms),
56    UseSrtp(ExtensionUseSrtp),
57    UseExtendedMasterSecret(ExtensionUseExtendedMasterSecret),
58    RenegotiationInfo(ExtensionRenegotiationInfo),
59}
60
61impl Extension {
62    pub fn extension_value(&self) -> ExtensionValue {
63        match self {
64            Extension::ServerName(ext) => ext.extension_value(),
65            Extension::SupportedEllipticCurves(ext) => ext.extension_value(),
66            Extension::SupportedPointFormats(ext) => ext.extension_value(),
67            Extension::SupportedSignatureAlgorithms(ext) => ext.extension_value(),
68            Extension::UseSrtp(ext) => ext.extension_value(),
69            Extension::UseExtendedMasterSecret(ext) => ext.extension_value(),
70            Extension::RenegotiationInfo(ext) => ext.extension_value(),
71        }
72    }
73
74    pub fn size(&self) -> usize {
75        let mut len = 2;
76
77        len += match self {
78            Extension::ServerName(ext) => ext.size(),
79            Extension::SupportedEllipticCurves(ext) => ext.size(),
80            Extension::SupportedPointFormats(ext) => ext.size(),
81            Extension::SupportedSignatureAlgorithms(ext) => ext.size(),
82            Extension::UseSrtp(ext) => ext.size(),
83            Extension::UseExtendedMasterSecret(ext) => ext.size(),
84            Extension::RenegotiationInfo(ext) => ext.size(),
85        };
86
87        len
88    }
89
90    pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
91        writer.write_u16::<BigEndian>(self.extension_value() as u16)?;
92        match self {
93            Extension::ServerName(ext) => ext.marshal(writer),
94            Extension::SupportedEllipticCurves(ext) => ext.marshal(writer),
95            Extension::SupportedPointFormats(ext) => ext.marshal(writer),
96            Extension::SupportedSignatureAlgorithms(ext) => ext.marshal(writer),
97            Extension::UseSrtp(ext) => ext.marshal(writer),
98            Extension::UseExtendedMasterSecret(ext) => ext.marshal(writer),
99            Extension::RenegotiationInfo(ext) => ext.marshal(writer),
100        }
101    }
102
103    pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
104        let extension_value: ExtensionValue = reader.read_u16::<BigEndian>()?.into();
105        match extension_value {
106            ExtensionValue::ServerName => Ok(Extension::ServerName(
107                ExtensionServerName::unmarshal(reader)?,
108            )),
109            ExtensionValue::SupportedEllipticCurves => Ok(Extension::SupportedEllipticCurves(
110                ExtensionSupportedEllipticCurves::unmarshal(reader)?,
111            )),
112            ExtensionValue::SupportedPointFormats => Ok(Extension::SupportedPointFormats(
113                ExtensionSupportedPointFormats::unmarshal(reader)?,
114            )),
115            ExtensionValue::SupportedSignatureAlgorithms => {
116                Ok(Extension::SupportedSignatureAlgorithms(
117                    ExtensionSupportedSignatureAlgorithms::unmarshal(reader)?,
118                ))
119            }
120            ExtensionValue::UseSrtp => Ok(Extension::UseSrtp(ExtensionUseSrtp::unmarshal(reader)?)),
121            ExtensionValue::UseExtendedMasterSecret => Ok(Extension::UseExtendedMasterSecret(
122                ExtensionUseExtendedMasterSecret::unmarshal(reader)?,
123            )),
124            ExtensionValue::RenegotiationInfo => Ok(Extension::RenegotiationInfo(
125                ExtensionRenegotiationInfo::unmarshal(reader)?,
126            )),
127            _ => Err(Error::ErrInvalidExtensionType),
128        }
129    }
130}