88//! This implementation includes RFC 5389 MESSAGE-INTEGRITY authentication using
99//! HMAC-SHA1, transaction ID validation, and fingerprint verification for secure
1010//! STUN operations.
11+ //!
12+ //! # Security Note on Cryptographic Algorithms
13+ //!
14+ //! **IMPORTANT:** This module uses MD5 and SHA1 algorithms as mandated by RFC 5389
15+ //! for STUN protocol compliance. While MD5 and SHA1 are considered cryptographically
16+ //! weak for general purposes, their use here is:
17+ //!
18+ //! 1. **RFC-Mandated**: RFC 5389 Section 15.4 specifically requires HMAC-SHA1 for
19+ //! MESSAGE-INTEGRITY and MD5 for long-term credential key derivation.
20+ //! 2. **Protocol-Specific**: These algorithms are used only for STUN protocol
21+ //! operations, not for general cryptographic purposes in WRAITH.
22+ //! 3. **Contextually Safe**: In the STUN context with proper authentication and
23+ //! message integrity checks, the protocol provides adequate security for its
24+ //! intended NAT traversal purpose.
25+ //!
26+ //! **DO NOT** use MD5 or SHA1 from this module for any other cryptographic
27+ //! operations. For general cryptography in WRAITH, use the strong algorithms
28+ //! provided in the `wraith-crypto` crate (e.g., BLAKE3, ChaCha20-Poly1305, X25519, Ed25519).
1129
1230use hmac:: { Hmac , Mac } ;
31+ // These imports are required by RFC 5389 for STUN protocol compliance.
32+ // DO NOT use for general cryptographic purposes - see security note above.
1333use md5:: Md5 ;
1434use sha1:: Sha1 ;
1535use std:: collections:: HashMap ;
@@ -139,9 +159,17 @@ impl StunAuthentication {
139159 ///
140160 /// For long-term credentials: MD5(username:realm:password)
141161 /// For short-term credentials: password
162+ ///
163+ /// # Security Note
164+ ///
165+ /// This function uses MD5 as required by RFC 5389 Section 15.4 for STUN
166+ /// long-term credential key derivation. This is a protocol requirement
167+ /// and cannot be changed without breaking STUN compatibility.
168+ /// MD5 is used here only for protocol compliance, not for collision resistance.
142169 fn derive_key ( & self ) -> Zeroizing < Vec < u8 > > {
143170 if let Some ( realm) = & self . realm {
144171 // Long-term credentials: MD5(username:realm:password)
172+ // Required by RFC 5389 Section 15.4 - DO NOT change to a different hash
145173 use md5:: Digest ;
146174 let mut hasher = Md5 :: new ( ) ;
147175 hasher. update ( self . username . as_bytes ( ) ) ;
@@ -583,6 +611,13 @@ impl StunMessage {
583611 /// Computes HMAC-SHA1 over the message up to (but not including) the
584612 /// MESSAGE-INTEGRITY attribute itself. Must be called before encoding.
585613 ///
614+ /// # Security Note
615+ ///
616+ /// This function uses HMAC-SHA1 as mandated by RFC 5389 Section 15.4 for
617+ /// STUN MESSAGE-INTEGRITY computation. This is a protocol requirement and
618+ /// cannot be changed without breaking STUN compatibility with other implementations.
619+ /// The use of HMAC-SHA1 here is for protocol compliance only.
620+ ///
586621 /// # Arguments
587622 ///
588623 /// * `auth` - Authentication credentials
@@ -625,7 +660,7 @@ impl StunMessage {
625660 let msg_length = bytes. len ( ) - HEADER_SIZE + 24 ;
626661 bytes[ length_offset..length_offset + 2 ] . copy_from_slice ( & ( msg_length as u16 ) . to_be_bytes ( ) ) ;
627662
628- // Compute HMAC-SHA1
663+ // Compute HMAC-SHA1 (RFC 5389 Section 15.4 requirement)
629664 let key = auth. derive_key ( ) ;
630665 type HmacSha1 = Hmac < Sha1 > ;
631666 let mut mac = HmacSha1 :: new_from_slice ( & key) . expect ( "HMAC can take key of any size" ) ;
@@ -642,6 +677,11 @@ impl StunMessage {
642677 ///
643678 /// Validates that the MESSAGE-INTEGRITY HMAC is correct.
644679 ///
680+ /// # Security Note
681+ ///
682+ /// This function uses HMAC-SHA1 as mandated by RFC 5389 Section 15.4 for
683+ /// STUN MESSAGE-INTEGRITY verification. This is a protocol requirement.
684+ ///
645685 /// # Arguments
646686 ///
647687 /// * `auth` - Authentication credentials
@@ -700,7 +740,7 @@ impl StunMessage {
700740 bytes. extend_from_slice ( & attr. encode ( & temp_msg. transaction_id ) ) ;
701741 }
702742
703- // Compute expected HMAC
743+ // Compute expected HMAC (RFC 5389 Section 15.4 requirement)
704744 let key = auth. derive_key ( ) ;
705745 type HmacSha1 = Hmac < Sha1 > ;
706746 let mut mac = HmacSha1 :: new_from_slice ( & key) . expect ( "HMAC can take key of any size" ) ;
@@ -1359,7 +1399,7 @@ mod tests {
13591399 fn test_authentication_key_derivation_long_term ( ) {
13601400 let auth = StunAuthentication :: new ( "user" , "pass" , Some ( "realm" . to_string ( ) ) ) ;
13611401 let key = auth. derive_key ( ) ;
1362- // Long-term credentials use MD5(username:realm:password)
1402+ // Long-term credentials use MD5(username:realm:password) as mandated by RFC 5389
13631403 assert_eq ! ( key. len( ) , 16 ) ; // MD5 produces 16 bytes
13641404 }
13651405}
0 commit comments