1
1
//! WebRTC connection authentication.
2
2
//!
3
- //! Provides cryptographic authentication for WebRTC connections using SDP hashes
4
- //! and public key encryption to prevent man-in-the-middle attacks.
3
+ //! This module provides cryptographic authentication for WebRTC connections
4
+ //! using SDP hashes and public key encryption to prevent man-in-the-middle
5
+ //! attacks. The authentication mechanism ensures that WebRTC connections are
6
+ //! established only between legitimate peers with verified identities.
7
+ //!
8
+ //! ## Security Model
9
+ //!
10
+ //! The connection authentication process works by:
11
+ //!
12
+ //! 1. **SDP Hash Combination**: Combining the SDP hashes from both the WebRTC
13
+ //! offer and answer to create a unique authentication token
14
+ //! 2. **Public Key Encryption**: Encrypting the authentication data using the
15
+ //! recipient's public key to ensure only they can decrypt it
16
+ //! 3. **Mutual Verification**: Both parties verify each other's ability to
17
+ //! decrypt the authentication data, proving they possess the correct private
18
+ //! keys
19
+ //!
20
+ //! ## Authentication Flow
21
+ //!
22
+ //! ```text
23
+ //! Peer A Peer B
24
+ //! | |
25
+ //! | 1. Create Offer (with SDP) |
26
+ //! |------------------------------------> |
27
+ //! | |
28
+ //! | 2. Create Answer (with SDP) |
29
+ //! | <------------------------------------|
30
+ //! | |
31
+ //! | 3. Generate ConnectionAuth from |
32
+ //! | both SDP hashes |
33
+ //! | |
34
+ //! | 4. Encrypt with peer's public key |
35
+ //! |------------------------------------> |
36
+ //! | |
37
+ //! | 5. Decrypt and verify |
38
+ //! | <------------------------------------|
39
+ //! | |
40
+ //! | 6. Connection authenticated ✓ |
41
+ //! ```
42
+ //!
43
+ //! ## Security Properties
44
+ //!
45
+ //! - **Identity Verification**: Ensures both parties possess the private keys
46
+ //! corresponding to their advertised public keys
47
+ //! - **Man-in-the-Middle Protection**: Prevents attackers from intercepting and
48
+ //! modifying the connection establishment process
49
+ //! - **Replay Attack Prevention**: Uses unique SDP hashes for each connection
50
+ //! attempt, preventing replay attacks
5
51
6
52
use rand:: { CryptoRng , Rng } ;
7
53
use serde:: { Deserialize , Serialize } ;
@@ -10,17 +56,155 @@ use crate::identity::{PublicKey, SecretKey};
10
56
11
57
use super :: { Answer , Offer } ;
12
58
59
+ /// Connection authentication data derived from WebRTC signaling.
60
+ ///
61
+ /// `ConnectionAuth` contains the authentication material generated from the
62
+ /// SDP (Session Description Protocol) hashes of both the WebRTC offer and
63
+ /// answer.
64
+ /// This creates a unique, connection-specific authentication token that can be
65
+ /// used to verify the authenticity of the WebRTC connection.
66
+ ///
67
+ /// ## Construction
68
+ ///
69
+ /// The authentication data is created by concatenating the SDP hashes from both
70
+ /// the offer and answer messages:
71
+ ///
72
+ /// ```text
73
+ /// ConnectionAuth = SDP_Hash(Offer) || SDP_Hash(Answer)
74
+ /// ```
75
+ ///
76
+ /// This ensures that both parties contributed to the authentication material
77
+ /// and that any tampering with either the offer or answer would be detected.
78
+ ///
79
+ /// ## Security Properties
80
+ ///
81
+ /// - **Uniqueness**: Each connection attempt generates unique SDP data,
82
+ /// preventing replay attacks
83
+ /// - **Integrity**: Any modification to the offer or answer changes the hashes,
84
+ /// invalidating the authentication
85
+ /// - **Binding**: Cryptographically binds the authentication to the specific
86
+ /// WebRTC session parameters
87
+ ///
88
+ /// ## Usage
89
+ ///
90
+ /// ```rust
91
+ /// use openmina_p2p::webrtc::{ConnectionAuth, Offer, Answer};
92
+ ///
93
+ /// let connection_auth = ConnectionAuth::new(&offer, &answer);
94
+ /// let encrypted_auth = connection_auth.encrypt(&my_secret_key, &peer_public_key, rng)?;
95
+ /// ```
13
96
#[ derive( Serialize , Deserialize , Debug , Eq , PartialEq , Clone ) ]
14
97
pub struct ConnectionAuth ( Vec < u8 > ) ;
15
98
99
+ /// Encrypted connection authentication data.
100
+ ///
101
+ /// `ConnectionAuthEncrypted` represents the connection authentication data after
102
+ /// it has been encrypted using public key cryptography. The encrypted data is
103
+ /// stored in a fixed-size array of 92 bytes, which corresponds to the output
104
+ /// size of the encryption algorithm used.
105
+ ///
106
+ /// ## Encryption Process
107
+ ///
108
+ /// The encryption uses the recipient's public key to ensure that only the
109
+ /// intended recipient can decrypt and verify the authentication data. This
110
+ /// prevents man-in-the-middle attackers from forging authentication tokens.
111
+ ///
112
+ /// ## Fixed Size
113
+ ///
114
+ /// The 92-byte fixed size is determined by the cryptographic parameters:
115
+ /// - The encryption algorithm produces a deterministic output size
116
+ /// - Fixed sizing enables efficient serialization and network transmission
117
+ /// - Prevents information leakage through size analysis
118
+ ///
119
+ /// ## Network Transmission
120
+ ///
121
+ /// This type is designed for transmission over the network and includes
122
+ /// serialization support for JSON and binary formats.
123
+ ///
124
+ /// ## Example
125
+ ///
126
+ /// ```rust
127
+ /// // After receiving encrypted authentication data
128
+ /// let decrypted_auth = encrypted_auth.decrypt(&my_secret_key, &peer_public_key)?;
129
+ /// // Verify that the decrypted data matches expected values
130
+ /// ```
16
131
#[ derive( Debug , Clone ) ]
17
132
pub struct ConnectionAuthEncrypted ( Box < [ u8 ; 92 ] > ) ;
18
133
19
134
impl ConnectionAuth {
135
+ /// Creates new connection authentication data from WebRTC offer and answer.
136
+ ///
137
+ /// This method generates connection authentication data by concatenating the
138
+ /// SDP hashes from both the WebRTC offer and answer messages. The resulting
139
+ /// authentication token is unique to this specific connection attempt and
140
+ /// binds the authentication to the exact WebRTC session parameters.
141
+ ///
142
+ /// # Parameters
143
+ ///
144
+ /// * `offer` - The WebRTC offer containing SDP data and peer information
145
+ /// * `answer` - The WebRTC answer containing SDP data and peer information
146
+ ///
147
+ /// # Returns
148
+ ///
149
+ /// A new `ConnectionAuth` instance containing the concatenated SDP hashes.
150
+ ///
151
+ /// # Security Considerations
152
+ ///
153
+ /// The authentication data is derived from both the offer and answer, ensuring
154
+ /// that any tampering with either message will result in different authentication
155
+ /// data. This prevents attackers from modifying signaling messages without
156
+ /// detection.
157
+ ///
158
+ /// # Example
159
+ ///
160
+ /// ```rust
161
+ /// use openmina_p2p::webrtc::ConnectionAuth;
162
+ ///
163
+ /// let auth = ConnectionAuth::new(&offer, &answer);
164
+ /// // Use auth for connection verification
165
+ /// ```
20
166
pub fn new ( offer : & Offer , answer : & Answer ) -> Self {
21
167
Self ( [ offer. sdp_hash ( ) , answer. sdp_hash ( ) ] . concat ( ) )
22
168
}
23
169
170
+ /// Encrypts the connection authentication data using public key cryptography.
171
+ ///
172
+ /// This method encrypts the authentication data using the recipient's
173
+ /// public key, ensuring that only the intended recipient (who possesses the
174
+ /// corresponding private key) can decrypt and verify the authentication
175
+ /// token.
176
+ ///
177
+ /// # Parameters
178
+ ///
179
+ /// * `sec_key` - The sender's secret key used for encryption
180
+ /// * `other_pk` - The recipient's public key used for encryption
181
+ /// * `rng` - A cryptographically secure random number generator
182
+ ///
183
+ /// # Returns
184
+ ///
185
+ /// * `Some(ConnectionAuthEncrypted)` if encryption succeeds
186
+ /// * `None` if encryption fails (e.g., due to invalid keys or cryptographic
187
+ /// errors)
188
+ ///
189
+ /// # Security Properties
190
+ ///
191
+ /// - **Confidentiality**: Only the holder of the corresponding private key can
192
+ /// decrypt the authentication data
193
+ /// - **Authenticity**: The encryption process provides assurance about the
194
+ /// sender's identity
195
+ ///
196
+ /// # Example
197
+ ///
198
+ /// ```rust
199
+ /// use rand::thread_rng;
200
+ ///
201
+ /// let mut rng = thread_rng();
202
+ /// let encrypted_auth = connection_auth.encrypt(&my_secret_key, &peer_public_key, &mut rng);
203
+ ///
204
+ /// if let Some(encrypted) = encrypted_auth {
205
+ /// // Send encrypted authentication data to peer
206
+ /// }
207
+ /// ```
24
208
pub fn encrypt (
25
209
& self ,
26
210
sec_key : & SecretKey ,
@@ -33,6 +217,52 @@ impl ConnectionAuth {
33
217
}
34
218
35
219
impl ConnectionAuthEncrypted {
220
+ /// Decrypts the connection authentication data using public key cryptography.
221
+ ///
222
+ /// This method decrypts the authentication data using the recipient's
223
+ /// secret key and the sender's public key. Successful decryption proves
224
+ /// that the sender possesses the private key corresponding to their
225
+ /// advertised public key, providing authentication and preventing
226
+ /// man-in-the-middle attacks.
227
+ ///
228
+ /// # Parameters
229
+ ///
230
+ /// * `sec_key` - The recipient's secret key used for decryption
231
+ /// * `other_pk` - The sender's public key used for decryption
232
+ ///
233
+ /// # Returns
234
+ ///
235
+ /// * `Some(ConnectionAuth)` if decryption succeeds and authentication is valid
236
+ /// * `None` if decryption fails (e.g., due to invalid keys, corrupted data, or
237
+ /// cryptographic errors)
238
+ ///
239
+ /// # Security Verification
240
+ ///
241
+ /// Successful decryption provides several security guarantees:
242
+ ///
243
+ /// - **Identity Verification**: The sender possesses the private key
244
+ /// corresponding to their public key
245
+ /// - **Message Integrity**: The encrypted data has not been tampered with
246
+ /// - **Authenticity**: The authentication data came from the claimed sender
247
+ ///
248
+ /// # Usage in Authentication Flow
249
+ ///
250
+ /// This method is typically called during the final stage of WebRTC connection
251
+ /// establishment to verify the peer's identity before allowing the connection
252
+ /// to proceed.
253
+ ///
254
+ /// # Example
255
+ ///
256
+ /// ```rust
257
+ /// // After receiving encrypted authentication data from peer
258
+ /// if let Some(decrypted_auth) = encrypted_auth.decrypt(&my_secret_key, &peer_public_key) {
259
+ /// // Authentication successful, proceed with connection
260
+ /// println!("Peer authentication verified");
261
+ /// } else {
262
+ /// // Authentication failed, reject connection
263
+ /// println!("Peer authentication failed");
264
+ /// }
265
+ /// ```
36
266
pub fn decrypt ( & self , sec_key : & SecretKey , other_pk : & PublicKey ) -> Option < ConnectionAuth > {
37
267
sec_key
38
268
. decrypt_raw ( other_pk, & * self . 0 )
0 commit comments