1#![allow(unreachable_patterns, dead_code, unused_variables)]
2
3use std::collections::VecDeque;
4use std::fmt;
5use std::time::Instant;
6
7use crate::net::DatagramSend;
8
9use super::CryptoProvider;
10use super::{CryptoError, Fingerprint, KeyingMaterial, SrtpProfile};
11
12const DTLS_CERT_IDENTITY: &str = "WebRTC";
19
20pub enum DtlsEvent {
22 Connected,
24
25 SrtpKeyingMaterial(KeyingMaterial, SrtpProfile),
27
28 RemoteFingerprint(Fingerprint),
32
33 Data(Vec<u8>),
35}
36
37#[derive(Clone, Debug, Default)]
39pub enum DtlsPKeyType {
40 Rsa2048,
42 #[default]
44 EcDsaP256,
45}
46
47#[derive(Clone, Debug)]
49pub struct DtlsCertOptions {
50 pub common_name: String,
52 pub pkey_type: DtlsPKeyType,
54}
55
56impl Default for DtlsCertOptions {
57 fn default() -> Self {
58 Self {
59 common_name: DTLS_CERT_IDENTITY.into(),
60 pkey_type: Default::default(),
61 }
62 }
63}
64
65#[derive(Clone)]
67pub struct DtlsCert(DtlsCertInner);
68
69#[derive(Debug, Clone)]
70enum DtlsCertInner {
71 #[cfg(feature = "openssl")]
72 OpenSsl(super::ossl::OsslDtlsCert),
73 #[cfg(not(feature = "openssl"))]
74 OpenSsl(DummyCert),
75 #[cfg(all(feature = "wincrypto", target_os = "windows"))]
76 WinCrypto(super::wincrypto::WinCryptoDtlsCert),
77 #[cfg(not(all(feature = "wincrypto", target_os = "windows")))]
78 WinCrypto(DummyCert),
79}
80
81impl DtlsCert {
82 pub fn new(p: CryptoProvider, opts: DtlsCertOptions) -> Self {
91 let inner = match p {
92 CryptoProvider::OpenSsl => {
93 #[cfg(feature = "openssl")]
94 {
95 let cert = super::ossl::OsslDtlsCert::new(opts);
96 DtlsCertInner::OpenSsl(cert)
97 }
98 #[cfg(not(feature = "openssl"))]
99 {
100 DtlsCertInner::OpenSsl(DummyCert(p))
101 }
102 }
103 CryptoProvider::WinCrypto => {
104 #[cfg(all(feature = "wincrypto", target_os = "windows"))]
105 {
106 let cert = super::wincrypto::WinCryptoDtlsCert::new(opts);
107 DtlsCertInner::WinCrypto(cert)
108 }
109 #[cfg(not(all(feature = "wincrypto", target_os = "windows")))]
110 {
111 DtlsCertInner::WinCrypto(DummyCert(p))
112 }
113 }
114 };
115
116 DtlsCert(inner)
117 }
118
119 pub(crate) fn crypto_provider(&self) -> CryptoProvider {
120 match self.0 {
121 DtlsCertInner::OpenSsl(_) => CryptoProvider::OpenSsl,
122 DtlsCertInner::WinCrypto(_) => CryptoProvider::WinCrypto,
123 }
124 }
125
126 pub fn fingerprint(&self) -> Fingerprint {
130 match &self.0 {
131 DtlsCertInner::OpenSsl(v) => v.fingerprint(),
132 DtlsCertInner::WinCrypto(v) => v.fingerprint(),
133 _ => unreachable!(),
134 }
135 }
136
137 pub(crate) fn create_dtls_impl(&self) -> Result<DtlsImpl, CryptoError> {
138 let imp = match &self.0 {
139 DtlsCertInner::OpenSsl(v) => DtlsImpl::OpenSsl(v.new_dtls_impl()?),
140 DtlsCertInner::WinCrypto(v) => DtlsImpl::WinCrypto(v.new_dtls_impl()?),
141 };
142
143 Ok(imp)
144 }
145}
146
147impl fmt::Debug for DtlsCert {
148 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149 match &self.0 {
150 DtlsCertInner::OpenSsl(c) => c.fmt(f),
151 DtlsCertInner::WinCrypto(c) => c.fmt(f),
152 _ => unreachable!(),
153 }
154 }
155}
156
157pub trait DtlsInner: Sized {
158 fn set_active(&mut self, active: bool);
163
164 fn handle_handshake(&mut self, o: &mut VecDeque<DtlsEvent>) -> Result<bool, CryptoError>;
166
167 fn is_active(&self) -> Option<bool>;
169
170 fn handle_receive(&mut self, m: &[u8], o: &mut VecDeque<DtlsEvent>) -> Result<(), CryptoError>;
172
173 fn poll_datagram(&mut self) -> Option<DatagramSend>;
175
176 fn poll_timeout(&mut self, now: Instant) -> Option<Instant>;
178
179 fn handle_input(&mut self, data: &[u8]) -> Result<(), CryptoError>;
181
182 fn is_connected(&self) -> bool;
184}
185
186pub(crate) enum DtlsImpl {
187 #[cfg(feature = "openssl")]
188 OpenSsl(super::ossl::OsslDtlsImpl),
189 #[cfg(not(feature = "openssl"))]
190 OpenSsl(DummyDtlsImpl),
191 #[cfg(all(feature = "wincrypto", target_os = "windows"))]
192 WinCrypto(super::wincrypto::WinCryptoDtls),
193 #[cfg(not(all(feature = "wincrypto", target_os = "windows")))]
194 WinCrypto(DummyDtlsImpl),
195}
196
197impl DtlsImpl {
198 pub fn set_active(&mut self, active: bool) {
199 match self {
200 DtlsImpl::OpenSsl(v) => v.set_active(active),
201 DtlsImpl::WinCrypto(v) => v.set_active(active),
202 }
203 }
204
205 pub fn handle_handshake(&mut self, o: &mut VecDeque<DtlsEvent>) -> Result<bool, CryptoError> {
206 match self {
207 DtlsImpl::OpenSsl(i) => i.handle_handshake(o),
208 DtlsImpl::WinCrypto(i) => i.handle_handshake(o),
209 }
210 }
211
212 pub fn is_active(&self) -> Option<bool> {
213 match self {
214 DtlsImpl::OpenSsl(i) => i.is_active(),
215 DtlsImpl::WinCrypto(i) => i.is_active(),
216 }
217 }
218
219 pub fn handle_receive(
220 &mut self,
221 m: &[u8],
222 o: &mut VecDeque<DtlsEvent>,
223 ) -> Result<(), CryptoError> {
224 match self {
225 DtlsImpl::OpenSsl(i) => i.handle_receive(m, o),
226 DtlsImpl::WinCrypto(i) => i.handle_receive(m, o),
227 }
228 }
229
230 pub fn poll_datagram(&mut self) -> Option<DatagramSend> {
231 match self {
232 DtlsImpl::OpenSsl(i) => i.poll_datagram(),
233 DtlsImpl::WinCrypto(i) => i.poll_datagram(),
234 }
235 }
236
237 pub fn poll_timeout(&mut self, now: Instant) -> Option<Instant> {
238 match self {
239 DtlsImpl::OpenSsl(i) => i.poll_timeout(now),
240 DtlsImpl::WinCrypto(i) => i.poll_timeout(now),
241 }
242 }
243
244 pub fn handle_input(&mut self, data: &[u8]) -> Result<(), CryptoError> {
245 match self {
246 DtlsImpl::OpenSsl(i) => i.handle_input(data),
247 DtlsImpl::WinCrypto(i) => i.handle_input(data),
248 }
249 }
250
251 pub fn is_connected(&self) -> bool {
252 match self {
253 DtlsImpl::OpenSsl(i) => i.is_connected(),
254 DtlsImpl::WinCrypto(i) => i.is_connected(),
255 }
256 }
257}
258
259#[derive(Debug, Clone)]
260struct DummyCert(CryptoProvider);
261
262impl DummyCert {
263 fn fingerprint(&self) -> Fingerprint {
264 panic!("Must enable feature: {}", self.0)
265 }
266
267 fn new_dtls_impl(&self) -> Result<DummyDtlsImpl, CryptoError> {
268 panic!("Must enable feature: {}", self.0)
269 }
270}
271
272pub struct DummyDtlsImpl(CryptoProvider);
273
274impl DummyDtlsImpl {
275 fn set_active(&self, active: bool) {
276 panic!("Must enable feature: {}", self.0)
277 }
278
279 fn handle_handshake(&self, o: &mut VecDeque<DtlsEvent>) -> Result<bool, CryptoError> {
280 panic!("Must enable feature: {}", self.0)
281 }
282
283 fn is_active(&self) -> Option<bool> {
284 panic!("Must enable feature: {}", self.0)
285 }
286
287 fn handle_receive(&self, m: &[u8], o: &mut VecDeque<DtlsEvent>) -> Result<(), CryptoError> {
288 panic!("Must enable feature: {}", self.0)
289 }
290
291 fn poll_datagram(&self) -> Option<DatagramSend> {
292 panic!("Must enable feature: {}", self.0)
293 }
294
295 fn poll_timeout(&self, now: Instant) -> Option<Instant> {
296 panic!("Must enable feature: {}", self.0)
297 }
298
299 fn handle_input(&self, data: &[u8]) -> Result<(), CryptoError> {
300 panic!("Must enable feature: {}", self.0)
301 }
302
303 fn is_connected(&self) -> bool {
304 panic!("Must enable feature: {}", self.0)
305 }
306}