xref: /webrtc/dtls/src/extension/mod.rs (revision ffe74184)
1 pub mod extension_server_name;
2 pub mod extension_supported_elliptic_curves;
3 pub mod extension_supported_point_formats;
4 pub mod extension_supported_signature_algorithms;
5 pub mod extension_use_extended_master_secret;
6 pub mod extension_use_srtp;
7 pub mod renegotiation_info;
8 
9 use extension_server_name::*;
10 use extension_supported_elliptic_curves::*;
11 use extension_supported_point_formats::*;
12 use extension_supported_signature_algorithms::*;
13 use extension_use_extended_master_secret::*;
14 use extension_use_srtp::*;
15 
16 use crate::error::*;
17 
18 use crate::extension::renegotiation_info::ExtensionRenegotiationInfo;
19 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
20 use std::io::{Read, Write};
21 
22 // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
23 #[derive(Clone, Debug, PartialEq, Eq)]
24 pub 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 
35 impl From<u16> for ExtensionValue {
from(val: u16) -> Self36     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)]
51 pub 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 
61 impl Extension {
extension_value(&self) -> ExtensionValue62     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 
size(&self) -> usize74     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 
marshal<W: Write>(&self, writer: &mut W) -> Result<()>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 
unmarshal<R: Read>(reader: &mut R) -> Result<Self>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 }
131