p2p/webrtc/
connection_auth.rs

1use rand::{CryptoRng, Rng};
2use serde::{Deserialize, Serialize};
3
4use crate::identity::{PublicKey, SecretKey};
5
6use super::{Answer, Offer};
7
8#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
9pub struct ConnectionAuth(Vec<u8>);
10
11#[derive(Debug, Clone)]
12pub struct ConnectionAuthEncrypted(Box<[u8; 92]>);
13
14impl ConnectionAuth {
15    pub fn new(offer: &Offer, answer: &Answer) -> Self {
16        Self([offer.sdp_hash(), answer.sdp_hash()].concat())
17    }
18
19    pub fn encrypt(
20        &self,
21        sec_key: &SecretKey,
22        other_pk: &PublicKey,
23        rng: impl Rng + CryptoRng,
24    ) -> Option<ConnectionAuthEncrypted> {
25        let bytes = sec_key.encrypt_raw(other_pk, rng, &self.0).ok()?;
26        bytes.try_into().ok()
27    }
28}
29
30impl ConnectionAuthEncrypted {
31    pub fn decrypt(&self, sec_key: &SecretKey, other_pk: &PublicKey) -> Option<ConnectionAuth> {
32        sec_key
33            .decrypt_raw(other_pk, &*self.0)
34            .map(ConnectionAuth)
35            .ok()
36    }
37}
38
39impl Serialize for ConnectionAuthEncrypted {
40    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41    where
42        S: serde::Serializer,
43    {
44        self.0.to_vec().serialize(serializer)
45    }
46}
47
48impl<'de> Deserialize<'de> for ConnectionAuthEncrypted {
49    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
50    where
51        D: serde::Deserializer<'de>,
52    {
53        Vec::deserialize(deserializer).and_then(|v| {
54            use serde::de::Error;
55            v.try_into().map_err(Error::custom)
56        })
57    }
58}
59
60impl TryFrom<Vec<u8>> for ConnectionAuthEncrypted {
61    type Error = &'static str;
62
63    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
64        value.as_slice().try_into()
65    }
66}
67
68impl TryFrom<&[u8]> for ConnectionAuthEncrypted {
69    type Error = &'static str;
70
71    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
72        value
73            .try_into()
74            .map(|v| Self(Box::new(v)))
75            .map_err(|_| "ConnectionAuthEncrypted not in expected size")
76    }
77}
78
79impl AsRef<[u8]> for ConnectionAuthEncrypted {
80    fn as_ref(&self) -> &[u8] {
81        &*self.0
82    }
83}