You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: src/servers/udp/connection_cookie.rs
+54-33
Original file line number
Diff line number
Diff line change
@@ -1,31 +1,32 @@
1
-
//! Module for generating and verifying connection IDs (cookies) used in the UDP tracker protocol.
1
+
//! Module for Generating and Verifying Connection IDs (Cookies) in the UDP Tracker Protocol
2
2
//!
3
3
//! **Overview:**
4
4
//!
5
-
//! In the BitTorrent UDP tracker protocol, clients must establish a connection by obtaining a connection ID from the server. This connection ID helps prevent IP spoofing and replay attacks by ensuring that only legitimate clients can interact with the tracker.
5
+
//! In the `BitTorrent` UDP tracker protocol, clients initiate communication by obtaining a connection ID from the server. This connection ID serves as a safeguard against IP spoofing and replay attacks, ensuring that only legitimate clients can interact with the tracker.
6
6
//!
7
-
//! Instead of storing connection IDs on the server (which would require maintaining state), this module implements a stateless method for generating and verifying connection IDs based on the client's fingerprint (typically derived from the client's IP address) and the time of issuance.
7
+
//! To maintain a stateless server architecture, this module implements a method for generating and verifying connection IDs based on the client's fingerprint (typically derived from the client's IP address) and the time of issuance, without storing state on the server.
8
8
//!
9
-
//! The Connection ID is an encrypted opaque cookie that he held by the client. Therefore endianness is not a concern as the same server checks the cookie as produced it.
9
+
//! The connection ID is an encrypted, opaque cookie held by the client. Since the same server that generates the cookie also validates it, endianness is not a concern.
10
10
//!
11
11
//! **Connection ID Generation Algorithm:**
12
12
//!
13
-
//! The connection ID is generated using the following steps:
14
-
//!
15
13
//! 1. **Issue Time (`issue_at`):**
16
14
//! - Obtain the current time as a 64-bit floating-point number (`f64`), representing seconds since the Unix epoch.
17
15
//!
18
16
//! 2. **Fingerprint:**
19
17
//! - Use an 8-byte fingerprint unique to the client (e.g., derived from the client's IP address).
20
18
//!
21
19
//! 3. **Assemble Cookie Value:**
22
-
//! - Interpret the bytes of `issue_at` as a 64-bit integer (`i64`) without changing the bit pattern.
23
-
//! - Interpret the fingerprint bytes as an `i64` in the same way.
//! - Use a symmetric block cipher (from `Current::get_cipher()`) to encrypt `cookie_value`.
29
+
//! - Encrypt `cookie_value` using a symmetric block cipher obtained from `Current::get_cipher()`.
29
30
//! - The encrypted `cookie_value` becomes the connection ID sent to the client.
30
31
//!
31
32
//! **Connection ID Verification Algorithm:**
@@ -34,62 +35,82 @@
34
35
//!
35
36
//! 1. **Decrypt Connection ID:**
36
37
//! - Decrypt the received connection ID using the same cipher to retrieve `cookie_value`.
37
-
//! - **Important Note:** The decryption is non-authenticated. This means it does not verify the integrity or authenticity of the ciphertext. The decrypted `cookie_value` can be any byte sequence, including manipulated data.
38
+
//! - *Important:* The decryption is non-authenticated, meaning it does not verify the integrity or authenticity of the ciphertext. The decrypted `cookie_value` can be any byte sequence, including manipulated data.
//! - Reinterpret `issue_at_i64` bytes as an `f64` to get `issue_time`.
44
48
//!
45
49
//! 3. **Validate Issue Time:**
46
50
//! - **Handling Arbitrary `issue_time` Values:**
47
-
//! - Since the decrypted `cookie_value` can be arbitrary, `issue_time` can be any `f64` value, including special values like `NaN`, positive or negative infinity, and subnormal numbers.
51
+
//! - Since the decrypted `cookie_value` may be arbitrary, `issue_time` can be any `f64` value, including special values like `NaN`, positive or negative infinity, and subnormal numbers.
48
52
//! - **Validation Steps:**
49
53
//! - **Step 1:** Check if `issue_time` is finite using `issue_time.is_finite()`.
50
54
//! - If `issue_time` is `NaN` or infinite, it is considered invalid.
51
-
//! - **Step 2:** Perform range checks only if `issue_time` is finite:
52
-
//! - Check if `issue_time >= min` and `issue_time <= max`.
55
+
//! - **Step 2:** If `issue_time` is finite, perform range checks:
56
+
//! - Verify that `min <= issue_time <= max`.
53
57
//! - If `issue_time` passes these checks, accept the connection ID; otherwise, reject it with an appropriate error.
54
58
//!
55
59
//! **Security Considerations:**
56
60
//!
57
61
//! - **Non-Authenticated Encryption:**
58
-
//! - The block size is 8-bytes, there is no good authenticated encryption algorithm that will work with 8-bytes.
59
-
//! - It is not an option to expand to 16-bytes, as the protocol is an external and widely adopted deployed standard.
60
-
//! - Because the cipher does not provide authentication, attackers could forge or manipulate connection IDs.
61
-
//! - However, the probability of an arbitrary 64-bit value decrypting to a valid `issue_time` within the acceptable range is extremely low, and is thus used a form of authentication.
62
+
//! - Due to protocol constraints (an 8-byte connection ID), using an authenticated encryption algorithm is not feasible.
63
+
//! - As a result, attackers might attempt to forge or manipulate connection IDs.
64
+
//! - However, the probability of an arbitrary 64-bit value decrypting to a valid `issue_time` within the acceptable range is extremely low, effectively serving as a form of authentication.
62
65
//!
63
66
//! - **Handling Special `f64` Values:**
64
-
//! - By checking `issue_time.is_finite()`, we prevent `NaN` and infinite values from passing the validation.
65
-
//! - This ensures that only valid, finite timestamps are considered.
67
+
//! - By checking `issue_time.is_finite()`, the implementation excludes `NaN` and infinite values, ensuring that only valid, finite timestamps are considered.
66
68
//!
67
69
//! - **Probability of Successful Attack:**
68
-
//! - Given the narrow valid time window (usually 2 minutes) compared to the vast range of `f64`, the chance of successfully guessing a valid `issue_time` is negligible.
70
+
//! - Given the narrow valid time window (usually around 2 minutes) compared to the vast range of `f64` values, the chance of successfully guessing a valid `issue_time` is negligible.
71
+
//!
72
+
//! **Key Points:**
73
+
//!
74
+
//! - The server maintains a stateless design, reducing resource consumption and complexity.
75
+
//! - Wrapping arithmetic ensures that the addition and subtraction of `i64` values are safe from overflow or underflow issues.
76
+
//! - The validation process is robust against malformed or malicious connection IDs due to stringent checks on the deserialized `issue_time`.
77
+
//! - The module leverages existing cryptographic primitives while acknowledging and addressing the limitations imposed by the protocol's specifications.
69
78
//!
70
79
71
80
use aquatic_udp_protocol::ConnectionIdasCookie;
72
81
use cookie_builder::{assemble, decode, disassemble, encode};
0 commit comments