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