1mod connector;
40mod fingerprint;
41mod key_stream;
42mod profile;
43mod session;
44
45use std::{
46 fmt::{self, Display, Formatter, Write},
47 future::Future,
48 io, ptr,
49};
50
51use bytes::Bytes;
52use futures::{Sink, Stream};
53use openssl::{
54 asn1::Asn1Time,
55 hash::MessageDigest,
56 pkey::{HasPrivate, PKeyRef},
57 ssl::{Ssl, SslContext, SslMethod, SslVerifyMode},
58 x509::{X509Ref, X509},
59};
60
61use self::connector::Connector;
62
63pub use msf_rtp::transceiver::{RtpTransceiver, RtpTransceiverOptions, SSRC2ClockRate, SSRCMode};
64
65pub use self::{
66 connector::{MuxedSrtpStream, SrtcpStream, SrtpStream},
67 fingerprint::{CertificateFingerprint, HashFunction, InvalidFingerprint, UnknownHashFunction},
68 profile::SrtpProfileId,
69};
70
71#[derive(Debug)]
73pub struct Error {
74 inner: InternalError,
75}
76
77impl Display for Error {
78 #[inline]
79 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
80 Display::fmt(&self.inner, f)
81 }
82}
83
84impl std::error::Error for Error {}
85
86impl From<openssl::error::ErrorStack> for Error {
87 fn from(err: openssl::error::ErrorStack) -> Self {
88 Self::from(InternalError::from(err))
89 }
90}
91
92impl From<io::Error> for Error {
93 fn from(err: io::Error) -> Self {
94 Self::from(InternalError::from(err))
95 }
96}
97
98impl From<InternalError> for Error {
99 fn from(err: InternalError) -> Self {
100 Self { inner: err }
101 }
102}
103
104#[derive(Debug)]
106enum InternalError {
107 MissingProfile,
108 UnsupportedProfile,
109 InvalidPacketType,
110 InvalidFingerprint(InvalidFingerprint),
111 OpenSslError(OpenSslError),
112 IOError(io::Error),
113}
114
115impl Display for InternalError {
116 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
117 match self {
118 Self::MissingProfile => f.write_str("no SRTP profile selected"),
119 Self::UnsupportedProfile => f.write_str("unsupported SRTP profile"),
120 Self::InvalidPacketType => f.write_str("invalid packet type"),
121 Self::InvalidFingerprint(err) => write!(f, "invalid fingerprint: {err}"),
122 Self::OpenSslError(err) => write!(f, "SSL error: {err}"),
123 Self::IOError(err) => write!(f, "IO error: {err}"),
124 }
125 }
126}
127
128impl std::error::Error for InternalError {}
129
130impl From<InvalidFingerprint> for InternalError {
131 fn from(err: InvalidFingerprint) -> Self {
132 Self::InvalidFingerprint(err)
133 }
134}
135
136impl From<openssl::error::Error> for InternalError {
137 fn from(err: openssl::error::Error) -> Self {
138 Self::OpenSslError(err.into())
139 }
140}
141
142impl From<openssl::error::ErrorStack> for InternalError {
143 fn from(err: openssl::error::ErrorStack) -> Self {
144 Self::OpenSslError(err.into())
145 }
146}
147
148impl From<openssl::ssl::Error> for InternalError {
149 fn from(err: openssl::ssl::Error) -> Self {
150 Self::OpenSslError(err.into())
151 }
152}
153
154impl From<io::Error> for InternalError {
155 fn from(err: io::Error) -> Self {
156 Self::IOError(err)
157 }
158}
159
160#[derive(Debug)]
162enum OpenSslError {
163 Error(openssl::error::Error),
164 ErrorStack(openssl::error::ErrorStack),
165 SslError(openssl::ssl::Error),
166}
167
168impl Display for OpenSslError {
169 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
170 match self {
171 Self::Error(err) => Display::fmt(err, f),
172 Self::ErrorStack(err) => Display::fmt(err, f),
173 Self::SslError(err) => Display::fmt(err, f),
174 }
175 }
176}
177
178impl std::error::Error for OpenSslError {}
179
180impl From<openssl::error::Error> for OpenSslError {
181 fn from(err: openssl::error::Error) -> Self {
182 Self::Error(err)
183 }
184}
185
186impl From<openssl::error::ErrorStack> for OpenSslError {
187 fn from(err: openssl::error::ErrorStack) -> Self {
188 Self::ErrorStack(err)
189 }
190}
191
192impl From<openssl::ssl::Error> for OpenSslError {
193 fn from(err: openssl::ssl::Error) -> Self {
194 Self::SslError(err)
195 }
196}
197
198pub struct SrtpContextBuilder {
200 profiles: Vec<SrtpProfileId>,
201}
202
203impl SrtpContextBuilder {
204 fn new() -> Self {
206 Self {
207 profiles: Vec::new(),
208 }
209 }
210
211 #[inline]
222 pub fn profile(mut self, profile: SrtpProfileId) -> Self {
223 self.profiles.push(profile);
224 self
225 }
226
227 pub fn with_ssl_context(mut self, context: SslContext) -> Result<SrtpContext, Error> {
233 assert!(context.certificate().is_some());
234 assert!(context.private_key().is_some());
235
236 if self.profiles.is_empty() {
237 self.profiles = vec![
238 SrtpProfileId::SRTP_AES128_CM_SHA1_80,
239 SrtpProfileId::SRTP_AES128_CM_SHA1_32,
240 ];
241 }
242
243 let mut profiles = String::new();
244
245 let mut iter = self.profiles.iter();
246
247 if let Some(profile) = iter.next() {
248 let _ = write!(profiles, "{profile}");
249 }
250
251 for profile in iter {
252 let _ = write!(profiles, ":{profile}");
253 }
254
255 let res = SrtpContext {
256 ssl_context: context,
257 srtp_profiles: profiles,
258 };
259
260 Ok(res)
261 }
262
263 pub fn build<T>(self, key: &PKeyRef<T>, cert: &X509Ref) -> Result<SrtpContext, Error>
266 where
267 T: HasPrivate,
268 {
269 let mut ssl_ctx_builder = SslContext::builder(SslMethod::dtls())?;
270
271 ssl_ctx_builder.set_certificate(cert)?;
272 ssl_ctx_builder.set_private_key(key)?;
273
274 self.with_ssl_context(ssl_ctx_builder.build())
275 }
276
277 pub fn self_signed<T>(self, key: &PKeyRef<T>) -> Result<SrtpContext, Error>
280 where
281 T: HasPrivate,
282 {
283 let now = unsafe { libc::time(ptr::null_mut()) };
284
285 let not_before = Asn1Time::from_unix(now)?;
286
287 let mut cert_builder = X509::builder()?;
288
289 cert_builder.set_pubkey(key)?;
290 cert_builder.set_not_before(¬_before)?;
291 cert_builder.sign(key, MessageDigest::sha256())?;
292
293 let public_cert = cert_builder.build();
294
295 self.build(key, &public_cert)
296 }
297}
298
299pub struct SrtpContext {
301 ssl_context: SslContext,
302 srtp_profiles: String,
303}
304
305impl SrtpContext {
306 #[inline]
308 pub fn builder() -> SrtpContextBuilder {
309 SrtpContextBuilder::new()
310 }
311
312 #[inline]
315 pub fn new<T>(key: &PKeyRef<T>, cert: &X509Ref) -> Result<Self, Error>
316 where
317 T: HasPrivate,
318 {
319 Self::builder().build(key, cert)
320 }
321
322 #[inline]
325 pub fn self_signed<T>(key: &PKeyRef<T>) -> Result<Self, Error>
326 where
327 T: HasPrivate,
328 {
329 Self::builder().self_signed(key)
330 }
331
332 #[inline]
339 pub fn from_ssl_context(context: SslContext) -> Result<Self, Error> {
340 Self::builder().with_ssl_context(context)
341 }
342
343 #[inline]
345 pub fn certificate_fingerprint(
346 &self,
347 hash_function: HashFunction,
348 ) -> Result<CertificateFingerprint, Error> {
349 let cert = self.ssl_context.certificate();
350
351 CertificateFingerprint::new(cert.unwrap(), hash_function)
352 }
353
354 pub fn connect_srtp<S>(
357 &self,
358 stream: S,
359 peer_cert_fingerprint: CertificateFingerprint,
360 options: RtpTransceiverOptions,
361 ) -> impl Future<Output = Result<SrtpStream<S>, Error>>
362 where
363 S: Stream<Item = io::Result<Bytes>>,
364 S: Sink<Bytes, Error = io::Error>,
365 S: Unpin,
366 {
367 let connector = self.new_connector(peer_cert_fingerprint);
368
369 async move { connector?.connect_srtp(stream, options).await }
370 }
371
372 pub fn connect_srtcp<S>(
375 &self,
376 stream: S,
377 peer_cert_fingerprint: CertificateFingerprint,
378 ) -> impl Future<Output = Result<SrtcpStream<S>, Error>>
379 where
380 S: Stream<Item = io::Result<Bytes>>,
381 S: Sink<Bytes, Error = io::Error>,
382 S: Unpin,
383 {
384 let connector = self.new_connector(peer_cert_fingerprint);
385
386 async move { connector?.connect_srtcp(stream).await }
387 }
388
389 pub fn connect_muxed<S>(
392 &self,
393 stream: S,
394 peer_cert_fingerprint: CertificateFingerprint,
395 options: RtpTransceiverOptions,
396 ) -> impl Future<Output = Result<MuxedSrtpStream<S>, Error>>
397 where
398 S: Stream<Item = io::Result<Bytes>>,
399 S: Sink<Bytes, Error = io::Error>,
400 S: Unpin,
401 {
402 let connector = self.new_connector(peer_cert_fingerprint);
403
404 async move { connector?.connect_muxed(stream, options).await }
405 }
406
407 pub fn accept_srtp<S>(
410 &self,
411 stream: S,
412 peer_cert_fingerprint: CertificateFingerprint,
413 options: RtpTransceiverOptions,
414 ) -> impl Future<Output = Result<SrtpStream<S>, Error>>
415 where
416 S: Stream<Item = io::Result<Bytes>>,
417 S: Sink<Bytes, Error = io::Error>,
418 S: Unpin,
419 {
420 let connector = self.new_connector(peer_cert_fingerprint);
421
422 async move { connector?.accept_srtp(stream, options).await }
423 }
424
425 pub fn accept_srtcp<S>(
428 &self,
429 stream: S,
430 peer_cert_fingerprint: CertificateFingerprint,
431 ) -> impl Future<Output = Result<SrtcpStream<S>, Error>>
432 where
433 S: Stream<Item = io::Result<Bytes>>,
434 S: Sink<Bytes, Error = io::Error>,
435 S: Unpin,
436 {
437 let connector = self.new_connector(peer_cert_fingerprint);
438
439 async move { connector?.accept_srtcp(stream).await }
440 }
441
442 pub fn accept_muxed<S>(
445 &self,
446 stream: S,
447 peer_cert_fingerprint: CertificateFingerprint,
448 options: RtpTransceiverOptions,
449 ) -> impl Future<Output = Result<MuxedSrtpStream<S>, Error>>
450 where
451 S: Stream<Item = io::Result<Bytes>>,
452 S: Sink<Bytes, Error = io::Error>,
453 S: Unpin,
454 {
455 let connector = self.new_connector(peer_cert_fingerprint);
456
457 async move { connector?.accept_muxed(stream, options).await }
458 }
459
460 fn new_connector(
462 &self,
463 peer_cert_fingerprint: CertificateFingerprint,
464 ) -> Result<Connector, InternalError> {
465 let mut ssl = Ssl::new(&self.ssl_context)?;
466
467 ssl.set_tlsext_use_srtp(&self.srtp_profiles)?;
468
469 let verify_mode = SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT;
470
471 ssl.set_verify_callback(verify_mode, move |_, store| {
472 if let Some(chain) = store.chain() {
473 if let Some(cert) = chain.get(0) {
474 if let Ok(success) = peer_cert_fingerprint.verify(cert) {
475 return success;
476 }
477 }
478 }
479
480 false
481 });
482
483 Ok(Connector::new(ssl))
484 }
485}