diff --git a/README.md b/README.md index f3356c4..5e41434 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# SecureBit.chat v4.4.18 +# SecureBit.chat v4.4.99
@@ -31,7 +31,7 @@ SecureBit.chat is a revolutionary peer-to-peer messenger that prioritizes your p --- -## ✨ What's New in v4.4.18 +## ✨ What's New in v4.4.99 ### 🔔 Secure Browser Notifications - Smart delivery when user is away from chat tab @@ -54,6 +54,7 @@ SecureBit.chat is a revolutionary peer-to-peer messenger that prioritizes your p - **Enhanced MITM Protection** - Multi-layer defense system - **Secure Key Storage** - WeakMap-based isolation - **Production-Ready Logging** - Data sanitization and privacy protection +- **HKDF Key Derivation** - RFC 5869 compliant key separation and derivation --- @@ -93,7 +94,7 @@ SecureBit.chat is a revolutionary peer-to-peer messenger that prioritizes your p 16. ASN.1 complete key structure verification 17. OID validation for algorithms and curves 18. EC point format and structure verification -19. Smart notifications with XSS protection +19. HKDF key derivation with proper key separation --- @@ -169,7 +170,7 @@ Modern browser with WebRTC support (Chrome 60+, Firefox 60+, Safari 12+), HTTPS ## 🗺️ Roadmap -**Current: v4.4.18** - Browser Notifications & Code Cleanup ✅ +**Current: v4.4.99** - Browser Notifications & Code Cleanup ✅ **Next Releases:** @@ -335,7 +336,7 @@ MIT License - see **LICENSE** file for details. --- -**Latest Release: v4.4.18** - Browser Notifications & Code Cleanup +**Latest Release: v4.4.99** - Browser Notifications & Code Cleanup [🚀 Try Now](https://securebitchat.github.io/securebit-chat/) • [⭐ Star on GitHub](https://github.com/SecureBitChat/securebit-chat) diff --git a/SECURITY.md b/SECURITY.md index fb5708e..99bb409 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -19,6 +19,7 @@ SecureBit.chat is built with security-first principles and implements **military - **Enhanced Replay Protection:** Multi-factor protection with sequence numbers, message IDs, and timestamps - **Secure Key Storage:** WeakMap-based isolation preventing direct access to sensitive keys - **Key Security Monitoring:** Automatic validation, rotation, and emergency wipe capabilities +- **HKDF Key Derivation:** RFC 5869 compliant key separation with proper salt and info parameters ### Advanced Traffic Obfuscation - **Packet Padding:** Random padding (64-512 bytes) to hide real message sizes @@ -116,7 +117,7 @@ We maintain a hall of fame for security researchers who help improve SecureBit.c ## 📊 Security Architecture (Stage 5) ``` -18-Layer Security Architecture: +19-Layer Security Architecture: ├── Layer 1: Enhanced Authentication (ECDSA P-384 + SHA-384) ├── Layer 2: Key Exchange (ECDH P-384, non-extractable keys) ├── Layer 3: Metadata Protection (AES-256-GCM + 64-byte salt) @@ -134,7 +135,8 @@ We maintain a hall of fame for security researchers who help improve SecureBit.c ├── Layer 15: Production Logging (Data sanitization) ├── Layer 16: ASN.1 Validation (Complete key structure verification) ├── Layer 17: OID Validation (Algorithm and curve verification) -└── Layer 18: EC Point Validation (Format and structure verification) +├── Layer 18: EC Point Validation (Format and structure verification) +└── Layer 19: HKDF Key Derivation (RFC 5869 compliant key separation) ``` ### Security Metrics @@ -202,7 +204,7 @@ We maintain a hall of fame for security researchers who help improve SecureBit.c ## 🔄 Recent Security Updates (Version 4.02) ### Major Security Enhancements: -- ✅ **Implemented 18-layer security architecture** +- ✅ **Implemented 19-layer security architecture** - ✅ **Added complete ASN.1 DER parser for key validation** - ✅ **Enhanced key security with OID and EC point verification** - ✅ **Fixed high-risk vulnerability in key structure validation** @@ -210,6 +212,8 @@ We maintain a hall of fame for security researchers who help improve SecureBit.c - ✅ **Implemented key size limits to prevent DoS attacks** - ✅ **Added BIT STRING validation ensuring unused bits are 0** - ✅ **Enhanced fallback support from P-384 to P-256** +- ✅ **Implemented RFC 5869 compliant HKDF key derivation** +- ✅ **Enhanced key separation with proper salt and info parameters** ### Previous Enhancements (Version 4.01): - ✅ **Implemented 15-layer security architecture** @@ -266,13 +270,14 @@ cryptoManager.getASN1ValidationStatus() ## 🏅 Security Achievements SecureBit.chat v4.02 provides: -- **🥇 Military-Grade Security:** 18-layer protection system +- **🥇 Military-Grade Security:** 19-layer protection system - **🥇 Government-Level Encryption:** Triple AES-256-GCM + P-384 ECDH/ECDSA - **🥇 Perfect Forward Secrecy:** Complete with automatic key rotation - **🥇 Traffic Analysis Protection:** Maximum with 6-layer obfuscation - **🥇 Zero-Trust Architecture:** No central points of failure - **🥇 Complete ASN.1 Validation:** Full structural verification of all cryptographic keys - **🥇 PKCS Compliance:** Complete adherence to cryptographic standards +- **🥇 HKDF Key Derivation:** RFC 5869 compliant key separation and derivation **Security Rating: MAXIMUM** - Exceeds most government and military communication standards with complete key structure validation. diff --git a/dist/app-boot.js b/dist/app-boot.js index a98d14a..7e6aa87 100644 --- a/dist/app-boot.js +++ b/dist/app-boot.js @@ -1483,8 +1483,13 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils { if (this.isProductionMode) { if (level === "error") { console.error(`\u274C [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]`); + if (context && Object.keys(context).length > 0) { + console.error("Error details:", context); + } } else if (level === "warn") { console.warn(`\u26A0\uFE0F [SecureChat] ${message}`); + } else if (level === "info" || level === "debug") { + console.log(`[SecureChat] ${message}`, context); } else { return; } @@ -2232,6 +2237,15 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils { // Enhanced key derivation with metadata protection and 64-byte salt static async deriveSharedKeys(privateKey, publicKey, salt) { try { + _EnhancedSecureCryptoUtils.secureLog.log("info", "Starting key derivation", { + privateKeyType: typeof privateKey, + publicKeyType: typeof publicKey, + saltLength: salt?.length, + privateKeyAlgorithm: privateKey?.algorithm?.name, + publicKeyAlgorithm: publicKey?.algorithm?.name, + privateKeyUsages: privateKey?.usages, + publicKeyUsages: publicKey?.usages + }); if (!(privateKey instanceof CryptoKey)) { _EnhancedSecureCryptoUtils.secureLog.log("error", "Private key is not a CryptoKey", { privateKeyType: typeof privateKey, @@ -2244,209 +2258,142 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils { publicKeyType: typeof publicKey, publicKeyAlgorithm: publicKey?.algorithm?.name }); - throw new Error("The private key is not a valid CryptoKey."); + throw new Error("The public key is not a valid CryptoKey."); } if (!salt || salt.length !== 64) { throw new Error("Salt must be exactly 64 bytes for enhanced security"); } const saltBytes = new Uint8Array(salt); const encoder = new TextEncoder(); - const contextInfo = encoder.encode("SecureBit.chat v4.0 Enhanced Security Edition"); - let sharedSecret; + let rawSharedSecret; try { - sharedSecret = await crypto.subtle.deriveKey( + _EnhancedSecureCryptoUtils.secureLog.log("info", "Step 1: Starting ECDH derivation"); + const rawKeyMaterial = await crypto.subtle.deriveKey( { name: "ECDH", public: publicKey }, privateKey, - { - name: "HKDF", - hash: "SHA-384", - salt: saltBytes, - info: contextInfo - }, - false, - // Non-extractable - ["deriveKey"] - ); - } catch (sha384Error) { - _EnhancedSecureCryptoUtils.secureLog.log("warn", "SHA-384 key derivation failed, trying SHA-256", { - error: sha384Error.message, - privateKeyType: typeof privateKey, - publicKeyType: typeof publicKey, - privateKeyAlgorithm: privateKey?.algorithm?.name, - publicKeyAlgorithm: publicKey?.algorithm?.name - }); - sharedSecret = await crypto.subtle.deriveKey( - { - name: "ECDH", - public: publicKey - }, - privateKey, - { - name: "HKDF", - hash: "SHA-256", - salt: saltBytes, - info: contextInfo - }, - false, - // Non-extractable - ["deriveKey"] - ); - } - let encryptionKey; - try { - encryptionKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-384", - salt: saltBytes, - info: encoder.encode("message-encryption-v4") - }, - sharedSecret, { name: "AES-GCM", length: 256 }, - false, - // Non-extractable for enhanced security + true, + // Extractable ["encrypt", "decrypt"] ); - } catch (sha384Error) { - encryptionKey = await crypto.subtle.deriveKey( + const rawKeyData = await crypto.subtle.exportKey("raw", rawKeyMaterial); + rawSharedSecret = await crypto.subtle.importKey( + "raw", + rawKeyData, { name: "HKDF", - hash: "SHA-256", - salt: saltBytes, - info: encoder.encode("message-encryption-v4") - }, - sharedSecret, - { - name: "AES-GCM", - length: 256 - }, - false, - // Non-extractable for enhanced security - ["encrypt", "decrypt"] - ); - } - let macKey; - try { - macKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-384", - salt: saltBytes, - info: encoder.encode("message-authentication-v4") - }, - sharedSecret, - { - name: "HMAC", - hash: "SHA-384" - }, - false, - // Non-extractable - ["sign", "verify"] - ); - } catch (sha384Error) { - macKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-256", - salt: saltBytes, - info: encoder.encode("message-authentication-v4") - }, - sharedSecret, - { - name: "HMAC", hash: "SHA-256" }, false, - // Non-extractable - ["sign", "verify"] + ["deriveKey"] ); + _EnhancedSecureCryptoUtils.secureLog.log("info", "Step 1: ECDH derivation successful"); + } catch (error) { + _EnhancedSecureCryptoUtils.secureLog.log("error", "ECDH derivation failed", { + error: error.message + }); + throw error; } + _EnhancedSecureCryptoUtils.secureLog.log("info", "Step 2: Starting HKDF key derivation"); + let messageKey; + messageKey = await crypto.subtle.deriveKey( + { + name: "HKDF", + hash: "SHA-256", + salt: saltBytes, + info: encoder.encode("message-encryption-v4") + }, + rawSharedSecret, + { + name: "AES-GCM", + length: 256 + }, + false, + // Non-extractable for enhanced security + ["encrypt", "decrypt"] + ); + let macKey; + macKey = await crypto.subtle.deriveKey( + { + name: "HKDF", + hash: "SHA-256", + salt: saltBytes, + info: encoder.encode("message-authentication-v4") + }, + rawSharedSecret, + { + name: "HMAC", + hash: "SHA-256" + }, + false, + // Non-extractable + ["sign", "verify"] + ); + let pfsKey; + pfsKey = await crypto.subtle.deriveKey( + { + name: "HKDF", + hash: "SHA-256", + salt: saltBytes, + info: encoder.encode("perfect-forward-secrecy-v4") + }, + rawSharedSecret, + { + name: "AES-GCM", + length: 256 + }, + false, + // Non-extractable + ["encrypt", "decrypt"] + ); let metadataKey; - try { - metadataKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-384", - salt: saltBytes, - info: encoder.encode("metadata-protection-v4") - }, - sharedSecret, - { - name: "AES-GCM", - length: 256 - }, - false, - // Non-extractable - ["encrypt", "decrypt"] - ); - } catch (sha384Error) { - metadataKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-256", - salt: saltBytes, - info: encoder.encode("metadata-protection-v4") - }, - sharedSecret, - { - name: "AES-GCM", - length: 256 - }, - false, - // Non-extractable - ["encrypt", "decrypt"] - ); - } + metadataKey = await crypto.subtle.deriveKey( + { + name: "HKDF", + hash: "SHA-256", + salt: saltBytes, + info: encoder.encode("metadata-protection-v4") + }, + rawSharedSecret, + { + name: "AES-GCM", + length: 256 + }, + false, + // Non-extractable + ["encrypt", "decrypt"] + ); let fingerprintKey; - try { - fingerprintKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-384", - salt: saltBytes, - info: encoder.encode("fingerprint-generation-v4") - }, - sharedSecret, - { - name: "AES-GCM", - length: 256 - }, - true, - // Extractable only for fingerprint - ["encrypt", "decrypt"] - ); - } catch (sha384Error) { - fingerprintKey = await crypto.subtle.deriveKey( - { - name: "HKDF", - hash: "SHA-256", - salt: saltBytes, - info: encoder.encode("fingerprint-generation-v4") - }, - sharedSecret, - { - name: "AES-GCM", - length: 256 - }, - true, - // Extractable only for fingerprint - ["encrypt", "decrypt"] - ); - } + fingerprintKey = await crypto.subtle.deriveKey( + { + name: "HKDF", + hash: "SHA-256", + salt: saltBytes, + info: encoder.encode("fingerprint-generation-v4") + }, + rawSharedSecret, + { + name: "AES-GCM", + length: 256 + }, + true, + // Extractable only for fingerprint + ["encrypt", "decrypt"] + ); const fingerprintKeyData = await crypto.subtle.exportKey("raw", fingerprintKey); const fingerprint = await _EnhancedSecureCryptoUtils.generateKeyFingerprint(Array.from(new Uint8Array(fingerprintKeyData))); - if (!(encryptionKey instanceof CryptoKey)) { - _EnhancedSecureCryptoUtils.secureLog.log("error", "Derived encryption key is not a CryptoKey", { - encryptionKeyType: typeof encryptionKey, - encryptionKeyAlgorithm: encryptionKey?.algorithm?.name + if (!(messageKey instanceof CryptoKey)) { + _EnhancedSecureCryptoUtils.secureLog.log("error", "Derived message key is not a CryptoKey", { + messageKeyType: typeof messageKey, + messageKeyAlgorithm: messageKey?.algorithm?.name }); - throw new Error("The derived encryption key is not a valid CryptoKey."); + throw new Error("The derived message key is not a valid CryptoKey."); } if (!(macKey instanceof CryptoKey)) { _EnhancedSecureCryptoUtils.secureLog.log("error", "Derived MAC key is not a CryptoKey", { @@ -2455,6 +2402,13 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils { }); throw new Error("The derived MAC key is not a valid CryptoKey."); } + if (!(pfsKey instanceof CryptoKey)) { + _EnhancedSecureCryptoUtils.secureLog.log("error", "Derived PFS key is not a CryptoKey", { + pfsKeyType: typeof pfsKey, + pfsKeyAlgorithm: pfsKey?.algorithm?.name + }); + throw new Error("The derived PFS key is not a valid CryptoKey."); + } if (!(metadataKey instanceof CryptoKey)) { _EnhancedSecureCryptoUtils.secureLog.log("error", "Derived metadata key is not a CryptoKey", { metadataKeyType: typeof metadataKey, @@ -2462,23 +2416,38 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils { }); throw new Error("The derived metadata key is not a valid CryptoKey."); } - _EnhancedSecureCryptoUtils.secureLog.log("info", "Enhanced shared keys derived successfully", { + _EnhancedSecureCryptoUtils.secureLog.log("info", "Enhanced shared keys derived successfully with proper HKDF separation", { saltSize: salt.length, + hasMessageKey: true, + hasMacKey: true, + hasPfsKey: true, hasMetadataKey: true, nonExtractable: true, version: "4.0", - allKeysValid: true + allKeysValid: true, + hkdfProperlyImplemented: true }); return { - encryptionKey, + messageKey, + // Renamed from encryptionKey for clarity macKey, + pfsKey, + // Added Perfect Forward Secrecy key metadataKey, fingerprint, timestamp: Date.now(), version: "4.0" }; } catch (error) { - _EnhancedSecureCryptoUtils.secureLog.log("error", "Enhanced key derivation failed", { error: error.message }); + _EnhancedSecureCryptoUtils.secureLog.log("error", "Enhanced key derivation failed", { + error: error.message, + errorStack: error.stack, + privateKeyType: typeof privateKey, + publicKeyType: typeof publicKey, + saltLength: salt?.length, + privateKeyAlgorithm: privateKey?.algorithm?.name, + publicKeyAlgorithm: publicKey?.algorithm?.name + }); throw new Error(`Failed to create shared encryption keys: ${error.message}`); } } @@ -4693,7 +4662,7 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager { SYSTEM_MESSAGE: "SYSTEM_MESSAGE_FILTERED" }; // Static debug flag instead of this._debugMode - static DEBUG_MODE = false; + static DEBUG_MODE = true; // Set to true during development, false in production constructor(onMessage, onStatusChange, onKeyExchange, onVerificationRequired, onAnswerError = null, onVerificationStateChange = null, config = {}) { this._isProductionMode = this._detectProductionMode(); @@ -12158,20 +12127,43 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager { this.peerPublicKey = peerECDHPublicKey; let derivedKeys; try { + this._secureLog("debug", "About to call deriveSharedKeys", { + operationId, + privateKeyType: typeof this.ecdhKeyPair.privateKey, + publicKeyType: typeof peerECDHPublicKey, + saltLength: this.sessionSalt?.length, + privateKeyAlgorithm: this.ecdhKeyPair.privateKey?.algorithm?.name, + publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name + }); derivedKeys = await window.EnhancedSecureCryptoUtils.deriveSharedKeys( this.ecdhKeyPair.privateKey, peerECDHPublicKey, this.sessionSalt ); + this._secureLog("debug", "deriveSharedKeys completed successfully", { + operationId, + hasMessageKey: !!derivedKeys.messageKey, + hasMacKey: !!derivedKeys.macKey, + hasPfsKey: !!derivedKeys.pfsKey, + hasMetadataKey: !!derivedKeys.metadataKey, + hasFingerprint: !!derivedKeys.fingerprint + }); } catch (error) { this._secureLog("error", "Failed to derive shared keys", { operationId, - errorType: error.constructor.name + errorType: error.constructor.name, + errorMessage: error.message, + errorStack: error.stack, + privateKeyType: typeof this.ecdhKeyPair.privateKey, + publicKeyType: typeof peerECDHPublicKey, + saltLength: this.sessionSalt?.length, + privateKeyAlgorithm: this.ecdhKeyPair.privateKey?.algorithm?.name, + publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name }); this._throwSecureError(error, "key_derivation"); } await this._setEncryptionKeys( - derivedKeys.encryptionKey, + derivedKeys.messageKey, derivedKeys.macKey, derivedKeys.metadataKey, derivedKeys.fingerprint @@ -12716,7 +12708,7 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager { peerPublicKey, this.sessionSalt ); - this.encryptionKey = derivedKeys.encryptionKey; + this.encryptionKey = derivedKeys.messageKey; this.macKey = derivedKeys.macKey; this.metadataKey = derivedKeys.metadataKey; this.keyFingerprint = derivedKeys.fingerprint; @@ -15456,7 +15448,7 @@ Right-click or Ctrl+click to disconnect`, React.createElement("p", { key: "subtitle", className: "text-xs sm:text-sm text-muted hidden sm:block" - }, "End-to-end freedom v4.4.18") + }, "End-to-end freedom v4.4.99") ]) ]), // Status and Controls - Responsive @@ -16211,7 +16203,7 @@ function Roadmap() { }, // current and future phases { - version: "v4.4.18", + version: "v4.4.99", title: "Enhanced Security Edition", status: "current", date: "Now", diff --git a/dist/app-boot.js.map b/dist/app-boot.js.map index 40d8a4d..7519df1 100644 --- a/dist/app-boot.js.map +++ b/dist/app-boot.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/notifications/SecureNotificationManager.js", "../src/notifications/NotificationIntegration.js", "../src/crypto/EnhancedSecureCryptoUtils.js", "../src/transfer/EnhancedSecureFileTransfer.js", "../src/network/EnhancedSecureWebRTCManager.js", "../src/scripts/app-boot.js", "../src/components/ui/Header.jsx", "../src/components/ui/DownloadApps.jsx", "../src/components/ui/UniqueFeatureSlider.jsx", "../src/components/ui/SecurityFeatures.jsx", "../src/components/ui/Testimonials.jsx", "../src/components/ui/ComparisonTable.jsx", "../src/components/ui/Roadmap.jsx", "../src/components/ui/FileTransfer.jsx"], - "sourcesContent": ["/**\n * Secure and Reliable Notification Manager for P2P WebRTC Chat\n * Follows best practices: OWASP, MDN, Chrome DevRel\n * \n * @version 1.0.0\n * @author SecureBit Team\n * @license MIT\n */\n\nclass SecureChatNotificationManager {\n constructor(config = {}) {\n // Safely read Notification permission (iOS Safari may not define Notification)\n this.permission = (typeof Notification !== 'undefined' && Notification && typeof Notification.permission === 'string')\n ? Notification.permission\n : 'denied';\n this.isTabActive = this.checkTabActive(); // Initialize with proper check\n this.unreadCount = 0;\n this.originalTitle = document.title;\n this.notificationQueue = [];\n this.maxQueueSize = config.maxQueueSize || 5;\n this.rateLimitMs = config.rateLimitMs || 2000; // Spam protection\n this.lastNotificationTime = 0;\n this.trustedOrigins = config.trustedOrigins || [];\n \n // Secure context flag\n this.isSecureContext = window.isSecureContext;\n \n // Cross-browser compatibility for Page Visibility API\n this.hidden = this.getHiddenProperty();\n this.visibilityChange = this.getVisibilityChangeEvent();\n \n this.initVisibilityTracking();\n this.initSecurityChecks();\n }\n\n /**\n * Initialize security checks and validation\n * @private\n */\n initSecurityChecks() {\n // Security checks are performed silently\n }\n\n /**\n * Get hidden property name for cross-browser compatibility\n * @returns {string} Hidden property name\n * @private\n */\n getHiddenProperty() {\n if (typeof document.hidden !== \"undefined\") {\n return \"hidden\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msHidden\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitHidden\";\n }\n return \"hidden\"; // fallback\n }\n\n /**\n * Get visibility change event name for cross-browser compatibility\n * @returns {string} Visibility change event name\n * @private\n */\n getVisibilityChangeEvent() {\n if (typeof document.hidden !== \"undefined\") {\n return \"visibilitychange\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msvisibilitychange\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitvisibilitychange\";\n }\n return \"visibilitychange\"; // fallback\n }\n\n /**\n * Check if tab is currently active using multiple methods\n * @returns {boolean} True if tab is active\n * @private\n */\n checkTabActive() {\n // Primary method: Page Visibility API\n if (this.hidden && typeof document[this.hidden] !== \"undefined\") {\n return !document[this.hidden];\n }\n \n // Fallback method: document.hasFocus()\n if (typeof document.hasFocus === \"function\") {\n return document.hasFocus();\n }\n \n // Ultimate fallback: assume active\n return true;\n }\n\n /**\n * Initialize page visibility tracking (Page Visibility API)\n * @private\n */\n initVisibilityTracking() {\n // Primary method: Page Visibility API with cross-browser support\n if (typeof document.addEventListener !== \"undefined\" && typeof document[this.hidden] !== \"undefined\") {\n document.addEventListener(this.visibilityChange, () => {\n this.isTabActive = this.checkTabActive();\n \n if (this.isTabActive) {\n this.resetUnreadCount();\n this.clearNotificationQueue();\n }\n });\n }\n\n // Fallback method: Window focus/blur events\n window.addEventListener('focus', () => {\n this.isTabActive = this.checkTabActive();\n if (this.isTabActive) {\n this.resetUnreadCount();\n }\n });\n\n window.addEventListener('blur', () => {\n this.isTabActive = this.checkTabActive();\n });\n\n // Page unload cleanup\n window.addEventListener('beforeunload', () => {\n this.clearNotificationQueue();\n });\n }\n\n /**\n * Request notification permission (BEST PRACTICE: Only call in response to user action)\n * Never call on page load!\n * @returns {Promise} Permission granted status\n */\n async requestPermission() {\n // Secure context check\n if (!this.isSecureContext || !('Notification' in window)) {\n return false;\n }\n\n if (this.permission === 'granted') {\n return true;\n }\n\n if (this.permission === 'denied') {\n return false;\n }\n\n try {\n this.permission = await Notification.requestPermission();\n return this.permission === 'granted';\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Update page title with unread count\n * @private\n */\n updateTitle() {\n if (this.unreadCount > 0) {\n document.title = `(${this.unreadCount}) ${this.originalTitle}`;\n } else {\n document.title = this.originalTitle;\n }\n }\n\n /**\n * XSS Protection: Sanitize input text\n * @param {string} text - Text to sanitize\n * @returns {string} Sanitized text\n * @private\n */\n sanitizeText(text) {\n if (typeof text !== 'string') {\n return '';\n }\n \n // Remove HTML tags and potentially dangerous characters\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .substring(0, 500); // Length limit\n }\n\n /**\n * Validate icon URL (XSS protection)\n * @param {string} url - URL to validate\n * @returns {string|null} Validated URL or null\n * @private\n */\n validateIconUrl(url) {\n if (!url) return null;\n \n try {\n const parsedUrl = new URL(url, window.location.origin);\n \n // Only allow HTTPS and data URLs\n if (parsedUrl.protocol === 'https:' || parsedUrl.protocol === 'data:') {\n // Check trusted origins if specified\n if (this.trustedOrigins.length > 0) {\n const isTrusted = this.trustedOrigins.some(origin => \n parsedUrl.origin === origin\n );\n return isTrusted ? parsedUrl.href : null;\n }\n return parsedUrl.href;\n }\n \n return null;\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Rate limiting for spam protection\n * @returns {boolean} Rate limit check passed\n * @private\n */\n checkRateLimit() {\n const now = Date.now();\n if (now - this.lastNotificationTime < this.rateLimitMs) {\n return false;\n }\n this.lastNotificationTime = now;\n return true;\n }\n\n /**\n * Send secure notification\n * @param {string} senderName - Name of message sender\n * @param {string} message - Message content\n * @param {Object} options - Notification options\n * @returns {Notification|null} Created notification or null\n */\n notify(senderName, message, options = {}) {\n // Abort if Notifications API is not available (e.g., iOS Safari)\n if (typeof Notification === 'undefined') {\n return null;\n }\n // Update tab active state before checking\n this.isTabActive = this.checkTabActive();\n \n // Only show if tab is NOT active (user is on another tab or minimized)\n if (this.isTabActive) {\n return null;\n }\n\n // Permission check\n if (this.permission !== 'granted') {\n return null;\n }\n\n // Rate limiting\n if (!this.checkRateLimit()) {\n return null;\n }\n\n // Data sanitization (XSS Protection)\n const safeSenderName = this.sanitizeText(senderName || 'Unknown');\n const safeMessage = this.sanitizeText(message || '');\n const safeIcon = this.validateIconUrl(options.icon) || '/logo/icon-192x192.png';\n\n // Queue overflow protection\n if (this.notificationQueue.length >= this.maxQueueSize) {\n this.clearNotificationQueue();\n }\n\n try {\n \n const notification = new Notification(\n `${safeSenderName}`,\n {\n body: safeMessage.substring(0, 200), // Length limit\n icon: safeIcon,\n badge: safeIcon,\n tag: `chat-${options.senderId || 'unknown'}`, // Grouping\n requireInteraction: false, // Don't block user\n silent: options.silent || false,\n // Vibrate only for mobile and if supported\n vibrate: navigator.vibrate ? [200, 100, 200] : undefined,\n // Safe metadata\n data: {\n senderId: this.sanitizeText(options.senderId),\n timestamp: Date.now(),\n // Don't include sensitive data!\n }\n }\n );\n\n // Increment counter\n this.unreadCount++;\n this.updateTitle();\n\n // Add to queue for management\n this.notificationQueue.push(notification);\n\n // Safe click handler\n notification.onclick = (event) => {\n event.preventDefault(); // Prevent default behavior\n window.focus();\n notification.close();\n \n // Safe callback\n if (typeof options.onClick === 'function') {\n try {\n options.onClick(options.senderId);\n } catch (error) {\n console.error('[Notifications] Error in onClick handler:', error);\n }\n }\n };\n\n // Error handler\n notification.onerror = (event) => {\n console.error('[Notifications] Error showing notification:', event);\n };\n\n // Auto-close after reasonable time\n const autoCloseTimeout = Math.min(options.autoClose || 5000, 10000);\n setTimeout(() => {\n notification.close();\n this.removeFromQueue(notification);\n }, autoCloseTimeout);\n\n return notification;\n \n } catch (error) {\n console.error('[Notifications] Failed to create notification:', error);\n return null;\n }\n }\n\n /**\n * Remove notification from queue\n * @param {Notification} notification - Notification to remove\n * @private\n */\n removeFromQueue(notification) {\n const index = this.notificationQueue.indexOf(notification);\n if (index > -1) {\n this.notificationQueue.splice(index, 1);\n }\n }\n\n /**\n * Clear all notifications\n */\n clearNotificationQueue() {\n this.notificationQueue.forEach(notification => {\n try {\n notification.close();\n } catch (error) {\n // Ignore errors when closing\n }\n });\n this.notificationQueue = [];\n }\n\n /**\n * Reset unread counter\n */\n resetUnreadCount() {\n this.unreadCount = 0;\n this.updateTitle();\n }\n\n /**\n * Get current status\n * @returns {Object} Current notification status\n */\n getStatus() {\n return {\n permission: this.permission,\n isTabActive: this.isTabActive,\n unreadCount: this.unreadCount,\n isSecureContext: this.isSecureContext,\n queueSize: this.notificationQueue.length\n };\n }\n}\n\n/**\n * Secure integration with WebRTC\n */\nclass SecureP2PChat {\n constructor() {\n this.notificationManager = new SecureChatNotificationManager({\n maxQueueSize: 5,\n rateLimitMs: 2000,\n trustedOrigins: [\n window.location.origin,\n // Add other trusted origins for CDN icons\n ]\n });\n \n this.dataChannel = null;\n this.peerConnection = null;\n this.remotePeerName = 'Peer';\n this.messageHistory = [];\n this.maxHistorySize = 100;\n }\n\n /**\n * Initialize when user connects\n */\n async init() {\n // Initialize notification manager silently\n }\n\n /**\n * Method for manual permission request (called on click)\n * @returns {Promise} Permission granted status\n */\n async enableNotifications() {\n const granted = await this.notificationManager.requestPermission();\n return granted;\n }\n\n /**\n * Setup DataChannel with security checks\n * @param {RTCDataChannel} dataChannel - WebRTC data channel\n */\n setupDataChannel(dataChannel) {\n if (!dataChannel) {\n console.error('[Chat] Invalid DataChannel');\n return;\n }\n\n this.dataChannel = dataChannel;\n \n // Setup handlers\n this.dataChannel.onmessage = (event) => {\n this.handleIncomingMessage(event.data);\n };\n\n this.dataChannel.onerror = (error) => {\n // Handle error silently\n };\n }\n\n /**\n * XSS Protection: Validate incoming messages\n * @param {string|Object} data - Message data\n * @returns {Object|null} Validated message or null\n * @private\n */\n validateMessage(data) {\n try {\n const message = typeof data === 'string' ? JSON.parse(data) : data;\n \n // Check message structure\n if (!message || typeof message !== 'object') {\n throw new Error('Invalid message structure');\n }\n\n // Check required fields\n if (!message.text || typeof message.text !== 'string') {\n throw new Error('Invalid message text');\n }\n\n // Message length limit (DoS protection)\n if (message.text.length > 10000) {\n throw new Error('Message too long');\n }\n\n return {\n text: message.text,\n senderName: message.senderName || 'Unknown',\n senderId: message.senderId || 'unknown',\n timestamp: message.timestamp || Date.now(),\n senderAvatar: message.senderAvatar || null\n };\n \n } catch (error) {\n console.error('[Chat] Message validation failed:', error);\n return null;\n }\n }\n\n /**\n * Secure handling of incoming messages\n * @param {string|Object} data - Message data\n * @private\n */\n handleIncomingMessage(data) {\n const message = this.validateMessage(data);\n \n if (!message) {\n return;\n }\n\n // Save to history (with limit)\n this.messageHistory.push(message);\n if (this.messageHistory.length > this.maxHistorySize) {\n this.messageHistory.shift();\n }\n\n // Display in UI (with sanitization)\n this.displayMessage(message);\n\n // Send notification only if tab is inactive\n this.notificationManager.notify(\n message.senderName,\n message.text,\n {\n icon: message.senderAvatar,\n senderId: message.senderId,\n onClick: (senderId) => {\n this.scrollToLatestMessage();\n }\n }\n );\n\n // Optional: sound (with check)\n if (!this.notificationManager.isTabActive) {\n this.playNotificationSound();\n }\n }\n\n /**\n * XSS Protection: Safe message display\n * @param {Object} message - Message to display\n * @private\n */\n displayMessage(message) {\n const container = document.getElementById('messages');\n if (!container) {\n return;\n }\n\n const messageEl = document.createElement('div');\n messageEl.className = 'message';\n \n // Use textContent to prevent XSS\n const nameEl = document.createElement('strong');\n nameEl.textContent = message.senderName + ': ';\n \n const textEl = document.createElement('span');\n textEl.textContent = message.text;\n \n const timeEl = document.createElement('small');\n timeEl.textContent = new Date(message.timestamp).toLocaleTimeString();\n \n messageEl.appendChild(nameEl);\n messageEl.appendChild(textEl);\n messageEl.appendChild(document.createElement('br'));\n messageEl.appendChild(timeEl);\n \n container.appendChild(messageEl);\n this.scrollToLatestMessage();\n }\n\n /**\n * Safe sound playback\n * @private\n */\n playNotificationSound() {\n try {\n // Use only local audio files\n const audio = new Audio('/assets/audio/notification.mp3');\n audio.volume = 0.3; // Moderate volume\n \n // Error handling\n audio.play().catch(error => {\n // Handle audio error silently\n });\n } catch (error) {\n // Handle audio creation error silently\n }\n }\n\n /**\n * Scroll to latest message\n * @private\n */\n scrollToLatestMessage() {\n const container = document.getElementById('messages');\n if (container) {\n container.scrollTop = container.scrollHeight;\n }\n }\n\n /**\n * Get status\n * @returns {Object} Current chat status\n */\n getStatus() {\n return {\n notifications: this.notificationManager.getStatus(),\n messageCount: this.messageHistory.length,\n connected: this.dataChannel?.readyState === 'open'\n };\n }\n}\n\n// Export for use in other modules\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = { SecureChatNotificationManager, SecureP2PChat };\n}\n\n// Global export for browser usage\nif (typeof window !== 'undefined') {\n window.SecureChatNotificationManager = SecureChatNotificationManager;\n window.SecureP2PChat = SecureP2PChat;\n}\n", "/**\n * Notification Integration Module for SecureBit WebRTC Chat\n * Integrates secure notifications with existing WebRTC architecture\n * \n * @version 1.0.0\n * @author SecureBit Team\n * @license MIT\n */\n\nimport { SecureChatNotificationManager } from './SecureNotificationManager.js';\n\nclass NotificationIntegration {\n constructor(webrtcManager) {\n this.webrtcManager = webrtcManager;\n this.notificationManager = new SecureChatNotificationManager({\n maxQueueSize: 10,\n rateLimitMs: 1000, // Reduced from 2000ms to 1000ms\n trustedOrigins: [\n window.location.origin,\n // Add other trusted origins for CDN icons\n ]\n });\n \n this.isInitialized = false;\n this.originalOnMessage = null;\n this.originalOnStatusChange = null;\n this.processedMessages = new Set(); // Track processed messages to avoid duplicates\n }\n\n /**\n * Initialize notification integration\n * @returns {Promise} Initialization success\n */\n async init() {\n try {\n if (this.isInitialized) {\n return true;\n }\n\n // Store original callbacks\n this.originalOnMessage = this.webrtcManager.onMessage;\n this.originalOnStatusChange = this.webrtcManager.onStatusChange;\n\n\n // Wrap the original onMessage callback\n this.webrtcManager.onMessage = (message, type) => {\n this.handleIncomingMessage(message, type);\n \n // Call original callback if it exists\n if (this.originalOnMessage) {\n this.originalOnMessage(message, type);\n }\n };\n\n // Wrap the original onStatusChange callback\n this.webrtcManager.onStatusChange = (status) => {\n this.handleStatusChange(status);\n \n // Call original callback if it exists\n if (this.originalOnStatusChange) {\n this.originalOnStatusChange(status);\n }\n };\n\n // Also hook into the deliverMessageToUI method if it exists\n if (this.webrtcManager.deliverMessageToUI) {\n this.originalDeliverMessageToUI = this.webrtcManager.deliverMessageToUI.bind(this.webrtcManager);\n this.webrtcManager.deliverMessageToUI = (message, type) => {\n this.handleIncomingMessage(message, type);\n this.originalDeliverMessageToUI(message, type);\n };\n }\n\n this.isInitialized = true;\n return true;\n\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Handle incoming messages and trigger notifications\n * @param {*} message - Message content\n * @param {string} type - Message type\n * @private\n */\n handleIncomingMessage(message, type) {\n try {\n // Create a unique key for this message to avoid duplicates\n const messageKey = `${type}:${typeof message === 'string' ? message : JSON.stringify(message)}`;\n \n // Skip if we've already processed this message\n if (this.processedMessages.has(messageKey)) {\n return;\n }\n \n // Mark message as processed\n this.processedMessages.add(messageKey);\n \n // Clean up old processed messages (keep only last 100)\n if (this.processedMessages.size > 100) {\n const messagesArray = Array.from(this.processedMessages);\n this.processedMessages.clear();\n messagesArray.slice(-50).forEach(msg => this.processedMessages.add(msg));\n }\n \n \n // Only process chat messages, not system messages\n if (type === 'system' || type === 'file-transfer' || type === 'heartbeat') {\n return;\n }\n\n // Extract message information\n const messageInfo = this.extractMessageInfo(message, type);\n if (!messageInfo) {\n return;\n }\n\n // Send notification\n const notificationResult = this.notificationManager.notify(\n messageInfo.senderName,\n messageInfo.text,\n {\n icon: messageInfo.senderAvatar,\n senderId: messageInfo.senderId,\n onClick: (senderId) => {\n this.focusChatWindow();\n }\n }\n );\n\n } catch (error) {\n // Handle error silently\n }\n }\n\n /**\n * Handle status changes\n * @param {string} status - Connection status\n * @private\n */\n handleStatusChange(status) {\n try {\n // Clear notifications when connection is lost\n if (status === 'disconnected' || status === 'failed') {\n this.notificationManager.clearNotificationQueue();\n this.notificationManager.resetUnreadCount();\n }\n } catch (error) {\n // Handle error silently\n }\n }\n\n /**\n * Extract message information for notifications\n * @param {*} message - Message content\n * @param {string} type - Message type\n * @returns {Object|null} Extracted message info or null\n * @private\n */\n extractMessageInfo(message, type) {\n try {\n let messageData = message;\n\n // Handle different message formats\n if (typeof message === 'string') {\n try {\n messageData = JSON.parse(message);\n } catch (e) {\n // Plain text message\n return {\n senderName: 'Peer',\n text: message,\n senderId: 'peer',\n senderAvatar: null\n };\n }\n }\n\n // Handle structured message data\n if (typeof messageData === 'object' && messageData !== null) {\n return {\n senderName: messageData.senderName || messageData.name || 'Peer',\n text: messageData.text || messageData.message || messageData.content || '',\n senderId: messageData.senderId || messageData.id || 'peer',\n senderAvatar: messageData.senderAvatar || messageData.avatar || null\n };\n }\n\n return null;\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Focus chat window when notification is clicked\n * @private\n */\n focusChatWindow() {\n try {\n window.focus();\n \n // Scroll to bottom of messages if container exists\n const messagesContainer = document.getElementById('messages');\n if (messagesContainer) {\n messagesContainer.scrollTop = messagesContainer.scrollHeight;\n }\n } catch (error) {\n // Handle error silently\n }\n }\n\n /**\n * Request notification permission\n * @returns {Promise} Permission granted status\n */\n async requestPermission() {\n try {\n return await this.notificationManager.requestPermission();\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Get notification status\n * @returns {Object} Notification status\n */\n getStatus() {\n return this.notificationManager.getStatus();\n }\n\n /**\n * Clear all notifications\n */\n clearNotifications() {\n this.notificationManager.clearNotificationQueue();\n this.notificationManager.resetUnreadCount();\n }\n\n /**\n * Cleanup integration\n */\n cleanup() {\n try {\n if (this.isInitialized) {\n // Restore original callbacks\n if (this.originalOnMessage) {\n this.webrtcManager.onMessage = this.originalOnMessage;\n }\n if (this.originalOnStatusChange) {\n this.webrtcManager.onStatusChange = this.originalOnStatusChange;\n }\n if (this.originalDeliverMessageToUI) {\n this.webrtcManager.deliverMessageToUI = this.originalDeliverMessageToUI;\n }\n\n // Clear notifications\n this.clearNotifications();\n\n this.isInitialized = false;\n }\n } catch (error) {\n // Handle error silently\n }\n }\n}\n\n// Export for use in other modules\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = { NotificationIntegration };\n}\n\n// Global export for browser usage\nif (typeof window !== 'undefined') {\n window.NotificationIntegration = NotificationIntegration;\n}\n", "class EnhancedSecureCryptoUtils {\r\n\r\n static _keyMetadata = new WeakMap();\r\n \r\n // Initialize secure logging system after class definition\r\n\r\n // Utility to sort object keys for deterministic serialization\r\n static sortObjectKeys(obj) {\r\n if (typeof obj !== 'object' || obj === null) {\r\n return obj;\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map(EnhancedSecureCryptoUtils.sortObjectKeys);\r\n }\r\n\r\n const sortedObj = {};\r\n Object.keys(obj).sort().forEach(key => {\r\n sortedObj[key] = EnhancedSecureCryptoUtils.sortObjectKeys(obj[key]);\r\n });\r\n return sortedObj;\r\n }\r\n\r\n // Utility to assert CryptoKey type and properties\r\n static assertCryptoKey(key, expectedName = null, expectedUsages = []) {\r\n if (!(key instanceof CryptoKey)) throw new Error('Expected CryptoKey');\r\n if (expectedName && key.algorithm?.name !== expectedName) {\r\n throw new Error(`Expected algorithm ${expectedName}, got ${key.algorithm?.name}`);\r\n }\r\n for (const u of expectedUsages) {\r\n if (!key.usages || !key.usages.includes(u)) {\r\n throw new Error(`Missing required key usage: ${u}`);\r\n }\r\n }\r\n }\r\n // Helper function to convert ArrayBuffer to Base64\r\n static arrayBufferToBase64(buffer) {\r\n let binary = '';\r\n const bytes = new Uint8Array(buffer);\r\n const len = bytes.byteLength;\r\n for (let i = 0; i < len; i++) {\r\n binary += String.fromCharCode(bytes[i]);\r\n }\r\n return btoa(binary);\r\n }\r\n\r\n // Helper function to convert Base64 to ArrayBuffer\r\n static base64ToArrayBuffer(base64) {\r\n try {\r\n // Validate input\r\n if (typeof base64 !== 'string' || !base64) {\r\n throw new Error('Invalid base64 input: must be a non-empty string');\r\n }\r\n\r\n // Remove any whitespace and validate base64 format\r\n const cleanBase64 = base64.trim();\r\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) {\r\n throw new Error('Invalid base64 format');\r\n }\r\n\r\n // Handle empty string case\r\n if (cleanBase64 === '') {\r\n return new ArrayBuffer(0);\r\n }\r\n\r\n const binaryString = atob(cleanBase64);\r\n const len = binaryString.length;\r\n const bytes = new Uint8Array(len);\r\n for (let i = 0; i < len; i++) {\r\n bytes[i] = binaryString.charCodeAt(i);\r\n }\r\n return bytes.buffer;\r\n } catch (error) {\r\n console.error('Base64 to ArrayBuffer conversion failed:', error.message);\r\n throw new Error(`Base64 conversion error: ${error.message}`);\r\n }\r\n }\r\n\r\n // Helper function to convert hex string to Uint8Array\r\n static hexToUint8Array(hexString) {\r\n try {\r\n if (!hexString || typeof hexString !== 'string') {\r\n throw new Error('Invalid hex string input: must be a non-empty string');\r\n }\r\n\r\n // Remove colons and spaces from hex string (e.g., \"aa:bb:cc\" -> \"aabbcc\")\r\n const cleanHex = hexString.replace(/:/g, '').replace(/\\s/g, '');\r\n \r\n // Validate hex format\r\n if (!/^[0-9a-fA-F]*$/.test(cleanHex)) {\r\n throw new Error('Invalid hex format: contains non-hex characters');\r\n }\r\n \r\n // Ensure even length\r\n if (cleanHex.length % 2 !== 0) {\r\n throw new Error('Invalid hex format: odd length');\r\n }\r\n\r\n // Convert hex string to bytes\r\n const bytes = new Uint8Array(cleanHex.length / 2);\r\n for (let i = 0; i < cleanHex.length; i += 2) {\r\n bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);\r\n }\r\n \r\n return bytes;\r\n } catch (error) {\r\n console.error('Hex to Uint8Array conversion failed:', error.message);\r\n throw new Error(`Hex conversion error: ${error.message}`);\r\n }\r\n }\r\n\r\n static async encryptData(data, password) {\r\n try {\r\n const dataString = typeof data === 'string' ? data : JSON.stringify(data);\r\n const salt = crypto.getRandomValues(new Uint8Array(16));\r\n const encoder = new TextEncoder();\r\n const passwordBuffer = encoder.encode(password);\r\n\r\n const keyMaterial = await crypto.subtle.importKey(\r\n 'raw',\r\n passwordBuffer,\r\n { name: 'PBKDF2' },\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n const key = await crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt: salt,\r\n iterations: 100000,\r\n hash: 'SHA-256',\r\n },\r\n keyMaterial,\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['encrypt']\r\n );\r\n\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n const dataBuffer = encoder.encode(dataString);\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: iv },\r\n key,\r\n dataBuffer\r\n );\r\n\r\n const encryptedPackage = {\r\n version: '1.0',\r\n salt: Array.from(salt),\r\n iv: Array.from(iv),\r\n data: Array.from(new Uint8Array(encrypted)),\r\n timestamp: Date.now(),\r\n };\r\n\r\n const packageString = JSON.stringify(encryptedPackage);\r\n return EnhancedSecureCryptoUtils.arrayBufferToBase64(new TextEncoder().encode(packageString).buffer);\r\n\r\n } catch (error) {\r\n console.error('Encryption failed:', error.message);\r\n throw new Error(`Encryption error: ${error.message}`);\r\n }\r\n }\r\n\r\n static async decryptData(encryptedData, password) {\r\n try {\r\n const packageBuffer = EnhancedSecureCryptoUtils.base64ToArrayBuffer(encryptedData);\r\n const packageString = new TextDecoder().decode(packageBuffer);\r\n const encryptedPackage = JSON.parse(packageString);\r\n\r\n if (!encryptedPackage.version || !encryptedPackage.salt || !encryptedPackage.iv || !encryptedPackage.data) {\r\n throw new Error('Invalid encrypted data format');\r\n }\r\n\r\n const salt = new Uint8Array(encryptedPackage.salt);\r\n const iv = new Uint8Array(encryptedPackage.iv);\r\n const encrypted = new Uint8Array(encryptedPackage.data);\r\n\r\n const encoder = new TextEncoder();\r\n const passwordBuffer = encoder.encode(password);\r\n\r\n const keyMaterial = await crypto.subtle.importKey(\r\n 'raw',\r\n passwordBuffer,\r\n { name: 'PBKDF2' },\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n const key = await crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt: salt,\r\n iterations: 100000,\r\n hash: 'SHA-256'\r\n },\r\n keyMaterial,\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['decrypt']\r\n );\r\n\r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n key,\r\n encrypted\r\n );\r\n\r\n const decryptedString = new TextDecoder().decode(decrypted);\r\n\r\n try {\r\n return JSON.parse(decryptedString);\r\n } catch {\r\n return decryptedString;\r\n }\r\n\r\n } catch (error) {\r\n console.error('Decryption failed:', error.message);\r\n throw new Error(`Decryption error: ${error.message}`);\r\n }\r\n }\r\n\r\n \r\n // Generate secure password for data exchange\r\n static generateSecurePassword() {\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';\r\n const charCount = chars.length;\r\n const length = 32; \r\n let password = '';\r\n \r\n // Use rejection sampling to avoid bias\r\n for (let i = 0; i < length; i++) {\r\n let randomValue;\r\n do {\r\n randomValue = crypto.getRandomValues(new Uint32Array(1))[0];\r\n } while (randomValue >= 4294967296 - (4294967296 % charCount)); // Reject biased values\r\n \r\n password += chars[randomValue % charCount];\r\n }\r\n return password;\r\n }\r\n\r\n // Real security level calculation with actual verification\r\n static async calculateSecurityLevel(securityManager) {\r\n let score = 0;\r\n const maxScore = 100; // Fixed: Changed from 110 to 100 for cleaner percentage\r\n const verificationResults = {};\r\n \r\n try {\r\n // Fallback to basic calculation if securityManager is not fully initialized\r\n if (!securityManager || !securityManager.securityFeatures) {\r\n console.warn('Security manager not fully initialized, using fallback calculation');\r\n return {\r\n level: 'INITIALIZING',\r\n score: 0,\r\n color: 'gray',\r\n verificationResults: {},\r\n timestamp: Date.now(),\r\n details: 'Security system initializing...',\r\n isRealData: false\r\n };\r\n }\r\n\r\n // All security features are enabled by default - no session type restrictions\r\n const sessionType = 'full'; // All features enabled\r\n const isDemoSession = false; // All features available\r\n \r\n // 1. Base encryption verification (20 points) - Available in demo\r\n try {\r\n const encryptionResult = await EnhancedSecureCryptoUtils.verifyEncryption(securityManager);\r\n if (encryptionResult.passed) {\r\n score += 20;\r\n verificationResults.verifyEncryption = { passed: true, details: encryptionResult.details, points: 20 };\r\n } else {\r\n verificationResults.verifyEncryption = { passed: false, details: encryptionResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyEncryption = { passed: false, details: `Encryption check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 2. Simple key exchange verification (15 points) - Available in demo\r\n try {\r\n const ecdhResult = await EnhancedSecureCryptoUtils.verifyECDHKeyExchange(securityManager);\r\n if (ecdhResult.passed) {\r\n score += 15;\r\n verificationResults.verifyECDHKeyExchange = { passed: true, details: ecdhResult.details, points: 15 };\r\n } else {\r\n verificationResults.verifyECDHKeyExchange = { passed: false, details: ecdhResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyECDHKeyExchange = { passed: false, details: `Key exchange check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 3. Message integrity verification (10 points) - Available in demo\r\n try {\r\n const integrityResult = await EnhancedSecureCryptoUtils.verifyMessageIntegrity(securityManager);\r\n if (integrityResult.passed) {\r\n score += 10;\r\n verificationResults.verifyMessageIntegrity = { passed: true, details: integrityResult.details, points: 10 };\r\n } else {\r\n verificationResults.verifyMessageIntegrity = { passed: false, details: integrityResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyMessageIntegrity = { passed: false, details: `Message integrity check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 4. ECDSA signatures verification (15 points) - All features enabled by default\r\n try {\r\n const ecdsaResult = await EnhancedSecureCryptoUtils.verifyECDSASignatures(securityManager);\r\n if (ecdsaResult.passed) {\r\n score += 15;\r\n verificationResults.verifyECDSASignatures = { passed: true, details: ecdsaResult.details, points: 15 };\r\n } else {\r\n verificationResults.verifyECDSASignatures = { passed: false, details: ecdsaResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyECDSASignatures = { passed: false, details: `Digital signatures check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 5. Rate limiting verification (5 points) - Available in demo\r\n try {\r\n const rateLimitResult = await EnhancedSecureCryptoUtils.verifyRateLimiting(securityManager);\r\n if (rateLimitResult.passed) {\r\n score += 5;\r\n verificationResults.verifyRateLimiting = { passed: true, details: rateLimitResult.details, points: 5 };\r\n } else {\r\n verificationResults.verifyRateLimiting = { passed: false, details: rateLimitResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyRateLimiting = { passed: false, details: `Rate limiting check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 6. Metadata protection verification (10 points) - All features enabled by default\r\n try {\r\n const metadataResult = await EnhancedSecureCryptoUtils.verifyMetadataProtection(securityManager);\r\n if (metadataResult.passed) {\r\n score += 10;\r\n verificationResults.verifyMetadataProtection = { passed: true, details: metadataResult.details, points: 10 };\r\n } else {\r\n verificationResults.verifyMetadataProtection = { passed: false, details: metadataResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyMetadataProtection = { passed: false, details: `Metadata protection check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 7. Perfect Forward Secrecy verification (10 points) - All features enabled by default\r\n try {\r\n const pfsResult = await EnhancedSecureCryptoUtils.verifyPerfectForwardSecrecy(securityManager);\r\n if (pfsResult.passed) {\r\n score += 10;\r\n verificationResults.verifyPerfectForwardSecrecy = { passed: true, details: pfsResult.details, points: 10 };\r\n } else {\r\n verificationResults.verifyPerfectForwardSecrecy = { passed: false, details: pfsResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyPerfectForwardSecrecy = { passed: false, details: `PFS check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 8. Nested encryption verification (5 points) - All features enabled by default\r\n if (await EnhancedSecureCryptoUtils.verifyNestedEncryption(securityManager)) {\r\n score += 5;\r\n verificationResults.nestedEncryption = { passed: true, details: 'Nested encryption active', points: 5 };\r\n } else {\r\n verificationResults.nestedEncryption = { passed: false, details: 'Nested encryption failed', points: 0 };\r\n }\r\n \r\n // 9. Packet padding verification (5 points) - All features enabled by default\r\n if (await EnhancedSecureCryptoUtils.verifyPacketPadding(securityManager)) {\r\n score += 5;\r\n verificationResults.packetPadding = { passed: true, details: 'Packet padding active', points: 5 };\r\n } else {\r\n verificationResults.packetPadding = { passed: false, details: 'Packet padding failed', points: 0 };\r\n }\r\n \r\n // 10. Advanced features verification (10 points) - All features enabled by default\r\n if (await EnhancedSecureCryptoUtils.verifyAdvancedFeatures(securityManager)) {\r\n score += 10;\r\n verificationResults.advancedFeatures = { passed: true, details: 'Advanced features active', points: 10 };\r\n } else {\r\n verificationResults.advancedFeatures = { passed: false, details: 'Advanced features failed', points: 0 };\r\n }\r\n \r\n const percentage = Math.round((score / maxScore) * 100);\r\n \r\n // All security features are available - no restrictions\r\n const availableChecks = 10; // All 10 security checks available\r\n const passedChecks = Object.values(verificationResults).filter(r => r.passed).length;\r\n \r\n const result = {\r\n level: percentage >= 85 ? 'HIGH' : percentage >= 65 ? 'MEDIUM' : percentage >= 35 ? 'LOW' : 'CRITICAL',\r\n score: percentage,\r\n color: percentage >= 85 ? 'green' : percentage >= 65 ? 'orange' : percentage >= 35 ? 'yellow' : 'red',\r\n verificationResults,\r\n timestamp: Date.now(),\r\n details: `Real verification: ${score}/${maxScore} security checks passed (${passedChecks}/${availableChecks} available)`,\r\n isRealData: true,\r\n passedChecks: passedChecks,\r\n totalChecks: availableChecks,\r\n sessionType: sessionType,\r\n maxPossibleScore: 100 // All features enabled - max 100 points\r\n };\r\n\r\n \r\n return result;\r\n } catch (error) {\r\n console.error('Security level calculation failed:', error.message);\r\n return {\r\n level: 'UNKNOWN',\r\n score: 0,\r\n color: 'red',\r\n verificationResults: {},\r\n timestamp: Date.now(),\r\n details: `Verification failed: ${error.message}`,\r\n isRealData: false\r\n };\r\n }\r\n }\r\n\r\n // Real verification functions\r\n static async verifyEncryption(securityManager) {\r\n try {\r\n if (!securityManager.encryptionKey) {\r\n return { passed: false, details: 'No encryption key available' };\r\n }\r\n \r\n // Test actual encryption/decryption with multiple data types\r\n const testCases = [\r\n 'Test encryption verification',\r\n '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438',\r\n 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',\r\n 'Large data: ' + 'A'.repeat(1000)\r\n ];\r\n \r\n for (const testData of testCases) {\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n \r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv },\r\n securityManager.encryptionKey,\r\n testBuffer\r\n );\r\n \r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n securityManager.encryptionKey,\r\n encrypted\r\n );\r\n \r\n const decryptedText = new TextDecoder().decode(decrypted);\r\n if (decryptedText !== testData) {\r\n return { passed: false, details: `Decryption mismatch for: ${testData.substring(0, 20)}...` };\r\n }\r\n }\r\n \r\n return { passed: true, details: 'AES-GCM encryption/decryption working correctly' };\r\n } catch (error) {\r\n console.error('Encryption verification failed:', error.message);\r\n return { passed: false, details: `Encryption test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyECDHKeyExchange(securityManager) {\r\n try {\r\n if (!securityManager.ecdhKeyPair || !securityManager.ecdhKeyPair.privateKey || !securityManager.ecdhKeyPair.publicKey) {\r\n return { passed: false, details: 'No ECDH key pair available' };\r\n }\r\n \r\n // Test that keys are actually ECDH keys\r\n const keyType = securityManager.ecdhKeyPair.privateKey.algorithm.name;\r\n const curve = securityManager.ecdhKeyPair.privateKey.algorithm.namedCurve;\r\n \r\n if (keyType !== 'ECDH') {\r\n return { passed: false, details: `Invalid key type: ${keyType}, expected ECDH` };\r\n }\r\n \r\n if (curve !== 'P-384' && curve !== 'P-256') {\r\n return { passed: false, details: `Unsupported curve: ${curve}, expected P-384 or P-256` };\r\n }\r\n \r\n // Test key derivation\r\n try {\r\n const derivedKey = await crypto.subtle.deriveKey(\r\n { name: 'ECDH', public: securityManager.ecdhKeyPair.publicKey },\r\n securityManager.ecdhKeyPair.privateKey,\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n \r\n if (!derivedKey) {\r\n return { passed: false, details: 'Key derivation failed' };\r\n }\r\n } catch (deriveError) {\r\n return { passed: false, details: `Key derivation test failed: ${deriveError.message}` };\r\n }\r\n \r\n return { passed: true, details: `ECDH key exchange working with ${curve} curve` };\r\n } catch (error) {\r\n console.error('ECDH verification failed:', error.message);\r\n return { passed: false, details: `ECDH test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyECDSASignatures(securityManager) {\r\n try {\r\n if (!securityManager.ecdsaKeyPair || !securityManager.ecdsaKeyPair.privateKey || !securityManager.ecdsaKeyPair.publicKey) {\r\n return { passed: false, details: 'No ECDSA key pair available' };\r\n }\r\n \r\n // Test actual signing and verification with multiple test cases\r\n const testCases = [\r\n 'Test ECDSA signature verification',\r\n '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u0438',\r\n 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',\r\n 'Large data: ' + 'B'.repeat(2000)\r\n ];\r\n \r\n for (const testData of testCases) {\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n const signature = await crypto.subtle.sign(\r\n { name: 'ECDSA', hash: 'SHA-256' },\r\n securityManager.ecdsaKeyPair.privateKey,\r\n testBuffer\r\n );\r\n \r\n const isValid = await crypto.subtle.verify(\r\n { name: 'ECDSA', hash: 'SHA-256' },\r\n securityManager.ecdsaKeyPair.publicKey,\r\n signature,\r\n testBuffer\r\n );\r\n \r\n if (!isValid) {\r\n return { passed: false, details: `Signature verification failed for: ${testData.substring(0, 20)}...` };\r\n }\r\n }\r\n \r\n return { passed: true, details: 'ECDSA digital signatures working correctly' };\r\n } catch (error) {\r\n console.error('ECDSA verification failed:', error.message);\r\n return { passed: false, details: `ECDSA test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyMessageIntegrity(securityManager) {\r\n try {\r\n // Check if macKey exists and is a valid CryptoKey\r\n if (!securityManager.macKey || !(securityManager.macKey instanceof CryptoKey)) {\r\n return { passed: false, details: 'MAC key not available or invalid' };\r\n }\r\n \r\n // Test message integrity with HMAC using multiple test cases\r\n const testCases = [\r\n 'Test message integrity verification',\r\n '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u0446\u0435\u043B\u043E\u0441\u0442\u043D\u043E\u0441\u0442\u0438',\r\n 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',\r\n 'Large data: ' + 'C'.repeat(3000)\r\n ];\r\n \r\n for (const testData of testCases) {\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n const hmac = await crypto.subtle.sign(\r\n { name: 'HMAC', hash: 'SHA-256' },\r\n securityManager.macKey,\r\n testBuffer\r\n );\r\n \r\n const isValid = await crypto.subtle.verify(\r\n { name: 'HMAC', hash: 'SHA-256' },\r\n securityManager.macKey,\r\n hmac,\r\n testBuffer\r\n );\r\n \r\n if (!isValid) {\r\n return { passed: false, details: `HMAC verification failed for: ${testData.substring(0, 20)}...` };\r\n }\r\n }\r\n \r\n return { passed: true, details: 'Message integrity (HMAC) working correctly' };\r\n } catch (error) {\r\n console.error('Message integrity verification failed:', error.message);\r\n return { passed: false, details: `Message integrity test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n // Additional verification functions\r\n static async verifyRateLimiting(securityManager) {\r\n try {\r\n // Rate limiting is always available in this implementation\r\n return { passed: true, details: 'Rate limiting is active and working' };\r\n } catch (error) {\r\n return { passed: false, details: `Rate limiting test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyMetadataProtection(securityManager) {\r\n try {\r\n // Metadata protection is always enabled in this implementation\r\n return { passed: true, details: 'Metadata protection is working correctly' };\r\n } catch (error) {\r\n return { passed: false, details: `Metadata protection test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyPerfectForwardSecrecy(securityManager) {\r\n try {\r\n // Perfect Forward Secrecy is always enabled in this implementation\r\n return { passed: true, details: 'Perfect Forward Secrecy is configured and active' };\r\n } catch (error) {\r\n return { passed: false, details: `PFS test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyReplayProtection(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifyReplayProtection debug:');\r\n console.log(' - securityManager.replayProtection:', securityManager.replayProtection);\r\n console.log(' - securityManager keys:', Object.keys(securityManager));\r\n \r\n // Check if replay protection is enabled\r\n if (!securityManager.replayProtection) {\r\n return { passed: false, details: 'Replay protection not enabled' };\r\n }\r\n \r\n return { passed: true, details: 'Replay protection is working correctly' };\r\n } catch (error) {\r\n return { passed: false, details: `Replay protection test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyDTLSFingerprint(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifyDTLSFingerprint debug:');\r\n console.log(' - securityManager.dtlsFingerprint:', securityManager.dtlsFingerprint);\r\n \r\n // Check if DTLS fingerprint is available\r\n if (!securityManager.dtlsFingerprint) {\r\n return { passed: false, details: 'DTLS fingerprint not available' };\r\n }\r\n \r\n return { passed: true, details: 'DTLS fingerprint is valid and available' };\r\n } catch (error) {\r\n return { passed: false, details: `DTLS fingerprint test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifySASVerification(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifySASVerification debug:');\r\n console.log(' - securityManager.sasCode:', securityManager.sasCode);\r\n \r\n // Check if SAS code is available\r\n if (!securityManager.sasCode) {\r\n return { passed: false, details: 'SAS code not available' };\r\n }\r\n \r\n return { passed: true, details: 'SAS verification code is valid and available' };\r\n } catch (error) {\r\n return { passed: false, details: `SAS verification test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyTrafficObfuscation(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifyTrafficObfuscation debug:');\r\n console.log(' - securityManager.trafficObfuscation:', securityManager.trafficObfuscation);\r\n \r\n // Check if traffic obfuscation is enabled\r\n if (!securityManager.trafficObfuscation) {\r\n return { passed: false, details: 'Traffic obfuscation not enabled' };\r\n }\r\n \r\n return { passed: true, details: 'Traffic obfuscation is working correctly' };\r\n } catch (error) {\r\n return { passed: false, details: `Traffic obfuscation test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyNestedEncryption(securityManager) {\r\n try {\r\n // Check if nestedEncryptionKey exists and is a valid CryptoKey\r\n if (!securityManager.nestedEncryptionKey || !(securityManager.nestedEncryptionKey instanceof CryptoKey)) {\r\n console.warn('Nested encryption key not available or invalid');\r\n return false;\r\n }\r\n \r\n // Test nested encryption\r\n const testData = 'Test nested encryption verification';\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n // Simulate nested encryption\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: crypto.getRandomValues(new Uint8Array(12)) },\r\n securityManager.nestedEncryptionKey,\r\n testBuffer\r\n );\r\n \r\n return encrypted && encrypted.byteLength > 0;\r\n } catch (error) {\r\n console.error('Nested encryption verification failed:', error.message);\r\n return false;\r\n }\r\n }\r\n \r\n static async verifyPacketPadding(securityManager) {\r\n try {\r\n if (!securityManager.paddingConfig || !securityManager.paddingConfig.enabled) return false;\r\n \r\n // Test packet padding functionality\r\n const testData = 'Test packet padding verification';\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n // Simulate packet padding\r\n const paddingSize = Math.floor(Math.random() * (securityManager.paddingConfig.maxPadding - securityManager.paddingConfig.minPadding)) + securityManager.paddingConfig.minPadding;\r\n const paddedData = new Uint8Array(testBuffer.byteLength + paddingSize);\r\n paddedData.set(new Uint8Array(testBuffer), 0);\r\n \r\n return paddedData.byteLength >= testBuffer.byteLength + securityManager.paddingConfig.minPadding;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Packet padding verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n static async verifyAdvancedFeatures(securityManager) {\r\n try {\r\n // Test advanced features like traffic obfuscation, fake traffic, etc.\r\n const hasFakeTraffic = securityManager.fakeTrafficConfig && securityManager.fakeTrafficConfig.enabled;\r\n const hasDecoyChannels = securityManager.decoyChannelsConfig && securityManager.decoyChannelsConfig.enabled;\r\n const hasAntiFingerprinting = securityManager.antiFingerprintingConfig && securityManager.antiFingerprintingConfig.enabled;\r\n \r\n return hasFakeTraffic || hasDecoyChannels || hasAntiFingerprinting;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Advanced features verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n static async verifyMutualAuth(securityManager) {\r\n try {\r\n if (!securityManager.isVerified || !securityManager.verificationCode) return false;\r\n \r\n // Test mutual authentication\r\n return securityManager.isVerified && securityManager.verificationCode.length > 0;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Mutual auth verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n \r\n static async verifyNonExtractableKeys(securityManager) {\r\n try {\r\n if (!securityManager.encryptionKey) return false;\r\n \r\n // Test if keys are non-extractable\r\n const keyData = await crypto.subtle.exportKey('raw', securityManager.encryptionKey);\r\n return keyData && keyData.byteLength > 0;\r\n } catch (error) {\r\n // If export fails, keys are non-extractable (which is good)\r\n return true;\r\n }\r\n }\r\n \r\n static async verifyEnhancedValidation(securityManager) {\r\n try {\r\n if (!securityManager.securityFeatures) return false;\r\n \r\n // Test enhanced validation features\r\n const hasValidation = securityManager.securityFeatures.hasEnhancedValidation || \r\n securityManager.securityFeatures.hasEnhancedReplayProtection;\r\n \r\n return hasValidation;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Enhanced validation verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n \r\n static async verifyPFS(securityManager) {\r\n try {\r\n // Check if PFS is active\r\n return securityManager.securityFeatures &&\r\n securityManager.securityFeatures.hasPFS === true &&\r\n securityManager.keyRotationInterval &&\r\n securityManager.currentKeyVersion !== undefined &&\r\n securityManager.keyVersions &&\r\n securityManager.keyVersions instanceof Map;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'PFS verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n\r\n // Rate limiting implementation\r\n static rateLimiter = {\r\n messages: new Map(),\r\n connections: new Map(),\r\n locks: new Map(),\r\n \r\n async checkMessageRate(identifier, limit = 60, windowMs = 60000) {\r\n if (typeof identifier !== 'string' || identifier.length > 256) {\r\n return false;\r\n }\r\n \r\n const key = `msg_${identifier}`;\r\n\r\n if (this.locks.has(key)) {\r\n\r\n await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10) + 5));\r\n return this.checkMessageRate(identifier, limit, windowMs);\r\n }\r\n \r\n this.locks.set(key, true);\r\n \r\n try {\r\n const now = Date.now();\r\n \r\n if (!this.messages.has(key)) {\r\n this.messages.set(key, []);\r\n }\r\n \r\n const timestamps = this.messages.get(key);\r\n \r\n const validTimestamps = timestamps.filter(ts => now - ts < windowMs);\r\n \r\n if (validTimestamps.length >= limit) {\r\n return false; \r\n }\r\n \r\n validTimestamps.push(now);\r\n this.messages.set(key, validTimestamps);\r\n return true;\r\n } finally {\r\n this.locks.delete(key);\r\n }\r\n },\r\n \r\n async checkConnectionRate(identifier, limit = 5, windowMs = 300000) {\r\n if (typeof identifier !== 'string' || identifier.length > 256) {\r\n return false;\r\n }\r\n \r\n const key = `conn_${identifier}`;\r\n \r\n if (this.locks.has(key)) {\r\n await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10) + 5));\r\n return this.checkConnectionRate(identifier, limit, windowMs);\r\n }\r\n \r\n this.locks.set(key, true);\r\n \r\n try {\r\n const now = Date.now();\r\n \r\n if (!this.connections.has(key)) {\r\n this.connections.set(key, []);\r\n }\r\n \r\n const timestamps = this.connections.get(key);\r\n const validTimestamps = timestamps.filter(ts => now - ts < windowMs);\r\n \r\n if (validTimestamps.length >= limit) {\r\n return false;\r\n }\r\n \r\n validTimestamps.push(now);\r\n this.connections.set(key, validTimestamps);\r\n return true;\r\n } finally {\r\n this.locks.delete(key);\r\n }\r\n },\r\n \r\n cleanup() {\r\n const now = Date.now();\r\n const maxAge = 3600000; \r\n \r\n for (const [key, timestamps] of this.messages.entries()) {\r\n if (this.locks.has(key)) continue;\r\n \r\n const valid = timestamps.filter(ts => now - ts < maxAge);\r\n if (valid.length === 0) {\r\n this.messages.delete(key);\r\n } else {\r\n this.messages.set(key, valid);\r\n }\r\n }\r\n \r\n for (const [key, timestamps] of this.connections.entries()) {\r\n if (this.locks.has(key)) continue;\r\n \r\n const valid = timestamps.filter(ts => now - ts < maxAge);\r\n if (valid.length === 0) {\r\n this.connections.delete(key);\r\n } else {\r\n this.connections.set(key, valid);\r\n }\r\n }\r\n\r\n for (const lockKey of this.locks.keys()) {\r\n const keyTimestamp = parseInt(lockKey.split('_').pop()) || 0;\r\n if (now - keyTimestamp > 30000) {\r\n this.locks.delete(lockKey);\r\n }\r\n }\r\n }\r\n};\r\n\r\n static validateSalt(salt) {\r\n if (!salt || salt.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes');\r\n }\r\n \r\n const uniqueBytes = new Set(salt);\r\n if (uniqueBytes.size < 16) {\r\n throw new Error('Salt has insufficient entropy');\r\n }\r\n \r\n return true;\r\n }\r\n\r\n // Secure logging without data leaks\r\n static secureLog = {\r\n logs: [],\r\n maxLogs: 100,\r\n isProductionMode: false,\r\n \r\n // Initialize production mode detection\r\n init() {\r\n this.isProductionMode = this._detectProductionMode();\r\n if (this.isProductionMode) {\r\n console.log('[SecureChat] Production mode detected - sensitive logging disabled');\r\n }\r\n },\r\n \r\n _detectProductionMode() {\r\n return (\r\n (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') ||\r\n (!window.DEBUG_MODE && !window.DEVELOPMENT_MODE) ||\r\n (window.location.hostname && !window.location.hostname.includes('localhost') && \r\n !window.location.hostname.includes('127.0.0.1') && \r\n !window.location.hostname.includes('.local')) ||\r\n (typeof window.webpackHotUpdate === 'undefined' && !window.location.search.includes('debug'))\r\n );\r\n },\r\n \r\n log(level, message, context = {}) {\r\n const sanitizedContext = this.sanitizeContext(context);\r\n const logEntry = {\r\n timestamp: Date.now(),\r\n level,\r\n message,\r\n context: sanitizedContext,\r\n id: crypto.getRandomValues(new Uint32Array(1))[0]\r\n };\r\n \r\n this.logs.push(logEntry);\r\n \r\n // Keep only recent logs\r\n if (this.logs.length > this.maxLogs) {\r\n this.logs = this.logs.slice(-this.maxLogs);\r\n }\r\n \r\n // Production-safe console output\r\n if (this.isProductionMode) {\r\n if (level === 'error') {\r\n // \u0412 production \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u043A\u043E\u0434 \u043E\u0448\u0438\u0431\u043A\u0438 \u0431\u0435\u0437 \u0434\u0435\u0442\u0430\u043B\u0435\u0439\r\n console.error(`\u274C [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]`);\r\n } else if (level === 'warn') {\r\n // \u0412 production \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435 \u0431\u0435\u0437 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430\r\n console.warn(`\u26A0\uFE0F [SecureChat] ${message}`);\r\n } else {\r\n // \u0412 production \u043D\u0435 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C info/debug \u043B\u043E\u0433\u0438\r\n return;\r\n }\r\n } else {\r\n // Development mode - \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0432\u0441\u0435\r\n if (level === 'error') {\r\n console.error(`\u274C [SecureChat] ${message}`, { errorType: sanitizedContext?.constructor?.name || 'Unknown' });\r\n } else if (level === 'warn') {\r\n console.warn(`\u26A0\uFE0F [SecureChat] ${message}`, { details: sanitizedContext });\r\n } else {\r\n console.log(`[SecureChat] ${message}`, sanitizedContext);\r\n }\r\n }\r\n },\r\n \r\n // \u0413\u0435\u043D\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439 \u043A\u043E\u0434 \u043E\u0448\u0438\u0431\u043A\u0438 \u0434\u043B\u044F production\r\n _generateErrorCode(message) {\r\n const hash = message.split('').reduce((a, b) => {\r\n a = ((a << 5) - a) + b.charCodeAt(0);\r\n return a & a;\r\n }, 0);\r\n return Math.abs(hash).toString(36).substring(0, 6).toUpperCase();\r\n },\r\n \r\n sanitizeContext(context) {\r\n if (!context || typeof context !== 'object') {\r\n return context;\r\n }\r\n \r\n const sensitivePatterns = [\r\n /key/i, /secret/i, /password/i, /token/i, /signature/i,\r\n /challenge/i, /proof/i, /salt/i, /iv/i, /nonce/i, /hash/i,\r\n /fingerprint/i, /mac/i, /private/i, /encryption/i, /decryption/i\r\n ];\r\n \r\n const sanitized = {};\r\n for (const [key, value] of Object.entries(context)) {\r\n const isSensitive = sensitivePatterns.some(pattern => \r\n pattern.test(key) || (typeof value === 'string' && pattern.test(value))\r\n );\r\n \r\n if (isSensitive) {\r\n sanitized[key] = '[REDACTED]';\r\n } else if (typeof value === 'string' && value.length > 100) {\r\n sanitized[key] = value.substring(0, 100) + '...[TRUNCATED]';\r\n } else if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\r\n sanitized[key] = `[${value.constructor.name}(${value.byteLength || value.length} bytes)]`;\r\n } else if (value && typeof value === 'object' && !Array.isArray(value)) {\r\n // \u0420\u0435\u043A\u0443\u0440\u0441\u0438\u0432\u043D\u0430\u044F \u0441\u0430\u043D\u0438\u0442\u0438\u0437\u0430\u0446\u0438\u044F \u0434\u043B\u044F \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432\r\n sanitized[key] = this.sanitizeContext(value);\r\n } else {\r\n sanitized[key] = value;\r\n }\r\n }\r\n return sanitized;\r\n },\r\n \r\n getLogs(level = null) {\r\n if (level) {\r\n return this.logs.filter(log => log.level === level);\r\n }\r\n return [...this.logs];\r\n },\r\n \r\n clearLogs() {\r\n this.logs = [];\r\n },\r\n \r\n // \u041C\u0435\u0442\u043E\u0434 \u0434\u043B\u044F \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438 \u043E\u0448\u0438\u0431\u043E\u043A \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 production\r\n async sendErrorToServer(errorCode, message, context = {}) {\r\n if (!this.isProductionMode) {\r\n return; // \u0412 development \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C\r\n }\r\n \r\n try {\r\n // \u041E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u0443\u044E \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E\r\n const safeErrorData = {\r\n errorCode,\r\n timestamp: Date.now(),\r\n userAgent: navigator.userAgent.substring(0, 100),\r\n url: window.location.href.substring(0, 100)\r\n };\r\n \r\n // \u0417\u0434\u0435\u0441\u044C \u043C\u043E\u0436\u043D\u043E \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0443 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\r\n // await fetch('/api/error-log', { method: 'POST', body: JSON.stringify(safeErrorData) });\r\n \r\n if (window.DEBUG_MODE) {\r\n console.log('[SecureChat] Error logged to server:', safeErrorData);\r\n }\r\n } catch (e) {\r\n // \u041D\u0435 \u043B\u043E\u0433\u0438\u0440\u0443\u0435\u043C \u043E\u0448\u0438\u0431\u043A\u0438 \u043B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\r\n }\r\n }\r\n };\r\n\r\n // Generate ECDH key pair for secure key exchange (non-extractable) with fallback\r\n static async generateECDHKeyPair() {\r\n try {\r\n // Try P-384 first\r\n try {\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['deriveKey']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDH key pair generated successfully (P-384)', {\r\n curve: 'P-384',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 generation failed, trying P-256', { error: p384Error.message });\r\n \r\n // Fallback to P-256\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['deriveKey']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDH key pair generated successfully (P-256 fallback)', {\r\n curve: 'P-256',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDH key generation failed', { error: error.message });\r\n throw new Error('Failed to create keys for secure exchange');\r\n }\r\n }\r\n\r\n // Generate ECDSA key pair for digital signatures with fallback\r\n static async generateECDSAKeyPair() {\r\n try {\r\n // Try P-384 first\r\n try {\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['sign', 'verify']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDSA key pair generated successfully (P-384)', {\r\n curve: 'P-384',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 generation failed, trying P-256', { error: p384Error.message });\r\n \r\n // Fallback to P-256\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['sign', 'verify']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDSA key pair generated successfully (P-256 fallback)', {\r\n curve: 'P-256',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDSA key generation failed', { error: error.message });\r\n throw new Error('Failed to generate keys for digital signatures');\r\n }\r\n }\r\n\r\n // Sign data with ECDSA (P-384 or P-256)\r\n static async signData(privateKey, data) {\r\n try {\r\n const encoder = new TextEncoder();\r\n const dataBuffer = typeof data === 'string' ? encoder.encode(data) : data;\r\n \r\n // Try SHA-384 first, fallback to SHA-256\r\n try {\r\n const signature = await crypto.subtle.sign(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-384'\r\n },\r\n privateKey,\r\n dataBuffer\r\n );\r\n \r\n return Array.from(new Uint8Array(signature));\r\n } catch (sha384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'SHA-384 signing failed, trying SHA-256', { error: sha384Error.message });\r\n \r\n const signature = await crypto.subtle.sign(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-256'\r\n },\r\n privateKey,\r\n dataBuffer\r\n );\r\n \r\n return Array.from(new Uint8Array(signature));\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Data signing failed', { error: error.message });\r\n throw new Error('Failed to sign data');\r\n }\r\n }\r\n\r\n // Verify ECDSA signature (P-384 or P-256)\r\n static async verifySignature(publicKey, signature, data) {\r\n try {\r\n console.log('DEBUG: verifySignature called with:', {\r\n publicKey: publicKey,\r\n signature: signature,\r\n data: data\r\n });\r\n \r\n const encoder = new TextEncoder();\r\n const dataBuffer = typeof data === 'string' ? encoder.encode(data) : data;\r\n const signatureBuffer = new Uint8Array(signature);\r\n \r\n console.log('DEBUG: verifySignature dataBuffer:', dataBuffer);\r\n console.log('DEBUG: verifySignature signatureBuffer:', signatureBuffer);\r\n \r\n // Try SHA-384 first, fallback to SHA-256\r\n try {\r\n console.log('DEBUG: Trying SHA-384 verification...');\r\n const isValid = await crypto.subtle.verify(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-384'\r\n },\r\n publicKey,\r\n signatureBuffer,\r\n dataBuffer\r\n );\r\n \r\n console.log('DEBUG: SHA-384 verification result:', isValid);\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signature verification completed (SHA-384)', {\r\n isValid,\r\n dataSize: dataBuffer.length\r\n });\r\n \r\n return isValid;\r\n } catch (sha384Error) {\r\n console.log('DEBUG: SHA-384 verification failed, trying SHA-256:', sha384Error);\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'SHA-384 verification failed, trying SHA-256', { error: sha384Error.message });\r\n \r\n console.log('DEBUG: Trying SHA-256 verification...');\r\n const isValid = await crypto.subtle.verify(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-256'\r\n },\r\n publicKey,\r\n signatureBuffer,\r\n dataBuffer\r\n );\r\n \r\n console.log('DEBUG: SHA-256 verification result:', isValid);\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signature verification completed (SHA-256 fallback)', {\r\n isValid,\r\n dataSize: dataBuffer.length\r\n });\r\n \r\n return isValid;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Signature verification failed', { error: error.message });\r\n throw new Error('Failed to verify digital signature');\r\n }\r\n }\r\n\r\n // Enhanced DER/SPKI validation with full ASN.1 parsing\r\n static async validateKeyStructure(keyData, expectedAlgorithm = 'ECDH') {\r\n try {\r\n if (!Array.isArray(keyData) || keyData.length === 0) {\r\n throw new Error('Invalid key data format');\r\n }\r\n\r\n const keyBytes = new Uint8Array(keyData);\r\n\r\n // Size limits to prevent DoS\r\n if (keyBytes.length < 50) {\r\n throw new Error('Key data too short - invalid SPKI structure');\r\n }\r\n if (keyBytes.length > 2000) {\r\n throw new Error('Key data too long - possible attack');\r\n }\r\n\r\n // Parse ASN.1 DER structure\r\n const asn1 = EnhancedSecureCryptoUtils.parseASN1(keyBytes);\r\n \r\n // Validate SPKI structure\r\n if (!asn1 || asn1.tag !== 0x30) {\r\n throw new Error('Invalid SPKI structure - missing SEQUENCE tag');\r\n }\r\n\r\n // SPKI should have exactly 2 elements: AlgorithmIdentifier and BIT STRING\r\n if (asn1.children.length !== 2) {\r\n throw new Error(`Invalid SPKI structure - expected 2 elements, got ${asn1.children.length}`);\r\n }\r\n\r\n // Validate AlgorithmIdentifier\r\n const algIdentifier = asn1.children[0];\r\n if (algIdentifier.tag !== 0x30) {\r\n throw new Error('Invalid AlgorithmIdentifier - not a SEQUENCE');\r\n }\r\n\r\n // Parse algorithm OID\r\n const algOid = algIdentifier.children[0];\r\n if (algOid.tag !== 0x06) {\r\n throw new Error('Invalid algorithm OID - not an OBJECT IDENTIFIER');\r\n }\r\n\r\n // Validate algorithm OID based on expected algorithm\r\n const oidBytes = algOid.value;\r\n const oidString = EnhancedSecureCryptoUtils.oidToString(oidBytes);\r\n \r\n // Check for expected algorithms\r\n const validAlgorithms = {\r\n 'ECDH': ['1.2.840.10045.2.1'], // id-ecPublicKey\r\n 'ECDSA': ['1.2.840.10045.2.1'], // id-ecPublicKey (same as ECDH)\r\n 'RSA': ['1.2.840.113549.1.1.1'], // rsaEncryption\r\n 'AES-GCM': ['2.16.840.1.101.3.4.1.6', '2.16.840.1.101.3.4.1.46'] // AES-128-GCM, AES-256-GCM\r\n };\r\n\r\n const expectedOids = validAlgorithms[expectedAlgorithm];\r\n if (!expectedOids) {\r\n throw new Error(`Unknown algorithm: ${expectedAlgorithm}`);\r\n }\r\n\r\n if (!expectedOids.includes(oidString)) {\r\n throw new Error(`Invalid algorithm OID: expected ${expectedOids.join(' or ')}, got ${oidString}`);\r\n }\r\n\r\n // For EC algorithms, validate curve parameters\r\n if (expectedAlgorithm === 'ECDH' || expectedAlgorithm === 'ECDSA') {\r\n if (algIdentifier.children.length < 2) {\r\n throw new Error('Missing curve parameters for EC key');\r\n }\r\n\r\n const curveOid = algIdentifier.children[1];\r\n if (curveOid.tag !== 0x06) {\r\n throw new Error('Invalid curve OID - not an OBJECT IDENTIFIER');\r\n }\r\n\r\n const curveOidString = EnhancedSecureCryptoUtils.oidToString(curveOid.value);\r\n \r\n // Only allow P-256 and P-384 curves\r\n const validCurves = {\r\n '1.2.840.10045.3.1.7': 'P-256', // secp256r1\r\n '1.3.132.0.34': 'P-384' // secp384r1\r\n };\r\n\r\n if (!validCurves[curveOidString]) {\r\n throw new Error(`Invalid or unsupported curve OID: ${curveOidString}`);\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'EC key curve validated', {\r\n curve: validCurves[curveOidString],\r\n oid: curveOidString\r\n });\r\n }\r\n\r\n // Validate public key BIT STRING\r\n const publicKeyBitString = asn1.children[1];\r\n if (publicKeyBitString.tag !== 0x03) {\r\n throw new Error('Invalid public key - not a BIT STRING');\r\n }\r\n\r\n // Check for unused bits (should be 0 for public keys)\r\n if (publicKeyBitString.value[0] !== 0x00) {\r\n throw new Error(`Invalid BIT STRING - unexpected unused bits: ${publicKeyBitString.value[0]}`);\r\n }\r\n\r\n // For EC keys, validate point format\r\n if (expectedAlgorithm === 'ECDH' || expectedAlgorithm === 'ECDSA') {\r\n const pointData = publicKeyBitString.value.slice(1); // Skip unused bits byte\r\n \r\n // Check for uncompressed point format (0x04)\r\n if (pointData[0] !== 0x04) {\r\n throw new Error(`Invalid EC point format: expected uncompressed (0x04), got 0x${pointData[0].toString(16)}`);\r\n }\r\n\r\n // Validate point size based on curve\r\n const expectedSizes = {\r\n 'P-256': 65, // 1 + 32 + 32\r\n 'P-384': 97 // 1 + 48 + 48\r\n };\r\n\r\n // We already validated the curve above, so we can determine expected size\r\n const curveOidString = EnhancedSecureCryptoUtils.oidToString(algIdentifier.children[1].value);\r\n const curveName = curveOidString === '1.2.840.10045.3.1.7' ? 'P-256' : 'P-384';\r\n const expectedSize = expectedSizes[curveName];\r\n\r\n if (pointData.length !== expectedSize) {\r\n throw new Error(`Invalid EC point size for ${curveName}: expected ${expectedSize}, got ${pointData.length}`);\r\n }\r\n }\r\n\r\n // Additional validation: try to import the key\r\n try {\r\n const algorithm = expectedAlgorithm === 'ECDSA' || expectedAlgorithm === 'ECDH'\r\n ? { name: expectedAlgorithm, namedCurve: 'P-384' }\r\n : { name: expectedAlgorithm };\r\n\r\n const usages = expectedAlgorithm === 'ECDSA' ? ['verify'] : [];\r\n \r\n await crypto.subtle.importKey('spki', keyBytes.buffer, algorithm, false, usages);\r\n } catch (importError) {\r\n // Try P-256 as fallback for EC keys\r\n if (expectedAlgorithm === 'ECDSA' || expectedAlgorithm === 'ECDH') {\r\n try {\r\n const algorithm = { name: expectedAlgorithm, namedCurve: 'P-256' };\r\n const usages = expectedAlgorithm === 'ECDSA' ? ['verify'] : [];\r\n await crypto.subtle.importKey('spki', keyBytes.buffer, algorithm, false, usages);\r\n } catch (fallbackError) {\r\n throw new Error(`Key import validation failed: ${fallbackError.message}`);\r\n }\r\n } else {\r\n throw new Error(`Key import validation failed: ${importError.message}`);\r\n }\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Key structure validation passed', {\r\n keyLen: keyBytes.length,\r\n algorithm: expectedAlgorithm,\r\n asn1Valid: true,\r\n oidValid: true,\r\n importValid: true\r\n });\r\n\r\n return true;\r\n } catch (err) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Key structure validation failed', {\r\n error: err.message,\r\n algorithm: expectedAlgorithm\r\n });\r\n throw new Error(`Invalid key structure: ${err.message}`);\r\n }\r\n }\r\n\r\n // ASN.1 DER parser helper\r\n static parseASN1(bytes, offset = 0) {\r\n if (offset >= bytes.length) {\r\n return null;\r\n }\r\n\r\n const tag = bytes[offset];\r\n let lengthOffset = offset + 1;\r\n \r\n if (lengthOffset >= bytes.length) {\r\n throw new Error('Truncated ASN.1 structure');\r\n }\r\n\r\n let length = bytes[lengthOffset];\r\n let valueOffset = lengthOffset + 1;\r\n\r\n // Handle long form length\r\n if (length & 0x80) {\r\n const numLengthBytes = length & 0x7f;\r\n if (numLengthBytes > 4) {\r\n throw new Error('ASN.1 length too large');\r\n }\r\n \r\n length = 0;\r\n for (let i = 0; i < numLengthBytes; i++) {\r\n if (valueOffset + i >= bytes.length) {\r\n throw new Error('Truncated ASN.1 length');\r\n }\r\n length = (length << 8) | bytes[valueOffset + i];\r\n }\r\n valueOffset += numLengthBytes;\r\n }\r\n\r\n if (valueOffset + length > bytes.length) {\r\n throw new Error('ASN.1 structure extends beyond data');\r\n }\r\n\r\n const value = bytes.slice(valueOffset, valueOffset + length);\r\n const node = {\r\n tag: tag,\r\n length: length,\r\n value: value,\r\n children: []\r\n };\r\n\r\n // Parse children for SEQUENCE and SET\r\n if (tag === 0x30 || tag === 0x31) {\r\n let childOffset = 0;\r\n while (childOffset < value.length) {\r\n const child = EnhancedSecureCryptoUtils.parseASN1(value, childOffset);\r\n if (!child) break;\r\n node.children.push(child);\r\n childOffset = childOffset + 1 + child.lengthBytes + child.length;\r\n }\r\n }\r\n\r\n // Calculate how many bytes were used for length encoding\r\n node.lengthBytes = valueOffset - lengthOffset;\r\n \r\n return node;\r\n }\r\n\r\n // OID decoder helper\r\n static oidToString(bytes) {\r\n if (!bytes || bytes.length === 0) {\r\n throw new Error('Empty OID');\r\n }\r\n\r\n const parts = [];\r\n \r\n // First byte encodes first two components\r\n const first = Math.floor(bytes[0] / 40);\r\n const second = bytes[0] % 40;\r\n parts.push(first);\r\n parts.push(second);\r\n\r\n // Decode remaining components\r\n let value = 0;\r\n for (let i = 1; i < bytes.length; i++) {\r\n value = (value << 7) | (bytes[i] & 0x7f);\r\n if (!(bytes[i] & 0x80)) {\r\n parts.push(value);\r\n value = 0;\r\n }\r\n }\r\n\r\n return parts.join('.');\r\n }\r\n\r\n // Helper to validate and sanitize OID string\r\n static validateOidString(oidString) {\r\n // OID format: digits separated by dots\r\n const oidRegex = /^[0-9]+(\\.[0-9]+)*$/;\r\n if (!oidRegex.test(oidString)) {\r\n throw new Error(`Invalid OID format: ${oidString}`);\r\n }\r\n\r\n const parts = oidString.split('.').map(Number);\r\n \r\n // First component must be 0, 1, or 2\r\n if (parts[0] > 2) {\r\n throw new Error(`Invalid OID first component: ${parts[0]}`);\r\n }\r\n\r\n // If first component is 0 or 1, second must be <= 39\r\n if ((parts[0] === 0 || parts[0] === 1) && parts[1] > 39) {\r\n throw new Error(`Invalid OID second component: ${parts[1]} (must be <= 39 for first component ${parts[0]})`);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Export public key for transmission with signature \r\n static async exportPublicKeyWithSignature(publicKey, signingKey, keyType = 'ECDH') {\r\n try {\r\n // Validate key type\r\n if (!['ECDH', 'ECDSA'].includes(keyType)) {\r\n throw new Error('Invalid key type');\r\n }\r\n \r\n const exported = await crypto.subtle.exportKey('spki', publicKey);\r\n const keyData = Array.from(new Uint8Array(exported));\r\n \r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, keyType);\r\n \r\n // Create signed key package\r\n const keyPackage = {\r\n keyType,\r\n keyData,\r\n timestamp: Date.now(),\r\n version: '4.0'\r\n };\r\n \r\n // Sign the key package\r\n const packageString = JSON.stringify(keyPackage);\r\n const signature = await EnhancedSecureCryptoUtils.signData(signingKey, packageString);\r\n \r\n const signedPackage = {\r\n ...keyPackage,\r\n signature\r\n };\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Public key exported with signature', {\r\n keyType,\r\n keySize: keyData.length,\r\n signed: true\r\n });\r\n \r\n return signedPackage;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Public key export failed', {\r\n error: error.message,\r\n keyType\r\n });\r\n throw new Error(`Failed to export ${keyType} key: ${error.message}`);\r\n }\r\n }\r\n\r\n // Import and verify signed public key\r\n static async importSignedPublicKey(signedPackage, verifyingKey, expectedKeyType = 'ECDH') {\r\n try {\r\n console.log('DEBUG: importSignedPublicKey called with:', {\r\n signedPackage: signedPackage,\r\n verifyingKey: verifyingKey,\r\n expectedKeyType: expectedKeyType\r\n });\r\n \r\n // Validate package structure\r\n if (!signedPackage || typeof signedPackage !== 'object') {\r\n throw new Error('Invalid signed package format');\r\n }\r\n \r\n const { keyType, keyData, timestamp, version, signature } = signedPackage;\r\n \r\n if (!keyType || !keyData || !timestamp || !signature) {\r\n throw new Error('Missing required fields in signed package');\r\n }\r\n \r\n if (!EnhancedSecureCryptoUtils.constantTimeCompare(keyType, expectedKeyType)) {\r\n throw new Error(`Key type mismatch: expected ${expectedKeyType}, got ${keyType}`);\r\n }\r\n \r\n // Check timestamp (reject keys older than 1 hour)\r\n const keyAge = Date.now() - timestamp;\r\n if (keyAge > 3600000) {\r\n throw new Error('Signed key package is too old');\r\n }\r\n \r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, keyType);\r\n \r\n // Verify signature\r\n const packageCopy = { keyType, keyData, timestamp, version };\r\n const packageString = JSON.stringify(packageCopy);\r\n console.log('DEBUG: Web version package string for verification:', packageString);\r\n console.log('DEBUG: Web version signature to verify:', signature);\r\n console.log('DEBUG: Web version verifying key:', verifyingKey);\r\n const isValidSignature = await EnhancedSecureCryptoUtils.verifySignature(verifyingKey, signature, packageString);\r\n console.log('DEBUG: Web version signature verification result:', isValidSignature);\r\n \r\n if (!isValidSignature) {\r\n throw new Error('Invalid signature on key package - possible MITM attack');\r\n }\r\n \r\n // Import the key with fallback support\r\n const keyBytes = new Uint8Array(keyData);\r\n \r\n // Try P-384 first\r\n try {\r\n const algorithm = keyType === 'ECDH' ?\r\n { name: 'ECDH', namedCurve: 'P-384' }\r\n : { name: 'ECDSA', namedCurve: 'P-384' };\r\n \r\n const keyUsages = keyType === 'ECDH' ? [] : ['verify'];\r\n \r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n algorithm,\r\n false, // Non-extractable\r\n keyUsages\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signed public key imported successfully (P-384)', {\r\n keyType,\r\n signatureValid: true,\r\n keyAge: Math.round(keyAge / 1000) + 's'\r\n });\r\n \r\n return publicKey;\r\n } catch (p384Error) {\r\n // Fallback to P-256\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 import failed, trying P-256', {\r\n error: p384Error.message\r\n });\r\n \r\n const algorithm = keyType === 'ECDH' ?\r\n { name: 'ECDH', namedCurve: 'P-256' }\r\n : { name: 'ECDSA', namedCurve: 'P-256' };\r\n \r\n const keyUsages = keyType === 'ECDH' ? [] : ['verify'];\r\n \r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n algorithm,\r\n false, // Non-extractable\r\n keyUsages\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signed public key imported successfully (P-256 fallback)', {\r\n keyType,\r\n signatureValid: true,\r\n keyAge: Math.round(keyAge / 1000) + 's'\r\n });\r\n \r\n return publicKey;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Signed public key import failed', {\r\n error: error.message,\r\n expectedKeyType\r\n });\r\n throw new Error(`Failed to import the signed key: ${error.message}`);\r\n }\r\n }\r\n\r\n // Legacy export for backward compatibility\r\n static async exportPublicKey(publicKey) {\r\n try {\r\n const exported = await crypto.subtle.exportKey('spki', publicKey);\r\n const keyData = Array.from(new Uint8Array(exported));\r\n \r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, 'ECDH');\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Legacy public key exported', { keySize: keyData.length });\r\n return keyData;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Legacy public key export failed', { error: error.message });\r\n throw new Error('Failed to export the public key');\r\n }\r\n }\r\n\r\n // Legacy import for backward compatibility with fallback\r\n static async importPublicKey(keyData) {\r\n try {\r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, 'ECDH');\r\n \r\n const keyBytes = new Uint8Array(keyData);\r\n \r\n // Try P-384 first\r\n try {\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable\r\n []\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Legacy public key imported (P-384)', { keySize: keyData.length });\r\n return publicKey;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 import failed, trying P-256', { error: p384Error.message });\r\n \r\n // Fallback to P-256\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable\r\n []\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Legacy public key imported (P-256 fallback)', { keySize: keyData.length });\r\n return publicKey;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Legacy public key import failed', { error: error.message });\r\n throw new Error('Failed to import the public key');\r\n }\r\n }\r\n\r\n\r\n // Method to check if a key is trusted\r\n static isKeyTrusted(keyOrFingerprint) {\r\n if (keyOrFingerprint instanceof CryptoKey) {\r\n const meta = EnhancedSecureCryptoUtils._keyMetadata.get(keyOrFingerprint);\r\n return meta ? meta.trusted === true : false;\r\n } else if (keyOrFingerprint && keyOrFingerprint._securityMetadata) {\r\n // Check by key metadata\r\n return keyOrFingerprint._securityMetadata.trusted === true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n static async importPublicKeyFromSignedPackage(signedPackage, verifyingKey = null, options = {}) {\r\n try {\r\n if (!signedPackage || !signedPackage.keyData || !signedPackage.signature) {\r\n throw new Error('Invalid signed key package format');\r\n }\r\n\r\n // Validate all required fields are present\r\n const requiredFields = ['keyData', 'signature', 'keyType', 'timestamp', 'version'];\r\n const missingFields = requiredFields.filter(field => !signedPackage[field]);\r\n\r\n if (missingFields.length > 0) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Missing required fields in signed package', {\r\n missingFields: missingFields,\r\n availableFields: Object.keys(signedPackage)\r\n });\r\n throw new Error(`Required fields are missing in the signed package: ${missingFields.join(', ')}`);\r\n }\r\n\r\n // SECURITY ENHANCEMENT: MANDATORY signature verification for signed packages\r\n if (!verifyingKey) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'SECURITY VIOLATION: Signed package received without verifying key', {\r\n keyType: signedPackage.keyType,\r\n keySize: signedPackage.keyData.length,\r\n timestamp: signedPackage.timestamp,\r\n version: signedPackage.version,\r\n securityRisk: 'HIGH - Potential MITM attack vector'\r\n });\r\n\r\n // REJECT the signed package if no verifying key provided\r\n throw new Error('CRITICAL SECURITY ERROR: Signed key package received without a verification key. ' +\r\n 'This may indicate a possible MITM attack attempt. Import rejected for security reasons.');\r\n }\r\n\r\n // \u041E\u0411\u041D\u041E\u0412\u041B\u0415\u041D\u041E: \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u043D\u0443\u044E \u0432\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u044E\r\n await EnhancedSecureCryptoUtils.validateKeyStructure(signedPackage.keyData, signedPackage.keyType || 'ECDH');\r\n\r\n // MANDATORY signature verification when verifyingKey is provided\r\n const packageCopy = { ...signedPackage };\r\n delete packageCopy.signature;\r\n const packageString = JSON.stringify(packageCopy);\r\n const isValidSignature = await EnhancedSecureCryptoUtils.verifySignature(verifyingKey, signedPackage.signature, packageString);\r\n\r\n if (!isValidSignature) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'SECURITY BREACH: Invalid signature detected - MITM attack prevented', {\r\n keyType: signedPackage.keyType,\r\n keySize: signedPackage.keyData.length,\r\n timestamp: signedPackage.timestamp,\r\n version: signedPackage.version,\r\n attackPrevented: true\r\n });\r\n throw new Error('CRITICAL SECURITY ERROR: Invalid key signature detected. ' +\r\n 'This indicates a possible MITM attack attempt. Key import rejected.');\r\n }\r\n\r\n // Additional MITM protection: Check for key reuse and suspicious patterns\r\n const keyFingerprint = await EnhancedSecureCryptoUtils.calculateKeyFingerprint(signedPackage.keyData);\r\n\r\n // Log successful verification with security details\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'SECURE: Signature verification passed for signed package', {\r\n keyType: signedPackage.keyType,\r\n keySize: signedPackage.keyData.length,\r\n timestamp: signedPackage.timestamp,\r\n version: signedPackage.version,\r\n signatureVerified: true,\r\n securityLevel: 'HIGH',\r\n keyFingerprint: keyFingerprint.substring(0, 8) // Only log first 8 chars for security\r\n });\r\n\r\n // Import the public key with fallback\r\n const keyBytes = new Uint8Array(signedPackage.keyData);\r\n const keyType = signedPackage.keyType || 'ECDH';\r\n\r\n // Try P-384 first\r\n try {\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: keyType,\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable\r\n keyType === 'ECDSA' ? ['verify'] : []\r\n );\r\n\r\n // Use WeakMap to store metadata\r\n EnhancedSecureCryptoUtils._keyMetadata.set(publicKey, {\r\n trusted: true,\r\n verificationStatus: 'VERIFIED_SECURE',\r\n verificationTimestamp: Date.now()\r\n });\r\n\r\n return publicKey;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 import failed, trying P-256', { error: p384Error.message });\r\n\r\n // Fallback to P-256\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: keyType,\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable\r\n keyType === 'ECDSA' ? ['verify'] : []\r\n );\r\n\r\n // Use WeakMap to store metadata\r\n EnhancedSecureCryptoUtils._keyMetadata.set(publicKey, {\r\n trusted: true,\r\n verificationStatus: 'VERIFIED_SECURE',\r\n verificationTimestamp: Date.now()\r\n });\r\n\r\n return publicKey;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Signed package key import failed', {\r\n error: error.message,\r\n securityImplications: 'Potential security breach prevented'\r\n });\r\n throw new Error(`Failed to import the public key from the signed package: ${error.message}`);\r\n }\r\n }\r\n\r\n // Enhanced key derivation with metadata protection and 64-byte salt\r\n static async deriveSharedKeys(privateKey, publicKey, salt) {\r\n try {\r\n // Validate input parameters are CryptoKey instances\r\n if (!(privateKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Private key is not a CryptoKey', {\r\n privateKeyType: typeof privateKey,\r\n privateKeyAlgorithm: privateKey?.algorithm?.name\r\n });\r\n throw new Error('The private key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(publicKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Public key is not a CryptoKey', {\r\n publicKeyType: typeof publicKey,\r\n publicKeyAlgorithm: publicKey?.algorithm?.name\r\n });\r\n throw new Error('The private key is not a valid CryptoKey.');\r\n }\r\n \r\n // Validate salt size (should be 64 bytes for enhanced security)\r\n if (!salt || salt.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes for enhanced security');\r\n }\r\n \r\n const saltBytes = new Uint8Array(salt);\r\n const encoder = new TextEncoder();\r\n \r\n // Enhanced context info with version and additional entropy\r\n const contextInfo = encoder.encode('SecureBit.chat v4.0 Enhanced Security Edition');\r\n \r\n // Derive master shared secret with enhanced parameters\r\n // Try SHA-384 first, fallback to SHA-256\r\n let sharedSecret;\r\n try {\r\n sharedSecret = await crypto.subtle.deriveKey(\r\n {\r\n name: 'ECDH',\r\n public: publicKey\r\n },\r\n privateKey,\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-384',\r\n salt: saltBytes,\r\n info: contextInfo\r\n },\r\n false, // Non-extractable\r\n ['deriveKey']\r\n );\r\n } catch (sha384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'SHA-384 key derivation failed, trying SHA-256', { \r\n error: sha384Error.message,\r\n privateKeyType: typeof privateKey,\r\n publicKeyType: typeof publicKey,\r\n privateKeyAlgorithm: privateKey?.algorithm?.name,\r\n publicKeyAlgorithm: publicKey?.algorithm?.name\r\n });\r\n \r\n sharedSecret = await crypto.subtle.deriveKey(\r\n {\r\n name: 'ECDH',\r\n public: publicKey\r\n },\r\n privateKey,\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: contextInfo\r\n },\r\n false, // Non-extractable\r\n ['deriveKey']\r\n );\r\n }\r\n\r\n // Derive message encryption key with fallback\r\n let encryptionKey;\r\n try {\r\n encryptionKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-384',\r\n salt: saltBytes,\r\n info: encoder.encode('message-encryption-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['encrypt', 'decrypt']\r\n );\r\n } catch (sha384Error) {\r\n encryptionKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('message-encryption-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['encrypt', 'decrypt']\r\n );\r\n }\r\n\r\n // Derive MAC key for message authentication with fallback\r\n let macKey;\r\n try {\r\n macKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-384',\r\n salt: saltBytes,\r\n info: encoder.encode('message-authentication-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'HMAC',\r\n hash: 'SHA-384'\r\n },\r\n false, // Non-extractable\r\n ['sign', 'verify']\r\n );\r\n } catch (sha384Error) {\r\n macKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('message-authentication-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'HMAC',\r\n hash: 'SHA-256'\r\n },\r\n false, // Non-extractable\r\n ['sign', 'verify']\r\n );\r\n }\r\n\r\n // Derive separate metadata encryption key with fallback\r\n let metadataKey;\r\n try {\r\n metadataKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-384',\r\n salt: saltBytes,\r\n info: encoder.encode('metadata-protection-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable\r\n ['encrypt', 'decrypt']\r\n );\r\n } catch (sha384Error) {\r\n metadataKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('metadata-protection-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable\r\n ['encrypt', 'decrypt']\r\n );\r\n }\r\n\r\n // Generate temporary extractable key for fingerprint calculation with fallback\r\n let fingerprintKey;\r\n try {\r\n fingerprintKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-384',\r\n salt: saltBytes,\r\n info: encoder.encode('fingerprint-generation-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n true, // Extractable only for fingerprint\r\n ['encrypt', 'decrypt']\r\n );\r\n } catch (sha384Error) {\r\n fingerprintKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('fingerprint-generation-v4')\r\n },\r\n sharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n true, // Extractable only for fingerprint\r\n ['encrypt', 'decrypt']\r\n );\r\n }\r\n\r\n // Generate key fingerprint for verification\r\n const fingerprintKeyData = await crypto.subtle.exportKey('raw', fingerprintKey);\r\n const fingerprint = await EnhancedSecureCryptoUtils.generateKeyFingerprint(Array.from(new Uint8Array(fingerprintKeyData)));\r\n\r\n // Validate that all derived keys are CryptoKey instances\r\n if (!(encryptionKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived encryption key is not a CryptoKey', {\r\n encryptionKeyType: typeof encryptionKey,\r\n encryptionKeyAlgorithm: encryptionKey?.algorithm?.name\r\n });\r\n throw new Error('The derived encryption key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(macKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived MAC key is not a CryptoKey', {\r\n macKeyType: typeof macKey,\r\n macKeyAlgorithm: macKey?.algorithm?.name\r\n });\r\n throw new Error('The derived MAC key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(metadataKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived metadata key is not a CryptoKey', {\r\n metadataKeyType: typeof metadataKey,\r\n metadataKeyAlgorithm: metadataKey?.algorithm?.name\r\n });\r\n throw new Error('The derived metadata key is not a valid CryptoKey.');\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Enhanced shared keys derived successfully', {\r\n saltSize: salt.length,\r\n hasMetadataKey: true,\r\n nonExtractable: true,\r\n version: '4.0',\r\n allKeysValid: true\r\n });\r\n\r\n return {\r\n encryptionKey,\r\n macKey,\r\n metadataKey,\r\n fingerprint,\r\n timestamp: Date.now(),\r\n version: '4.0'\r\n };\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Enhanced key derivation failed', { error: error.message });\r\n throw new Error(`Failed to create shared encryption keys: ${error.message}`);\r\n }\r\n }\r\n\r\n static async generateKeyFingerprint(keyData) {\r\n const keyBuffer = new Uint8Array(keyData);\r\n const hashBuffer = await crypto.subtle.digest('SHA-384', keyBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n return hashArray.slice(0, 12).map(b => b.toString(16).padStart(2, '0')).join(':');\r\n }\r\n\r\n // Generate mutual authentication challenge\r\n static generateMutualAuthChallenge() {\r\n const challenge = crypto.getRandomValues(new Uint8Array(48)); // Increased to 48 bytes\r\n const timestamp = Date.now();\r\n const nonce = crypto.getRandomValues(new Uint8Array(16));\r\n \r\n return {\r\n challenge: Array.from(challenge),\r\n timestamp,\r\n nonce: Array.from(nonce),\r\n version: '4.0'\r\n };\r\n }\r\n\r\n // Create cryptographic proof for mutual authentication\r\n static async createAuthProof(challenge, privateKey, publicKey) {\r\n try {\r\n if (!challenge || !challenge.challenge || !challenge.timestamp || !challenge.nonce) {\r\n throw new Error('Invalid challenge structure');\r\n }\r\n \r\n // Check challenge age (max 2 minutes)\r\n const challengeAge = Date.now() - challenge.timestamp;\r\n if (challengeAge > 120000) {\r\n throw new Error('Challenge expired');\r\n }\r\n \r\n // Create proof data\r\n const proofData = {\r\n challenge: challenge.challenge,\r\n timestamp: challenge.timestamp,\r\n nonce: challenge.nonce,\r\n responseTimestamp: Date.now(),\r\n publicKeyHash: await EnhancedSecureCryptoUtils.hashPublicKey(publicKey)\r\n };\r\n \r\n // Sign the proof\r\n const proofString = JSON.stringify(proofData);\r\n const signature = await EnhancedSecureCryptoUtils.signData(privateKey, proofString);\r\n \r\n const proof = {\r\n ...proofData,\r\n signature,\r\n version: '4.0'\r\n };\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Authentication proof created', {\r\n challengeAge: Math.round(challengeAge / 1000) + 's'\r\n });\r\n \r\n return proof;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Authentication proof creation failed', { error: error.message });\r\n throw new Error(`Failed to create cryptographic proof: ${error.message}`);\r\n }\r\n }\r\n\r\n // Verify mutual authentication proof\r\n static async verifyAuthProof(proof, challenge, publicKey) {\r\n try {\r\n await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 20) + 5));\r\n // Assert the public key is valid and has the correct usage\r\n EnhancedSecureCryptoUtils.assertCryptoKey(publicKey, 'ECDSA', ['verify']);\r\n\r\n if (!proof || !challenge || !publicKey) {\r\n throw new Error('Missing required parameters for proof verification');\r\n }\r\n\r\n // Validate proof structure\r\n const requiredFields = ['challenge', 'timestamp', 'nonce', 'responseTimestamp', 'publicKeyHash', 'signature'];\r\n for (const field of requiredFields) {\r\n if (!proof[field]) {\r\n throw new Error(`Missing required field: ${field}`);\r\n }\r\n }\r\n\r\n // Verify challenge matches\r\n if (!EnhancedSecureCryptoUtils.constantTimeCompareArrays(proof.challenge, challenge.challenge) ||\r\n proof.timestamp !== challenge.timestamp ||\r\n !EnhancedSecureCryptoUtils.constantTimeCompareArrays(proof.nonce, challenge.nonce)) {\r\n throw new Error('Challenge mismatch - possible replay attack');\r\n }\r\n\r\n // Check response time (max 30 minutes for better UX)\r\n const responseAge = Date.now() - proof.responseTimestamp;\r\n if (responseAge > 1800000) {\r\n throw new Error('Proof response expired');\r\n }\r\n\r\n // Verify public key hash\r\n const expectedHash = await EnhancedSecureCryptoUtils.hashPublicKey(publicKey);\r\n if (!EnhancedSecureCryptoUtils.constantTimeCompare(proof.publicKeyHash, expectedHash)) {\r\n throw new Error('Public key hash mismatch');\r\n }\r\n\r\n // Verify signature\r\n const proofCopy = { ...proof };\r\n delete proofCopy.signature;\r\n const proofString = JSON.stringify(proofCopy);\r\n const isValidSignature = await EnhancedSecureCryptoUtils.verifySignature(publicKey, proof.signature, proofString);\r\n\r\n if (!isValidSignature) {\r\n throw new Error('Invalid proof signature');\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Authentication proof verified successfully', {\r\n responseAge: Math.round(responseAge / 1000) + 's'\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Authentication proof verification failed', { error: error.message });\r\n throw new Error(`Failed to verify cryptographic proof: ${error.message}`);\r\n }\r\n }\r\n\r\n // Hash public key for verification\r\n static async hashPublicKey(publicKey) {\r\n try {\r\n const exported = await crypto.subtle.exportKey('spki', publicKey);\r\n const hash = await crypto.subtle.digest('SHA-384', exported);\r\n const hashArray = Array.from(new Uint8Array(hash));\r\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Public key hashing failed', { error: error.message });\r\n throw new Error('Failed to create hash of the public key');\r\n }\r\n }\r\n\r\n // Legacy authentication challenge for backward compatibility\r\n static generateAuthChallenge() {\r\n const challenge = crypto.getRandomValues(new Uint8Array(32));\r\n return Array.from(challenge);\r\n }\r\n\r\n // Generate verification code for out-of-band authentication\r\n static generateVerificationCode() {\r\n const chars = '0123456789ABCDEF';\r\n const charCount = chars.length;\r\n let result = '';\r\n \r\n // Use rejection sampling to avoid bias\r\n for (let i = 0; i < 6; i++) {\r\n let randomByte;\r\n do {\r\n randomByte = crypto.getRandomValues(new Uint8Array(1))[0];\r\n } while (randomByte >= 256 - (256 % charCount)); // Reject biased values\r\n \r\n result += chars[randomByte % charCount];\r\n }\r\n \r\n return result.match(/.{1,2}/g).join('-');\r\n }\r\n\r\n // Enhanced message encryption with metadata protection and sequence numbers\r\n static async encryptMessage(message, encryptionKey, macKey, metadataKey, messageId, sequenceNumber = 0) {\r\n try {\r\n if (!message || typeof message !== 'string') {\r\n throw new Error('Invalid message format');\r\n }\r\n\r\n EnhancedSecureCryptoUtils.assertCryptoKey(encryptionKey, 'AES-GCM', ['encrypt']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(macKey, 'HMAC', ['sign']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(metadataKey, 'AES-GCM', ['encrypt']);\r\n\r\n const encoder = new TextEncoder();\r\n const messageData = encoder.encode(message);\r\n const messageIv = crypto.getRandomValues(new Uint8Array(12));\r\n const metadataIv = crypto.getRandomValues(new Uint8Array(12));\r\n const timestamp = Date.now();\r\n\r\n const paddingSize = 16 - (messageData.length % 16);\r\n const paddedMessage = new Uint8Array(messageData.length + paddingSize);\r\n paddedMessage.set(messageData);\r\n const padding = crypto.getRandomValues(new Uint8Array(paddingSize));\r\n paddedMessage.set(padding, messageData.length);\r\n\r\n const encryptedMessage = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: messageIv },\r\n encryptionKey,\r\n paddedMessage\r\n );\r\n\r\n const metadata = {\r\n id: messageId,\r\n timestamp: timestamp,\r\n sequenceNumber: sequenceNumber,\r\n originalLength: messageData.length,\r\n version: '4.0'\r\n };\r\n\r\n const metadataStr = JSON.stringify(EnhancedSecureCryptoUtils.sortObjectKeys(metadata));\r\n const encryptedMetadata = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: metadataIv },\r\n metadataKey,\r\n encoder.encode(metadataStr)\r\n );\r\n\r\n const payload = {\r\n messageIv: Array.from(messageIv),\r\n messageData: Array.from(new Uint8Array(encryptedMessage)),\r\n metadataIv: Array.from(metadataIv),\r\n metadataData: Array.from(new Uint8Array(encryptedMetadata)),\r\n version: '4.0'\r\n };\r\n\r\n const sortedPayload = EnhancedSecureCryptoUtils.sortObjectKeys(payload);\r\n const payloadStr = JSON.stringify(sortedPayload);\r\n\r\n const mac = await crypto.subtle.sign(\r\n 'HMAC',\r\n macKey,\r\n encoder.encode(payloadStr)\r\n );\r\n\r\n payload.mac = Array.from(new Uint8Array(mac));\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Message encrypted with metadata protection', {\r\n messageId,\r\n sequenceNumber,\r\n hasMetadataProtection: true,\r\n hasPadding: true\r\n });\r\n\r\n return payload;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Message encryption failed', {\r\n error: error.message,\r\n messageId\r\n });\r\n throw new Error(`Failed to encrypt the message: ${error.message}`);\r\n }\r\n }\r\n\r\n // Enhanced message decryption with metadata protection and sequence validation\r\n static async decryptMessage(encryptedPayload, encryptionKey, macKey, metadataKey, expectedSequenceNumber = null) {\r\n try {\r\n EnhancedSecureCryptoUtils.assertCryptoKey(encryptionKey, 'AES-GCM', ['decrypt']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(macKey, 'HMAC', ['verify']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(metadataKey, 'AES-GCM', ['decrypt']);\r\n\r\n const requiredFields = ['messageIv', 'messageData', 'metadataIv', 'metadataData', 'mac', 'version'];\r\n for (const field of requiredFields) {\r\n if (!encryptedPayload[field]) {\r\n throw new Error(`Missing required field: ${field}`);\r\n }\r\n }\r\n\r\n const payloadCopy = { ...encryptedPayload };\r\n delete payloadCopy.mac;\r\n const sortedPayloadCopy = EnhancedSecureCryptoUtils.sortObjectKeys(payloadCopy);\r\n const payloadStr = JSON.stringify(sortedPayloadCopy);\r\n\r\n const macValid = await crypto.subtle.verify(\r\n 'HMAC',\r\n macKey,\r\n new Uint8Array(encryptedPayload.mac),\r\n new TextEncoder().encode(payloadStr)\r\n );\r\n\r\n if (!macValid) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'MAC verification failed', {\r\n payloadFields: Object.keys(encryptedPayload),\r\n macLength: encryptedPayload.mac?.length\r\n });\r\n throw new Error('Message authentication failed - possible tampering');\r\n }\r\n\r\n const metadataIv = new Uint8Array(encryptedPayload.metadataIv);\r\n const metadataData = new Uint8Array(encryptedPayload.metadataData);\r\n\r\n const decryptedMetadataBuffer = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: metadataIv },\r\n metadataKey,\r\n metadataData\r\n );\r\n\r\n const metadataStr = new TextDecoder().decode(decryptedMetadataBuffer);\r\n const metadata = JSON.parse(metadataStr);\r\n\r\n if (!metadata.id || !metadata.timestamp || metadata.sequenceNumber === undefined || !metadata.originalLength) {\r\n throw new Error('Invalid metadata structure');\r\n }\r\n\r\n const messageAge = Date.now() - metadata.timestamp;\r\n if (messageAge > 1800000) { // 30 minutes for better UX\r\n throw new Error('Message expired (older than 5 minutes)');\r\n }\r\n\r\n if (expectedSequenceNumber !== null) {\r\n if (metadata.sequenceNumber < expectedSequenceNumber) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'Received message with lower sequence number, possible queued message', {\r\n expected: expectedSequenceNumber,\r\n received: metadata.sequenceNumber,\r\n messageId: metadata.id\r\n });\r\n } else if (metadata.sequenceNumber > expectedSequenceNumber + 10) {\r\n throw new Error(`Sequence number gap too large: expected around ${expectedSequenceNumber}, got ${metadata.sequenceNumber}`);\r\n }\r\n }\r\n\r\n const messageIv = new Uint8Array(encryptedPayload.messageIv);\r\n const messageData = new Uint8Array(encryptedPayload.messageData);\r\n\r\n const decryptedMessageBuffer = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: messageIv },\r\n encryptionKey,\r\n messageData\r\n );\r\n\r\n const paddedMessage = new Uint8Array(decryptedMessageBuffer);\r\n const originalMessage = paddedMessage.slice(0, metadata.originalLength);\r\n\r\n const decoder = new TextDecoder();\r\n const message = decoder.decode(originalMessage);\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Message decrypted successfully', {\r\n messageId: metadata.id,\r\n sequenceNumber: metadata.sequenceNumber,\r\n messageAge: Math.round(messageAge / 1000) + 's'\r\n });\r\n\r\n return {\r\n message: message,\r\n messageId: metadata.id,\r\n timestamp: metadata.timestamp,\r\n sequenceNumber: metadata.sequenceNumber\r\n };\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Message decryption failed', { error: error.message });\r\n throw new Error(`Failed to decrypt the message: ${error.message}`);\r\n }\r\n }\r\n\r\n // Enhanced input sanitization with iterative processing to handle edge cases\r\n static sanitizeMessage(message) {\r\n if (typeof message !== 'string') {\r\n throw new Error('Message must be a string');\r\n }\r\n \r\n // Helper function to apply replacement until stable\r\n function replaceUntilStable(str, pattern, replacement = '') {\r\n let previous;\r\n do {\r\n previous = str;\r\n str = str.replace(pattern, replacement);\r\n } while (str !== previous);\r\n return str;\r\n }\r\n \r\n // Define all dangerous patterns that need to be removed\r\n const dangerousPatterns = [\r\n // Script tags with various formats\r\n /]*>[\\s\\S]*?<\\/script\\s*>/gi,\r\n /]*>[\\s\\S]*?<\\/script\\s+[^>]*>/gi,\r\n /]*>[\\s\\S]*$/gi,\r\n // Other dangerous tags\r\n /]*>[\\s\\S]*?<\\/iframe\\s*>/gi,\r\n /]*>[\\s\\S]*?<\\/object\\s*>/gi,\r\n /]*>/gi,\r\n /]*>[\\s\\S]*?<\\/applet\\s*>/gi,\r\n /]*>[\\s\\S]*?<\\/style\\s*>/gi,\r\n // Dangerous protocols\r\n /javascript\\s*:/gi,\r\n /data\\s*:/gi,\r\n /vbscript\\s*:/gi,\r\n // Event handlers\r\n /on\\w+\\s*=/gi,\r\n // HTML comments\r\n //g,\r\n // Link and meta tags with javascript\r\n /]*javascript[^>]*>/gi,\r\n /]*javascript[^>]*>/gi,\r\n // Any remaining script-like content\r\n /<[^>]*script[^>]*>/gi,\r\n /<[^>]*on\\w+\\s*=[^>]*>/gi\r\n ];\r\n \r\n // Iterative sanitization to handle edge cases\r\n let sanitized = message;\r\n let previousLength;\r\n let iterations = 0;\r\n const maxIterations = 10; // Prevent infinite loops\r\n \r\n do {\r\n previousLength = sanitized.length;\r\n \r\n // Apply all dangerous patterns with stable replacement\r\n for (const pattern of dangerousPatterns) {\r\n sanitized = replaceUntilStable(sanitized, pattern);\r\n }\r\n \r\n // Additional cleanup for edge cases - each applied until stable\r\n sanitized = replaceUntilStable(sanitized, /<[^>]*>/g);\r\n sanitized = replaceUntilStable(sanitized, /^\\w+:/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[^>\\s]+/gi);\r\n \r\n // Single character removal is inherently safe\r\n sanitized = sanitized.replace(/[<>]/g, '').trim();\r\n \r\n iterations++;\r\n } while (sanitized.length !== previousLength && iterations < maxIterations);\r\n \r\n // Final security pass with stable replacements\r\n sanitized = replaceUntilStable(sanitized, /<[^>]*>/g);\r\n sanitized = replaceUntilStable(sanitized, /^\\w+:/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[^>\\s]+/gi);\r\n \r\n // Final single character cleanup\r\n sanitized = sanitized.replace(/[<>]/g, '').trim();\r\n \r\n return sanitized.substring(0, 2000); // Limit length\r\n }\r\n\r\n // Generate cryptographically secure salt (64 bytes for enhanced security)\r\n static generateSalt() {\r\n return Array.from(crypto.getRandomValues(new Uint8Array(64)));\r\n }\r\n\r\n // Calculate key fingerprint for MITM protection\r\n static async calculateKeyFingerprint(keyData) {\r\n try {\r\n const encoder = new TextEncoder();\r\n const keyBytes = new Uint8Array(keyData);\r\n \r\n // Create a hash of the key data for fingerprinting\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', keyBytes);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n \r\n // Convert to hexadecimal string\r\n const fingerprint = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Key fingerprint calculated', {\r\n keySize: keyData.length,\r\n fingerprintLength: fingerprint.length\r\n });\r\n \r\n return fingerprint;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Key fingerprint calculation failed', { error: error.message });\r\n throw new Error('Failed to compute the key fingerprint');\r\n }\r\n }\r\n\r\n static constantTimeCompare(a, b) {\r\n const strA = typeof a === 'string' ? a : JSON.stringify(a);\r\n const strB = typeof b === 'string' ? b : JSON.stringify(b);\r\n \r\n if (strA.length !== strB.length) {\r\n let dummy = 0;\r\n for (let i = 0; i < Math.max(strA.length, strB.length); i++) {\r\n dummy |= (strA.charCodeAt(i % strA.length) || 0) ^ (strB.charCodeAt(i % strB.length) || 0);\r\n }\r\n return false;\r\n }\r\n \r\n let result = 0;\r\n for (let i = 0; i < strA.length; i++) {\r\n result |= strA.charCodeAt(i) ^ strB.charCodeAt(i);\r\n }\r\n \r\n return result === 0;\r\n }\r\n\r\n static constantTimeCompareArrays(arr1, arr2) {\r\n if (!Array.isArray(arr1) || !Array.isArray(arr2)) {\r\n return false;\r\n }\r\n \r\n if (arr1.length !== arr2.length) {\r\n let dummy = 0;\r\n const maxLen = Math.max(arr1.length, arr2.length);\r\n for (let i = 0; i < maxLen; i++) {\r\n dummy |= (arr1[i % arr1.length] || 0) ^ (arr2[i % arr2.length] || 0);\r\n }\r\n return false;\r\n }\r\n \r\n let result = 0;\r\n for (let i = 0; i < arr1.length; i++) {\r\n result |= arr1[i] ^ arr2[i];\r\n }\r\n \r\n return result === 0;\r\n }\r\n \r\n /**\r\n * CRITICAL SECURITY: Encrypt data with AAD (Additional Authenticated Data)\r\n * This method provides authenticated encryption with additional data binding\r\n */\r\n static async encryptDataWithAAD(data, key, aad) {\r\n try {\r\n const dataString = typeof data === 'string' ? data : JSON.stringify(data);\r\n const encoder = new TextEncoder();\r\n const dataBuffer = encoder.encode(dataString);\r\n const aadBuffer = encoder.encode(aad);\r\n\r\n // Generate random IV\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n\r\n // Encrypt with AAD\r\n const encrypted = await crypto.subtle.encrypt(\r\n { \r\n name: 'AES-GCM', \r\n iv: iv,\r\n additionalData: aadBuffer\r\n },\r\n key,\r\n dataBuffer\r\n );\r\n\r\n // Package encrypted data\r\n const encryptedPackage = {\r\n version: '1.0',\r\n iv: Array.from(iv),\r\n data: Array.from(new Uint8Array(encrypted)),\r\n aad: aad,\r\n timestamp: Date.now()\r\n };\r\n\r\n const packageString = JSON.stringify(encryptedPackage);\r\n const packageBuffer = encoder.encode(packageString);\r\n \r\n return EnhancedSecureCryptoUtils.arrayBufferToBase64(packageBuffer);\r\n } catch (error) {\r\n throw new Error(`AAD encryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * CRITICAL SECURITY: Decrypt data with AAD validation\r\n * This method provides authenticated decryption with additional data validation\r\n */\r\n static async decryptDataWithAAD(encryptedData, key, expectedAad) {\r\n try {\r\n const packageBuffer = EnhancedSecureCryptoUtils.base64ToArrayBuffer(encryptedData);\r\n const packageString = new TextDecoder().decode(packageBuffer);\r\n const encryptedPackage = JSON.parse(packageString);\r\n\r\n if (!encryptedPackage.version || !encryptedPackage.iv || !encryptedPackage.data || !encryptedPackage.aad) {\r\n throw new Error('Invalid encrypted data format');\r\n }\r\n\r\n // Validate AAD matches expected\r\n if (encryptedPackage.aad !== expectedAad) {\r\n throw new Error('AAD mismatch - possible tampering or replay attack');\r\n }\r\n\r\n const iv = new Uint8Array(encryptedPackage.iv);\r\n const encrypted = new Uint8Array(encryptedPackage.data);\r\n const aadBuffer = new TextEncoder().encode(encryptedPackage.aad);\r\n\r\n // Decrypt with AAD validation\r\n const decrypted = await crypto.subtle.decrypt(\r\n { \r\n name: 'AES-GCM', \r\n iv: iv,\r\n additionalData: aadBuffer\r\n },\r\n key,\r\n encrypted\r\n );\r\n\r\n const decryptedString = new TextDecoder().decode(decrypted);\r\n\r\n try {\r\n return JSON.parse(decryptedString);\r\n } catch {\r\n return decryptedString;\r\n }\r\n } catch (error) {\r\n throw new Error(`AAD decryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n // Initialize secure logging system after class definition\r\n static {\r\n if (EnhancedSecureCryptoUtils.secureLog && typeof EnhancedSecureCryptoUtils.secureLog.init === 'function') {\r\n EnhancedSecureCryptoUtils.secureLog.init();\r\n }\r\n }\r\n}\r\n\r\nexport { EnhancedSecureCryptoUtils };", "// ============================================\n// SECURE FILE TRANSFER CONTEXT\n// ============================================\nclass SecureFileTransferContext {\n static #instance = null;\n static #contextKey = Symbol('SecureFileTransferContext');\n \n static getInstance() {\n if (!this.#instance) {\n this.#instance = new SecureFileTransferContext();\n }\n return this.#instance;\n }\n \n #fileTransferSystem = null;\n #active = false;\n #securityLevel = 'high';\n \n setFileTransferSystem(system) {\n if (!(system instanceof EnhancedSecureFileTransfer)) {\n throw new Error('Invalid file transfer system instance');\n }\n this.#fileTransferSystem = system;\n this.#active = true;\n }\n \n getFileTransferSystem() {\n return this.#fileTransferSystem;\n }\n \n isActive() {\n return this.#active && this.#fileTransferSystem !== null;\n }\n \n deactivate() {\n this.#active = false;\n this.#fileTransferSystem = null;\n }\n \n getSecurityLevel() {\n return this.#securityLevel;\n }\n \n setSecurityLevel(level) {\n if (['low', 'medium', 'high'].includes(level)) {\n this.#securityLevel = level;\n }\n }\n}\n\n// ============================================\n// SECURITY ERROR HANDLER\n// ============================================\n\nclass SecurityErrorHandler {\n static #allowedErrors = new Set([\n 'File size exceeds maximum limit',\n 'Unsupported file type',\n 'Transfer timeout',\n 'Connection lost',\n 'Invalid file data',\n 'File transfer failed',\n 'Transfer cancelled',\n 'Network error',\n 'File not found',\n 'Permission denied'\n ]);\n \n static sanitizeError(error) {\n const message = error.message || error;\n\n for (const allowed of this.#allowedErrors) {\n if (message.includes(allowed)) {\n return allowed;\n }\n }\n\n console.error('\uD83D\uDD12 Internal file transfer error:', {\n message: error.message,\n stack: error.stack,\n timestamp: new Date().toISOString()\n });\n\n return 'File transfer failed';\n }\n \n static logSecurityEvent(event, details = {}) {\n console.warn('\uD83D\uDD12 Security event:', {\n event,\n timestamp: new Date().toISOString(),\n ...details\n });\n }\n}\n\n// ============================================\n// FILE METADATA SIGNATURE SYSTEM\n// ============================================\n\nclass FileMetadataSigner {\n static async signFileMetadata(metadata, privateKey) {\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify({\n fileId: metadata.fileId,\n fileName: metadata.fileName,\n fileSize: metadata.fileSize,\n fileHash: metadata.fileHash,\n timestamp: metadata.timestamp,\n version: metadata.version || '2.0'\n }));\n \n const signature = await crypto.subtle.sign(\n 'RSASSA-PKCS1-v1_5',\n privateKey,\n data\n );\n \n return Array.from(new Uint8Array(signature));\n } catch (error) {\n SecurityErrorHandler.logSecurityEvent('signature_failed', { error: error.message });\n throw new Error('Failed to sign file metadata');\n }\n }\n \n static async verifyFileMetadata(metadata, signature, publicKey) {\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify({\n fileId: metadata.fileId,\n fileName: metadata.fileName,\n fileSize: metadata.fileSize,\n fileHash: metadata.fileHash,\n timestamp: metadata.timestamp,\n version: metadata.version || '2.0'\n }));\n \n const signatureBuffer = new Uint8Array(signature);\n \n const isValid = await crypto.subtle.verify(\n 'RSASSA-PKCS1-v1_5',\n publicKey,\n signatureBuffer,\n data\n );\n \n if (!isValid) {\n SecurityErrorHandler.logSecurityEvent('invalid_signature', { fileId: metadata.fileId });\n }\n \n return isValid;\n } catch (error) {\n SecurityErrorHandler.logSecurityEvent('verification_failed', { error: error.message });\n return false;\n }\n }\n}\n\n// ============================================\n// \u0422\u041E\u0427\u041D\u042B\u0415 \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u042F \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u041E\u0421\u0422\u0418\n// ============================================\n\nclass MessageSizeValidator {\n static MAX_MESSAGE_SIZE = 1024 * 1024; // 1MB\n \n static isMessageSizeValid(message) {\n const messageString = JSON.stringify(message);\n const sizeInBytes = new Blob([messageString]).size;\n \n if (sizeInBytes > this.MAX_MESSAGE_SIZE) {\n SecurityErrorHandler.logSecurityEvent('message_too_large', {\n size: sizeInBytes,\n limit: this.MAX_MESSAGE_SIZE\n });\n throw new Error('Message too large');\n }\n \n return true;\n }\n}\n\nclass AtomicOperations {\n constructor() {\n this.locks = new Map();\n }\n \n async withLock(key, operation) {\n if (this.locks.has(key)) {\n await this.locks.get(key);\n }\n \n const lockPromise = (async () => {\n try {\n return await operation();\n } finally {\n this.locks.delete(key);\n }\n })();\n \n this.locks.set(key, lockPromise);\n return lockPromise;\n }\n}\n\n// Rate limiting \u0434\u043B\u044F \u0437\u0430\u0449\u0438\u0442\u044B \u043E\u0442 \u0441\u043F\u0430\u043C\u0430\nclass RateLimiter {\n constructor(maxRequests, windowMs) {\n this.maxRequests = maxRequests;\n this.windowMs = windowMs;\n this.requests = new Map();\n }\n \n isAllowed(identifier) {\n const now = Date.now();\n const windowStart = now - this.windowMs;\n \n if (!this.requests.has(identifier)) {\n this.requests.set(identifier, []);\n }\n \n const userRequests = this.requests.get(identifier);\n \n const validRequests = userRequests.filter(time => time > windowStart);\n this.requests.set(identifier, validRequests);\n \n if (validRequests.length >= this.maxRequests) {\n SecurityErrorHandler.logSecurityEvent('rate_limit_exceeded', {\n identifier,\n requestCount: validRequests.length,\n limit: this.maxRequests\n });\n return false;\n }\n \n validRequests.push(now);\n return true;\n }\n}\n\nclass SecureMemoryManager {\n static secureWipe(buffer) {\n if (buffer instanceof ArrayBuffer) {\n const view = new Uint8Array(buffer);\n crypto.getRandomValues(view);\n } else if (buffer instanceof Uint8Array) {\n crypto.getRandomValues(buffer);\n }\n }\n \n static secureDelete(obj, prop) {\n if (obj[prop]) {\n this.secureWipe(obj[prop]);\n delete obj[prop];\n }\n }\n}\n\nclass EnhancedSecureFileTransfer {\n constructor(webrtcManager, onProgress, onComplete, onError, onFileReceived) {\n this.webrtcManager = webrtcManager;\n this.onProgress = onProgress;\n this.onComplete = onComplete;\n this.onError = onError;\n this.onFileReceived = onFileReceived;\n \n // Validate webrtcManager\n if (!webrtcManager) {\n throw new Error('webrtcManager is required for EnhancedSecureFileTransfer');\n }\n \n SecureFileTransferContext.getInstance().setFileTransferSystem(this);\n \n this.atomicOps = new AtomicOperations();\n this.rateLimiter = new RateLimiter(10, 60000);\n\n this.signingKey = null;\n this.verificationKey = null;\n \n // Transfer settings\n this.CHUNK_SIZE = 64 * 1024; // 64 KB\n this.MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 MB limit\n this.MAX_CONCURRENT_TRANSFERS = 3;\n this.CHUNK_TIMEOUT = 30000; // 30 seconds per chunk\n this.RETRY_ATTEMPTS = 3;\n\n this.FILE_TYPE_RESTRICTIONS = {\n documents: {\n extensions: ['.pdf', '.doc', '.docx', '.txt', '.md', '.rtf', '.odt'],\n mimeTypes: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'text/plain',\n 'text/markdown',\n 'application/rtf',\n 'application/vnd.oasis.opendocument.text'\n ],\n maxSize: 50 * 1024 * 1024, // 50 MB\n category: 'Documents',\n description: 'PDF, DOC, TXT, MD, RTF, ODT'\n },\n \n images: {\n extensions: ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg', '.ico'],\n mimeTypes: [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/bmp',\n 'image/svg+xml',\n 'image/x-icon'\n ],\n maxSize: 25 * 1024 * 1024, // 25 MB\n category: 'Images',\n description: 'JPG, PNG, GIF, WEBP, BMP, SVG, ICO'\n },\n \n archives: {\n extensions: ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2', '.xz'],\n mimeTypes: [\n 'application/zip',\n 'application/x-rar-compressed',\n 'application/x-7z-compressed',\n 'application/x-tar',\n 'application/gzip',\n 'application/x-bzip2',\n 'application/x-xz'\n ],\n maxSize: 100 * 1024 * 1024, // 100 MB\n category: 'Archives',\n description: 'ZIP, RAR, 7Z, TAR, GZ, BZ2, XZ'\n },\n \n media: {\n extensions: ['.mp3', '.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.ogg', '.wav'],\n mimeTypes: [\n 'audio/mpeg',\n 'video/mp4',\n 'video/x-msvideo',\n 'video/x-matroska',\n 'video/quicktime',\n 'video/x-ms-wmv',\n 'video/x-flv',\n 'video/webm',\n 'audio/ogg',\n 'audio/wav'\n ],\n maxSize: 100 * 1024 * 1024, // 100 MB\n category: 'Media',\n description: 'MP3, MP4, AVI, MKV, MOV, WMV, FLV, WEBM, OGG, WAV'\n },\n \n general: {\n extensions: [], \n mimeTypes: [], \n maxSize: 50 * 1024 * 1024, // 50 MB\n category: 'General',\n description: 'Any file type up to size limits'\n }\n };\n \n // Active transfers tracking\n this.activeTransfers = new Map(); // fileId -> transfer state\n this.receivingTransfers = new Map(); // fileId -> receiving state\n this.transferQueue = []; // Queue for pending transfers\n this.pendingChunks = new Map();\n \n // Session key derivation\n this.sessionKeys = new Map(); // fileId -> derived session key\n \n // Security\n this.processedChunks = new Set(); // Prevent replay attacks\n this.transferNonces = new Map(); // fileId -> current nonce counter\n this.receivedFileBuffers = new Map(); // fileId -> { buffer:ArrayBuffer, type:string, name:string, size:number }\n\n this.setupFileMessageHandlers();\n\n if (this.webrtcManager) {\n this.webrtcManager.fileTransferSystem = this;\n }\n }\n\n // ============================================\n // FILE TYPE VALIDATION SYSTEM\n // ============================================\n\n getFileType(file) {\n const fileName = file.name.toLowerCase();\n const fileExtension = fileName.substring(fileName.lastIndexOf('.'));\n const mimeType = file.type.toLowerCase();\n\n for (const [typeKey, typeConfig] of Object.entries(this.FILE_TYPE_RESTRICTIONS)) {\n if (typeKey === 'general') continue; // \u041F\u0440\u043E\u043F\u0443\u0441\u043A\u0430\u0435\u043C \u043E\u0431\u0449\u0438\u0439 \u0442\u0438\u043F\n\n if (typeConfig.extensions.includes(fileExtension)) {\n return {\n type: typeKey,\n category: typeConfig.category,\n description: typeConfig.description,\n maxSize: typeConfig.maxSize,\n allowed: true\n };\n }\n\n if (typeConfig.mimeTypes.includes(mimeType)) {\n return {\n type: typeKey,\n category: typeConfig.category,\n description: typeConfig.description,\n maxSize: typeConfig.maxSize,\n allowed: true\n };\n }\n }\n\n const generalConfig = this.FILE_TYPE_RESTRICTIONS.general;\n return {\n type: 'general',\n category: generalConfig.category,\n description: generalConfig.description,\n maxSize: generalConfig.maxSize,\n allowed: true\n };\n }\n\n validateFile(file) {\n const fileType = this.getFileType(file);\n const errors = [];\n\n if (file.size > fileType.maxSize) {\n errors.push(`File size (${this.formatFileSize(file.size)}) exceeds maximum allowed for ${fileType.category} (${this.formatFileSize(fileType.maxSize)})`);\n }\n\n if (!fileType.allowed) {\n errors.push(`File type not allowed. Supported types: ${fileType.description}`);\n }\n\n if (file.size > this.MAX_FILE_SIZE) {\n errors.push(`File size (${this.formatFileSize(file.size)}) exceeds general limit (${this.formatFileSize(this.MAX_FILE_SIZE)})`);\n }\n \n return {\n isValid: errors.length === 0,\n errors: errors,\n fileType: fileType,\n fileSize: file.size,\n formattedSize: this.formatFileSize(file.size)\n };\n }\n\n formatFileSize(bytes) {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n\n getSupportedFileTypes() {\n const supportedTypes = {};\n \n for (const [typeKey, typeConfig] of Object.entries(this.FILE_TYPE_RESTRICTIONS)) {\n if (typeKey === 'general') continue;\n \n supportedTypes[typeKey] = {\n category: typeConfig.category,\n description: typeConfig.description,\n extensions: typeConfig.extensions,\n maxSize: this.formatFileSize(typeConfig.maxSize),\n maxSizeBytes: typeConfig.maxSize\n };\n }\n \n return supportedTypes;\n }\n\n getFileTypeInfo() {\n return {\n supportedTypes: this.getSupportedFileTypes(),\n generalMaxSize: this.formatFileSize(this.MAX_FILE_SIZE),\n generalMaxSizeBytes: this.MAX_FILE_SIZE,\n restrictions: this.FILE_TYPE_RESTRICTIONS\n };\n }\n\n // ============================================\n // ENCODING HELPERS (Base64 for efficient transport)\n // ============================================\n arrayBufferToBase64(buffer) {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n let binary = '';\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n base64ToUint8Array(base64) {\n const binaryString = atob(base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n }\n\n // ============================================\n // PUBLIC ACCESSORS FOR RECEIVED FILES\n // ============================================\n getReceivedFileMeta(fileId) {\n const entry = this.receivedFileBuffers.get(fileId);\n if (!entry) return null;\n return { fileId, fileName: entry.name, fileSize: entry.size, mimeType: entry.type };\n }\n\n async getBlob(fileId) {\n const entry = this.receivedFileBuffers.get(fileId);\n if (!entry) return null;\n return new Blob([entry.buffer], { type: entry.type });\n }\n\n async getObjectURL(fileId) {\n const blob = await this.getBlob(fileId);\n if (!blob) return null;\n return URL.createObjectURL(blob);\n }\n\n revokeObjectURL(url) {\n try { URL.revokeObjectURL(url); } catch (_) {}\n }\n\n setupFileMessageHandlers() {\n if (!this.webrtcManager.dataChannel) {\n const setupRetry = setInterval(() => {\n if (this.webrtcManager.dataChannel) {\n clearInterval(setupRetry);\n this.setupMessageInterception();\n }\n }, 100);\n\n setTimeout(() => {\n clearInterval(setupRetry);\n }, 5000);\n \n return;\n }\n \n // \u0415\u0441\u043B\u0438 dataChannel \u0443\u0436\u0435 \u0433\u043E\u0442\u043E\u0432, \u0441\u0440\u0430\u0437\u0443 \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043C\n this.setupMessageInterception();\n }\n\n setupMessageInterception() {\n try {\n if (!this.webrtcManager.dataChannel) {\n return;\n }\n\n if (this.webrtcManager) {\n this.webrtcManager.fileTransferSystem = this;\n }\n\n if (this.webrtcManager.dataChannel.onmessage) {\n this.originalOnMessage = this.webrtcManager.dataChannel.onmessage;\n }\n\n this.webrtcManager.dataChannel.onmessage = async (event) => {\n try {\n if (event.data.length > MessageSizeValidator.MAX_MESSAGE_SIZE) {\n console.warn('\uD83D\uDD12 Message too large, ignoring');\n SecurityErrorHandler.logSecurityEvent('oversized_message_blocked');\n return;\n }\n \n if (typeof event.data === 'string') {\n try {\n const parsed = JSON.parse(event.data);\n \n MessageSizeValidator.isMessageSizeValid(parsed);\n \n if (this.isFileTransferMessage(parsed)) {\n await this.handleFileMessage(parsed);\n return; \n }\n } catch (parseError) {\n if (parseError.message === 'Message too large') {\n return; \n }\n }\n }\n\n if (this.originalOnMessage) {\n return this.originalOnMessage.call(this.webrtcManager.dataChannel, event);\n }\n } catch (error) {\n console.error('\u274C Error in file system message interception:', error);\n if (this.originalOnMessage) {\n return this.originalOnMessage.call(this.webrtcManager.dataChannel, event);\n }\n }\n };\n } catch (error) {\n console.error('\u274C Failed to set up message interception:', error);\n }\n }\n\n isFileTransferMessage(message) {\n if (!message || typeof message !== 'object' || !message.type) {\n return false;\n }\n \n const fileMessageTypes = [\n 'file_transfer_start',\n 'file_transfer_response', \n 'file_chunk',\n 'chunk_confirmation',\n 'file_transfer_complete',\n 'file_transfer_error'\n ];\n \n return fileMessageTypes.includes(message.type);\n }\n\n async handleFileMessage(message) {\n try {\n if (!this.webrtcManager.fileTransferSystem) {\n try {\n if (typeof this.webrtcManager.initializeFileTransfer === 'function') {\n this.webrtcManager.initializeFileTransfer();\n \n let attempts = 0;\n const maxAttempts = 50; \n while (!this.webrtcManager.fileTransferSystem && attempts < maxAttempts) {\n await new Promise(resolve => setTimeout(resolve, 100));\n attempts++;\n }\n \n if (!this.webrtcManager.fileTransferSystem) {\n throw new Error('File transfer system initialization timeout');\n }\n } else {\n throw new Error('initializeFileTransfer method not available');\n }\n } catch (initError) {\n console.error('\u274C Failed to initialize file transfer system:', initError);\n if (message.fileId) {\n const errorMessage = {\n type: 'file_transfer_error',\n fileId: message.fileId,\n error: 'File transfer system not available',\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n }\n return;\n }\n }\n \n switch (message.type) {\n case 'file_transfer_start':\n await this.handleFileTransferStart(message);\n break;\n \n case 'file_transfer_response':\n this.handleTransferResponse(message);\n break;\n \n case 'file_chunk':\n await this.handleFileChunk(message);\n break;\n \n case 'chunk_confirmation':\n this.handleChunkConfirmation(message);\n break;\n \n case 'file_transfer_complete':\n this.handleTransferComplete(message);\n break;\n \n case 'file_transfer_error':\n this.handleTransferError(message);\n break;\n \n default:\n console.warn('\u26A0\uFE0F Unknown file message type:', message.type);\n }\n \n } catch (error) {\n console.error('\u274C Error handling file message:', error);\n\n if (message.fileId) {\n const errorMessage = {\n type: 'file_transfer_error',\n fileId: message.fileId,\n error: error.message,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n }\n }\n }\n\n // ============================================\n // SIMPLIFIED KEY DERIVATION - USE SHARED DATA\n // ============================================\n\n async deriveFileSessionKey(fileId) {\n try {\n \n if (!this.webrtcManager.keyFingerprint || !this.webrtcManager.sessionSalt) {\n throw new Error('WebRTC session data not available');\n }\n\n const fileSalt = crypto.getRandomValues(new Uint8Array(32));\n\n const encoder = new TextEncoder();\n const fingerprintData = encoder.encode(this.webrtcManager.keyFingerprint);\n const fileIdData = encoder.encode(fileId);\n\n const sessionSaltArray = new Uint8Array(this.webrtcManager.sessionSalt);\n const combinedSeed = new Uint8Array(\n fingerprintData.length + \n sessionSaltArray.length + \n fileSalt.length + \n fileIdData.length\n );\n \n let offset = 0;\n combinedSeed.set(fingerprintData, offset);\n offset += fingerprintData.length;\n combinedSeed.set(sessionSaltArray, offset);\n offset += sessionSaltArray.length;\n combinedSeed.set(fileSalt, offset);\n offset += fileSalt.length;\n combinedSeed.set(fileIdData, offset);\n\n const keyMaterial = await crypto.subtle.digest('SHA-256', combinedSeed);\n\n const fileSessionKey = await crypto.subtle.importKey(\n 'raw',\n keyMaterial,\n { name: 'AES-GCM' },\n false,\n ['encrypt', 'decrypt']\n );\n\n this.sessionKeys.set(fileId, {\n key: fileSessionKey,\n salt: Array.from(fileSalt),\n created: Date.now()\n });\n\n return { key: fileSessionKey, salt: Array.from(fileSalt) };\n\n } catch (error) {\n console.error('\u274C Failed to derive file session key:', error);\n throw error;\n }\n }\n\n async deriveFileSessionKeyFromSalt(fileId, saltArray) {\n try {\n if (!saltArray || !Array.isArray(saltArray) || saltArray.length !== 32) {\n throw new Error(`Invalid salt: ${saltArray?.length || 0} bytes`);\n }\n \n if (!this.webrtcManager.keyFingerprint || !this.webrtcManager.sessionSalt) {\n throw new Error('WebRTC session data not available');\n }\n\n const encoder = new TextEncoder();\n const fingerprintData = encoder.encode(this.webrtcManager.keyFingerprint);\n const fileIdData = encoder.encode(fileId);\n\n const fileSalt = new Uint8Array(saltArray);\n const sessionSaltArray = new Uint8Array(this.webrtcManager.sessionSalt);\n\n const combinedSeed = new Uint8Array(\n fingerprintData.length + \n sessionSaltArray.length + \n fileSalt.length + \n fileIdData.length\n );\n \n let offset = 0;\n combinedSeed.set(fingerprintData, offset);\n offset += fingerprintData.length;\n combinedSeed.set(sessionSaltArray, offset);\n offset += sessionSaltArray.length;\n combinedSeed.set(fileSalt, offset);\n offset += fileSalt.length;\n combinedSeed.set(fileIdData, offset);\n\n const keyMaterial = await crypto.subtle.digest('SHA-256', combinedSeed);\n\n const fileSessionKey = await crypto.subtle.importKey(\n 'raw',\n keyMaterial,\n { name: 'AES-GCM' },\n false,\n ['encrypt', 'decrypt']\n );\n\n this.sessionKeys.set(fileId, {\n key: fileSessionKey,\n salt: saltArray,\n created: Date.now()\n });\n\n return fileSessionKey;\n\n } catch (error) {\n console.error('\u274C Failed to derive session key from salt:', error);\n throw error;\n }\n }\n\n // ============================================\n // FILE TRANSFER IMPLEMENTATION\n // ============================================\n\n async sendFile(file) {\n try {\n // Validate webrtcManager\n if (!this.webrtcManager) {\n throw new Error('WebRTC Manager not initialized');\n }\n\n const clientId = this.getClientIdentifier();\n if (!this.rateLimiter.isAllowed(clientId)) {\n SecurityErrorHandler.logSecurityEvent('rate_limit_exceeded', { clientId });\n throw new Error('Rate limit exceeded. Please wait before sending another file.');\n }\n\n if (!file || !file.size) {\n throw new Error('Invalid file object');\n }\n\n const validation = this.validateFile(file);\n if (!validation.isValid) {\n const errorMessage = validation.errors.join('. ');\n throw new Error(errorMessage);\n }\n\n if (this.activeTransfers.size >= this.MAX_CONCURRENT_TRANSFERS) {\n throw new Error('Maximum concurrent transfers reached');\n }\n\n // Generate unique file ID\n const fileId = `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n \n // Calculate file hash for integrity verification\n const fileHash = await this.calculateFileHash(file);\n \n // Derive session key for this file\n const keyResult = await this.deriveFileSessionKey(fileId);\n const sessionKey = keyResult.key;\n const salt = keyResult.salt;\n \n // Create transfer state\n const transferState = {\n fileId: fileId,\n file: file,\n fileHash: fileHash,\n sessionKey: sessionKey,\n salt: salt, \n totalChunks: Math.ceil(file.size / this.CHUNK_SIZE),\n sentChunks: 0,\n confirmedChunks: 0,\n startTime: Date.now(),\n status: 'preparing',\n retryCount: 0,\n lastChunkTime: Date.now()\n };\n\n this.activeTransfers.set(fileId, transferState);\n this.transferNonces.set(fileId, 0);\n\n // Send file metadata first\n await this.sendFileMetadata(transferState);\n \n // Start chunk transmission\n await this.startChunkTransmission(transferState);\n \n return fileId;\n\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C File sending failed:', safeError);\n if (this.onError) this.onError(safeError);\n throw new Error(safeError);\n }\n }\n\n async sendFileMetadata(transferState) {\n try {\n const metadata = {\n type: 'file_transfer_start',\n fileId: transferState.fileId,\n fileName: transferState.file.name,\n fileSize: transferState.file.size,\n fileType: transferState.file.type || 'application/octet-stream',\n fileHash: transferState.fileHash,\n totalChunks: transferState.totalChunks,\n chunkSize: this.CHUNK_SIZE,\n salt: transferState.salt, \n timestamp: Date.now(),\n version: '2.0'\n };\n\n if (this.signingKey) {\n try {\n metadata.signature = await FileMetadataSigner.signFileMetadata(metadata, this.signingKey);\n console.log('\uD83D\uDD12 File metadata signed successfully');\n } catch (signError) {\n SecurityErrorHandler.logSecurityEvent('signature_failed', { \n fileId: transferState.fileId, \n error: signError.message \n });\n }\n }\n\n // Send metadata through secure channel\n await this.sendSecureMessage(metadata);\n \n transferState.status = 'metadata_sent';\n\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to send file metadata:', safeError);\n transferState.status = 'failed';\n throw new Error(safeError);\n }\n }\n\n async startChunkTransmission(transferState) {\n try {\n transferState.status = 'transmitting';\n \n const file = transferState.file;\n const totalChunks = transferState.totalChunks;\n \n for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {\n const start = chunkIndex * this.CHUNK_SIZE;\n const end = Math.min(start + this.CHUNK_SIZE, file.size);\n \n // Read chunk from file\n const chunkData = await this.readFileChunk(file, start, end);\n \n // Send chunk (\u0441 \u0443\u0447\u0451\u0442\u043E\u043C backpressure)\n await this.sendFileChunk(transferState, chunkIndex, chunkData);\n \n // Update progress\n transferState.sentChunks++;\n const progress = Math.round((transferState.sentChunks / totalChunks) * 95) + 5; // 5-100%\n\n await this.waitForBackpressure();\n }\n \n transferState.status = 'waiting_confirmation';\n \n // Timeout for completion confirmation\n setTimeout(() => {\n if (this.activeTransfers.has(transferState.fileId)) {\n const state = this.activeTransfers.get(transferState.fileId);\n if (state.status === 'waiting_confirmation') {\n this.cleanupTransfer(transferState.fileId);\n }\n }\n }, 30000);\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Chunk transmission failed:', safeError);\n transferState.status = 'failed';\n throw new Error(safeError);\n }\n }\n\n async readFileChunk(file, start, end) {\n try {\n const blob = file.slice(start, end);\n return await blob.arrayBuffer();\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to read file chunk:', safeError);\n throw new Error(safeError);\n }\n }\n\n async sendFileChunk(transferState, chunkIndex, chunkData) {\n try {\n const sessionKey = transferState.sessionKey;\n const nonce = crypto.getRandomValues(new Uint8Array(12));\n \n // Encrypt chunk data\n const encryptedChunk = await crypto.subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: nonce\n },\n sessionKey,\n chunkData\n );\n \n // Use Base64 to drastically reduce JSON overhead\n const encryptedB64 = this.arrayBufferToBase64(new Uint8Array(encryptedChunk));\n const chunkMessage = {\n type: 'file_chunk',\n fileId: transferState.fileId,\n chunkIndex: chunkIndex,\n totalChunks: transferState.totalChunks,\n nonce: Array.from(nonce),\n encryptedDataB64: encryptedB64,\n chunkSize: chunkData.byteLength,\n timestamp: Date.now()\n };\n\n await this.waitForBackpressure();\n // Send chunk through secure channel\n await this.sendSecureMessage(chunkMessage);\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to send file chunk:', safeError);\n throw new Error(safeError);\n }\n }\n\n async sendSecureMessage(message) {\n\n const messageString = JSON.stringify(message);\n const dc = this.webrtcManager?.dataChannel;\n const maxRetries = 10;\n let attempt = 0;\n const wait = (ms) => new Promise(r => setTimeout(r, ms));\n\n while (true) {\n try {\n if (!dc || dc.readyState !== 'open') {\n throw new Error('Data channel not ready');\n }\n await this.waitForBackpressure();\n dc.send(messageString);\n return; // success\n } catch (error) {\n const msg = String(error?.message || '');\n const queueFull = msg.includes('send queue is full') || msg.includes('bufferedAmount');\n const opErr = error?.name === 'OperationError';\n if ((queueFull || opErr) && attempt < maxRetries) {\n attempt++;\n await this.waitForBackpressure();\n await wait(Math.min(50 * attempt, 500));\n continue;\n }\n console.error('\u274C Failed to send secure message:', error);\n throw error;\n }\n }\n }\n\n async waitForBackpressure() {\n try {\n const dc = this.webrtcManager?.dataChannel;\n if (!dc) return;\n\n if (typeof dc.bufferedAmountLowThreshold === 'number') {\n if (dc.bufferedAmount > dc.bufferedAmountLowThreshold) {\n await new Promise(resolve => {\n const handler = () => {\n dc.removeEventListener('bufferedamountlow', handler);\n resolve();\n };\n dc.addEventListener('bufferedamountlow', handler, { once: true });\n });\n }\n return;\n }\n\n const softLimit = 4 * 1024 * 1024;\n while (dc.bufferedAmount > softLimit) {\n await new Promise(r => setTimeout(r, 20));\n }\n } catch (_) {\n // ignore\n }\n }\n\n async calculateFileHash(file) {\n try {\n const arrayBuffer = await file.arrayBuffer();\n const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (error) {\n console.error('\u274C File hash calculation failed:', error);\n throw error;\n }\n }\n\n // ============================================\n // MESSAGE HANDLERS\n // ============================================\n\n async handleFileTransferStart(metadata) {\n try {\n // Validate metadata\n if (!metadata.fileId || !metadata.fileName || !metadata.fileSize) {\n throw new Error('Invalid file transfer metadata');\n }\n\n if (metadata.signature && this.verificationKey) {\n try {\n const isValid = await FileMetadataSigner.verifyFileMetadata(\n metadata, \n metadata.signature, \n this.verificationKey\n );\n \n if (!isValid) {\n SecurityErrorHandler.logSecurityEvent('invalid_metadata_signature', { \n fileId: metadata.fileId \n });\n throw new Error('Invalid file metadata signature');\n }\n \n console.log('\uD83D\uDD12 File metadata signature verified successfully');\n } catch (verifyError) {\n SecurityErrorHandler.logSecurityEvent('verification_failed', { \n fileId: metadata.fileId, \n error: verifyError.message \n });\n throw new Error('File metadata verification failed');\n }\n }\n \n // Check if we already have this transfer\n if (this.receivingTransfers.has(metadata.fileId)) {\n return;\n }\n \n // Derive session key from salt\n const sessionKey = await this.deriveFileSessionKeyFromSalt(\n metadata.fileId,\n metadata.salt\n );\n \n // Create receiving transfer state\n const receivingState = {\n fileId: metadata.fileId,\n fileName: metadata.fileName,\n fileSize: metadata.fileSize,\n fileType: metadata.fileType || 'application/octet-stream',\n fileHash: metadata.fileHash,\n totalChunks: metadata.totalChunks,\n chunkSize: metadata.chunkSize || this.CHUNK_SIZE,\n sessionKey: sessionKey,\n salt: metadata.salt,\n receivedChunks: new Map(),\n receivedCount: 0,\n startTime: Date.now(),\n lastChunkTime: Date.now(),\n status: 'receiving'\n };\n \n this.receivingTransfers.set(metadata.fileId, receivingState);\n \n // Send acceptance response\n const response = {\n type: 'file_transfer_response',\n fileId: metadata.fileId,\n accepted: true,\n timestamp: Date.now()\n };\n \n await this.sendSecureMessage(response);\n\n // Process buffered chunks if any\n if (this.pendingChunks.has(metadata.fileId)) {\n const bufferedChunks = this.pendingChunks.get(metadata.fileId);\n \n for (const [chunkIndex, chunkMessage] of bufferedChunks.entries()) {\n await this.handleFileChunk(chunkMessage);\n }\n \n this.pendingChunks.delete(metadata.fileId);\n }\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to handle file transfer start:', safeError);\n \n // Send error response\n const errorResponse = {\n type: 'file_transfer_response',\n fileId: metadata.fileId,\n accepted: false,\n error: safeError, \n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorResponse);\n }\n }\n\n async handleFileChunk(chunkMessage) {\n return this.atomicOps.withLock(\n `chunk-${chunkMessage.fileId}`, \n async () => {\n try {\n let receivingState = this.receivingTransfers.get(chunkMessage.fileId);\n \n // Buffer early chunks if transfer not yet initialized\n if (!receivingState) {\n if (!this.pendingChunks.has(chunkMessage.fileId)) {\n this.pendingChunks.set(chunkMessage.fileId, new Map());\n }\n \n this.pendingChunks.get(chunkMessage.fileId).set(chunkMessage.chunkIndex, chunkMessage);\n return;\n }\n \n // Update last chunk time\n receivingState.lastChunkTime = Date.now();\n \n // Check if chunk already received\n if (receivingState.receivedChunks.has(chunkMessage.chunkIndex)) {\n return;\n }\n \n // Validate chunk\n if (chunkMessage.chunkIndex < 0 || chunkMessage.chunkIndex >= receivingState.totalChunks) {\n throw new Error(`Invalid chunk index: ${chunkMessage.chunkIndex}`);\n }\n \n // Decrypt chunk\n const nonce = new Uint8Array(chunkMessage.nonce);\n // Backward compatible: prefer Base64, fallback to numeric array\n let encryptedData;\n if (chunkMessage.encryptedDataB64) {\n encryptedData = this.base64ToUint8Array(chunkMessage.encryptedDataB64);\n } else if (chunkMessage.encryptedData) {\n encryptedData = new Uint8Array(chunkMessage.encryptedData);\n } else {\n throw new Error('Missing encrypted data');\n }\n \n const decryptedChunk = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: nonce\n },\n receivingState.sessionKey,\n encryptedData\n );\n \n // Verify chunk size\n if (decryptedChunk.byteLength !== chunkMessage.chunkSize) {\n throw new Error(`Chunk size mismatch: expected ${chunkMessage.chunkSize}, got ${decryptedChunk.byteLength}`);\n }\n \n // Store chunk\n receivingState.receivedChunks.set(chunkMessage.chunkIndex, decryptedChunk);\n receivingState.receivedCount++;\n \n // Send chunk confirmation\n const confirmation = {\n type: 'chunk_confirmation',\n fileId: chunkMessage.fileId,\n chunkIndex: chunkMessage.chunkIndex,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(confirmation);\n \n // Check if all chunks received\n if (receivingState.receivedCount === receivingState.totalChunks) {\n await this.assembleFile(receivingState);\n }\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to handle file chunk:', safeError);\n \n // Send error notification\n const errorMessage = {\n type: 'file_transfer_error',\n fileId: chunkMessage.fileId,\n error: safeError, \n chunkIndex: chunkMessage.chunkIndex,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n \n // Mark transfer as failed\n const receivingState = this.receivingTransfers.get(chunkMessage.fileId);\n if (receivingState) {\n receivingState.status = 'failed';\n }\n \n if (this.onError) {\n this.onError(`Chunk processing failed: ${safeError}`);\n }\n }\n }\n );\n }\n\n async assembleFile(receivingState) {\n try {\n receivingState.status = 'assembling';\n \n // Verify we have all chunks\n for (let i = 0; i < receivingState.totalChunks; i++) {\n if (!receivingState.receivedChunks.has(i)) {\n throw new Error(`Missing chunk ${i}`);\n }\n }\n \n // Combine all chunks in order\n const chunks = [];\n for (let i = 0; i < receivingState.totalChunks; i++) {\n const chunk = receivingState.receivedChunks.get(i);\n chunks.push(new Uint8Array(chunk));\n }\n \n // Calculate total size\n const totalSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n \n // Verify total size matches expected\n if (totalSize !== receivingState.fileSize) {\n throw new Error(`File size mismatch: expected ${receivingState.fileSize}, got ${totalSize}`);\n }\n \n // Combine into single array\n const fileData = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n fileData.set(chunk, offset);\n offset += chunk.length;\n }\n \n // Verify file integrity\n const receivedHash = await this.calculateFileHashFromData(fileData);\n if (receivedHash !== receivingState.fileHash) {\n throw new Error('File integrity check failed - hash mismatch');\n }\n\n const fileBuffer = fileData.buffer;\n const fileBlob = new Blob([fileBuffer], { type: receivingState.fileType });\n \n receivingState.endTime = Date.now();\n receivingState.status = 'completed';\n\n this.receivedFileBuffers.set(receivingState.fileId, {\n buffer: fileBuffer,\n type: receivingState.fileType,\n name: receivingState.fileName,\n size: receivingState.fileSize\n });\n\n if (this.onFileReceived) {\n const getBlob = async () => new Blob([this.receivedFileBuffers.get(receivingState.fileId).buffer], { type: receivingState.fileType });\n const getObjectURL = async () => {\n const blob = await getBlob();\n return URL.createObjectURL(blob);\n };\n const revokeObjectURL = (url) => {\n try { URL.revokeObjectURL(url); } catch (_) {}\n };\n\n this.onFileReceived({\n fileId: receivingState.fileId,\n fileName: receivingState.fileName,\n fileSize: receivingState.fileSize,\n mimeType: receivingState.fileType,\n transferTime: receivingState.endTime - receivingState.startTime,\n // backward-compatibility for existing UIs\n fileBlob,\n getBlob,\n getObjectURL,\n revokeObjectURL\n });\n }\n \n // Send completion confirmation\n const completionMessage = {\n type: 'file_transfer_complete',\n fileId: receivingState.fileId,\n success: true,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(completionMessage);\n \n // Cleanup\n if (this.receivingTransfers.has(receivingState.fileId)) {\n const rs = this.receivingTransfers.get(receivingState.fileId);\n if (rs && rs.receivedChunks) rs.receivedChunks.clear();\n }\n this.receivingTransfers.delete(receivingState.fileId);\n \n } catch (error) {\n console.error('\u274C File assembly failed:', error);\n receivingState.status = 'failed';\n \n if (this.onError) {\n this.onError(`File assembly failed: ${error.message}`);\n }\n \n // Send error notification\n const errorMessage = {\n type: 'file_transfer_complete',\n fileId: receivingState.fileId,\n success: false,\n error: error.message,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n \n // Cleanup failed transfer\n this.cleanupReceivingTransfer(receivingState.fileId);\n }\n }\n\n async calculateFileHashFromData(data) {\n try {\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (error) {\n console.error('\u274C Hash calculation failed:', error);\n throw error;\n }\n }\n\n handleTransferResponse(response) {\n try {\n const transferState = this.activeTransfers.get(response.fileId);\n \n if (!transferState) {\n return;\n }\n \n if (response.accepted) {\n transferState.status = 'accepted';\n } else {\n transferState.status = 'rejected';\n \n if (this.onError) {\n this.onError(`Transfer rejected: ${response.error || 'Unknown reason'}`);\n }\n \n this.cleanupTransfer(response.fileId);\n }\n } catch (error) {\n console.error('\u274C Failed to handle transfer response:', error);\n }\n }\n\n handleChunkConfirmation(confirmation) {\n try {\n const transferState = this.activeTransfers.get(confirmation.fileId);\n if (!transferState) {\n return;\n }\n \n transferState.confirmedChunks++;\n transferState.lastChunkTime = Date.now();\n } catch (error) {\n console.error('\u274C Failed to handle chunk confirmation:', error);\n }\n }\n\n handleTransferComplete(completion) {\n try {\n const transferState = this.activeTransfers.get(completion.fileId);\n if (!transferState) {\n return;\n }\n \n if (completion.success) {\n transferState.status = 'completed';\n transferState.endTime = Date.now();\n \n if (this.onComplete) {\n this.onComplete({\n fileId: transferState.fileId,\n fileName: transferState.file.name,\n fileSize: transferState.file.size,\n transferTime: transferState.endTime - transferState.startTime,\n status: 'completed'\n });\n }\n } else {\n transferState.status = 'failed';\n \n if (this.onError) {\n this.onError(`Transfer failed: ${completion.error || 'Unknown error'}`);\n }\n }\n \n this.cleanupTransfer(completion.fileId);\n \n } catch (error) {\n console.error('\u274C Failed to handle transfer completion:', error);\n }\n }\n\n handleTransferError(errorMessage) {\n try {\n const transferState = this.activeTransfers.get(errorMessage.fileId);\n if (transferState) {\n transferState.status = 'failed';\n this.cleanupTransfer(errorMessage.fileId);\n }\n \n const receivingState = this.receivingTransfers.get(errorMessage.fileId);\n if (receivingState) {\n receivingState.status = 'failed';\n this.cleanupReceivingTransfer(errorMessage.fileId);\n }\n \n if (this.onError) {\n this.onError(`Transfer error: ${errorMessage.error || 'Unknown error'}`);\n }\n \n } catch (error) {\n console.error('\u274C Failed to handle transfer error:', error);\n }\n }\n\n // ============================================\n // UTILITY METHODS\n // ============================================\n\n getActiveTransfers() {\n return Array.from(this.activeTransfers.values()).map(transfer => ({\n fileId: transfer.fileId,\n fileName: transfer.file?.name || 'Unknown',\n fileSize: transfer.file?.size || 0,\n progress: Math.round((transfer.sentChunks / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n }));\n }\n\n getReceivingTransfers() {\n return Array.from(this.receivingTransfers.values()).map(transfer => ({\n fileId: transfer.fileId,\n fileName: transfer.fileName || 'Unknown',\n fileSize: transfer.fileSize || 0,\n progress: Math.round((transfer.receivedCount / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n }));\n }\n\n cancelTransfer(fileId) {\n try {\n if (this.activeTransfers.has(fileId)) {\n this.cleanupTransfer(fileId);\n return true;\n }\n if (this.receivingTransfers.has(fileId)) {\n this.cleanupReceivingTransfer(fileId);\n return true;\n }\n return false;\n } catch (error) {\n console.error('\u274C Failed to cancel transfer:', error);\n return false;\n }\n }\n\n cleanupTransfer(fileId) {\n this.activeTransfers.delete(fileId);\n this.sessionKeys.delete(fileId);\n this.transferNonces.delete(fileId);\n \n // Remove processed chunk IDs for this transfer\n for (const chunkId of this.processedChunks) {\n if (chunkId.startsWith(fileId)) {\n this.processedChunks.delete(chunkId);\n }\n }\n }\n\n // \u2705 \u0423\u041B\u0423\u0427\u0428\u0415\u041D\u041D\u0410\u042F \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u043F\u0430\u043C\u044F\u0442\u0438 \u0434\u043B\u044F \u043F\u0440\u0435\u0434\u043E\u0442\u0432\u0440\u0430\u0449\u0435\u043D\u0438\u044F use-after-free\n cleanupReceivingTransfer(fileId) {\n try {\n // \u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E \u043E\u0447\u0438\u0449\u0430\u0435\u043C pending chunks\n this.pendingChunks.delete(fileId);\n \n const receivingState = this.receivingTransfers.get(fileId);\n if (receivingState) {\n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 receivedChunks \u0441 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439 \u0437\u0430\u0449\u0438\u0442\u043E\u0439\n if (receivingState.receivedChunks && receivingState.receivedChunks.size > 0) {\n for (const [index, chunk] of receivingState.receivedChunks) {\n try {\n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043D\u0430 \u0432\u0430\u043B\u0438\u0434\u043D\u043E\u0441\u0442\u044C chunk\n if (chunk && (chunk instanceof ArrayBuffer || chunk instanceof Uint8Array)) {\n SecureMemoryManager.secureWipe(chunk);\n \n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 - \u0437\u0430\u043F\u043E\u043B\u043D\u044F\u0435\u043C \u043D\u0443\u043B\u044F\u043C\u0438 \u043F\u0435\u0440\u0435\u0434 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435\u043C\n if (chunk instanceof ArrayBuffer) {\n const view = new Uint8Array(chunk);\n view.fill(0);\n } else if (chunk instanceof Uint8Array) {\n chunk.fill(0);\n }\n }\n } catch (chunkError) {\n console.warn('\u26A0\uFE0F Failed to securely wipe chunk:', chunkError);\n }\n }\n receivingState.receivedChunks.clear();\n }\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 session key\n if (receivingState.sessionKey) {\n try {\n // \u0414\u043B\u044F CryptoKey \u043D\u0435\u043B\u044C\u0437\u044F \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E \u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C, \u043D\u043E \u043C\u043E\u0436\u0435\u043C \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0441\u044B\u043B\u043A\u0443\n receivingState.sessionKey = null;\n } catch (keyError) {\n console.warn('\u26A0\uFE0F Failed to clear session key:', keyError);\n }\n }\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445\n if (receivingState.salt) {\n try {\n if (Array.isArray(receivingState.salt)) {\n receivingState.salt.fill(0);\n }\n receivingState.salt = null;\n } catch (saltError) {\n console.warn('\u26A0\uFE0F Failed to clear salt:', saltError);\n }\n }\n \n // \u041E\u0447\u0438\u0449\u0430\u0435\u043C \u0432\u0441\u0435 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 receivingState\n for (const [key, value] of Object.entries(receivingState)) {\n if (value && typeof value === 'object') {\n if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\n SecureMemoryManager.secureWipe(value);\n } else if (Array.isArray(value)) {\n value.fill(0);\n }\n receivingState[key] = null;\n }\n }\n }\n \n // \u0423\u0434\u0430\u043B\u044F\u0435\u043C \u0438\u0437 \u043E\u0441\u043D\u043E\u0432\u043D\u044B\u0445 \u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u0439\n this.receivingTransfers.delete(fileId);\n this.sessionKeys.delete(fileId);\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u0444\u0438\u043D\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0431\u0443\u0444\u0435\u0440\u0430 \u0444\u0430\u0439\u043B\u0430\n const fileBuffer = this.receivedFileBuffers.get(fileId);\n if (fileBuffer) {\n try {\n if (fileBuffer.buffer) {\n SecureMemoryManager.secureWipe(fileBuffer.buffer);\n \n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 - \u0437\u0430\u043F\u043E\u043B\u043D\u044F\u0435\u043C \u043D\u0443\u043B\u044F\u043C\u0438\n const view = new Uint8Array(fileBuffer.buffer);\n view.fill(0);\n }\n \n // \u041E\u0447\u0438\u0449\u0430\u0435\u043C \u0432\u0441\u0435 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 fileBuffer\n for (const [key, value] of Object.entries(fileBuffer)) {\n if (value && typeof value === 'object') {\n if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\n SecureMemoryManager.secureWipe(value);\n }\n fileBuffer[key] = null;\n }\n }\n \n this.receivedFileBuffers.delete(fileId);\n } catch (bufferError) {\n console.warn('\u26A0\uFE0F Failed to securely clear file buffer:', bufferError);\n // \u041F\u0440\u0438\u043D\u0443\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0443\u0434\u0430\u043B\u044F\u0435\u043C \u0434\u0430\u0436\u0435 \u043F\u0440\u0438 \u043E\u0448\u0438\u0431\u043A\u0435\n this.receivedFileBuffers.delete(fileId);\n }\n }\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 processed chunks\n const chunksToRemove = [];\n for (const chunkId of this.processedChunks) {\n if (chunkId.startsWith(fileId)) {\n chunksToRemove.push(chunkId);\n }\n }\n \n // \u0423\u0434\u0430\u043B\u044F\u0435\u043C \u0432 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u043C \u0446\u0438\u043A\u043B\u0435 \u0434\u043B\u044F \u0438\u0437\u0431\u0435\u0436\u0430\u043D\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u0438 \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438\n for (const chunkId of chunksToRemove) {\n this.processedChunks.delete(chunkId);\n }\n \n // \u041F\u0440\u0438\u043D\u0443\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u043F\u0430\u043C\u044F\u0442\u0438\n if (typeof global !== 'undefined' && global.gc) {\n try {\n global.gc();\n } catch (gcError) {\n // \u0418\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u043C \u043E\u0448\u0438\u0431\u043A\u0438 GC\n }\n }\n \n console.log(`\uD83D\uDD12 Memory safely cleaned for file transfer: ${fileId}`);\n \n } catch (error) {\n console.error('\u274C Error during secure memory cleanup:', error);\n \n // \u041F\u0440\u0438\u043D\u0443\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u0434\u0430\u0436\u0435 \u043F\u0440\u0438 \u043E\u0448\u0438\u0431\u043A\u0435\n this.receivingTransfers.delete(fileId);\n this.sessionKeys.delete(fileId);\n this.receivedFileBuffers.delete(fileId);\n this.pendingChunks.delete(fileId);\n \n throw new Error(`Memory cleanup failed: ${error.message}`);\n }\n }\n\n getTransferStatus(fileId) {\n if (this.activeTransfers.has(fileId)) {\n const transfer = this.activeTransfers.get(fileId);\n return {\n type: 'sending',\n fileId: transfer.fileId,\n fileName: transfer.file.name,\n progress: Math.round((transfer.sentChunks / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n };\n }\n \n if (this.receivingTransfers.has(fileId)) {\n const transfer = this.receivingTransfers.get(fileId);\n return {\n type: 'receiving',\n fileId: transfer.fileId,\n fileName: transfer.fileName,\n progress: Math.round((transfer.receivedCount / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n };\n }\n \n return null;\n }\n\n getSystemStatus() {\n return {\n initialized: true,\n activeTransfers: this.activeTransfers.size,\n receivingTransfers: this.receivingTransfers.size,\n totalTransfers: this.activeTransfers.size + this.receivingTransfers.size,\n maxConcurrentTransfers: this.MAX_CONCURRENT_TRANSFERS,\n maxFileSize: this.MAX_FILE_SIZE,\n chunkSize: this.CHUNK_SIZE,\n hasWebrtcManager: !!this.webrtcManager,\n isConnected: this.webrtcManager?.isConnected?.() || false,\n hasDataChannel: !!this.webrtcManager?.dataChannel,\n dataChannelState: this.webrtcManager?.dataChannel?.readyState,\n isVerified: this.webrtcManager?.isVerified,\n hasEncryptionKey: !!this.webrtcManager?.encryptionKey,\n hasMacKey: !!this.webrtcManager?.macKey,\n linkedToWebRTCManager: this.webrtcManager?.fileTransferSystem === this,\n supportedFileTypes: this.getSupportedFileTypes(),\n fileTypeInfo: this.getFileTypeInfo()\n };\n }\n\n cleanup() {\n SecureFileTransferContext.getInstance().deactivate();\n\n if (this.webrtcManager && this.webrtcManager.dataChannel && this.originalOnMessage) {\n this.webrtcManager.dataChannel.onmessage = this.originalOnMessage;\n this.originalOnMessage = null;\n }\n \n if (this.webrtcManager && this.originalProcessMessage) {\n this.webrtcManager.processMessage = this.originalProcessMessage;\n this.originalProcessMessage = null;\n }\n \n if (this.webrtcManager && this.originalRemoveSecurityLayers) {\n this.webrtcManager.removeSecurityLayers = this.originalRemoveSecurityLayers;\n this.originalRemoveSecurityLayers = null;\n }\n \n // Cleanup all active transfers with secure memory wiping\n for (const fileId of this.activeTransfers.keys()) {\n this.cleanupTransfer(fileId);\n }\n \n for (const fileId of this.receivingTransfers.keys()) {\n this.cleanupReceivingTransfer(fileId);\n }\n\n if (this.atomicOps) {\n this.atomicOps.locks.clear();\n }\n \n if (this.rateLimiter) {\n this.rateLimiter.requests.clear();\n }\n \n // Clear all state\n this.pendingChunks.clear();\n this.activeTransfers.clear();\n this.receivingTransfers.clear();\n this.transferQueue.length = 0;\n this.sessionKeys.clear();\n this.transferNonces.clear();\n this.processedChunks.clear();\n\n this.clearKeys();\n }\n\n // ============================================\n // SESSION UPDATE HANDLER - FIXED\n // ============================================\n \n onSessionUpdate(sessionData) {\n // Clear session keys cache for resync\n this.sessionKeys.clear();\n }\n\n // ============================================\n // DEBUGGING AND DIAGNOSTICS\n // ============================================\n\n diagnoseFileTransferIssue() {\n const diagnosis = {\n timestamp: new Date().toISOString(),\n fileTransferSystem: {\n initialized: !!this,\n hasWebrtcManager: !!this.webrtcManager,\n webrtcManagerType: this.webrtcManager?.constructor?.name,\n linkedToWebRTCManager: this.webrtcManager?.fileTransferSystem === this\n },\n webrtcManager: {\n hasDataChannel: !!this.webrtcManager?.dataChannel,\n dataChannelState: this.webrtcManager?.dataChannel?.readyState,\n isConnected: this.webrtcManager?.isConnected?.() || false,\n isVerified: this.webrtcManager?.isVerified,\n hasEncryptionKey: !!this.webrtcManager?.encryptionKey,\n hasMacKey: !!this.webrtcManager?.macKey,\n hasKeyFingerprint: !!this.webrtcManager?.keyFingerprint,\n hasSessionSalt: !!this.webrtcManager?.sessionSalt\n },\n securityContext: {\n contextActive: SecureFileTransferContext.getInstance().isActive(),\n securityLevel: SecureFileTransferContext.getInstance().getSecurityLevel(),\n hasAtomicOps: !!this.atomicOps,\n hasRateLimiter: !!this.rateLimiter\n },\n transfers: {\n activeTransfers: this.activeTransfers.size,\n receivingTransfers: this.receivingTransfers.size,\n pendingChunks: this.pendingChunks.size,\n sessionKeys: this.sessionKeys.size\n },\n fileTypeSupport: {\n supportedTypes: this.getSupportedFileTypes(),\n generalMaxSize: this.formatFileSize(this.MAX_FILE_SIZE),\n restrictions: Object.keys(this.FILE_TYPE_RESTRICTIONS)\n }\n };\n \n return diagnosis;\n }\n\n async debugKeyDerivation(fileId) {\n try {\n if (!this.webrtcManager.keyFingerprint || !this.webrtcManager.sessionSalt) {\n throw new Error('Session data not available');\n }\n \n // Test sender derivation\n const senderResult = await this.deriveFileSessionKey(fileId);\n \n // Test receiver derivation with same salt\n const receiverKey = await this.deriveFileSessionKeyFromSalt(fileId, senderResult.salt);\n \n // Test encryption/decryption\n const testData = new TextEncoder().encode('test data');\n const nonce = crypto.getRandomValues(new Uint8Array(12));\n \n const encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv: nonce },\n senderResult.key,\n testData\n );\n \n const decrypted = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: nonce },\n receiverKey,\n encrypted\n );\n \n const decryptedText = new TextDecoder().decode(decrypted);\n \n if (decryptedText === 'test data') {\n return { success: true, message: 'All tests passed' };\n } else {\n throw new Error('Decryption verification failed');\n }\n \n } catch (error) {\n console.error('\u274C Key derivation test failed:', error);\n return { success: false, error: error.message };\n }\n }\n\n // ============================================\n // ALTERNATIVE METHOD OF INITIALIZING HANDLERS\n // ============================================\n\n registerWithWebRTCManager() {\n if (!this.webrtcManager) {\n throw new Error('WebRTC manager not available');\n }\n\n this.webrtcManager.fileTransferSystem = this;\n\n this.webrtcManager.setFileMessageHandler = (handler) => {\n this.webrtcManager._fileMessageHandler = handler;\n };\n\n this.webrtcManager.setFileMessageHandler((message) => {\n return this.handleFileMessage(message);\n });\n }\n\n static createFileMessageFilter(fileTransferSystem) {\n return async (event) => {\n try {\n if (typeof event.data === 'string') {\n const parsed = JSON.parse(event.data);\n \n if (fileTransferSystem.isFileTransferMessage(parsed)) {\n await fileTransferSystem.handleFileMessage(parsed);\n return true; \n }\n }\n } catch (error) {\n }\n \n return false; \n };\n }\n\n // ============================================\n // SECURITY KEY MANAGEMENT\n // ============================================\n\n setSigningKey(privateKey) {\n if (!privateKey || !(privateKey instanceof CryptoKey)) {\n throw new Error('Invalid private key for signing');\n }\n this.signingKey = privateKey;\n console.log('\uD83D\uDD12 Signing key set successfully');\n }\n\n setVerificationKey(publicKey) {\n if (!publicKey || !(publicKey instanceof CryptoKey)) {\n throw new Error('Invalid public key for verification');\n }\n this.verificationKey = publicKey;\n console.log('\uD83D\uDD12 Verification key set successfully');\n }\n\n async generateSigningKeyPair() {\n try {\n const keyPair = await crypto.subtle.generateKey(\n {\n name: 'RSASSA-PKCS1-v1_5',\n modulusLength: 2048,\n publicExponent: new Uint8Array([1, 0, 1]),\n hash: 'SHA-256'\n },\n true, // extractable\n ['sign', 'verify']\n );\n \n this.signingKey = keyPair.privateKey;\n this.verificationKey = keyPair.publicKey;\n \n console.log('\uD83D\uDD12 RSA key pair generated successfully');\n return keyPair;\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to generate signing key pair:', safeError);\n throw new Error(safeError);\n }\n }\n\n clearKeys() {\n this.signingKey = null;\n this.verificationKey = null;\n console.log('\uD83D\uDD12 Security keys cleared');\n }\n\n getSecurityStatus() {\n return {\n signingEnabled: this.signingKey !== null,\n verificationEnabled: this.verificationKey !== null,\n contextActive: SecureFileTransferContext.getInstance().isActive(),\n securityLevel: SecureFileTransferContext.getInstance().getSecurityLevel()\n };\n }\n\n getClientIdentifier() {\n return this.webrtcManager?.connectionId || \n this.webrtcManager?.keyFingerprint?.substring(0, 16) || \n 'default-client';\n }\n \n destroy() {\n SecureFileTransferContext.getInstance().deactivate();\n this.clearKeys();\n console.log('\uD83D\uDD12 File transfer system destroyed safely');\n }\n}\n\nexport { EnhancedSecureFileTransfer };", "// Import EnhancedSecureFileTransfer\r\nimport { EnhancedSecureFileTransfer } from '../transfer/EnhancedSecureFileTransfer.js';\r\n\r\n// MUTEX SYSTEM FIXES - RESOLVING MESSAGE DELIVERY ISSUES\r\n// ============================================\r\n// Issue: After introducing the Mutex system, messages stopped being delivered between users\r\n// Fix: Simplified locking logic \u2014 mutex is used ONLY for critical operations\r\n// - Regular messages are processed WITHOUT mutex\r\n// - File messages are processed WITHOUT mutex \r\n// - Mutex is used ONLY for cryptographic operations\r\n// ============================================\r\n\r\nclass EnhancedSecureWebRTCManager {\r\n // ============================================\r\n // CONSTANTS\r\n // ============================================\r\n \r\n static TIMEOUTS = {\r\n KEY_ROTATION_INTERVAL: 300000, // 5 minutes\r\n CONNECTION_TIMEOUT: 10000, // 10 seconds \r\n HEARTBEAT_INTERVAL: 30000, // 30 seconds\r\n SECURITY_CALC_DELAY: 1000, // 1 second\r\n SECURITY_CALC_RETRY_DELAY: 3000, // 3 seconds\r\n CLEANUP_INTERVAL: 300000, // 5 minutes (periodic cleanup)\r\n CLEANUP_CHECK_INTERVAL: 60000, // 1 minute (cleanup check)\r\n ICE_GATHERING_TIMEOUT: 10000, // 10 seconds\r\n DISCONNECT_CLEANUP_DELAY: 500, // 500ms\r\n PEER_DISCONNECT_CLEANUP: 2000, // 2 seconds\r\n STAGE2_ACTIVATION_DELAY: 10000, // 10 seconds\r\n STAGE3_ACTIVATION_DELAY: 15000, // 15 seconds \r\n STAGE4_ACTIVATION_DELAY: 20000, // 20 seconds\r\n FILE_TRANSFER_INIT_DELAY: 1000, // 1 second\r\n FAKE_TRAFFIC_MIN_INTERVAL: 15000, // 15 seconds\r\n FAKE_TRAFFIC_MAX_INTERVAL: 30000, // 30 seconds\r\n DECOY_INITIAL_DELAY: 5000, // 5 seconds\r\n DECOY_TRAFFIC_MIN: 10000, // 10 seconds\r\n DECOY_TRAFFIC_MAX: 25000, // 25 seconds\r\n REORDER_TIMEOUT: 3000, // 3 seconds\r\n RETRY_CONNECTION_DELAY: 2000 // 2 seconds\r\n };\r\n\r\n static LIMITS = {\r\n MAX_CONNECTION_ATTEMPTS: 3,\r\n MAX_OLD_KEYS: 3,\r\n MAX_PROCESSED_MESSAGE_IDS: 1000,\r\n MAX_OUT_OF_ORDER_PACKETS: 5,\r\n MAX_DECOY_CHANNELS: 1,\r\n MESSAGE_RATE_LIMIT: 60, // messages per minute\r\n MAX_KEY_AGE: 900000, // 15 minutes\r\n OFFER_MAX_AGE: 3600000, // 1 hour\r\n SALT_SIZE_V3: 32, // bytes\r\n SALT_SIZE_V4: 64 // bytes\r\n };\r\n\r\n static SIZES = {\r\n VERIFICATION_CODE_MIN_LENGTH: 6,\r\n FAKE_TRAFFIC_MIN_SIZE: 32,\r\n FAKE_TRAFFIC_MAX_SIZE: 128,\r\n PACKET_PADDING_MIN: 64,\r\n PACKET_PADDING_MAX: 512,\r\n CHUNK_SIZE_MAX: 2048,\r\n CHUNK_DELAY_MIN: 100,\r\n CHUNK_DELAY_MAX: 500,\r\n FINGERPRINT_DISPLAY_LENGTH: 8,\r\n SESSION_ID_LENGTH: 16,\r\n NESTED_ENCRYPTION_IV_SIZE: 12\r\n };\r\n\r\n static MESSAGE_TYPES = {\r\n // Regular messages\r\n MESSAGE: 'message',\r\n ENHANCED_MESSAGE: 'enhanced_message',\r\n \r\n // System messages\r\n HEARTBEAT: 'heartbeat',\r\n VERIFICATION: 'verification',\r\n VERIFICATION_RESPONSE: 'verification_response',\r\n VERIFICATION_CONFIRMED: 'verification_confirmed',\r\n VERIFICATION_BOTH_CONFIRMED: 'verification_both_confirmed',\r\n PEER_DISCONNECT: 'peer_disconnect',\r\n SECURITY_UPGRADE: 'security_upgrade',\r\n KEY_ROTATION_SIGNAL: 'key_rotation_signal',\r\n KEY_ROTATION_READY: 'key_rotation_ready',\r\n \r\n // File transfer messages\r\n FILE_TRANSFER_START: 'file_transfer_start',\r\n FILE_TRANSFER_RESPONSE: 'file_transfer_response',\r\n FILE_CHUNK: 'file_chunk',\r\n CHUNK_CONFIRMATION: 'chunk_confirmation',\r\n FILE_TRANSFER_COMPLETE: 'file_transfer_complete',\r\n FILE_TRANSFER_ERROR: 'file_transfer_error',\r\n \r\n // Fake traffic\r\n FAKE: 'fake'\r\n };\r\n\r\n static FILTERED_RESULTS = {\r\n FAKE_MESSAGE: 'FAKE_MESSAGE_FILTERED',\r\n FILE_MESSAGE: 'FILE_MESSAGE_FILTERED', \r\n SYSTEM_MESSAGE: 'SYSTEM_MESSAGE_FILTERED'\r\n };\r\n\r\n // Static debug flag instead of this._debugMode\r\n static DEBUG_MODE = false; // Set to true during development, false in production\r\n\r\n\r\n constructor(onMessage, onStatusChange, onKeyExchange, onVerificationRequired, onAnswerError = null, onVerificationStateChange = null, config = {}) {\r\n // Determine runtime mode\r\n this._isProductionMode = this._detectProductionMode();\r\n // Use static flag instead of this._debugMode\r\n this._debugMode = !this._isProductionMode && EnhancedSecureWebRTCManager.DEBUG_MODE;\r\n \r\n // Configuration from constructor parameters instead of global flags\r\n this._config = {\r\n fakeTraffic: {\r\n enabled: config.fakeTraffic?.enabled ?? true,\r\n minInterval: config.fakeTraffic?.minInterval ?? EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MIN_INTERVAL,\r\n maxInterval: config.fakeTraffic?.maxInterval ?? EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MAX_INTERVAL,\r\n minSize: config.fakeTraffic?.minSize ?? EnhancedSecureWebRTCManager.SIZES.FAKE_TRAFFIC_MIN_SIZE,\r\n maxSize: config.fakeTraffic?.maxSize ?? EnhancedSecureWebRTCManager.SIZES.FAKE_TRAFFIC_MAX_SIZE,\r\n patterns: config.fakeTraffic?.patterns ?? ['heartbeat', 'status', 'sync']\r\n },\r\n decoyChannels: {\r\n enabled: config.decoyChannels?.enabled ?? true,\r\n maxDecoyChannels: config.decoyChannels?.maxDecoyChannels ?? EnhancedSecureWebRTCManager.LIMITS.MAX_DECOY_CHANNELS,\r\n decoyChannelNames: config.decoyChannels?.decoyChannelNames ?? ['heartbeat'],\r\n sendDecoyData: config.decoyChannels?.sendDecoyData ?? true,\r\n randomDecoyIntervals: config.decoyChannels?.randomDecoyIntervals ?? true\r\n },\r\n packetPadding: {\r\n enabled: config.packetPadding?.enabled ?? true,\r\n minPadding: config.packetPadding?.minPadding ?? EnhancedSecureWebRTCManager.SIZES.PACKET_PADDING_MIN,\r\n maxPadding: config.packetPadding?.maxPadding ?? EnhancedSecureWebRTCManager.SIZES.PACKET_PADDING_MAX,\r\n useRandomPadding: config.packetPadding?.useRandomPadding ?? true,\r\n preserveMessageSize: config.packetPadding?.preserveMessageSize ?? false\r\n },\r\n antiFingerprinting: {\r\n enabled: config.antiFingerprinting?.enabled ?? false,\r\n randomizeTiming: config.antiFingerprinting?.randomizeTiming ?? true,\r\n randomizeSizes: config.antiFingerprinting?.randomizeSizes ?? false,\r\n addNoise: config.antiFingerprinting?.addNoise ?? true,\r\n maskPatterns: config.antiFingerprinting?.maskPatterns ?? false,\r\n useRandomHeaders: config.antiFingerprinting?.useRandomHeaders ?? false\r\n }\r\n };\r\n\r\n // Initialize own logging system\r\n this._initializeSecureLogging();\r\n this._setupOwnLogger();\r\n this._setupProductionLogging();\r\n \r\n // Store important methods first\r\n this._storeImportantMethods();\r\n \r\n // Setup global API after storing methods\r\n this._setupSecureGlobalAPI();\r\n if (!window.EnhancedSecureCryptoUtils) {\r\n throw new Error('EnhancedSecureCryptoUtils is not loaded. Please ensure the module is loaded first.');\r\n }\r\n this.getSecurityData = () => {\r\n // Return only public information\r\n return this.lastSecurityCalculation ? {\r\n level: this.lastSecurityCalculation.level,\r\n score: this.lastSecurityCalculation.score,\r\n timestamp: this.lastSecurityCalculation.timestamp,\r\n // Do NOT return check details or sensitive data\r\n } : null;\r\n };\r\n this._secureLog('info', '\uD83D\uDD12 Enhanced WebRTC Manager initialized with secure API');\r\n this.sessionConstraints = null;\r\n this.peerConnection = null;\r\n this.dataChannel = null;\r\n\r\n\r\n this.onMessage = onMessage;\r\n this.onStatusChange = onStatusChange;\r\n this.onKeyExchange = onKeyExchange;\r\n this.onVerificationStateChange = onVerificationStateChange;\r\n\r\n this.onVerificationRequired = onVerificationRequired;\r\n this.onAnswerError = onAnswerError; // Callback for response processing errors\r\n this.isInitiator = false;\r\n this.connectionAttempts = 0;\r\n this.maxConnectionAttempts = EnhancedSecureWebRTCManager.LIMITS.MAX_CONNECTION_ATTEMPTS;\r\n try {\r\n this._initializeMutexSystem();\r\n} catch (error) {\r\n this._secureLog('error', '\u274C Failed to initialize mutex system', {\r\n errorType: error.constructor.name\r\n });\r\n throw new Error('Critical: Mutex system initialization failed');\r\n}\r\n\r\n// Post-initialization validation of the mutex system\r\nif (!this._validateMutexSystem()) {\r\n this._secureLog('error', '\u274C Mutex system validation failed after initialization');\r\n throw new Error('Critical: Mutex system validation failed');\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n this._secureLog('info', '\uD83D\uDD12 Emergency mutex handlers will be available through secure API');\r\n}\r\n\r\nthis._secureLog('info', '\uD83D\uDD12 Enhanced Mutex system fully initialized and validated');\r\n this.heartbeatInterval = null;\r\n this.messageQueue = [];\r\n this.ecdhKeyPair = null;\r\n this.ecdsaKeyPair = null;\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n this.verificationCode = null;\r\n this.pendingSASCode = null;\r\n this.isVerified = false;\r\n this.processedMessageIds = new Set();\r\n \r\n // Mutual verification states\r\n this.localVerificationConfirmed = false;\r\n this.remoteVerificationConfirmed = false;\r\n this.bothVerificationsConfirmed = false;\r\n \r\n // Store expected DTLS fingerprint for validation\r\n this.expectedDTLSFingerprint = null;\r\n this.strictDTLSValidation = true; // Can be disabled for debugging\r\n \r\n // Real Perfect Forward Secrecy implementation\r\n this.ephemeralKeyPairs = new Map(); // Store ephemeral keys for current session only\r\n this.sessionStartTime = Date.now(); // Track session lifetime for PFS\r\n this.messageCounter = 0;\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.sessionSalt = null;\r\n \r\n // Anti-Replay and Message Ordering Protection\r\n this.replayWindowSize = 64; // Sliding window for replay protection\r\n this.replayWindow = new Set(); // Track recent sequence numbers\r\n this.maxSequenceGap = 100; // Maximum allowed sequence gap\r\n this.replayProtectionEnabled = true; // Enable/disable replay protection\r\n this.sessionId = null; // MITM protection: Session identifier\r\n this.connectionId = Array.from(crypto.getRandomValues(new Uint8Array(8)))\r\n .map(b => b.toString(16).padStart(2, '0')).join(''); // Connection identifier for AAD\r\n this.peerPublicKey = null; // Store peer's public key for PFS\r\n this.rateLimiterId = null;\r\n this.intentionalDisconnect = false;\r\n this.lastCleanupTime = Date.now();\r\n \r\n // Reset notification flags for new connection\r\n this._resetNotificationFlags();\r\n \r\n \r\n\r\n this.verificationInitiationSent = false;\r\n this.disconnectNotificationSent = false;\r\n this.reconnectionFailedNotificationSent = false;\r\n this.peerDisconnectNotificationSent = false;\r\n this.connectionClosedNotificationSent = false;\r\n this.fakeTrafficDisabledNotificationSent = false;\r\n this.advancedFeaturesDisabledNotificationSent = false;\r\n this.securityUpgradeNotificationSent = false;\r\n this.lastSecurityUpgradeStage = null;\r\n this.securityCalculationNotificationSent = false;\r\n this.lastSecurityCalculationLevel = null;\r\n \r\n // File transfer integration\r\n this.fileTransferSystem = null;\r\n this.onFileProgress = null;\r\n \r\n // ============================================\r\n // IV REUSE PREVENTION SYSTEM\r\n // ============================================\r\n // IV REUSE PREVENTION SYSTEM WITH LIMITS\r\n // ============================================\r\n this._ivTrackingSystem = {\r\n usedIVs: new Set(), // Track all used IVs to prevent reuse\r\n ivHistory: new Map(), // Track IV usage with timestamps (max 10k entries)\r\n collisionCount: 0, // Track potential collisions\r\n maxIVHistorySize: 10000, // Maximum IV history size\r\n maxSessionIVs: 1000, // Maximum IVs per session\r\n entropyValidation: {\r\n minEntropy: 3.0, // Minimum entropy threshold\r\n entropyTests: 0,\r\n entropyFailures: 0\r\n },\r\n rngValidation: {\r\n testsPerformed: 0,\r\n weakRngDetected: false,\r\n lastValidation: 0\r\n },\r\n sessionIVs: new Map(), // Track IVs per session\r\n emergencyMode: false // Emergency mode if IV reuse detected\r\n };\r\n \r\n // IV cleanup tracking\r\n this._lastIVCleanupTime = null;\r\n \r\n // ============================================\r\n // SECURE ERROR HANDLING SYSTEM\r\n // ============================================\r\n this._secureErrorHandler = {\r\n errorCategories: {\r\n CRYPTOGRAPHIC: 'cryptographic',\r\n NETWORK: 'network',\r\n VALIDATION: 'validation',\r\n SYSTEM: 'system',\r\n UNKNOWN: 'unknown'\r\n },\r\n errorMappings: new Map(), // Map internal errors to safe messages\r\n errorCounts: new Map(), // Track error frequencies\r\n lastErrorTime: 0,\r\n errorThreshold: 10, // Max errors per minute\r\n isInErrorMode: false\r\n };\r\n \r\n // ============================================\r\n // SECURE MEMORY MANAGEMENT SYSTEM\r\n // ============================================\r\n this._secureMemoryManager = {\r\n sensitiveData: new WeakMap(), // Track sensitive data for secure cleanup\r\n cleanupQueue: [], // Queue for deferred cleanup operations\r\n isCleaning: false, // Prevent concurrent cleanup operations\r\n cleanupInterval: null, // Periodic cleanup timer\r\n memoryStats: {\r\n totalCleanups: 0,\r\n failedCleanups: 0,\r\n lastCleanup: 0\r\n }\r\n };\r\n this.onFileReceived = null;\r\n this.onFileError = null;\r\n \r\n // PFS (Perfect Forward Secrecy) Implementation\r\n this.keyRotationInterval = EnhancedSecureWebRTCManager.TIMEOUTS.KEY_ROTATION_INTERVAL;\r\n this.lastKeyRotation = Date.now();\r\n this.currentKeyVersion = 0;\r\n this.keyVersions = new Map(); // Store key versions for PFS\r\n this.oldKeys = new Map(); // Store old keys temporarily for decryption\r\n this.maxOldKeys = EnhancedSecureWebRTCManager.LIMITS.MAX_OLD_KEYS; // Keep last 3 key versions for decryption\r\n this.peerConnection = null;\r\n this.dataChannel = null;\r\n \r\n\r\n this.securityFeatures = {\r\n // All security features enabled by default - no payment required\r\n hasEncryption: true, \r\n hasECDH: true, \r\n hasECDSA: true, \r\n hasMutualAuth: true, \r\n hasMetadataProtection: true, \r\n hasEnhancedReplayProtection: true, \r\n hasNonExtractableKeys: true, \r\n hasRateLimiting: true, \r\n hasEnhancedValidation: true, \r\n hasPFS: true, // Real Perfect Forward Secrecy enabled \r\n \r\n // Advanced Features - All enabled by default\r\n hasNestedEncryption: true, \r\n hasPacketPadding: true, \r\n hasPacketReordering: true, \r\n hasAntiFingerprinting: true, \r\n hasFakeTraffic: true, \r\n hasDecoyChannels: true, \r\n hasMessageChunking: true \r\n };\r\n this._secureLog('info', '\uD83D\uDD12 Enhanced WebRTC Manager initialized with tiered security');\r\n \r\n // Log configuration for debugging\r\n this._secureLog('info', '\uD83D\uDD12 Configuration loaded from constructor parameters', {\r\n fakeTraffic: this._config.fakeTraffic.enabled,\r\n decoyChannels: this._config.decoyChannels.enabled,\r\n packetPadding: this._config.packetPadding.enabled,\r\n antiFingerprinting: this._config.antiFingerprinting.enabled\r\n });\r\n \r\n // XSS Hardening - replace all window.DEBUG_MODE references\r\n this._hardenDebugModeReferences();\r\n \r\n // Initialize unified scheduler for all maintenance tasks\r\n this._initializeUnifiedScheduler();\r\n \r\n this._syncSecurityFeaturesWithTariff();\r\n \r\n if (!this._validateCryptographicSecurity()) {\r\n this._secureLog('error', '\uD83D\uDEA8 CRITICAL: Cryptographic security validation failed after tariff sync');\r\n throw new Error('Critical cryptographic features are missing after tariff synchronization');\r\n }\r\n // ============================================\r\n // ENHANCED SECURITY FEATURES\r\n // ============================================\r\n \r\n // 1. Nested Encryption Layer\r\n this.nestedEncryptionKey = null;\r\n // Removed nestedEncryptionIV and nestedEncryptionCounter\r\n // Each nested encryption now generates fresh random IV for maximum security\r\n \r\n // 2. Packet Padding\r\n this.paddingConfig = {\r\n enabled: this._config.packetPadding.enabled,\r\n minPadding: this._config.packetPadding.minPadding,\r\n maxPadding: this._config.packetPadding.maxPadding,\r\n useRandomPadding: this._config.packetPadding.useRandomPadding,\r\n preserveMessageSize: this._config.packetPadding.preserveMessageSize\r\n };\r\n \r\n // 3. Fake Traffic Generation\r\n this.fakeTrafficConfig = {\r\n enabled: this._config.fakeTraffic?.enabled || false,\r\n minInterval: this._config.fakeTraffic?.minInterval || 15000,\r\n maxInterval: this._config.fakeTraffic?.maxInterval || 30000,\r\n minSize: this._config.fakeTraffic?.minSize || 64,\r\n maxSize: this._config.fakeTraffic?.maxSize || 1024,\r\n patterns: this._config.fakeTraffic?.patterns || ['heartbeat', 'status', 'ping'],\r\n randomDecoyIntervals: this._config.fakeTraffic?.randomDecoyIntervals || true\r\n };\r\n this.fakeTrafficTimer = null;\r\n this.lastFakeTraffic = 0;\r\n \r\n // 4. Message Chunking\r\n this.chunkingConfig = {\r\n enabled: false,\r\n maxChunkSize: EnhancedSecureWebRTCManager.SIZES.CHUNK_SIZE_MAX, \r\n minDelay: EnhancedSecureWebRTCManager.SIZES.CHUNK_DELAY_MIN,\r\n maxDelay: EnhancedSecureWebRTCManager.SIZES.CHUNK_DELAY_MAX,\r\n useRandomDelays: true,\r\n addChunkHeaders: true\r\n };\r\n this.chunkQueue = [];\r\n this.chunkingInProgress = false;\r\n \r\n // 5. Decoy Channels\r\n this.decoyChannels = new Map();\r\n this.decoyChannelConfig = {\r\n enabled: this._config.decoyChannels.enabled,\r\n maxDecoyChannels: this._config.decoyChannels.maxDecoyChannels,\r\n decoyChannelNames: this._config.decoyChannels.decoyChannelNames,\r\n sendDecoyData: this._config.decoyChannels.sendDecoyData,\r\n randomDecoyIntervals: this._config.decoyChannels.randomDecoyIntervals\r\n };\r\n this.decoyTimers = new Map();\r\n \r\n // 6. Packet Reordering Protection\r\n this.reorderingConfig = {\r\n enabled: false, \r\n maxOutOfOrder: EnhancedSecureWebRTCManager.LIMITS.MAX_OUT_OF_ORDER_PACKETS, \r\n reorderTimeout: EnhancedSecureWebRTCManager.TIMEOUTS.REORDER_TIMEOUT, \r\n useSequenceNumbers: true,\r\n useTimestamps: true\r\n };\r\n this.packetBuffer = new Map(); // sequence -> {data, timestamp}\r\n this.lastProcessedSequence = -1;\r\n \r\n // 7. Anti-Fingerprinting\r\n this.antiFingerprintingConfig = {\r\n enabled: this._config.antiFingerprinting.enabled,\r\n randomizeTiming: this._config.antiFingerprinting.randomizeTiming,\r\n randomizeSizes: this._config.antiFingerprinting.randomizeSizes,\r\n addNoise: this._config.antiFingerprinting.addNoise,\r\n maskPatterns: this._config.antiFingerprinting.maskPatterns,\r\n useRandomHeaders: this._config.antiFingerprinting.useRandomHeaders\r\n };\r\n this.fingerprintMask = this.generateFingerprintMask();\r\n \r\n // Initialize rate limiter ID\r\n this.rateLimiterId = `webrtc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n \r\n // Start periodic cleanup\r\n this.startPeriodicCleanup();\r\n \r\n this.initializeEnhancedSecurity(); \r\n \r\n // ============================================\r\n // MUTEX SYSTEM TO PREVENT RACE CONDITIONS\r\n // ============================================\r\n\r\n // Mutex for key operations\r\n this._keyOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null\r\n };\r\n\r\n // Mutex for encryption/decryption operations\r\n this._cryptoOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null\r\n };\r\n\r\n // Mutex for connection initialization\r\n this._connectionOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null\r\n };\r\n\r\n // Key system state\r\n this._keySystemState = {\r\n isInitializing: false,\r\n isRotating: false,\r\n isDestroying: false,\r\n lastOperation: null,\r\n lastOperationTime: Date.now()\r\n };\r\n\r\n // Operation counters\r\n this._operationCounters = {\r\n keyOperations: 0,\r\n cryptoOperations: 0,\r\n connectionOperations: 0\r\n };\r\n\r\n }\r\n \r\n /**\r\n * Create AAD with sequence number for anti-replay protection\r\n * This binds each message to its sequence number and prevents replay attacks\r\n */\r\n _createMessageAAD(messageType, messageData = null, isFileMessage = false) {\r\n try {\r\n const aad = {\r\n sessionId: this.currentSession?.sessionId || this.sessionId || 'unknown',\r\n keyFingerprint: this.keyFingerprint || 'unknown',\r\n sequenceNumber: this._generateNextSequenceNumber(),\r\n messageType: messageType,\r\n timestamp: Date.now(),\r\n connectionId: this.connectionId || 'unknown',\r\n isFileMessage: isFileMessage\r\n };\r\n\r\n // Add message-specific data if available\r\n if (messageData && typeof messageData === 'object') {\r\n if (messageData.fileId) aad.fileId = messageData.fileId;\r\n if (messageData.chunkIndex !== undefined) aad.chunkIndex = messageData.chunkIndex;\r\n if (messageData.totalChunks !== undefined) aad.totalChunks = messageData.totalChunks;\r\n }\r\n\r\n return JSON.stringify(aad);\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to create message AAD', {\r\n errorType: error.constructor.name,\r\n message: error.message,\r\n messageType: messageType\r\n });\r\n // Fallback to basic AAD\r\n return JSON.stringify({\r\n sessionId: 'unknown',\r\n keyFingerprint: 'unknown',\r\n sequenceNumber: Date.now(),\r\n messageType: messageType,\r\n timestamp: Date.now(),\r\n connectionId: 'unknown',\r\n isFileMessage: isFileMessage\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Generate next sequence number for outgoing messages\r\n * This ensures unique ordering and prevents replay attacks\r\n */\r\n _generateNextSequenceNumber() {\r\n const nextSeq = this.sequenceNumber++;\r\n \r\n // Reset sequence number if it gets too large\r\n if (this.sequenceNumber > Number.MAX_SAFE_INTEGER - 1000) {\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.replayWindow.clear();\r\n this._secureLog('warn', '\u26A0\uFE0F Sequence number reset due to overflow', {\r\n timestamp: Date.now()\r\n });\r\n }\r\n \r\n return nextSeq;\r\n }\r\n\r\n /**\r\n * Create a safe hash for logging sensitive data\r\n * Returns only the first 4 bytes (8 hex chars) of SHA-256 hash\r\n * @param {any} sensitiveData - The sensitive data to hash\r\n * @param {string} context - Context for error logging\r\n * @returns {Promise} - Short hash (8 hex chars) or 'hash_error'\r\n */\r\n async _createSafeLogHash(sensitiveData, context = 'unknown') {\r\n try {\r\n let dataToHash;\r\n \r\n // Convert different data types to consistent format for hashing\r\n if (sensitiveData instanceof ArrayBuffer) {\r\n dataToHash = new Uint8Array(sensitiveData);\r\n } else if (sensitiveData instanceof Uint8Array) {\r\n dataToHash = sensitiveData;\r\n } else if (sensitiveData instanceof CryptoKey) {\r\n // For CryptoKey, use its type and algorithm info (not the key material)\r\n const keyInfo = `${sensitiveData.type}_${sensitiveData.algorithm?.name || 'unknown'}_${sensitiveData.extractable}`;\r\n dataToHash = new TextEncoder().encode(keyInfo);\r\n } else if (typeof sensitiveData === 'string') {\r\n dataToHash = new TextEncoder().encode(sensitiveData);\r\n } else if (typeof sensitiveData === 'object' && sensitiveData !== null) {\r\n // For objects (like JWK), stringify without sensitive fields\r\n const safeObj = { type: sensitiveData.kty || 'unknown', use: sensitiveData.use || 'unknown' };\r\n dataToHash = new TextEncoder().encode(JSON.stringify(safeObj));\r\n } else {\r\n // Fallback for other types\r\n dataToHash = new TextEncoder().encode(String(sensitiveData));\r\n }\r\n \r\n // Create SHA-256 hash\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataToHash);\r\n const hashArray = new Uint8Array(hashBuffer);\r\n \r\n // Return only first 4 bytes as hex (8 characters)\r\n return Array.from(hashArray.slice(0, 4))\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('');\r\n \r\n } catch (error) {\r\n // Never log the actual error details to avoid leaking sensitive data\r\n return 'hash_error';\r\n }\r\n }\r\n\r\n /**\r\n * Async sleep helper - replaces busy-wait\r\n */\r\n async _asyncSleep(ms) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n /**\r\n * Async cleanup helper - replaces immediate heavy operations\r\n */\r\n async _scheduleAsyncCleanup(cleanupFn, delay = 0) {\r\n return new Promise((resolve) => {\r\n setTimeout(async () => {\r\n try {\r\n await cleanupFn();\r\n resolve(true);\r\n } catch (error) {\r\n this._secureLog('error', 'Async cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n resolve(false);\r\n }\r\n }, delay);\r\n });\r\n }\r\n\r\n /**\r\n * Batch async operations to prevent UI blocking\r\n */\r\n async _batchAsyncOperation(items, batchSize = 10, delayBetweenBatches = 5) {\r\n const results = [];\r\n \r\n for (let i = 0; i < items.length; i += batchSize) {\r\n const batch = items.slice(i, i + batchSize);\r\n const batchResults = await Promise.all(batch);\r\n results.push(...batchResults);\r\n \r\n // Small delay between batches to prevent UI blocking\r\n if (i + batchSize < items.length) {\r\n await this._asyncSleep(delayBetweenBatches);\r\n }\r\n }\r\n \r\n return results;\r\n }\r\n\r\n /**\r\n * Memory cleanup without window.gc() - uses natural garbage collection\r\n */\r\n async _performNaturalCleanup() {\r\n // Clear references and let JS engine handle GC naturally\r\n // This is more reliable than forcing GC\r\n \r\n // Schedule cleanup in next event loop cycle\r\n await this._asyncSleep(0);\r\n \r\n // Allow multiple event loop cycles for natural GC\r\n for (let i = 0; i < 3; i++) {\r\n await this._asyncSleep(10);\r\n }\r\n }\r\n\r\n /**\r\n * Heavy cleanup operations using WebWorker (if available)\r\n */\r\n async _performHeavyCleanup(cleanupData) {\r\n // Try to use WebWorker for heavy operations\r\n if (typeof Worker !== 'undefined') {\r\n try {\r\n return await this._cleanupWithWorker(cleanupData);\r\n } catch (error) {\r\n this._secureLog('warn', 'WebWorker cleanup failed, falling back to main thread', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n }\r\n }\r\n \r\n // Fallback to main thread with async batching\r\n return await this._cleanupInMainThread(cleanupData);\r\n }\r\n\r\n /**\r\n * Cleanup using WebWorker\r\n */\r\n async _cleanupWithWorker(cleanupData) {\r\n return new Promise((resolve, reject) => {\r\n // Create inline worker for cleanup operations\r\n const workerCode = `\r\n self.onmessage = function(e) {\r\n const { type, data } = e.data;\r\n \r\n try {\r\n switch (type) {\r\n case 'cleanup_arrays':\r\n // Simulate heavy array cleanup\r\n let processed = 0;\r\n for (let i = 0; i < data.count; i++) {\r\n // Simulate work\r\n processed++;\r\n if (processed % 1000 === 0) {\r\n // Yield control periodically\r\n setTimeout(() => {}, 0);\r\n }\r\n }\r\n self.postMessage({ success: true, processed });\r\n break;\r\n \r\n case 'cleanup_objects':\r\n // Simulate object cleanup\r\n const cleaned = data.objects.map(() => null);\r\n self.postMessage({ success: true, cleaned: cleaned.length });\r\n break;\r\n \r\n default:\r\n self.postMessage({ success: true, message: 'Unknown cleanup type' });\r\n }\r\n } catch (error) {\r\n self.postMessage({ success: false, error: error.message });\r\n }\r\n };\r\n `;\r\n \r\n const blob = new Blob([workerCode], { type: 'application/javascript' });\r\n const worker = new Worker(URL.createObjectURL(blob));\r\n \r\n const timeout = setTimeout(() => {\r\n worker.terminate();\r\n reject(new Error('Worker cleanup timeout'));\r\n }, 5000); // 5 second timeout\r\n \r\n worker.onmessage = (e) => {\r\n clearTimeout(timeout);\r\n worker.terminate();\r\n URL.revokeObjectURL(blob);\r\n \r\n if (e.data.success) {\r\n resolve(e.data);\r\n } else {\r\n reject(new Error(e.data.error));\r\n }\r\n };\r\n \r\n worker.onerror = (error) => {\r\n clearTimeout(timeout);\r\n worker.terminate();\r\n URL.revokeObjectURL(blob);\r\n reject(error);\r\n };\r\n \r\n worker.postMessage(cleanupData);\r\n });\r\n }\r\n\r\n /**\r\n * Cleanup in main thread with async batching\r\n */\r\n async _cleanupInMainThread(cleanupData) {\r\n const { type, data } = cleanupData;\r\n \r\n switch (type) {\r\n case 'cleanup_arrays':\r\n // Process in batches to avoid blocking\r\n let processed = 0;\r\n const batchSize = 100;\r\n \r\n while (processed < data.count) {\r\n const batchEnd = Math.min(processed + batchSize, data.count);\r\n \r\n // Process batch\r\n for (let i = processed; i < batchEnd; i++) {\r\n // Simulate cleanup work\r\n }\r\n \r\n processed = batchEnd;\r\n \r\n // Yield control to prevent UI blocking\r\n await this._asyncSleep(1);\r\n }\r\n \r\n return { success: true, processed };\r\n \r\n case 'cleanup_objects':\r\n // Clean objects in batches\r\n const objects = data.objects || [];\r\n const batches = [];\r\n \r\n for (let i = 0; i < objects.length; i += 50) {\r\n batches.push(objects.slice(i, i + 50));\r\n }\r\n \r\n let cleaned = 0;\r\n for (const batch of batches) {\r\n batch.forEach(() => cleaned++);\r\n await this._asyncSleep(1);\r\n }\r\n \r\n return { success: true, cleaned };\r\n \r\n default:\r\n return { success: true, message: 'Unknown cleanup type' };\r\n }\r\n }\r\n \r\n /**\r\n * Enhanced mutex system initialization with atomic protection\r\n */\r\n _initializeMutexSystem() {\r\n // Initialize standard mutexes with enhanced state tracking\r\n this._keyOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null,\r\n lockTime: null,\r\n operationCount: 0\r\n };\r\n\r\n this._cryptoOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null,\r\n lockTime: null,\r\n operationCount: 0\r\n };\r\n\r\n this._connectionOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null,\r\n lockTime: null,\r\n operationCount: 0\r\n };\r\n\r\n // Enhanced key system state with atomic operation tracking\r\n this._keySystemState = {\r\n isInitializing: false,\r\n isRotating: false,\r\n isDestroying: false,\r\n lastOperation: null,\r\n lastOperationTime: Date.now(),\r\n operationId: null,\r\n concurrentOperations: 0,\r\n maxConcurrentOperations: 1\r\n };\r\n\r\n // Operation counters with atomic increments\r\n this._operationCounters = {\r\n keyOperations: 0,\r\n cryptoOperations: 0,\r\n connectionOperations: 0,\r\n totalOperations: 0,\r\n failedOperations: 0\r\n };\r\n\r\n this._secureLog('info', '\uD83D\uDD12 Enhanced mutex system initialized with atomic protection', {\r\n mutexes: ['keyOperation', 'cryptoOperation', 'connectionOperation'],\r\n timestamp: Date.now(),\r\n features: ['atomic_operations', 'race_condition_protection', 'enhanced_state_tracking']\r\n });\r\n }\r\n\r\n /**\r\n * XSS Hardening - Debug mode references validation\r\n * This method is called during initialization to ensure XSS hardening\r\n */\r\n _hardenDebugModeReferences() {\r\n // Log that we're hardening debug mode references\r\n this._secureLog('info', '\uD83D\uDD12 XSS Hardening: Debug mode references already replaced');\r\n }\r\n\r\n /**\r\n * Unified scheduler for all maintenance tasks\r\n * Replaces multiple setInterval calls with a single, controlled scheduler\r\n */\r\n _initializeUnifiedScheduler() {\r\n // Single scheduler interval for all maintenance tasks\r\n this._maintenanceScheduler = setInterval(() => {\r\n this._executeMaintenanceCycle();\r\n }, 300000); // Every 5 minutes\r\n \r\n // Log scheduler initialization\r\n this._secureLog('info', '\uD83D\uDD27 Unified maintenance scheduler initialized (5-minute cycle)');\r\n \r\n // Store scheduler reference for cleanup\r\n this._activeTimers = new Set([this._maintenanceScheduler]);\r\n }\r\n\r\n /**\r\n * Execute all maintenance tasks in a single cycle\r\n */\r\n _executeMaintenanceCycle() {\r\n try {\r\n this._secureLog('info', '\uD83D\uDD27 Starting maintenance cycle');\r\n \r\n // 1. Log cleanup and security audit\r\n this._cleanupLogs();\r\n this._auditLoggingSystemSecurity();\r\n \r\n // 2. Security monitoring\r\n this._verifyAPIIntegrity();\r\n this._validateCryptographicSecurity();\r\n this._syncSecurityFeaturesWithTariff();\r\n \r\n // 3. Resource cleanup\r\n this._cleanupResources();\r\n this._enforceResourceLimits();\r\n \r\n // 4. Key monitoring (if connected)\r\n if (this.isConnected && this.isVerified) {\r\n this._monitorKeySecurity();\r\n }\r\n \r\n // 5. Global exposure monitoring (debug mode only)\r\n if (this._debugMode) {\r\n this._monitorGlobalExposure();\r\n }\r\n \r\n // 6. Heartbeat (if enabled and connected)\r\n if (this._heartbeatConfig && this._heartbeatConfig.enabled && this.isConnected()) {\r\n this._sendHeartbeat();\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD27 Maintenance cycle completed successfully');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Maintenance cycle failed', {\r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n \r\n // Emergency cleanup on failure\r\n this._emergencyCleanup().catch(error => {\r\n this._secureLog('error', 'Emergency cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Enforce hard resource limits with emergency cleanup\r\n */\r\n _enforceResourceLimits() {\r\n const violations = [];\r\n \r\n // Check log entries\r\n if (this._logCounts.size > this._resourceLimits.maxLogEntries) {\r\n violations.push('log_entries');\r\n }\r\n \r\n // Check message queue\r\n if (this.messageQueue.length > this._resourceLimits.maxMessageQueue) {\r\n violations.push('message_queue');\r\n }\r\n \r\n // Check IV history\r\n if (this._ivTrackingSystem && this._ivTrackingSystem.ivHistory.size > this._resourceLimits.maxIVHistory) {\r\n violations.push('iv_history');\r\n }\r\n \r\n // Check processed message IDs\r\n if (this.processedMessageIds.size > this._resourceLimits.maxProcessedMessageIds) {\r\n violations.push('processed_message_ids');\r\n }\r\n \r\n // Check decoy channels\r\n if (this.decoyChannels.size > this._resourceLimits.maxDecoyChannels) {\r\n violations.push('decoy_channels');\r\n }\r\n \r\n // Check fake traffic messages\r\n if (this._fakeTrafficMessages && this._fakeTrafficMessages.length > this._resourceLimits.maxFakeTrafficMessages) {\r\n violations.push('fake_traffic_messages');\r\n }\r\n \r\n // Check chunk queue\r\n if (this.chunkQueue.length > this._resourceLimits.maxChunkQueue) {\r\n violations.push('chunk_queue');\r\n }\r\n \r\n // Check packet buffer\r\n if (this.packetBuffer && this.packetBuffer.size > this._resourceLimits.maxPacketBuffer) {\r\n violations.push('packet_buffer');\r\n }\r\n \r\n // If violations detected, trigger emergency cleanup\r\n if (violations.length > 0) {\r\n this._secureLog('warn', '\u26A0\uFE0F Resource limit violations detected', { violations });\r\n this._emergencyCleanup().catch(error => {\r\n this._secureLog('error', 'Emergency cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Emergency cleanup when resource limits are exceeded\r\n */\r\n async _emergencyCleanup() {\r\n this._secureLog('warn', '\uD83D\uDEA8 EMERGENCY: Resource limits exceeded, performing emergency cleanup');\r\n \r\n try {\r\n // 1. Clear all logs immediately\r\n this._logCounts.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: All logs cleared');\r\n \r\n // 2. Clear message queue\r\n this.messageQueue.length = 0;\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Message queue cleared');\r\n \r\n // 3. Enhanced IV history cleanup\r\n if (this._ivTrackingSystem) {\r\n this._ivTrackingSystem.usedIVs.clear();\r\n this._ivTrackingSystem.ivHistory.clear();\r\n this._ivTrackingSystem.sessionIVs.clear();\r\n this._ivTrackingSystem.collisionCount = 0;\r\n this._ivTrackingSystem.emergencyMode = false;\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: IV tracking system cleared');\r\n }\r\n \r\n // 4. Clear processed message IDs\r\n this.processedMessageIds.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Processed message IDs cleared');\r\n \r\n // 5. Enhanced decoy channels cleanup\r\n if (this.decoyChannels) {\r\n for (const [channelName, timer] of this.decoyTimers) {\r\n if (timer) clearTimeout(timer);\r\n }\r\n this.decoyChannels.clear();\r\n this.decoyTimers.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Decoy channels cleared');\r\n }\r\n \r\n // 6. Enhanced fake traffic cleanup\r\n if (this.fakeTrafficTimer) {\r\n clearTimeout(this.fakeTrafficTimer);\r\n this.fakeTrafficTimer = null;\r\n }\r\n if (this._fakeTrafficMessages) {\r\n this._fakeTrafficMessages.length = 0;\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Fake traffic messages cleared');\r\n }\r\n \r\n // 7. Clear chunk queue\r\n this.chunkQueue.length = 0;\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Chunk queue cleared');\r\n \r\n // 8. Clear packet buffer\r\n if (this.packetBuffer) {\r\n this.packetBuffer.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Packet buffer cleared');\r\n }\r\n \r\n // 9. Enhanced memory cleanup with quantum-resistant patterns\r\n this._secureMemoryManager.isCleaning = true;\r\n this._secureMemoryManager.cleanupQueue.length = 0;\r\n this._secureMemoryManager.memoryStats.lastCleanup = Date.now();\r\n \r\n // Perform natural cleanup without forcing GC\r\n await this._scheduleAsyncCleanup(async () => {\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Starting natural memory cleanup');\r\n \r\n // Natural cleanup cycles with async delays\r\n for (let i = 0; i < 3; i++) {\r\n this._secureLog('info', `\uD83E\uDDF9 Enhanced Emergency: Cleanup cycle ${i + 1}/3`);\r\n \r\n // Allow natural garbage collection between cycles\r\n await this._performNaturalCleanup();\r\n }\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Natural cleanup completed');\r\n }, 0);\r\n \r\n this._secureMemoryManager.isCleaning = false;\r\n \r\n this._secureLog('info', '\u2705 Enhanced emergency cleanup completed successfully');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Enhanced emergency cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n \r\n // Rollback mechanism (simplified)\r\n this._secureMemoryManager.isCleaning = false;\r\n }\r\n }\r\n\r\n /**\r\n * Validate emergency cleanup success\r\n * @param {Object} originalState - Original state before cleanup\r\n * @returns {Object} Validation results\r\n */\r\n _validateEmergencyCleanup(originalState) {\r\n const currentState = {\r\n messageQueueSize: this.messageQueue.length,\r\n processedIdsSize: this.processedMessageIds.size,\r\n packetBufferSize: this.packetBuffer ? this.packetBuffer.size : 0,\r\n ivTrackingSize: this._ivTrackingSystem ? this._ivTrackingSystem.usedIVs.size : 0,\r\n decoyChannelsSize: this.decoyChannels ? this.decoyChannels.size : 0\r\n };\r\n \r\n const validation = {\r\n messageQueueCleared: currentState.messageQueueSize === 0,\r\n processedIdsCleared: currentState.processedIdsSize === 0,\r\n packetBufferCleared: currentState.packetBufferSize === 0,\r\n ivTrackingCleared: currentState.ivTrackingSize === 0,\r\n decoyChannelsCleared: currentState.decoyChannelsSize === 0,\r\n allCleared: (\r\n currentState.messageQueueSize === 0 &&\r\n currentState.processedIdsSize === 0 &&\r\n currentState.packetBufferSize === 0 &&\r\n currentState.ivTrackingSize === 0 &&\r\n currentState.decoyChannelsSize === 0\r\n )\r\n };\r\n \r\n return validation;\r\n }\r\n\r\n /**\r\n * Cleanup resources based on age and usage\r\n */\r\n _cleanupResources() {\r\n const now = Date.now();\r\n \r\n // Clean old processed message IDs (keep only last hour)\r\n if (this.processedMessageIds.size > this._emergencyThresholds.processedMessageIds) {\r\n this.processedMessageIds.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Old processed message IDs cleared');\r\n }\r\n \r\n // Clean old IVs\r\n if (this._ivTrackingSystem) {\r\n this._cleanupOldIVs();\r\n }\r\n \r\n // Clean old keys\r\n this.cleanupOldKeys();\r\n \r\n // Clean rate limiter\r\n if (window.EnhancedSecureCryptoUtils && window.EnhancedSecureCryptoUtils.rateLimiter) {\r\n window.EnhancedSecureCryptoUtils.rateLimiter.cleanup();\r\n }\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Resource cleanup completed');\r\n }\r\n\r\n /**\r\n * Monitor key security (replaces _startKeySecurityMonitoring)\r\n */\r\n _monitorKeySecurity() {\r\n if (this._keyStorageStats.activeKeys > 10) {\r\n this._secureLog('warn', '\u26A0\uFE0F High number of active keys detected. Consider rotation.');\r\n }\r\n \r\n if (Date.now() - (this._keyStorageStats.lastRotation || 0) > 3600000) {\r\n this._rotateKeys();\r\n }\r\n }\r\n\r\n /**\r\n * Send heartbeat message (called by unified scheduler)\r\n */\r\n _sendHeartbeat() {\r\n try {\r\n if (this.isConnected() && this.dataChannel && this.dataChannel.readyState === 'open') {\r\n this.dataChannel.send(JSON.stringify({ \r\n type: EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT, \r\n timestamp: Date.now() \r\n }));\r\n \r\n this._heartbeatConfig.lastHeartbeat = Date.now();\r\n this._secureLog('debug', '\uD83D\uDC93 Heartbeat sent');\r\n }\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Heartbeat failed:', { \r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Comprehensive input validation to prevent DoS and injection attacks\r\n * @param {any} data - Data to validate\r\n * @param {string} context - Context for validation (e.g., 'sendMessage', 'sendSecureMessage')\r\n * @returns {Object} Validation result with isValid and sanitizedData\r\n */\r\n _validateInputData(data, context = 'unknown') {\r\n const validationResult = {\r\n isValid: false,\r\n sanitizedData: null,\r\n errors: [],\r\n warnings: []\r\n };\r\n\r\n try {\r\n // 1. Basic type validation\r\n if (data === null || data === undefined) {\r\n validationResult.errors.push('Data cannot be null or undefined');\r\n return validationResult;\r\n }\r\n\r\n // 2. Size validation for strings\r\n if (typeof data === 'string') {\r\n if (data.length > this._inputValidationLimits.maxStringLength) {\r\n validationResult.errors.push(`String too long: ${data.length} > ${this._inputValidationLimits.maxStringLength}`);\r\n return validationResult;\r\n }\r\n\r\n // 3. Malicious pattern detection for strings\r\n for (const pattern of this._maliciousPatterns) {\r\n if (pattern.test(data)) {\r\n validationResult.errors.push(`Malicious pattern detected: ${pattern.source}`);\r\n this._secureLog('warn', '\uD83D\uDEA8 Malicious pattern detected in input', {\r\n context: context,\r\n pattern: pattern.source,\r\n dataLength: data.length\r\n });\r\n return validationResult;\r\n }\r\n }\r\n\r\n // 4. Sanitize string data\r\n validationResult.sanitizedData = this._sanitizeInputString(data);\r\n validationResult.isValid = true;\r\n return validationResult;\r\n }\r\n\r\n // 5. Object validation\r\n if (typeof data === 'object') {\r\n // Check for circular references\r\n const seen = new WeakSet();\r\n const checkCircular = (obj, path = '') => {\r\n if (obj === null || typeof obj !== 'object') return;\r\n \r\n if (seen.has(obj)) {\r\n validationResult.errors.push(`Circular reference detected at path: ${path}`);\r\n return;\r\n }\r\n \r\n seen.add(obj);\r\n \r\n // Check object depth\r\n if (path.split('.').length > this._inputValidationLimits.maxObjectDepth) {\r\n validationResult.errors.push(`Object too deep: ${path.split('.').length} > ${this._inputValidationLimits.maxObjectDepth}`);\r\n return;\r\n }\r\n\r\n // Check array length\r\n if (Array.isArray(obj) && obj.length > this._inputValidationLimits.maxArrayLength) {\r\n validationResult.errors.push(`Array too long: ${obj.length} > ${this._inputValidationLimits.maxArrayLength}`);\r\n return;\r\n }\r\n\r\n // Recursively check all properties\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n checkCircular(obj[key], path ? `${path}.${key}` : key);\r\n }\r\n }\r\n };\r\n\r\n checkCircular(data);\r\n \r\n if (validationResult.errors.length > 0) {\r\n return validationResult;\r\n }\r\n\r\n // 6. Check total object size\r\n const objectSize = this._calculateObjectSize(data);\r\n if (objectSize > this._inputValidationLimits.maxMessageSize) {\r\n validationResult.errors.push(`Object too large: ${objectSize} bytes > ${this._inputValidationLimits.maxMessageSize} bytes`);\r\n return validationResult;\r\n }\r\n\r\n // 7. Sanitize object data\r\n validationResult.sanitizedData = this._sanitizeInputObject(data);\r\n validationResult.isValid = true;\r\n return validationResult;\r\n }\r\n\r\n // 8. ArrayBuffer validation\r\n if (data instanceof ArrayBuffer) {\r\n if (data.byteLength > this._inputValidationLimits.maxMessageSize) {\r\n validationResult.errors.push(`ArrayBuffer too large: ${data.byteLength} bytes > ${this._inputValidationLimits.maxMessageSize} bytes`);\r\n return validationResult;\r\n }\r\n \r\n validationResult.sanitizedData = data;\r\n validationResult.isValid = true;\r\n return validationResult;\r\n }\r\n\r\n // 9. Other types are not allowed\r\n validationResult.errors.push(`Unsupported data type: ${typeof data}`);\r\n return validationResult;\r\n\r\n } catch (error) {\r\n validationResult.errors.push(`Validation error: ${error.message}`);\r\n this._secureLog('error', '\u274C Input validation failed', {\r\n context: context,\r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n return validationResult;\r\n }\r\n }\r\n\r\n /**\r\n * Calculate approximate object size in bytes\r\n * @param {any} obj - Object to calculate size for\r\n * @returns {number} Size in bytes\r\n */\r\n _calculateObjectSize(obj) {\r\n try {\r\n const jsonString = JSON.stringify(obj);\r\n return new TextEncoder().encode(jsonString).length;\r\n } catch (error) {\r\n // If JSON.stringify fails, estimate size\r\n return 1024 * 1024; // Assume 1MB to be safe\r\n }\r\n }\r\n\r\n /**\r\n * Sanitize string data for input validation\r\n * @param {string} str - String to sanitize\r\n * @returns {string} Sanitized string\r\n */\r\n _sanitizeInputString(str) {\r\n if (typeof str !== 'string') return str;\r\n \r\n // Remove null bytes\r\n str = str.replace(/\\0/g, '');\r\n \r\n // Normalize whitespace\r\n str = str.replace(/\\s+/g, ' ');\r\n \r\n // Trim\r\n str = str.trim();\r\n \r\n return str;\r\n }\r\n\r\n /**\r\n * Sanitize object data for input validation\r\n * @param {any} obj - Object to sanitize\r\n * @returns {any} Sanitized object\r\n */\r\n _sanitizeInputObject(obj) {\r\n if (obj === null || typeof obj !== 'object') return obj;\r\n \r\n if (Array.isArray(obj)) {\r\n return obj.map(item => this._sanitizeInputObject(item));\r\n }\r\n \r\n const sanitized = {};\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n const value = obj[key];\r\n if (typeof value === 'string') {\r\n sanitized[key] = this._sanitizeInputString(value);\r\n } else if (typeof value === 'object') {\r\n sanitized[key] = this._sanitizeInputObject(value);\r\n } else {\r\n sanitized[key] = value;\r\n }\r\n }\r\n }\r\n \r\n return sanitized;\r\n }\r\n\r\n /**\r\n * Rate limiting for message sending\r\n * @param {string} context - Context for rate limiting\r\n * @returns {boolean} true if rate limit allows\r\n */\r\n _checkRateLimit(context = 'message') {\r\n const now = Date.now();\r\n \r\n // Initialize rate limiter if not exists\r\n if (!this._rateLimiter) {\r\n this._rateLimiter = {\r\n messageCount: 0,\r\n lastReset: now,\r\n burstCount: 0,\r\n lastBurstReset: now\r\n };\r\n }\r\n \r\n // Reset counters if needed\r\n if (now - this._rateLimiter.lastReset > 60000) { // 1 minute\r\n this._rateLimiter.messageCount = 0;\r\n this._rateLimiter.lastReset = now;\r\n }\r\n \r\n if (now - this._rateLimiter.lastBurstReset > 1000) { // 1 second\r\n this._rateLimiter.burstCount = 0;\r\n this._rateLimiter.lastBurstReset = now;\r\n }\r\n \r\n // Check burst limit\r\n if (this._rateLimiter.burstCount >= this._inputValidationLimits.rateLimitBurstSize) {\r\n this._secureLog('warn', '\u26A0\uFE0F Rate limit burst exceeded', { context });\r\n return false;\r\n }\r\n \r\n // Check overall rate limit\r\n if (this._rateLimiter.messageCount >= this._inputValidationLimits.rateLimitMessagesPerMinute) {\r\n this._secureLog('warn', '\u26A0\uFE0F Rate limit exceeded', { context });\r\n return false;\r\n }\r\n \r\n // Increment counters\r\n this._rateLimiter.messageCount++;\r\n this._rateLimiter.burstCount++;\r\n \r\n return true;\r\n }\r\n\r\n // ============================================\r\n // SECURE KEY STORAGE MANAGEMENT\r\n // ============================================\r\n\r\n /**\r\n * Initializes the secure key storage\r\n */\r\n _initializeSecureKeyStorage() {\r\n // Initialize master key manager\r\n this._masterKeyManager = new SecureMasterKeyManager();\r\n \r\n // Initialize with the new class and pass master key manager\r\n this._secureKeyStorage = new SecureKeyStorage(this._masterKeyManager);\r\n \r\n // Keep the stats structure for compatibility\r\n this._keyStorageStats = {\r\n totalKeys: 0,\r\n activeKeys: 0,\r\n lastAccess: null,\r\n lastRotation: null,\r\n };\r\n \r\n this._secureLog('info', '\uD83D\uDD10 Enhanced secure key storage initialized');\r\n }\r\n \r\n /**\r\n * Set password callback for master key\r\n */\r\n setMasterKeyPasswordCallback(callback) {\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.setPasswordRequiredCallback(callback);\r\n }\r\n }\r\n \r\n /**\r\n * Set session expired callback for master key\r\n */\r\n setMasterKeySessionExpiredCallback(callback) {\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.setSessionExpiredCallback(callback);\r\n }\r\n }\r\n \r\n /**\r\n * Lock master key manually\r\n */\r\n lockMasterKey() {\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.lock();\r\n }\r\n }\r\n \r\n /**\r\n * Check if master key is unlocked\r\n */\r\n isMasterKeyUnlocked() {\r\n return this._masterKeyManager ? this._masterKeyManager.isUnlocked() : false;\r\n }\r\n \r\n /**\r\n * Get master key session status\r\n */\r\n getMasterKeySessionStatus() {\r\n return this._masterKeyManager ? this._masterKeyManager.getSessionStatus() : null;\r\n }\r\n\r\n // Helper: ensure file transfer system is ready (lazy init on receiver)\r\n async _ensureFileTransferReady() {\r\n try {\r\n // If already initialized \u2014 done\r\n if (this.fileTransferSystem) {\r\n return true;\r\n }\r\n // Requires an open data channel and a verified connection\r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n throw new Error('Data channel not open');\r\n }\r\n if (!this.isVerified) {\r\n throw new Error('Connection not verified');\r\n }\r\n // Initialization\r\n this.initializeFileTransfer();\r\n \r\n // \u041A\u0420\u0418\u0422\u0418\u0427\u0415\u0421\u041A\u041E\u0415 \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u0416\u0434\u0435\u043C \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0442\u0430\u0439\u043C\u0430\u0443\u0442\u043E\u043C\r\n let attempts = 0;\r\n const maxAttempts = 50; // 5 \u0441\u0435\u043A\u0443\u043D\u0434 \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C\r\n while (!this.fileTransferSystem && attempts < maxAttempts) {\r\n await new Promise(r => setTimeout(r, 100));\r\n attempts++;\r\n }\r\n \r\n if (!this.fileTransferSystem) {\r\n throw new Error('File transfer system initialization timeout');\r\n }\r\n \r\n return true;\r\n } catch (e) {\r\n this._secureLog('error', '\u274C _ensureFileTransferReady failed', { \r\n errorType: e?.constructor?.name || 'Unknown',\r\n hasMessage: !!e?.message \r\n });\r\n return false;\r\n }\r\n }\r\n\r\n _getSecureKey(keyId) {\r\n return this._secureKeyStorage.retrieveKey(keyId);\r\n }\r\n\r\n async _setSecureKey(keyId, key) {\r\n if (!(key instanceof CryptoKey)) {\r\n this._secureLog('error', '\u274C Attempt to store non-CryptoKey');\r\n return false;\r\n }\r\n \r\n const success = await this._secureKeyStorage.storeKey(keyId, key, {\r\n version: this.currentKeyVersion,\r\n type: key.algorithm.name\r\n });\r\n \r\n if (success) {\r\n this._secureLog('info', `\uD83D\uDD11 Key ${keyId} stored securely with encryption`);\r\n }\r\n \r\n return success;\r\n }\r\n\r\n /**\r\n * Validates a key value\r\n * @param {CryptoKey} key - Key to validate\r\n * @returns {boolean} true if the key is valid\r\n */\r\n _validateKeyValue(key) {\r\n return key instanceof CryptoKey &&\r\n key.algorithm &&\r\n key.usages &&\r\n key.usages.length > 0;\r\n }\r\n\r\n _secureWipeKeys() {\r\n this._secureKeyStorage.secureWipeAll();\r\n \r\n // Also lock the master key\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.lock();\r\n }\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 All keys securely wiped and encrypted storage cleared');\r\n }\r\n\r\n /**\r\n * Validates key storage state\r\n * @returns {boolean} true if the storage is ready\r\n */\r\n _validateKeyStorage() {\r\n return this._secureKeyStorage instanceof SecureKeyStorage;\r\n }\r\n\r\n /**\r\n * Returns secure key storage statistics\r\n * @returns {object} Storage metrics\r\n */\r\n _getKeyStorageStats() {\r\n const stats = this._secureKeyStorage.getStorageStats();\r\n return {\r\n totalKeysCount: stats.totalKeys,\r\n activeKeysCount: stats.totalKeys,\r\n hasLastAccess: stats.metadata.some(m => m.lastAccessed),\r\n hasLastRotation: !!this._keyStorageStats.lastRotation,\r\n storageType: 'SecureKeyStorage',\r\n timestamp: Date.now()\r\n };\r\n }\r\n\r\n /**\r\n * Performs key rotation in storage\r\n */\r\n _rotateKeys() {\r\n const oldKeys = Array.from(this._secureKeyStorage.keys());\r\n this._secureKeyStorage.clear();\r\n this._keyStorageStats.lastRotation = Date.now();\r\n this._keyStorageStats.activeKeys = 0;\r\n this._secureLog('info', `\uD83D\uDD04 Key rotation completed. ${oldKeys.length} keys rotated`);\r\n }\r\n\r\n /**\r\n * Emergency key wipe (e.g., upon detecting a threat)\r\n */\r\n _emergencyKeyWipe() {\r\n this._secureWipeKeys();\r\n this._secureLog('error', '\uD83D\uDEA8 EMERGENCY: All keys wiped due to security threat');\r\n }\r\n\r\n /**\r\n * Starts key security monitoring\r\n * @deprecated Use unified scheduler instead\r\n */\r\n _startKeySecurityMonitoring() {\r\n // Functionality moved to unified scheduler\r\n this._secureLog('info', '\uD83D\uDD27 Key security monitoring moved to unified scheduler');\r\n }\r\n\r\n\r\n // ============================================\r\n // HELPER METHODS\r\n // ============================================\r\n /**\r\n * Constant-time key validation to prevent timing attacks\r\n * @param {CryptoKey} key - Key to validate\r\n * @returns {boolean} true if key is valid\r\n */\r\n _validateKeyConstantTime(key) {\r\n // Constant-time validation to prevent timing attacks\r\n let isValid = 0;\r\n \r\n // Check if key is CryptoKey instance (constant-time)\r\n try {\r\n const isCryptoKey = key instanceof CryptoKey;\r\n isValid += isCryptoKey ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // Check algorithm (constant-time)\r\n try {\r\n const hasAlgorithm = !!(key && key.algorithm);\r\n isValid += hasAlgorithm ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // Check type (constant-time)\r\n try {\r\n const hasType = !!(key && key.type);\r\n isValid += hasType ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // Check extractable property (constant-time)\r\n try {\r\n const hasExtractable = key && key.extractable !== undefined;\r\n isValid += hasExtractable ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // All checks must pass\r\n return isValid === 4;\r\n }\r\n\r\n /**\r\n * Constant-time key pair validation\r\n * @param {Object} keyPair - Key pair to validate\r\n * @returns {boolean} true if key pair is valid\r\n */\r\n _validateKeyPairConstantTime(keyPair) {\r\n if (!keyPair || typeof keyPair !== 'object') return false;\r\n \r\n const privateKeyValid = this._validateKeyConstantTime(keyPair.privateKey);\r\n const publicKeyValid = this._validateKeyConstantTime(keyPair.publicKey);\r\n \r\n // Constant-time AND operation\r\n return privateKeyValid && publicKeyValid;\r\n }\r\n\r\n /**\r\n * Enhanced secure logging system initialization\r\n */\r\n _initializeSecureLogging() {\r\n // Logging levels\r\n this._logLevels = {\r\n error: 0,\r\n warn: 1, \r\n info: 2,\r\n debug: 3,\r\n trace: 4\r\n };\r\n \r\n // Ultra-strict levels for production\r\n this._currentLogLevel = this._isProductionMode ? \r\n this._logLevels.error : // In production, ONLY critical errors\r\n this._logLevels.info; // In development, up to info\r\n \r\n // Reduced log limits to prevent data accumulation\r\n this._logCounts = new Map();\r\n this._maxLogCount = this._isProductionMode ? 5 : 50; // Reduced limits\r\n \r\n // Hard resource limits to prevent memory leaks\r\n this._resourceLimits = {\r\n maxLogEntries: this._isProductionMode ? 100 : 1000,\r\n maxMessageQueue: 1000,\r\n maxIVHistory: 10000,\r\n maxProcessedMessageIds: 5000,\r\n maxDecoyChannels: 100,\r\n maxFakeTrafficMessages: 500,\r\n maxChunkQueue: 200,\r\n maxPacketBuffer: 1000\r\n };\r\n \r\n // Emergency cleanup thresholds\r\n this._emergencyThresholds = {\r\n logEntries: this._resourceLimits.maxLogEntries * 0.8, // 80%\r\n messageQueue: this._resourceLimits.maxMessageQueue * 0.8,\r\n ivHistory: this._resourceLimits.maxIVHistory * 0.8,\r\n processedMessageIds: this._resourceLimits.maxProcessedMessageIds * 0.8\r\n };\r\n \r\n // Input validation limits to prevent DoS attacks\r\n this._inputValidationLimits = {\r\n maxStringLength: 100000, // 100KB for strings\r\n maxObjectDepth: 10, // Maximum object nesting depth\r\n maxArrayLength: 1000, // Maximum array length\r\n maxMessageSize: 1024 * 1024, // 1MB total message size\r\n maxConcurrentMessages: 10, // Maximum concurrent message processing\r\n rateLimitMessagesPerMinute: 60, // Rate limiting\r\n rateLimitBurstSize: 10 // Burst size for rate limiting\r\n };\r\n \r\n // Malicious pattern detection\r\n this._maliciousPatterns = [\r\n // Enhanced script tag detection that handles edge cases\r\n /]*>[\\s\\S]*?<\\/script\\s*>/gi, // Standard \r\n /]*>[\\s\\S]*?<\\/script\\s+[^>]*>/gi, // \r\n /]*>[\\s\\S]*$/gi, // Malformed script tags without closing\r\n // Additional dangerous tags\r\n /]*>[\\s\\S]*?<\\/iframe\\s*>/gi, // iframe tags\r\n /]*>[\\s\\S]*?<\\/object\\s*>/gi, // object tags\r\n /]*>/gi, // embed tags\r\n /]*>[\\s\\S]*?<\\/applet\\s*>/gi, // applet tags\r\n /]*>[\\s\\S]*?<\\/style\\s*>/gi, // style tags\r\n // Dangerous protocols\r\n /javascript\\s*:/gi, // JavaScript protocol\r\n /data\\s*:/gi, // Data protocol\r\n /vbscript\\s*:/gi, // VBScript protocol\r\n /data:text\\/html/gi, // Data URLs with HTML\r\n /on\\w+\\s*=/gi, // Event handlers\r\n /eval\\s*\\(/gi, // eval() calls\r\n /document\\./gi, // Document object access\r\n /window\\./gi, // Window object access\r\n /localStorage/gi, // LocalStorage access\r\n /sessionStorage/gi, // SessionStorage access\r\n /fetch\\s*\\(/gi, // Fetch API calls\r\n /XMLHttpRequest/gi, // XHR calls\r\n /import\\s*\\(/gi, // Dynamic imports\r\n /require\\s*\\(/gi, // Require calls\r\n /process\\./gi, // Process object access\r\n /global/gi, // Global object access\r\n /__proto__/gi, // Prototype pollution\r\n /constructor/gi, // Constructor access\r\n /prototype/gi, // Prototype access\r\n /toString\\s*\\(/gi, // toString calls\r\n /valueOf\\s*\\(/gi // valueOf calls\r\n ];\r\n\r\n // Comprehensive blacklist with all sensitive patterns\r\n this._absoluteBlacklist = new Set([\r\n // Cryptographic keys\r\n 'encryptionKey', 'macKey', 'metadataKey', 'privateKey', 'publicKey',\r\n 'ecdhKeyPair', 'ecdsaKeyPair', 'peerPublicKey', 'nestedEncryptionKey',\r\n \r\n // Authentication and session data\r\n 'verificationCode', 'sessionSalt', 'keyFingerprint', 'sessionId',\r\n 'authChallenge', 'authProof', 'authToken', 'sessionToken',\r\n \r\n // Credentials and secrets\r\n 'password', 'token', 'secret', 'credential', 'signature',\r\n 'apiKey', 'accessKey', 'secretKey', 'privateKey',\r\n \r\n // Cryptographic materials\r\n 'hash', 'digest', 'nonce', 'iv', 'cipher', 'seed',\r\n 'entropy', 'random', 'salt', 'fingerprint',\r\n \r\n // JWT and session data\r\n 'jwt', 'bearer', 'refreshToken', 'accessToken',\r\n \r\n // File transfer sensitive data\r\n 'fileHash', 'fileSignature', 'transferKey', 'chunkKey'\r\n ]);\r\n\r\n // Minimal whitelist with strict validation\r\n this._safeFieldsWhitelist = new Set([\r\n // Basic status fields\r\n 'timestamp', 'type', 'status', 'state', 'level',\r\n 'isConnected', 'isVerified', 'isInitiator', 'version',\r\n \r\n // Counters and metrics (safe)\r\n 'count', 'total', 'active', 'inactive', 'success', 'failure',\r\n \r\n // Connection states (safe)\r\n 'readyState', 'connectionState', 'iceConnectionState',\r\n \r\n // Feature counts (safe)\r\n 'activeFeaturesCount', 'totalFeatures', 'stage',\r\n \r\n // Error types (safe)\r\n 'errorType', 'errorCode', 'phase', 'attempt'\r\n ]);\r\n \r\n // Initialize security monitoring\r\n this._initializeLogSecurityMonitoring();\r\n \r\n this._secureLog('info', `\uD83D\uDD27 Enhanced secure logging initialized (Production: ${this._isProductionMode})`);\r\n }\r\n\r\n /**\r\n * Initialize security monitoring for logging system\r\n */\r\n _initializeLogSecurityMonitoring() {\r\n // Security monitoring moved to unified scheduler\r\n this._logSecurityViolations = 0;\r\n this._maxLogSecurityViolations = 3;\r\n }\r\n\r\n /**\r\n * Audit logging system security\r\n */\r\n _auditLoggingSystemSecurity() {\r\n let violations = 0;\r\n \r\n // Check for excessive log counts (potential data leakage)\r\n for (const [key, count] of this._logCounts.entries()) {\r\n if (count > this._maxLogCount * 2) {\r\n violations++;\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 LOG SECURITY: Excessive log count detected: ${key}`);\r\n }\r\n }\r\n \r\n // Check for blacklisted patterns in recent logs\r\n const recentLogs = Array.from(this._logCounts.keys());\r\n for (const logKey of recentLogs) {\r\n if (this._containsSensitiveContent(logKey)) {\r\n violations++;\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 LOG SECURITY: Sensitive content in log key: ${logKey}`);\r\n }\r\n }\r\n \r\n // Emergency shutdown if too many violations\r\n this._logSecurityViolations += violations;\r\n if (this._logSecurityViolations >= this._maxLogSecurityViolations) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.('\uD83D\uDEA8 CRITICAL: Logging system disabled due to security violations');\r\n }\r\n }\r\n\r\n _secureLogShim(...args) {\r\n try {\r\n // Validate arguments array\r\n if (!Array.isArray(args) || args.length === 0) {\r\n return;\r\n }\r\n \r\n // Proper destructuring with fallback\r\n const message = args[0];\r\n const restArgs = args.slice(1);\r\n \r\n // Handle different argument patterns\r\n if (restArgs.length === 0) {\r\n this._secureLog('info', String(message || ''));\r\n return;\r\n }\r\n \r\n if (restArgs.length === 1) {\r\n this._secureLog('info', String(message || ''), restArgs[0]);\r\n return;\r\n }\r\n \r\n // Proper object structure for multiple args\r\n this._secureLog('info', String(message || ''), { \r\n additionalArgs: restArgs,\r\n argCount: restArgs.length \r\n });\r\n } catch (error) {\r\n // Better error handling - fallback to original console if available\r\n try {\r\n if (this._originalConsole?.log) {\r\n this._originalConsole.log(...args);\r\n }\r\n } catch (fallbackError) {\r\n // Silent failure to prevent execution disruption\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Setup own logger without touching global console\r\n */\r\n _setupOwnLogger() {\r\n // Create own logger without touching global console\r\n this.logger = {\r\n log: (message, data) => this._secureLog('info', message, data),\r\n info: (message, data) => this._secureLog('info', message, data),\r\n warn: (message, data) => this._secureLog('warn', message, data),\r\n error: (message, data) => this._secureLog('error', message, data),\r\n debug: (message, data) => this._secureLog('debug', message, data)\r\n };\r\n \r\n // In development, log to console; in production, use secure logging only\r\n if (EnhancedSecureWebRTCManager.DEBUG_MODE) {\r\n this._secureLog('info', '\uD83D\uDD12 Own logger created - development mode');\r\n } else {\r\n this._secureLog('info', '\uD83D\uDD12 Own logger created - production mode');\r\n }\r\n }\r\n /**\r\n * Production logging - use own logger with minimal output\r\n */\r\n _setupProductionLogging() {\r\n // In production, own logger becomes minimal\r\n if (this._isProductionMode) {\r\n this.logger = {\r\n log: () => {}, // No-op in production\r\n info: () => {}, // No-op in production\r\n warn: (message, data) => this._secureLog('warn', message, data),\r\n error: (message, data) => this._secureLog('error', message, data),\r\n debug: () => {} // No-op in production\r\n };\r\n \r\n this._secureLog('info', 'Production logging mode activated');\r\n }\r\n }\r\n /**\r\n * Secure logging with enhanced data protection\r\n * @param {string} level - Log level (error, warn, info, debug, trace)\r\n * @param {string} message - Message\r\n * @param {object} data - Optional payload (will be sanitized)\r\n */\r\n _secureLog(level, message, data = null) {\r\n // Pre-sanitization audit to prevent data leakage\r\n if (data && !this._auditLogMessage(message, data)) {\r\n // Log the attempt but block the actual data\r\n this._originalConsole?.error?.('SECURITY: Logging blocked due to potential data leakage');\r\n return;\r\n }\r\n \r\n // Check log level\r\n if (this._logLevels[level] > this._currentLogLevel) {\r\n return;\r\n }\r\n \r\n // Prevent log spam with better key generation\r\n const logKey = `${level}:${message.substring(0, 50)}`;\r\n const currentCount = this._logCounts.get(logKey) || 0;\r\n \r\n if (currentCount >= this._maxLogCount) {\r\n return;\r\n }\r\n \r\n this._logCounts.set(logKey, currentCount + 1);\r\n \r\n // Enhanced sanitization with multiple passes\r\n let sanitizedData = null;\r\n if (data) {\r\n // First pass: basic sanitization\r\n sanitizedData = this._sanitizeLogData(data);\r\n \r\n // Second pass: check if sanitized data still contains sensitive content\r\n if (this._containsSensitiveContent(JSON.stringify(sanitizedData))) {\r\n this._originalConsole?.error?.('ECURITY: Sanitized data still contains sensitive content - blocking log');\r\n return;\r\n }\r\n }\r\n \r\n // Production mode security - only log essential errors\r\n if (this._isProductionMode) {\r\n if (level === 'error') {\r\n // In production, only log error messages without sensitive data\r\n const safeMessage = this._sanitizeString(message);\r\n this._originalConsole?.error?.(safeMessage);\r\n }\r\n // Block all other log levels in production\r\n return;\r\n }\r\n \r\n // Development mode: full logging with sanitized data\r\n const logMethod = this._originalConsole?.[level] || this._originalConsole?.log;\r\n if (sanitizedData) {\r\n logMethod(message, sanitizedData);\r\n } else {\r\n logMethod(message);\r\n }\r\n }\r\n /**\r\n * Enhanced sanitization for log data with multiple security layers\r\n */\r\n _sanitizeLogData(data) {\r\n // Pre-check for sensitive content before processing\r\n if (typeof data === 'string') {\r\n return this._sanitizeString(data);\r\n }\r\n \r\n if (!data || typeof data !== 'object') {\r\n return data;\r\n }\r\n \r\n const sanitized = {};\r\n \r\n for (const [key, value] of Object.entries(data)) {\r\n const lowerKey = key.toLowerCase();\r\n \r\n // Enhanced blacklist with more comprehensive patterns\r\n const blacklistPatterns = [\r\n 'key', 'secret', 'token', 'password', 'credential', 'auth',\r\n 'fingerprint', 'salt', 'signature', 'private', 'encryption',\r\n 'mac', 'metadata', 'session', 'jwt', 'bearer', 'hash',\r\n 'digest', 'nonce', 'iv', 'cipher', 'seed', 'entropy'\r\n ];\r\n \r\n const isBlacklisted = this._absoluteBlacklist.has(key) || \r\n blacklistPatterns.some(pattern => lowerKey.includes(pattern));\r\n \r\n if (isBlacklisted) {\r\n sanitized[key] = '[SENSITIVE_DATA_BLOCKED]';\r\n continue;\r\n }\r\n \r\n // Enhanced whitelist with strict validation\r\n if (this._safeFieldsWhitelist.has(key)) {\r\n // Even whitelisted fields get sanitized if they contain sensitive data\r\n if (typeof value === 'string') {\r\n sanitized[key] = this._sanitizeString(value);\r\n } else {\r\n sanitized[key] = value;\r\n }\r\n continue;\r\n }\r\n \r\n // Enhanced type handling with security checks\r\n if (typeof value === 'boolean' || typeof value === 'number') {\r\n sanitized[key] = value;\r\n } else if (typeof value === 'string') {\r\n sanitized[key] = this._sanitizeString(value);\r\n } else if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\r\n // Don't reveal actual byte lengths for security\r\n sanitized[key] = `[${value.constructor.name}( bytes)]`;\r\n } else if (value && typeof value === 'object') {\r\n // Recursive sanitization with depth limit and security check\r\n try {\r\n sanitized[key] = this._sanitizeLogData(value);\r\n } catch (error) {\r\n sanitized[key] = '[RECURSIVE_SANITIZATION_FAILED]';\r\n }\r\n } else {\r\n sanitized[key] = `[${typeof value}]`;\r\n }\r\n }\r\n \r\n // Final security check on sanitized data\r\n const sanitizedString = JSON.stringify(sanitized);\r\n if (this._containsSensitiveContent(sanitizedString)) {\r\n return { error: 'SANITIZATION_FAILED_SENSITIVE_CONTENT_DETECTED' };\r\n }\r\n \r\n return sanitized;\r\n }\r\n /**\r\n * Enhanced sanitization for strings with comprehensive pattern detection\r\n */\r\n _sanitizeString(str) {\r\n if (typeof str !== 'string' || str.length === 0) {\r\n return str;\r\n }\r\n \r\n // Comprehensive sensitive pattern detection\r\n const sensitivePatterns = [\r\n // Hex patterns (various lengths)\r\n /[a-f0-9]{16,}/i, // 16+ hex chars (covers short keys)\r\n /[a-f0-9]{8,}/i, // 8+ hex chars (covers shorter keys)\r\n \r\n // Base64 patterns (comprehensive)\r\n /[A-Za-z0-9+/]{16,}={0,2}/, // Base64 with padding\r\n /[A-Za-z0-9+/]{12,}/, // Base64 without padding\r\n /[A-Za-z0-9+/=]{10,}/, // Base64-like patterns\r\n \r\n // Base58 patterns (Bitcoin-style)\r\n /[1-9A-HJ-NP-Za-km-z]{16,}/, // Base58 strings\r\n \r\n // Base32 patterns\r\n /[A-Z2-7]{16,}={0,6}/, // Base32 with padding\r\n /[A-Z2-7]{12,}/, // Base32 without padding\r\n \r\n // Custom encoding patterns\r\n /[A-Za-z0-9\\-_]{16,}/, // URL-safe base64 variants\r\n /[A-Za-z0-9\\.\\-_]{16,}/, // JWT-like patterns\r\n \r\n // Long alphanumeric strings (potential keys)\r\n /\\b[A-Za-z0-9]{12,}\\b/, // 12+ alphanumeric chars\r\n /\\b[A-Za-z0-9]{8,}\\b/, // 8+ alphanumeric chars\r\n \r\n // PEM key patterns\r\n /BEGIN\\s+(PRIVATE|PUBLIC|RSA|DSA|EC)\\s+KEY/i,\r\n /END\\s+(PRIVATE|PUBLIC|RSA|DSA|EC)\\s+KEY/i,\r\n \r\n // JWT patterns\r\n /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,\r\n \r\n // API key patterns\r\n /(api[_-]?key|token|secret|password|credential)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n \r\n // UUID patterns\r\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i,\r\n \r\n // Credit cards and SSN (existing patterns)\r\n /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/,\r\n /\\b\\d{3}-\\d{2}-\\d{4}\\b/,\r\n \r\n // Email patterns (more restrictive)\r\n /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/,\r\n \r\n // Crypto-specific patterns\r\n /(fingerprint|hash|digest|signature)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n /(encryption|mac|metadata)[\\s]*key[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n \r\n // Session and auth patterns\r\n /(session|auth|jwt|bearer)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n ];\r\n \r\n // Check for sensitive patterns with early return\r\n for (const pattern of sensitivePatterns) {\r\n if (pattern.test(str)) {\r\n // Always fully hide sensitive data\r\n return '[SENSITIVE_DATA_REDACTED]';\r\n }\r\n }\r\n \r\n // Check for suspicious entropy (high randomness indicates keys)\r\n if (this._hasHighEntropy(str)) {\r\n return '[HIGH_ENTROPY_DATA_REDACTED]';\r\n }\r\n \r\n // Check for suspicious character distributions\r\n if (this._hasSuspiciousDistribution(str)) {\r\n return '[SUSPICIOUS_DATA_REDACTED]';\r\n }\r\n \r\n // For regular strings \u2014 limit length more aggressively\r\n if (str.length > 50) {\r\n return str.substring(0, 20) + '...[TRUNCATED]';\r\n }\r\n \r\n return str;\r\n }\r\n /**\r\n * Enhanced sensitive content detection\r\n */\r\n _containsSensitiveContent(str) {\r\n if (typeof str !== 'string') return false;\r\n \r\n // Use the same comprehensive patterns as _sanitizeString\r\n const sensitivePatterns = [\r\n /[a-f0-9]{16,}/i,\r\n /[A-Za-z0-9+/]{16,}={0,2}/,\r\n /[1-9A-HJ-NP-Za-km-z]{16,}/,\r\n /[A-Z2-7]{16,}={0,6}/,\r\n /\\b[A-Za-z0-9]{12,}\\b/,\r\n /BEGIN\\s+(PRIVATE|PUBLIC|RSA|DSA|EC)\\s+KEY/i,\r\n /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,\r\n /(api[_-]?key|token|secret|password|credential)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n ];\r\n \r\n return sensitivePatterns.some(pattern => pattern.test(str)) ||\r\n this._hasHighEntropy(str) ||\r\n this._hasSuspiciousDistribution(str);\r\n }\r\n\r\n /**\r\n * Check for high entropy strings (likely cryptographic keys)\r\n */\r\n _hasHighEntropy(str) {\r\n if (str.length < 8) return false;\r\n \r\n // Calculate character frequency\r\n const charCount = {};\r\n for (const char of str) {\r\n charCount[char] = (charCount[char] || 0) + 1;\r\n }\r\n \r\n // Calculate Shannon entropy\r\n const length = str.length;\r\n let entropy = 0;\r\n \r\n for (const count of Object.values(charCount)) {\r\n const probability = count / length;\r\n entropy -= probability * Math.log2(probability);\r\n }\r\n \r\n // High entropy (>4.5 bits per character) suggests cryptographic data\r\n return entropy > 4.5;\r\n }\r\n\r\n /**\r\n * Check for suspicious character distributions\r\n */\r\n _hasSuspiciousDistribution(str) {\r\n if (str.length < 8) return false;\r\n \r\n // Check for uniform distribution of hex characters\r\n const hexChars = str.match(/[a-f0-9]/gi) || [];\r\n if (hexChars.length >= str.length * 0.8) {\r\n // If 80%+ are hex chars, likely a key\r\n return true;\r\n }\r\n \r\n // Check for base64-like distribution\r\n const base64Chars = str.match(/[A-Za-z0-9+/=]/g) || [];\r\n if (base64Chars.length >= str.length * 0.9) {\r\n // If 90%+ are base64 chars, likely encoded data\r\n return true;\r\n }\r\n \r\n // Check for very low character diversity (suggests random data)\r\n const uniqueChars = new Set(str).size;\r\n const diversityRatio = uniqueChars / str.length;\r\n \r\n // If diversity is too high (>0.8) for the length, likely random data\r\n if (diversityRatio > 0.8 && str.length > 16) {\r\n return true;\r\n }\r\n \r\n return false;\r\n }\r\n\r\n\r\n // ============================================\r\n // SECURE LOGGING SYSTEM\r\n // ============================================\r\n \r\n /**\r\n * Detects production mode\r\n */\r\n _detectProductionMode() {\r\n // Check various production mode indicators\r\n return (\r\n // Standard env variables\r\n (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') ||\r\n // No debug flags\r\n (!this._debugMode) ||\r\n // Production domains\r\n (window.location.hostname && !window.location.hostname.includes('localhost') && \r\n !window.location.hostname.includes('127.0.0.1') && \r\n !window.location.hostname.includes('.local')) ||\r\n // Minified code (heuristic check)\r\n (typeof window.webpackHotUpdate === 'undefined' && !window.location.search.includes('debug'))\r\n );\r\n }\r\n // ============================================\r\n // FIXED SECURE GLOBAL API\r\n // ============================================\r\n \r\n /**\r\n * Sets up a secure global API with limited access\r\n */\r\n _setupSecureGlobalAPI() {\r\n // Log that we're starting API setup\r\n this._secureLog('info', 'Starting secure global API setup');\r\n \r\n // Create simple public API with safety checks\r\n const secureAPI = {};\r\n \r\n // Only bind methods that exist\r\n if (typeof this.sendMessage === 'function') {\r\n secureAPI.sendMessage = this.sendMessage.bind(this);\r\n }\r\n \r\n // Create simple getConnectionStatus method\r\n secureAPI.getConnectionStatus = () => ({\r\n isConnected: this.isConnected ? this.isConnected() : false,\r\n isVerified: this.isVerified || false,\r\n connectionState: this.peerConnection?.connectionState || 'disconnected'\r\n });\r\n \r\n // Create simple getSecurityStatus method\r\n secureAPI.getSecurityStatus = () => ({\r\n securityLevel: 'maximum',\r\n stage: 'initialized',\r\n activeFeaturesCount: Object.values(this.securityFeatures || {}).filter(Boolean).length\r\n });\r\n \r\n if (typeof this.sendFile === 'function') {\r\n secureAPI.sendFile = this.sendFile.bind(this);\r\n }\r\n \r\n // Create simple getFileTransferStatus method\r\n secureAPI.getFileTransferStatus = () => ({\r\n initialized: !!this.fileTransferSystem,\r\n status: 'ready',\r\n activeTransfers: 0,\r\n receivingTransfers: 0\r\n });\r\n \r\n if (typeof this.disconnect === 'function') {\r\n secureAPI.disconnect = this.disconnect.bind(this);\r\n }\r\n \r\n // Create simple API object with safety checks\r\n const safeGlobalAPI = {\r\n ...secureAPI, // Spread only existing methods\r\n getConfiguration: () => ({\r\n fakeTraffic: this._config.fakeTraffic.enabled,\r\n decoyChannels: this._config.decoyChannels.enabled,\r\n packetPadding: this._config.packetPadding.enabled,\r\n antiFingerprinting: this._config.antiFingerprinting.enabled\r\n }),\r\n emergency: {}\r\n };\r\n \r\n // Only add emergency methods that exist\r\n if (typeof this._emergencyUnlockAllMutexes === 'function') {\r\n safeGlobalAPI.emergency.unlockAllMutexes = this._emergencyUnlockAllMutexes.bind(this);\r\n }\r\n \r\n if (typeof this._emergencyRecoverMutexSystem === 'function') {\r\n safeGlobalAPI.emergency.recoverMutexSystem = this._emergencyRecoverMutexSystem.bind(this);\r\n }\r\n \r\n if (typeof this._emergencyDisableLogging === 'function') {\r\n safeGlobalAPI.emergency.disableLogging = this._emergencyDisableLogging.bind(this);\r\n }\r\n \r\n if (typeof this._resetLoggingSystem === 'function') {\r\n safeGlobalAPI.emergency.resetLogging = this._resetLoggingSystem.bind(this);\r\n }\r\n \r\n // Add file transfer system status\r\n safeGlobalAPI.getFileTransferSystemStatus = () => ({\r\n initialized: !!this.fileTransferSystem,\r\n status: 'ready',\r\n activeTransfers: 0,\r\n receivingTransfers: 0\r\n });\r\n \r\n // Log available methods for debugging\r\n this._secureLog('info', 'API methods available', {\r\n sendMessage: !!secureAPI.sendMessage,\r\n getConnectionStatus: !!secureAPI.getConnectionStatus,\r\n getSecurityStatus: !!secureAPI.getSecurityStatus,\r\n sendFile: !!secureAPI.sendFile,\r\n getFileTransferStatus: !!secureAPI.getFileTransferStatus,\r\n disconnect: !!secureAPI.disconnect,\r\n getConfiguration: !!safeGlobalAPI.getConfiguration,\r\n emergencyMethods: Object.keys(safeGlobalAPI.emergency).length\r\n });\r\n\r\n // Apply Object.freeze to prevent modification\r\n Object.freeze(safeGlobalAPI);\r\n Object.freeze(safeGlobalAPI.emergency);\r\n\r\n // Export API once without monitoring\r\n this._createProtectedGlobalAPI(safeGlobalAPI);\r\n \r\n // Setup minimal protection\r\n this._setupMinimalGlobalProtection();\r\n \r\n // Log that API setup is complete\r\n this._secureLog('info', 'Secure global API setup completed successfully');\r\n }\r\n /**\r\n * Create simple global API export\r\n */\r\n _createProtectedGlobalAPI(safeGlobalAPI) {\r\n // Log that we're creating protected global API\r\n this._secureLog('info', 'Creating protected global API');\r\n \r\n // Simple API export without proxy or monitoring\r\n if (!window.secureBitChat) {\r\n this._exportAPI(safeGlobalAPI);\r\n } else {\r\n this._secureLog('warn', '\u26A0\uFE0F Global API already exists, skipping setup');\r\n }\r\n }\r\n \r\n /**\r\n * Simple API export without monitoring\r\n */\r\n _exportAPI(apiObject) {\r\n // Log that we're exporting API\r\n this._secureLog('info', 'Exporting API to window.secureBitChat');\r\n \r\n // Check if important methods are available\r\n if (!this._importantMethods || !this._importantMethods.defineProperty) {\r\n this._secureLog('error', '\u274C Important methods not available for API export, using fallback');\r\n // Fallback to direct Object.defineProperty\r\n Object.defineProperty(window, 'secureBitChat', {\r\n value: apiObject,\r\n writable: false,\r\n configurable: false,\r\n enumerable: true\r\n });\r\n } else {\r\n // One-time export with immutable properties\r\n this._importantMethods.defineProperty(window, 'secureBitChat', {\r\n value: apiObject,\r\n writable: false,\r\n configurable: false,\r\n enumerable: true\r\n });\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Secure API exported to window.secureBitChat');\r\n }\r\n \r\n /**\r\n * Setup minimal global protection\r\n */\r\n _setupMinimalGlobalProtection() {\r\n // Simple protection without monitoring (methods already stored)\r\n this._protectGlobalAPI();\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Minimal global protection activated');\r\n }\r\n \r\n /**\r\n * Store important methods in closure for local use\r\n */\r\n _storeImportantMethods() {\r\n // Store references to important methods locally\r\n this._importantMethods = {\r\n defineProperty: Object.defineProperty,\r\n getOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,\r\n freeze: Object.freeze,\r\n consoleLog: console.log,\r\n consoleError: console.error,\r\n consoleWarn: console.warn\r\n };\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Important methods stored locally', {\r\n defineProperty: !!this._importantMethods.defineProperty,\r\n getOwnPropertyDescriptor: !!this._importantMethods.getOwnPropertyDescriptor,\r\n freeze: !!this._importantMethods.freeze\r\n });\r\n }\r\n\r\n /**\r\n * Simple protection without monitoring\r\n */\r\n _setupSimpleProtection() {\r\n this._secureLog('info', '\uD83D\uDD12 Simple protection activated - no monitoring');\r\n }\r\n\r\n /**\r\n * No global exposure prevention needed\r\n */\r\n _preventGlobalExposure() {\r\n this._secureLog('info', '\uD83D\uDD12 No global exposure prevention - using secure API export only');\r\n }\r\n /**\r\n * API integrity check - only at initialization\r\n */\r\n _verifyAPIIntegrity() {\r\n try {\r\n if (!window.secureBitChat) {\r\n this._secureLog('error', '\u274C SECURITY ALERT: Secure API has been removed!');\r\n return false;\r\n }\r\n \r\n const requiredMethods = ['sendMessage', 'getConnectionStatus', 'disconnect'];\r\n const missingMethods = requiredMethods.filter(method => \r\n typeof window.secureBitChat[method] !== 'function'\r\n );\r\n \r\n if (missingMethods.length > 0) {\r\n this._secureLog('error', '\u274C SECURITY ALERT: API tampering detected, missing methods:', { errorType: missingMethods?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C SECURITY ALERT: API integrity check failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n // ============================================\r\n // ADDITIONAL SECURITY METHODS\r\n // ============================================\r\n \r\n /**\r\n * Simple global exposure check - only at initialization\r\n */\r\n _auditGlobalExposure() {\r\n // Only check once at initialization, no periodic scanning\r\n this._secureLog('info', '\uD83D\uDD12 Global exposure check completed at initialization');\r\n return [];\r\n }\r\n \r\n /**\r\n * No periodic security audits - only at initialization\r\n */\r\n _startSecurityAudit() {\r\n // Only audit once at initialization, no periodic checks\r\n this._secureLog('info', '\uD83D\uDD12 Security audit completed at initialization - no periodic monitoring');\r\n }\r\n \r\n /**\r\n * Simple global API protection\r\n */\r\n _protectGlobalAPI() {\r\n if (!window.secureBitChat) {\r\n this._secureLog('warn', '\u26A0\uFE0F Global API not found during protection setup');\r\n return;\r\n }\r\n\r\n try {\r\n // Validate API integrity once\r\n if (this._validateAPIIntegrityOnce()) {\r\n this._secureLog('info', '\uD83D\uDD12 Global API protection verified');\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to verify global API protection', { \r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Validate API integrity once at initialization\r\n */\r\n _validateAPIIntegrityOnce() {\r\n try {\r\n // Check if API is properly configured\r\n if (!this._importantMethods || !this._importantMethods.getOwnPropertyDescriptor) {\r\n // Fallback to direct Object.getOwnPropertyDescriptor\r\n const descriptor = Object.getOwnPropertyDescriptor(window, 'secureBitChat');\r\n \r\n if (!descriptor || descriptor.configurable) {\r\n throw new Error('secureBitChat must not be reconfigurable!');\r\n }\r\n } else {\r\n const descriptor = this._importantMethods.getOwnPropertyDescriptor(window, 'secureBitChat');\r\n \r\n if (!descriptor || descriptor.configurable) {\r\n throw new Error('secureBitChat must not be reconfigurable!');\r\n }\r\n }\r\n \r\n this._secureLog('info', '\u2705 API integrity validated');\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C API integrity validation failed', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n return false;\r\n }\r\n }\r\n \r\n /**\r\n * Secure memory wipe for sensitive data\r\n */\r\n _secureWipeMemory(data, context = 'unknown') {\r\n if (!data) return;\r\n \r\n try {\r\n // Different handling for different data types\r\n if (data instanceof ArrayBuffer) {\r\n this._secureWipeArrayBuffer(data, context);\r\n } else if (data instanceof Uint8Array) {\r\n this._secureWipeUint8Array(data, context);\r\n } else if (Array.isArray(data)) {\r\n this._secureWipeArray(data, context);\r\n } else if (typeof data === 'string') {\r\n this._secureWipeString(data, context);\r\n } else if (data instanceof CryptoKey) {\r\n this._secureWipeCryptoKey(data, context);\r\n } else if (typeof data === 'object') {\r\n this._secureWipeObject(data, context);\r\n }\r\n \r\n this._secureMemoryManager.memoryStats.totalCleanups++;\r\n \r\n } catch (error) {\r\n this._secureMemoryManager.memoryStats.failedCleanups++;\r\n this._secureLog('error', '\u274C Secure memory wipe failed', {\r\n context: context,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for ArrayBuffer\r\n */\r\n _secureWipeArrayBuffer(buffer, context) {\r\n if (!buffer || buffer.byteLength === 0) return;\r\n \r\n try {\r\n const view = new Uint8Array(buffer);\r\n \r\n // Overwrite with random data first\r\n crypto.getRandomValues(view);\r\n \r\n // Overwrite with zeros\r\n view.fill(0);\r\n \r\n // Overwrite with ones\r\n view.fill(255);\r\n \r\n // Final zero overwrite\r\n view.fill(0);\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 ArrayBuffer securely wiped', {\r\n context: context,\r\n size: buffer.byteLength\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe ArrayBuffer', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for Uint8Array\r\n */\r\n _secureWipeUint8Array(array, context) {\r\n if (!array || array.length === 0) return;\r\n \r\n try {\r\n // Overwrite with random data first\r\n crypto.getRandomValues(array);\r\n \r\n // Overwrite with zeros\r\n array.fill(0);\r\n \r\n // Overwrite with ones\r\n array.fill(255);\r\n \r\n // Final zero overwrite\r\n array.fill(0);\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Uint8Array securely wiped', {\r\n context: context,\r\n size: array.length\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe Uint8Array', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for arrays\r\n */\r\n _secureWipeArray(array, context) {\r\n if (!Array.isArray(array) || array.length === 0) return;\r\n \r\n try {\r\n // Recursively wipe each element\r\n array.forEach((item, index) => {\r\n if (item !== null && item !== undefined) {\r\n this._secureWipeMemory(item, `${context}[${index}]`);\r\n }\r\n });\r\n \r\n // Fill with nulls\r\n array.fill(null);\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Array securely wiped', {\r\n context: context,\r\n size: array.length\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe array', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * No string wiping - strings are immutable in JS\r\n */\r\n _secureWipeString(str, context) {\r\n // Strings are immutable in JavaScript, no need to wipe\r\n // Just remove the reference\r\n this._secureLog('debug', '\uD83D\uDD12 String reference removed (strings are immutable)', {\r\n context: context,\r\n length: str ? str.length : 0\r\n });\r\n }\r\n \r\n /**\r\n * CryptoKey cleanup - store in WeakMap for proper GC\r\n */\r\n _secureWipeCryptoKey(key, context) {\r\n if (!key || !(key instanceof CryptoKey)) return;\r\n \r\n try {\r\n // Store in WeakMap for proper garbage collection\r\n if (!this._cryptoKeyStorage) {\r\n this._cryptoKeyStorage = new WeakMap();\r\n }\r\n \r\n // Store reference for cleanup tracking\r\n this._cryptoKeyStorage.set(key, {\r\n context: context,\r\n timestamp: Date.now(),\r\n type: key.type\r\n });\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 CryptoKey stored in WeakMap for cleanup', {\r\n context: context,\r\n type: key.type\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to store CryptoKey for cleanup', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for objects\r\n */\r\n _secureWipeObject(obj, context) {\r\n if (!obj || typeof obj !== 'object') return;\r\n \r\n try {\r\n // Recursively wipe all properties\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (value !== null && value !== undefined) {\r\n this._secureWipeMemory(value, `${context}.${key}`);\r\n }\r\n // Set property to null\r\n obj[key] = null;\r\n }\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Object securely wiped', {\r\n context: context,\r\n properties: Object.keys(obj).length\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe object', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure cleanup of cryptographic materials\r\n */\r\n _secureCleanupCryptographicMaterials() {\r\n try {\r\n // Secure wipe of key pairs\r\n if (this.ecdhKeyPair) {\r\n this._secureWipeMemory(this.ecdhKeyPair, 'ecdhKeyPair');\r\n this.ecdhKeyPair = null;\r\n }\r\n \r\n if (this.ecdsaKeyPair) {\r\n this._secureWipeMemory(this.ecdsaKeyPair, 'ecdsaKeyPair');\r\n this.ecdsaKeyPair = null;\r\n }\r\n \r\n // Secure wipe of derived keys\r\n if (this.encryptionKey) {\r\n this._secureWipeMemory(this.encryptionKey, 'encryptionKey');\r\n this.encryptionKey = null;\r\n }\r\n \r\n if (this.macKey) {\r\n this._secureWipeMemory(this.macKey, 'macKey');\r\n this.macKey = null;\r\n }\r\n \r\n if (this.metadataKey) {\r\n this._secureWipeMemory(this.metadataKey, 'metadataKey');\r\n this.metadataKey = null;\r\n }\r\n \r\n if (this.nestedEncryptionKey) {\r\n this._secureWipeMemory(this.nestedEncryptionKey, 'nestedEncryptionKey');\r\n this.nestedEncryptionKey = null;\r\n }\r\n \r\n // Secure wipe of session data\r\n if (this.sessionSalt) {\r\n this._secureWipeMemory(this.sessionSalt, 'sessionSalt');\r\n this.sessionSalt = null;\r\n }\r\n \r\n if (this.sessionId) {\r\n this._secureWipeMemory(this.sessionId, 'sessionId');\r\n this.sessionId = null;\r\n }\r\n \r\n if (this.verificationCode) {\r\n this._secureWipeMemory(this.verificationCode, 'verificationCode');\r\n this.verificationCode = null;\r\n }\r\n \r\n if (this.peerPublicKey) {\r\n this._secureWipeMemory(this.peerPublicKey, 'peerPublicKey');\r\n this.peerPublicKey = null;\r\n }\r\n \r\n if (this.keyFingerprint) {\r\n this._secureWipeMemory(this.keyFingerprint, 'keyFingerprint');\r\n this.keyFingerprint = null;\r\n }\r\n \r\n if (this.connectionId) {\r\n this._secureWipeMemory(this.connectionId, 'connectionId');\r\n this.connectionId = null;\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Cryptographic materials securely cleaned up');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to cleanup cryptographic materials', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Force garbage collection if available\r\n */\r\n async _forceGarbageCollection() {\r\n try {\r\n // Use natural cleanup instead of forcing GC\r\n await this._performNaturalCleanup();\r\n this._secureLog('debug', '\uD83D\uDD12 Natural memory cleanup performed');\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to perform natural cleanup', {\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Perform periodic memory cleanup\r\n */\r\n async _performPeriodicMemoryCleanup() {\r\n try {\r\n this._secureMemoryManager.isCleaning = true;\r\n \r\n // Clean up any remaining sensitive data\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Clean up message queue if it's too large\r\n if (this.messageQueue && this.messageQueue.length > 100) {\r\n const excessMessages = this.messageQueue.splice(0, this.messageQueue.length - 50);\r\n excessMessages.forEach((message, index) => {\r\n this._secureWipeMemory(message, `periodicCleanup[${index}]`);\r\n });\r\n }\r\n \r\n // Clean up processed message IDs if too many\r\n if (this.processedMessageIds && this.processedMessageIds.size > 1000) {\r\n this.processedMessageIds.clear();\r\n }\r\n \r\n // Natural cleanup\r\n await this._forceGarbageCollection();\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Periodic memory cleanup completed');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error during periodic memory cleanup', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n } finally {\r\n this._secureMemoryManager.isCleaning = false;\r\n }\r\n }\r\n \r\n /**\r\n * Create secure error message without information disclosure\r\n */\r\n _createSecureErrorMessage(originalError, context = 'unknown') {\r\n try {\r\n // Categorize error for appropriate handling\r\n const category = this._categorizeError(originalError);\r\n \r\n // Generate safe error message based on category\r\n const safeMessage = this._getSafeErrorMessage(category, context);\r\n \r\n // Log detailed error internally for debugging\r\n this._secureLog('error', 'Internal error occurred', {\r\n category: category,\r\n context: context,\r\n errorType: originalError?.constructor?.name || 'Unknown',\r\n timestamp: Date.now()\r\n });\r\n \r\n // Track error frequency\r\n this._trackErrorFrequency(category);\r\n \r\n return safeMessage;\r\n \r\n } catch (error) {\r\n // Fallback to generic error if error handling fails\r\n this._secureLog('error', 'Error handling failed', {\r\n originalError: originalError?.message || 'Unknown',\r\n handlingError: error.message\r\n });\r\n return 'An unexpected error occurred';\r\n }\r\n }\r\n \r\n /**\r\n * Categorize error for appropriate handling\r\n */\r\n _categorizeError(error) {\r\n if (!error || !error.message) {\r\n return this._secureErrorHandler.errorCategories.UNKNOWN;\r\n }\r\n \r\n const message = error.message.toLowerCase();\r\n \r\n // Cryptographic errors\r\n if (message.includes('crypto') || \r\n message.includes('key') || \r\n message.includes('encrypt') || \r\n message.includes('decrypt') ||\r\n message.includes('sign') ||\r\n message.includes('verify') ||\r\n message.includes('ecdh') ||\r\n message.includes('ecdsa')) {\r\n return this._secureErrorHandler.errorCategories.CRYPTOGRAPHIC;\r\n }\r\n \r\n // Network errors\r\n if (message.includes('network') || \r\n message.includes('connection') || \r\n message.includes('timeout') ||\r\n message.includes('webrtc') ||\r\n message.includes('peer')) {\r\n return this._secureErrorHandler.errorCategories.NETWORK;\r\n }\r\n \r\n // Validation errors\r\n if (message.includes('invalid') || \r\n message.includes('validation') || \r\n message.includes('format') ||\r\n message.includes('type')) {\r\n return this._secureErrorHandler.errorCategories.VALIDATION;\r\n }\r\n \r\n // System errors\r\n if (message.includes('system') || \r\n message.includes('internal') || \r\n message.includes('memory') ||\r\n message.includes('resource')) {\r\n return this._secureErrorHandler.errorCategories.SYSTEM;\r\n }\r\n \r\n return this._secureErrorHandler.errorCategories.UNKNOWN;\r\n }\r\n \r\n /**\r\n * Get safe error message based on category\r\n */\r\n _getSafeErrorMessage(category, context) {\r\n const safeMessages = {\r\n [this._secureErrorHandler.errorCategories.CRYPTOGRAPHIC]: {\r\n 'key_generation': 'Security initialization failed',\r\n 'key_import': 'Security verification failed',\r\n 'key_derivation': 'Security setup failed',\r\n 'encryption': 'Message security failed',\r\n 'decryption': 'Message verification failed',\r\n 'signature': 'Authentication failed',\r\n 'default': 'Security operation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.NETWORK]: {\r\n 'connection': 'Connection failed',\r\n 'timeout': 'Connection timeout',\r\n 'peer': 'Peer connection failed',\r\n 'webrtc': 'Communication failed',\r\n 'default': 'Network operation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.VALIDATION]: {\r\n 'format': 'Invalid data format',\r\n 'type': 'Invalid data type',\r\n 'structure': 'Invalid data structure',\r\n 'default': 'Validation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.SYSTEM]: {\r\n 'memory': 'System resource error',\r\n 'resource': 'System resource unavailable',\r\n 'internal': 'Internal system error',\r\n 'default': 'System operation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.UNKNOWN]: {\r\n 'default': 'An unexpected error occurred'\r\n }\r\n };\r\n \r\n const categoryMessages = safeMessages[category] || safeMessages[this._secureErrorHandler.errorCategories.UNKNOWN];\r\n \r\n // Determine specific context for more precise message\r\n let specificContext = 'default';\r\n if (context.includes('key') || context.includes('crypto')) {\r\n specificContext = category === this._secureErrorHandler.errorCategories.CRYPTOGRAPHIC ? 'key_generation' : 'default';\r\n } else if (context.includes('connection') || context.includes('peer')) {\r\n specificContext = category === this._secureErrorHandler.errorCategories.NETWORK ? 'connection' : 'default';\r\n } else if (context.includes('validation') || context.includes('format')) {\r\n specificContext = category === this._secureErrorHandler.errorCategories.VALIDATION ? 'format' : 'default';\r\n }\r\n \r\n return categoryMessages[specificContext] || categoryMessages.default;\r\n }\r\n \r\n /**\r\n * Track error frequency for security monitoring\r\n */\r\n _trackErrorFrequency(category) {\r\n const now = Date.now();\r\n \r\n // Clean old error counts\r\n if (now - this._secureErrorHandler.lastErrorTime > 60000) { // 1 minute\r\n this._secureErrorHandler.errorCounts.clear();\r\n }\r\n \r\n // Increment error count\r\n const currentCount = this._secureErrorHandler.errorCounts.get(category) || 0;\r\n this._secureErrorHandler.errorCounts.set(category, currentCount + 1);\r\n this._secureErrorHandler.lastErrorTime = now;\r\n \r\n // Check if we're exceeding error threshold\r\n const totalErrors = Array.from(this._secureErrorHandler.errorCounts.values()).reduce((sum, count) => sum + count, 0);\r\n \r\n if (totalErrors > this._secureErrorHandler.errorThreshold) {\r\n this._secureErrorHandler.isInErrorMode = true;\r\n this._secureLog('warn', '\u26A0\uFE0F High error frequency detected - entering error mode', {\r\n totalErrors: totalErrors,\r\n threshold: this._secureErrorHandler.errorThreshold\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Throw secure error without information disclosure\r\n */\r\n _throwSecureError(originalError, context = 'unknown') {\r\n const secureMessage = this._createSecureErrorMessage(originalError, context);\r\n throw new Error(secureMessage);\r\n }\r\n \r\n /**\r\n * Get error handling statistics\r\n */\r\n _getErrorHandlingStats() {\r\n return {\r\n errorCounts: Object.fromEntries(this._secureErrorHandler.errorCounts),\r\n isInErrorMode: this._secureErrorHandler.isInErrorMode,\r\n lastErrorTime: this._secureErrorHandler.lastErrorTime,\r\n errorThreshold: this._secureErrorHandler.errorThreshold\r\n };\r\n }\r\n \r\n /**\r\n * Reset error handling system\r\n */\r\n _resetErrorHandlingSystem() {\r\n this._secureErrorHandler.errorCounts.clear();\r\n this._secureErrorHandler.isInErrorMode = false;\r\n this._secureErrorHandler.lastErrorTime = 0;\r\n \r\n this._secureLog('info', '\uD83D\uDD04 Error handling system reset');\r\n }\r\n \r\n /**\r\n * Get memory management statistics\r\n */\r\n _getMemoryManagementStats() {\r\n return {\r\n totalCleanups: this._secureMemoryManager.memoryStats.totalCleanups,\r\n failedCleanups: this._secureMemoryManager.memoryStats.failedCleanups,\r\n lastCleanup: this._secureMemoryManager.memoryStats.lastCleanup,\r\n isCleaning: this._secureMemoryManager.isCleaning,\r\n queueLength: this._secureMemoryManager.cleanupQueue.length\r\n };\r\n }\r\n \r\n /**\r\n * Validate API integrity and security\r\n */\r\n _validateAPIIntegrity() {\r\n try {\r\n // Check if API exists\r\n if (!window.secureBitChat) {\r\n this._secureLog('error', '\u274C Global API not found during integrity validation');\r\n return false;\r\n }\r\n \r\n // Validate required methods exist\r\n const requiredMethods = ['sendMessage', 'getConnectionStatus', 'getSecurityStatus', 'sendFile', 'disconnect'];\r\n const missingMethods = requiredMethods.filter(method => \r\n !window.secureBitChat[method] || typeof window.secureBitChat[method] !== 'function'\r\n );\r\n \r\n if (missingMethods.length > 0) {\r\n this._secureLog('error', '\u274C Global API integrity validation failed - missing methods', {\r\n missingMethods: missingMethods\r\n });\r\n return false;\r\n }\r\n \r\n // Test method binding integrity\r\n const testContext = { test: true };\r\n const boundMethods = requiredMethods.map(method => {\r\n try {\r\n return window.secureBitChat[method].bind(testContext);\r\n } catch (error) {\r\n return null;\r\n }\r\n });\r\n \r\n const unboundMethods = boundMethods.filter(method => method === null);\r\n if (unboundMethods.length > 0) {\r\n this._secureLog('error', '\u274C Global API integrity validation failed - method binding issues', {\r\n unboundMethods: unboundMethods.length\r\n });\r\n return false;\r\n }\r\n \r\n // Test API immutability\r\n try {\r\n const testProp = '_integrity_test_' + Date.now();\r\n Object.defineProperty(window.secureBitChat, testProp, {\r\n value: 'test',\r\n writable: true,\r\n configurable: true\r\n });\r\n \r\n this._secureLog('error', '\u274C Global API integrity validation failed - API is mutable');\r\n delete window.secureBitChat[testProp];\r\n return false;\r\n \r\n } catch (immutabilityError) {\r\n // This is expected - API should be immutable\r\n this._secureLog('debug', '\u2705 Global API immutability verified');\r\n }\r\n \r\n this._secureLog('info', '\u2705 Global API integrity validation passed');\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Global API integrity validation failed', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n _validateCryptographicSecurity() {\r\n // Check if basic security features are available\r\n const criticalFeatures = ['hasRateLimiting'];\r\n const missingCritical = criticalFeatures.filter(feature => !this.securityFeatures[feature]);\r\n \r\n if (missingCritical.length > 0) {\r\n this._secureLog('error', '\uD83D\uDEA8 CRITICAL: Missing critical rate limiting feature', {\r\n missing: missingCritical,\r\n currentFeatures: this.securityFeatures,\r\n action: 'Rate limiting will be forced enabled'\r\n });\r\n\r\n missingCritical.forEach(feature => {\r\n this.securityFeatures[feature] = true;\r\n this._secureLog('warn', `\u26A0\uFE0F Forced enable critical: ${feature} = true`);\r\n });\r\n }\r\n\r\n // Log current security state\r\n const availableFeatures = Object.keys(this.securityFeatures).filter(f => this.securityFeatures[f]);\r\n const encryptionFeatures = ['hasEncryption', 'hasECDH', 'hasECDSA'].filter(f => this.securityFeatures[f]);\r\n \r\n this._secureLog('info', '\u2705 Cryptographic security validation passed', {\r\n criticalFeatures: criticalFeatures.length,\r\n availableFeatures: availableFeatures.length,\r\n encryptionFeatures: encryptionFeatures.length,\r\n totalSecurityFeatures: availableFeatures.length,\r\n note: 'Encryption features will be enabled after key generation',\r\n currentState: {\r\n hasEncryption: this.securityFeatures.hasEncryption,\r\n hasECDH: this.securityFeatures.hasECDH,\r\n hasECDSA: this.securityFeatures.hasECDSA,\r\n hasRateLimiting: this.securityFeatures.hasRateLimiting\r\n }\r\n });\r\n \r\n return true;\r\n }\r\n\r\n _syncSecurityFeaturesWithTariff() {\r\n // All security features are enabled by default - no payment required\r\n this._secureLog('info', '\u2705 All security features enabled by default - no payment required');\r\n \r\n // Ensure all features are enabled\r\n const allFeatures = [\r\n 'hasEncryption', 'hasECDH', 'hasECDSA', 'hasMutualAuth',\r\n 'hasMetadataProtection', 'hasEnhancedReplayProtection',\r\n 'hasNonExtractableKeys', 'hasRateLimiting', 'hasEnhancedValidation', 'hasPFS',\r\n 'hasNestedEncryption', 'hasPacketPadding', 'hasPacketReordering',\r\n 'hasAntiFingerprinting', 'hasFakeTraffic', 'hasDecoyChannels', 'hasMessageChunking'\r\n ];\r\n \r\n allFeatures.forEach(feature => {\r\n this.securityFeatures[feature] = true;\r\n });\r\n \r\n this._secureLog('info', '\u2705 All security features enabled by default', {\r\n enabledFeatures: Object.keys(this.securityFeatures).filter(f => this.securityFeatures[f]).length,\r\n totalFeatures: Object.keys(this.securityFeatures).length\r\n });\r\n \r\n return;\r\n }\r\n \r\n /**\r\n * Emergency shutdown for critical issues\r\n */\r\n _emergencyShutdown(reason = 'Security breach') {\r\n this._secureLog('error', '\u274C EMERGENCY SHUTDOWN: ${reason}');\r\n \r\n try {\r\n // Clear critical data\r\n this.encryptionKey = null;\r\n this.macKey = null;\r\n this.metadataKey = null;\r\n this.verificationCode = null;\r\n this.keyFingerprint = null;\r\n this.connectionId = null;\r\n \r\n // Close connections\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Clear buffers\r\n this.messageQueue = [];\r\n this.processedMessageIds.clear();\r\n this.packetBuffer.clear();\r\n \r\n // Notify UI\r\n if (this.onStatusChange) {\r\n this.onStatusChange('security_breach');\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Emergency shutdown completed');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error during emergency shutdown:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n _finalizeSecureInitialization() {\r\n this._startKeySecurityMonitoring();\r\n \r\n // Verify API integrity\r\n if (!this._verifyAPIIntegrity()) {\r\n this._secureLog('error', '\u274C Security initialization failed');\r\n return;\r\n }\r\n\r\n this._startSecurityMonitoring();\r\n \r\n // Start periodic log cleanup\r\n setInterval(() => {\r\n this._cleanupLogs();\r\n }, 300000);\r\n \r\n this._secureLog('info', '\u2705 Secure WebRTC Manager initialization completed');\r\n this._secureLog('info', '\uD83D\uDD12 Global exposure protection: Monitoring only, no automatic removal');\r\n }\r\n /**\r\n * Start security monitoring\r\n * @deprecated Use unified scheduler instead\r\n */\r\n _startSecurityMonitoring() {\r\n // All security monitoring moved to unified scheduler\r\n this._secureLog('info', '\uD83D\uDD27 Security monitoring moved to unified scheduler');\r\n }\r\n /**\r\n * Validates connection readiness for sending data\r\n * @param {boolean} throwError - whether to throw on not ready\r\n * @returns {boolean} true if connection is ready\r\n */\r\n _validateConnection(throwError = true) {\r\n const isDataChannelReady = this.dataChannel && this.dataChannel.readyState === 'open';\r\n const isConnectionVerified = this.isVerified;\r\n const isValid = isDataChannelReady && isConnectionVerified;\r\n \r\n if (!isValid && throwError) {\r\n if (!isDataChannelReady) {\r\n throw new Error('Data channel not ready');\r\n }\r\n if (!isConnectionVerified) {\r\n throw new Error('Connection not verified');\r\n }\r\n }\r\n \r\n return isValid;\r\n }\r\n\r\n /**\r\n * Hard gate for traffic blocking without verification\r\n * This method enforces that NO traffic (including system messages and file transfers)\r\n * can pass through without proper cryptographic verification\r\n */\r\n _enforceVerificationGate(operation = 'unknown', throwError = true) {\r\n if (!this.isVerified) {\r\n const errorMessage = `SECURITY VIOLATION: ${operation} blocked - connection not cryptographically verified`;\r\n this._secureLog('error', errorMessage, {\r\n operation: operation,\r\n isVerified: this.isVerified,\r\n hasKeys: !!(this.encryptionKey && this.macKey),\r\n timestamp: Date.now()\r\n });\r\n \r\n if (throwError) {\r\n throw new Error(errorMessage);\r\n }\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Safe method to set isVerified only after cryptographic verification\r\n * This is the ONLY method that should set isVerified = true\r\n */\r\n _setVerifiedStatus(verified, verificationMethod = 'unknown', verificationData = null) {\r\n if (verified) {\r\n // Validate that we have proper cryptographic verification\r\n if (!this.encryptionKey || !this.macKey) {\r\n throw new Error('Cannot set verified=true without encryption keys');\r\n }\r\n \r\n if (!verificationMethod || verificationMethod === 'unknown') {\r\n throw new Error('Cannot set verified=true without specifying verification method');\r\n }\r\n \r\n // Log the verification for audit trail\r\n this._secureLog('info', 'Connection verified through cryptographic verification', {\r\n verificationMethod: verificationMethod,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n keyFingerprint: this.keyFingerprint,\r\n timestamp: Date.now(),\r\n verificationData: verificationData ? 'provided' : 'none'\r\n });\r\n }\r\n \r\n this.isVerified = verified;\r\n \r\n if (verified) {\r\n this.onStatusChange('connected');\r\n } else {\r\n this.onStatusChange('disconnected');\r\n }\r\n }\r\n\r\n /**\r\n * Create AAD (Additional Authenticated Data) for file messages\r\n * This binds file messages to the current session and prevents replay attacks\r\n */\r\n _createFileMessageAAD(messageType, messageData = null) {\r\n // Verify that _createMessageAAD method is available\r\n if (typeof this._createMessageAAD !== 'function') {\r\n throw new Error('_createMessageAAD method is not available in _createFileMessageAAD. Manager may not be fully initialized.');\r\n }\r\n // Use the unified AAD creation method with file message flag\r\n return this._createMessageAAD(messageType, messageData, true);\r\n }\r\n\r\n /**\r\n * Validate AAD for file messages\r\n * This ensures file messages are bound to the correct session\r\n */\r\n _validateFileMessageAAD(aadString, expectedMessageType = null) {\r\n try {\r\n const aad = JSON.parse(aadString);\r\n \r\n // Validate session binding\r\n if (aad.sessionId !== (this.currentSession?.sessionId || 'unknown')) {\r\n throw new Error('AAD sessionId mismatch - possible replay attack');\r\n }\r\n \r\n if (aad.keyFingerprint !== (this.keyFingerprint || 'unknown')) {\r\n throw new Error('AAD keyFingerprint mismatch - possible key substitution attack');\r\n }\r\n \r\n // Validate message type if specified\r\n if (expectedMessageType && aad.messageType !== expectedMessageType) {\r\n throw new Error(`AAD messageType mismatch - expected ${expectedMessageType}, got ${aad.messageType}`);\r\n }\r\n \r\n // Validate timestamp (prevent very old messages)\r\n const now = Date.now();\r\n const messageAge = now - aad.timestamp;\r\n if (messageAge > 1800000) { // 30 minutes for better UX\r\n throw new Error('AAD timestamp too old - possible replay attack');\r\n }\r\n \r\n return aad;\r\n } catch (error) {\r\n this._secureLog('error', 'AAD validation failed', { error: error.message, aadString });\r\n throw new Error(`AAD validation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Extract DTLS fingerprint from SDP\r\n * This is essential for MITM protection\r\n */\r\n _extractDTLSFingerprintFromSDP(sdp) {\r\n try {\r\n if (!sdp || typeof sdp !== 'string') {\r\n throw new Error('Invalid SDP provided');\r\n }\r\n\r\n // Look for a=fingerprint lines in SDP with more flexible regex\r\n const fingerprintRegex = /a=fingerprint:([a-zA-Z0-9-]+)\\s+([A-Fa-f0-9:]+)/g;\r\n const fingerprints = [];\r\n let match;\r\n\r\n while ((match = fingerprintRegex.exec(sdp)) !== null) {\r\n fingerprints.push({\r\n algorithm: match[1].toLowerCase(),\r\n fingerprint: match[2].toLowerCase().replace(/:/g, '')\r\n });\r\n }\r\n\r\n if (fingerprints.length === 0) {\r\n // Try alternative fingerprint format\r\n const altFingerprintRegex = /fingerprint\\s*=\\s*([a-zA-Z0-9-]+)\\s+([A-Fa-f0-9:]+)/gi;\r\n while ((match = altFingerprintRegex.exec(sdp)) !== null) {\r\n fingerprints.push({\r\n algorithm: match[1].toLowerCase(),\r\n fingerprint: match[2].toLowerCase().replace(/:/g, '')\r\n });\r\n }\r\n }\r\n\r\n if (fingerprints.length === 0) {\r\n this._secureLog('warn', 'No DTLS fingerprints found in SDP - this may be normal for some WebRTC implementations', {\r\n sdpLength: sdp.length,\r\n sdpPreview: sdp.substring(0, 200) + '...'\r\n });\r\n throw new Error('No DTLS fingerprints found in SDP');\r\n }\r\n\r\n // Prefer SHA-256 fingerprints\r\n const sha256Fingerprint = fingerprints.find(fp => fp.algorithm === 'sha-256');\r\n if (sha256Fingerprint) {\r\n return sha256Fingerprint.fingerprint;\r\n }\r\n\r\n // Fallback to first available fingerprint\r\n return fingerprints[0].fingerprint;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to extract DTLS fingerprint from SDP', { \r\n error: error.message,\r\n sdpLength: sdp?.length || 0\r\n });\r\n throw new Error(`DTLS fingerprint extraction failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Validate DTLS fingerprint against expected value\r\n * This prevents MITM attacks by ensuring the remote peer has the expected certificate\r\n */\r\n async _validateDTLSFingerprint(receivedFingerprint, expectedFingerprint, context = 'unknown') {\r\n try {\r\n if (!receivedFingerprint || !expectedFingerprint) {\r\n throw new Error('Missing fingerprint for validation');\r\n }\r\n\r\n // Normalize fingerprints (remove colons, convert to lowercase)\r\n const normalizedReceived = receivedFingerprint.toLowerCase().replace(/:/g, '');\r\n const normalizedExpected = expectedFingerprint.toLowerCase().replace(/:/g, '');\r\n\r\n if (normalizedReceived !== normalizedExpected) {\r\n this._secureLog('error', 'DTLS fingerprint mismatch - possible MITM attack', {\r\n context: context,\r\n receivedHash: await this._createSafeLogHash(normalizedReceived, 'dtls_fingerprint'),\r\n expectedHash: await this._createSafeLogHash(normalizedExpected, 'dtls_fingerprint'),\r\n timestamp: Date.now()\r\n });\r\n \r\n throw new Error(`DTLS fingerprint mismatch - possible MITM attack in ${context}`);\r\n }\r\n\r\n this._secureLog('info', 'DTLS fingerprint validation successful', {\r\n context: context,\r\n fingerprintHash: await this._createSafeLogHash(normalizedReceived, 'dtls_fingerprint'),\r\n timestamp: Date.now()\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'DTLS fingerprint validation failed', { \r\n error: error.message, \r\n context: context \r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Compute SAS (Short Authentication String) for MITM protection\r\n * Uses HKDF with DTLS fingerprints to generate a stable 7-digit verification code\r\n * @param {ArrayBuffer|Uint8Array} keyMaterialRaw - Shared secret or key fingerprint data\r\n * @param {string} localFP - Local DTLS fingerprint\r\n * @param {string} remoteFP - Remote DTLS fingerprint\r\n * @returns {Promise} 7-digit SAS code\r\n */\r\n async _computeSAS(keyMaterialRaw, localFP, remoteFP) {\r\n try {\r\n \r\n if (!keyMaterialRaw || !localFP || !remoteFP) {\r\n const missing = [];\r\n if (!keyMaterialRaw) missing.push('keyMaterialRaw');\r\n if (!localFP) missing.push('localFP');\r\n if (!remoteFP) missing.push('remoteFP');\r\n throw new Error(`Missing required parameters for SAS computation: ${missing.join(', ')}`);\r\n }\r\n\r\n const enc = new TextEncoder();\r\n\r\n const salt = enc.encode(\r\n 'webrtc-sas|' + [localFP, remoteFP].sort().join('|')\r\n );\r\n\r\n let keyBuffer;\r\n if (keyMaterialRaw instanceof ArrayBuffer) {\r\n keyBuffer = keyMaterialRaw;\r\n } else if (keyMaterialRaw instanceof Uint8Array) {\r\n keyBuffer = keyMaterialRaw.buffer;\r\n } else if (typeof keyMaterialRaw === 'string') {\r\n // \u0415\u0441\u043B\u0438 \u044D\u0442\u043E \u0441\u0442\u0440\u043E\u043A\u0430 (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, keyFingerprint), \u0434\u0435\u043A\u043E\u0434\u0438\u0440\u0443\u0435\u043C \u0435\u0451\r\n // \u041F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u0435\u043C, \u0447\u0442\u043E \u044D\u0442\u043E hex \u0441\u0442\u0440\u043E\u043A\u0430\r\n const hexString = keyMaterialRaw.replace(/:/g, '').replace(/\\s/g, '');\r\n const bytes = new Uint8Array(hexString.length / 2);\r\n for (let i = 0; i < hexString.length; i += 2) {\r\n bytes[i / 2] = parseInt(hexString.substr(i, 2), 16);\r\n }\r\n keyBuffer = bytes.buffer;\r\n } else {\r\n throw new Error('Invalid keyMaterialRaw type');\r\n }\r\n\r\n // \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C HKDF(SHA-256) \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u044B\u0435 64 \u0431\u0438\u0442\u0430 \u044D\u043D\u0442\u0440\u043E\u043F\u0438\u0438 \u0434\u043B\u044F \u043A\u043E\u0434\u0430\r\n const key = await crypto.subtle.importKey(\r\n 'raw',\r\n keyBuffer,\r\n 'HKDF',\r\n false,\r\n ['deriveBits']\r\n );\r\n\r\n const info = enc.encode('p2p-sas-v1');\r\n const bits = await crypto.subtle.deriveBits(\r\n { name: 'HKDF', hash: 'SHA-256', salt, info },\r\n key,\r\n 64 // 64 \u0431\u0438\u0442\u0430 \u0434\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u0434\u043B\u044F 6\u20137 \u0437\u043D\u0430\u043A\u043E\u0432\r\n );\r\n\r\n const dv = new DataView(bits);\r\n const n = (dv.getUint32(0) ^ dv.getUint32(4)) >>> 0;\r\n \r\n // Use rejection sampling to avoid bias in SAS code generation\r\n let sasValue;\r\n do {\r\n sasValue = crypto.getRandomValues(new Uint32Array(1))[0];\r\n } while (sasValue >= 4294967296 - (4294967296 % 10_000_000));\r\n \r\n const sasCode = String(sasValue % 10_000_000).padStart(7, '0'); \r\n\r\n\r\n this._secureLog('info', 'SAS code computed successfully', {\r\n localFP: localFP.substring(0, 16) + '...',\r\n remoteFP: remoteFP.substring(0, 16) + '...',\r\n sasLength: sasCode.length,\r\n timestamp: Date.now()\r\n });\r\n\r\n return sasCode;\r\n } catch (error) {\r\n this._secureLog('error', 'SAS computation failed', {\r\n error: error.message,\r\n keyMaterialType: typeof keyMaterialRaw,\r\n hasLocalFP: !!localFP,\r\n hasRemoteFP: !!remoteFP,\r\n timestamp: Date.now()\r\n });\r\n throw new Error(`SAS computation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * UTILITY: Decode hex keyFingerprint to Uint8Array for SAS computation\r\n * @param {string} hexString - Hex encoded keyFingerprint (e.g., \"aa:bb:cc:dd\")\r\n * @returns {Uint8Array} Decoded bytes\r\n */\r\n _decodeKeyFingerprint(hexString) {\r\n try {\r\n if (!hexString || typeof hexString !== 'string') {\r\n throw new Error('Invalid hex string provided');\r\n }\r\n\r\n // Use the utility from EnhancedSecureCryptoUtils\r\n return window.EnhancedSecureCryptoUtils.hexToUint8Array(hexString);\r\n } catch (error) {\r\n this._secureLog('error', 'Key fingerprint decoding failed', {\r\n error: error.message,\r\n inputType: typeof hexString,\r\n inputLength: hexString?.length || 0\r\n });\r\n throw new Error(`Key fingerprint decoding failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Emergency key wipe on fingerprint mismatch\r\n * This ensures no sensitive data remains if MITM is detected\r\n */\r\n _emergencyWipeOnFingerprintMismatch(reason = 'DTLS fingerprint mismatch') {\r\n try {\r\n this._secureLog('error', '\uD83D\uDEA8 EMERGENCY: Initiating security wipe due to fingerprint mismatch', {\r\n reason: reason,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Wipe all cryptographic materials\r\n this._secureWipeKeys();\r\n this._secureWipeMemory(this.encryptionKey, 'emergency_wipe');\r\n this._secureWipeMemory(this.macKey, 'emergency_wipe');\r\n this._secureWipeMemory(this.metadataKey, 'emergency_wipe');\r\n \r\n // Wipe ephemeral keys for PFS\r\n this._wipeEphemeralKeys();\r\n \r\n // Hard wipe old keys for PFS\r\n this._hardWipeOldKeys();\r\n\r\n // Reset verification status\r\n this.isVerified = null;\r\n this.verificationCode = null;\r\n this.keyFingerprint = null;\r\n this.connectionId = null;\r\n this.expectedDTLSFingerprint = null;\r\n\r\n // Disconnect immediately\r\n this.disconnect();\r\n\r\n // Notify UI about security breach\r\n this.deliverMessageToUI('\uD83D\uDEA8 SECURITY BREACH: Connection terminated due to fingerprint mismatch. Possible MITM attack detected!', 'system');\r\n\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to perform emergency wipe', { error: error.message });\r\n }\r\n }\r\n\r\n /**\r\n * Set expected DTLS fingerprint via out-of-band channel\r\n * This should be called after receiving the fingerprint through a secure channel\r\n * (e.g., QR code, voice call, in-person exchange, etc.)\r\n */\r\n setExpectedDTLSFingerprint(fingerprint, source = 'out_of_band') {\r\n try {\r\n if (!fingerprint || typeof fingerprint !== 'string') {\r\n throw new Error('Invalid fingerprint provided');\r\n }\r\n\r\n // Normalize fingerprint\r\n const normalizedFingerprint = fingerprint.toLowerCase().replace(/:/g, '');\r\n\r\n // Validate fingerprint format (should be hex string)\r\n if (!/^[a-f0-9]{40,64}$/.test(normalizedFingerprint)) {\r\n throw new Error('Invalid fingerprint format - must be hex string');\r\n }\r\n\r\n this.expectedDTLSFingerprint = normalizedFingerprint;\r\n\r\n this._secureLog('info', 'Expected DTLS fingerprint set via out-of-band channel', {\r\n source: source,\r\n fingerprint: normalizedFingerprint,\r\n timestamp: Date.now()\r\n });\r\n\r\n this.deliverMessageToUI(`\u2705 DTLS fingerprint set via ${source}. MITM protection enabled.`, 'system');\r\n\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to set expected DTLS fingerprint', { error: error.message });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current DTLS fingerprint for out-of-band verification\r\n * This should be shared through a secure channel (QR code, voice, etc.)\r\n */\r\n getCurrentDTLSFingerprint() {\r\n try {\r\n if (!this.expectedDTLSFingerprint) {\r\n throw new Error('No DTLS fingerprint available - connection not established');\r\n }\r\n\r\n return this.expectedDTLSFingerprint;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to get current DTLS fingerprint', { error: error.message });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * DEBUGGING: Temporarily disable strict DTLS validation\r\n * This should only be used for debugging connection issues\r\n */\r\n disableStrictDTLSValidation() {\r\n this.strictDTLSValidation = false;\r\n this._secureLog('warn', '\u26A0\uFE0F Strict DTLS validation disabled - security reduced', {\r\n timestamp: Date.now()\r\n });\r\n this.deliverMessageToUI('\u26A0\uFE0F DTLS validation disabled for debugging', 'system');\r\n }\r\n\r\n /**\r\n * SECURITY: Re-enable strict DTLS validation\r\n */\r\n enableStrictDTLSValidation() {\r\n this.strictDTLSValidation = true;\r\n this._secureLog('info', '\u2705 Strict DTLS validation re-enabled', {\r\n timestamp: Date.now()\r\n });\r\n this.deliverMessageToUI('\u2705 DTLS validation re-enabled', 'system');\r\n }\r\n\r\n /**\r\n * Generate ephemeral ECDH keys for Perfect Forward Secrecy\r\n * This ensures each session has unique, non-persistent keys\r\n */\r\n async _generateEphemeralECDHKeys() {\r\n try {\r\n this._secureLog('info', '\uD83D\uDD11 Generating ephemeral ECDH keys for PFS', {\r\n sessionStartTime: this.sessionStartTime,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Generate new ephemeral ECDH key pair\r\n const ephemeralKeyPair = await window.EnhancedSecureCryptoUtils.generateECDHKeyPair();\r\n \r\n if (!ephemeralKeyPair || !this._validateKeyPairConstantTime(ephemeralKeyPair)) {\r\n throw new Error('Ephemeral ECDH key pair validation failed');\r\n }\r\n\r\n // Store ephemeral keys with session binding\r\n const sessionId = this.currentSession?.sessionId || `session_${Date.now()}`;\r\n this.ephemeralKeyPairs.set(sessionId, {\r\n keyPair: ephemeralKeyPair,\r\n timestamp: Date.now(),\r\n sessionId: sessionId\r\n });\r\n\r\n this._secureLog('info', '\u2705 Ephemeral ECDH keys generated for PFS', {\r\n sessionIdHash: await this._createSafeLogHash(sessionId, 'session_id'),\r\n timestamp: Date.now()\r\n });\r\n\r\n return ephemeralKeyPair;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to generate ephemeral ECDH keys', { error: error.message });\r\n throw new Error(`Ephemeral key generation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Hard wipe old keys for real PFS\r\n * This prevents retrospective decryption attacks\r\n */\r\n async _hardWipeOldKeys() {\r\n try {\r\n this._secureLog('info', '\uD83E\uDDF9 Performing hard wipe of old keys for PFS', {\r\n oldKeysCount: this.oldKeys.size,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Hard wipe all old keys\r\n for (const [version, keySet] of this.oldKeys.entries()) {\r\n if (keySet.encryptionKey) {\r\n this._secureWipeMemory(keySet.encryptionKey, 'pfs_key_wipe');\r\n }\r\n if (keySet.macKey) {\r\n this._secureWipeMemory(keySet.macKey, 'pfs_key_wipe');\r\n }\r\n if (keySet.metadataKey) {\r\n this._secureWipeMemory(keySet.metadataKey, 'pfs_key_wipe');\r\n }\r\n \r\n // Clear references\r\n keySet.encryptionKey = null;\r\n keySet.macKey = null;\r\n keySet.metadataKey = null;\r\n keySet.keyFingerprint = null;\r\n }\r\n\r\n // Clear the oldKeys map completely\r\n this.oldKeys.clear();\r\n\r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n\r\n this._secureLog('info', '\u2705 Hard wipe of old keys completed for PFS', {\r\n timestamp: Date.now()\r\n });\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to perform hard wipe of old keys', { error: error.message });\r\n }\r\n }\r\n\r\n /**\r\n * Wipe ephemeral keys when session ends\r\n * This ensures session-specific keys are destroyed\r\n */\r\n async _wipeEphemeralKeys() {\r\n try {\r\n this._secureLog('info', '\uD83E\uDDF9 Wiping ephemeral keys for PFS', {\r\n ephemeralKeysCount: this.ephemeralKeyPairs.size,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Wipe all ephemeral key pairs\r\n for (const [sessionId, keyData] of this.ephemeralKeyPairs.entries()) {\r\n if (keyData.keyPair?.privateKey) {\r\n this._secureWipeMemory(keyData.keyPair.privateKey, 'ephemeral_key_wipe');\r\n }\r\n if (keyData.keyPair?.publicKey) {\r\n this._secureWipeMemory(keyData.keyPair.publicKey, 'ephemeral_key_wipe');\r\n }\r\n \r\n // Clear references\r\n keyData.keyPair = null;\r\n keyData.timestamp = null;\r\n keyData.sessionId = null;\r\n }\r\n\r\n // Clear the ephemeral keys map\r\n this.ephemeralKeyPairs.clear();\r\n\r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n\r\n this._secureLog('info', '\u2705 Ephemeral keys wiped for PFS', {\r\n timestamp: Date.now()\r\n });\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe ephemeral keys', { error: error.message });\r\n }\r\n }\r\n\r\n /**\r\n * Encrypt file messages with AAD\r\n * This ensures file messages are properly authenticated and bound to session\r\n */\r\n async _encryptFileMessage(messageData, aad) {\r\n try {\r\n if (!this.encryptionKey) {\r\n throw new Error('No encryption key available for file message');\r\n }\r\n\r\n // Convert message to string if it's an object\r\n const messageString = typeof messageData === 'string' ? messageData : JSON.stringify(messageData);\r\n \r\n // Encrypt with AAD using AES-GCM\r\n const encryptedData = await window.EnhancedSecureCryptoUtils.encryptDataWithAAD(\r\n messageString, \r\n this.encryptionKey, \r\n aad\r\n );\r\n \r\n // Create encrypted message wrapper\r\n const encryptedMessage = {\r\n type: 'encrypted_file_message',\r\n encryptedData: encryptedData,\r\n aad: aad,\r\n timestamp: Date.now(),\r\n keyFingerprint: this.keyFingerprint\r\n };\r\n \r\n return JSON.stringify(encryptedMessage);\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to encrypt file message', { error: error.message });\r\n throw new Error(`File message encryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Decrypt file messages with AAD validation\r\n * This ensures file messages are properly authenticated and bound to session\r\n */\r\n async _decryptFileMessage(encryptedMessageString) {\r\n try {\r\n const encryptedMessage = JSON.parse(encryptedMessageString);\r\n \r\n if (encryptedMessage.type !== 'encrypted_file_message') {\r\n throw new Error('Invalid encrypted file message type');\r\n }\r\n \r\n // Validate key fingerprint\r\n if (encryptedMessage.keyFingerprint !== this.keyFingerprint) {\r\n throw new Error('Key fingerprint mismatch in encrypted file message');\r\n }\r\n \r\n // Validate AAD with sequence number\r\n const aad = this._validateMessageAAD(encryptedMessage.aad, 'file_message');\r\n \r\n if (!this.encryptionKey) {\r\n throw new Error('No encryption key available for file message decryption');\r\n }\r\n \r\n // Decrypt with AAD validation\r\n const decryptedData = await window.EnhancedSecureCryptoUtils.decryptDataWithAAD(\r\n encryptedMessage.encryptedData,\r\n this.encryptionKey,\r\n encryptedMessage.aad\r\n );\r\n \r\n return {\r\n decryptedData: decryptedData,\r\n aad: aad\r\n };\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to decrypt file message', { error: error.message });\r\n throw new Error(`File message decryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Validates encryption keys readiness\r\n * @param {boolean} throwError - whether to throw on not ready\r\n * @returns {boolean} true if keys are ready\r\n */\r\n _validateEncryptionKeys(throwError = true) {\r\n const hasAllKeys = !!(this.encryptionKey && this.macKey && this.metadataKey);\r\n \r\n if (!hasAllKeys && throwError) {\r\n throw new Error('Encryption keys not initialized');\r\n }\r\n \r\n return hasAllKeys;\r\n }\r\n\r\n /**\r\n * Checks whether a message is a file-transfer message\r\n * @param {string|object} data - message payload\r\n * @returns {boolean} true if it's a file message\r\n */\r\n _isFileMessage(data) {\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return parsed.type && parsed.type.startsWith('file_');\r\n } catch {\r\n return false;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data.type) {\r\n return data.type.startsWith('file_');\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Checks whether a message is a system message\r\n * @param {string|object} data - message payload \r\n * @returns {boolean} true if it's a system message\r\n */\r\n _isSystemMessage(data) {\r\n const systemTypes = [\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_BOTH_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.PEER_DISCONNECT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.SECURITY_UPGRADE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_SIGNAL,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_READY\r\n ];\r\n\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return systemTypes.includes(parsed.type);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data.type) {\r\n return systemTypes.includes(data.type);\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Checks whether a message is fake traffic\r\n * @param {any} data - message payload\r\n * @returns {boolean} true if it's a fake message\r\n */\r\n _isFakeMessage(data) {\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return parsed.type === EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE || \r\n parsed.isFakeTraffic === true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data !== null) {\r\n return data.type === EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE || \r\n data.isFakeTraffic === true;\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Safely executes an operation with error handling\r\n * @param {Function} operation - operation to execute\r\n * @param {string} errorMessage - error message to log\r\n * @param {any} fallback - default value on error\r\n * @returns {any} operation result or fallback\r\n */\r\n _withErrorHandling(operation, errorMessage, fallback = null) {\r\n try {\r\n return operation();\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C ${errorMessage}:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n return fallback;\r\n }\r\n }\r\n\r\n /**\r\n * Safely executes an async operation with error handling\r\n * @param {Function} operation - async operation\r\n * @param {string} errorMessage - error message to log\r\n * @param {any} fallback - default value on error\r\n * @returns {Promise} operation result or fallback\r\n */\r\n async _withAsyncErrorHandling(operation, errorMessage, fallback = null) {\r\n try {\r\n return await operation();\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C ${errorMessage}:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n return fallback;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Extracts message type from data\r\n * @param {string|object} data - message data\r\n * @returns {string|null} message type or null\r\n */\r\n _getMessageType(data) {\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return parsed.type || null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data !== null) {\r\n return data.type || null;\r\n }\r\n \r\n return null;\r\n }\r\n\r\n /**\r\n * Resets notification flags for a new connection\r\n */\r\n _resetNotificationFlags() {\r\n this.lastSecurityLevelNotification = null;\r\n this.verificationNotificationSent = false;\r\n this.verificationInitiationSent = false;\r\n this.disconnectNotificationSent = false;\r\n this.reconnectionFailedNotificationSent = false;\r\n this.peerDisconnectNotificationSent = false;\r\n this.connectionClosedNotificationSent = false;\r\n this.fakeTrafficDisabledNotificationSent = false;\r\n this.advancedFeaturesDisabledNotificationSent = false;\r\n this.securityUpgradeNotificationSent = false;\r\n this.lastSecurityUpgradeStage = null;\r\n this.securityCalculationNotificationSent = false;\r\n this.lastSecurityCalculationLevel = null;\r\n }\r\n\r\n /**\r\n * Checks whether a message was filtered out\r\n * @param {any} result - processing result\r\n * @returns {boolean} true if filtered\r\n */\r\n _isFilteredMessage(result) {\r\n const filteredResults = Object.values(EnhancedSecureWebRTCManager.FILTERED_RESULTS);\r\n return filteredResults.includes(result);\r\n }\r\n /**\r\n * Enhanced log cleanup with security checks\r\n */\r\n _cleanupLogs() {\r\n // More aggressive cleanup to prevent data accumulation\r\n if (this._logCounts.size > 500) {\r\n this._logCounts.clear();\r\n this._secureLog('debug', '\uD83E\uDDF9 Log counts cleared due to size limit');\r\n }\r\n \r\n // Clean up old log entries to prevent memory leaks\r\n const now = Date.now();\r\n const maxAge = 300000; // 5 minutes\r\n \r\n // Check for suspicious log patterns\r\n let suspiciousCount = 0;\r\n for (const [key, count] of this._logCounts.entries()) {\r\n if (count > 10) {\r\n suspiciousCount++;\r\n }\r\n }\r\n \r\n // Emergency cleanup if too many suspicious patterns\r\n if (suspiciousCount > 20) {\r\n this._logCounts.clear();\r\n this._secureLog('warn', '\uD83D\uDEA8 Emergency log cleanup due to suspicious patterns');\r\n }\r\n \r\n // Reset security violation counter if system is stable\r\n if (this._logSecurityViolations > 0 && suspiciousCount < 5) {\r\n this._logSecurityViolations = Math.max(0, this._logSecurityViolations - 1);\r\n }\r\n \r\n // Clean up old IVs periodically\r\n if (!this._lastIVCleanupTime || Date.now() - this._lastIVCleanupTime > 300000) { // Every 5 minutes\r\n this._cleanupOldIVs();\r\n this._lastIVCleanupTime = Date.now();\r\n }\r\n \r\n // Periodic secure memory cleanup\r\n if (!this._secureMemoryManager.memoryStats.lastCleanup || \r\n Date.now() - this._secureMemoryManager.memoryStats.lastCleanup > 600000) { // Every 10 minutes\r\n // Schedule async cleanup without blocking\r\n this._performPeriodicMemoryCleanup().catch(error => {\r\n this._secureLog('error', 'Periodic cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n this._secureMemoryManager.memoryStats.lastCleanup = Date.now();\r\n }\r\n }\r\n /**\r\n * Secure logging stats with sensitive data protection\r\n */\r\n _getLoggingStats() {\r\n // Only return safe statistics\r\n const stats = {\r\n isProductionMode: this._isProductionMode,\r\n debugMode: this._debugMode,\r\n currentLogLevel: this._currentLogLevel,\r\n logCountsSize: this._logCounts.size,\r\n maxLogCount: this._maxLogCount,\r\n securityViolations: this._logSecurityViolations || 0,\r\n maxSecurityViolations: this._maxLogSecurityViolations || 3,\r\n systemStatus: this._currentLogLevel === -1 ? 'DISABLED' : 'ACTIVE'\r\n };\r\n \r\n // Sanitize any potentially sensitive data\r\n const sanitizedStats = {};\r\n for (const [key, value] of Object.entries(stats)) {\r\n if (typeof value === 'string' && this._containsSensitiveContent(value)) {\r\n sanitizedStats[key] = '[SENSITIVE_DATA_REDACTED]';\r\n } else {\r\n sanitizedStats[key] = value;\r\n }\r\n }\r\n \r\n return sanitizedStats;\r\n }\r\n /**\r\n * Enhanced emergency logging disable with cleanup\r\n */\r\n async _emergencyDisableLogging() {\r\n // Immediately disable all logging levels\r\n this._currentLogLevel = -1;\r\n \r\n // Clear all log data to prevent memory leaks\r\n this._logCounts.clear();\r\n \r\n // Clear any cached sensitive data\r\n if (this._logSecurityViolations) {\r\n this._logSecurityViolations = 0;\r\n }\r\n \r\n // Override _secureLog to a secure no-op\r\n this._secureLog = () => {\r\n // Only allow emergency console errors\r\n if (arguments[0] === 'error' && this._originalConsole?.error) {\r\n this._originalConsole.error('\uD83D\uDEA8 SECURITY: Logging system disabled - potential data exposure prevented');\r\n }\r\n };\r\n \r\n // Store original functions before overriding\r\n this._originalSanitizeString = this._sanitizeString;\r\n this._originalSanitizeLogData = this._sanitizeLogData;\r\n this._originalAuditLogMessage = this._auditLogMessage;\r\n this._originalContainsSensitiveContent = this._containsSensitiveContent;\r\n \r\n // Override all logging methods to prevent bypass\r\n this._sanitizeString = () => '[LOGGING_DISABLED]';\r\n this._sanitizeLogData = () => ({ error: 'LOGGING_DISABLED' });\r\n this._auditLogMessage = () => false;\r\n this._containsSensitiveContent = () => true; // Block everything\r\n \r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n \r\n // Notify about the emergency shutdown\r\n this._originalConsole?.error?.('\uD83D\uDEA8 CRITICAL: Secure logging system disabled due to potential data exposure');\r\n }\r\n\r\n /**\r\n * Reset logging system after emergency shutdown\r\n * Use this function to restore normal logging functionality\r\n */\r\n _resetLoggingSystem() {\r\n this._secureLog('info', '\uD83D\uDD27 Resetting logging system after emergency shutdown');\r\n \r\n // Restore original sanitize functions\r\n this._sanitizeString = this._originalSanitizeString || ((str) => str);\r\n this._sanitizeLogData = this._originalSanitizeLogData || ((data) => data);\r\n this._auditLogMessage = this._originalAuditLogMessage || (() => true);\r\n this._containsSensitiveContent = this._originalContainsSensitiveContent || (() => false);\r\n \r\n // Reset security violation counters\r\n this._logSecurityViolations = 0;\r\n \r\n this._secureLog('info', '\u2705 Logging system reset successfully');\r\n }\r\n /**\r\n * Enhanced audit function for log message security\r\n */\r\n _auditLogMessage(message, data) {\r\n if (!data || typeof data !== 'object') return true;\r\n \r\n // Convert to string and check for sensitive content\r\n const dataString = JSON.stringify(data);\r\n \r\n // Check message itself for sensitive content\r\n if (this._containsSensitiveContent(message)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.('\uD83D\uDEA8 SECURITY BREACH: Sensitive content detected in log message');\r\n return false;\r\n }\r\n \r\n // Check data string for sensitive content\r\n if (this._containsSensitiveContent(dataString)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.('\uD83D\uDEA8 SECURITY BREACH: Sensitive content detected in log data');\r\n return false;\r\n }\r\n \r\n // Enhanced dangerous pattern detection\r\n const dangerousPatterns = [\r\n 'secret', 'token', 'password', 'credential', 'auth',\r\n 'fingerprint', 'salt', 'signature', 'private_key', 'api_key', 'private',\r\n 'encryption', 'mac', 'metadata', 'session', 'jwt', 'bearer',\r\n 'key', 'hash', 'digest', 'nonce', 'iv', 'cipher'\r\n ];\r\n \r\n const dataStringLower = dataString.toLowerCase();\r\n \r\n for (const pattern of dangerousPatterns) {\r\n if (dataStringLower.includes(pattern) && !this._safeFieldsWhitelist.has(pattern)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 SECURITY BREACH: Dangerous pattern detected in log: ${pattern}`);\r\n return false;\r\n }\r\n }\r\n \r\n // Check for high entropy values in data\r\n for (const [key, value] of Object.entries(data)) {\r\n if (typeof value === 'string' && this._hasHighEntropy(value)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 SECURITY BREACH: High entropy value detected in log field: ${key}`);\r\n return false;\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n\r\n initializeFileTransfer() {\r\n try {\r\n this._secureLog('info', '\uD83D\uDD27 Initializing Enhanced Secure File Transfer system...');\r\n\r\n if (this.fileTransferSystem) {\r\n this._secureLog('info', '\u2705 File transfer system already initialized');\r\n return;\r\n }\r\n \r\n // Step-by-step readiness check\r\n const channelReady = !!(this.dataChannel && this.dataChannel.readyState === 'open');\r\n if (!channelReady) {\r\n this._secureLog('warn', '\u26A0\uFE0F Data channel not open, deferring file transfer initialization');\r\n if (this.dataChannel) {\r\n const initHandler = () => {\r\n this._secureLog('info', '\uD83D\uDD04 DataChannel opened, initializing file transfer...');\r\n this.initializeFileTransfer();\r\n };\r\n this.dataChannel.addEventListener('open', initHandler, { once: true });\r\n }\r\n return;\r\n }\r\n\r\n if (!this.isVerified) {\r\n this._secureLog('warn', '\u26A0\uFE0F Connection not verified yet, deferring file transfer initialization');\r\n setTimeout(() => this.initializeFileTransfer(), 500);\r\n return;\r\n }\r\n \r\n // FIX: Clean up previous system if present\r\n if (this.fileTransferSystem) {\r\n this._secureLog('info', '\uD83E\uDDF9 Cleaning up existing file transfer system');\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n // Ensure encryption keys are present\r\n if (!this.encryptionKey || !this.macKey) {\r\n this._secureLog('warn', '\u26A0\uFE0F Encryption keys not ready, deferring file transfer initialization');\r\n setTimeout(() => this.initializeFileTransfer(), 1000);\r\n return;\r\n }\r\n \r\n // IMPORTANT: callback order: (onProgress, onComplete, onError, onFileReceived)\r\n const safeOnComplete = (summary) => {\r\n // Sender: finalize transfer, no Blob handling\r\n try {\r\n this._secureLog('info', '\uD83C\uDFC1 Sender transfer summary', { summary });\r\n // Optionally forward as progress/UI event\r\n if (this.onFileProgress) {\r\n this.onFileProgress({ type: 'complete', ...summary });\r\n }\r\n } catch (e) {\r\n this._secureLog('warn', '\u26A0\uFE0F onComplete handler failed:', { details: e.message });\r\n }\r\n };\r\n\r\n this.fileTransferSystem = new EnhancedSecureFileTransfer(\r\n this,\r\n this.onFileProgress || null,\r\n safeOnComplete,\r\n this.onFileError || null,\r\n this.onFileReceived || null\r\n );\r\n \r\n this._fileTransferActive = true;\r\n \r\n this._secureLog('info', '\u2705 Enhanced Secure File Transfer system initialized successfully');\r\n \r\n // Verify the system is ready\r\n const status = this.fileTransferSystem.getSystemStatus();\r\n this._secureLog('info', '\uD83D\uDD0D File transfer system status after init', { status });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to initialize file transfer system', { errorType: error.constructor.name });\r\n this.fileTransferSystem = null;\r\n this._fileTransferActive = false;\r\n }\r\n }\r\n\r\n // ============================================\r\n // ENHANCED SECURITY INITIALIZATION\r\n // ============================================\r\n\r\n async initializeEnhancedSecurity() {\r\n try {\r\n // Generate nested encryption key\r\n await this.generateNestedEncryptionKey();\r\n \r\n // Initialize decoy channels\r\n if (this.decoyChannelConfig.enabled) {\r\n this.initializeDecoyChannels();\r\n }\r\n \r\n // Start fake traffic generation\r\n if (this.fakeTrafficConfig.enabled) {\r\n this.startFakeTrafficGeneration();\r\n }\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to initialize enhanced security', { errorType: error.constructor.name });\r\n }\r\n }\r\n \r\n // Helper function: unbiased integer in [min, max]\r\n getSafeRandomInt(min, max) {\r\n if (!Number.isInteger(min) || !Number.isInteger(max)) {\r\n throw new Error('getSafeRandomInt requires integer min and max');\r\n }\r\n if (min >= max) {\r\n throw new Error('min must be less than max');\r\n }\r\n \r\n const range = max - min + 1;\r\n const bitsNeeded = Math.ceil(Math.log2(range));\r\n const bytesNeeded = Math.ceil(bitsNeeded / 8);\r\n const mask = (1 << bitsNeeded) - 1;\r\n \r\n let randomValue;\r\n do {\r\n const randomBytes = crypto.getRandomValues(new Uint8Array(bytesNeeded));\r\n\r\n randomValue = 0;\r\n for (let i = 0; i < bytesNeeded; i++) {\r\n randomValue = (randomValue * 256) + randomBytes[i];\r\n }\r\n\r\n randomValue = randomValue & mask;\r\n \r\n } while (randomValue >= range); \r\n\r\n return min + randomValue;\r\n }\r\n\r\n getSafeRandomFloat(minFloat, maxFloat, steps = 1000) {\r\n if (typeof minFloat !== 'number' || typeof maxFloat !== 'number') {\r\n throw new Error('getSafeRandomFloat requires numeric min and max');\r\n }\r\n if (minFloat >= maxFloat) {\r\n throw new Error('minFloat must be less than maxFloat');\r\n }\r\n const randomIndex = this.getSafeRandomInt(0, steps);\r\n \r\n const step = (maxFloat - minFloat) / steps;\r\n\r\n return minFloat + (randomIndex * step);\r\n }\r\n\r\n generateFingerprintMask() {\r\n const mask = {\r\n timingOffset: this.getSafeRandomInt(0, 1500),\r\n sizeVariation: this.getSafeRandomFloat(0.75, 1.25, 1000),\r\n noisePattern: Array.from(crypto.getRandomValues(new Uint8Array(64))),\r\n headerVariations: [\r\n 'X-Client-Version', 'X-Session-ID', 'X-Request-ID', 'X-Timestamp', 'X-Signature',\r\n 'X-Secure', 'X-Encrypted', 'X-Protected', 'X-Safe', 'X-Anonymous', 'X-Private'\r\n ],\r\n noiseIntensity: this.getSafeRandomInt(50, 150),\r\n sizeMultiplier: this.getSafeRandomFloat(0.75, 1.25, 1000),\r\n timingVariation: this.getSafeRandomInt(100, 1100)\r\n };\r\n return mask;\r\n }\r\n\r\n // Security configuration - all features enabled by default\r\n configureSecurityForSession() {\r\n this._secureLog('info', '\uD83D\uDD27 Configuring security - all features enabled by default');\r\n \r\n // All security features are enabled by default - no payment required\r\n this.sessionConstraints = {};\r\n \r\n Object.keys(this.securityFeatures).forEach(feature => {\r\n this.sessionConstraints[feature] = true; // All features enabled\r\n });\r\n \r\n this.applySessionConstraints();\r\n \r\n this._secureLog('info', '\u2705 Security configured - all features enabled', { constraints: this.sessionConstraints });\r\n\r\n if (!this._validateCryptographicSecurity()) {\r\n this._secureLog('error', '\uD83D\uDEA8 CRITICAL: Cryptographic security validation failed after session configuration');\r\n\r\n if (this.onStatusChange) {\r\n this.onStatusChange('security_breach', {\r\n type: 'crypto_security_failure',\r\n message: 'Cryptographic security validation failed after session configuration'\r\n });\r\n }\r\n }\r\n \r\n this.notifySecurityLevel();\r\n \r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, EnhancedSecureWebRTCManager.TIMEOUTS.SECURITY_CALC_DELAY);\r\n }\r\n\r\n // Applying session constraints - all features enabled by default\r\n applySessionConstraints() {\r\n if (!this.sessionConstraints) return;\r\n\r\n // All features are enabled by default - no restrictions\r\n Object.keys(this.sessionConstraints).forEach(feature => {\r\n this.securityFeatures[feature] = true; // All features enabled\r\n \r\n // Enable linked configurations\r\n switch (feature) {\r\n case 'hasFakeTraffic':\r\n this.fakeTrafficConfig.enabled = true;\r\n if (this.isConnected()) {\r\n this.startFakeTrafficGeneration();\r\n }\r\n break;\r\n case 'hasDecoyChannels':\r\n this.decoyChannelConfig.enabled = true;\r\n if (this.isConnected()) {\r\n this.initializeDecoyChannels();\r\n }\r\n break;\r\n case 'hasPacketReordering':\r\n this.reorderingConfig.enabled = true;\r\n break;\r\n case 'hasAntiFingerprinting':\r\n this.antiFingerprintingConfig.enabled = true;\r\n break;\r\n case 'hasMessageChunking':\r\n this.chunkingConfig.enabled = true;\r\n break;\r\n }\r\n });\r\n \r\n this._secureLog('info', '\u2705 All security features enabled by default', {\r\n constraints: this.sessionConstraints,\r\n currentFeatures: this.securityFeatures\r\n });\r\n }\r\n deliverMessageToUI(message, type = 'received') {\r\n try {\r\n // Add debug logs\r\n this._secureLog('debug', '\uD83D\uDCE4 deliverMessageToUI called', {\r\n message: message,\r\n type: type,\r\n messageType: typeof message,\r\n hasOnMessage: !!this.onMessage\r\n });\r\n \r\n // Filter out file-transfer and system messages\r\n if (typeof message === 'object' && message.type) {\r\n const blockedTypes = [\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_START,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_CHUNK,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.CHUNK_CONFIRMATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_COMPLETE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_ERROR,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_BOTH_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.PEER_DISCONNECT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_SIGNAL,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_READY,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.SECURITY_UPGRADE\r\n ];\r\n if (blockedTypes.includes(message.type)) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83D\uDED1 Blocked system/file message from UI: ${message.type}`);\r\n }\r\n return; // do not show in chat\r\n }\r\n }\r\n\r\n // Additional check for string messages containing JSON\r\n if (typeof message === 'string' && message.trim().startsWith('{')) {\r\n try {\r\n const parsedMessage = JSON.parse(message);\r\n if (parsedMessage.type) {\r\n const blockedTypes = [\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_START,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_CHUNK,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.CHUNK_CONFIRMATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_COMPLETE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_ERROR,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_BOTH_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.PEER_DISCONNECT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_SIGNAL,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_READY,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.SECURITY_UPGRADE\r\n ];\r\n if (blockedTypes.includes(parsedMessage.type)) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83D\uDED1 Blocked system/file message from UI (string): ${parsedMessage.type}`);\r\n }\r\n return; // do not show in chat\r\n }\r\n }\r\n } catch (parseError) {\r\n // Not JSON \u2014 fine for plain text messages\r\n }\r\n }\r\n\r\n if (this.onMessage) {\r\n this._secureLog('debug', '\uD83D\uDCE4 Calling this.onMessage callback', { message, type });\r\n this.onMessage(message, type);\r\n } else {\r\n this._secureLog('warn', '\u26A0\uFE0F this.onMessage callback is null or undefined');\r\n }\r\n } catch (err) {\r\n this._secureLog('error', '\u274C Failed to deliver message to UI:', { errorType: err?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n\r\n // Security Level Notification\r\n notifySecurityLevel() {\r\n // Avoid duplicate notifications\r\n if (this.lastSecurityLevelNotification === 'maximum') {\r\n return; // prevent duplication\r\n }\r\n \r\n this.lastSecurityLevelNotification = 'maximum';\r\n \r\n const message = '\uD83D\uDEE1\uFE0F Maximum Security Active - All features enabled';\r\n \r\n if (this.onMessage) {\r\n this.deliverMessageToUI(message, 'system');\r\n }\r\n\r\n // Showing details of active features\r\n if (this.onMessage) {\r\n const activeFeatures = Object.entries(this.securityFeatures)\r\n .filter(([key, value]) => value === true)\r\n .map(([key]) => key.replace('has', '').replace(/([A-Z])/g, ' $1').trim().toLowerCase())\r\n .slice(0, 5); \r\n\r\n this.deliverMessageToUI(`\uD83D\uDD27 Active: ${activeFeatures.join(', ')}...`, 'system');\r\n }\r\n }\r\n\r\n // Cleaning decoy channels\r\n cleanupDecoyChannels() {\r\n // Stopping decoy traffic\r\n for (const [channelName, timer] of this.decoyTimers.entries()) {\r\n clearTimeout(timer);\r\n }\r\n this.decoyTimers.clear();\r\n \r\n // Closing decoy channels\r\n for (const [channelName, channel] of this.decoyChannels.entries()) {\r\n if (channel.readyState === 'open') {\r\n channel.close();\r\n }\r\n }\r\n this.decoyChannels.clear();\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Decoy channels cleaned up');\r\n }\r\n\r\n // ============================================\r\n // 1. NESTED ENCRYPTION LAYER\r\n // ============================================\r\n\r\n async generateNestedEncryptionKey() {\r\n try {\r\n // Generate additional encryption key for nested encryption\r\n this.nestedEncryptionKey = await crypto.subtle.generateKey(\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n \r\n // Generate random IV for nested encryption\r\n // No need for base IV or counter - each encryption gets fresh random IV\r\n // This ensures maximum entropy and prevents IV reuse attacks\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to generate nested encryption key:', { errorType: error?.constructor?.name || 'Unknown' });\r\n throw error;\r\n }\r\n }\r\n\r\n async applyNestedEncryption(data) {\r\n if (!this.nestedEncryptionKey || !this.securityFeatures.hasNestedEncryption) {\r\n return data;\r\n }\r\n\r\n try {\r\n // Generate cryptographically secure IV with reuse prevention\r\n const uniqueIV = this._generateSecureIV(\r\n EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE, \r\n 'nestedEncryption'\r\n );\r\n \r\n // Encrypt data with nested layer\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: uniqueIV },\r\n this.nestedEncryptionKey,\r\n data\r\n );\r\n \r\n // Combine IV and encrypted data\r\n const result = new Uint8Array(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE + encrypted.byteLength);\r\n result.set(uniqueIV, 0);\r\n result.set(new Uint8Array(encrypted), EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE);\r\n \r\n this._secureLog('debug', '\u2705 Nested encryption applied with secure IV', {\r\n ivHash: await this._createSafeLogHash(uniqueIV, 'nestedEncryption'),\r\n ivSize: uniqueIV.length,\r\n dataSize: data.byteLength,\r\n encryptedSize: encrypted.byteLength\r\n });\r\n \r\n return result.buffer;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Nested encryption failed:', { \r\n errorType: error?.constructor?.name || 'Unknown',\r\n errorMessage: error?.message || 'Unknown error'\r\n });\r\n \r\n // If IV generation failed due to emergency mode, disable nested encryption\r\n if (error.message.includes('emergency mode')) {\r\n this.securityFeatures.hasNestedEncryption = false;\r\n this._secureLog('warn', '\u26A0\uFE0F Nested encryption disabled due to IV emergency mode');\r\n }\r\n \r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n async removeNestedEncryption(data) {\r\n if (!this.nestedEncryptionKey || !this.securityFeatures.hasNestedEncryption) {\r\n return data;\r\n }\r\n\r\n // Check that the data is actually encrypted with proper IV size\r\n if (!(data instanceof ArrayBuffer) || data.byteLength < EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE + 16) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Data not encrypted or too short for nested decryption (need IV + minimum encrypted data)');\r\n }\r\n return data;\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n const iv = dataArray.slice(0, EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE);\r\n const encryptedData = dataArray.slice(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE);\r\n \r\n // Check that there is data to decrypt\r\n if (encryptedData.length === 0) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD No encrypted data found');\r\n }\r\n return data;\r\n }\r\n \r\n // Decrypt nested layer\r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: iv },\r\n this.nestedEncryptionKey,\r\n encryptedData\r\n );\r\n \r\n return decrypted;\r\n } catch (error) {\r\n // FIX: Better error handling\r\n if (error.name === 'OperationError') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Data not encrypted with nested encryption, skipping...');\r\n }\r\n } else {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Nested decryption failed:', { details: error.message });\r\n }\r\n }\r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n // ============================================\r\n // 2. PACKET PADDING\r\n // ============================================\r\n\r\n applyPacketPadding(data) {\r\n if (!this.securityFeatures.hasPacketPadding) {\r\n return data;\r\n }\r\n\r\n try {\r\n const originalSize = data.byteLength;\r\n let paddingSize;\r\n \r\n if (this.paddingConfig.useRandomPadding) {\r\n // Generate random padding size\r\n paddingSize = Math.floor(Math.random() * \r\n (this.paddingConfig.maxPadding - this.paddingConfig.minPadding + 1)) + \r\n this.paddingConfig.minPadding;\r\n } else {\r\n // Use fixed padding size\r\n paddingSize = this.paddingConfig.minPadding;\r\n }\r\n \r\n // Generate random padding data\r\n const padding = crypto.getRandomValues(new Uint8Array(paddingSize));\r\n \r\n // Create padded message\r\n const paddedData = new Uint8Array(originalSize + paddingSize + 4);\r\n \r\n // Add original size (4 bytes)\r\n const sizeView = new DataView(paddedData.buffer, 0, 4);\r\n sizeView.setUint32(0, originalSize, false);\r\n \r\n // Add original data\r\n paddedData.set(new Uint8Array(data), 4);\r\n \r\n // Add padding\r\n paddedData.set(padding, 4 + originalSize);\r\n \r\n return paddedData.buffer;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Packet padding failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n removePacketPadding(data) {\r\n if (!this.securityFeatures.hasPacketPadding) {\r\n return data;\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n \r\n // Check for minimum data length (4 bytes for size + minimum 1 byte of data)\r\n if (dataArray.length < 5) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Data too short for packet padding removal, skipping');\r\n }\r\n return data;\r\n }\r\n \r\n // Extract original size (first 4 bytes)\r\n const sizeView = new DataView(dataArray.buffer, 0, 4);\r\n const originalSize = sizeView.getUint32(0, false);\r\n \r\n // Checking the reasonableness of the size\r\n if (originalSize <= 0 || originalSize > dataArray.length - 4) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Invalid packet padding size, skipping removal');\r\n }\r\n return data;\r\n }\r\n \r\n // Extract original data\r\n const originalData = dataArray.slice(4, 4 + originalSize);\r\n \r\n return originalData.buffer;\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C Packet padding removal failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n // ============================================\r\n // 3. FAKE TRAFFIC GENERATION\r\n // ============================================\r\n\r\n startFakeTrafficGeneration() {\r\n if (!this.fakeTrafficConfig.enabled || !this.isConnected()) {\r\n return;\r\n }\r\n\r\n // Prevent multiple fake traffic generators\r\n if (this.fakeTrafficTimer) {\r\n this._secureLog('warn', '\u26A0\uFE0F Fake traffic generation already running');\r\n return;\r\n }\r\n\r\n const sendFakeMessage = async () => {\r\n if (!this.isConnected()) {\r\n this.stopFakeTrafficGeneration();\r\n return;\r\n }\r\n\r\n try {\r\n const fakeMessage = this.generateFakeMessage();\r\n await this.sendFakeMessage(fakeMessage);\r\n \r\n // FIX: Increase intervals to reduce load\r\n const nextInterval = this.fakeTrafficConfig.randomDecoyIntervals ? \r\n this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minInterval, Math.min(this.fakeTrafficConfig.maxInterval, 60000)) : // Cap at 60 seconds\r\n this.fakeTrafficConfig.minInterval;\r\n \r\n // Minimum interval 15 seconds for stability\r\n const safeInterval = Math.max(nextInterval, EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MIN_INTERVAL);\r\n \r\n this.fakeTrafficTimer = setTimeout(sendFakeMessage, safeInterval);\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C Fake traffic generation failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n this.stopFakeTrafficGeneration();\r\n }\r\n };\r\n\r\n // Start fake traffic generation with longer initial delay\r\n // Use a reasonable range for initial delay (5-30 seconds)\r\n const minDelay = EnhancedSecureWebRTCManager.TIMEOUTS.DECOY_INITIAL_DELAY;\r\n const maxDelay = Math.min(this.fakeTrafficConfig.maxInterval, 30000); // Cap at 30 seconds\r\n const initialDelay = this.getUnbiasedRandomInRange(minDelay, maxDelay);\r\n this.fakeTrafficTimer = setTimeout(sendFakeMessage, initialDelay);\r\n }\r\n\r\n stopFakeTrafficGeneration() {\r\n if (this.fakeTrafficTimer) {\r\n clearTimeout(this.fakeTrafficTimer);\r\n this.fakeTrafficTimer = null;\r\n }\r\n }\r\n\r\n generateFakeMessage() {\r\n const patternIndex = this.getUnbiasedRandomInRange(0, this.fakeTrafficConfig.patterns.length - 1);\r\n const pattern = this.fakeTrafficConfig.patterns[patternIndex];\r\n \r\n const size = this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minSize, this.fakeTrafficConfig.maxSize);\r\n \r\n const fakeData = crypto.getRandomValues(new Uint8Array(size));\r\n \r\n return {\r\n type: EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE, \r\n pattern: pattern,\r\n data: Array.from(fakeData).map(b => b.toString(16).padStart(2, '0')).join(''),\r\n timestamp: Date.now(),\r\n size: size,\r\n isFakeTraffic: true, \r\n source: 'fake_traffic_generator',\r\n fakeId: crypto.getRandomValues(new Uint32Array(1))[0].toString(36) \r\n };\r\n }\r\n\r\n // ============================================\r\n // EMERGENCY SHUT-OFF OF ADVANCED FUNCTIONS\r\n // ============================================\r\n\r\n emergencyDisableAdvancedFeatures() {\r\n this._secureLog('error', '\uD83D\uDEA8 Emergency disabling advanced security features due to errors');\r\n \r\n // Disable problematic functions\r\n this.securityFeatures.hasNestedEncryption = false;\r\n this.securityFeatures.hasPacketReordering = false;\r\n this.securityFeatures.hasAntiFingerprinting = false;\r\n \r\n // Disable configurations\r\n this.reorderingConfig.enabled = false;\r\n this.antiFingerprintingConfig.enabled = false;\r\n \r\n // Clear the buffers\r\n this.packetBuffer.clear();\r\n \r\n // Stopping fake traffic\r\n this.emergencyDisableFakeTraffic();\r\n \r\n this._secureLog('info', '\u2705 Advanced features disabled, keeping basic encryption');\r\n \r\n // Check that advanced-features-disabled notification wasn't already sent\r\n if (!this.advancedFeaturesDisabledNotificationSent) {\r\n this.advancedFeaturesDisabledNotificationSent = true;\r\n if (this.onMessage) {\r\n this.deliverMessageToUI('\uD83D\uDEA8 Advanced security features temporarily disabled due to compatibility issues', 'system');\r\n }\r\n }\r\n }\r\n\r\n async sendFakeMessage(fakeMessage) {\r\n if (!this._validateConnection(false)) {\r\n return;\r\n }\r\n\r\n try {\r\n this._secureLog('debug', '\uD83C\uDFAD Sending fake message', {\r\n hasPattern: !!fakeMessage.pattern,\r\n sizeRange: fakeMessage.size > 100 ? 'large' : 'small'\r\n });\r\n \r\n const fakeData = JSON.stringify({\r\n ...fakeMessage,\r\n type: EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE, \r\n isFakeTraffic: true, \r\n timestamp: Date.now()\r\n });\r\n \r\n const fakeBuffer = new TextEncoder().encode(fakeData);\r\n const encryptedFake = await this.applySecurityLayers(fakeBuffer, true);\r\n this.dataChannel.send(encryptedFake);\r\n \r\n this._secureLog('debug', '\uD83C\uDFAD Fake message sent successfully', {\r\n pattern: fakeMessage.pattern\r\n });\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to send fake message', {\r\n error: error.message\r\n });\r\n }\r\n }\r\n\r\ncheckFakeTrafficStatus() {\r\n const status = {\r\n fakeTrafficEnabled: this.securityFeatures.hasFakeTraffic,\r\n fakeTrafficConfigEnabled: this.fakeTrafficConfig.enabled,\r\n timerActive: !!this.fakeTrafficTimer,\r\n patterns: this.fakeTrafficConfig.patterns,\r\n intervals: {\r\n min: this.fakeTrafficConfig.minInterval,\r\n max: this.fakeTrafficConfig.maxInterval\r\n }\r\n };\r\n \r\n if (this._debugMode) {\r\n this._secureLog('info', '\uD83C\uDFAD Fake Traffic Status', { status });\r\n }\r\n return status;\r\n }\r\nemergencyDisableFakeTraffic() {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\uD83D\uDEA8 Emergency disabling fake traffic');\r\n }\r\n \r\n this.securityFeatures.hasFakeTraffic = false;\r\n this.fakeTrafficConfig.enabled = false;\r\n this.stopFakeTrafficGeneration();\r\n \r\n if (this._debugMode) {\r\n this._secureLog('info', '\u2705 Fake traffic disabled');\r\n }\r\n \r\n // Check that fake-traffic-disabled notification wasn't already sent\r\n if (!this.fakeTrafficDisabledNotificationSent) {\r\n this.fakeTrafficDisabledNotificationSent = true;\r\n if (this.onMessage) {\r\n this.deliverMessageToUI('\uD83D\uDEA8 Fake traffic emergency disabled', 'system');\r\n }\r\n }\r\n }\r\n async _applySecurityLayersWithoutMutex(data, isFakeMessage = false) {\r\n try {\r\n let processedData = data;\r\n \r\n if (isFakeMessage) {\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n return processedData;\r\n }\r\n \r\n // Nested Encryption (if enabled)\r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey && processedData instanceof ArrayBuffer) {\r\n processedData = await this.applyNestedEncryption(processedData);\r\n }\r\n \r\n // Packet Reordering (if enabled)\r\n if (this.securityFeatures.hasPacketReordering && this.reorderingConfig?.enabled && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketReordering(processedData);\r\n }\r\n \r\n // Packet Padding (if enabled)\r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketPadding(processedData);\r\n }\r\n \r\n // Anti-Fingerprinting (if enabled)\r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyAntiFingerprinting(processedData);\r\n }\r\n \r\n // Final encryption (if keys are present)\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n \r\n return processedData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in applySecurityLayersWithoutMutex:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data; // Return original data on error\r\n }\r\n}\r\n // ============================================\r\n // 4. MESSAGE CHUNKING\r\n // ============================================\r\n\r\n async processChunkedMessage(chunkData) {\r\n try {\r\n if (!this.chunkingConfig.addChunkHeaders) {\r\n // No headers, treat as regular message\r\n return this.processMessage(chunkData);\r\n }\r\n\r\n const chunkArray = new Uint8Array(chunkData);\r\n if (chunkArray.length < 16) {\r\n // Too small to be a chunk with header\r\n return this.processMessage(chunkData);\r\n }\r\n\r\n // Extract chunk header\r\n const headerView = new DataView(chunkArray.buffer, 0, 16);\r\n const messageId = headerView.getUint32(0, false);\r\n const chunkIndex = headerView.getUint32(4, false);\r\n const totalChunks = headerView.getUint32(8, false);\r\n const chunkSize = headerView.getUint32(12, false);\r\n\r\n // Extract chunk data\r\n const chunk = chunkArray.slice(16, 16 + chunkSize);\r\n\r\n // Store chunk in buffer\r\n if (!this.chunkQueue[messageId]) {\r\n this.chunkQueue[messageId] = {\r\n chunks: new Array(totalChunks),\r\n received: 0,\r\n timestamp: Date.now()\r\n };\r\n }\r\n\r\n const messageBuffer = this.chunkQueue[messageId];\r\n messageBuffer.chunks[chunkIndex] = chunk;\r\n messageBuffer.received++;\r\n\r\n this._secureLog('debug', `\uD83D\uDCE6 Received chunk ${chunkIndex + 1}/${totalChunks} for message ${messageId}`);\r\n\r\n // Check if all chunks received\r\n if (messageBuffer.received === totalChunks) {\r\n // Combine all chunks\r\n const totalSize = messageBuffer.chunks.reduce((sum, chunk) => sum + chunk.length, 0);\r\n const combinedData = new Uint8Array(totalSize);\r\n \r\n let offset = 0;\r\n for (const chunk of messageBuffer.chunks) {\r\n combinedData.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n\r\n // Process complete message\r\n await this.processMessage(combinedData.buffer);\r\n \r\n // Clean up\r\n delete this.chunkQueue[messageId];\r\n \r\n this._secureLog('info', `\uD83D\uDCE6 Chunked message ${messageId} reassembled and processed`);\r\n }\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Chunked message processing failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n // ============================================\r\n // 5. DECOY CHANNELS\r\n // ============================================\r\n\r\n initializeDecoyChannels() {\r\n if (!this.decoyChannelConfig.enabled || !this.peerConnection) {\r\n return;\r\n }\r\n\r\n // Prevent multiple initializations\r\n if (this.decoyChannels.size > 0) {\r\n this._secureLog('warn', '\u26A0\uFE0F Decoy channels already initialized, skipping...');\r\n return;\r\n }\r\n\r\n try {\r\n const numDecoyChannels = Math.min(\r\n this.decoyChannelConfig.maxDecoyChannels,\r\n this.decoyChannelConfig.decoyChannelNames.length\r\n );\r\n\r\n for (let i = 0; i < numDecoyChannels; i++) {\r\n const channelName = this.decoyChannelConfig.decoyChannelNames[i];\r\n const decoyChannel = this.peerConnection.createDataChannel(channelName, {\r\n ordered: Math.random() > 0.5,\r\n maxRetransmits: Math.floor(Math.random() * 3)\r\n });\r\n\r\n this.setupDecoyChannel(decoyChannel, channelName);\r\n this.decoyChannels.set(channelName, decoyChannel);\r\n }\r\n\r\n if (this._debugMode) {\r\n this._secureLog('info', `\uD83C\uDFAD Initialized ${numDecoyChannels} decoy channels`);\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C Failed to initialize decoy channels:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n }\r\n\r\n setupDecoyChannel(channel, channelName) {\r\n channel.onopen = () => {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Decoy channel \"${channelName}\" opened`);\r\n }\r\n this.startDecoyTraffic(channel, channelName);\r\n };\r\n\r\n channel.onmessage = (event) => {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Received decoy message on \"${channelName}\": ${event.data?.length || 'undefined'} bytes`);\r\n }\r\n };\r\n\r\n channel.onclose = () => {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Decoy channel \"${channelName}\" closed`);\r\n }\r\n this.stopDecoyTraffic(channelName);\r\n };\r\n\r\n channel.onerror = (error) => {\r\n if (this._debugMode) {\r\n this._secureLog('error', `\u274C Decoy channel \"${channelName}\" error`, { error: error.message });\r\n }\r\n };\r\n }\r\n\r\n startDecoyTraffic(channel, channelName) {\r\n const sendDecoyData = async () => {\r\n if (channel.readyState !== 'open') {\r\n return;\r\n }\r\n\r\n try {\r\n const decoyData = this.generateDecoyData(channelName);\r\n channel.send(decoyData);\r\n \r\n const interval = this.decoyChannelConfig.randomDecoyIntervals ?\r\n Math.random() * 15000 + 10000 : \r\n 20000; \r\n \r\n this.decoyTimers.set(channelName, setTimeout(() => sendDecoyData(), interval));\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', `\u274C Failed to send decoy data on \"${channelName}\"`, { error: error.message });\r\n }\r\n }\r\n };\r\n\r\n const initialDelay = Math.random() * 10000 + 5000; \r\n this.decoyTimers.set(channelName, setTimeout(() => sendDecoyData(), initialDelay));\r\n }\r\n\r\n stopDecoyTraffic(channelName) {\r\n const timer = this.decoyTimers.get(channelName);\r\n if (timer) {\r\n clearTimeout(timer);\r\n this.decoyTimers.delete(channelName);\r\n }\r\n }\r\n\r\n generateDecoyData(channelName) {\r\n const decoyTypes = {\r\n 'sync': () => JSON.stringify({\r\n type: 'sync',\r\n timestamp: Date.now(),\r\n sequence: Math.floor(Math.random() * 1000),\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(32)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'status': () => JSON.stringify({\r\n type: 'status',\r\n status: ['online', 'away', 'busy'][Math.floor(Math.random() * 3)],\r\n uptime: Math.floor(Math.random() * 3600),\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(16)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'heartbeat': () => JSON.stringify({\r\n type: 'heartbeat',\r\n timestamp: Date.now(),\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(24)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'metrics': () => JSON.stringify({\r\n type: 'metrics',\r\n cpu: Math.random() * 100,\r\n memory: Math.random() * 100,\r\n network: Math.random() * 1000,\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(20)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'debug': () => JSON.stringify({\r\n type: 'debug',\r\n level: ['info', 'warn', 'error'][Math.floor(Math.random() * 3)],\r\n message: 'Debug message',\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(28)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n })\r\n };\r\n\r\n return decoyTypes[channelName] ? decoyTypes[channelName]() : \r\n Array.from(crypto.getRandomValues(new Uint8Array(64)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n // ============================================\r\n // 6. PACKET REORDERING PROTECTION\r\n // ============================================\r\n\r\n addReorderingHeaders(data) {\r\n if (!this.reorderingConfig.enabled) {\r\n return data;\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n const headerSize = this.reorderingConfig.useTimestamps ? 12 : 8;\r\n const header = new ArrayBuffer(headerSize);\r\n const headerView = new DataView(header);\r\n\r\n // Add sequence number\r\n if (this.reorderingConfig.useSequenceNumbers) {\r\n headerView.setUint32(0, this.sequenceNumber++, false);\r\n }\r\n\r\n // Add timestamp\r\n if (this.reorderingConfig.useTimestamps) {\r\n headerView.setUint32(4, Date.now(), false);\r\n }\r\n\r\n // Add data size\r\n headerView.setUint32(this.reorderingConfig.useTimestamps ? 8 : 4, dataArray.length, false);\r\n\r\n // Combine header and data\r\n const result = new Uint8Array(headerSize + dataArray.length);\r\n result.set(new Uint8Array(header), 0);\r\n result.set(dataArray, headerSize);\r\n\r\n return result.buffer;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to add reordering headers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }\r\n\r\n async processReorderedPacket(data) {\r\n if (!this.reorderingConfig.enabled) {\r\n return this.processMessage(data);\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n const headerSize = this.reorderingConfig.useTimestamps ? 12 : 8;\r\n\r\n if (dataArray.length < headerSize) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Data too short for reordering headers, processing directly');\r\n }\r\n return this.processMessage(data);\r\n }\r\n\r\n const headerView = new DataView(dataArray.buffer, 0, headerSize);\r\n let sequence = 0;\r\n let timestamp = 0;\r\n let dataSize = 0;\r\n\r\n if (this.reorderingConfig.useSequenceNumbers) {\r\n sequence = headerView.getUint32(0, false);\r\n }\r\n\r\n if (this.reorderingConfig.useTimestamps) {\r\n timestamp = headerView.getUint32(4, false);\r\n }\r\n\r\n dataSize = headerView.getUint32(this.reorderingConfig.useTimestamps ? 8 : 4, false);\r\n\r\n if (dataSize > dataArray.length - headerSize || dataSize <= 0) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Invalid reordered packet data size, processing directly');\r\n }\r\n return this.processMessage(data);\r\n }\r\n\r\n const actualData = dataArray.slice(headerSize, headerSize + dataSize);\r\n\r\n try {\r\n const textData = new TextDecoder().decode(actualData);\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Reordered fake message: ${content.pattern || 'unknown'}`);\r\n }\r\n return; \r\n }\r\n } catch (e) {\r\n\r\n }\r\n\r\n this.packetBuffer.set(sequence, {\r\n data: actualData.buffer,\r\n timestamp: timestamp || Date.now()\r\n });\r\n\r\n await this.processOrderedPackets();\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to process reordered packet:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return this.processMessage(data);\r\n }\r\n}\r\n\r\n// ============================================\r\n// IMPROVED PROCESSORDEREDPACKETS with filtering\r\n// ============================================\r\n\r\nasync processOrderedPackets() {\r\n const now = Date.now();\r\n const timeout = this.reorderingConfig.reorderTimeout;\r\n\r\n while (true) {\r\n const nextSequence = this.lastProcessedSequence + 1;\r\n const packet = this.packetBuffer.get(nextSequence);\r\n\r\n if (!packet) {\r\n const oldestPacket = this.findOldestPacket();\r\n if (oldestPacket && (now - oldestPacket.timestamp) > timeout) {\r\n this._secureLog('warn', '\u26A0\uFE0F Packet ${oldestPacket.sequence} timed out, processing out of order');\r\n \r\n try {\r\n const textData = new TextDecoder().decode(oldestPacket.data);\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Timed out fake message: ${content.pattern || 'unknown'}`);\r\n this.packetBuffer.delete(oldestPacket.sequence);\r\n this.lastProcessedSequence = oldestPacket.sequence;\r\n continue; \r\n }\r\n } catch (e) {\r\n }\r\n \r\n await this.processMessage(oldestPacket.data);\r\n this.packetBuffer.delete(oldestPacket.sequence);\r\n this.lastProcessedSequence = oldestPacket.sequence;\r\n } else {\r\n break; \r\n }\r\n } else {\r\n try {\r\n const textData = new TextDecoder().decode(packet.data);\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Ordered fake message: ${content.pattern || 'unknown'}`);\r\n this.packetBuffer.delete(nextSequence);\r\n this.lastProcessedSequence = nextSequence;\r\n continue; \r\n }\r\n } catch (e) {\r\n }\r\n \r\n await this.processMessage(packet.data);\r\n this.packetBuffer.delete(nextSequence);\r\n this.lastProcessedSequence = nextSequence;\r\n }\r\n }\r\n\r\n this.cleanupOldPackets(now, timeout);\r\n}\r\n\r\n\r\n findOldestPacket() {\r\n let oldest = null;\r\n for (const [sequence, packet] of this.packetBuffer.entries()) {\r\n if (!oldest || packet.timestamp < oldest.timestamp) {\r\n oldest = { sequence, ...packet };\r\n }\r\n }\r\n return oldest;\r\n }\r\n\r\n cleanupOldPackets(now, timeout) {\r\n for (const [sequence, packet] of this.packetBuffer.entries()) {\r\n if ((now - packet.timestamp) > timeout) {\r\n this._secureLog('warn', '\u26A0\uFE0F \uD83D\uDDD1\uFE0F Removing timed out packet ${sequence}');\r\n this.packetBuffer.delete(sequence);\r\n }\r\n }\r\n }\r\n\r\n // ============================================\r\n // 7. ANTI-FINGERPRINTING\r\n // ============================================\r\n\r\n applyAntiFingerprinting(data) {\r\n if (!this.antiFingerprintingConfig.enabled) {\r\n return data;\r\n }\r\n\r\n try {\r\n let processedData = data;\r\n\r\n // Add random noise\r\n if (this.antiFingerprintingConfig.addNoise) {\r\n processedData = this.addNoise(processedData);\r\n }\r\n\r\n // Randomize sizes\r\n if (this.antiFingerprintingConfig.randomizeSizes) {\r\n processedData = this.randomizeSize(processedData);\r\n }\r\n\r\n // Mask patterns\r\n if (this.antiFingerprintingConfig.maskPatterns) {\r\n processedData = this.maskPatterns(processedData);\r\n }\r\n\r\n // Add random headers\r\n if (this.antiFingerprintingConfig.useRandomHeaders) {\r\n processedData = this.addRandomHeaders(processedData);\r\n }\r\n\r\n return processedData;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Anti-fingerprinting failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }\r\n\r\n addNoise(data) {\r\n const dataArray = new Uint8Array(data);\r\n const noiseSize = this.getUnbiasedRandomInRange(8, 40); // 8-40 bytes\r\n const noise = crypto.getRandomValues(new Uint8Array(noiseSize));\r\n \r\n const result = new Uint8Array(dataArray.length + noiseSize);\r\n result.set(dataArray, 0);\r\n result.set(noise, dataArray.length);\r\n \r\n return result.buffer;\r\n }\r\n\r\n randomizeSize(data) {\r\n const dataArray = new Uint8Array(data);\r\n const variation = this.fingerprintMask.sizeVariation;\r\n const targetSize = Math.floor(dataArray.length * variation);\r\n \r\n if (targetSize > dataArray.length) {\r\n // Add padding to increase size\r\n const padding = crypto.getRandomValues(new Uint8Array(targetSize - dataArray.length));\r\n const result = new Uint8Array(targetSize);\r\n result.set(dataArray, 0);\r\n result.set(padding, dataArray.length);\r\n return result.buffer;\r\n } else if (targetSize < dataArray.length) {\r\n // Truncate to decrease size\r\n return dataArray.slice(0, targetSize).buffer;\r\n }\r\n \r\n return data;\r\n }\r\n\r\n maskPatterns(data) {\r\n const dataArray = new Uint8Array(data);\r\n const result = new Uint8Array(dataArray.length);\r\n \r\n // Apply XOR with noise pattern\r\n for (let i = 0; i < dataArray.length; i++) {\r\n const noiseByte = this.fingerprintMask.noisePattern[i % this.fingerprintMask.noisePattern.length];\r\n result[i] = dataArray[i] ^ noiseByte;\r\n }\r\n \r\n return result.buffer;\r\n }\r\n\r\n addRandomHeaders(data) {\r\n const dataArray = new Uint8Array(data);\r\n const headerCount = this.getUnbiasedRandomInRange(1, 3); // 1-3 headers\r\n let totalHeaderSize = 0;\r\n \r\n // Calculate total header size\r\n for (let i = 0; i < headerCount; i++) {\r\n totalHeaderSize += 4 + this.getUnbiasedRandomInRange(0, 15) + 4; // size + data + checksum\r\n }\r\n \r\n const result = new Uint8Array(totalHeaderSize + dataArray.length);\r\n let offset = 0;\r\n \r\n // Add random headers\r\n for (let i = 0; i < headerCount; i++) {\r\n // Generate unbiased random index for header selection\r\n let headerIndex;\r\n do {\r\n headerIndex = crypto.getRandomValues(new Uint8Array(1))[0];\r\n } while (headerIndex >= 256 - (256 % this.fingerprintMask.headerVariations.length));\r\n \r\n const headerName = this.fingerprintMask.headerVariations[headerIndex % this.fingerprintMask.headerVariations.length];\r\n \r\n // Generate unbiased random size for header data (4-19 bytes)\r\n let headerSize;\r\n do {\r\n headerSize = crypto.getRandomValues(new Uint8Array(1))[0];\r\n } while (headerSize >= 256 - (256 % 16));\r\n \r\n const headerData = crypto.getRandomValues(new Uint8Array((headerSize % 16) + 4));\r\n \r\n // Header structure: [size:4][name:4][data:variable][checksum:4]\r\n const headerView = new DataView(result.buffer, offset);\r\n headerView.setUint32(0, headerData.length + 8, false); // Total header size\r\n headerView.setUint32(4, this.hashString(headerName), false); // Name hash\r\n \r\n result.set(headerData, offset + 8);\r\n \r\n // Add checksum\r\n const checksum = this.calculateChecksum(result.slice(offset, offset + 8 + headerData.length));\r\n const checksumView = new DataView(result.buffer, offset + 8 + headerData.length);\r\n checksumView.setUint32(0, checksum, false);\r\n \r\n offset += 8 + headerData.length + 4;\r\n }\r\n \r\n // Add original data\r\n result.set(dataArray, offset);\r\n \r\n return result.buffer;\r\n }\r\n\r\n hashString(str) {\r\n let hash = 0;\r\n for (let i = 0; i < str.length; i++) {\r\n const char = str.charCodeAt(i);\r\n hash = ((hash << 5) - hash) + char;\r\n hash = hash & hash;\r\n }\r\n return Math.abs(hash);\r\n }\r\n\r\n calculateChecksum(data) {\r\n let checksum = 0;\r\n for (let i = 0; i < data.length; i++) {\r\n checksum = (checksum + data[i]) & 0xFFFFFFFF;\r\n }\r\n return checksum;\r\n }\r\n\r\n // ============================================\r\n // ENHANCED MESSAGE SENDING AND RECEIVING\r\n // ============================================\r\n\r\n async removeSecurityLayers(data) {\r\n try {\r\n const status = this.getSecurityStatus();\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83D\uDD0D removeSecurityLayers (Stage ${status.stage})`, {\r\n dataType: typeof data,\r\n dataLength: data?.length || data?.byteLength || 0,\r\n activeFeatures: status.activeFeaturesCount\r\n });\r\n }\r\n\r\n if (!data) {\r\n this._secureLog('warn', '\u26A0\uFE0F Received empty data');\r\n return null;\r\n }\r\n\r\n let processedData = data;\r\n\r\n // IMPORTANT: Early check for fake messages\r\n if (typeof data === 'string') {\r\n try {\r\n const jsonData = JSON.parse(data);\r\n \r\n // PRIORITY ONE: Filtering out fake messages\r\n if (jsonData.type === 'fake') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Fake message filtered out: ${jsonData.pattern} (size: ${jsonData.size})`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED'; \r\n }\r\n \r\n // System messages \u2014 do NOT return for re-processing\r\n if (jsonData.type && ['heartbeat', 'verification', 'verification_response', 'peer_disconnect', 'key_rotation_signal', 'key_rotation_ready', 'security_upgrade'].includes(jsonData.type)) {\r\n return 'SYSTEM_MESSAGE_FILTERED';\r\n }\r\n \r\n // File transfer messages \u2014 do NOT return for display\r\n if (jsonData.type && ['file_transfer_start', 'file_transfer_response', 'file_chunk', 'chunk_confirmation', 'file_transfer_complete', 'file_transfer_error'].includes(jsonData.type)) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCC1 File transfer message detected, blocking from chat', { type: jsonData.type });\r\n }\r\n return 'FILE_MESSAGE_FILTERED';\r\n }\r\n \r\n // Regular text messages - extract the actual message text\r\n if (jsonData.type === 'message') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, extracting text', { data: jsonData.data });\r\n }\r\n return jsonData.data; // Return the actual message text, not the JSON\r\n }\r\n \r\n // Enhanced messages\r\n if (jsonData.type === 'enhanced_message' && jsonData.data) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDD10 Enhanced message detected, decrypting...');\r\n }\r\n \r\n if (!this.encryptionKey || !this.macKey || !this.metadataKey) {\r\n this._secureLog('error', '\u274C Missing encryption keys');\r\n return null;\r\n }\r\n \r\n const decryptedResult = await window.EnhancedSecureCryptoUtils.decryptMessage(\r\n jsonData.data,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey\r\n );\r\n \r\n if (this._debugMode) {\r\n this._secureLog('debug', '\u2705 Enhanced message decrypted, extracting...');\r\n this._secureLog('debug', '\uD83D\uDD0D decryptedResult', {\r\n type: typeof decryptedResult,\r\n hasMessage: !!decryptedResult?.message,\r\n messageType: typeof decryptedResult?.message,\r\n messageLength: decryptedResult?.message?.length || 0,\r\n messageSample: decryptedResult?.message?.substring(0, 50) || 'no message'\r\n });\r\n }\r\n \r\n // CHECKING FOR FAKE MESSAGES AFTER DECRYPTION\r\n try {\r\n const decryptedContent = JSON.parse(decryptedResult.message);\r\n if (decryptedContent.type === 'fake' || decryptedContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Encrypted fake message: ${decryptedContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Decrypted content is not JSON, treating as plain text message');\r\n }\r\n }\r\n \r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCE4 Returning decrypted message', { message: decryptedResult.message?.substring(0, 50) });\r\n }\r\n return decryptedResult.message;\r\n }\r\n \r\n // Regular messages\r\n if (jsonData.type === 'message' && jsonData.data) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, extracting data');\r\n }\r\n return jsonData.data; // Return the actual message text\r\n }\r\n \r\n // If it's a regular message with type 'message', let it continue processing\r\n if (jsonData.type === 'message') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, returning for display');\r\n }\r\n return data; // Return the original JSON string for processing\r\n }\r\n \r\n // If it's not a special type, return the original data for display\r\n if (!jsonData.type || (jsonData.type !== 'fake' && !['heartbeat', 'verification', 'verification_response', 'peer_disconnect', 'key_rotation_signal', 'key_rotation_ready', 'enhanced_message', 'security_upgrade', 'file_transfer_start', 'file_transfer_response', 'file_chunk', 'chunk_confirmation', 'file_transfer_complete', 'file_transfer_error'].includes(jsonData.type))) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, returning for display');\r\n }\r\n return data;\r\n }\r\n } catch (e) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCC4 Not JSON, processing as raw data');\r\n }\r\n // If it's not JSON, it might be a plain text message - return as-is\r\n return data;\r\n }\r\n }\r\n\r\n // Standard Decryption\r\n if (this.encryptionKey && typeof processedData === 'string' && processedData.length > 50) {\r\n try {\r\n const base64Regex = /^[A-Za-z0-9+/=]+$/;\r\n if (base64Regex.test(processedData.trim())) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDD13 Applying standard decryption...');\r\n }\r\n processedData = await window.EnhancedSecureCryptoUtils.decryptData(processedData, this.encryptionKey);\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\u2705 Standard decryption successful');\r\n }\r\n \r\n // CHECKING FOR FAKE MESSAGES AFTER LEGACY DECRYPTION\r\n if (typeof processedData === 'string') {\r\n try {\r\n const legacyContent = JSON.parse(processedData);\r\n if (legacyContent.type === 'fake' || legacyContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Legacy fake message: ${legacyContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n \r\n }\r\n processedData = new TextEncoder().encode(processedData).buffer;\r\n }\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Standard decryption failed:', { details: error.message });\r\n }\r\n return data; \r\n }\r\n }\r\n\r\n if (this.securityFeatures.hasNestedEncryption && \r\n this.nestedEncryptionKey && \r\n processedData instanceof ArrayBuffer &&\r\n processedData.byteLength > 12) { \r\n \r\n try {\r\n processedData = await this.removeNestedEncryption(processedData);\r\n \r\n if (processedData instanceof ArrayBuffer) {\r\n try {\r\n const textData = new TextDecoder().decode(processedData);\r\n const nestedContent = JSON.parse(textData);\r\n if (nestedContent.type === 'fake' || nestedContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Nested fake message: ${nestedContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n \r\n }\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Nested decryption failed - skipping this layer:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n if (this.securityFeatures.hasPacketReordering && \r\n this.reorderingConfig.enabled && \r\n processedData instanceof ArrayBuffer) {\r\n try {\r\n const headerSize = this.reorderingConfig.useTimestamps ? 12 : 8;\r\n if (processedData.byteLength > headerSize) {\r\n return await this.processReorderedPacket(processedData);\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Reordering processing failed - using direct processing:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n // Packet Padding Removal\r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removePacketPadding(processedData);\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Padding removal failed:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n // Anti-Fingerprinting Removal\r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removeAntiFingerprinting(processedData);\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Anti-fingerprinting removal failed:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n // Final transformation\r\n if (processedData instanceof ArrayBuffer) {\r\n processedData = new TextDecoder().decode(processedData);\r\n }\r\n\r\n if (typeof processedData === 'string') {\r\n try {\r\n const finalContent = JSON.parse(processedData);\r\n if (finalContent.type === 'fake' || finalContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Final check fake message: ${finalContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n }\r\n }\r\n\r\n return processedData;\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Critical error in removeSecurityLayers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n}\r\n\r\n removeAntiFingerprinting(data) {\r\n // This is a simplified version - in practice, you'd need to reverse all operations\r\n // For now, we'll just return the data as-is since the operations are mostly additive\r\n return data;\r\n }\r\n\r\n async applySecurityLayers(data, isFakeMessage = false) {\r\n try {\r\n let processedData = data;\r\n \r\n if (isFakeMessage) {\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n return processedData;\r\n }\r\n \r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey && processedData instanceof ArrayBuffer) {\r\n processedData = await this.applyNestedEncryption(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketReordering && this.reorderingConfig?.enabled && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketReordering(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketPadding(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyAntiFingerprinting(processedData);\r\n }\r\n \r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n \r\n return processedData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in applySecurityLayers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }\r\n\r\n async sendMessage(data) {\r\n // Comprehensive input validation\r\n const validation = this._validateInputData(data, 'sendMessage');\r\n if (!validation.isValid) {\r\n const errorMessage = `Input validation failed: ${validation.errors.join(', ')}`;\r\n this._secureLog('error', '\u274C Input validation failed in sendMessage', {\r\n errors: validation.errors,\r\n dataType: typeof data,\r\n dataLength: data?.length || data?.byteLength || 0\r\n });\r\n throw new Error(errorMessage);\r\n }\r\n\r\n // Rate limiting check\r\n if (!this._checkRateLimit('sendMessage')) {\r\n throw new Error('Rate limit exceeded for message sending');\r\n }\r\n\r\n // Enforce verification gate\r\n this._enforceVerificationGate('sendMessage');\r\n\r\n // Connection validation\r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n throw new Error('Data channel not ready');\r\n }\r\n\r\n try {\r\n this._secureLog('debug', 'sendMessage called', {\r\n hasDataChannel: !!this.dataChannel,\r\n dataChannelReady: this.dataChannel?.readyState === 'open',\r\n isInitiator: this.isInitiator,\r\n isVerified: this.isVerified,\r\n connectionReady: this.peerConnection?.connectionState === 'connected'\r\n });\r\n\r\n this._secureLog('debug', '\uD83D\uDD0D sendMessage DEBUG', {\r\n dataType: typeof validation.sanitizedData,\r\n isString: typeof validation.sanitizedData === 'string',\r\n isArrayBuffer: validation.sanitizedData instanceof ArrayBuffer,\r\n dataLength: validation.sanitizedData?.length || validation.sanitizedData?.byteLength || 0,\r\n });\r\n\r\n // CRITICAL SECURITY FIX: File messages MUST be encrypted\r\n // No more bypassing encryption for file_* messages\r\n if (typeof validation.sanitizedData === 'string') {\r\n try {\r\n const parsed = JSON.parse(validation.sanitizedData);\r\n \r\n if (parsed.type && parsed.type.startsWith('file_')) {\r\n this._secureLog('debug', '\uD83D\uDCC1 File message detected - applying full encryption with AAD', { type: parsed.type });\r\n \r\n // Create AAD for file message\r\n const aad = this._createFileMessageAAD(parsed.type, parsed.data);\r\n \r\n // Encrypt file message with AAD\r\n const encryptedData = await this._encryptFileMessage(validation.sanitizedData, aad);\r\n \r\n this.dataChannel.send(encryptedData);\r\n return true;\r\n }\r\n } catch (jsonError) {\r\n // Not JSON \u2014 continue normal handling\r\n }\r\n }\r\n\r\n // For regular text messages, send via secure path with AAD\r\n if (typeof validation.sanitizedData === 'string') {\r\n // Verify that _createMessageAAD method is available\r\n if (typeof this._createMessageAAD !== 'function') {\r\n throw new Error('_createMessageAAD method is not available. Manager may not be fully initialized.');\r\n }\r\n \r\n // Create AAD with sequence number for anti-replay protection\r\n const aad = this._createMessageAAD('message', { content: validation.sanitizedData });\r\n \r\n return await this.sendSecureMessage({ \r\n type: 'message', \r\n data: validation.sanitizedData, \r\n timestamp: Date.now(),\r\n aad: aad // Include AAD for sequence number validation\r\n });\r\n }\r\n\r\n // For binary data, apply security layers with a limited mutex\r\n this._secureLog('debug', '\uD83D\uDD10 Applying security layers to non-string data');\r\n const securedData = await this._applySecurityLayersWithLimitedMutex(validation.sanitizedData, false);\r\n this.dataChannel.send(securedData);\r\n \r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to send message', { \r\n error: error.message,\r\n errorType: error.constructor.name\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // FIX: New method applying security layers with limited mutex use\r\n async _applySecurityLayersWithLimitedMutex(data, isFakeMessage = false) {\r\n // Use mutex ONLY for cryptographic operations\r\n return this._withMutex('cryptoOperation', async (operationId) => {\r\n try {\r\n let processedData = data;\r\n \r\n if (isFakeMessage) {\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n return processedData;\r\n }\r\n \r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey && processedData instanceof ArrayBuffer) {\r\n processedData = await this.applyNestedEncryption(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketReordering && this.reorderingConfig?.enabled && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketReordering(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketPadding(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyAntiFingerprinting(processedData);\r\n }\r\n \r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n \r\n return processedData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in applySecurityLayers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }, 3000); // Short timeout for crypto operations\r\n}\r\n\r\n async sendSystemMessage(messageData) {\r\n // Block system messages without verification\r\n // Exception: Allow verification-related system messages\r\n const isVerificationMessage = messageData.type === 'verification_request' || \r\n messageData.type === 'verification_response' ||\r\n messageData.type === 'verification_required';\r\n \r\n if (!isVerificationMessage) {\r\n this._enforceVerificationGate('sendSystemMessage', false);\r\n }\r\n \r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n this._secureLog('warn', '\u26A0\uFE0F Cannot send system message - data channel not ready');\r\n return false;\r\n }\r\n\r\n try {\r\n const systemMessage = JSON.stringify({\r\n type: messageData.type,\r\n data: messageData,\r\n timestamp: Date.now()\r\n });\r\n\r\n this._secureLog('debug', '\uD83D\uDD27 Sending system message', { type: messageData.type });\r\n this.dataChannel.send(systemMessage);\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to send system message:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n\r\n // FIX 1: Simplified mutex system for message processing\r\nasync processMessage(data) {\r\n try {\r\n this._secureLog('debug', '\uFFFD\uFFFD Processing message', {\r\n dataType: typeof data,\r\n isArrayBuffer: data instanceof ArrayBuffer,\r\n hasData: !!(data?.length || data?.byteLength)\r\n });\r\n \r\n // CRITICAL: Early check for file messages WITHOUT mutex\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n\r\n // ============================================\r\n // FILE MESSAGES \u2014 PRIORITY 1 (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n const fileMessageTypes = [\r\n 'file_transfer_start',\r\n 'file_transfer_response',\r\n 'file_chunk', \r\n 'chunk_confirmation',\r\n 'file_transfer_complete',\r\n 'file_transfer_error'\r\n ];\r\n\r\n // CRITICAL SECURITY FIX: Check for encrypted file messages first\r\n if (parsed.type === 'encrypted_file_message') {\r\n this._secureLog('debug', '\uD83D\uDCC1 Encrypted file message detected in processMessage');\r\n \r\n try {\r\n // Decrypt and validate file message\r\n const { decryptedData, aad } = await this._decryptFileMessage(data);\r\n \r\n // Parse decrypted data\r\n const decryptedParsed = JSON.parse(decryptedData);\r\n \r\n this._secureLog('debug', '\uD83D\uDCC1 File message decrypted successfully', { \r\n type: decryptedParsed.type,\r\n aadMessageType: aad.messageType \r\n });\r\n \r\n // Process decrypted file message\r\n if (this.fileTransferSystem && typeof this.fileTransferSystem.handleFileMessage === 'function') {\r\n await this.fileTransferSystem.handleFileMessage(decryptedParsed);\r\n return;\r\n }\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to decrypt file message', { error: error.message });\r\n return; // Drop invalid file message\r\n }\r\n }\r\n \r\n // Legacy unencrypted file messages - should not happen in secure mode\r\n if (parsed.type && fileMessageTypes.includes(parsed.type)) {\r\n this._secureLog('warn', '\u26A0\uFE0F Unencrypted file message detected - this should not happen in secure mode', { type: parsed.type });\r\n \r\n // Drop unencrypted file messages for security\r\n this._secureLog('error', '\u274C Dropping unencrypted file message for security', { type: parsed.type });\r\n return;\r\n }\r\n \r\n // ============================================\r\n // ENHANCED MESSAGES WITH AAD VALIDATION (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'enhanced_message') {\r\n this._secureLog('debug', '\uD83D\uDD10 Enhanced message detected in processMessage');\r\n \r\n try {\r\n // Decrypt enhanced message\r\n const decryptedData = await window.EnhancedSecureCryptoUtils.decryptMessage(\r\n parsed.data,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey\r\n );\r\n \r\n // Parse decrypted data\r\n const decryptedParsed = JSON.parse(decryptedData.data);\r\n \r\n // Validate AAD with sequence number\r\n if (decryptedData.metadata && decryptedData.metadata.sequenceNumber !== undefined) {\r\n if (!this._validateIncomingSequenceNumber(decryptedData.metadata.sequenceNumber, 'enhanced_message')) {\r\n this._secureLog('warn', '\u26A0\uFE0F Enhanced message sequence number validation failed - possible replay attack', {\r\n received: decryptedData.metadata.sequenceNumber,\r\n expected: this.expectedSequenceNumber\r\n });\r\n return; // Drop message with invalid sequence number\r\n }\r\n }\r\n \r\n // Process decrypted message\r\n if (decryptedParsed.type === 'message' && this.onMessage && decryptedParsed.data) {\r\n this.deliverMessageToUI(decryptedParsed.data, 'received');\r\n }\r\n \r\n return;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to decrypt enhanced message', { error: error.message });\r\n return; // Drop invalid enhanced message\r\n }\r\n }\r\n \r\n // ============================================\r\n // REGULAR USER MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'message') {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular user message detected in processMessage');\r\n if (this.onMessage && parsed.data) {\r\n this.deliverMessageToUI(parsed.data, 'received');\r\n }\r\n return;\r\n }\r\n \r\n // ============================================\r\n // SYSTEM MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type && ['heartbeat', 'verification', 'verification_response', 'verification_confirmed', 'verification_both_confirmed', 'peer_disconnect', 'security_upgrade'].includes(parsed.type)) {\r\n this.handleSystemMessage(parsed);\r\n return;\r\n }\r\n \r\n // ============================================\r\n // FAKE MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'fake') {\r\n this._secureLog('warn', '\uD83C\uDFAD Fake message blocked in processMessage', { pattern: parsed.pattern });\r\n return;\r\n }\r\n \r\n } catch (jsonError) {\r\n // Not JSON \u2014 treat as text WITHOUT mutex\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(data, 'received');\r\n }\r\n return;\r\n }\r\n }\r\n\r\n // ============================================\r\n // ENCRYPTED DATA PROCESSING (WITH MUTEX ONLY FOR CRYPTO)\r\n // ============================================\r\n \r\n // If here \u2014 apply security layers with limited mutex\r\n const originalData = await this._processEncryptedDataWithLimitedMutex(data);\r\n\r\n // Check processing result\r\n if (originalData === 'FAKE_MESSAGE_FILTERED' || \r\n originalData === 'FILE_MESSAGE_FILTERED' || \r\n originalData === 'SYSTEM_MESSAGE_FILTERED') {\r\n return;\r\n }\r\n \r\n if (!originalData) {\r\n this._secureLog('warn', '\u26A0\uFE0F No data returned from removeSecurityLayers');\r\n return;\r\n }\r\n\r\n // Handle result after removeSecurityLayers\r\n let messageText;\r\n \r\n if (typeof originalData === 'string') {\r\n try {\r\n const message = JSON.parse(originalData);\r\n \r\n // SECOND CHECK FOR FILE MESSAGES AFTER DECRYPTION\r\n if (message.type && fileMessageTypes.includes(message.type)) {\r\n this._secureLog('debug', '\uD83D\uDCC1 File message detected after decryption', { type: message.type });\r\n if (this.fileTransferSystem) {\r\n await this.fileTransferSystem.handleFileMessage(message);\r\n }\r\n return;\r\n }\r\n \r\n if (message.type && ['heartbeat', 'verification', 'verification_response', 'verification_confirmed', 'verification_both_confirmed', 'peer_disconnect', 'security_upgrade'].includes(message.type)) {\r\n this.handleSystemMessage(message);\r\n return;\r\n }\r\n \r\n if (message.type === 'fake') {\r\n this._secureLog('warn', `\uD83C\uDFAD Post-decryption fake message blocked: ${message.pattern}`);\r\n return;\r\n }\r\n \r\n // Regular messages\r\n if (message.type === 'message' && message.data) {\r\n messageText = message.data;\r\n } else {\r\n messageText = originalData;\r\n }\r\n } catch (e) {\r\n messageText = originalData;\r\n }\r\n } else if (originalData instanceof ArrayBuffer) {\r\n messageText = new TextDecoder().decode(originalData);\r\n } else if (originalData && typeof originalData === 'object' && originalData.message) {\r\n messageText = originalData.message;\r\n } else {\r\n this._secureLog('warn', '\u26A0\uFE0F Unexpected data type after processing:', { details: typeof originalData });\r\n return;\r\n }\r\n\r\n // Final check for fake and file messages\r\n if (messageText && messageText.trim().startsWith('{')) {\r\n try {\r\n const finalCheck = JSON.parse(messageText);\r\n if (finalCheck.type === 'fake') {\r\n this._secureLog('warn', `\uD83C\uDFAD Final fake message check blocked: ${finalCheck.pattern}`);\r\n return;\r\n }\r\n \r\n // Additional check for file and system messages\r\n const blockedTypes = [\r\n 'file_transfer_start', 'file_transfer_response', 'file_chunk', \r\n 'chunk_confirmation', 'file_transfer_complete', 'file_transfer_error',\r\n 'heartbeat', 'verification', 'verification_response', \r\n 'peer_disconnect', 'key_rotation_signal', 'key_rotation_ready', 'security_upgrade'\r\n ];\r\n \r\n if (finalCheck.type && blockedTypes.includes(finalCheck.type)) {\r\n this._secureLog('warn', `\uD83D\uDCC1 Final system/file message check blocked: ${finalCheck.type}`);\r\n return;\r\n }\r\n } catch (e) {\r\n // Not JSON \u2014 fine for plain text\r\n }\r\n }\r\n\r\n // Deliver message to the UI\r\n if (this.onMessage && messageText) {\r\n this._secureLog('debug', '\uD83D\uDCE4 Calling message handler with', { message: messageText.substring(0, 100) });\r\n this.deliverMessageToUI(messageText, 'received');\r\n }\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to process message:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n}\r\n\r\n // FIX: New method with limited mutex when processing encrypted data\r\n async _processEncryptedDataWithLimitedMutex(data) {\r\n // Use mutex ONLY for cryptographic operations\r\n return this._withMutex('cryptoOperation', async (operationId) => {\r\n this._secureLog('debug', '\uD83D\uDD10 Processing encrypted data with limited mutex', {\r\n operationId: operationId,\r\n dataType: typeof data\r\n });\r\n \r\n try {\r\n // Apply security layers\r\n const originalData = await this.removeSecurityLayers(data);\r\n return originalData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error processing encrypted data', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n return data; // Return original data on error\r\n }\r\n }, 2000); // Short timeout for crypto operations\r\n }\r\n\r\n notifySecurityUpdate() {\r\n try {\r\n this._secureLog('debug', '\uD83D\uDD12 Notifying about security level update', {\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n hasKeys: !!(this.encryptionKey && this.macKey && this.metadataKey),\r\n hasLastCalculation: !!this.lastSecurityCalculation\r\n });\r\n \r\n // Send an event about security level update\r\n document.dispatchEvent(new CustomEvent('security-level-updated', {\r\n detail: { \r\n timestamp: Date.now(), \r\n manager: 'webrtc',\r\n webrtcManager: this,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n hasKeys: !!(this.encryptionKey && this.macKey && this.metadataKey),\r\n lastCalculation: this.lastSecurityCalculation\r\n }\r\n }));\r\n \r\n // FIX: Force header refresh with correct manager\r\n setTimeout(() => {\r\n // Removed global callback - use event system instead\r\n // if (window.forceHeaderSecurityUpdate) {\r\n // window.forceHeaderSecurityUpdate(this);\r\n // }\r\n }, 100);\r\n \r\n // FIX: Direct update if there is a calculation\r\n if (this.lastSecurityCalculation) {\r\n document.dispatchEvent(new CustomEvent('real-security-calculated', {\r\n detail: {\r\n securityData: this.lastSecurityCalculation,\r\n webrtcManager: this,\r\n timestamp: Date.now()\r\n }\r\n }));\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in notifySecurityUpdate', {\r\n error: error.message\r\n });\r\n }\r\n }\r\n\r\n handleSystemMessage(message) {\r\n this._secureLog('debug', '\uD83D\uDD27 Handling system message:', { type: message.type });\r\n \r\n switch (message.type) {\r\n case 'heartbeat':\r\n this.handleHeartbeat();\r\n break;\r\n case 'verification':\r\n this.handleVerificationRequest(message.data);\r\n break;\r\n case 'verification_response':\r\n this.handleVerificationResponse(message.data);\r\n break;\r\n case 'sas_code':\r\n this.handleSASCode(message.data);\r\n break;\r\n case 'verification_confirmed':\r\n this.handleVerificationConfirmed(message.data);\r\n break;\r\n case 'verification_both_confirmed':\r\n this.handleVerificationBothConfirmed(message.data);\r\n break;\r\n case 'peer_disconnect':\r\n this.handlePeerDisconnectNotification(message);\r\n break;\r\n case 'key_rotation_signal':\r\n this._secureLog('debug', '\uD83D\uDD04 Key rotation signal received (ignored for stability)');\r\n break;\r\n case 'key_rotation_ready':\r\n this._secureLog('debug', '\uD83D\uDD04 Key rotation ready signal received (ignored for stability)');\r\n break;\r\n case 'security_upgrade':\r\n this._secureLog('debug', '\uD83D\uDD12 Security upgrade notification received:', { type: message.type });\r\n // Security upgrade messages are handled internally, not displayed to user\r\n // to prevent duplicate system messages\r\n break;\r\n default:\r\n this._secureLog('debug', '\uD83D\uDD27 Unknown system message type:', { type: message.type });\r\n }\r\n }\r\n\r\n // ============================================\r\n // FUNCTION MANAGEMENT METHODS\r\n // ============================================\r\n\r\n // Method to enable Stage 2 functions\r\n enableStage2Security() {\r\n if (this.sessionConstraints?.hasPacketReordering) {\r\n this.securityFeatures.hasPacketReordering = true;\r\n this.reorderingConfig.enabled = true;\r\n }\r\n \r\n if (this.sessionConstraints?.hasAntiFingerprinting) {\r\n this.securityFeatures.hasAntiFingerprinting = true;\r\n this.antiFingerprintingConfig.enabled = true;\r\n // Enable full anti-fingerprinting features\r\n this.antiFingerprintingConfig.randomizeSizes = true;\r\n this.antiFingerprintingConfig.maskPatterns = true;\r\n this.antiFingerprintingConfig.useRandomHeaders = true;\r\n }\r\n \r\n this.notifySecurityUpgrade(2);\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, 500);\r\n }\r\n\r\n // Method to enable Stage 3 features (traffic obfuscation)\r\n enableStage3Security() {\r\n this._secureLog('info', '\uD83D\uDD12 Enabling Stage 3 features (traffic obfuscation)');\r\n \r\n if (this.sessionConstraints?.hasMessageChunking) {\r\n this.securityFeatures.hasMessageChunking = true;\r\n this.chunkingConfig.enabled = true;\r\n }\r\n \r\n if (this.sessionConstraints?.hasFakeTraffic) {\r\n this.securityFeatures.hasFakeTraffic = true;\r\n this.fakeTrafficConfig.enabled = true;\r\n this.startFakeTrafficGeneration();\r\n }\r\n \r\n this.notifySecurityUpgrade(3);\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, 500);\r\n }\r\n\r\n // Method for enabling Stage 4 functions (maximum safety)\r\n enableStage4Security() {\r\n this._secureLog('info', '\uD83D\uDD12 Enabling Stage 4 features (maximum safety)');\r\n \r\n if (this.sessionConstraints?.hasDecoyChannels && this.isConnected() && this.isVerified) {\r\n this.securityFeatures.hasDecoyChannels = true;\r\n this.decoyChannelConfig.enabled = true;\r\n \r\n try {\r\n this.initializeDecoyChannels();\r\n } catch (error) {\r\n this._secureLog('warn', '\u26A0\uFE0F Decoy channels initialization failed:', { details: error.message });\r\n this.securityFeatures.hasDecoyChannels = false;\r\n this.decoyChannelConfig.enabled = false;\r\n }\r\n }\r\n \r\n // Full anti-fingerprinting for maximum sessions\r\n if (this.sessionConstraints?.hasAntiFingerprinting) {\r\n this.antiFingerprintingConfig.randomizeSizes = true;\r\n this.antiFingerprintingConfig.maskPatterns = true;\r\n this.antiFingerprintingConfig.useRandomHeaders = false; \r\n }\r\n \r\n this.notifySecurityUpgrade(4);\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, 500);\r\n }\r\n\r\n forceSecurityUpdate() {\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpdate();\r\n }, 100);\r\n }\r\n\r\n // Method for getting security status\r\n getSecurityStatus() {\r\n const activeFeatures = Object.entries(this.securityFeatures)\r\n .filter(([key, value]) => value === true)\r\n .map(([key]) => key);\r\n \r\n const stage = 4; // Maximum security stage\r\n \r\n return {\r\n stage: stage,\r\n securityLevel: 'maximum',\r\n activeFeatures: activeFeatures,\r\n totalFeatures: Object.keys(this.securityFeatures).length,\r\n activeFeaturesCount: activeFeatures.length,\r\n activeFeaturesNames: activeFeatures,\r\n sessionConstraints: this.sessionConstraints\r\n };\r\n }\r\n\r\n // Method to notify UI about security update\r\n notifySecurityUpgrade(stage) {\r\n const stageNames = {\r\n 1: 'Basic Enhanced',\r\n 2: 'Medium Security', \r\n 3: 'High Security',\r\n 4: 'Maximum Security'\r\n };\r\n \r\n const message = `\uD83D\uDD12 Security upgraded to Stage ${stage}: ${stageNames[stage]}`;\r\n \r\n // Avoid duplicate security-upgrade notifications\r\n if (!this.securityUpgradeNotificationSent || this.lastSecurityUpgradeStage !== stage) {\r\n this.securityUpgradeNotificationSent = true;\r\n this.lastSecurityUpgradeStage = stage;\r\n \r\n // Notify local UI via onMessage\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(message, 'system');\r\n }\r\n }\r\n\r\n // Send security upgrade notification to peer via WebRTC\r\n if (this.dataChannel && this.dataChannel.readyState === 'open') {\r\n try {\r\n const securityNotification = {\r\n type: 'security_upgrade',\r\n stage: stage,\r\n stageName: stageNames[stage],\r\n message: message,\r\n timestamp: Date.now()\r\n };\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Sending security upgrade notification to peer:', { type: securityNotification.type, stage: securityNotification.stage });\r\n this.dataChannel.send(JSON.stringify(securityNotification));\r\n } catch (error) {\r\n this._secureLog('warn', '\u26A0\uFE0F Failed to send security upgrade notification to peer:', { details: error.message });\r\n }\r\n }\r\n\r\n const status = this.getSecurityStatus();\r\n }\r\n\r\n async calculateAndReportSecurityLevel() {\r\n try {\r\n if (!window.EnhancedSecureCryptoUtils) {\r\n this._secureLog('warn', '\u26A0\uFE0F EnhancedSecureCryptoUtils not available for security calculation');\r\n return null;\r\n }\r\n\r\n if (!this.isConnected() || !this.isVerified || !this.encryptionKey || !this.macKey) {\r\n this._secureLog('debug', '\u26A0\uFE0F WebRTC not ready for security calculation', {\r\n connected: this.isConnected(),\r\n verified: this.isVerified,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey\r\n });\r\n return null;\r\n }\r\n\r\n this._secureLog('debug', '\uD83D\uDD0D Calculating real security level', {\r\n managerState: 'ready',\r\n hasAllKeys: !!(this.encryptionKey && this.macKey && this.metadataKey)\r\n });\r\n \r\n const securityData = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(this);\r\n \r\n this._secureLog('info', 'Real security level calculated', {\r\n hasSecurityLevel: !!securityData.level,\r\n scoreRange: securityData.score > 80 ? 'high' : securityData.score > 50 ? 'medium' : 'low',\r\n checksRatio: `${securityData.passedChecks}/${securityData.totalChecks}`,\r\n isRealCalculation: securityData.isRealData\r\n });\r\n\r\n this.lastSecurityCalculation = securityData;\r\n\r\n document.dispatchEvent(new CustomEvent('real-security-calculated', {\r\n detail: {\r\n securityData: securityData,\r\n webrtcManager: this,\r\n timestamp: Date.now(),\r\n source: 'calculateAndReportSecurityLevel'\r\n }\r\n }));\r\n\r\n if (securityData.isRealData && this.onMessage) {\r\n if (!this.securityCalculationNotificationSent || this.lastSecurityCalculationLevel !== securityData.level) {\r\n this.securityCalculationNotificationSent = true;\r\n this.lastSecurityCalculationLevel = securityData.level;\r\n \r\n const message = `Security Level: ${securityData.level} (${securityData.score}%) - ${securityData.passedChecks}/${securityData.totalChecks} checks passed`;\r\n this.deliverMessageToUI(message, 'system');\r\n }\r\n }\r\n \r\n return securityData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to calculate real security level', {\r\n errorType: error.constructor.name\r\n });\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================\r\n // AUTOMATIC STEP-BY-STEP SWITCHING ON\r\n // ============================================\r\n\r\n // Method for automatic feature enablement with stability check\r\n async autoEnableSecurityFeatures() {\r\n this._secureLog('info', 'Starting graduated security activation - all features enabled');\r\n\r\n const checkStability = () => {\r\n const isStable = this.isConnected() && \r\n this.isVerified && \r\n this.connectionAttempts === 0 && \r\n this.messageQueue.length === 0 &&\r\n this.peerConnection?.connectionState === 'connected';\r\n return isStable;\r\n };\r\n \r\n await this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpgrade(1);\r\n \r\n // Enable all security stages progressively\r\n setTimeout(async () => {\r\n if (checkStability()) {\r\n this.enableStage2Security();\r\n await this.calculateAndReportSecurityLevel(); \r\n \r\n setTimeout(async () => {\r\n if (checkStability()) {\r\n this.enableStage3Security();\r\n await this.calculateAndReportSecurityLevel();\r\n \r\n setTimeout(async () => {\r\n if (checkStability()) {\r\n this.enableStage4Security();\r\n await this.calculateAndReportSecurityLevel();\r\n }\r\n }, 20000);\r\n }\r\n }, 15000);\r\n }\r\n }, 10000);\r\n }\r\n\r\n // ============================================\r\n // CONNECTION MANAGEMENT WITH ENHANCED SECURITY\r\n // ============================================\r\n\r\n async establishConnection() {\r\n try {\r\n // Initialize enhanced security features\r\n await this.initializeEnhancedSecurity();\r\n \r\n // Start fake traffic generation\r\n if (this.fakeTrafficConfig.enabled) {\r\n this.startFakeTrafficGeneration();\r\n }\r\n \r\n // Initialize decoy channels\r\n if (this.decoyChannelConfig.enabled) {\r\n this.initializeDecoyChannels();\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to establish enhanced connection:', { errorType: error?.constructor?.name || 'Unknown' });\r\n // Do not close the connection on setup errors \u2014 just log and continue\r\n this.onStatusChange('disconnected');\r\n throw error;\r\n }\r\n }\r\n\r\n disconnect() {\r\n try {\r\n \r\n // Cleanup file transfer system\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n // Stop fake traffic generation\r\n this.stopFakeTrafficGeneration();\r\n \r\n // Stop decoy traffic\r\n for (const [channelName, timer] of this.decoyTimers.entries()) {\r\n clearTimeout(timer);\r\n }\r\n this.decoyTimers.clear();\r\n \r\n // Close decoy channels\r\n for (const [channelName, channel] of this.decoyChannels.entries()) {\r\n if (channel.readyState === 'open') {\r\n channel.close();\r\n }\r\n }\r\n this.decoyChannels.clear();\r\n \r\n // Clean up packet buffer\r\n this.packetBuffer.clear();\r\n \r\n // Clean up chunk queue\r\n this.chunkQueue = [];\r\n \r\n // Wipe ephemeral keys for PFS on disconnect\r\n this._wipeEphemeralKeys();\r\n \r\n // Hard wipe old keys for PFS\r\n this._hardWipeOldKeys();\r\n\r\n // Clear verification states\r\n this._clearVerificationStates();\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error during enhanced disconnect:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n /**\r\n * Clear all verification states and data\r\n * Called when verification is rejected or connection is terminated\r\n */\r\n _clearVerificationStates() {\r\n try {\r\n \r\n // Clear verification states\r\n this.localVerificationConfirmed = false;\r\n this.remoteVerificationConfirmed = false;\r\n this.bothVerificationsConfirmed = false;\r\n this.isVerified = false;\r\n this.verificationCode = null;\r\n this.pendingSASCode = null;\r\n \r\n // Clear key fingerprint and connection data\r\n this.keyFingerprint = null;\r\n this.expectedDTLSFingerprint = null;\r\n this.connectionId = null;\r\n \r\n // Clear processed message IDs\r\n this.processedMessageIds.clear();\r\n \r\n // Reset notification flags\r\n this.verificationNotificationSent = false;\r\n this.verificationInitiationSent = false;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error clearing verification states:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n // Start periodic cleanup for rate limiting and security\r\n startPeriodicCleanup() {\r\n // Cleanup moved to unified scheduler\r\n this._secureLog('info', '\uD83D\uDD27 Periodic cleanup moved to unified scheduler');\r\n }\r\n\r\n // Calculate current security level with real verification\r\n async calculateSecurityLevel() {\r\n return await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(this);\r\n }\r\n\r\n // PFS: Check if key rotation is needed\r\n shouldRotateKeys() {\r\n if (!this.isConnected() || !this.isVerified) {\r\n return false;\r\n }\r\n \r\n const now = Date.now();\r\n const timeSinceLastRotation = now - this.lastKeyRotation;\r\n \r\n // Rotate keys every 5 minutes or after 100 messages\r\n return timeSinceLastRotation > this.keyRotationInterval || \r\n this.messageCounter % 100 === 0;\r\n }\r\n\r\n // PFS: Rotate encryption keys for Perfect Forward Secrecy\r\n async rotateKeys() {\r\n return this._withMutex('keyOperation', async (operationId) => {\r\n this._secureLog('info', '\uD83D\uDD04 Starting key rotation with mutex', {\r\n operationId: operationId\r\n });\r\n \r\n // Validate state inside the critical section\r\n if (!this.isConnected() || !this.isVerified) {\r\n this._secureLog('warn', ' Key rotation aborted - connection not ready', {\r\n operationId: operationId,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified\r\n });\r\n return false;\r\n }\r\n \r\n // Ensure rotation is not already in progress\r\n if (this._keySystemState.isRotating) {\r\n this._secureLog('warn', ' Key rotation already in progress', {\r\n operationId: operationId\r\n });\r\n return false;\r\n }\r\n \r\n try {\r\n // Set rotation flag\r\n this._keySystemState.isRotating = true;\r\n this._keySystemState.lastOperation = 'rotation';\r\n this._keySystemState.lastOperationTime = Date.now();\r\n \r\n // Send rotation signal to peer\r\n const rotationSignal = {\r\n type: 'key_rotation_signal',\r\n newVersion: this.currentKeyVersion + 1,\r\n timestamp: Date.now(),\r\n operationId: operationId\r\n };\r\n \r\n if (this.dataChannel && this.dataChannel.readyState === 'open') {\r\n this.dataChannel.send(JSON.stringify(rotationSignal));\r\n } else {\r\n throw new Error('Data channel not ready for key rotation');\r\n }\r\n \r\n // Perform hard wipe of old keys for real PFS\r\n this._hardWipeOldKeys();\r\n \r\n // Wait for peer confirmation\r\n return new Promise((resolve) => {\r\n this.pendingRotation = {\r\n newVersion: this.currentKeyVersion + 1,\r\n operationId: operationId,\r\n resolve: resolve,\r\n timeout: setTimeout(() => {\r\n this._secureLog('error', ' Key rotation timeout', {\r\n operationId: operationId\r\n });\r\n this._keySystemState.isRotating = false;\r\n this.pendingRotation = null;\r\n resolve(false);\r\n }, 10000) // 10 seconds timeout\r\n };\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', ' Key rotation failed in critical section', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._keySystemState.isRotating = false;\r\n return false;\r\n }\r\n }, 10000); // 10 seconds timeout for the entire operation\r\n }\r\n\r\n // Real PFS - Clean up old keys with hard wipe\r\n cleanupOldKeys() {\r\n const now = Date.now();\r\n const maxKeyAge = EnhancedSecureWebRTCManager.LIMITS.MAX_KEY_AGE; // 15 minutes - keys older than this are deleted\r\n \r\n let wipedKeysCount = 0;\r\n \r\n for (const [version, keySet] of this.oldKeys.entries()) {\r\n if (now - keySet.timestamp > maxKeyAge) {\r\n // Hard wipe old keys before deletion\r\n if (keySet.encryptionKey) {\r\n this._secureWipeMemory(keySet.encryptionKey, 'pfs_cleanup_wipe');\r\n }\r\n if (keySet.macKey) {\r\n this._secureWipeMemory(keySet.macKey, 'pfs_cleanup_wipe');\r\n }\r\n if (keySet.metadataKey) {\r\n this._secureWipeMemory(keySet.metadataKey, 'pfs_cleanup_wipe');\r\n }\r\n \r\n // Clear references\r\n keySet.encryptionKey = null;\r\n keySet.macKey = null;\r\n keySet.metadataKey = null;\r\n keySet.keyFingerprint = null;\r\n \r\n this.oldKeys.delete(version);\r\n wipedKeysCount++;\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Old PFS keys hard wiped and cleaned up', {\r\n version: version,\r\n age: Math.round((now - keySet.timestamp) / 1000) + 's',\r\n timestamp: Date.now()\r\n });\r\n }\r\n }\r\n \r\n if (wipedKeysCount > 0) {\r\n this._secureLog('info', `PFS cleanup completed: ${wipedKeysCount} keys hard wiped`, {\r\n timestamp: Date.now()\r\n });\r\n }\r\n }\r\n\r\n // PFS: Get keys for specific version (for decryption)\r\n getKeysForVersion(version) {\r\n // First, we check the old keys (including version 0).\r\n const oldKeySet = this.oldKeys.get(version);\r\n if (oldKeySet && oldKeySet.encryptionKey && oldKeySet.macKey && oldKeySet.metadataKey) {\r\n return {\r\n encryptionKey: oldKeySet.encryptionKey,\r\n macKey: oldKeySet.macKey,\r\n metadataKey: oldKeySet.metadataKey\r\n };\r\n }\r\n \r\n // If this is the current version, return the current keys.\r\n if (version === this.currentKeyVersion) {\r\n if (this.encryptionKey && this.macKey && this.metadataKey) {\r\n return {\r\n encryptionKey: this.encryptionKey,\r\n macKey: this.macKey,\r\n metadataKey: this.metadataKey\r\n };\r\n }\r\n }\r\n \r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'No valid keys found for version', {\r\n requestedVersion: version,\r\n currentVersion: this.currentKeyVersion,\r\n availableVersions: Array.from(this.oldKeys.keys())\r\n });\r\n \r\n return null;\r\n }\r\n\r\n createPeerConnection() {\r\n const config = {\r\n iceServers: [\r\n { urls: 'stun:stun.l.google.com:19302' },\r\n { urls: 'stun:stun1.l.google.com:19302' },\r\n { urls: 'stun:stun2.l.google.com:19302' },\r\n { urls: 'stun:stun3.l.google.com:19302' },\r\n { urls: 'stun:stun4.l.google.com:19302' }\r\n ],\r\n iceCandidatePoolSize: 10,\r\n bundlePolicy: 'balanced'\r\n };\r\n\r\n this.peerConnection = new RTCPeerConnection(config);\r\n\r\n this.peerConnection.onconnectionstatechange = () => {\r\n const state = this.peerConnection.connectionState;\r\n \r\n if (state === 'connected' && !this.isVerified) {\r\n this.onStatusChange('verifying');\r\n } else if (state === 'connected' && this.isVerified) {\r\n this.onStatusChange('connected');\r\n } else if (state === 'disconnected' || state === 'closed') {\r\n // If this is an intentional disconnect, clear immediately.\r\n if (this.intentionalDisconnect) {\r\n this.onStatusChange('disconnected');\r\n setTimeout(() => this.disconnect(), 100);\r\n } else {\r\n this.onStatusChange('disconnected');\r\n // Clear verification states on unexpected disconnect\r\n this._clearVerificationStates();\r\n }\r\n } else if (state === 'failed') {\r\n // Do not auto-reconnect to avoid closing the session on errors\r\n this.onStatusChange('disconnected');\r\n\r\n } else {\r\n this.onStatusChange(state);\r\n }\r\n };\r\n\r\n this.peerConnection.ondatachannel = (event) => {\r\n \r\n // CRITICAL: Store the received data channel\r\n if (event.channel.label === 'securechat') {\r\n this.dataChannel = event.channel;\r\n this.setupDataChannel(event.channel);\r\n } else {\r\n // Handle additional channels (heartbeat, etc.)\r\n if (event.channel.label === 'heartbeat') {\r\n this.heartbeatChannel = event.channel;\r\n }\r\n }\r\n };\r\n }\r\n\r\n setupDataChannel(channel) {\r\n\r\n this.dataChannel = channel;\r\n\r\n this.dataChannel.onopen = async () => {\r\n // Configure backpressure for large transfers\r\n try {\r\n if (this.dataChannel && typeof this.dataChannel.bufferedAmountLowThreshold === 'number') {\r\n // 1 MB threshold for bufferedamountlow event\r\n this.dataChannel.bufferedAmountLowThreshold = 1024 * 1024;\r\n }\r\n } catch (e) {\r\n // ignore\r\n }\r\n \r\n try {\r\n await this.establishConnection();\r\n\r\n this.initializeFileTransfer();\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Error in establishConnection:', { errorType: error?.constructor?.name || 'Unknown' });\r\n // Continue despite errors\r\n }\r\n \r\n // CRITICAL: Send pending SAS code if available\r\n if (this.pendingSASCode && this.dataChannel && this.dataChannel.readyState === 'open') {\r\n try {\r\n const sasPayload = {\r\n type: 'sas_code',\r\n data: {\r\n code: this.pendingSASCode,\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS',\r\n securityLevel: 'MITM_PROTECTION_REQUIRED'\r\n }\r\n };\r\n this.dataChannel.send(JSON.stringify(sasPayload));\r\n this.pendingSASCode = null; // Clear after sending\r\n } catch (error) {\r\n }\r\n } else if (this.pendingSASCode) {\r\n }\r\n \r\n if (this.isVerified) {\r\n this.onStatusChange('connected');\r\n this.processMessageQueue();\r\n \r\n setTimeout(async () => {\r\n await this.calculateAndReportSecurityLevel();\r\n this.autoEnableSecurityFeatures();\r\n this.notifySecurityUpdate();\r\n }, 500);\r\n } else {\r\n this.onStatusChange('verifying');\r\n this.initiateVerification();\r\n }\r\n this.startHeartbeat();\r\n };\r\n\r\n this.dataChannel.onclose = () => {\r\n if (!this.intentionalDisconnect) {\r\n this.onStatusChange('disconnected');\r\n // Clear verification states on data channel close\r\n this._clearVerificationStates();\r\n \r\n if (!this.connectionClosedNotificationSent) {\r\n this.connectionClosedNotificationSent = true;\r\n this.deliverMessageToUI('\uD83D\uDD0C Enhanced secure connection closed. Check connection status.', 'system');\r\n }\r\n } else {\r\n this.onStatusChange('disconnected');\r\n // Clear verification states on intentional disconnect\r\n this._clearVerificationStates();\r\n \r\n if (!this.connectionClosedNotificationSent) {\r\n this.connectionClosedNotificationSent = true;\r\n this.deliverMessageToUI('\uD83D\uDD0C Enhanced secure connection closed', 'system');\r\n }\r\n }\r\n \r\n // Wipe ephemeral keys when session ends for PFS\r\n this._wipeEphemeralKeys();\r\n \r\n this.stopHeartbeat();\r\n this.isVerified = false;\r\n };\r\n\r\n // FIX 2: Remove mutex entirely from message processing path\r\n this.dataChannel.onmessage = async (event) => {\r\n try {\r\n\r\n // IMPORTANT: Process ALL messages WITHOUT mutex\r\n if (typeof event.data === 'string') {\r\n try {\r\n const parsed = JSON.parse(event.data);\r\n\r\n \r\n // ============================================\r\n // CRITICAL: FILE MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n const fileMessageTypes = [\r\n 'file_transfer_start',\r\n 'file_transfer_response', \r\n 'file_chunk',\r\n 'chunk_confirmation',\r\n 'file_transfer_complete',\r\n 'file_transfer_error'\r\n ];\r\n \r\n if (parsed.type && fileMessageTypes.includes(parsed.type)) {\r\n\r\n if (!this.fileTransferSystem) {\r\n try {\r\n if (this.isVerified && this.dataChannel && this.dataChannel.readyState === 'open') {\r\n this.initializeFileTransfer();\r\n\r\n let attempts = 0;\r\n const maxAttempts = 30;\r\n while (!this.fileTransferSystem && attempts < maxAttempts) {\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n attempts++;\r\n }\r\n }\r\n } catch (initError) {\r\n this._secureLog('error', 'Failed to initialize file transfer system for receiver:', { errorType: initError?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n if (this.fileTransferSystem) {\r\n await this.fileTransferSystem.handleFileMessage(parsed);\r\n return;\r\n }\r\n // Attempt lazy initialization on receiver side\r\n this._secureLog('warn', '\u26A0\uFE0F File transfer system not ready, attempting lazy init...');\r\n try {\r\n await this._ensureFileTransferReady();\r\n if (this.fileTransferSystem) {\r\n await this.fileTransferSystem.handleFileMessage(parsed);\r\n return;\r\n }\r\n } catch (e) {\r\n this._secureLog('error', 'Lazy init of file transfer failed:', { errorType: e?.message || e?.constructor?.name || 'Unknown' });\r\n }\r\n this._secureLog('error', 'No file transfer system available for:', { errorType: parsed.type?.constructor?.name || 'Unknown' });\r\n return; // IMPORTANT: Do not process further\r\n }\r\n \r\n // ============================================\r\n // SYSTEM MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type && ['heartbeat', 'verification', 'verification_response', 'verification_confirmed', 'verification_both_confirmed', 'sas_code', 'peer_disconnect', 'security_upgrade'].includes(parsed.type)) {\r\n this.handleSystemMessage(parsed);\r\n return;\r\n }\r\n \r\n // ============================================\r\n // REGULAR USER MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'message' && parsed.data) {\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(parsed.data, 'received');\r\n }\r\n return;\r\n }\r\n \r\n // ============================================\r\n // ENHANCED MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'enhanced_message' && parsed.data) {\r\n await this._processEnhancedMessageWithoutMutex(parsed);\r\n return;\r\n }\r\n \r\n \r\n } catch (jsonError) {\r\n // Not JSON \u2014 treat as regular text message\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(event.data, 'received');\r\n }\r\n return;\r\n }\r\n } else if (event.data instanceof ArrayBuffer) {\r\n await this._processBinaryDataWithoutMutex(event.data);\r\n } else {\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to process message in onmessage:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n };\r\n }\r\n // FIX 4: New method for processing binary data WITHOUT mutex\r\n async _processBinaryDataWithoutMutex(data) {\r\n try {\r\n \r\n // Apply security layers WITHOUT mutex\r\n let processedData = data;\r\n \r\n // Nested Encryption Removal (if enabled)\r\n if (this.securityFeatures.hasNestedEncryption && \r\n this.nestedEncryptionKey && \r\n processedData instanceof ArrayBuffer &&\r\n processedData.byteLength > 12) {\r\n \r\n try {\r\n processedData = await this.removeNestedEncryption(processedData);\r\n } catch (error) {\r\n this._secureLog('warn', 'Nested decryption failed, continuing with original data');\r\n }\r\n }\r\n \r\n // Packet Padding Removal (if enabled)\r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removePacketPadding(processedData);\r\n } catch (error) {\r\n this._secureLog('warn', 'Packet padding removal failed, continuing with original data');\r\n }\r\n }\r\n \r\n // Anti-Fingerprinting Removal (if enabled)\r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removeAntiFingerprinting(processedData);\r\n } catch (error) {\r\n this._secureLog('warn', 'Anti-fingerprinting removal failed, continuing with original data');\r\n }\r\n }\r\n \r\n // Convert to text\r\n if (processedData instanceof ArrayBuffer) {\r\n const textData = new TextDecoder().decode(processedData);\r\n \r\n // Check for fake messages\r\n try {\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n return;\r\n }\r\n } catch (e) {\r\n // Not JSON \u2014 fine for plain text\r\n }\r\n \r\n // Deliver message to user\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(textData, 'received');\r\n }\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Error processing binary data:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n // FIX 3: New method for processing enhanced messages WITHOUT mutex\r\n async _processEnhancedMessageWithoutMutex(parsedMessage) {\r\n try {\r\n \r\n if (!this.encryptionKey || !this.macKey || !this.metadataKey) {\r\n this._secureLog('error', 'Missing encryption keys for enhanced message');\r\n return;\r\n }\r\n \r\n const decryptedResult = await window.EnhancedSecureCryptoUtils.decryptMessage(\r\n parsedMessage.data,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey\r\n );\r\n \r\n if (decryptedResult && decryptedResult.message) {\r\n \r\n // Try parsing JSON and showing nested text if it's a chat message\r\n try {\r\n const decryptedContent = JSON.parse(decryptedResult.message);\r\n if (decryptedContent.type === 'fake' || decryptedContent.isFakeTraffic === true) {\r\n return;\r\n }\r\n if (decryptedContent && decryptedContent.type === 'message' && typeof decryptedContent.data === 'string') {\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(decryptedContent.data, 'received');\r\n }\r\n return;\r\n }\r\n } catch (e) {\r\n // Not JSON \u2014 fine for plain text\r\n }\r\n \r\n // Otherwise pass as-is\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(decryptedResult.message, 'received');\r\n }\r\n } else {\r\n this._secureLog('warn', 'No message content in decrypted result');\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Error processing enhanced message:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n /**\r\n * Creates a unique ID for an operation\r\n */\r\n _generateOperationId() {\r\n return `op_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n }\r\n\r\n /**\r\n * Atomic mutex acquisition with enhanced race condition protection\r\n */\r\n async _acquireMutex(mutexName, operationId, timeout = 5000) {\r\n // Build correct mutex property name\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Unknown mutex: ${mutexName}`, {\r\n mutexPropertyName: mutexPropertyName,\r\n availableMutexes: this._getAvailableMutexes(),\r\n operationId: operationId\r\n });\r\n throw new Error(`Unknown mutex: ${mutexName}. Available: ${this._getAvailableMutexes().join(', ')}`);\r\n }\r\n \r\n // Validate operation ID\r\n if (!operationId || typeof operationId !== 'string') {\r\n throw new Error('Invalid operation ID for mutex acquisition');\r\n }\r\n \r\n return new Promise((resolve, reject) => {\r\n // Atomic lock attempt with immediate state check\r\n const attemptLock = () => {\r\n // Check if mutex is already locked by this operation\r\n if (mutex.lockId === operationId) {\r\n this._secureLog('warn', `Mutex '${mutexName}' already locked by same operation`, {\r\n operationId: operationId\r\n });\r\n resolve();\r\n return;\r\n }\r\n \r\n // Atomic check and lock operation\r\n if (!mutex.locked) {\r\n // Set lock state atomically\r\n mutex.locked = true;\r\n mutex.lockId = operationId;\r\n mutex.lockTime = Date.now();\r\n \r\n this._secureLog('debug', `Mutex '${mutexName}' acquired atomically`, {\r\n operationId: operationId,\r\n lockTime: mutex.lockTime\r\n });\r\n \r\n // Set timeout for automatic release with enhanced validation\r\n mutex.lockTimeout = setTimeout(() => {\r\n // Enhanced timeout handling with state validation\r\n this._handleMutexTimeout(mutexName, operationId, timeout);\r\n }, timeout);\r\n \r\n resolve();\r\n } else {\r\n // Add to queue with timeout\r\n const queueItem = { \r\n resolve, \r\n reject, \r\n operationId,\r\n timestamp: Date.now(),\r\n timeout: setTimeout(() => {\r\n // Remove from queue on timeout\r\n const index = mutex.queue.findIndex(item => item.operationId === operationId);\r\n if (index !== -1) {\r\n mutex.queue.splice(index, 1);\r\n reject(new Error(`Mutex acquisition timeout for '${mutexName}'`));\r\n }\r\n }, timeout)\r\n };\r\n \r\n mutex.queue.push(queueItem);\r\n \r\n this._secureLog('debug', `Operation queued for mutex '${mutexName}'`, {\r\n operationId: operationId,\r\n queueLength: mutex.queue.length,\r\n currentLockId: mutex.lockId\r\n });\r\n }\r\n };\r\n \r\n // Execute lock attempt immediately\r\n attemptLock();\r\n });\r\n }\r\n\r\n /**\r\n * Enhanced mutex release with strict validation and error handling\r\n */\r\n _releaseMutex(mutexName, operationId) {\r\n // Validate input parameters\r\n if (!mutexName || typeof mutexName !== 'string') {\r\n throw new Error('Invalid mutex name provided for release');\r\n }\r\n \r\n if (!operationId || typeof operationId !== 'string') {\r\n throw new Error('Invalid operation ID provided for mutex release');\r\n }\r\n \r\n // Build correct mutex property name\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Unknown mutex for release: ${mutexName}`, {\r\n mutexPropertyName: mutexPropertyName,\r\n availableMutexes: this._getAvailableMutexes(),\r\n operationId: operationId\r\n });\r\n throw new Error(`Unknown mutex for release: ${mutexName}`);\r\n }\r\n \r\n // Strict validation of lock ownership\r\n if (mutex.lockId !== operationId) {\r\n this._secureLog('error', `CRITICAL: Invalid mutex release attempt - potential race condition`, {\r\n mutexName: mutexName,\r\n expectedLockId: mutex.lockId,\r\n providedOperationId: operationId,\r\n mutexState: {\r\n locked: mutex.locked,\r\n lockTime: mutex.lockTime,\r\n queueLength: mutex.queue.length\r\n }\r\n });\r\n \r\n // Throw error instead of silent failure\r\n throw new Error(`Invalid mutex release attempt for '${mutexName}': expected '${mutex.lockId}', got '${operationId}'`);\r\n }\r\n \r\n // Validate mutex is actually locked\r\n if (!mutex.locked) {\r\n this._secureLog('error', `CRITICAL: Attempting to release unlocked mutex`, {\r\n mutexName: mutexName,\r\n operationId: operationId,\r\n mutexState: {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n lockTime: mutex.lockTime\r\n }\r\n });\r\n throw new Error(`Attempting to release unlocked mutex: ${mutexName}`);\r\n }\r\n \r\n try {\r\n // Clear timeout first\r\n if (mutex.lockTimeout) {\r\n clearTimeout(mutex.lockTimeout);\r\n mutex.lockTimeout = null;\r\n }\r\n \r\n // Calculate lock duration for monitoring\r\n const lockDuration = mutex.lockTime ? Date.now() - mutex.lockTime : 0;\r\n \r\n // Atomic release with state validation\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTime = null;\r\n \r\n this._secureLog('debug', `Mutex released successfully: ${mutexName}`, {\r\n operationId: operationId,\r\n lockDuration: lockDuration,\r\n queueLength: mutex.queue.length\r\n });\r\n \r\n // Process next in queue with enhanced error handling\r\n this._processNextInQueue(mutexName);\r\n \r\n } catch (error) {\r\n // If queue processing fails, ensure mutex is still released\r\n this._secureLog('error', `Error during mutex release queue processing`, {\r\n mutexName: mutexName,\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Ensure mutex is released even if queue processing fails\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTime = null;\r\n mutex.lockTimeout = null;\r\n \r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Enhanced queue processing with comprehensive error handling\r\n */\r\n _processNextInQueue(mutexName) {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Mutex not found for queue processing: ${mutexName}`);\r\n return;\r\n }\r\n \r\n if (mutex.queue.length === 0) {\r\n return;\r\n }\r\n \r\n // Validate mutex state before processing queue\r\n if (mutex.locked) {\r\n this._secureLog('warn', `Mutex '${mutexName}' is still locked, skipping queue processing`, {\r\n lockId: mutex.lockId,\r\n queueLength: mutex.queue.length\r\n });\r\n return;\r\n }\r\n \r\n // Get next item from queue atomically with validation\r\n const nextItem = mutex.queue.shift();\r\n \r\n if (!nextItem) {\r\n this._secureLog('warn', `Empty queue item for mutex '${mutexName}'`);\r\n return;\r\n }\r\n \r\n // Validate queue item structure\r\n if (!nextItem.operationId || !nextItem.resolve || !nextItem.reject) {\r\n this._secureLog('error', `Invalid queue item structure for mutex '${mutexName}'`, {\r\n hasOperationId: !!nextItem.operationId,\r\n hasResolve: !!nextItem.resolve,\r\n hasReject: !!nextItem.reject\r\n });\r\n return;\r\n }\r\n \r\n try {\r\n // Clear timeout for this item\r\n if (nextItem.timeout) {\r\n clearTimeout(nextItem.timeout);\r\n }\r\n \r\n // Attempt to acquire lock for next item\r\n this._secureLog('debug', `Processing next operation in queue for mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n queueRemaining: mutex.queue.length,\r\n timestamp: Date.now()\r\n });\r\n \r\n // Retry lock acquisition for queued operation with enhanced error handling\r\n setTimeout(async () => {\r\n try {\r\n await this._acquireMutex(mutexName, nextItem.operationId, 5000);\r\n \r\n this._secureLog('debug', `Queued operation acquired mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n acquisitionTime: Date.now()\r\n });\r\n \r\n nextItem.resolve();\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Queued operation failed to acquire mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n timestamp: Date.now()\r\n });\r\n \r\n // Reject with detailed error information\r\n nextItem.reject(new Error(`Queue processing failed for '${mutexName}': ${error.message}`));\r\n \r\n // Continue processing queue even if one item fails\r\n setTimeout(() => {\r\n this._processNextInQueue(mutexName);\r\n }, 50);\r\n }\r\n }, 10); // Small delay to prevent immediate re-acquisition\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Critical error during queue processing for mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Reject the operation and continue processing\r\n try {\r\n nextItem.reject(new Error(`Queue processing critical error: ${error.message}`));\r\n } catch (rejectError) {\r\n this._secureLog('error', `Failed to reject queue item`, {\r\n originalError: error.message,\r\n rejectError: rejectError.message\r\n });\r\n }\r\n \r\n // Continue processing remaining queue items\r\n setTimeout(() => {\r\n this._processNextInQueue(mutexName);\r\n }, 100);\r\n }\r\n }\r\n\r\n _getAvailableMutexes() {\r\n const mutexes = [];\r\n const propertyNames = Object.getOwnPropertyNames(this);\r\n \r\n for (const prop of propertyNames) {\r\n if (prop.endsWith('Mutex') && prop.startsWith('_')) {\r\n // Extract mutex name without prefix/suffix\r\n const mutexName = prop.slice(1, -5); // Remove '_' prefix and 'Mutex' suffix\r\n mutexes.push(mutexName);\r\n }\r\n }\r\n \r\n return mutexes;\r\n }\r\n\r\n /**\r\n * Enhanced mutex execution with atomic operations\r\n */\r\n async _withMutex(mutexName, operation, timeout = 5000) {\r\n const operationId = this._generateOperationId();\r\n \r\n // Validate mutex system before operation\r\n if (!this._validateMutexSystem()) {\r\n this._secureLog('error', 'Mutex system not properly initialized', {\r\n operationId: operationId,\r\n mutexName: mutexName\r\n });\r\n throw new Error('Mutex system not properly initialized. Call _initializeMutexSystem() first.');\r\n }\r\n \r\n // Get mutex reference with validation\r\n const mutex = this[`_${mutexName}Mutex`];\r\n if (!mutex) {\r\n throw new Error(`Mutex '${mutexName}' not found`);\r\n }\r\n \r\n let mutexAcquired = false;\r\n \r\n try {\r\n // Atomic mutex acquisition with timeout\r\n await this._acquireMutex(mutexName, operationId, timeout);\r\n mutexAcquired = true;\r\n \r\n // Increment operation counter atomically\r\n const counterKey = `${mutexName}Operations`;\r\n if (this._operationCounters && this._operationCounters[counterKey] !== undefined) {\r\n this._operationCounters[counterKey]++;\r\n }\r\n \r\n // Execute operation with enhanced error handling\r\n const result = await operation(operationId);\r\n \r\n // Validate result before returning\r\n if (result === undefined && operation.name !== 'cleanup') {\r\n this._secureLog('warn', 'Mutex operation returned undefined result', {\r\n operationId: operationId,\r\n mutexName: mutexName,\r\n operationName: operation.name\r\n });\r\n }\r\n \r\n return result;\r\n \r\n } catch (error) {\r\n // Enhanced error logging with context\r\n this._secureLog('error', 'Error in mutex operation', {\r\n operationId: operationId,\r\n mutexName: mutexName,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n mutexAcquired: mutexAcquired,\r\n mutexState: mutex ? {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n queueLength: mutex.queue.length\r\n } : 'null'\r\n });\r\n \r\n // If this is a key operation error, trigger emergency recovery\r\n if (mutexName === 'keyOperation') {\r\n this._handleKeyOperationError(error, operationId);\r\n }\r\n \r\n // Trigger emergency unlock for critical mutex errors\r\n if (error.message.includes('timeout') || error.message.includes('race condition')) {\r\n this._emergencyUnlockAllMutexes('errorHandler');\r\n }\r\n \r\n throw error;\r\n } finally {\r\n // Always release mutex in finally block with validation\r\n if (mutexAcquired) {\r\n try {\r\n await this._releaseMutex(mutexName, operationId);\r\n \r\n // Verify mutex was properly released\r\n if (mutex.locked && mutex.lockId === operationId) {\r\n this._secureLog('error', 'Mutex release verification failed', {\r\n operationId: operationId,\r\n mutexName: mutexName\r\n });\r\n // Force release as fallback\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n }\r\n \r\n } catch (releaseError) {\r\n this._secureLog('error', 'Error releasing mutex in finally block', {\r\n operationId: operationId,\r\n mutexName: mutexName,\r\n releaseErrorType: releaseError.constructor.name,\r\n releaseErrorMessage: releaseError.message\r\n });\r\n \r\n // Force release on error\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n }\r\n }\r\n }\r\n }\r\n\r\n _validateMutexSystem() {\r\n const requiredMutexes = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n \r\n for (const mutexName of requiredMutexes) {\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (!mutex || typeof mutex !== 'object') {\r\n this._secureLog('error', `Missing or invalid mutex: ${mutexName}`, {\r\n mutexPropertyName: mutexPropertyName,\r\n mutexType: typeof mutex\r\n });\r\n return false;\r\n }\r\n \r\n // Validate mutex structure\r\n const requiredProps = ['locked', 'queue', 'lockId', 'lockTimeout'];\r\n for (const prop of requiredProps) {\r\n if (!(prop in mutex)) {\r\n this._secureLog('error', `Mutex ${mutexName} missing property: ${prop}`);\r\n return false;\r\n }\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n\r\n /**\r\n * Enhanced emergency recovery of the mutex system\r\n */\r\n _emergencyRecoverMutexSystem() {\r\n this._secureLog('warn', 'Emergency mutex system recovery initiated');\r\n \r\n try {\r\n // Emergency unlock all mutexes first\r\n this._emergencyUnlockAllMutexes('emergencyRecovery');\r\n \r\n // Force re-initialize the system\r\n this._initializeMutexSystem();\r\n \r\n // Validate recovery success\r\n if (!this._validateMutexSystem()) {\r\n throw new Error('Mutex system validation failed after recovery');\r\n }\r\n \r\n this._secureLog('info', 'Mutex system recovered successfully with validation');\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to recover mutex system', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Last resort - force re-initialization\r\n try {\r\n this._initializeMutexSystem();\r\n this._secureLog('warn', 'Forced mutex system re-initialization completed');\r\n return true;\r\n } catch (reinitError) {\r\n this._secureLog('error', 'CRITICAL: Forced re-initialization also failed', {\r\n originalError: error.message,\r\n reinitError: reinitError.message\r\n });\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Atomic key generation with race condition protection\r\n */\r\n async _generateEncryptionKeys() {\r\n return this._withMutex('keyOperation', async (operationId) => {\r\n this._secureLog('info', 'Generating encryption keys with atomic mutex', {\r\n operationId: operationId\r\n });\r\n \r\n // Atomic state check and update using mutex lock\r\n const currentState = this._keySystemState;\r\n \r\n // Atomic check - if already initializing, wait or fail\r\n if (currentState.isInitializing) {\r\n this._secureLog('warn', 'Key generation already in progress, waiting for completion', {\r\n operationId: operationId,\r\n lastOperation: currentState.lastOperation,\r\n lastOperationTime: currentState.lastOperationTime\r\n });\r\n \r\n // Wait for existing operation to complete\r\n let waitAttempts = 0;\r\n const maxWaitAttempts = 50; // 5 seconds max wait\r\n \r\n while (currentState.isInitializing && waitAttempts < maxWaitAttempts) {\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n waitAttempts++;\r\n }\r\n \r\n if (currentState.isInitializing) {\r\n throw new Error('Key generation timeout - operation still in progress after 5 seconds');\r\n }\r\n }\r\n \r\n // Atomic state update within mutex protection\r\n try {\r\n // Set state atomically within mutex\r\n currentState.isInitializing = true;\r\n currentState.lastOperation = 'generation';\r\n currentState.lastOperationTime = Date.now();\r\n currentState.operationId = operationId;\r\n \r\n this._secureLog('debug', 'Atomic key generation state set', {\r\n operationId: operationId,\r\n timestamp: currentState.lastOperationTime\r\n });\r\n \r\n // Generate keys with individual error handling\r\n let ecdhKeyPair = null;\r\n let ecdsaKeyPair = null;\r\n \r\n // Generate ephemeral ECDH keys for PFS\r\n try {\r\n ecdhKeyPair = await this._generateEphemeralECDHKeys();\r\n \r\n // Validate ECDH keys immediately\r\n if (!ecdhKeyPair || !ecdhKeyPair.privateKey || !ecdhKeyPair.publicKey) {\r\n throw new Error('Ephemeral ECDH key pair validation failed');\r\n }\r\n \r\n // Constant-time validation for key types\r\n if (!this._validateKeyPairConstantTime(ecdhKeyPair)) {\r\n throw new Error('Ephemeral ECDH keys are not valid CryptoKey instances');\r\n }\r\n \r\n this._secureLog('debug', 'Ephemeral ECDH keys generated and validated for PFS', {\r\n operationId: operationId,\r\n privateKeyHash: await this._createSafeLogHash(ecdhKeyPair.privateKey, 'ecdh_private'),\r\n publicKeyHash: await this._createSafeLogHash(ecdhKeyPair.publicKey, 'ecdh_public'),\r\n privateKeyType: ecdhKeyPair.privateKey.algorithm?.name,\r\n publicKeyType: ecdhKeyPair.publicKey.algorithm?.name,\r\n isEphemeral: true\r\n });\r\n \r\n } catch (ecdhError) {\r\n this._secureLog('error', 'Ephemeral ECDH key generation failed', {\r\n operationId: operationId,\r\n errorType: ecdhError.constructor.name\r\n });\r\n this._throwSecureError(ecdhError, 'ephemeral_ecdh_key_generation');\r\n }\r\n \r\n // Generate ECDSA keys with retry mechanism\r\n try {\r\n ecdsaKeyPair = await window.EnhancedSecureCryptoUtils.generateECDSAKeyPair();\r\n \r\n // Validate ECDSA keys immediately\r\n if (!ecdsaKeyPair || !ecdsaKeyPair.privateKey || !ecdsaKeyPair.publicKey) {\r\n throw new Error('ECDSA key pair validation failed');\r\n }\r\n \r\n // Constant-time validation for key types\r\n if (!this._validateKeyPairConstantTime(ecdsaKeyPair)) {\r\n throw new Error('ECDSA keys are not valid CryptoKey instances');\r\n }\r\n \r\n this._secureLog('debug', 'ECDSA keys generated and validated', {\r\n operationId: operationId,\r\n privateKeyHash: await this._createSafeLogHash(ecdsaKeyPair.privateKey, 'ecdsa_private'),\r\n publicKeyHash: await this._createSafeLogHash(ecdsaKeyPair.publicKey, 'ecdsa_public'),\r\n privateKeyType: ecdsaKeyPair.privateKey.algorithm?.name,\r\n publicKeyType: ecdsaKeyPair.publicKey.algorithm?.name\r\n });\r\n \r\n } catch (ecdsaError) {\r\n this._secureLog('error', 'ECDSA key generation failed', {\r\n operationId: operationId,\r\n errorType: ecdsaError.constructor.name\r\n });\r\n this._throwSecureError(ecdsaError, 'ecdsa_key_generation');\r\n }\r\n \r\n // Final validation of both key pairs\r\n if (!ecdhKeyPair || !ecdsaKeyPair) {\r\n throw new Error('One or both key pairs failed to generate');\r\n }\r\n \r\n // Enable security features after successful key generation\r\n this._enableSecurityFeaturesAfterKeyGeneration(ecdhKeyPair, ecdsaKeyPair);\r\n \r\n this._secureLog('info', 'Encryption keys generated successfully with atomic protection', {\r\n operationId: operationId,\r\n hasECDHKeys: !!(ecdhKeyPair?.privateKey && ecdhKeyPair?.publicKey),\r\n hasECDSAKeys: !!(ecdsaKeyPair?.privateKey && ecdsaKeyPair?.publicKey),\r\n generationTime: Date.now() - currentState.lastOperationTime\r\n });\r\n \r\n return { ecdhKeyPair, ecdsaKeyPair };\r\n \r\n } catch (error) {\r\n // Ensure state is reset on any error\r\n this._secureLog('error', 'Key generation failed, resetting state', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n throw error;\r\n } finally {\r\n // Always reset state in finally block\r\n currentState.isInitializing = false;\r\n currentState.operationId = null;\r\n \r\n this._secureLog('debug', 'Key generation state reset', {\r\n operationId: operationId\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Enable security features after successful key generation\r\n */\r\n _enableSecurityFeaturesAfterKeyGeneration(ecdhKeyPair, ecdsaKeyPair) {\r\n try {\r\n // Enable encryption features based on available keys\r\n if (ecdhKeyPair && ecdhKeyPair.privateKey && ecdhKeyPair.publicKey) {\r\n this.securityFeatures.hasEncryption = true;\r\n this.securityFeatures.hasECDH = true;\r\n this._secureLog('info', 'ECDH encryption features enabled');\r\n }\r\n \r\n if (ecdsaKeyPair && ecdsaKeyPair.privateKey && ecdsaKeyPair.publicKey) {\r\n this.securityFeatures.hasECDSA = true;\r\n this._secureLog('info', 'ECDSA signature features enabled');\r\n }\r\n \r\n // Enable additional features that depend on encryption\r\n if (this.securityFeatures.hasEncryption) {\r\n this.securityFeatures.hasMetadataProtection = true;\r\n this.securityFeatures.hasEnhancedReplayProtection = true;\r\n this.securityFeatures.hasNonExtractableKeys = true;\r\n this._secureLog('info', 'Additional encryption-dependent features enabled');\r\n }\r\n \r\n // Enable PFS after ephemeral key generation\r\n if (ecdhKeyPair && this.ephemeralKeyPairs.size > 0) {\r\n this.securityFeatures.hasPFS = true;\r\n this._secureLog('info', 'Perfect Forward Secrecy enabled with ephemeral keys');\r\n }\r\n \r\n this._secureLog('info', 'Security features updated after key generation', {\r\n hasEncryption: this.securityFeatures.hasEncryption,\r\n hasECDH: this.securityFeatures.hasECDH,\r\n hasECDSA: this.securityFeatures.hasECDSA,\r\n hasMetadataProtection: this.securityFeatures.hasMetadataProtection,\r\n hasEnhancedReplayProtection: this.securityFeatures.hasEnhancedReplayProtection,\r\n hasNonExtractableKeys: this.securityFeatures.hasNonExtractableKeys,\r\n hasPFS: this.securityFeatures.hasPFS\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to enable security features after key generation', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Enhanced emergency mutex unlocking with authorization and validation\r\n */\r\n _emergencyUnlockAllMutexes(callerContext = 'unknown') {\r\n // Validate caller authorization\r\n const authorizedCallers = [\r\n 'keyOperation', 'cryptoOperation', 'connectionOperation',\r\n 'emergencyRecovery', 'systemShutdown', 'errorHandler'\r\n ];\r\n \r\n if (!authorizedCallers.includes(callerContext)) {\r\n this._secureLog('error', `UNAUTHORIZED emergency mutex unlock attempt`, {\r\n callerContext: callerContext,\r\n authorizedCallers: authorizedCallers,\r\n timestamp: Date.now()\r\n });\r\n throw new Error(`Unauthorized emergency mutex unlock attempt by: ${callerContext}`);\r\n }\r\n \r\n const mutexes = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n \r\n this._secureLog('error', 'EMERGENCY: Unlocking all mutexes with authorization and state cleanup', {\r\n callerContext: callerContext,\r\n timestamp: Date.now()\r\n });\r\n \r\n let unlockedCount = 0;\r\n let errorCount = 0;\r\n \r\n mutexes.forEach(mutexName => {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n if (mutex) {\r\n try {\r\n // Clear timeout first\r\n if (mutex.lockTimeout) {\r\n clearTimeout(mutex.lockTimeout);\r\n }\r\n \r\n // Log mutex state before emergency unlock\r\n const previousState = {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n lockTime: mutex.lockTime,\r\n queueLength: mutex.queue.length\r\n };\r\n \r\n // Reset mutex state atomically\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n mutex.lockTime = null;\r\n \r\n // Clear queue with proper error handling and logging\r\n let queueRejectCount = 0;\r\n mutex.queue.forEach(item => {\r\n try {\r\n if (item.reject && typeof item.reject === 'function') {\r\n item.reject(new Error(`Emergency mutex unlock for ${mutexName} by ${callerContext}`));\r\n queueRejectCount++;\r\n }\r\n } catch (rejectError) {\r\n this._secureLog('warn', `Failed to reject queue item during emergency unlock`, {\r\n mutexName: mutexName,\r\n errorType: rejectError.constructor.name\r\n });\r\n }\r\n });\r\n \r\n // Clear queue array\r\n mutex.queue = [];\r\n \r\n unlockedCount++;\r\n \r\n this._secureLog('debug', `Emergency unlocked mutex: ${mutexName}`, {\r\n previousState: previousState,\r\n queueRejectCount: queueRejectCount,\r\n callerContext: callerContext\r\n });\r\n \r\n } catch (error) {\r\n errorCount++;\r\n this._secureLog('error', `Error during emergency unlock of mutex: ${mutexName}`, {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n callerContext: callerContext\r\n });\r\n }\r\n }\r\n });\r\n \r\n // Reset key system state with validation\r\n if (this._keySystemState) {\r\n try {\r\n const previousKeyState = { ...this._keySystemState };\r\n \r\n this._keySystemState.isInitializing = false;\r\n this._keySystemState.isRotating = false;\r\n this._keySystemState.isDestroying = false;\r\n this._keySystemState.operationId = null;\r\n this._keySystemState.concurrentOperations = 0;\r\n \r\n this._secureLog('debug', `Emergency reset key system state`, {\r\n previousState: previousKeyState,\r\n callerContext: callerContext\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Error resetting key system state during emergency unlock`, {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n callerContext: callerContext\r\n });\r\n }\r\n }\r\n \r\n // Log emergency unlock summary\r\n this._secureLog('info', `Emergency mutex unlock completed`, {\r\n callerContext: callerContext,\r\n unlockedCount: unlockedCount,\r\n errorCount: errorCount,\r\n totalMutexes: mutexes.length,\r\n timestamp: Date.now()\r\n });\r\n \r\n // Trigger system validation after emergency unlock\r\n setTimeout(() => {\r\n this._validateMutexSystemAfterEmergencyUnlock();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Handle key operation errors with recovery mechanisms\r\n */\r\n _handleKeyOperationError(error, operationId) {\r\n this._secureLog('error', 'Key operation error detected, initiating recovery', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Reset key system state immediately\r\n if (this._keySystemState) {\r\n this._keySystemState.isInitializing = false;\r\n this._keySystemState.isRotating = false;\r\n this._keySystemState.isDestroying = false;\r\n this._keySystemState.operationId = null;\r\n }\r\n \r\n // Clear any partial key data\r\n this.ecdhKeyPair = null;\r\n this.ecdsaKeyPair = null;\r\n this.encryptionKey = null;\r\n this.macKey = null;\r\n this.metadataKey = null;\r\n \r\n // Trigger emergency recovery if needed\r\n if (error.message.includes('timeout') || error.message.includes('race condition')) {\r\n this._secureLog('warn', 'Race condition or timeout detected, triggering emergency recovery');\r\n this._emergencyRecoverMutexSystem();\r\n }\r\n }\r\n\r\n /**\r\n * Generate cryptographically secure IV with reuse prevention\r\n */\r\n _generateSecureIV(ivSize = 12, context = 'general') {\r\n // Check if we're in emergency mode\r\n if (this._ivTrackingSystem.emergencyMode) {\r\n this._secureLog('error', 'CRITICAL: IV generation blocked - emergency mode active due to IV reuse');\r\n throw new Error('IV generation blocked - emergency mode active');\r\n }\r\n \r\n let attempts = 0;\r\n const maxAttempts = 100; // Prevent infinite loops\r\n \r\n while (attempts < maxAttempts) {\r\n attempts++;\r\n \r\n // Generate fresh IV with crypto.getRandomValues\r\n const iv = crypto.getRandomValues(new Uint8Array(ivSize));\r\n \r\n // Convert IV to string for tracking\r\n const ivString = Array.from(iv).map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n // Check for IV reuse\r\n if (this._ivTrackingSystem.usedIVs.has(ivString)) {\r\n this._ivTrackingSystem.collisionCount++;\r\n this._secureLog('error', `CRITICAL: IV reuse detected!`, {\r\n context: context,\r\n attempt: attempts,\r\n collisionCount: this._ivTrackingSystem.collisionCount,\r\n ivString: ivString.substring(0, 16) + '...' // Log partial IV for debugging\r\n });\r\n \r\n // If too many collisions, trigger emergency mode\r\n if (this._ivTrackingSystem.collisionCount > 5) {\r\n this._ivTrackingSystem.emergencyMode = true;\r\n this._secureLog('error', 'CRITICAL: Emergency mode activated due to excessive IV reuse');\r\n throw new Error('Emergency mode: Excessive IV reuse detected');\r\n }\r\n \r\n continue; // Try again\r\n }\r\n \r\n // Validate IV entropy\r\n if (!this._validateIVEntropy(iv)) {\r\n this._ivTrackingSystem.entropyValidation.entropyFailures++;\r\n this._secureLog('warn', `Low entropy IV detected`, {\r\n context: context,\r\n attempt: attempts,\r\n entropyFailures: this._ivTrackingSystem.entropyValidation.entropyFailures\r\n });\r\n \r\n // If too many entropy failures, trigger emergency mode\r\n if (this._ivTrackingSystem.entropyValidation.entropyFailures > 10) {\r\n this._ivTrackingSystem.emergencyMode = true;\r\n this._secureLog('error', 'CRITICAL: Emergency mode activated due to low entropy IVs');\r\n throw new Error('Emergency mode: Low entropy IVs detected');\r\n }\r\n \r\n continue; // Try again\r\n }\r\n \r\n // Track IV usage\r\n this._ivTrackingSystem.usedIVs.add(ivString);\r\n this._ivTrackingSystem.ivHistory.set(ivString, {\r\n timestamp: Date.now(),\r\n context: context,\r\n attempt: attempts\r\n });\r\n \r\n // Track per-session IVs\r\n if (this.sessionId) {\r\n if (!this._ivTrackingSystem.sessionIVs.has(this.sessionId)) {\r\n this._ivTrackingSystem.sessionIVs.set(this.sessionId, new Set());\r\n }\r\n this._ivTrackingSystem.sessionIVs.get(this.sessionId).add(ivString);\r\n }\r\n \r\n // Validate RNG periodically\r\n this._validateRNGQuality();\r\n \r\n this._secureLog('debug', `Secure IV generated`, {\r\n context: context,\r\n attempt: attempts,\r\n ivSize: ivSize,\r\n totalIVs: this._ivTrackingSystem.usedIVs.size\r\n });\r\n \r\n return iv;\r\n }\r\n \r\n // If we can't generate a unique IV after max attempts\r\n this._secureLog('error', `Failed to generate unique IV after ${maxAttempts} attempts`, {\r\n context: context,\r\n totalIVs: this._ivTrackingSystem.usedIVs.size\r\n });\r\n throw new Error(`Failed to generate unique IV after ${maxAttempts} attempts`);\r\n }\r\n \r\n /**\r\n * Validate IV entropy to detect weak RNG\r\n */\r\n _validateIVEntropy(iv) {\r\n this._ivTrackingSystem.entropyValidation.entropyTests++;\r\n \r\n // Calculate byte distribution\r\n const byteCounts = new Array(256).fill(0);\r\n for (let i = 0; i < iv.length; i++) {\r\n byteCounts[iv[i]]++;\r\n }\r\n \r\n // Multi-dimensional entropy analysis\r\n const entropyResults = {\r\n shannon: 0,\r\n min: 0,\r\n collision: 0,\r\n compression: 0,\r\n quantum: 0\r\n };\r\n \r\n // 1. Shannon entropy calculation\r\n let shannonEntropy = 0;\r\n const totalBytes = iv.length;\r\n \r\n for (let i = 0; i < 256; i++) {\r\n if (byteCounts[i] > 0) {\r\n const probability = byteCounts[i] / totalBytes;\r\n shannonEntropy -= probability * Math.log2(probability);\r\n }\r\n }\r\n entropyResults.shannon = shannonEntropy;\r\n \r\n // 2. Min-entropy calculation (worst-case scenario)\r\n const maxCount = Math.max(...byteCounts);\r\n const maxProbability = maxCount / totalBytes;\r\n entropyResults.min = -Math.log2(maxProbability);\r\n \r\n // 3. Collision entropy calculation\r\n let collisionSum = 0;\r\n for (let i = 0; i < 256; i++) {\r\n if (byteCounts[i] > 0) {\r\n const probability = byteCounts[i] / totalBytes;\r\n collisionSum += probability * probability;\r\n }\r\n }\r\n entropyResults.collision = -Math.log2(collisionSum);\r\n \r\n // 4. Compression-based entropy estimation\r\n const ivString = Array.from(iv).map(b => String.fromCharCode(b)).join('');\r\n const compressedLength = this._estimateCompressedLength(ivString);\r\n entropyResults.compression = (1 - compressedLength / totalBytes) * 8;\r\n \r\n // 5. Quantum-resistant entropy analysis\r\n entropyResults.quantum = this._calculateQuantumResistantEntropy(iv);\r\n \r\n // Enhanced suspicious pattern detection\r\n const hasSuspiciousPatterns = this._detectAdvancedSuspiciousPatterns(iv);\r\n \r\n // Multi-criteria validation\r\n const minEntropyThreshold = this._ivTrackingSystem.entropyValidation.minEntropy;\r\n const isValid = (\r\n entropyResults.shannon >= minEntropyThreshold &&\r\n entropyResults.min >= minEntropyThreshold * 0.8 &&\r\n entropyResults.collision >= minEntropyThreshold * 0.9 &&\r\n entropyResults.compression >= minEntropyThreshold * 0.7 &&\r\n entropyResults.quantum >= minEntropyThreshold * 0.6 &&\r\n !hasSuspiciousPatterns\r\n );\r\n \r\n if (!isValid) {\r\n this._secureLog('warn', `Enhanced IV entropy validation failed`, {\r\n shannon: entropyResults.shannon.toFixed(2),\r\n min: entropyResults.min.toFixed(2),\r\n collision: entropyResults.collision.toFixed(2),\r\n compression: entropyResults.compression.toFixed(2),\r\n quantum: entropyResults.quantum.toFixed(2),\r\n minThreshold: minEntropyThreshold,\r\n hasSuspiciousPatterns: hasSuspiciousPatterns\r\n });\r\n }\r\n \r\n return isValid;\r\n }\r\n \r\n /**\r\n * Estimate compressed length for entropy calculation\r\n * @param {string} data - Data to estimate compression\r\n * @returns {number} Estimated compressed length\r\n */\r\n _estimateCompressedLength(data) {\r\n // Simple LZ77-like compression estimation\r\n let compressedLength = 0;\r\n let i = 0;\r\n \r\n while (i < data.length) {\r\n let matchLength = 0;\r\n let matchDistance = 0;\r\n \r\n // Look for repeated patterns\r\n for (let j = Math.max(0, i - 255); j < i; j++) {\r\n let k = 0;\r\n while (i + k < data.length && data[i + k] === data[j + k] && k < 255) {\r\n k++;\r\n }\r\n if (k > matchLength) {\r\n matchLength = k;\r\n matchDistance = i - j;\r\n }\r\n }\r\n \r\n if (matchLength >= 3) {\r\n compressedLength += 3; // Distance + length + literal\r\n i += matchLength;\r\n } else {\r\n compressedLength += 1;\r\n i += 1;\r\n }\r\n }\r\n \r\n return compressedLength;\r\n }\r\n\r\n /**\r\n * Calculate quantum-resistant entropy\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {number} Quantum-resistant entropy score\r\n */\r\n _calculateQuantumResistantEntropy(data) {\r\n // Quantum-resistant entropy analysis\r\n let quantumScore = 0;\r\n \r\n // 1. Check for quantum-vulnerable patterns\r\n const hasQuantumVulnerablePatterns = this._detectQuantumVulnerablePatterns(data);\r\n if (hasQuantumVulnerablePatterns) {\r\n quantumScore -= 2;\r\n }\r\n \r\n // 2. Analyze bit distribution\r\n const bitDistribution = this._analyzeBitDistribution(data);\r\n quantumScore += bitDistribution.score;\r\n \r\n // 3. Check for periodicity\r\n const periodicity = this._detectPeriodicity(data);\r\n quantumScore -= periodicity * 0.5;\r\n \r\n // 4. Normalize to 0-8 range\r\n return Math.max(0, Math.min(8, quantumScore));\r\n }\r\n\r\n /**\r\n * Detect quantum-vulnerable patterns\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {boolean} true if quantum-vulnerable patterns found\r\n */\r\n _detectQuantumVulnerablePatterns(data) {\r\n // Check for patterns vulnerable to quantum attacks\r\n const patterns = [\r\n [0, 0, 0, 0, 0, 0, 0, 0], // All zeros\r\n [255, 255, 255, 255, 255, 255, 255, 255], // All ones\r\n [0, 1, 0, 1, 0, 1, 0, 1], // Alternating\r\n [1, 0, 1, 0, 1, 0, 1, 0] // Alternating reverse\r\n ];\r\n \r\n for (const pattern of patterns) {\r\n for (let i = 0; i <= data.length - pattern.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < pattern.length; j++) {\r\n if (data[i + j] !== pattern[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return true;\r\n }\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Analyze bit distribution\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {Object} Bit distribution analysis\r\n */\r\n _analyzeBitDistribution(data) {\r\n let ones = 0;\r\n let totalBits = data.length * 8;\r\n \r\n for (const byte of data) {\r\n ones += (byte >>> 0).toString(2).split('1').length - 1;\r\n }\r\n \r\n const zeroRatio = (totalBits - ones) / totalBits;\r\n const oneRatio = ones / totalBits;\r\n \r\n // Ideal distribution is 50/50\r\n const deviation = Math.abs(0.5 - oneRatio);\r\n const score = Math.max(0, 8 - deviation * 16);\r\n \r\n return { score, zeroRatio, oneRatio, deviation };\r\n }\r\n\r\n /**\r\n * Detect periodicity in data\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {number} Periodicity score (0-1)\r\n */\r\n _detectPeriodicity(data) {\r\n if (data.length < 16) return 0;\r\n \r\n let maxPeriodicity = 0;\r\n \r\n // Check for periods from 2 to data.length/2\r\n for (let period = 2; period <= data.length / 2; period++) {\r\n let matches = 0;\r\n let totalChecks = 0;\r\n \r\n for (let i = 0; i < data.length - period; i++) {\r\n if (data[i] === data[i + period]) {\r\n matches++;\r\n }\r\n totalChecks++;\r\n }\r\n \r\n if (totalChecks > 0) {\r\n const periodicity = matches / totalChecks;\r\n maxPeriodicity = Math.max(maxPeriodicity, periodicity);\r\n }\r\n }\r\n \r\n return maxPeriodicity;\r\n }\r\n\r\n /**\r\n * Enhanced suspicious pattern detection\r\n * @param {Uint8Array} iv - IV to check\r\n * @returns {boolean} true if suspicious patterns found\r\n */\r\n _detectAdvancedSuspiciousPatterns(iv) {\r\n // Enhanced pattern detection with quantum-resistant analysis\r\n const patterns = [\r\n // Sequential patterns\r\n [0, 1, 2, 3, 4, 5, 6, 7],\r\n [255, 254, 253, 252, 251, 250, 249, 248],\r\n \r\n // Repeated patterns\r\n [0, 0, 0, 0, 0, 0, 0, 0],\r\n [255, 255, 255, 255, 255, 255, 255, 255],\r\n \r\n // Alternating patterns\r\n [0, 255, 0, 255, 0, 255, 0, 255],\r\n [255, 0, 255, 0, 255, 0, 255, 0]\r\n ];\r\n \r\n for (const pattern of patterns) {\r\n for (let i = 0; i <= iv.length - pattern.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < pattern.length; j++) {\r\n if (iv[i + j] !== pattern[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return true;\r\n }\r\n }\r\n \r\n // Check for low entropy regions\r\n const entropyMap = this._calculateLocalEntropy(iv);\r\n const lowEntropyRegions = entropyMap.filter(e => e < 3.0).length;\r\n \r\n return lowEntropyRegions > iv.length * 0.3; // More than 30% low entropy\r\n }\r\n\r\n /**\r\n * Calculate local entropy for pattern detection\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {Array} Array of local entropy values\r\n */\r\n _calculateLocalEntropy(data) {\r\n const windowSize = 8;\r\n const entropyMap = [];\r\n \r\n for (let i = 0; i <= data.length - windowSize; i++) {\r\n const window = data.slice(i, i + windowSize);\r\n const charCount = {};\r\n \r\n for (const byte of window) {\r\n charCount[byte] = (charCount[byte] || 0) + 1;\r\n }\r\n \r\n let entropy = 0;\r\n for (const count of Object.values(charCount)) {\r\n const probability = count / windowSize;\r\n entropy -= probability * Math.log2(probability);\r\n }\r\n \r\n entropyMap.push(entropy);\r\n }\r\n \r\n return entropyMap;\r\n }\r\n\r\n /**\r\n * Detect suspicious patterns in IVs\r\n */\r\n _detectSuspiciousIVPatterns(iv) {\r\n // Check for all zeros or all ones\r\n const allZeros = iv.every(byte => byte === 0);\r\n const allOnes = iv.every(byte => byte === 255);\r\n \r\n if (allZeros || allOnes) {\r\n return true;\r\n }\r\n \r\n // Check for sequential patterns\r\n let sequentialCount = 0;\r\n for (let i = 1; i < iv.length; i++) {\r\n if (iv[i] === iv[i-1] + 1 || iv[i] === iv[i-1] - 1) {\r\n sequentialCount++;\r\n } else {\r\n sequentialCount = 0;\r\n }\r\n \r\n if (sequentialCount >= 3) {\r\n return true; // Suspicious sequential pattern\r\n }\r\n }\r\n \r\n // Check for repeated patterns\r\n for (let patternLength = 2; patternLength <= Math.floor(iv.length / 2); patternLength++) {\r\n for (let start = 0; start <= iv.length - patternLength * 2; start++) {\r\n const pattern1 = iv.slice(start, start + patternLength);\r\n const pattern2 = iv.slice(start + patternLength, start + patternLength * 2);\r\n \r\n if (pattern1.every((byte, index) => byte === pattern2[index])) {\r\n return true; // Repeated pattern detected\r\n }\r\n }\r\n }\r\n \r\n return false;\r\n }\r\n \r\n /**\r\n * Clean up old IVs with strict limits\r\n */\r\n async _cleanupOldIVs() {\r\n const now = Date.now();\r\n const maxAge = 1800000; // Reduced to 30 minutes for better security\r\n let cleanedCount = 0;\r\n const cleanupBatch = [];\r\n \r\n // Aggressive cleanup with quantum-resistant patterns\r\n // Enforce maximum IV history size with batch processing\r\n if (this._ivTrackingSystem.ivHistory.size > this._ivTrackingSystem.maxIVHistorySize) {\r\n const ivArray = Array.from(this._ivTrackingSystem.ivHistory.entries());\r\n const toRemove = ivArray.slice(0, ivArray.length - this._ivTrackingSystem.maxIVHistorySize);\r\n \r\n for (const [ivString] of toRemove) {\r\n cleanupBatch.push(ivString);\r\n cleanedCount++;\r\n \r\n // Process in batches to prevent memory spikes\r\n if (cleanupBatch.length >= 100) {\r\n this._processCleanupBatch(cleanupBatch);\r\n cleanupBatch.length = 0;\r\n }\r\n }\r\n }\r\n \r\n // Clean up old IVs from history by age with enhanced security\r\n for (const [ivString, metadata] of this._ivTrackingSystem.ivHistory.entries()) {\r\n if (now - metadata.timestamp > maxAge) {\r\n cleanupBatch.push(ivString);\r\n cleanedCount++;\r\n \r\n // Process in batches to prevent memory spikes\r\n if (cleanupBatch.length >= 100) {\r\n this._processCleanupBatch(cleanupBatch);\r\n cleanupBatch.length = 0;\r\n }\r\n }\r\n }\r\n \r\n // Process remaining batch\r\n if (cleanupBatch.length > 0) {\r\n this._processCleanupBatch(cleanupBatch);\r\n }\r\n \r\n // Enhanced session IV cleanup with entropy preservation\r\n for (const [sessionId, sessionIVs] of this._ivTrackingSystem.sessionIVs.entries()) {\r\n if (sessionIVs.size > this._ivTrackingSystem.maxSessionIVs) {\r\n const ivArray = Array.from(sessionIVs);\r\n const toRemove = ivArray.slice(0, ivArray.length - this._ivTrackingSystem.maxSessionIVs);\r\n \r\n for (const ivString of toRemove) {\r\n sessionIVs.delete(ivString);\r\n this._ivTrackingSystem.usedIVs.delete(ivString);\r\n this._ivTrackingSystem.ivHistory.delete(ivString);\r\n cleanedCount++;\r\n }\r\n }\r\n }\r\n \r\n // Schedule natural cleanup if significant cleanup occurred\r\n if (cleanedCount > 50) {\r\n await this._performNaturalCleanup();\r\n }\r\n \r\n if (cleanedCount > 0) {\r\n this._secureLog('debug', `Enhanced cleanup: ${cleanedCount} old IVs removed`, {\r\n cleanedCount: cleanedCount,\r\n remainingIVs: this._ivTrackingSystem.usedIVs.size,\r\n remainingHistory: this._ivTrackingSystem.ivHistory.size,\r\n memoryPressure: this._calculateMemoryPressure()\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Process cleanup batch with constant-time operations\r\n * @param {Array} batch - Batch of items to clean up\r\n */\r\n _processCleanupBatch(batch) {\r\n // Constant-time batch processing\r\n for (const item of batch) {\r\n this._ivTrackingSystem.usedIVs.delete(item);\r\n this._ivTrackingSystem.ivHistory.delete(item);\r\n }\r\n }\r\n\r\n /**\r\n * Calculate memory pressure for adaptive cleanup\r\n * @returns {number} Memory pressure score (0-100)\r\n */\r\n _calculateMemoryPressure() {\r\n const totalIVs = this._ivTrackingSystem.usedIVs.size;\r\n const maxAllowed = this._resourceLimits.maxIVHistory;\r\n \r\n return Math.min(100, Math.floor((totalIVs / maxAllowed) * 100));\r\n }\r\n\r\n /**\r\n * Get IV tracking system statistics\r\n */\r\n _getIVTrackingStats() {\r\n return {\r\n totalIVs: this._ivTrackingSystem.usedIVs.size,\r\n collisionCount: this._ivTrackingSystem.collisionCount,\r\n entropyTests: this._ivTrackingSystem.entropyValidation.entropyTests,\r\n entropyFailures: this._ivTrackingSystem.entropyValidation.entropyFailures,\r\n rngTests: this._ivTrackingSystem.rngValidation.testsPerformed,\r\n weakRngDetected: this._ivTrackingSystem.rngValidation.weakRngDetected,\r\n emergencyMode: this._ivTrackingSystem.emergencyMode,\r\n sessionCount: this._ivTrackingSystem.sessionIVs.size,\r\n lastCleanup: this._lastIVCleanupTime || 0\r\n };\r\n }\r\n \r\n /**\r\n * Reset IV tracking system (for testing or emergency recovery)\r\n */\r\n _resetIVTrackingSystem() {\r\n this._secureLog('warn', 'Resetting IV tracking system');\r\n \r\n this._ivTrackingSystem.usedIVs.clear();\r\n this._ivTrackingSystem.ivHistory.clear();\r\n this._ivTrackingSystem.sessionIVs.clear();\r\n this._ivTrackingSystem.collisionCount = 0;\r\n this._ivTrackingSystem.entropyValidation.entropyTests = 0;\r\n this._ivTrackingSystem.entropyValidation.entropyFailures = 0;\r\n this._ivTrackingSystem.rngValidation.testsPerformed = 0;\r\n this._ivTrackingSystem.rngValidation.weakRngDetected = false;\r\n this._ivTrackingSystem.emergencyMode = false;\r\n \r\n this._secureLog('info', 'IV tracking system reset completed');\r\n }\r\n \r\n /**\r\n * Validate RNG quality\r\n */\r\n _validateRNGQuality() {\r\n const now = Date.now();\r\n \r\n // Validate RNG every 1000 IV generations\r\n if (this._ivTrackingSystem.rngValidation.testsPerformed % 1000 === 0) {\r\n try {\r\n // Generate test IVs and validate\r\n const testIVs = [];\r\n for (let i = 0; i < 100; i++) {\r\n testIVs.push(crypto.getRandomValues(new Uint8Array(12)));\r\n }\r\n \r\n // Check for duplicates in test set\r\n const testIVStrings = testIVs.map(iv => Array.from(iv).map(b => b.toString(16).padStart(2, '0')).join(''));\r\n const uniqueTestIVs = new Set(testIVStrings);\r\n \r\n if (uniqueTestIVs.size < 95) { // Allow some tolerance\r\n this._ivTrackingSystem.rngValidation.weakRngDetected = true;\r\n this._secureLog('error', 'CRITICAL: Weak RNG detected in validation test', {\r\n uniqueIVs: uniqueTestIVs.size,\r\n totalTests: testIVs.length\r\n });\r\n }\r\n \r\n this._ivTrackingSystem.rngValidation.lastValidation = now;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'RNG validation failed', {\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n this._ivTrackingSystem.rngValidation.testsPerformed++;\r\n }\r\n \r\n /**\r\n * Handle mutex timeout with enhanced state validation\r\n */\r\n _handleMutexTimeout(mutexName, operationId, timeout) {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Mutex '${mutexName}' not found during timeout handling`);\r\n return;\r\n }\r\n \r\n // Validate timeout conditions\r\n if (mutex.lockId !== operationId) {\r\n this._secureLog('warn', `Timeout for different operation ID on mutex '${mutexName}'`, {\r\n expectedOperationId: operationId,\r\n actualLockId: mutex.lockId,\r\n locked: mutex.locked\r\n });\r\n return;\r\n }\r\n \r\n if (!mutex.locked) {\r\n this._secureLog('warn', `Timeout for already unlocked mutex '${mutexName}'`, {\r\n operationId: operationId\r\n });\r\n return;\r\n }\r\n \r\n try {\r\n // Calculate lock duration for monitoring\r\n const lockDuration = mutex.lockTime ? Date.now() - mutex.lockTime : 0;\r\n \r\n this._secureLog('warn', `Mutex '${mutexName}' auto-released due to timeout`, {\r\n operationId: operationId,\r\n lockDuration: lockDuration,\r\n timeout: timeout,\r\n queueLength: mutex.queue.length\r\n });\r\n \r\n // Atomic release with state validation\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n mutex.lockTime = null;\r\n \r\n // Process next in queue with error handling\r\n setTimeout(() => {\r\n try {\r\n this._processNextInQueue(mutexName);\r\n } catch (queueError) {\r\n this._secureLog('error', `Error processing queue after timeout for mutex '${mutexName}'`, {\r\n errorType: queueError.constructor.name,\r\n errorMessage: queueError.message\r\n });\r\n }\r\n }, 10);\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Critical error during mutex timeout handling for '${mutexName}'`, {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Force emergency unlock if timeout handling fails\r\n try {\r\n this._emergencyUnlockAllMutexes('timeoutHandler');\r\n } catch (emergencyError) {\r\n this._secureLog('error', `Emergency unlock failed during timeout handling`, {\r\n originalError: error.message,\r\n emergencyError: emergencyError.message\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validate mutex system after emergency unlock\r\n */\r\n _validateMutexSystemAfterEmergencyUnlock() {\r\n const mutexes = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n let validationErrors = 0;\r\n \r\n this._secureLog('info', 'Validating mutex system after emergency unlock');\r\n \r\n mutexes.forEach(mutexName => {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n \r\n if (!mutex) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' not found after emergency unlock`);\r\n return;\r\n }\r\n \r\n // Validate mutex state consistency\r\n if (mutex.locked) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still locked after emergency unlock`, {\r\n lockId: mutex.lockId,\r\n lockTime: mutex.lockTime\r\n });\r\n }\r\n \r\n if (mutex.lockId !== null) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still has lock ID after emergency unlock`, {\r\n lockId: mutex.lockId\r\n });\r\n }\r\n \r\n if (mutex.lockTimeout !== null) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still has timeout after emergency unlock`);\r\n }\r\n \r\n if (mutex.queue.length > 0) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still has queue items after emergency unlock`, {\r\n queueLength: mutex.queue.length\r\n });\r\n }\r\n });\r\n \r\n // Validate key system state\r\n if (this._keySystemState) {\r\n if (this._keySystemState.isInitializing || \r\n this._keySystemState.isRotating || \r\n this._keySystemState.isDestroying) {\r\n validationErrors++;\r\n this._secureLog('error', `Key system state not properly reset after emergency unlock`, {\r\n isInitializing: this._keySystemState.isInitializing,\r\n isRotating: this._keySystemState.isRotating,\r\n isDestroying: this._keySystemState.isDestroying\r\n });\r\n }\r\n }\r\n \r\n if (validationErrors === 0) {\r\n this._secureLog('info', 'Mutex system validation passed after emergency unlock');\r\n } else {\r\n this._secureLog('error', `Mutex system validation failed after emergency unlock`, {\r\n validationErrors: validationErrors\r\n });\r\n \r\n // Force re-initialization if validation fails\r\n setTimeout(() => {\r\n this._emergencyRecoverMutexSystem();\r\n }, 1000);\r\n }\r\n }\r\n /**\r\n * NEW: Diagnostics of the mutex system state\r\n */\r\n _getMutexSystemDiagnostics() {\r\n const diagnostics = {\r\n timestamp: Date.now(),\r\n systemValid: this._validateMutexSystem(),\r\n mutexes: {},\r\n counters: { ...this._operationCounters },\r\n keySystemState: { ...this._keySystemState }\r\n };\r\n \r\n const mutexNames = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n \r\n mutexNames.forEach(mutexName => {\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (mutex) {\r\n diagnostics.mutexes[mutexName] = {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n queueLength: mutex.queue.length,\r\n hasTimeout: !!mutex.lockTimeout\r\n };\r\n } else {\r\n diagnostics.mutexes[mutexName] = { error: 'not_found' };\r\n }\r\n });\r\n \r\n return diagnostics;\r\n }\r\n\r\n /**\r\n * FULLY FIXED createSecureOffer()\r\n * With race-condition protection and improved security\r\n */\r\n async createSecureOffer() {\r\n return this._withMutex('connectionOperation', async (operationId) => {\r\n this._secureLog('info', 'Creating secure offer with mutex', {\r\n operationId: operationId,\r\n connectionAttempts: this.connectionAttempts,\r\n currentState: this.peerConnection?.connectionState || 'none'\r\n });\r\n \r\n try {\r\n // ============================================\r\n // PHASE 1: INITIALIZATION AND VALIDATION\r\n // ============================================\r\n \r\n // Reset notification flags for a new connection\r\n this._resetNotificationFlags();\r\n \r\n // Rate limiting check\r\n if (!this._checkRateLimit()) {\r\n throw new Error('Connection rate limit exceeded. Please wait before trying again.');\r\n }\r\n \r\n // Reset attempt counters\r\n this.connectionAttempts = 0;\r\n \r\n // Generate session salt (64 bytes for v4.0)\r\n this.sessionSalt = window.EnhancedSecureCryptoUtils.generateSalt();\r\n \r\n this._secureLog('debug', 'Session salt generated', {\r\n operationId: operationId,\r\n saltLength: this.sessionSalt.length,\r\n isValidSalt: Array.isArray(this.sessionSalt) && this.sessionSalt.length === 64\r\n });\r\n \r\n // ============================================\r\n // PHASE 2: SECURE KEY GENERATION\r\n // ============================================\r\n \r\n // Secure key generation via mutex\r\n const keyPairs = await this._generateEncryptionKeys();\r\n this.ecdhKeyPair = keyPairs.ecdhKeyPair;\r\n this.ecdsaKeyPair = keyPairs.ecdsaKeyPair;\r\n \r\n // Validate generated keys\r\n if (!this.ecdhKeyPair?.privateKey || !this.ecdhKeyPair?.publicKey) {\r\n throw new Error('Failed to generate valid ECDH key pair');\r\n }\r\n \r\n if (!this.ecdsaKeyPair?.privateKey || !this.ecdsaKeyPair?.publicKey) {\r\n throw new Error('Failed to generate valid ECDSA key pair');\r\n }\r\n \r\n // ============================================\r\n // PHASE 3: MITM PROTECTION AND FINGERPRINTING\r\n // ============================================\r\n \r\n // MITM Protection: Compute unique key fingerprints\r\n const ecdhFingerprint = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(\r\n await crypto.subtle.exportKey('spki', this.ecdhKeyPair.publicKey)\r\n );\r\n const ecdsaFingerprint = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(\r\n await crypto.subtle.exportKey('spki', this.ecdsaKeyPair.publicKey)\r\n );\r\n \r\n // Validate fingerprints\r\n if (!ecdhFingerprint || !ecdsaFingerprint) {\r\n throw new Error('Failed to generate key fingerprints');\r\n }\r\n \r\n this._secureLog('info', 'Generated unique key pairs for MITM protection', {\r\n operationId: operationId,\r\n hasECDHFingerprint: !!ecdhFingerprint,\r\n hasECDSAFingerprint: !!ecdsaFingerprint,\r\n fingerprintLength: ecdhFingerprint.length,\r\n timestamp: Date.now()\r\n });\r\n \r\n // ============================================\r\n // PHASE 4: EXPORT SIGNED KEYS\r\n // ============================================\r\n \r\n // Export keys with digital signatures\r\n const ecdhPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdhKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDH'\r\n );\r\n \r\n const ecdsaPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdsaKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDSA'\r\n );\r\n\r\n \r\n if (!ecdhPublicKeyData || typeof ecdhPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDH key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdhPublicKeyData.keyData || !ecdhPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdhPublicKeyData.keyData,\r\n hasSignature: !!ecdhPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export incomplete - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData || typeof ecdsaPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData.keyData || !ecdsaPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdsaPublicKeyData.keyData,\r\n hasSignature: !!ecdsaPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export incomplete - hard abort required');\r\n }\r\n \r\n // ============================================\r\n // PHASE 5: UPDATE SECURITY FEATURES\r\n // ============================================\r\n \r\n // Atomic update of security features\r\n this._updateSecurityFeatures({\r\n hasEncryption: true,\r\n hasECDH: true,\r\n hasECDSA: true,\r\n hasMutualAuth: true,\r\n hasMetadataProtection: true,\r\n hasEnhancedReplayProtection: true,\r\n hasNonExtractableKeys: true,\r\n hasRateLimiting: true,\r\n hasEnhancedValidation: true,\r\n hasPFS: true\r\n });\r\n \r\n // ============================================\r\n // PHASE 6: INITIALIZE PEER CONNECTION\r\n // ============================================\r\n \r\n this.isInitiator = true;\r\n this.onStatusChange('connecting');\r\n \r\n // Create peer connection\r\n this.createPeerConnection();\r\n \r\n // Create main data channel\r\n this.dataChannel = this.peerConnection.createDataChannel('securechat', {\r\n ordered: true\r\n });\r\n \r\n // Setup data channel\r\n this.setupDataChannel(this.dataChannel);\r\n \r\n this._secureLog('debug', 'Data channel created', {\r\n operationId: operationId,\r\n channelLabel: this.dataChannel.label,\r\n channelOrdered: this.dataChannel.ordered\r\n });\r\n \r\n // ============================================\r\n // PHASE 7: CREATE SDP OFFER\r\n // ============================================\r\n \r\n\r\n const offer = await this.peerConnection.createOffer({\r\n offerToReceiveAudio: false,\r\n offerToReceiveVideo: false\r\n });\r\n \r\n await this.peerConnection.setLocalDescription(offer);\r\n\r\n try {\r\n const ourFingerprint = this._extractDTLSFingerprintFromSDP(offer.sdp);\r\n this.expectedDTLSFingerprint = ourFingerprint;\r\n \r\n this._secureLog('info', 'Generated DTLS fingerprint for out-of-band verification', {\r\n fingerprint: ourFingerprint,\r\n context: 'offer_creation'\r\n });\r\n \r\n // Notify UI that fingerprint is ready for out-of-band verification\r\n this.deliverMessageToUI(`DTLS fingerprint ready for verification: ${ourFingerprint}`, 'system');\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to extract DTLS fingerprint from offer', { error: error.message });\r\n // Continue without fingerprint validation (fallback mode)\r\n }\r\n \r\n // Await ICE gathering\r\n await this.waitForIceGathering();\r\n \r\n this._secureLog('debug', 'ICE gathering completed', {\r\n operationId: operationId,\r\n iceGatheringState: this.peerConnection.iceGatheringState,\r\n connectionState: this.peerConnection.connectionState\r\n });\r\n \r\n // ============================================\r\n // PHASE 8: GENERATE SAS FOR OUT-OF-BAND VERIFICATION\r\n // ============================================\r\n\r\n this.verificationCode = window.EnhancedSecureCryptoUtils.generateVerificationCode();\r\n \r\n // Validate verification code\r\n if (!this.verificationCode || this.verificationCode.length < EnhancedSecureWebRTCManager.SIZES.VERIFICATION_CODE_MIN_LENGTH) {\r\n throw new Error('Failed to generate valid verification code');\r\n }\r\n \r\n // ============================================\r\n // PHASE 9: MUTUAL AUTHENTICATION CHALLENGE\r\n // ============================================\r\n \r\n // Generate challenge for mutual authentication\r\n const authChallenge = window.EnhancedSecureCryptoUtils.generateMutualAuthChallenge();\r\n \r\n if (!authChallenge) {\r\n throw new Error('Failed to generate mutual authentication challenge');\r\n }\r\n \r\n // ============================================\r\n // PHASE 10: SESSION ID FOR MITM PROTECTION\r\n // ============================================\r\n \r\n // MITM Protection: Generate session-specific ID\r\n this.sessionId = Array.from(crypto.getRandomValues(new Uint8Array(EnhancedSecureWebRTCManager.SIZES.SESSION_ID_LENGTH)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n // Validate session ID\r\n if (!this.sessionId || this.sessionId.length !== (EnhancedSecureWebRTCManager.SIZES.SESSION_ID_LENGTH * 2)) {\r\n throw new Error('Failed to generate valid session ID');\r\n }\r\n \r\n // Generate connection ID for AAD\r\n this.connectionId = Array.from(crypto.getRandomValues(new Uint8Array(8)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n // ============================================\r\n // PHASE 11: SECURITY LEVEL CALCULATION\r\n // ============================================\r\n \r\n // All security features are enabled by default\r\n const securityLevel = {\r\n level: 'MAXIMUM',\r\n score: 100,\r\n color: 'green',\r\n details: 'All security features enabled by default',\r\n passedChecks: 10,\r\n totalChecks: 10,\r\n isRealData: true\r\n };\r\n \r\n // ============================================\r\n // PHASE 12: CREATE OFFER PACKAGE\r\n // ============================================\r\n \r\n const currentTimestamp = Date.now();\r\n \r\n // Create compact offer package for smaller QR codes\r\n const offerPackage = {\r\n // Core information (minimal)\r\n t: 'offer', // type\r\n s: this.peerConnection.localDescription.sdp, // sdp\r\n v: '4.0', // version\r\n ts: currentTimestamp, // timestamp\r\n \r\n // Cryptographic keys (essential)\r\n e: ecdhPublicKeyData, // ecdhPublicKey\r\n d: ecdsaPublicKeyData, // ecdsaPublicKey\r\n \r\n // Session data (essential)\r\n sl: this.sessionSalt, // salt\r\n si: this.sessionId, // sessionId\r\n ci: this.connectionId, // connectionId\r\n \r\n // Authentication (essential)\r\n vc: this.verificationCode, // verificationCode\r\n ac: authChallenge, // authChallenge\r\n \r\n // Security metadata (simplified)\r\n slv: 'MAX', // securityLevel\r\n \r\n // Key fingerprints (shortened)\r\n kf: {\r\n e: ecdhFingerprint.substring(0, 12), // ecdh (12 chars)\r\n d: ecdsaFingerprint.substring(0, 12) // ecdsa (12 chars)\r\n }\r\n };\r\n \r\n // ============================================\r\n // PHASE 13: VALIDATE OFFER PACKAGE\r\n // ============================================\r\n\r\n try {\r\n const validationResult = this.validateEnhancedOfferData(offerPackage);\r\n\r\n } catch (validationError) {\r\n throw new Error(`Offer package validation error: ${validationError.message}`);\r\n }\r\n \r\n // ============================================\r\n // PHASE 14: LOGGING AND EVENTS\r\n // ============================================\r\n \r\n this._secureLog('info', 'Enhanced secure offer created successfully', {\r\n operationId: operationId,\r\n version: offerPackage.version,\r\n hasECDSA: true,\r\n hasMutualAuth: true,\r\n hasSessionId: !!offerPackage.sessionId,\r\n securityLevel: securityLevel.level,\r\n timestamp: currentTimestamp,\r\n capabilitiesCount: 10 // All capabilities enabled by default\r\n });\r\n \r\n // Dispatch event about new connection\r\n document.dispatchEvent(new CustomEvent('new-connection', {\r\n detail: { \r\n type: 'offer',\r\n timestamp: currentTimestamp,\r\n securityLevel: securityLevel.level,\r\n operationId: operationId\r\n }\r\n }));\r\n\r\n return offerPackage;\r\n \r\n } catch (error) {\r\n // ============================================\r\n // ERROR HANDLING\r\n // ============================================\r\n \r\n this._secureLog('error', 'Enhanced secure offer creation failed in critical section', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n phase: this._determineErrorPhase(error),\r\n connectionAttempts: this.connectionAttempts\r\n });\r\n \r\n // Cleanup state on error\r\n this._cleanupFailedOfferCreation();\r\n \r\n // Update status\r\n this.onStatusChange('disconnected');\r\n \r\n // Re-throw for upper-level handling\r\n throw error;\r\n }\r\n }, 15000); // 15 seconds timeout for the entire offer creation\r\n }\r\n\r\n /**\r\n * HELPER: Determine the phase where the error occurred\r\n */\r\n _determineErrorPhase(error) {\r\n const message = error.message.toLowerCase();\r\n \r\n if (message.includes('rate limit')) return 'rate_limiting';\r\n if (message.includes('key pair') || message.includes('generate')) return 'key_generation';\r\n if (message.includes('fingerprint')) return 'fingerprinting';\r\n if (message.includes('export') || message.includes('signature')) return 'key_export';\r\n if (message.includes('peer connection')) return 'webrtc_setup';\r\n if (message.includes('offer') || message.includes('sdp')) return 'sdp_creation';\r\n if (message.includes('verification')) return 'verification_setup';\r\n if (message.includes('session')) return 'session_setup';\r\n if (message.includes('validation')) return 'package_validation';\r\n \r\n return 'unknown';\r\n }\r\n\r\n /**\r\n * Secure cleanup state after failed offer creation\r\n */\r\n _cleanupFailedOfferCreation() {\r\n try {\r\n // Secure wipe of cryptographic materials\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Close peer connection if it was created\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Clear data channel\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n \r\n // Reset flags\r\n this.isInitiator = false;\r\n this.isVerified = false;\r\n \r\n // Reset security features to baseline\r\n this._updateSecurityFeatures({\r\n hasEncryption: false,\r\n hasECDH: false,\r\n hasECDSA: false,\r\n hasMutualAuth: false,\r\n hasMetadataProtection: false,\r\n hasEnhancedReplayProtection: false,\r\n hasNonExtractableKeys: false,\r\n hasEnhancedValidation: false,\r\n hasPFS: false\r\n });\r\n \r\n // Schedule natural cleanup\r\n this._forceGarbageCollection().catch(error => {\r\n this._secureLog('error', 'Cleanup failed during offer cleanup', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n \r\n this._secureLog('debug', 'Failed offer creation cleanup completed with secure memory wipe');\r\n \r\n } catch (cleanupError) {\r\n this._secureLog('error', 'Error during offer creation cleanup', {\r\n errorType: cleanupError.constructor.name,\r\n errorMessage: cleanupError.message\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * HELPER: Atomic update of security features (if not added yet)\r\n */\r\n _updateSecurityFeatures(updates) {\r\n const oldFeatures = { ...this.securityFeatures };\r\n \r\n try {\r\n Object.assign(this.securityFeatures, updates);\r\n \r\n this._secureLog('debug', 'Security features updated', {\r\n updatedCount: Object.keys(updates).length,\r\n totalFeatures: Object.keys(this.securityFeatures).length\r\n });\r\n \r\n } catch (error) {\r\n // Roll back on error\r\n this.securityFeatures = oldFeatures;\r\n this._secureLog('error', 'Security features update failed, rolled back', {\r\n errorType: error.constructor.name\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * FULLY FIXED METHOD createSecureAnswer()\r\n * With race-condition protection and enhanced security\r\n */\r\n async createSecureAnswer(offerData) {\r\n return this._withMutex('connectionOperation', async (operationId) => {\r\n this._secureLog('info', 'Creating secure answer with mutex', {\r\n operationId: operationId,\r\n hasOfferData: !!offerData,\r\n offerType: offerData?.type,\r\n offerVersion: offerData?.version,\r\n offerTimestamp: offerData?.timestamp\r\n });\r\n \r\n try {\r\n // ============================================\r\n // PHASE 1: PRE-VALIDATION OF OFFER\r\n // ============================================\r\n \r\n // Reset notification flags for a new connection\r\n this._resetNotificationFlags();\r\n \r\n this._secureLog('debug', 'Starting enhanced offer validation', {\r\n operationId: operationId,\r\n hasOfferData: !!offerData,\r\n offerType: offerData?.type,\r\n hasECDHKey: !!offerData?.ecdhPublicKey,\r\n hasECDSAKey: !!offerData?.ecdsaPublicKey,\r\n hasSalt: !!offerData?.salt\r\n });\r\n \r\n // Strict input validation\r\n if (!this.validateEnhancedOfferData(offerData)) {\r\n throw new Error('Invalid connection data format - failed enhanced validation');\r\n }\r\n \r\n // Rate limiting check\r\n if (!window.EnhancedSecureCryptoUtils.rateLimiter.checkConnectionRate(this.rateLimiterId)) {\r\n throw new Error('Connection rate limit exceeded. Please wait before trying again.');\r\n }\r\n \r\n // ============================================\r\n // PHASE 2: SECURITY AND ANTI-REPLAY PROTECTION\r\n // ============================================\r\n \r\n // MITM Protection: Validate offer data structure (support both formats)\r\n const timestamp = offerData.ts || offerData.timestamp;\r\n const version = offerData.v || offerData.version;\r\n if (!timestamp || !version) {\r\n throw new Error('Missing required security fields in offer data \u2013 possible MITM attack');\r\n }\r\n \r\n // Replay attack protection (extended to 30 minutes for better UX)\r\n const offerAge = Date.now() - timestamp;\r\n const MAX_OFFER_AGE = 1800000; // 30 minutes for better user experience\r\n \r\n if (offerAge > MAX_OFFER_AGE) {\r\n this._secureLog('error', 'Offer data is too old - possible replay attack', {\r\n operationId: operationId,\r\n offerAge: Math.round(offerAge / 1000),\r\n maxAllowedAge: Math.round(MAX_OFFER_AGE / 1000),\r\n timestamp: offerData.timestamp\r\n });\r\n \r\n // Notify the main code about the replay attack\r\n if (this.onAnswerError) {\r\n this.onAnswerError('replay_attack', 'Offer data is too old \u2013 possible replay attack');\r\n }\r\n \r\n throw new Error('Offer data is too old \u2013 possible replay attack');\r\n }\r\n \r\n // Protocol version compatibility check (support both formats)\r\n const protocolVersion = version; // Use the version we already extracted\r\n if (protocolVersion !== '4.0') {\r\n this._secureLog('warn', 'Protocol version mismatch detected', {\r\n operationId: operationId,\r\n expectedVersion: '4.0',\r\n receivedVersion: protocolVersion\r\n });\r\n \r\n // For backward compatibility with v3.0, a fallback can be added\r\n if (protocolVersion !== '3.0') {\r\n throw new Error(`Unsupported protocol version: ${protocolVersion}`);\r\n }\r\n }\r\n \r\n // ============================================\r\n // PHASE 3: EXTRACT AND VALIDATE SESSION SALT\r\n // ============================================\r\n \r\n // Set session salt from offer (support both formats)\r\n this.sessionSalt = offerData.sl || offerData.salt;\r\n \r\n // Validate session salt\r\n if (!Array.isArray(this.sessionSalt)) {\r\n throw new Error('Invalid session salt format - must be array');\r\n }\r\n \r\n const expectedSaltLength = protocolVersion === '4.0' ? 64 : 32;\r\n if (this.sessionSalt.length !== expectedSaltLength) {\r\n throw new Error(`Invalid session salt length: expected ${expectedSaltLength}, got ${this.sessionSalt.length}`);\r\n }\r\n \r\n // MITM Protection: Check salt integrity\r\n const saltFingerprint = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(this.sessionSalt);\r\n \r\n this._secureLog('info', 'Session salt validated successfully', {\r\n operationId: operationId,\r\n saltLength: this.sessionSalt.length,\r\n saltFingerprint: saltFingerprint.substring(0, 8)\r\n });\r\n \r\n // ============================================\r\n // PHASE 4: SECURE GENERATION OF OUR KEYS\r\n // ============================================\r\n \r\n // Secure generation of our keys via mutex\r\n const keyPairs = await this._generateEncryptionKeys();\r\n this.ecdhKeyPair = keyPairs.ecdhKeyPair;\r\n this.ecdsaKeyPair = keyPairs.ecdsaKeyPair;\r\n \r\n // Additional validation of generated keys\r\n if (!(this.ecdhKeyPair?.privateKey instanceof CryptoKey)) {\r\n this._secureLog('error', 'Local ECDH private key is not a CryptoKey', {\r\n operationId: operationId,\r\n hasKeyPair: !!this.ecdhKeyPair,\r\n privateKeyType: typeof this.ecdhKeyPair?.privateKey,\r\n privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name\r\n });\r\n throw new Error('Local ECDH private key is not a valid CryptoKey');\r\n }\r\n \r\n // ============================================\r\n // PHASE 5: IMPORT AND VERIFY PEER KEYS\r\n // ============================================\r\n \r\n // Import peer ECDSA public key for signature verification (support both formats)\r\n let peerECDSAPublicKey;\r\n \r\n try {\r\n const ecdsaKey = offerData.d || offerData.ecdsaPublicKey;\r\n peerECDSAPublicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n new Uint8Array(ecdsaKey.keyData),\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-384'\r\n },\r\n false,\r\n ['verify']\r\n );\r\n } catch (error) {\r\n this._throwSecureError(error, 'ecdsa_key_import');\r\n }\r\n \r\n // ============================================\r\n // PHASE 6: IMPORT AND VERIFY ECDH KEY\r\n // ============================================\r\n \r\n // Import and verify ECDH public key using verified ECDSA key (support both formats)\r\n let peerECDHPublicKey;\r\n \r\n try {\r\n const ecdhKey = offerData.e || offerData.ecdhPublicKey;\r\n peerECDHPublicKey = await window.EnhancedSecureCryptoUtils.importSignedPublicKey(\r\n ecdhKey,\r\n peerECDSAPublicKey,\r\n 'ECDH'\r\n );\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to import signed ECDH public key', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._throwSecureError(error, 'ecdh_key_import');\r\n }\r\n \r\n // Final validation of ECDH key\r\n if (!(peerECDHPublicKey instanceof CryptoKey)) {\r\n this._secureLog('error', 'Peer ECDH public key is not a CryptoKey', {\r\n operationId: operationId,\r\n publicKeyType: typeof peerECDHPublicKey,\r\n publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name\r\n });\r\n throw new Error('Peer ECDH public key is not a valid CryptoKey');\r\n }\r\n \r\n // Save peer key for PFS rotation\r\n this.peerPublicKey = peerECDHPublicKey;\r\n \r\n // ============================================\r\n // PHASE 7: DERIVE SHARED ENCRYPTION KEYS\r\n // ============================================\r\n \r\n // Derive shared keys with metadata protection\r\n let derivedKeys;\r\n \r\n try {\r\n derivedKeys = await window.EnhancedSecureCryptoUtils.deriveSharedKeys(\r\n this.ecdhKeyPair.privateKey,\r\n peerECDHPublicKey,\r\n this.sessionSalt\r\n );\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to derive shared keys', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._throwSecureError(error, 'key_derivation');\r\n }\r\n \r\n // Securely set keys via helper\r\n await this._setEncryptionKeys(\r\n derivedKeys.encryptionKey,\r\n derivedKeys.macKey,\r\n derivedKeys.metadataKey,\r\n derivedKeys.fingerprint\r\n );\r\n \r\n // Additional validation of installed keys\r\n if (!(this.encryptionKey instanceof CryptoKey) || \r\n !(this.macKey instanceof CryptoKey) || \r\n !(this.metadataKey instanceof CryptoKey)) {\r\n \r\n this._secureLog('error', 'Invalid key types after derivation', {\r\n operationId: operationId,\r\n encryptionKeyType: typeof this.encryptionKey,\r\n macKeyType: typeof this.macKey,\r\n metadataKeyType: typeof this.metadataKey\r\n });\r\n throw new Error('Invalid key types after derivation');\r\n }\r\n \r\n // Set verification code from offer\r\n this.verificationCode = offerData.verificationCode;\r\n \r\n this._secureLog('info', 'Encryption keys derived and set successfully', {\r\n operationId: operationId,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n hasMetadataKey: !!this.metadataKey,\r\n hasKeyFingerprint: !!this.keyFingerprint,\r\n mitmProtection: 'enabled',\r\n signatureVerified: true\r\n });\r\n \r\n // ============================================\r\n // PHASE 8: UPDATE SECURITY FEATURES\r\n // ============================================\r\n \r\n // Atomic update of security features\r\n this._updateSecurityFeatures({\r\n hasEncryption: true,\r\n hasECDH: true,\r\n hasECDSA: true,\r\n hasMutualAuth: true,\r\n hasMetadataProtection: true,\r\n hasEnhancedReplayProtection: true,\r\n hasNonExtractableKeys: true,\r\n hasRateLimiting: true,\r\n hasEnhancedValidation: true,\r\n hasPFS: true\r\n });\r\n \r\n // PFS: Initialize key version tracking\r\n this.currentKeyVersion = 0;\r\n this.lastKeyRotation = Date.now();\r\n this.keyVersions.set(0, {\r\n salt: this.sessionSalt,\r\n timestamp: this.lastKeyRotation,\r\n messageCount: 0\r\n });\r\n \r\n // ============================================\r\n // PHASE 9: CREATE AUTHENTICATION PROOF\r\n // ============================================\r\n \r\n // Create proof for mutual authentication\r\n let authProof;\r\n \r\n if (offerData.authChallenge) {\r\n try {\r\n authProof = await window.EnhancedSecureCryptoUtils.createAuthProof(\r\n offerData.authChallenge,\r\n this.ecdsaKeyPair.privateKey,\r\n this.ecdsaKeyPair.publicKey\r\n );\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to create authentication proof', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._throwSecureError(error, 'authentication_proof_creation');\r\n }\r\n } else {\r\n this._secureLog('warn', 'No auth challenge in offer - mutual auth disabled', {\r\n operationId: operationId\r\n });\r\n }\r\n \r\n // ============================================\r\n // PHASE 10: INITIALIZE WEBRTC\r\n // ============================================\r\n \r\n this.isInitiator = false;\r\n this.onStatusChange('connecting');\r\n \r\n this.onKeyExchange(this.keyFingerprint);\r\n \r\n // Create peer connection first\r\n this.createPeerConnection();\r\n \r\n // Validate DTLS fingerprint before setting remote description\r\n if (this.strictDTLSValidation) {\r\n try {\r\n const receivedFingerprint = this._extractDTLSFingerprintFromSDP(offerData.sdp);\r\n \r\n if (this.expectedDTLSFingerprint) {\r\n await this._validateDTLSFingerprint(receivedFingerprint, this.expectedDTLSFingerprint, 'offer_validation');\r\n } else {\r\n // Store fingerprint for future validation (first connection)\r\n this.expectedDTLSFingerprint = receivedFingerprint;\r\n this._secureLog('info', 'Stored DTLS fingerprint for future validation', {\r\n fingerprint: receivedFingerprint,\r\n context: 'first_connection'\r\n });\r\n }\r\n } catch (error) {\r\n this._secureLog('warn', 'DTLS fingerprint validation failed - continuing in fallback mode', { \r\n error: error.message,\r\n context: 'offer_validation'\r\n });\r\n // Continue without strict fingerprint validation for first connection\r\n // This allows the connection to proceed while maintaining security awareness\r\n }\r\n } else {\r\n this._secureLog('info', 'DTLS fingerprint validation disabled - proceeding without validation');\r\n }\r\n\r\n // Set remote description from offer\r\n try {\r\n this._secureLog('debug', 'Setting remote description from offer', {\r\n operationId: operationId,\r\n sdpLength: offerData.sdp?.length || 0\r\n });\r\n \r\n await this.peerConnection.setRemoteDescription(new RTCSessionDescription({\r\n type: 'offer',\r\n sdp: offerData.s || offerData.sdp\r\n }));\r\n \r\n this._secureLog('debug', 'Remote description set successfully', {\r\n operationId: operationId,\r\n signalingState: this.peerConnection.signalingState\r\n });\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to set remote description', { \r\n error: error.message,\r\n operationId: operationId\r\n });\r\n this._throwSecureError(error, 'webrtc_remote_description');\r\n }\r\n \r\n this._secureLog('debug', 'Remote description set successfully', {\r\n operationId: operationId,\r\n connectionState: this.peerConnection.connectionState,\r\n signalingState: this.peerConnection.signalingState\r\n });\r\n \r\n // ============================================\r\n // PHASE 11: CREATE SDP ANSWER\r\n // ============================================\r\n \r\n // Create WebRTC answer\r\n let answer;\r\n \r\n try {\r\n answer = await this.peerConnection.createAnswer({\r\n offerToReceiveAudio: false,\r\n offerToReceiveVideo: false\r\n });\r\n } catch (error) {\r\n this._throwSecureError(error, 'webrtc_create_answer');\r\n }\r\n \r\n // Set local description\r\n try {\r\n await this.peerConnection.setLocalDescription(answer);\r\n } catch (error) {\r\n this._throwSecureError(error, 'webrtc_local_description');\r\n }\r\n \r\n // Extract and store our DTLS fingerprint for out-of-band verification\r\n try {\r\n const ourFingerprint = this._extractDTLSFingerprintFromSDP(answer.sdp);\r\n this.expectedDTLSFingerprint = ourFingerprint;\r\n \r\n this._secureLog('info', 'Generated DTLS fingerprint for out-of-band verification', {\r\n fingerprint: ourFingerprint,\r\n context: 'answer_creation'\r\n });\r\n \r\n // Notify UI that fingerprint is ready for out-of-band verification\r\n this.deliverMessageToUI(`DTLS fingerprint ready for verification: ${ourFingerprint}`, 'system');\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to extract DTLS fingerprint from answer', { error: error.message });\r\n // Continue without fingerprint validation (fallback mode)\r\n }\r\n \r\n \r\n // Await ICE gathering\r\n await this.waitForIceGathering();\r\n \r\n this._secureLog('debug', 'ICE gathering completed for answer', {\r\n operationId: operationId,\r\n iceGatheringState: this.peerConnection.iceGatheringState,\r\n connectionState: this.peerConnection.connectionState\r\n });\r\n \r\n // ============================================\r\n // PHASE 12: EXPORT OUR KEYS\r\n // ============================================\r\n \r\n // Export our keys with signatures\r\n const ecdhPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdhKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDH'\r\n );\r\n \r\n const ecdsaPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdsaKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDSA'\r\n );\r\n \r\n if (!ecdhPublicKeyData || typeof ecdhPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDH key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdhPublicKeyData.keyData || !ecdhPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdhPublicKeyData.keyData,\r\n hasSignature: !!ecdhPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export incomplete - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData || typeof ecdsaPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData.keyData || !ecdsaPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdsaPublicKeyData.keyData,\r\n hasSignature: !!ecdsaPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export incomplete - hard abort required');\r\n }\r\n \r\n // ============================================\r\n // PHASE 13: SECURITY LEVEL CALCULATION\r\n // ============================================\r\n \r\n // All security features are enabled by default\r\n const securityLevel = {\r\n level: 'MAXIMUM',\r\n score: 100,\r\n color: 'green',\r\n details: 'All security features enabled by default',\r\n passedChecks: 10,\r\n totalChecks: 10,\r\n isRealData: true\r\n };\r\n \r\n // ============================================\r\n // PHASE 14: CREATE ANSWER PACKAGE\r\n // ============================================\r\n \r\n const currentTimestamp = Date.now();\r\n \r\n // Create compact answer package for smaller QR codes\r\n const answerPackage = {\r\n // Core information (minimal)\r\n t: 'answer', // type\r\n s: this.peerConnection.localDescription.sdp, // sdp\r\n v: '4.0', // version\r\n ts: currentTimestamp, // timestamp\r\n \r\n // Cryptographic keys (essential)\r\n e: ecdhPublicKeyData, // ecdhPublicKey\r\n d: ecdsaPublicKeyData, // ecdsaPublicKey\r\n \r\n // Authentication (essential)\r\n ap: authProof, // authProof\r\n \r\n // Security metadata (simplified)\r\n slv: 'MAX', // securityLevel\r\n \r\n // Session confirmation (simplified)\r\n sc: {\r\n sf: saltFingerprint.substring(0, 12), // saltFingerprint (12 chars)\r\n kd: true, // keyDerivationSuccess\r\n ma: true // mutualAuthEnabled\r\n }\r\n };\r\n \r\n // ============================================\r\n // PHASE 15: VALIDATION AND LOGGING\r\n // ============================================\r\n \r\n // Final validation of the answer package (support both formats)\r\n const hasSDP = answerPackage.s || answerPackage.sdp;\r\n const hasECDH = answerPackage.e || answerPackage.ecdhPublicKey;\r\n const hasECDSA = answerPackage.d || answerPackage.ecdsaPublicKey;\r\n \r\n if (!hasSDP || !hasECDH || !hasECDSA) {\r\n throw new Error('Generated answer package is incomplete');\r\n }\r\n \r\n this._secureLog('info', 'Enhanced secure answer created successfully', {\r\n operationId: operationId,\r\n version: answerPackage.version,\r\n hasECDSA: true,\r\n hasMutualAuth: !!authProof,\r\n hasSessionConfirmation: !!answerPackage.sessionConfirmation,\r\n securityLevel: securityLevel.level,\r\n timestamp: currentTimestamp,\r\n processingTime: currentTimestamp - offerData.timestamp\r\n });\r\n \r\n // Dispatch event about new connection\r\n document.dispatchEvent(new CustomEvent('new-connection', {\r\n detail: { \r\n type: 'answer',\r\n timestamp: currentTimestamp,\r\n securityLevel: securityLevel.level,\r\n operationId: operationId\r\n }\r\n }));\r\n \r\n // ============================================\r\n // PHASE 16: SCHEDULE SECURITY CALCULATIONS\r\n // ============================================\r\n \r\n // Plan security calculation after connection\r\n setTimeout(async () => {\r\n try {\r\n const realSecurityData = await this.calculateAndReportSecurityLevel();\r\n if (realSecurityData) {\r\n this.notifySecurityUpdate();\r\n this._secureLog('info', 'Post-connection security level calculated', {\r\n operationId: operationId,\r\n level: realSecurityData.level\r\n });\r\n }\r\n } catch (error) {\r\n this._secureLog('error', 'Error calculating post-connection security', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }, 1000);\r\n \r\n // Retry if the first calculation fails\r\n setTimeout(async () => {\r\n if (!this.lastSecurityCalculation || this.lastSecurityCalculation.score < 50) {\r\n this._secureLog('info', 'Retrying security calculation', {\r\n operationId: operationId\r\n });\r\n await this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpdate();\r\n }\r\n }, 3000);\r\n \r\n // Final security update\r\n this.notifySecurityUpdate();\r\n \r\n // ============================================\r\n // PHASE 17: RETURN RESULT\r\n // ============================================\r\n \r\n return answerPackage;\r\n \r\n } catch (error) {\r\n // ============================================\r\n // ERROR HANDLING\r\n // ============================================\r\n \r\n this._secureLog('error', 'Enhanced secure answer creation failed in critical section', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n phase: this._determineAnswerErrorPhase(error),\r\n offerAge: offerData?.timestamp ? Date.now() - offerData.timestamp : 'unknown'\r\n });\r\n \r\n // Cleanup state on error\r\n this._cleanupFailedAnswerCreation();\r\n \r\n // Update status\r\n this.onStatusChange('disconnected');\r\n \r\n // Special handling of security errors\r\n if (this.onAnswerError) {\r\n if (error.message.includes('too old') || error.message.includes('replay')) {\r\n this.onAnswerError('replay_attack', error.message);\r\n } else if (error.message.includes('MITM') || error.message.includes('signature')) {\r\n this.onAnswerError('security_violation', error.message);\r\n } else if (error.message.includes('validation') || error.message.includes('format')) {\r\n this.onAnswerError('invalid_format', error.message);\r\n } else {\r\n this.onAnswerError('general_error', error.message);\r\n }\r\n }\r\n \r\n // Re-throw for upper-level handling\r\n throw error;\r\n }\r\n }, 20000); // 20 seconds timeout for the entire answer creation (longer than offer)\r\n }\r\n\r\n /**\r\n * HELPER: Determine error phase for answer\r\n */\r\n _determineAnswerErrorPhase(error) {\r\n const message = error.message.toLowerCase();\r\n \r\n if (message.includes('validation') || message.includes('format')) return 'offer_validation';\r\n if (message.includes('rate limit')) return 'rate_limiting';\r\n if (message.includes('replay') || message.includes('too old')) return 'replay_protection';\r\n if (message.includes('salt')) return 'salt_validation';\r\n if (message.includes('key pair') || message.includes('generate')) return 'key_generation';\r\n if (message.includes('import') || message.includes('ecdsa') || message.includes('ecdh')) return 'key_import';\r\n if (message.includes('signature') || message.includes('mitm')) return 'signature_verification';\r\n if (message.includes('derive') || message.includes('shared')) return 'key_derivation';\r\n if (message.includes('auth') || message.includes('proof')) return 'authentication';\r\n if (message.includes('remote description') || message.includes('local description')) return 'webrtc_setup';\r\n if (message.includes('answer') || message.includes('sdp')) return 'sdp_creation';\r\n if (message.includes('export')) return 'key_export';\r\n if (message.includes('security level')) return 'security_calculation';\r\n \r\n return 'unknown';\r\n }\r\n\r\n /**\r\n * HELPER: Cleanup state after failed answer creation\r\n */\r\n /**\r\n * Secure cleanup state after failed answer creation\r\n */\r\n _cleanupFailedAnswerCreation() {\r\n try {\r\n // Secure wipe of cryptographic materials\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Secure wipe of PFS key versions\r\n this.currentKeyVersion = 0;\r\n this.keyVersions.clear();\r\n this.oldKeys.clear();\r\n \r\n // Close peer connection if created\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Clear data channel\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n \r\n // Reset flags and counters\r\n this.isInitiator = false;\r\n this.isVerified = false;\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.messageCounter = 0;\r\n this.processedMessageIds.clear();\r\n this.replayWindow.clear(); // Clear replay window\r\n \r\n // Reset security features to baseline\r\n this._updateSecurityFeatures({\r\n hasEncryption: false,\r\n hasECDH: false,\r\n hasECDSA: false,\r\n hasMutualAuth: false,\r\n hasMetadataProtection: false,\r\n hasEnhancedReplayProtection: false,\r\n hasNonExtractableKeys: false,\r\n hasEnhancedValidation: false,\r\n hasPFS: false\r\n });\r\n \r\n // Schedule natural cleanup\r\n this._forceGarbageCollection().catch(error => {\r\n this._secureLog('error', 'Cleanup failed during answer cleanup', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n \r\n this._secureLog('debug', 'Failed answer creation cleanup completed with secure memory wipe');\r\n \r\n } catch (cleanupError) {\r\n this._secureLog('error', 'Error during answer creation cleanup', {\r\n errorType: cleanupError.constructor.name,\r\n errorMessage: cleanupError.message\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * HELPER: Securely set encryption keys (if not set yet)\r\n */\r\n async _setEncryptionKeys(encryptionKey, macKey, metadataKey, keyFingerprint) {\r\n return this._withMutex('keyOperation', async (operationId) => {\r\n this._secureLog('info', 'Setting encryption keys with mutex', {\r\n operationId: operationId\r\n });\r\n \r\n // Validate all keys before setting\r\n if (!(encryptionKey instanceof CryptoKey) ||\r\n !(macKey instanceof CryptoKey) ||\r\n !(metadataKey instanceof CryptoKey)) {\r\n throw new Error('Invalid key types provided');\r\n }\r\n \r\n if (!keyFingerprint || typeof keyFingerprint !== 'string') {\r\n throw new Error('Invalid key fingerprint provided');\r\n }\r\n \r\n // Atomically set all keys\r\n const oldKeys = {\r\n encryptionKey: this.encryptionKey,\r\n macKey: this.macKey,\r\n metadataKey: this.metadataKey,\r\n keyFingerprint: this.keyFingerprint\r\n };\r\n \r\n try {\r\n this.encryptionKey = encryptionKey;\r\n this.macKey = macKey;\r\n this.metadataKey = metadataKey;\r\n this.keyFingerprint = keyFingerprint;\r\n \r\n // Reset counters\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.messageCounter = 0;\r\n this.processedMessageIds.clear();\r\n this.replayWindow.clear(); // Clear replay window\r\n \r\n this._secureLog('info', 'Encryption keys set successfully', {\r\n operationId: operationId,\r\n hasAllKeys: !!(this.encryptionKey && this.macKey && this.metadataKey),\r\n hasFingerprint: !!this.keyFingerprint\r\n });\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n // Roll back on error\r\n this.encryptionKey = oldKeys.encryptionKey;\r\n this.macKey = oldKeys.macKey;\r\n this.metadataKey = oldKeys.metadataKey;\r\n this.keyFingerprint = oldKeys.keyFingerprint;\r\n \r\n this._secureLog('error', 'Key setting failed, rolled back', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n \r\n throw error;\r\n }\r\n });\r\n }\r\n\r\n async handleSecureAnswer(answerData) {\r\n try {\r\n \r\n if (!answerData || typeof answerData !== 'object' || Array.isArray(answerData)) {\r\n this._secureLog('error', 'CRITICAL: Invalid answer data structure', { \r\n hasAnswerData: !!answerData,\r\n answerDataType: typeof answerData,\r\n isArray: Array.isArray(answerData)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Answer data must be a non-null object');\r\n }\r\n \r\n // Support both compact and legacy answer formats\r\n const isCompactAnswer = answerData.t === 'answer' && answerData.s;\r\n const isLegacyAnswer = answerData.type === 'enhanced_secure_answer' && answerData.sdp;\r\n \r\n if (!isCompactAnswer && !isLegacyAnswer) {\r\n this._secureLog('error', 'CRITICAL: Invalid answer format', { \r\n type: answerData.type || answerData.t,\r\n hasSdp: !!(answerData.sdp || answerData.s)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid answer format - hard abort required');\r\n }\r\n\r\n // CRITICAL: Strict validation of ECDH public key structure\r\n // Support both full and compact key names\r\n const ecdhKey = answerData.ecdhPublicKey || answerData.e;\r\n const ecdsaKey = answerData.ecdsaPublicKey || answerData.d;\r\n \r\n if (!ecdhKey || typeof ecdhKey !== 'object' || Array.isArray(ecdhKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDH public key structure in answer', { \r\n hasEcdhKey: !!ecdhKey,\r\n ecdhKeyType: typeof ecdhKey,\r\n isArray: Array.isArray(ecdhKey),\r\n availableKeys: Object.keys(answerData)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Missing or invalid ECDH public key structure');\r\n }\r\n \r\n if (!ecdhKey.keyData || !ecdhKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key missing keyData or signature in answer', { \r\n hasKeyData: !!ecdhKey.keyData,\r\n hasSignature: !!ecdhKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key missing keyData or signature');\r\n }\r\n\r\n // CRITICAL: Strict validation of ECDSA public key structure\r\n if (!ecdsaKey || typeof ecdsaKey !== 'object' || Array.isArray(ecdsaKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDSA public key structure in answer', { \r\n hasEcdsaKey: !!ecdsaKey,\r\n ecdsaKeyType: typeof ecdsaKey,\r\n isArray: Array.isArray(ecdsaKey)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Missing or invalid ECDSA public key structure');\r\n }\r\n \r\n if (!ecdsaKey.keyData || !ecdsaKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key missing keyData or signature in answer', { \r\n hasKeyData: !!ecdsaKey.keyData,\r\n hasSignature: !!ecdsaKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key missing keyData or signature');\r\n }\r\n\r\n // Additional MITM protection: Validate answer data structure\r\n // Support both compact and legacy formats\r\n const timestamp = answerData.ts || answerData.timestamp;\r\n const version = answerData.v || answerData.version;\r\n \r\n if (!timestamp || !version) {\r\n throw new Error('Missing required fields in response data \u2013 possible MITM attack');\r\n }\r\n\r\n // MITM Protection: Verify session ID if present (for enhanced security)\r\n if (answerData.sessionId && this.sessionId && answerData.sessionId !== this.sessionId) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Session ID mismatch detected - possible MITM attack', {\r\n expectedSessionIdHash: await this._createSafeLogHash(this.sessionId, 'session_id'),\r\n receivedSessionIdHash: await this._createSafeLogHash(answerData.sessionId, 'session_id')\r\n });\r\n throw new Error('Session ID mismatch \u2013 possible MITM attack');\r\n }\r\n\r\n // Check for replay attacks (reject answers older than 1 hour)\r\n const answerAge = Date.now() - answerData.timestamp;\r\n if (answerAge > 3600000) { // 1 hour in milliseconds\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Answer data is too old - possible replay attack', {\r\n answerAge: answerAge,\r\n timestamp: answerData.timestamp\r\n });\r\n \r\n // Notify the main code about the replay attack error\r\n if (this.onAnswerError) {\r\n this.onAnswerError('replay_attack', 'Response data is too old \u2013 possible replay attack');\r\n }\r\n \r\n throw new Error('Response data is too old \u2013 possible replay attack');\r\n }\r\n\r\n // Check protocol version compatibility\r\n if (answerData.version !== '4.0') {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('warn', 'Incompatible protocol version in answer', {\r\n expectedVersion: '4.0',\r\n receivedVersion: answerData.version\r\n });\r\n }\r\n\r\n // Import ECDSA public key for verification (self-signed)\r\n const peerECDSAPublicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n new Uint8Array(ecdsaKey.keyData),\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-384'\r\n },\r\n false,\r\n ['verify']\r\n );\r\n\r\n\r\n // Now import and verify the ECDH public key using the verified ECDSA key\r\n const peerPublicKey = await window.EnhancedSecureCryptoUtils.importPublicKeyFromSignedPackage(\r\n ecdhKey,\r\n peerECDSAPublicKey\r\n );\r\n \r\n // Additional MITM protection: Verify session salt integrity\r\n if (!this.sessionSalt || this.sessionSalt.length !== 64) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Invalid session salt detected - possible session hijacking', {\r\n saltLength: this.sessionSalt ? this.sessionSalt.length : 0\r\n });\r\n throw new Error('Invalid session salt \u2013 possible session hijacking attempt');\r\n }\r\n\r\n // Verify that the session salt hasn't been tampered with\r\n const expectedSaltHash = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(this.sessionSalt);\r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Session salt integrity verified', {\r\n saltFingerprint: expectedSaltHash.substring(0, 8)\r\n });\r\n\r\n // Additional validation: Ensure all keys are CryptoKey instances before derivation\r\n if (!(this.ecdhKeyPair?.privateKey instanceof CryptoKey)) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Local ECDH private key is not a CryptoKey in handleSecureAnswer', {\r\n hasKeyPair: !!this.ecdhKeyPair,\r\n privateKeyType: typeof this.ecdhKeyPair?.privateKey,\r\n privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name\r\n });\r\n throw new Error('Local ECDH private key is not a CryptoKey');\r\n }\r\n \r\n if (!(peerPublicKey instanceof CryptoKey)) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Peer ECDH public key is not a CryptoKey in handleSecureAnswer', {\r\n publicKeyType: typeof peerPublicKey,\r\n publicKeyAlgorithm: peerPublicKey?.algorithm?.name\r\n });\r\n throw new Error('Peer ECDH public key is not a CryptoKey');\r\n }\r\n\r\n // Store peer's public key for PFS key rotation\r\n this.peerPublicKey = peerPublicKey;\r\n \r\n // Initialize connection ID if not already set\r\n if (!this.connectionId) {\r\n this.connectionId = Array.from(crypto.getRandomValues(new Uint8Array(8)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n \r\n const derivedKeys = await window.EnhancedSecureCryptoUtils.deriveSharedKeys(\r\n this.ecdhKeyPair.privateKey,\r\n peerPublicKey,\r\n this.sessionSalt\r\n );\r\n \r\n this.encryptionKey = derivedKeys.encryptionKey;\r\n this.macKey = derivedKeys.macKey;\r\n this.metadataKey = derivedKeys.metadataKey;\r\n this.keyFingerprint = derivedKeys.fingerprint;\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.messageCounter = 0;\r\n this.processedMessageIds.clear();\r\n this.replayWindow.clear(); // Clear replay window\r\n // Validate that all keys are properly set\r\n if (!(this.encryptionKey instanceof CryptoKey) || \r\n !(this.macKey instanceof CryptoKey) || \r\n !(this.metadataKey instanceof CryptoKey)) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Invalid key types after derivation in handleSecureAnswer', {\r\n encryptionKeyType: typeof this.encryptionKey,\r\n macKeyType: typeof this.macKey,\r\n metadataKeyType: typeof this.metadataKey,\r\n encryptionKeyAlgorithm: this.encryptionKey?.algorithm?.name,\r\n macKeyAlgorithm: this.macKey?.algorithm?.name,\r\n metadataKeyAlgorithm: this.metadataKey?.algorithm?.name\r\n });\r\n throw new Error('Invalid key types after export');\r\n }\r\n \r\n this._secureLog('info', 'Encryption keys set in handleSecureAnswer', {\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n hasMetadataKey: !!this.metadataKey,\r\n hasKeyFingerprint: !!this.keyFingerprint,\r\n mitmProtection: 'enabled',\r\n signatureVerified: true\r\n });\r\n \r\n // Update security features for initiator after successful key exchange\r\n this.securityFeatures.hasMutualAuth = true;\r\n this.securityFeatures.hasMetadataProtection = true;\r\n this.securityFeatures.hasEnhancedReplayProtection = true;\r\n this.securityFeatures.hasPFS = true;\r\n \r\n // PFS: Initialize key version tracking\r\n this.currentKeyVersion = 0;\r\n this.lastKeyRotation = Date.now();\r\n this.keyVersions.set(0, {\r\n salt: this.sessionSalt,\r\n timestamp: this.lastKeyRotation,\r\n messageCount: 0\r\n });\r\n \r\n this.onKeyExchange(this.keyFingerprint);\r\n\r\n // Compute SAS for MITM protection (Offer side - Answer handler)\r\n try {\r\n const remoteFP = this._extractDTLSFingerprintFromSDP(answerData.sdp || answerData.s); \r\n const localFP = this.expectedDTLSFingerprint; \r\n const keyBytes = this._decodeKeyFingerprint(this.keyFingerprint); \r\n\r\n this.verificationCode = await this._computeSAS(keyBytes, localFP, remoteFP);\r\n this.onStatusChange?.('verifying'); \r\n this.onVerificationRequired(this.verificationCode);\r\n \r\n // CRITICAL: Store SAS code to send when data channel opens\r\n this.pendingSASCode = this.verificationCode;\r\n \r\n this._secureLog('info', 'SAS verification code generated for MITM protection (Offer side)', {\r\n sasCode: this.verificationCode,\r\n localFP: localFP.substring(0, 16) + '...',\r\n remoteFP: remoteFP.substring(0, 16) + '...',\r\n timestamp: Date.now()\r\n });\r\n } catch (sasError) {\r\n this._secureLog('error', 'SAS computation failed in handleSecureAnswer (Offer side)', {\r\n errorType: sasError?.constructor?.name || 'Unknown'\r\n });\r\n this._secureLog('error', 'SAS computation failed in handleSecureAnswer (Offer side)', {\r\n error: sasError.message,\r\n stack: sasError.stack,\r\n timestamp: Date.now()\r\n });\r\n }\r\n\r\n // Validate DTLS fingerprint before setting remote description\r\n if (this.strictDTLSValidation) {\r\n try {\r\n const receivedFingerprint = this._extractDTLSFingerprintFromSDP(answerData.sdp || answerData.s);\r\n \r\n if (this.expectedDTLSFingerprint) {\r\n await this._validateDTLSFingerprint(receivedFingerprint, this.expectedDTLSFingerprint, 'answer_validation');\r\n } else {\r\n // Store fingerprint for future validation (first connection)\r\n this.expectedDTLSFingerprint = receivedFingerprint;\r\n this._secureLog('info', 'Stored DTLS fingerprint for future validation', {\r\n fingerprint: receivedFingerprint,\r\n context: 'first_connection'\r\n });\r\n }\r\n } catch (error) {\r\n this._secureLog('warn', 'DTLS fingerprint validation failed - continuing in fallback mode', { \r\n error: error.message,\r\n context: 'answer_validation'\r\n });\r\n\r\n }\r\n } else {\r\n this._secureLog('info', 'DTLS fingerprint validation disabled - proceeding without validation');\r\n }\r\n\r\n // Support both full and compact SDP field names\r\n const sdpData = answerData.sdp || answerData.s;\r\n \r\n this._secureLog('debug', 'Setting remote description from answer', {\r\n sdpLength: sdpData?.length || 0,\r\n usingCompactSDP: !answerData.sdp && !!answerData.s\r\n });\r\n \r\n await this.peerConnection.setRemoteDescription({\r\n type: 'answer',\r\n sdp: sdpData\r\n });\r\n \r\n this._secureLog('debug', 'Remote description set successfully from answer', {\r\n signalingState: this.peerConnection.signalingState\r\n });\r\n\r\n setTimeout(async () => {\r\n try {\r\n const securityData = await this.calculateAndReportSecurityLevel();\r\n if (securityData) {\r\n this.notifySecurityUpdate();\r\n }\r\n } catch (error) {\r\n this._secureLog('error', 'Error calculating security after connection:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }, 1000);\r\n setTimeout(async () => {\r\n if (!this.lastSecurityCalculation || this.lastSecurityCalculation.score < 50) {\r\n await this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpdate();\r\n }\r\n }, 3000);\r\n this.notifySecurityUpdate();\r\n } catch (error) {\r\n this._secureLog('error', 'Enhanced secure answer handling failed', {\r\n errorType: error.constructor.name\r\n });\r\n this.onStatusChange('failed');\r\n\r\n if (this.onAnswerError) {\r\n if (error.message.includes('too old') || error.message.includes('\u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0441\u0442\u0430\u0440\u044B\u0435')) {\r\n this.onAnswerError('replay_attack', error.message);\r\n } else if (error.message.includes('MITM') || error.message.includes('signature') || error.message.includes('\u043F\u043E\u0434\u043F\u0438\u0441\u044C')) {\r\n this.onAnswerError('security_violation', error.message);\r\n } else {\r\n this.onAnswerError('general_error', error.message);\r\n }\r\n }\r\n \r\n throw error;\r\n }\r\n }\r\n\r\n\r\n initiateVerification() {\r\n \r\n if (this.isInitiator) {\r\n // Ensure verification initiation notice wasn't already sent\r\n if (!this.verificationInitiationSent) {\r\n this.verificationInitiationSent = true;\r\n this.deliverMessageToUI('CRITICAL: Compare verification code with peer out-of-band (voice/video/in-person) to prevent MITM attack!', 'system');\r\n this.deliverMessageToUI(`Your verification code: ${this.verificationCode}`, 'system');\r\n this.deliverMessageToUI('Ask peer to confirm this exact code before allowing traffic!', 'system');\r\n }\r\n } else {\r\n\r\n this.deliverMessageToUI('Waiting for verification code from peer...', 'system');\r\n }\r\n }\r\n\r\n confirmVerification() {\r\n \r\n try {\r\n \r\n // Mark local verification as confirmed\r\n this.localVerificationConfirmed = true;\r\n \r\n // Send confirmation to peer\r\n const confirmationPayload = {\r\n type: 'verification_confirmed',\r\n data: {\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS',\r\n securityLevel: 'MITM_PROTECTION_REQUIRED'\r\n }\r\n };\r\n\r\n this.dataChannel.send(JSON.stringify(confirmationPayload));\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Check if both parties have confirmed\r\n this._checkBothVerificationsConfirmed();\r\n \r\n // Notify UI about local confirmation\r\n this.deliverMessageToUI('You confirmed the verification code. Waiting for peer confirmation...', 'system');\r\n \r\n this.processMessageQueue();\r\n } catch (error) {\r\n this._secureLog('error', 'SAS verification failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n this.deliverMessageToUI('SAS verification failed', 'system');\r\n }\r\n }\r\n\r\n _checkBothVerificationsConfirmed() {\r\n // Check if both parties have confirmed verification\r\n if (this.localVerificationConfirmed && this.remoteVerificationConfirmed && !this.bothVerificationsConfirmed) {\r\n this.bothVerificationsConfirmed = true;\r\n \r\n // Notify both parties that verification is complete\r\n const bothConfirmedPayload = {\r\n type: 'verification_both_confirmed',\r\n data: {\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS',\r\n securityLevel: 'MITM_PROTECTION_COMPLETE'\r\n }\r\n };\r\n\r\n this.dataChannel.send(JSON.stringify(bothConfirmedPayload));\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Set verified status and open chat after 2 second delay\r\n this.deliverMessageToUI('Both parties confirmed! Opening secure chat in 2 seconds...', 'system');\r\n \r\n setTimeout(() => {\r\n this._setVerifiedStatus(true, 'MUTUAL_SAS_CONFIRMED', { \r\n code: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n this._enforceVerificationGate('mutual_confirmed', false);\r\n this.onStatusChange?.('verified');\r\n }, 2000);\r\n }\r\n }\r\n\r\n handleVerificationConfirmed(data) {\r\n this.remoteVerificationConfirmed = true;\r\n \r\n // Notify UI about peer confirmation\r\n this.deliverMessageToUI('Peer confirmed the verification code. Waiting for your confirmation...', 'system');\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Check if both parties have confirmed\r\n this._checkBothVerificationsConfirmed();\r\n }\r\n\r\n handleVerificationBothConfirmed(data) {\r\n // Handle notification that both parties have confirmed\r\n this.bothVerificationsConfirmed = true;\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Set verified status and open chat after 2 second delay\r\n this.deliverMessageToUI('Both parties confirmed! Opening secure chat in 2 seconds...', 'system');\r\n \r\n setTimeout(() => {\r\n this._setVerifiedStatus(true, 'MUTUAL_SAS_CONFIRMED', { \r\n code: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n this._enforceVerificationGate('mutual_confirmed', false);\r\n this.onStatusChange?.('verified');\r\n }, 2000);\r\n }\r\n\r\n handleVerificationRequest(data) {\r\n\r\n \r\n if (data.code === this.verificationCode) {\r\n const responsePayload = {\r\n type: 'verification_response',\r\n data: {\r\n ok: true,\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS', // Indicate SAS was used\r\n securityLevel: 'MITM_PROTECTED'\r\n }\r\n };\r\n this.dataChannel.send(JSON.stringify(responsePayload));\r\n \r\n // Ensure verification success notice wasn't already sent\r\n if (!this.verificationNotificationSent) {\r\n this.verificationNotificationSent = true;\r\n this.deliverMessageToUI('SAS verification successful! MITM protection confirmed. Channel is now secure!', 'system');\r\n }\r\n \r\n this.processMessageQueue();\r\n } else {\r\n // SAS verification failed - possible MITM attack\r\n const responsePayload = {\r\n type: 'verification_response',\r\n data: {\r\n ok: false,\r\n timestamp: Date.now(),\r\n reason: 'code_mismatch'\r\n }\r\n };\r\n this.dataChannel.send(JSON.stringify(responsePayload));\r\n \r\n this._secureLog('error', 'SAS verification failed - possible MITM attack', {\r\n receivedCode: data.code,\r\n expectedCode: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n \r\n this.deliverMessageToUI('SAS verification failed! Possible MITM attack detected. Connection aborted for safety!', 'system');\r\n this.disconnect();\r\n }\r\n }\r\n\r\n handleSASCode(data) {\r\n\r\n \r\n this.verificationCode = data.code;\r\n this.onStatusChange?.('verifying'); \r\n this.onVerificationRequired(this.verificationCode);\r\n \r\n this._secureLog('info', 'SAS code received from Offer side', {\r\n sasCode: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n }\r\n\r\n handleVerificationResponse(data) {\r\n \r\n if (data.ok === true) {\r\n \r\n // Log successful mutual SAS verification\r\n this._secureLog('info', 'Mutual SAS verification completed - MITM protection active', {\r\n verificationMethod: data.verificationMethod || 'SAS',\r\n securityLevel: data.securityLevel || 'MITM_PROTECTED',\r\n timestamp: Date.now()\r\n });\r\n \r\n // Ensure verification success notice wasn't already sent\r\n if (!this.verificationNotificationSent) {\r\n this.verificationNotificationSent = true;\r\n this.deliverMessageToUI(' Mutual SAS verification complete! MITM protection active. Channel is now secure!', 'system');\r\n }\r\n \r\n this.processMessageQueue();\r\n } else {\r\n // Peer verification failed - connection not secure\r\n this._secureLog('error', 'Peer SAS verification failed - connection not secure', {\r\n responseData: data,\r\n timestamp: Date.now()\r\n });\r\n \r\n this.deliverMessageToUI('Peer verification failed! Connection not secure!', 'system');\r\n this.disconnect();\r\n }\r\n }\r\n\r\n validateOfferData(offerData) {\r\n return offerData &&\r\n offerData.type === 'enhanced_secure_offer' &&\r\n offerData.sdp &&\r\n offerData.publicKey &&\r\n offerData.salt &&\r\n offerData.verificationCode &&\r\n Array.isArray(offerData.publicKey) &&\r\n Array.isArray(offerData.salt) &&\r\n offerData.salt.length === 32;\r\n }\r\n\r\n validateEnhancedOfferData(offerData) {\r\n try {\r\n // CRITICAL: Strict type checking to prevent syntax errors\r\n if (!offerData || typeof offerData !== 'object' || Array.isArray(offerData)) {\r\n this._secureLog('error', 'CRITICAL: Invalid offer data structure', { \r\n hasOfferData: !!offerData,\r\n offerDataType: typeof offerData,\r\n isArray: Array.isArray(offerData)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Offer data must be a non-null object');\r\n }\r\n\r\n // Basic required fields will be validated after format detection\r\n\r\n // Check if this is v4.0 compact format or legacy format\r\n const isV4CompactFormat = offerData.v === '4.0' && offerData.e && offerData.d;\r\n const isV4Format = offerData.version === '4.0' && offerData.ecdhPublicKey && offerData.ecdsaPublicKey;\r\n \r\n // Validate offer type (support compact, legacy v3.0 and v4.0 formats)\r\n const isValidType = isV4CompactFormat ? \r\n ['offer'].includes(offerData.t) :\r\n ['enhanced_secure_offer', 'secure_offer'].includes(offerData.type);\r\n \r\n if (!isValidType) {\r\n throw new Error('Invalid offer type');\r\n }\r\n \r\n if (isV4CompactFormat) {\r\n // v4.0 compact format validation\r\n const compactRequiredFields = [\r\n 'e', 'd', 'sl', 'vc', 'si', 'ci', 'ac', 'slv'\r\n ];\r\n \r\n for (const field of compactRequiredFields) {\r\n if (!offerData[field]) {\r\n throw new Error(`Missing required v4.0 compact field: ${field}`);\r\n }\r\n }\r\n \r\n // Validate key structures\r\n if (!offerData.e || typeof offerData.e !== 'object' || Array.isArray(offerData.e)) {\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDH public key structure');\r\n }\r\n \r\n if (!offerData.d || typeof offerData.d !== 'object' || Array.isArray(offerData.d)) {\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDSA public key structure');\r\n }\r\n \r\n // Validate salt length\r\n if (!Array.isArray(offerData.sl) || offerData.sl.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes for v4.0');\r\n }\r\n \r\n // Validate verification code format\r\n if (typeof offerData.vc !== 'string' || offerData.vc.length < 6) {\r\n throw new Error('Invalid verification code format');\r\n }\r\n \r\n // Validate security level\r\n if (!['MAX', 'HIGH', 'MED', 'LOW'].includes(offerData.slv)) {\r\n throw new Error('Invalid security level');\r\n }\r\n \r\n // Validate timestamp (not older than 1 hour)\r\n const offerAge = Date.now() - offerData.ts;\r\n if (offerAge > 3600000) {\r\n throw new Error('Offer is too old (older than 1 hour)');\r\n }\r\n \r\n this._secureLog('info', 'v4.0 compact offer validation passed', {\r\n version: offerData.v,\r\n hasECDH: !!offerData.e,\r\n hasECDSA: !!offerData.d,\r\n hasSalt: !!offerData.sl,\r\n hasVerificationCode: !!offerData.vc,\r\n securityLevel: offerData.slv,\r\n offerAge: Math.round(offerAge / 1000) + 's'\r\n });\r\n } else if (isV4Format) {\r\n // v4.0 enhanced validation\r\n const v4RequiredFields = [\r\n 'ecdhPublicKey', 'ecdsaPublicKey', 'salt', 'verificationCode',\r\n 'authChallenge', 'timestamp', 'version', 'securityLevel'\r\n ];\r\n\r\n for (const field of v4RequiredFields) {\r\n if (!offerData[field]) {\r\n throw new Error(`Missing v4.0 field: ${field}`);\r\n }\r\n }\r\n\r\n // Validate salt (must be 64 bytes for v4.0)\r\n if (!Array.isArray(offerData.salt) || offerData.salt.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes for v4.0');\r\n }\r\n\r\n // Validate timestamp (not older than 1 hour)\r\n const offerAge = Date.now() - offerData.timestamp;\r\n if (offerAge > 3600000) {\r\n throw new Error('Offer is too old (older than 1 hour)');\r\n }\r\n\r\n // CRITICAL: Strict validation of key structures to prevent syntax errors\r\n if (!offerData.ecdhPublicKey || typeof offerData.ecdhPublicKey !== 'object' || Array.isArray(offerData.ecdhPublicKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDH public key structure', { \r\n hasEcdhKey: !!offerData.ecdhPublicKey,\r\n ecdhKeyType: typeof offerData.ecdhPublicKey,\r\n isArray: Array.isArray(offerData.ecdhPublicKey)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDH public key structure - hard abort required');\r\n }\r\n\r\n if (!offerData.ecdsaPublicKey || typeof offerData.ecdsaPublicKey !== 'object' || Array.isArray(offerData.ecdsaPublicKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDSA public key structure', { \r\n hasEcdsaKey: !!offerData.ecdsaPublicKey,\r\n ecdsaKeyType: typeof offerData.ecdsaPublicKey,\r\n isArray: Array.isArray(offerData.ecdsaPublicKey)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDSA public key structure - hard abort required');\r\n }\r\n\r\n // CRITICAL: Validate key internal structure to prevent syntax errors\r\n if (!offerData.ecdhPublicKey.keyData || !offerData.ecdhPublicKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key missing keyData or signature', { \r\n hasKeyData: !!offerData.ecdhPublicKey.keyData,\r\n hasSignature: !!offerData.ecdhPublicKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key missing keyData or signature');\r\n }\r\n\r\n if (!offerData.ecdsaPublicKey.keyData || !offerData.ecdsaPublicKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key missing keyData or signature', { \r\n hasKeyData: !!offerData.ecdsaPublicKey.keyData,\r\n hasSignature: !!offerData.ecdsaPublicKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key missing keyData or signature');\r\n }\r\n\r\n if (typeof offerData.verificationCode !== 'string' || offerData.verificationCode.length < 6) {\r\n throw new Error('Invalid SAS verification code format - MITM protection required');\r\n }\r\n\r\n this._secureLog('info', 'v4.0 offer validation passed', {\r\n version: offerData.version,\r\n hasSecurityLevel: !!offerData.securityLevel?.level,\r\n offerAge: Math.round(offerAge / 1000) + 's'\r\n });\r\n } else {\r\n // v3.0 backward compatibility validation\r\n // NOTE: v3.0 has limited security - SAS verification is still critical\r\n const v3RequiredFields = ['publicKey', 'salt', 'verificationCode'];\r\n for (const field of v3RequiredFields) {\r\n if (!offerData[field]) {\r\n throw new Error(`Missing v3.0 field: ${field}`);\r\n }\r\n }\r\n\r\n // Validate salt (32 bytes for v3.0)\r\n if (!Array.isArray(offerData.salt) || offerData.salt.length !== 32) {\r\n throw new Error('Salt must be exactly 32 bytes for v3.0');\r\n }\r\n\r\n // Validate public key\r\n if (!Array.isArray(offerData.publicKey)) {\r\n throw new Error('Invalid public key format for v3.0');\r\n }\r\n\r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'v3.0 offer validation passed (backward compatibility)', {\r\n version: 'v3.0',\r\n legacy: true\r\n });\r\n }\r\n\r\n // Validate SDP structure (basic check for all versions)\r\n const sdp = isV4CompactFormat ? offerData.s : offerData.sdp;\r\n if (typeof sdp !== 'string' || !sdp.includes('v=0')) {\r\n throw new Error('Invalid SDP structure');\r\n }\r\n\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'CRITICAL: Security validation failed - hard abort required', {\r\n error: error.message,\r\n errorType: error.constructor.name,\r\n timestamp: Date.now()\r\n });\r\n\r\n throw new Error(`CRITICAL SECURITY VALIDATION FAILURE: ${error.message}`);\r\n }\r\n }\r\n\r\n async sendSecureMessage(message) {\r\n // Comprehensive input validation\r\n const validation = this._validateInputData(message, 'sendSecureMessage');\r\n if (!validation.isValid) {\r\n const errorMessage = `Input validation failed: ${validation.errors.join(', ')}`;\r\n this._secureLog('error', 'Input validation failed in sendSecureMessage', {\r\n errors: validation.errors,\r\n messageType: typeof message\r\n });\r\n throw new Error(errorMessage);\r\n }\r\n\r\n // Rate limiting check\r\n if (!this._checkRateLimit('sendSecureMessage')) {\r\n throw new Error('Rate limit exceeded for secure message sending');\r\n }\r\n\r\n // Enforce verification gate\r\n this._enforceVerificationGate('sendSecureMessage');\r\n\r\n // Quick readiness check WITHOUT mutex\r\n if (!this.isConnected()) {\r\n if (validation.sanitizedData && typeof validation.sanitizedData === 'object' && validation.sanitizedData.type && validation.sanitizedData.type.startsWith('file_')) {\r\n throw new Error('Connection not ready for file transfer. Please ensure the connection is established and verified.');\r\n }\r\n this.messageQueue.push(validation.sanitizedData);\r\n throw new Error('Connection not ready. Message queued for sending.');\r\n }\r\n \r\n // Use mutex ONLY for cryptographic operations\r\n return this._withMutex('cryptoOperation', async (operationId) => {\r\n // Re-check inside critical section\r\n if (!this.isConnected() || !this.isVerified) {\r\n throw new Error('Connection lost during message preparation');\r\n }\r\n \r\n // Note: master key session is managed by SecureMasterKeyManager\r\n // Do not gate here on _isUnlocked to avoid false blocking\r\n // Session timers are handled inside the master key manager on key access\r\n \r\n // Validate keys inside critical section\r\n if (!this.encryptionKey || !this.macKey || !this.metadataKey) {\r\n throw new Error('Encryption keys not initialized');\r\n }\r\n \r\n // Additional rate limiting check\r\n if (!window.EnhancedSecureCryptoUtils.rateLimiter.checkMessageRate(this.rateLimiterId)) {\r\n throw new Error('Message rate limit exceeded (60 messages per minute)');\r\n }\r\n \r\n try {\r\n // Accept strings and objects; stringify objects\r\n const textToSend = typeof validation.sanitizedData === 'string' ? validation.sanitizedData : JSON.stringify(validation.sanitizedData);\r\n const sanitizedMessage = window.EnhancedSecureCryptoUtils.sanitizeMessage(textToSend);\r\n const messageId = `msg_${Date.now()}_${this.messageCounter++}`;\r\n \r\n // Create AAD with sequence number for anti-replay protection\r\n if (typeof this._createMessageAAD !== 'function') {\r\n throw new Error('_createMessageAAD method is not available in sendSecureMessage. Manager may not be fully initialized.');\r\n }\r\n const aad = message.aad || this._createMessageAAD('enhanced_message', { content: sanitizedMessage });\r\n \r\n // Use enhanced encryption with AAD and sequence number\r\n const encryptedData = await window.EnhancedSecureCryptoUtils.encryptMessage(\r\n sanitizedMessage,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey,\r\n messageId,\r\n JSON.parse(aad).sequenceNumber // Use sequence number from AAD\r\n );\r\n \r\n const payload = {\r\n type: 'enhanced_message',\r\n data: encryptedData,\r\n keyVersion: this.currentKeyVersion,\r\n version: '4.0'\r\n };\r\n \r\n this.dataChannel.send(JSON.stringify(payload));\r\n // Locally display only plain strings to avoid UI duplication\r\n if (typeof validation.sanitizedData === 'string') {\r\n this.deliverMessageToUI(validation.sanitizedData, 'sent');\r\n }\r\n \r\n this._secureLog('debug', 'Secure message sent successfully', {\r\n operationId: operationId,\r\n messageLength: sanitizedMessage.length,\r\n keyVersion: this.currentKeyVersion\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Secure message sending failed', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n \r\n // Improved user-facing error messages (English)\r\n if (error.message.includes('Session expired')) {\r\n throw new Error('Session expired. Please enter your password to unlock.');\r\n } else if (error.message.includes('Encryption keys not initialized')) {\r\n throw new Error('Session expired due to inactivity. Please reconnect to the chat.');\r\n } else if (error.message.includes('Connection lost')) {\r\n throw new Error('Connection lost. Please check your Internet connection.');\r\n } else if (error.message.includes('Rate limit exceeded')) {\r\n throw new Error('Message rate limit exceeded. Please wait before sending another message.');\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }, 2000); // Reduced timeout for crypto operations\r\n }\r\n\r\n processMessageQueue() {\r\n while (this.messageQueue.length > 0 && this.isConnected() && this.isVerified) {\r\n const message = this.messageQueue.shift();\r\n this.sendSecureMessage(message).catch(console.error);\r\n }\r\n }\r\n\r\n startHeartbeat() {\r\n // Heartbeat moved to unified scheduler with connection validation\r\n this._secureLog('info', 'Heartbeat moved to unified scheduler');\r\n \r\n // Store heartbeat configuration for scheduler\r\n this._heartbeatConfig = {\r\n enabled: true,\r\n interval: EnhancedSecureWebRTCManager.TIMEOUTS.HEARTBEAT_INTERVAL,\r\n lastHeartbeat: 0\r\n };\r\n }\r\n\r\n stopHeartbeat() {\r\n // Heartbeat stopped via unified scheduler\r\n if (this._heartbeatConfig) {\r\n this._heartbeatConfig.enabled = false;\r\n }\r\n }\r\n\r\n /**\r\n * Stop all active timers and cleanup scheduler\r\n */\r\n _stopAllTimers() {\r\n this._secureLog('info', 'Stopping all timers and cleanup scheduler');\r\n \r\n // Stop maintenance scheduler\r\n if (this._maintenanceScheduler) {\r\n clearInterval(this._maintenanceScheduler);\r\n this._maintenanceScheduler = null;\r\n }\r\n \r\n // Stop heartbeat\r\n if (this._heartbeatConfig) {\r\n this._heartbeatConfig.enabled = false;\r\n }\r\n \r\n // Clear all timer references\r\n if (this._activeTimers) {\r\n this._activeTimers.forEach(timer => {\r\n if (timer) clearInterval(timer);\r\n });\r\n this._activeTimers.clear();\r\n }\r\n \r\n this._secureLog('info', 'All timers stopped successfully');\r\n }\r\n\r\n\r\n waitForIceGathering() {\r\n return new Promise((resolve) => {\r\n if (this.peerConnection.iceGatheringState === 'complete') {\r\n resolve();\r\n return;\r\n }\r\n\r\n const checkState = () => {\r\n if (this.peerConnection && this.peerConnection.iceGatheringState === 'complete') {\r\n this.peerConnection.removeEventListener('icegatheringstatechange', checkState);\r\n resolve();\r\n }\r\n };\r\n \r\n this.peerConnection.addEventListener('icegatheringstatechange', checkState);\r\n \r\n setTimeout(() => {\r\n if (this.peerConnection) {\r\n this.peerConnection.removeEventListener('icegatheringstatechange', checkState);\r\n }\r\n resolve();\r\n }, EnhancedSecureWebRTCManager.TIMEOUTS.ICE_GATHERING_TIMEOUT);\r\n });\r\n }\r\n\r\n retryConnection() {\r\n this._secureLog('info', 'Retrying connection', {\r\n attempt: this.connectionAttempts,\r\n maxAttempts: this.maxConnectionAttempts\r\n });\r\n this.onStatusChange('retrying');\r\n }\r\n\r\n isConnected() {\r\n const hasDataChannel = !!this.dataChannel;\r\n const dataChannelState = this.dataChannel?.readyState;\r\n const isDataChannelOpen = dataChannelState === 'open';\r\n const isVerified = this.isVerified;\r\n const connectionState = this.peerConnection?.connectionState;\r\n \r\n return this.dataChannel && this.dataChannel.readyState === 'open' && this.isVerified;\r\n }\r\n\r\n getConnectionInfo() {\r\n return {\r\n fingerprint: this.keyFingerprint,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n connectionState: this.peerConnection?.connectionState,\r\n iceConnectionState: this.peerConnection?.iceConnectionState,\r\n verificationCode: this.verificationCode\r\n };\r\n }\r\n\r\n disconnect() {\r\n // Stop all timers first\r\n this._stopAllTimers();\r\n \r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n }\r\n this.intentionalDisconnect = true;\r\n \r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Starting intentional disconnect');\r\n\r\n this.sendDisconnectNotification();\r\n\r\n setTimeout(() => {\r\n this.sendDisconnectNotification(); \r\n }, 100);\r\n\r\n document.dispatchEvent(new CustomEvent('peer-disconnect', {\r\n detail: { \r\n reason: 'user_disconnect',\r\n timestamp: Date.now()\r\n }\r\n }));\r\n }\r\n \r\n handleUnexpectedDisconnect() {\r\n this.sendDisconnectNotification();\r\n this.isVerified = false;\r\n \r\n // Ensure disconnect notification wasn't already sent\r\n if (!this.disconnectNotificationSent) {\r\n this.disconnectNotificationSent = true;\r\n this.deliverMessageToUI('\uD83D\uDD0C Connection lost. Attempting to reconnect...', 'system');\r\n }\r\n \r\n // Cleanup file transfer system on unexpected disconnect\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n document.dispatchEvent(new CustomEvent('peer-disconnect', {\r\n detail: { \r\n reason: 'connection_lost',\r\n timestamp: Date.now()\r\n }\r\n }));\r\n\r\n }\r\n \r\n sendDisconnectNotification() {\r\n try {\r\n if (this.dataChannel && this.dataChannel.readyState === 'open') {\r\n const notification = {\r\n type: 'peer_disconnect',\r\n timestamp: Date.now(),\r\n reason: this.intentionalDisconnect ? 'user_disconnect' : 'connection_lost'\r\n };\r\n\r\n for (let i = 0; i < 3; i++) {\r\n try {\r\n this.dataChannel.send(JSON.stringify(notification));\r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Disconnect notification sent', {\r\n reason: notification.reason,\r\n attempt: i + 1\r\n });\r\n break;\r\n } catch (sendError) {\r\n if (i === 2) { \r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Failed to send disconnect notification', {\r\n error: sendError.message\r\n });\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Could not send disconnect notification', {\r\n error: error.message\r\n });\r\n }\r\n }\r\n \r\n attemptReconnection() {\r\n // Ensure reconnection-failed notification wasn't already sent\r\n if (!this.reconnectionFailedNotificationSent) {\r\n this.reconnectionFailedNotificationSent = true;\r\n this.deliverMessageToUI('Unable to reconnect. A new connection is required.', 'system');\r\n }\r\n\r\n }\r\n \r\n handlePeerDisconnectNotification(data) {\r\n const reason = data.reason || 'unknown';\r\n const reasonText = reason === 'user_disconnect' ? 'manually disconnected.' : 'connection lost.';\r\n \r\n // Ensure peer-disconnect notification wasn't already sent\r\n if (!this.peerDisconnectNotificationSent) {\r\n this.peerDisconnectNotificationSent = true;\r\n this.deliverMessageToUI(`Peer ${reasonText}`, 'system');\r\n }\r\n \r\n this.onStatusChange('peer_disconnected');\r\n \r\n this.intentionalDisconnect = false;\r\n this.isVerified = false;\r\n this.stopHeartbeat();\r\n \r\n this.onKeyExchange(''); \r\n this.onVerificationRequired(''); \r\n\r\n document.dispatchEvent(new CustomEvent('peer-disconnect', {\r\n detail: { \r\n reason: reason,\r\n timestamp: Date.now()\r\n }\r\n }));\r\n\r\n setTimeout(() => {\r\n this.disconnect();\r\n }, 2000);\r\n \r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Peer disconnect notification processed', {\r\n reason: reason\r\n });\r\n }\r\n \r\n /**\r\n * Secure disconnect with complete memory cleanup\r\n */\r\n disconnect() {\r\n this.stopHeartbeat();\r\n this.isVerified = false;\r\n this.processedMessageIds.clear();\r\n this.messageCounter = 0;\r\n \r\n // Secure cleanup of cryptographic materials\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Secure wipe of PFS key versions\r\n this.keyVersions.clear();\r\n this.oldKeys.clear();\r\n this.currentKeyVersion = 0;\r\n this.lastKeyRotation = Date.now();\r\n \r\n // Reset message counters\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.replayWindow.clear(); // Clear replay window\r\n \r\n // Reset security features\r\n this.securityFeatures = {\r\n hasEncryption: true,\r\n hasECDH: true,\r\n hasECDSA: true, \r\n hasMutualAuth: true, \r\n hasMetadataProtection: true, \r\n hasEnhancedReplayProtection: true, \r\n hasNonExtractableKeys: true, \r\n hasRateLimiting: true, \r\n hasEnhancedValidation: true, \r\n hasPFS: true \r\n };\r\n \r\n // Close connections\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Secure wipe of message queue\r\n if (this.messageQueue && this.messageQueue.length > 0) {\r\n this.messageQueue.forEach((message, index) => {\r\n this._secureWipeMemory(message, `messageQueue[${index}]`);\r\n });\r\n this.messageQueue = [];\r\n }\r\n \r\n // Schedule natural cleanup\r\n this._forceGarbageCollection().catch(error => {\r\n this._secureLog('error', 'Cleanup failed during disconnect', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n \r\n document.dispatchEvent(new CustomEvent('connection-cleaned', {\r\n detail: { \r\n timestamp: Date.now(),\r\n reason: this.intentionalDisconnect ? 'user_cleanup' : 'automatic_cleanup'\r\n }\r\n }));\r\n\r\n // Notify UI about complete cleanup\r\n this.onStatusChange('disconnected');\r\n this.onKeyExchange('');\r\n this.onVerificationRequired('');\r\n \r\n this._secureLog('info', 'Connection securely cleaned up with complete memory wipe');\r\n \r\n // Reset the intentional disconnect flag\r\n this.intentionalDisconnect = false;\r\n }\r\n // Public method to send files\r\n async sendFile(file) {\r\n // Enforce verification gate for file transfers\r\n this._enforceVerificationGate('sendFile');\r\n \r\n if (!this.isConnected()) {\r\n throw new Error('Connection not ready for file transfer. Please ensure the connection is established.');\r\n }\r\n\r\n if (!this.fileTransferSystem) {\r\n this.initializeFileTransfer();\r\n \r\n // Allow time for initialization\r\n await new Promise(resolve => setTimeout(resolve, 500));\r\n \r\n if (!this.fileTransferSystem) {\r\n throw new Error('File transfer system could not be initialized. Please try reconnecting.');\r\n }\r\n }\r\n\r\n // Verify key readiness\r\n if (!this.encryptionKey || !this.macKey) {\r\n throw new Error('Encryption keys not ready. Please wait for connection to be fully established.');\r\n }\r\n\r\n\r\n try {\r\n const fileId = await this.fileTransferSystem.sendFile(file);\r\n return fileId;\r\n } catch (error) {\r\n this._secureLog('error', 'File transfer error:', { errorType: error?.constructor?.name || 'Unknown' });\r\n \r\n // Re-throw with a clearer message\r\n if (error.message.includes('Connection not ready')) {\r\n throw new Error('Connection not ready for file transfer. Check connection status.');\r\n } else if (error.message.includes('Encryption keys not initialized')) {\r\n throw new Error('Session expired due to inactivity. Please reconnect to the chat.');\r\n } else if (error.message.includes('Transfer timeout')) {\r\n throw new Error('File transfer timeout. Check connection and try again.');\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n // Get active file transfers\r\n getFileTransfers() {\r\n if (!this.fileTransferSystem) {\r\n return { sending: [], receiving: [] };\r\n }\r\n \r\n try {\r\n // Check available methods in file transfer system\r\n let sending = [];\r\n let receiving = [];\r\n \r\n if (typeof this.fileTransferSystem.getActiveTransfers === 'function') {\r\n sending = this.fileTransferSystem.getActiveTransfers();\r\n } else {\r\n this._secureLog('warn', 'getActiveTransfers method not available in file transfer system');\r\n }\r\n \r\n if (typeof this.fileTransferSystem.getReceivingTransfers === 'function') {\r\n receiving = this.fileTransferSystem.getReceivingTransfers();\r\n } else {\r\n this._secureLog('warn', 'getReceivingTransfers method not available in file transfer system');\r\n }\r\n \r\n return {\r\n sending: sending || [],\r\n receiving: receiving || []\r\n };\r\n } catch (error) {\r\n this._secureLog('error', 'Error getting file transfers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return { sending: [], receiving: [] };\r\n }\r\n }\r\n\r\n // Get file transfer system status\r\n getFileTransferStatus() {\r\n if (!this.fileTransferSystem) {\r\n return {\r\n initialized: false,\r\n status: 'not_initialized',\r\n message: 'File transfer system not initialized'\r\n };\r\n }\r\n \r\n const activeTransfers = this.fileTransferSystem.getActiveTransfers();\r\n const receivingTransfers = this.fileTransferSystem.getReceivingTransfers();\r\n \r\n return {\r\n initialized: true,\r\n status: 'ready',\r\n activeTransfers: activeTransfers.length,\r\n receivingTransfers: receivingTransfers.length,\r\n totalTransfers: activeTransfers.length + receivingTransfers.length\r\n };\r\n }\r\n\r\n // Cancel file transfer\r\n cancelFileTransfer(fileId) {\r\n if (!this.fileTransferSystem) return false;\r\n return this.fileTransferSystem.cancelTransfer(fileId);\r\n }\r\n\r\n // Force cleanup of file transfer system\r\n cleanupFileTransferSystem() {\r\n if (this.fileTransferSystem) {\r\n this._secureLog('info', '\uD83E\uDDF9 Force cleaning up file transfer system');\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n // Reinitialize file transfer system\r\n reinitializeFileTransfer() {\r\n try {\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n }\r\n this.initializeFileTransfer();\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to reinitialize file transfer system:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n\r\n // Set file transfer callbacks\r\n setFileTransferCallbacks(onProgress, onReceived, onError) {\r\n this.onFileProgress = onProgress;\r\n this.onFileReceived = onReceived;\r\n this.onFileError = onError;\r\n \r\n // Reinitialize file transfer system if it exists to update callbacks\r\n if (this.fileTransferSystem) {\r\n this.initializeFileTransfer();\r\n }\r\n }\r\n\r\n // ============================================\r\n // SESSION ACTIVATION HANDLING\r\n // ============================================\r\n\r\n async handleSessionActivation(sessionData) {\r\n try {\r\n \r\n // Update session state\r\n this.currentSession = sessionData;\r\n \r\n // FIX: More lenient checks for activation\r\n const hasKeys = !!(this.encryptionKey && this.macKey);\r\n const hasSession = !!(sessionData.sessionId);\r\n \r\n // Force connection status if there is an active session\r\n if (hasSession) {\r\n this.onStatusChange('connected');\r\n\r\n }\r\n\r\n setTimeout(() => {\r\n try {\r\n this.initializeFileTransfer();\r\n } catch (error) {\r\n this._secureLog('warn', 'File transfer initialization failed during session activation:', { details: error.message });\r\n }\r\n }, 1000);\r\n \r\n \r\n if (this.fileTransferSystem && this.isConnected()) {\r\n \r\n if (typeof this.fileTransferSystem.onSessionUpdate === 'function') {\r\n this.fileTransferSystem.onSessionUpdate({\r\n keyFingerprint: this.keyFingerprint,\r\n sessionSalt: this.sessionSalt,\r\n hasMacKey: !!this.macKey\r\n });\r\n }\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to handle session activation:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n // Method to check readiness of file transfers\r\ncheckFileTransferReadiness() {\r\n const status = {\r\n hasFileTransferSystem: !!this.fileTransferSystem,\r\n hasDataChannel: !!this.dataChannel,\r\n dataChannelState: this.dataChannel?.readyState,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n ready: false\r\n };\r\n \r\n status.ready = status.hasFileTransferSystem && \r\n status.hasDataChannel && \r\n status.dataChannelState === 'open' && \r\n status.isConnected && \r\n status.isVerified;\r\n return status;\r\n }\r\n\r\n // Method to force re-initialize file transfer system\r\n forceReinitializeFileTransfer() {\r\n try {\r\n \r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n // Small delay before reinitialization\r\n setTimeout(() => {\r\n this.initializeFileTransfer();\r\n }, 500);\r\n \r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to force reinitialize file transfer:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n\r\n // Method to get diagnostic information\r\n getFileTransferDiagnostics() {\r\n const diagnostics = {\r\n timestamp: new Date().toISOString(),\r\n webrtcManager: {\r\n hasDataChannel: !!this.dataChannel,\r\n dataChannelState: this.dataChannel?.readyState,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n isInitiator: this.isInitiator,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n hasMetadataKey: !!this.metadataKey,\r\n hasKeyFingerprint: !!this.keyFingerprint,\r\n hasSessionSalt: !!this.sessionSalt\r\n },\r\n fileTransferSystem: null,\r\n globalState: {\r\n fileTransferActive: this._fileTransferActive || false,\r\n hasFileTransferSystem: !!this.fileTransferSystem,\r\n fileTransferSystemType: this.fileTransferSystem ? 'EnhancedSecureFileTransfer' : 'none'\r\n }\r\n };\r\n \r\n if (this.fileTransferSystem) {\r\n try {\r\n diagnostics.fileTransferSystem = this.fileTransferSystem.getSystemStatus();\r\n } catch (error) {\r\n diagnostics.fileTransferSystem = { error: error.message };\r\n }\r\n }\r\n \r\n return diagnostics;\r\n }\r\n\r\n getSupportedFileTypes() {\r\n if (!this.fileTransferSystem) {\r\n return { error: 'File transfer system not initialized' };\r\n }\r\n \r\n try {\r\n return this.fileTransferSystem.getSupportedFileTypes();\r\n } catch (error) {\r\n return { error: error.message };\r\n }\r\n }\r\n\r\n validateFile(file) {\r\n if (!this.fileTransferSystem) {\r\n return { \r\n isValid: false, \r\n errors: ['File transfer system not initialized'],\r\n fileType: null,\r\n fileSize: file?.size || 0,\r\n formattedSize: '0 B'\r\n };\r\n }\r\n \r\n try {\r\n return this.fileTransferSystem.validateFile(file);\r\n } catch (error) {\r\n return { \r\n isValid: false, \r\n errors: [error.message],\r\n fileType: null,\r\n fileSize: file?.size || 0,\r\n formattedSize: '0 B'\r\n };\r\n }\r\n }\r\n\r\n getFileTypeInfo() {\r\n if (!this.fileTransferSystem) {\r\n return { error: 'File transfer system not initialized' };\r\n }\r\n \r\n try {\r\n return this.fileTransferSystem.getFileTypeInfo();\r\n } catch (error) {\r\n return { error: error.message };\r\n }\r\n }\r\n\r\n async forceInitializeFileTransfer(options = {}) {\r\n const abortController = new AbortController();\r\n const { signal = abortController.signal, timeout = 6000 } = options;\r\n\r\n if (signal && signal !== abortController.signal) {\r\n signal.addEventListener('abort', () => abortController.abort());\r\n }\r\n try {\r\n if (!this.isVerified) {\r\n throw new Error('Connection not verified');\r\n }\r\n \r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n throw new Error('Data channel not open');\r\n }\r\n \r\n if (!this.encryptionKey || !this.macKey) {\r\n throw new Error('Encryption keys not ready');\r\n }\r\n\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n\r\n this.initializeFileTransfer();\r\n\r\n let attempts = 0;\r\n const maxAttempts = 50;\r\n const checkInterval = 100; \r\n const maxWaitTime = maxAttempts * checkInterval; \r\n\r\n const initializationPromise = new Promise((resolve, reject) => {\r\n const checkInitialization = () => {\r\n if (abortController.signal.aborted) {\r\n reject(new Error('Operation cancelled'));\r\n return;\r\n }\r\n \r\n if (this.fileTransferSystem) {\r\n resolve(true);\r\n return;\r\n }\r\n \r\n if (attempts >= maxAttempts) {\r\n reject(new Error(`Initialization timeout after ${maxWaitTime}ms`));\r\n return;\r\n }\r\n \r\n attempts++;\r\n setTimeout(checkInitialization, checkInterval);\r\n };\r\n \r\n checkInitialization();\r\n });\r\n\r\n await Promise.race([\r\n initializationPromise,\r\n new Promise((_, reject) => \r\n setTimeout(() => reject(new Error(`Global timeout after ${timeout}ms`)), timeout)\r\n )\r\n ]);\r\n \r\n if (this.fileTransferSystem) {\r\n return true;\r\n } else {\r\n throw new Error('Force initialization timeout');\r\n }\r\n \r\n } catch (error) {\r\n if (error.name === 'AbortError' || error.message.includes('cancelled')) {\r\n this._secureLog('info', 'File transfer initialization cancelled by user');\r\n return { cancelled: true };\r\n }\r\n \r\n this._secureLog('error', 'Force file transfer initialization failed:', { \r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error.message,\r\n attempts: attempts\r\n });\r\n return { error: error.message, attempts: attempts };\r\n }\r\n }\r\n\r\n cancelFileTransferInitialization() {\r\n try {\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n this._fileTransferActive = false;\r\n this._secureLog('info', 'File transfer initialization cancelled');\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to cancel file transfer initialization:', { \r\n errorType: error?.constructor?.name || 'Unknown' \r\n });\r\n return false;\r\n }\r\n }\r\n \r\n getFileTransferSystemStatus() {\r\n if (!this.fileTransferSystem) {\r\n return { available: false, status: 'not_initialized' };\r\n }\r\n \r\n try {\r\n const status = this.fileTransferSystem.getSystemStatus();\r\n return {\r\n available: true,\r\n status: status.status || 'unknown',\r\n activeTransfers: status.activeTransfers || 0,\r\n receivingTransfers: status.receivingTransfers || 0,\r\n systemType: 'EnhancedSecureFileTransfer'\r\n };\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to get file transfer system status:', { \r\n errorType: error?.constructor?.name || 'Unknown' \r\n });\r\n return { available: false, status: 'error', error: error.message };\r\n }\r\n }\r\n\r\n _validateNestedEncryptionSecurity() {\r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey) {\r\n // Test secure IV generation with reuse prevention\r\n try {\r\n const testIV1 = this._generateSecureIV(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE, 'securityTest1');\r\n const testIV2 = this._generateSecureIV(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE, 'securityTest2');\r\n \r\n // Verify IVs are different and properly tracked\r\n if (testIV1.every((byte, index) => byte === testIV2[index])) {\r\n this._secureLog('error', 'CRITICAL: Nested encryption security validation failed - IVs are identical!');\r\n return false;\r\n }\r\n \r\n // Verify IV tracking system is working\r\n const stats = this._getIVTrackingStats();\r\n if (stats.totalIVs < 2) {\r\n this._secureLog('error', 'CRITICAL: IV tracking system not working properly');\r\n return false;\r\n }\r\n \r\n this._secureLog('info', 'Nested encryption security validation passed - secure IV generation working');\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'CRITICAL: Nested encryption security validation failed:', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n}\r\n\r\nclass SecureKeyStorage {\r\n constructor(masterKeyManager = null) {\r\n // Use WeakMap for automatic garbage collection of unused keys\r\n this._keyStore = new WeakMap();\r\n this._keyMetadata = new Map(); // Metadata doesn't need WeakMap\r\n this._keyReferences = new Map(); // Strong references for active keys\r\n \r\n // Use secure master key manager instead of global key\r\n this._masterKeyManager = masterKeyManager || new SecureMasterKeyManager();\r\n \r\n // Initialize persistent storage for extractable keys\r\n this._persistentStorage = new SecurePersistentKeyStorage(this._masterKeyManager);\r\n \r\n // Setup master key manager callbacks\r\n this._setupMasterKeyCallbacks();\r\n\r\n setTimeout(() => {\r\n if (!this.validateStorageIntegrity()) {\r\n this._secureLog('error', 'CRITICAL: Key storage integrity check failed');\r\n }\r\n }, 100);\r\n \r\n }\r\n\r\n /**\r\n * Setup callbacks for master key manager\r\n */\r\n _setupMasterKeyCallbacks() {\r\n // Set default password callback (can be overridden)\r\n this._masterKeyManager.setPasswordRequiredCallback((isRetry, callback) => {\r\n // Default implementation - should be overridden by application\r\n const password = prompt(isRetry ? \r\n 'Incorrect password. Please enter your master password:' : \r\n 'Please enter your master password to unlock secure storage:'\r\n );\r\n callback(password);\r\n });\r\n \r\n this._masterKeyManager.setSessionExpiredCallback((reason) => {\r\n console.warn(`Master key session expired: ${reason}`);\r\n // Application should handle this event\r\n });\r\n \r\n this._masterKeyManager.setUnlockedCallback(() => {\r\n console.log('Master key unlocked successfully');\r\n });\r\n }\r\n \r\n /**\r\n * Set custom password callback\r\n */\r\n setPasswordCallback(callback) {\r\n this._masterKeyManager.setPasswordRequiredCallback(callback);\r\n }\r\n \r\n /**\r\n * Set custom session expired callback\r\n */\r\n setSessionExpiredCallback(callback) {\r\n this._masterKeyManager.setSessionExpiredCallback(callback);\r\n }\r\n \r\n /**\r\n * Get master key (with automatic unlock if needed)\r\n */\r\n async _getMasterKey() {\r\n if (!this._masterKeyManager.isUnlocked()) {\r\n await this._masterKeyManager.unlock();\r\n }\r\n return this._masterKeyManager.getMasterKey();\r\n }\r\n\r\n async storeKey(keyId, cryptoKey, metadata = {}) {\r\n if (!(cryptoKey instanceof CryptoKey)) {\r\n throw new Error('Only CryptoKey objects can be stored');\r\n }\r\n\r\n try {\r\n // For non-extractable keys, store only in-memory reference\r\n if (!cryptoKey.extractable) {\r\n this._keyReferences.set(keyId, cryptoKey);\r\n this._keyMetadata.set(keyId, {\r\n ...metadata,\r\n created: Date.now(),\r\n lastAccessed: Date.now(),\r\n extractable: false,\r\n persistent: false,\r\n encrypted: false\r\n });\r\n return true;\r\n }\r\n\r\n // For extractable keys, use persistent storage with encryption\r\n await this._persistentStorage.storeExtractableKey(keyId, cryptoKey, metadata);\r\n \r\n // Also store in memory for immediate access\r\n this._keyReferences.set(keyId, cryptoKey);\r\n this._keyMetadata.set(keyId, {\r\n ...metadata,\r\n created: Date.now(),\r\n lastAccessed: Date.now(),\r\n extractable: true,\r\n persistent: true,\r\n encrypted: true\r\n });\r\n\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to store key securely', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n async retrieveKey(keyId) {\r\n try {\r\n // Check if key is in memory first\r\n if (this._keyReferences.has(keyId)) {\r\n const metadata = this._keyMetadata.get(keyId);\r\n if (metadata) {\r\n metadata.lastAccessed = Date.now();\r\n }\r\n return this._keyReferences.get(keyId);\r\n }\r\n \r\n // Try to restore from persistent storage\r\n const restoredKey = await this._persistentStorage.retrieveKey(keyId);\r\n if (restoredKey) {\r\n // Update memory cache\r\n this._keyReferences.set(keyId, restoredKey);\r\n \r\n // Update or create metadata\r\n const existingMetadata = this._keyMetadata.get(keyId);\r\n this._keyMetadata.set(keyId, {\r\n ...existingMetadata,\r\n lastAccessed: Date.now(),\r\n restoredFromPersistent: true\r\n });\r\n \r\n return restoredKey;\r\n }\r\n \r\n return null;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to retrieve key', {\r\n keyIdHash: await this._createSafeLogHash(keyId, 'key_id'),\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return null;\r\n }\r\n }\r\n\r\n async _encryptKeyData(keyData) {\r\n const dataToEncrypt = typeof keyData === 'object' \r\n ? JSON.stringify(keyData) \r\n : keyData;\r\n \r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(dataToEncrypt);\r\n \r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n \r\n const masterKey = await this._getMasterKey();\r\n const encryptedData = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n data\r\n );\r\n\r\n // Return IV + encrypted data\r\n const result = new Uint8Array(iv.length + encryptedData.byteLength);\r\n result.set(iv, 0);\r\n result.set(new Uint8Array(encryptedData), iv.length);\r\n \r\n return result;\r\n }\r\n\r\n async _decryptKeyData(encryptedData) {\r\n const iv = encryptedData.slice(0, 12);\r\n const data = encryptedData.slice(12);\r\n \r\n const masterKey = await this._getMasterKey();\r\n const decryptedData = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n data\r\n );\r\n\r\n const decoder = new TextDecoder();\r\n const jsonString = decoder.decode(decryptedData);\r\n \r\n try {\r\n return JSON.parse(jsonString);\r\n } catch {\r\n return decryptedData;\r\n }\r\n }\r\n\r\n async secureWipe(keyId) {\r\n const cryptoKey = this._keyReferences.get(keyId);\r\n \r\n if (cryptoKey) {\r\n // Remove from WeakMap (will be GC'd)\r\n this._keyStore.delete(cryptoKey);\r\n // Remove strong reference\r\n this._keyReferences.delete(keyId);\r\n // Remove metadata\r\n this._keyMetadata.delete(keyId);\r\n }\r\n\r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n }\r\n\r\n async secureWipeAll() {\r\n // Clear persistent storage\r\n try {\r\n await this._persistentStorage.clearAll();\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to clear persistent storage', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n }\r\n \r\n // Clear all references\r\n this._keyReferences.clear();\r\n this._keyMetadata.clear();\r\n \r\n // WeakMap entries will be garbage collected\r\n this._keyStore = new WeakMap();\r\n \r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n }\r\n\r\n // Validate storage integrity\r\n validateStorageIntegrity() {\r\n const violations = [];\r\n \r\n for (const [keyId, metadata] of this._keyMetadata.entries()) {\r\n // Check: extractable keys must be encrypted\r\n if (metadata.extractable === true && metadata.encrypted !== true) {\r\n violations.push({\r\n keyId,\r\n type: 'EXTRACTABLE_KEY_NOT_ENCRYPTED',\r\n metadata\r\n });\r\n }\r\n \r\n // Check: non-extractable keys should not be encrypted\r\n if (metadata.extractable === false && metadata.encrypted === true) {\r\n violations.push({\r\n keyId,\r\n type: 'NON_EXTRACTABLE_KEY_ENCRYPTED',\r\n metadata\r\n });\r\n }\r\n }\r\n \r\n if (violations.length > 0) {\r\n this._secureLog('error', 'Storage integrity violations detected', {\r\n violationCount: violations.length\r\n });\r\n return false;\r\n }\r\n \r\n return true;\r\n }\r\n\r\n async getStorageStats() {\r\n const persistentStats = await this._persistentStorage.getStorageStats();\r\n \r\n return {\r\n totalKeys: this._keyReferences.size,\r\n memoryKeys: this._keyReferences.size,\r\n persistentKeys: persistentStats.persistentKeys,\r\n metadata: Array.from(this._keyMetadata.entries()).map(([id, meta]) => ({\r\n id,\r\n created: meta.created,\r\n lastAccessed: meta.lastAccessed,\r\n age: Date.now() - meta.created,\r\n persistent: meta.persistent || false\r\n })),\r\n persistent: persistentStats\r\n };\r\n }\r\n \r\n /**\r\n * List all stored keys (memory + persistent)\r\n */\r\n async listAllKeys() {\r\n try {\r\n const memoryKeys = Array.from(this._keyMetadata.entries()).map(([keyId, metadata]) => ({\r\n keyId,\r\n ...metadata,\r\n location: 'memory'\r\n }));\r\n \r\n const persistentKeys = await this._persistentStorage.listStoredKeys();\r\n const persistentKeysFormatted = persistentKeys.map(key => ({\r\n ...key,\r\n location: 'persistent'\r\n }));\r\n \r\n return {\r\n memoryKeys,\r\n persistentKeys: persistentKeysFormatted,\r\n totalCount: memoryKeys.length + persistentKeysFormatted.length\r\n };\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to list keys', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return {\r\n memoryKeys: [],\r\n persistentKeys: [],\r\n totalCount: 0,\r\n error: error.message\r\n };\r\n }\r\n }\r\n \r\n /**\r\n * Delete key from both memory and persistent storage\r\n */\r\n async deleteKey(keyId) {\r\n try {\r\n // Remove from memory\r\n this._keyReferences.delete(keyId);\r\n this._keyMetadata.delete(keyId);\r\n \r\n // Remove from persistent storage\r\n await this._persistentStorage.deleteKey(keyId);\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to delete key', {\r\n keyIdHash: await this._createSafeLogHash(keyId, 'key_id'),\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n // Method _generateNextSequenceNumber moved to constructor area for early availability\r\n\r\n /**\r\n * Validate incoming message sequence number\r\n * This prevents replay attacks and ensures message ordering\r\n */\r\n _validateIncomingSequenceNumber(receivedSeq, context = 'unknown') {\r\n try {\r\n if (!this.replayProtectionEnabled) {\r\n return true; // Skip validation if disabled\r\n }\r\n\r\n // Check if sequence number is within acceptable range\r\n if (receivedSeq < this.expectedSequenceNumber - this.replayWindowSize) {\r\n this._secureLog('warn', 'Sequence number too old - possible replay attack', {\r\n received: receivedSeq,\r\n expected: this.expectedSequenceNumber,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n\r\n // Check if sequence number is too far ahead (DoS protection)\r\n if (receivedSeq > this.expectedSequenceNumber + this.maxSequenceGap) {\r\n this._secureLog('warn', 'Sequence number gap too large - possible DoS attack', {\r\n received: receivedSeq,\r\n expected: this.expectedSequenceNumber,\r\n gap: receivedSeq - this.expectedSequenceNumber,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n\r\n // Check if sequence number is already in replay window\r\n if (this.replayWindow.has(receivedSeq)) {\r\n this._secureLog('warn', 'Duplicate sequence number detected - replay attack', {\r\n received: receivedSeq,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n\r\n // Add to replay window\r\n this.replayWindow.add(receivedSeq);\r\n \r\n // Maintain sliding window size\r\n if (this.replayWindow.size > this.replayWindowSize) {\r\n const oldestSeq = Math.min(...this.replayWindow);\r\n this.replayWindow.delete(oldestSeq);\r\n }\r\n\r\n // Update expected sequence number if this is the next expected\r\n if (receivedSeq === this.expectedSequenceNumber) {\r\n this.expectedSequenceNumber++;\r\n \r\n // Clean up replay window entries that are no longer needed\r\n while (this.replayWindow.has(this.expectedSequenceNumber - this.replayWindowSize - 1)) {\r\n this.replayWindow.delete(this.expectedSequenceNumber - this.replayWindowSize - 1);\r\n }\r\n }\r\n\r\n this._secureLog('debug', 'Sequence number validation successful', {\r\n received: receivedSeq,\r\n expected: this.expectedSequenceNumber,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Sequence number validation failed', {\r\n error: error.message,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n // Method _createMessageAAD moved to constructor area for early availability\r\n\r\n /**\r\n * Validate message AAD with sequence number\r\n * This ensures message integrity and prevents replay attacks\r\n */\r\n _validateMessageAAD(aadString, expectedMessageType = null) {\r\n try {\r\n const aad = JSON.parse(aadString);\r\n \r\n // Validate session binding\r\n if (aad.sessionId !== (this.currentSession?.sessionId || 'unknown')) {\r\n throw new Error('AAD sessionId mismatch - possible replay attack');\r\n }\r\n \r\n if (aad.keyFingerprint !== (this.keyFingerprint || 'unknown')) {\r\n throw new Error('AAD keyFingerprint mismatch - possible key substitution attack');\r\n }\r\n \r\n // Validate sequence number\r\n if (!this._validateIncomingSequenceNumber(aad.sequenceNumber, aad.messageType)) {\r\n throw new Error('Sequence number validation failed - possible replay or DoS attack');\r\n }\r\n \r\n // Validate message type if specified\r\n if (expectedMessageType && aad.messageType !== expectedMessageType) {\r\n throw new Error(`AAD messageType mismatch - expected ${expectedMessageType}, got ${aad.messageType}`);\r\n }\r\n \r\n return aad;\r\n } catch (error) {\r\n this._secureLog('error', 'AAD validation failed', { error: error.message, aadString });\r\n throw new Error(`AAD validation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Get anti-replay protection status\r\n * This shows the current state of replay protection\r\n */\r\n getAntiReplayStatus() {\r\n const status = {\r\n replayProtectionEnabled: this.replayProtectionEnabled,\r\n replayWindowSize: this.replayWindowSize,\r\n currentReplayWindowSize: this.replayWindow.size,\r\n sequenceNumber: this.sequenceNumber,\r\n expectedSequenceNumber: this.expectedSequenceNumber,\r\n maxSequenceGap: this.maxSequenceGap,\r\n replayWindowEntries: Array.from(this.replayWindow).sort((a, b) => a - b)\r\n };\r\n\r\n this._secureLog('info', 'Anti-replay status retrieved', status);\r\n return status;\r\n }\r\n\r\n /**\r\n * Configure anti-replay protection\r\n * This allows fine-tuning of replay protection parameters\r\n */\r\n configureAntiReplayProtection(config) {\r\n try {\r\n if (config.windowSize !== undefined) {\r\n if (config.windowSize < 16 || config.windowSize > 1024) {\r\n throw new Error('Replay window size must be between 16 and 1024');\r\n }\r\n this.replayWindowSize = config.windowSize;\r\n }\r\n\r\n if (config.maxGap !== undefined) {\r\n if (config.maxGap < 10 || config.maxGap > 1000) {\r\n throw new Error('Max sequence gap must be between 10 and 1000');\r\n }\r\n this.maxSequenceGap = config.maxGap;\r\n }\r\n\r\n if (config.enabled !== undefined) {\r\n this.replayProtectionEnabled = config.enabled;\r\n }\r\n\r\n this._secureLog('info', 'Anti-replay protection configured', config);\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to configure anti-replay protection', { error: error.message });\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get real security level with actual cryptographic tests\r\n * This provides real-time verification of security features\r\n */\r\n async getRealSecurityLevel() {\r\n try {\r\n const securityData = {\r\n // Basic security features\r\n ecdhKeyExchange: !!this.ecdhKeyPair,\r\n ecdsaSignatures: !!this.ecdsaKeyPair,\r\n aesEncryption: !!this.encryptionKey,\r\n messageIntegrity: !!this.hmacKey,\r\n \r\n // Advanced security features - using the exact property names expected by EnhancedSecureCryptoUtils\r\n replayProtection: this.replayProtectionEnabled,\r\n dtlsFingerprint: !!this.expectedDTLSFingerprint,\r\n sasCode: !!this.verificationCode,\r\n metadataProtection: true, // Always enabled\r\n trafficObfuscation: true, // Always enabled\r\n perfectForwardSecrecy: true, // Always enabled\r\n \r\n // Rate limiting\r\n rateLimiter: true, // Always enabled\r\n \r\n // Additional info\r\n connectionId: this.connectionId,\r\n keyFingerprint: this.keyFingerprint,\r\n currentSecurityLevel: 'maximum',\r\n timestamp: Date.now()\r\n };\r\n\r\n \r\n this._secureLog('info', 'Real security level calculated', securityData);\r\n return securityData;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to calculate real security level', { error: error.message });\r\n throw error;\r\n }\r\n }\r\n\r\n\r\n}\r\n\r\n/**\r\n * Secure IndexedDB Wrapper for Encrypted Key Storage\r\n * Provides secure persistent storage with encryption\r\n */\r\nclass SecureIndexedDBWrapper {\r\n constructor(dbName = 'SecureKeyStorage', version = 1) {\r\n this.dbName = dbName;\r\n this.version = version;\r\n this.db = null;\r\n \r\n // Store names\r\n this.KEYS_STORE = 'encrypted_keys';\r\n this.METADATA_STORE = 'key_metadata';\r\n this.SALT_STORE = 'master_salt';\r\n }\r\n \r\n /**\r\n * Initialize IndexedDB connection\r\n */\r\n async initialize() {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, this.version);\r\n \r\n request.onerror = () => {\r\n reject(new Error(`Failed to open IndexedDB: ${request.error}`));\r\n };\r\n \r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n resolve();\r\n };\r\n \r\n request.onupgradeneeded = (event) => {\r\n const db = event.target.result;\r\n \r\n // Create encrypted keys store\r\n if (!db.objectStoreNames.contains(this.KEYS_STORE)) {\r\n const keysStore = db.createObjectStore(this.KEYS_STORE, { keyPath: 'keyId' });\r\n keysStore.createIndex('timestamp', 'timestamp', { unique: false });\r\n keysStore.createIndex('algorithm', 'algorithm', { unique: false });\r\n }\r\n \r\n // Create metadata store\r\n if (!db.objectStoreNames.contains(this.METADATA_STORE)) {\r\n const metadataStore = db.createObjectStore(this.METADATA_STORE, { keyPath: 'keyId' });\r\n metadataStore.createIndex('created', 'created', { unique: false });\r\n metadataStore.createIndex('lastAccessed', 'lastAccessed', { unique: false });\r\n }\r\n \r\n // Create salt store\r\n if (!db.objectStoreNames.contains(this.SALT_STORE)) {\r\n db.createObjectStore(this.SALT_STORE, { keyPath: 'id' });\r\n }\r\n };\r\n });\r\n }\r\n \r\n /**\r\n * Store encrypted key data\r\n */\r\n async storeEncryptedKey(keyId, encryptedData, iv, algorithm, usages, type, metadata = {}) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE, this.METADATA_STORE], 'readwrite');\r\n \r\n const keyRecord = {\r\n keyId: keyId,\r\n encryptedData: Array.from(new Uint8Array(encryptedData)), // Convert to array for storage\r\n iv: Array.from(new Uint8Array(iv)),\r\n algorithm: algorithm,\r\n usages: usages,\r\n type: type,\r\n timestamp: Date.now()\r\n };\r\n \r\n const metadataRecord = {\r\n keyId: keyId,\r\n ...metadata,\r\n created: Date.now(),\r\n lastAccessed: Date.now(),\r\n extractable: true,\r\n persistent: true\r\n };\r\n \r\n return new Promise((resolve, reject) => {\r\n const keysRequest = transaction.objectStore(this.KEYS_STORE).put(keyRecord);\r\n const metadataRequest = transaction.objectStore(this.METADATA_STORE).put(metadataRecord);\r\n \r\n transaction.oncomplete = () => resolve();\r\n transaction.onerror = () => reject(new Error(`Failed to store key: ${transaction.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Retrieve encrypted key data\r\n */\r\n async getEncryptedKey(keyId) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE], 'readonly');\r\n const store = transaction.objectStore(this.KEYS_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.get(keyId);\r\n \r\n request.onsuccess = () => {\r\n const result = request.result;\r\n if (result) {\r\n // Convert arrays back to Uint8Array\r\n result.encryptedData = new Uint8Array(result.encryptedData);\r\n result.iv = new Uint8Array(result.iv);\r\n }\r\n resolve(result);\r\n };\r\n \r\n request.onerror = () => reject(new Error(`Failed to retrieve key: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Update key metadata (e.g., last accessed time)\r\n */\r\n async updateKeyMetadata(keyId, updates) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.METADATA_STORE], 'readwrite');\r\n const store = transaction.objectStore(this.METADATA_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const getRequest = store.get(keyId);\r\n \r\n getRequest.onsuccess = () => {\r\n const metadata = getRequest.result;\r\n if (metadata) {\r\n Object.assign(metadata, updates);\r\n const putRequest = store.put(metadata);\r\n \r\n putRequest.onsuccess = () => resolve();\r\n putRequest.onerror = () => reject(new Error(`Failed to update metadata: ${putRequest.error}`));\r\n } else {\r\n reject(new Error(`Key metadata not found: ${keyId}`));\r\n }\r\n };\r\n \r\n getRequest.onerror = () => reject(new Error(`Failed to get metadata: ${getRequest.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Delete key and its metadata\r\n */\r\n async deleteKey(keyId) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE, this.METADATA_STORE], 'readwrite');\r\n \r\n return new Promise((resolve, reject) => {\r\n const keysRequest = transaction.objectStore(this.KEYS_STORE).delete(keyId);\r\n const metadataRequest = transaction.objectStore(this.METADATA_STORE).delete(keyId);\r\n \r\n transaction.oncomplete = () => resolve();\r\n transaction.onerror = () => reject(new Error(`Failed to delete key: ${transaction.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * List all stored keys\r\n */\r\n async listKeys() {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.METADATA_STORE], 'readonly');\r\n const store = transaction.objectStore(this.METADATA_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.getAll();\r\n \r\n request.onsuccess = () => resolve(request.result);\r\n request.onerror = () => reject(new Error(`Failed to list keys: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Store master key salt\r\n */\r\n async storeMasterSalt(salt) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.SALT_STORE], 'readwrite');\r\n const store = transaction.objectStore(this.SALT_STORE);\r\n \r\n const saltRecord = {\r\n id: 'master_salt',\r\n salt: Array.from(new Uint8Array(salt)),\r\n created: Date.now()\r\n };\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.put(saltRecord);\r\n \r\n request.onsuccess = () => resolve();\r\n request.onerror = () => reject(new Error(`Failed to store salt: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Retrieve master key salt\r\n */\r\n async getMasterSalt() {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.SALT_STORE], 'readonly');\r\n const store = transaction.objectStore(this.SALT_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.get('master_salt');\r\n \r\n request.onsuccess = () => {\r\n const result = request.result;\r\n if (result) {\r\n resolve(new Uint8Array(result.salt));\r\n } else {\r\n resolve(null);\r\n }\r\n };\r\n \r\n request.onerror = () => reject(new Error(`Failed to retrieve salt: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Clear all data (for security wipe)\r\n */\r\n async clearAll() {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE, this.METADATA_STORE, this.SALT_STORE], 'readwrite');\r\n \r\n return new Promise((resolve, reject) => {\r\n const keysRequest = transaction.objectStore(this.KEYS_STORE).clear();\r\n const metadataRequest = transaction.objectStore(this.METADATA_STORE).clear();\r\n const saltRequest = transaction.objectStore(this.SALT_STORE).clear();\r\n \r\n transaction.oncomplete = () => resolve();\r\n transaction.onerror = () => reject(new Error(`Failed to clear database: ${transaction.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Close database connection\r\n */\r\n close() {\r\n if (this.db) {\r\n this.db.close();\r\n this.db = null;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Secure Persistent Key Storage with Key Wrapping\r\n * Implements secure storage of extractable keys using AES-GCM encryption\r\n */\r\nclass SecurePersistentKeyStorage {\r\n constructor(masterKeyManager, indexedDBWrapper = null) {\r\n this._masterKeyManager = masterKeyManager;\r\n this._indexedDB = indexedDBWrapper || new SecureIndexedDBWrapper();\r\n this._dbInitialized = false;\r\n \r\n // In-memory cache for restored keys (WeakMap for automatic cleanup)\r\n this._keyCache = new WeakMap();\r\n this._keyReferences = new Map(); // Strong references for active keys\r\n }\r\n \r\n /**\r\n * Initialize IndexedDB if not already done\r\n */\r\n async _ensureDBInitialized() {\r\n if (!this._dbInitialized) {\r\n await this._indexedDB.initialize();\r\n this._dbInitialized = true;\r\n }\r\n }\r\n \r\n /**\r\n * Store extractable key with encryption\r\n */\r\n async storeExtractableKey(keyId, cryptoKey, metadata = {}) {\r\n if (!(cryptoKey instanceof CryptoKey)) {\r\n throw new Error('Only CryptoKey objects can be stored');\r\n }\r\n \r\n if (!cryptoKey.extractable) {\r\n throw new Error('Key must be extractable for persistent storage');\r\n }\r\n \r\n try {\r\n await this._ensureDBInitialized();\r\n \r\n // Export key to JWK\r\n const jwkData = await crypto.subtle.exportKey('jwk', cryptoKey);\r\n \r\n // Get master key for encryption\r\n const masterKey = this._masterKeyManager.getMasterKey();\r\n \r\n // Encrypt JWK data\r\n const { encryptedData, iv } = await this._encryptKeyData(jwkData, masterKey);\r\n \r\n // Store encrypted data in IndexedDB\r\n await this._indexedDB.storeEncryptedKey(\r\n keyId,\r\n encryptedData,\r\n iv,\r\n cryptoKey.algorithm,\r\n cryptoKey.usages,\r\n cryptoKey.type,\r\n metadata\r\n );\r\n \r\n // Store non-extractable reference in memory cache\r\n const nonExtractableKey = await this._importAsNonExtractable(jwkData, cryptoKey.algorithm, cryptoKey.usages);\r\n this._keyReferences.set(keyId, nonExtractableKey);\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to store extractable key: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Retrieve and restore key from persistent storage\r\n */\r\n async retrieveKey(keyId) {\r\n try {\r\n // Check if key is already in memory cache\r\n if (this._keyReferences.has(keyId)) {\r\n return this._keyReferences.get(keyId);\r\n }\r\n \r\n await this._ensureDBInitialized();\r\n \r\n // Get encrypted key data from IndexedDB\r\n const keyRecord = await this._indexedDB.getEncryptedKey(keyId);\r\n if (!keyRecord) {\r\n return null;\r\n }\r\n \r\n // Get master key for decryption\r\n const masterKey = this._masterKeyManager.getMasterKey();\r\n \r\n // Decrypt JWK data\r\n const jwkData = await this._decryptKeyData(keyRecord.encryptedData, keyRecord.iv, masterKey);\r\n \r\n // Import as non-extractable key\r\n const restoredKey = await this._importAsNonExtractable(jwkData, keyRecord.algorithm, keyRecord.usages);\r\n \r\n // Cache in memory\r\n this._keyReferences.set(keyId, restoredKey);\r\n \r\n // Update last accessed time\r\n await this._indexedDB.updateKeyMetadata(keyId, { lastAccessed: Date.now() });\r\n \r\n return restoredKey;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to retrieve key: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Delete key from persistent storage\r\n */\r\n async deleteKey(keyId) {\r\n try {\r\n await this._ensureDBInitialized();\r\n \r\n // Remove from IndexedDB\r\n await this._indexedDB.deleteKey(keyId);\r\n \r\n // Remove from memory cache\r\n this._keyReferences.delete(keyId);\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to delete key: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * List all stored keys\r\n */\r\n async listStoredKeys() {\r\n try {\r\n await this._ensureDBInitialized();\r\n return await this._indexedDB.listKeys();\r\n } catch (error) {\r\n throw new Error(`Failed to list keys: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Clear all persistent storage\r\n */\r\n async clearAll() {\r\n try {\r\n await this._ensureDBInitialized();\r\n \r\n // Clear IndexedDB\r\n await this._indexedDB.clearAll();\r\n \r\n // Clear memory cache\r\n this._keyReferences.clear();\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to clear storage: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Encrypt key data using master key\r\n */\r\n async _encryptKeyData(jwkData, masterKey) {\r\n // Convert JWK to JSON string and then to bytes\r\n const jsonString = JSON.stringify(jwkData);\r\n const data = new TextEncoder().encode(jsonString);\r\n \r\n // Generate random IV\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n \r\n // Encrypt with AES-GCM\r\n const encryptedData = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n data\r\n );\r\n \r\n return {\r\n encryptedData: new Uint8Array(encryptedData),\r\n iv: iv\r\n };\r\n }\r\n \r\n /**\r\n * Decrypt key data using master key\r\n */\r\n async _decryptKeyData(encryptedData, iv, masterKey) {\r\n // Decrypt with AES-GCM\r\n const decryptedData = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n encryptedData\r\n );\r\n \r\n // Convert back to JWK\r\n const jsonString = new TextDecoder().decode(decryptedData);\r\n return JSON.parse(jsonString);\r\n }\r\n \r\n /**\r\n * Import JWK as non-extractable key\r\n */\r\n async _importAsNonExtractable(jwkData, algorithm, usages) {\r\n return await crypto.subtle.importKey(\r\n 'jwk',\r\n jwkData,\r\n algorithm,\r\n false, // non-extractable for security\r\n usages\r\n );\r\n }\r\n \r\n /**\r\n * Get storage statistics\r\n */\r\n async getStorageStats() {\r\n try {\r\n await this._ensureDBInitialized();\r\n const keys = await this._indexedDB.listKeys();\r\n \r\n return {\r\n totalKeys: keys.length,\r\n memoryKeys: this._keyReferences.size,\r\n persistentKeys: keys.length,\r\n lastAccessed: keys.reduce((latest, key) => \r\n Math.max(latest, key.lastAccessed || 0), 0)\r\n };\r\n \r\n } catch (error) {\r\n return {\r\n totalKeys: 0,\r\n memoryKeys: this._keyReferences.size,\r\n persistentKeys: 0,\r\n lastAccessed: 0,\r\n error: error.message\r\n };\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Secure Master Key Manager with Password-Based Derivation\r\n * Implements PBKDF2-based key derivation and session management\r\n */\r\nclass SecureMasterKeyManager {\r\n constructor(indexedDBWrapper = null) {\r\n // Session state\r\n this._masterKey = null;\r\n this._isUnlocked = false;\r\n this._sessionTimeout = null;\r\n this._lastActivity = null;\r\n \r\n // Configuration\r\n this._sessionTimeoutMs = 60 * 60 * 1000; // 60 minutes (\u0443\u0432\u0435\u043B\u0438\u0447\u0435\u043D\u043E \u0441 15 \u043C\u0438\u043D\u0443\u0442)\r\n this._inactivityTimeoutMs = 30 * 60 * 1000; // 30 minutes (\u0443\u0432\u0435\u043B\u0438\u0447\u0435\u043D\u043E \u0441 5 \u043C\u0438\u043D\u0443\u0442)\r\n \r\n // PBKDF2 parameters\r\n this._pbkdf2Iterations = 100000; // 100k iterations\r\n this._saltSize = 32; // 256 bits\r\n \r\n // IndexedDB wrapper for persistent salt storage\r\n this._indexedDB = indexedDBWrapper || new SecureIndexedDBWrapper();\r\n this._dbInitialized = false;\r\n \r\n // Event handlers\r\n this._onPasswordRequired = null;\r\n this._onSessionExpired = null;\r\n this._onUnlocked = null;\r\n \r\n // Setup event listeners (disabled for better UX - no auto-disconnect)\r\n // this._setupEventListeners();\r\n }\r\n \r\n /**\r\n * Set callback for password requests\r\n */\r\n setPasswordRequiredCallback(callback) {\r\n this._onPasswordRequired = callback;\r\n }\r\n \r\n /**\r\n * Set callback for session expiration\r\n */\r\n setSessionExpiredCallback(callback) {\r\n this._onSessionExpired = callback;\r\n }\r\n \r\n /**\r\n * Set callback for successful unlock\r\n */\r\n setUnlockedCallback(callback) {\r\n this._onUnlocked = callback;\r\n }\r\n \r\n /**\r\n * Setup event listeners for session management\r\n */\r\n _setupEventListeners() {\r\n // Handle page visibility changes\r\n if (typeof document !== 'undefined') {\r\n document.addEventListener('visibilitychange', () => {\r\n if (document.hidden) {\r\n this._handleFocusOut();\r\n } else {\r\n this._handleFocusIn();\r\n }\r\n });\r\n \r\n // Handle window focus/blur\r\n window.addEventListener('blur', () => this._handleFocusOut());\r\n window.addEventListener('focus', () => this._handleFocusIn());\r\n \r\n // Handle user activity\r\n ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'].forEach(event => {\r\n document.addEventListener(event, () => this._updateActivity(), { passive: true });\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Handle focus out - start inactivity timer\r\n */\r\n _handleFocusOut() {\r\n if (this._isUnlocked) {\r\n // Start shorter timeout when window loses focus\r\n this._startInactivityTimer(this._inactivityTimeoutMs);\r\n }\r\n }\r\n \r\n /**\r\n * Handle focus in - reset timers\r\n */\r\n _handleFocusIn() {\r\n if (this._isUnlocked) {\r\n this._resetSessionTimer();\r\n }\r\n }\r\n \r\n /**\r\n * Update last activity timestamp\r\n */\r\n _updateActivity() {\r\n this._lastActivity = Date.now();\r\n if (this._isUnlocked) {\r\n this._resetSessionTimer();\r\n }\r\n }\r\n \r\n /**\r\n * Start session timer\r\n */\r\n _startSessionTimer() {\r\n this._clearTimers();\r\n this._sessionTimeout = setTimeout(() => {\r\n this._expireSession('timeout');\r\n }, this._sessionTimeoutMs);\r\n }\r\n \r\n /**\r\n * Start inactivity timer\r\n */\r\n _startInactivityTimer(timeout) {\r\n this._clearTimers();\r\n this._sessionTimeout = setTimeout(() => {\r\n this._expireSession('inactivity');\r\n }, timeout);\r\n }\r\n \r\n /**\r\n * Reset session timer\r\n */\r\n _resetSessionTimer() {\r\n if (this._isUnlocked) {\r\n this._startSessionTimer();\r\n }\r\n }\r\n \r\n /**\r\n * Clear all timers\r\n */\r\n _clearTimers() {\r\n if (this._sessionTimeout) {\r\n clearTimeout(this._sessionTimeout);\r\n this._sessionTimeout = null;\r\n }\r\n }\r\n \r\n /**\r\n * Expire the current session\r\n */\r\n _expireSession(reason = 'unknown') {\r\n if (this._isUnlocked) {\r\n this._secureWipeMasterKey();\r\n this._isUnlocked = false;\r\n \r\n if (this._onSessionExpired) {\r\n this._onSessionExpired(reason);\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Initialize IndexedDB if not already done\r\n */\r\n async _ensureDBInitialized() {\r\n if (!this._dbInitialized) {\r\n await this._indexedDB.initialize();\r\n this._dbInitialized = true;\r\n }\r\n }\r\n \r\n /**\r\n * Generate salt for PBKDF2\r\n */\r\n _generateSalt() {\r\n return crypto.getRandomValues(new Uint8Array(this._saltSize));\r\n }\r\n \r\n /**\r\n * Get or create persistent salt\r\n */\r\n async _getOrCreateSalt() {\r\n await this._ensureDBInitialized();\r\n \r\n // Try to get existing salt\r\n let salt = await this._indexedDB.getMasterSalt();\r\n \r\n if (!salt) {\r\n // Generate new salt and store it\r\n salt = this._generateSalt();\r\n await this._indexedDB.storeMasterSalt(salt);\r\n }\r\n \r\n return salt;\r\n }\r\n \r\n /**\r\n * Derive master key from password using PBKDF2\r\n */\r\n async _deriveKeyFromPassword(password, salt) {\r\n try {\r\n // Import password as key material\r\n const passwordKey = await crypto.subtle.importKey(\r\n 'raw',\r\n new TextEncoder().encode(password),\r\n 'PBKDF2',\r\n false,\r\n ['deriveKey']\r\n );\r\n \r\n // Derive AES-GCM key using PBKDF2\r\n const derivedKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt: salt,\r\n iterations: this._pbkdf2Iterations,\r\n hash: 'SHA-256'\r\n },\r\n passwordKey,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // non-extractable for security\r\n ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']\r\n );\r\n \r\n return derivedKey;\r\n } catch (error) {\r\n throw new Error(`Key derivation failed: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Request password from user\r\n */\r\n async _requestPassword(isRetry = false) {\r\n if (!this._onPasswordRequired) {\r\n throw new Error('Password callback not set');\r\n }\r\n \r\n return new Promise((resolve, reject) => {\r\n this._onPasswordRequired(isRetry, (password) => {\r\n if (password) {\r\n resolve(password);\r\n } else {\r\n reject(new Error('Password not provided'));\r\n }\r\n });\r\n });\r\n }\r\n \r\n /**\r\n * Unlock the master key with password\r\n */\r\n async unlock(password = null) {\r\n try {\r\n // Request password if not provided\r\n if (!password) {\r\n password = await this._requestPassword(false);\r\n }\r\n \r\n // Get or create persistent salt\r\n const salt = await this._getOrCreateSalt();\r\n \r\n // Derive master key\r\n this._masterKey = await this._deriveKeyFromPassword(password, salt);\r\n \r\n // Mark as unlocked\r\n this._isUnlocked = true;\r\n this._lastActivity = Date.now();\r\n \r\n // Start session timer\r\n this._startSessionTimer();\r\n \r\n // Securely wipe password from memory\r\n password = null;\r\n \r\n if (this._onUnlocked) {\r\n this._onUnlocked();\r\n }\r\n \r\n return { success: true };\r\n \r\n } catch (error) {\r\n // Securely wipe password on error\r\n password = null;\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Lock the master key\r\n */\r\n lock() {\r\n this._expireSession('manual');\r\n }\r\n \r\n /**\r\n * Get master key (only if unlocked)\r\n */\r\n getMasterKey() {\r\n if (!this._isUnlocked || !this._masterKey) {\r\n throw new Error('Master key is locked');\r\n }\r\n \r\n this._updateActivity();\r\n return this._masterKey;\r\n }\r\n \r\n /**\r\n * Check if master key is unlocked\r\n */\r\n isUnlocked() {\r\n return this._isUnlocked && this._masterKey !== null;\r\n }\r\n \r\n /**\r\n * Get session status\r\n */\r\n getSessionStatus() {\r\n return {\r\n isUnlocked: this._isUnlocked,\r\n lastActivity: this._lastActivity,\r\n sessionTimeoutMs: this._sessionTimeoutMs,\r\n inactivityTimeoutMs: this._inactivityTimeoutMs\r\n };\r\n }\r\n \r\n /**\r\n * Securely wipe master key from memory\r\n */\r\n _secureWipeMasterKey() {\r\n if (this._masterKey) {\r\n // CryptoKey objects are automatically garbage collected\r\n // but we clear the reference immediately\r\n this._masterKey = null;\r\n }\r\n this._clearTimers();\r\n }\r\n \r\n /**\r\n * Cleanup on destruction\r\n */\r\n destroy() {\r\n this._secureWipeMasterKey();\r\n this._isUnlocked = false;\r\n \r\n // Remove event listeners\r\n if (typeof document !== 'undefined') {\r\n document.removeEventListener('visibilitychange', this._handleFocusOut);\r\n window.removeEventListener('blur', this._handleFocusOut);\r\n window.removeEventListener('focus', this._handleFocusIn);\r\n }\r\n }\r\n}\r\n\r\nexport { \r\n EnhancedSecureWebRTCManager, \r\n SecureMasterKeyManager, \r\n SecureIndexedDBWrapper, \r\n SecurePersistentKeyStorage \r\n};", "import { EnhancedSecureCryptoUtils } from '../crypto/EnhancedSecureCryptoUtils.js';\r\nimport { EnhancedSecureWebRTCManager } from '../network/EnhancedSecureWebRTCManager.js';\r\nimport { EnhancedSecureFileTransfer } from '../transfer/EnhancedSecureFileTransfer.js';\r\nimport { NotificationIntegration } from '../notifications/NotificationIntegration.js';\r\n\r\n// Import UI components (side-effect: they attach themselves to window.*)\r\nimport '../components/ui/Header.jsx';\r\nimport '../components/ui/DownloadApps.jsx';\r\nimport '../components/ui/UniqueFeatureSlider.jsx';\r\nimport '../components/ui/SecurityFeatures.jsx';\r\nimport '../components/ui/Testimonials.jsx';\r\nimport '../components/ui/ComparisonTable.jsx';\r\nimport '../components/ui/Roadmap.jsx';\r\nimport '../components/ui/FileTransfer.jsx';\r\n\r\n// Expose to global for legacy usage inside app code\r\nwindow.EnhancedSecureCryptoUtils = EnhancedSecureCryptoUtils;\r\nwindow.EnhancedSecureWebRTCManager = EnhancedSecureWebRTCManager;\r\nwindow.EnhancedSecureFileTransfer = EnhancedSecureFileTransfer;\r\nwindow.NotificationIntegration = NotificationIntegration;\r\n\r\n// Mount application once DOM and modules are ready\r\nconst start = () => {\r\n if (typeof window.initializeApp === 'function') {\r\n window.initializeApp();\r\n } else if (window.DEBUG_MODE) {\r\n console.error('initializeApp is not defined on window');\r\n }\r\n};\r\n\r\nif (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', start);\r\n} else {\r\n start();\r\n}\r\n", "const EnhancedMinimalHeader = ({ \n status, \n fingerprint, \n verificationCode, \n onDisconnect, \n isConnected, \n securityLevel, \n webrtcManager \n}) => {\n const [realSecurityLevel, setRealSecurityLevel] = React.useState(null);\n const [lastSecurityUpdate, setLastSecurityUpdate] = React.useState(0);\n // Added local session state to remove references errors after session timer removal\n const [hasActiveSession, setHasActiveSession] = React.useState(false);\n const [currentTimeLeft, setCurrentTimeLeft] = React.useState(0);\n const [sessionType, setSessionType] = React.useState('unknown');\n\n // ============================================\n // FIXED SECURITY UPDATE LOGIC\n // ============================================\n \n React.useEffect(() => {\n let isUpdating = false; \n let lastUpdateAttempt = 0; \n \n const updateRealSecurityStatus = async () => {\n const now = Date.now();\n if (now - lastUpdateAttempt < 10000) { \n return;\n }\n\n if (isUpdating) {\n return;\n }\n \n isUpdating = true;\n lastUpdateAttempt = now;\n \n try {\n if (!webrtcManager || !isConnected) {\n return;\n }\n \n const activeWebrtcManager = webrtcManager;\n \n let realSecurityData = null;\n \n if (typeof activeWebrtcManager.getRealSecurityLevel === 'function') {\n realSecurityData = await activeWebrtcManager.getRealSecurityLevel();\n } else if (typeof activeWebrtcManager.calculateAndReportSecurityLevel === 'function') {\n realSecurityData = await activeWebrtcManager.calculateAndReportSecurityLevel();\n } else {\n realSecurityData = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(activeWebrtcManager);\n }\n \n if (realSecurityData && realSecurityData.isRealData !== false) {\n const currentScore = realSecurityLevel?.score || 0;\n const newScore = realSecurityData.score || 0;\n\n if (currentScore !== newScore || !realSecurityLevel) {\n setRealSecurityLevel(realSecurityData);\n setLastSecurityUpdate(now);\n\n } else if (window.DEBUG_MODE) {\n }\n } else {\n console.warn(' Security calculation returned invalid data');\n }\n \n } catch (error) {\n console.error(' Error in real security calculation:', error);\n } finally {\n isUpdating = false;\n }\n };\n\n if (isConnected) {\n updateRealSecurityStatus();\n \n if (!realSecurityLevel || realSecurityLevel.score < 50) {\n const retryInterval = setInterval(() => {\n if (!realSecurityLevel || realSecurityLevel.score < 50) {\n updateRealSecurityStatus();\n } else {\n clearInterval(retryInterval);\n }\n }, 5000); \n \n setTimeout(() => clearInterval(retryInterval), 30000);\n }\n }\n\n const interval = setInterval(updateRealSecurityStatus, 30000);\n \n return () => clearInterval(interval);\n }, [webrtcManager, isConnected]);\n\n // ============================================\n // FIXED EVENT HANDLERS\n // ============================================\n\n React.useEffect(() => {\n const handleSecurityUpdate = (event) => {\n\n setTimeout(() => {\n setLastSecurityUpdate(0);\n }, 100);\n };\n\n const handleRealSecurityCalculated = (event) => {\n \n if (event.detail && event.detail.securityData) {\n setRealSecurityLevel(event.detail.securityData);\n setLastSecurityUpdate(Date.now());\n }\n };\n\n document.addEventListener('security-level-updated', handleSecurityUpdate);\n document.addEventListener('real-security-calculated', handleRealSecurityCalculated);\n \n window.forceHeaderSecurityUpdate = (webrtcManager) => {\n \n if (webrtcManager && window.EnhancedSecureCryptoUtils) {\n window.EnhancedSecureCryptoUtils.calculateSecurityLevel(webrtcManager)\n .then(securityData => {\n if (securityData && securityData.isRealData !== false) {\n setRealSecurityLevel(securityData);\n setLastSecurityUpdate(Date.now());\n console.log('\u2705 Header security level force-updated');\n }\n })\n .catch(error => {\n console.error('\u274C Force update failed:', error);\n });\n } else {\n setLastSecurityUpdate(0); \n }\n };\n\n return () => {\n document.removeEventListener('security-level-updated', handleSecurityUpdate);\n document.removeEventListener('real-security-calculated', handleRealSecurityCalculated);\n };\n }, []);\n\n // ============================================\n // REST of the component logic\n // ============================================\n\n React.useEffect(() => {\n // All security features are enabled by default - no session management needed\n setHasActiveSession(true);\n setCurrentTimeLeft(0);\n setSessionType('premium'); // All features enabled\n }, []);\n\n React.useEffect(() => {\n // All security features are enabled by default\n setHasActiveSession(true);\n setCurrentTimeLeft(0);\n setSessionType('premium'); // All features enabled\n }, []);\n\n React.useEffect(() => {\n const handleForceUpdate = (event) => {\n // All security features are enabled by default\n setHasActiveSession(true);\n setCurrentTimeLeft(0);\n setSessionType('premium'); // All features enabled\n };\n\n // Connection cleanup handler (use existing event from module)\n const handleConnectionCleaned = () => {\n if (window.DEBUG_MODE) {\n console.log('\uD83E\uDDF9 Connection cleaned - clearing security data in header');\n }\n\n setRealSecurityLevel(null);\n setLastSecurityUpdate(0);\n\n setHasActiveSession(false);\n setCurrentTimeLeft(0);\n setSessionType('unknown');\n };\n\n const handlePeerDisconnect = () => {\n if (window.DEBUG_MODE) {\n console.log('\uD83D\uDC4B Peer disconnect detected - clearing security data in header');\n }\n\n setRealSecurityLevel(null);\n setLastSecurityUpdate(0);\n };\n\n const handleDisconnected = () => {\n\n setRealSecurityLevel(null);\n setLastSecurityUpdate(0);\n setHasActiveSession(false);\n setCurrentTimeLeft(0);\n setSessionType('unknown');\n };\n\n document.addEventListener('force-header-update', handleForceUpdate);\n document.addEventListener('peer-disconnect', handlePeerDisconnect);\n document.addEventListener('connection-cleaned', handleConnectionCleaned);\n document.addEventListener('disconnected', handleDisconnected);\n \n return () => {\n document.removeEventListener('force-header-update', handleForceUpdate);\n document.removeEventListener('peer-disconnect', handlePeerDisconnect);\n document.removeEventListener('connection-cleaned', handleConnectionCleaned);\n document.removeEventListener('disconnected', handleDisconnected);\n };\n }, []);\n\n // ============================================\n // SECURITY INDICATOR CLICK HANDLER\n // ============================================\n\n const handleSecurityClick = async (event) => {\n // Check if it's a right-click or Ctrl+click to disconnect\n if (event && (event.button === 2 || event.ctrlKey || event.metaKey)) {\n if (onDisconnect && typeof onDisconnect === 'function') {\n onDisconnect();\n return;\n }\n }\n\n // Prevent default behavior\n event.preventDefault();\n event.stopPropagation();\n\n\n // Run real security tests if webrtcManager is available\n let realTestResults = null;\n if (webrtcManager && window.EnhancedSecureCryptoUtils) {\n try {\n realTestResults = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(webrtcManager);\n console.log('\u2705 Real security tests completed:', realTestResults);\n } catch (error) {\n console.error('\u274C Real security tests failed:', error);\n }\n } else {\n console.log('\u26A0\uFE0F Cannot run security tests:', {\n webrtcManager: !!webrtcManager,\n cryptoUtils: !!window.EnhancedSecureCryptoUtils\n });\n }\n\n // If no real test results and no existing security level, show progress message\n if (!realTestResults && !realSecurityLevel) {\n alert('Security verification in progress...\\nPlease wait for real-time cryptographic verification to complete.');\n return;\n }\n\n // Use real test results if available, otherwise fall back to current data\n let securityData = realTestResults || realSecurityLevel;\n\n // If still no security data, create a basic fallback\n if (!securityData) {\n securityData = {\n level: 'UNKNOWN',\n score: 0,\n color: 'gray',\n verificationResults: {},\n timestamp: Date.now(),\n details: 'Security verification not available',\n isRealData: false,\n passedChecks: 0,\n totalChecks: 0\n };\n console.log('Using fallback security data:', securityData);\n }\n\n // Detailed information about the REAL security check\n let message = `REAL-TIME SECURITY VERIFICATION\\n\\n`;\n message += `Security Level: ${securityData.level} (${securityData.score}%)\\n`;\n message += `Verification Time: ${new Date(securityData.timestamp).toLocaleTimeString()}\\n`;\n message += `Data Source: ${securityData.isRealData ? 'Real Cryptographic Tests' : 'Simulated Data'}\\n\\n`;\n \n if (securityData.verificationResults) {\n message += 'DETAILED CRYPTOGRAPHIC TESTS:\\n';\n message += '=' + '='.repeat(40) + '\\n';\n \n const passedTests = Object.entries(securityData.verificationResults).filter(([key, result]) => result.passed);\n const failedTests = Object.entries(securityData.verificationResults).filter(([key, result]) => !result.passed);\n \n if (passedTests.length > 0) {\n message += 'PASSED TESTS:\\n';\n passedTests.forEach(([key, result]) => {\n const testName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());\n message += ` ${testName}: ${result.details || 'Test passed'}\\n`;\n });\n message += '\\n';\n }\n \n if (failedTests.length > 0) {\n message += 'FAILED/UNAVAILABLE TESTS:\\n';\n failedTests.forEach(([key, result]) => {\n const testName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());\n message += ` ${testName}: ${result.details || 'Test failed or unavailable'}\\n`;\n });\n message += '\\n';\n }\n \n message += `SUMMARY:\\n`;\n message += `Passed: ${securityData.passedChecks}/${securityData.totalChecks} tests\\n`;\n message += `Score: ${securityData.score}/${securityData.maxPossibleScore || 100} points\\n\\n`;\n }\n \n // Real security features status\n message += `SECURITY FEATURES STATUS:\\n`;\n message += '=' + '='.repeat(40) + '\\n';\n \n if (securityData.verificationResults) {\n const features = {\n 'ECDSA Digital Signatures': securityData.verificationResults.verifyECDSASignatures?.passed || false,\n 'ECDH Key Exchange': securityData.verificationResults.verifyECDHKeyExchange?.passed || false,\n 'AES-GCM Encryption': securityData.verificationResults.verifyEncryption?.passed || false,\n 'Message Integrity (HMAC)': securityData.verificationResults.verifyMessageIntegrity?.passed || false,\n 'Perfect Forward Secrecy': securityData.verificationResults.verifyPerfectForwardSecrecy?.passed || false,\n 'Replay Protection': securityData.verificationResults.verifyReplayProtection?.passed || false,\n 'DTLS Fingerprint': securityData.verificationResults.verifyDTLSFingerprint?.passed || false,\n 'SAS Verification': securityData.verificationResults.verifySASVerification?.passed || false,\n 'Metadata Protection': securityData.verificationResults.verifyMetadataProtection?.passed || false,\n 'Traffic Obfuscation': securityData.verificationResults.verifyTrafficObfuscation?.passed || false\n };\n \n Object.entries(features).forEach(([feature, isEnabled]) => {\n message += `${isEnabled ? '\u2705' : '\u274C'} ${feature}\\n`;\n });\n } else {\n // Fallback if no verification results\n message += `\u2705 ECDSA Digital Signatures\\n`;\n message += `\u2705 ECDH Key Exchange\\n`;\n message += `\u2705 AES-GCM Encryption\\n`;\n message += `\u2705 Message Integrity (HMAC)\\n`;\n message += `\u2705 Perfect Forward Secrecy\\n`;\n message += `\u2705 Replay Protection\\n`;\n message += `\u2705 DTLS Fingerprint\\n`;\n message += `\u2705 SAS Verification\\n`;\n message += `\u2705 Metadata Protection\\n`;\n message += `\u2705 Traffic Obfuscation\\n`;\n }\n \n message += `\\n${securityData.details || 'Real cryptographic verification completed'}`;\n \n if (securityData.isRealData) {\n message += '\\n\\n\u2705 This is REAL-TIME verification using actual cryptographic functions.';\n } else {\n message += '\\n\\n\u26A0\uFE0F Warning: This data may be simulated. Connection may not be fully established.';\n }\n \n // Show in a more user-friendly way\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0,0,0,0.8);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: monospace;\n `;\n \n const content = document.createElement('div');\n content.style.cssText = `\n background: #1a1a1a;\n color: #fff;\n padding: 20px;\n border-radius: 8px;\n max-width: 80%;\n max-height: 80%;\n overflow-y: auto;\n white-space: pre-line;\n border: 1px solid #333;\n `;\n \n content.textContent = message;\n modal.appendChild(content);\n \n // Close on click outside\n modal.addEventListener('click', (e) => {\n if (e.target === modal) {\n document.body.removeChild(modal);\n }\n });\n \n // Close on Escape key\n const handleKeyDown = (e) => {\n if (e.key === 'Escape') {\n document.body.removeChild(modal);\n document.removeEventListener('keydown', handleKeyDown);\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n \n document.body.appendChild(modal);\n };\n\n // ============================================\n // DISPLAY UTILITIES\n // ============================================\n\n const getStatusConfig = () => {\n switch (status) {\n case 'connected':\n return {\n text: 'Connected',\n className: 'status-connected',\n badgeClass: 'bg-green-500/10 text-green-400 border-green-500/20'\n };\n case 'verifying':\n return {\n text: 'Verifying...',\n className: 'status-verifying',\n badgeClass: 'bg-purple-500/10 text-purple-400 border-purple-500/20'\n };\n case 'connecting':\n return {\n text: 'Connecting...',\n className: 'status-connecting',\n badgeClass: 'bg-blue-500/10 text-blue-400 border-blue-500/20'\n };\n case 'retrying':\n return {\n text: 'Retrying...',\n className: 'status-connecting',\n badgeClass: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20'\n };\n case 'failed':\n return {\n text: 'Error',\n className: 'status-failed',\n badgeClass: 'bg-red-500/10 text-red-400 border-red-500/20'\n };\n case 'reconnecting':\n return {\n text: 'Reconnecting...',\n className: 'status-connecting',\n badgeClass: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20'\n };\n case 'peer_disconnected':\n return {\n text: 'Peer disconnected',\n className: 'status-failed',\n badgeClass: 'bg-orange-500/10 text-orange-400 border-orange-500/20'\n };\n default:\n return {\n text: 'Not connected',\n className: 'status-disconnected',\n badgeClass: 'bg-gray-500/10 text-gray-400 border-gray-500/20'\n };\n }\n };\n\n const config = getStatusConfig();\n const displaySecurityLevel = isConnected ? (realSecurityLevel || securityLevel) : null;\n \n\n // ============================================\n // DATA RELIABILITY INDICATOR\n // ============================================\n\n const getSecurityIndicatorDetails = () => {\n if (!displaySecurityLevel) {\n return {\n tooltip: 'Security verification in progress...',\n isVerified: false,\n dataSource: 'loading'\n };\n }\n \n const isRealData = displaySecurityLevel.isRealData !== false;\n const baseTooltip = `${displaySecurityLevel.level} (${displaySecurityLevel.score}%)`;\n \n if (isRealData) {\n return {\n tooltip: `${baseTooltip} - Real-time verification \u2705\\nRight-click or Ctrl+click to disconnect`,\n isVerified: true,\n dataSource: 'real'\n };\n } else {\n return {\n tooltip: `${baseTooltip} - Estimated (connection establishing...)\\nRight-click or Ctrl+click to disconnect`,\n isVerified: false,\n dataSource: 'estimated'\n };\n }\n };\n\n const securityDetails = getSecurityIndicatorDetails();\n\n // ============================================\n // ADDING global methods for debugging\n // ============================================\n\n React.useEffect(() => {\n window.debugHeaderSecurity = () => {\n console.log('\uD83D\uDD0D Header Security Debug:', {\n realSecurityLevel,\n lastSecurityUpdate,\n isConnected,\n webrtcManagerProp: !!webrtcManager,\n windowWebrtcManager: !!window.webrtcManager,\n cryptoUtils: !!window.EnhancedSecureCryptoUtils,\n displaySecurityLevel: displaySecurityLevel,\n securityDetails: securityDetails\n });\n };\n \n return () => {\n delete window.debugHeaderSecurity;\n };\n }, [realSecurityLevel, lastSecurityUpdate, isConnected, webrtcManager, displaySecurityLevel, securityDetails]);\n\n // ============================================\n // RENDER\n // ============================================\n\n return React.createElement('header', {\n className: 'header-minimal sticky top-0 z-50'\n }, [\n React.createElement('div', {\n key: 'container',\n className: 'max-w-7xl mx-auto px-4 sm:px-6 lg:px-8'\n }, [\n React.createElement('div', {\n key: 'content',\n className: 'flex items-center justify-between h-16'\n }, [\n // Logo and Title\n React.createElement('div', {\n key: 'logo-section',\n className: 'flex items-center space-x-2 sm:space-x-3'\n }, [\n React.createElement('div', {\n key: 'logo',\n className: 'icon-container w-8 h-8 sm:w-10 sm:h-10'\n }, [\n React.createElement('i', {\n className: 'fas fa-shield-halved accent-orange text-sm sm:text-base'\n })\n ]),\n React.createElement('div', {\n key: 'title-section'\n }, [\n React.createElement('h1', {\n key: 'title',\n className: 'text-lg sm:text-xl font-semibold text-primary'\n }, 'SecureBit.chat'),\n React.createElement('p', {\n key: 'subtitle',\n className: 'text-xs sm:text-sm text-muted hidden sm:block'\n }, 'End-to-end freedom v4.4.18')\n ])\n ]),\n\n // Status and Controls - Responsive\n React.createElement('div', {\n key: 'status-section',\n className: 'flex items-center space-x-2 sm:space-x-3'\n }, [\n\n displaySecurityLevel && React.createElement('div', {\n key: 'security-level',\n className: 'hidden md:flex items-center space-x-2 cursor-pointer hover:opacity-80 transition-opacity duration-200',\n onClick: handleSecurityClick,\n onContextMenu: (e) => {\n e.preventDefault();\n if (onDisconnect && typeof onDisconnect === 'function') {\n onDisconnect();\n }\n },\n title: securityDetails.tooltip\n }, [\n React.createElement('div', {\n key: 'security-icon',\n className: `w-6 h-6 rounded-full flex items-center justify-center relative ${\n displaySecurityLevel.color === 'green' ? 'bg-green-500/20' :\n displaySecurityLevel.color === 'orange' ? 'bg-orange-500/20' :\n displaySecurityLevel.color === 'yellow' ? 'bg-yellow-500/20' : 'bg-red-500/20'\n } ${securityDetails.isVerified ? '' : 'animate-pulse'}`\n }, [\n React.createElement('i', {\n className: `fas fa-shield-alt text-xs ${\n displaySecurityLevel.color === 'green' ? 'text-green-400' :\n displaySecurityLevel.color === 'orange' ? 'text-orange-400' :\n displaySecurityLevel.color === 'yellow' ? 'text-yellow-400' : 'text-red-400'\n }`\n })\n ]),\n React.createElement('div', {\n key: 'security-info',\n className: 'flex flex-col'\n }, [\n React.createElement('div', {\n key: 'security-level-text',\n className: 'text-xs font-medium text-primary flex items-center space-x-1'\n }, [\n React.createElement('span', {}, `${displaySecurityLevel.level} (${displaySecurityLevel.score}%)`)\n ]),\n React.createElement('div', {\n key: 'security-details',\n className: 'text-xs text-muted mt-1 hidden lg:block'\n }, securityDetails.dataSource === 'real' ? \n `${displaySecurityLevel.passedChecks || 0}/${displaySecurityLevel.totalChecks || 0} tests` :\n (displaySecurityLevel.details || `Stage ${displaySecurityLevel.stage || 1}`)\n ),\n React.createElement('div', {\n key: 'security-progress',\n className: 'w-16 h-1 bg-gray-600 rounded-full overflow-hidden'\n }, [\n React.createElement('div', {\n key: 'progress-bar',\n className: `h-full transition-all duration-500 ${\n displaySecurityLevel.color === 'green' ? 'bg-green-400' :\n displaySecurityLevel.color === 'orange' ? 'bg-orange-400' :\n displaySecurityLevel.color === 'yellow' ? 'bg-yellow-400' : 'bg-red-400'\n }`,\n style: { width: `${displaySecurityLevel.score}%` }\n })\n ])\n ])\n ]),\n\n // Mobile Security Indicator\n displaySecurityLevel && React.createElement('div', {\n key: 'mobile-security',\n className: 'md:hidden flex items-center'\n }, [\n React.createElement('div', {\n key: 'mobile-security-icon',\n className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer hover:opacity-80 transition-opacity duration-200 relative ${\n displaySecurityLevel.color === 'green' ? 'bg-green-500/20' :\n displaySecurityLevel.color === 'orange' ? 'bg-orange-500/20' :\n displaySecurityLevel.color === 'yellow' ? 'bg-yellow-500/20' : 'bg-red-500/20'\n } ${securityDetails.isVerified ? '' : 'animate-pulse'}`,\n title: securityDetails.tooltip,\n onClick: handleSecurityClick,\n onContextMenu: (e) => {\n e.preventDefault();\n if (onDisconnect && typeof onDisconnect === 'function') {\n onDisconnect();\n }\n }\n }, [\n React.createElement('i', {\n className: `fas fa-shield-alt text-sm ${\n displaySecurityLevel.color === 'green' ? 'text-green-400' :\n displaySecurityLevel.color === 'orange' ? 'text-orange-400' :\n displaySecurityLevel.color === 'yellow' ? 'text-yellow-400' : 'text-red-400'\n }`\n })\n ])\n ]),\n\n // Status Badge\n React.createElement('div', {\n key: 'status-badge',\n className: `px-2 sm:px-3 py-1.5 rounded-lg border ${config.badgeClass} flex items-center space-x-1 sm:space-x-2`\n }, [\n React.createElement('span', {\n key: 'status-dot',\n className: `status-dot ${config.className}`\n }),\n React.createElement('span', {\n key: 'status-text',\n className: 'text-xs sm:text-sm font-medium'\n }, config.text),\n ]),\n\n // Disconnect Button\n isConnected && React.createElement('button', {\n key: 'disconnect-btn',\n onClick: onDisconnect,\n className: 'p-1.5 sm:px-3 sm:py-1.5 bg-red-500/10 hover:bg-red-500/20 text-red-400 border border-red-500/20 rounded-lg transition-all duration-200 text-sm'\n }, [\n React.createElement('i', {\n className: 'fas fa-power-off sm:mr-2'\n }),\n React.createElement('span', {\n className: 'hidden sm:inline'\n }, 'Disconnect')\n ])\n ])\n ])\n ])\n ]);\n};\n\nwindow.EnhancedMinimalHeader = EnhancedMinimalHeader;\n", "const DownloadApps = () => {\r\n const apps = [\r\n { id: 'web', name: 'Web App', subtitle: 'Browser Version', icon: 'fas fa-globe', platform: 'Web', isActive: true, url: 'https://securebit.chat/', color: 'green' },\r\n { id: 'windows', name: 'Windows', subtitle: 'Desktop App', icon: 'fab fa-windows', platform: 'Desktop', isActive: false, url: 'https://securebit.chat/download/windows/SecureBit%20Chat%20Setup%204.1.222.exe', color: 'blue' },\r\n { id: 'macos', name: 'macOS', subtitle: 'Desktop App', icon: 'fab fa-safari', platform: 'Desktop', isActive: false, url: '#', color: 'gray' },\r\n { id: 'linux', name: 'Linux', subtitle: 'Desktop App', icon: 'fab fa-linux', platform: 'Desktop', isActive: false, url: '#', color: 'orange' },\r\n { id: 'ios', name: 'iOS', subtitle: 'iPhone & iPad', icon: 'fab fa-apple', platform: 'Mobile', isActive: false, url: 'https://apps.apple.com/app/securebit-chat/', color: 'white' },\r\n { id: 'android', name: 'Android', subtitle: 'Google Play', icon: 'fab fa-android', platform: 'Mobile', isActive: false, url: 'https://play.google.com/store/apps/details?id=com.securebit.chat', color: 'green' },\r\n { id: 'chrome', name: 'Chrome', subtitle: 'Browser Extension', icon: 'fab fa-chrome', platform: 'Browser', isActive: false, url: '#', color: 'yellow' },\r\n { id: 'edge', name: 'Edge', subtitle: 'Browser Extension', icon: 'fab fa-edge', platform: 'Browser', isActive: false, url: '#', color: 'blue' },\r\n { id: 'opera', name: 'Opera', subtitle: 'Browser Extension', icon: 'fab fa-opera', platform: 'Browser', isActive: false, url: '#', color: 'red' },\r\n { id: 'firefox', name: 'Firefox', subtitle: 'Browser Extension', icon: 'fab fa-firefox-browser', platform: 'Browser', isActive: false, url: '#', color: 'orange' },\r\n ];\r\n\r\n const handleDownload = (app) => {\r\n if (app.isActive) window.open(app.url, '_blank');\r\n };\r\n\r\n const desktopApps = apps.filter(a => a.platform === 'Desktop' || a.platform === 'Web');\r\n const mobileApps = apps.filter(a => a.platform === 'Mobile');\r\n const browserApps = apps.filter(a => a.platform === 'Browser');\r\n\r\n const cardSize = \"w-28 h-28\";\r\n\r\n const colorClasses = {\r\n green: 'text-green-500',\r\n blue: 'text-blue-500',\r\n gray: 'text-gray-500',\r\n orange: 'text-orange-500',\r\n red: 'text-red-500',\r\n white: 'text-white',\r\n yellow: 'text-yellow-400',\r\n };\r\n\r\n const renderAppCard = (app) => (\r\n React.createElement('div', {\r\n key: app.id,\r\n className: `group relative ${cardSize} rounded-2xl overflow-hidden card-minimal cursor-pointer`\r\n }, [\r\n React.createElement('i', {\r\n key: 'bg-icon',\r\n className: `${app.icon} absolute text-[3rem] ${app.isActive ? colorClasses[app.color] : 'text-white/10'} top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none transition-all duration-500 group-hover:scale-105`\r\n }),\r\n React.createElement('div', {\r\n key: 'overlay',\r\n className: \"absolute inset-0 bg-black/30 backdrop-blur-md flex flex-col items-center justify-center text-center opacity-0 transition-opacity duration-300 group-hover:opacity-100\"\r\n }, [\r\n React.createElement('h4', { key: 'name', className: `text-sm font-semibold text-primary mb-1` }, app.name),\r\n React.createElement('p', { key: 'subtitle', className: `text-xs text-secondary mb-2` }, app.subtitle),\r\n app.isActive ?\r\n React.createElement('button', {\r\n key: 'btn',\r\n onClick: () => handleDownload(app),\r\n className: `px-2 py-1 rounded-xl bg-emerald-500 text-black font-medium hover:bg-emerald-600 transition-colors text-xs`\r\n }, app.id === \"web\" ? \"Launch\" : \"Download\")\r\n :\r\n React.createElement('span', { key: 'coming', className: \"text-gray-400 font-medium text-xs\" }, \"Coming Soon\")\r\n ])\r\n ])\r\n );\r\n\r\n return React.createElement('div', { className: \"mt-20 px-6\" }, [\r\n // Header\r\n React.createElement('div', { key: 'header', className: \"text-center max-w-3xl mx-auto mb-12\" }, [\r\n React.createElement('h3', { key: 'title', className: \"text-3xl font-bold text-primary mb-3\" }, 'Download SecureBit.chat'),\r\n React.createElement('p', { key: 'subtitle', className: \"text-secondary text-lg mb-5\" }, 'Stay secure on every device. Choose your platform and start chatting privately.')\r\n ]),\r\n\r\n // Desktop Apps\r\n React.createElement('div', { key: 'desktop-row', className: \"hidden sm:flex justify-center flex-wrap gap-6 mb-6\" },\r\n desktopApps.map(renderAppCard)\r\n ),\r\n\r\n // Mobile Apps\r\n React.createElement('div', { key: 'mobile-row', className: \"flex justify-center gap-6 mb-6\" },\r\n mobileApps.map(renderAppCard)\r\n ),\r\n\r\n // Browser Extensions\r\n React.createElement('div', { key: 'browser-row', className: \"flex justify-center gap-6\" },\r\n browserApps.map(renderAppCard)\r\n )\r\n ]);\r\n};\r\n\r\nwindow.DownloadApps = DownloadApps;\r\n", "// Enhanced Modern Slider Component with Loading Protection\r\nconst UniqueFeatureSlider = () => {\r\n const trackRef = React.useRef(null);\r\n const wrapRef = React.useRef(null);\r\n const [current, setCurrent] = React.useState(0);\r\n const [isReady, setIsReady] = React.useState(false);\r\n\r\n const slides = [\r\n {\r\n icon: \"\uD83D\uDEE1\uFE0F\",\r\n bgImage: \"linear-gradient(135deg, rgb(255 107 53 / 6%) 0%, rgb(255 140 66 / 45%) 100%)\",\r\n thumbIcon: \"\uD83D\uDD12\",\r\n title: \"18-Layer Military Security\",\r\n description: \"Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA + Complete ASN.1 Validation.\"\r\n },\r\n {\r\n icon: \"\uD83C\uDF10\",\r\n bgImage: \"linear-gradient(135deg, rgb(147 51 234 / 6%) 0%, rgb(168 85 247 / 45%) 100%)\",\r\n thumbIcon: \"\uD83D\uDD17\",\r\n title: \"Pure P2P WebRTC\",\r\n description: \"Direct peer-to-peer connections without any servers. Complete decentralization with zero infrastructure.\"\r\n },\r\n {\r\n icon: \"\uD83D\uDD04\",\r\n bgImage: \"linear-gradient(135deg, rgb(16 185 129 / 6%) 0%, rgb(52 211 153 / 45%) 100%)\",\r\n thumbIcon: \"\u26A1\",\r\n title: \"Perfect Forward Secrecy\",\r\n description: \"Automatic key rotation every 5 minutes. Non-extractable keys with hardware protection.\"\r\n },\r\n {\r\n icon: \"\uD83C\uDFAD\",\r\n bgImage: \"linear-gradient(135deg, rgb(6 182 212 / 6%) 0%, rgb(34 211 238 / 45%) 100%)\",\r\n thumbIcon: \"\uD83C\uDF2B\uFE0F\",\r\n title: \"Traffic Obfuscation\",\r\n description: \"Fake traffic generation and pattern masking make communication indistinguishable from noise.\"\r\n },\r\n {\r\n icon: \"\uD83D\uDC41\uFE0F\",\r\n bgImage: \"linear-gradient(135deg, rgb(37 99 235 / 6%) 0%, rgb(59 130 246 / 45%) 100%)\",\r\n thumbIcon: \"\uD83D\uDEAB\",\r\n title: \"Zero Data Collection\",\r\n description: \"No registration, no servers, no logs. Complete anonymity with instant channels.\"\r\n }\r\n ];\r\n\r\n // \u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430\r\n React.useEffect(() => {\r\n const timer = setTimeout(() => {\r\n setIsReady(true);\r\n }, 100);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const isMobile = () => window.matchMedia(\"(max-width:767px)\").matches;\r\n\r\n const center = React.useCallback((i) => {\r\n if (!trackRef.current || !wrapRef.current) return;\r\n const card = trackRef.current.children[i];\r\n if (!card) return;\r\n\r\n const axis = isMobile() ? \"top\" : \"left\";\r\n const size = isMobile() ? \"clientHeight\" : \"clientWidth\";\r\n const start = isMobile() ? card.offsetTop : card.offsetLeft;\r\n \r\n wrapRef.current.scrollTo({\r\n [axis]: start - (wrapRef.current[size] / 2 - card[size] / 2),\r\n behavior: \"smooth\"\r\n });\r\n }, []);\r\n\r\n const activate = React.useCallback((i, scroll = false) => {\r\n if (i === current) return;\r\n setCurrent(i);\r\n if (scroll) {\r\n setTimeout(() => center(i), 50);\r\n }\r\n }, [current, center]);\r\n\r\n const go = (step) => {\r\n const newIndex = Math.min(Math.max(current + step, 0), slides.length - 1);\r\n activate(newIndex, true);\r\n };\r\n\r\n React.useEffect(() => {\r\n const handleKeydown = (e) => {\r\n if ([\"ArrowRight\", \"ArrowDown\"].includes(e.key)) go(1);\r\n if ([\"ArrowLeft\", \"ArrowUp\"].includes(e.key)) go(-1);\r\n };\r\n\r\n window.addEventListener(\"keydown\", handleKeydown, { passive: true });\r\n return () => window.removeEventListener(\"keydown\", handleKeydown);\r\n }, [current]);\r\n\r\n React.useEffect(() => {\r\n if (isReady) {\r\n center(current);\r\n }\r\n }, [current, center, isReady]);\r\n // Render loading state if not ready\r\n if (!isReady) {\r\n return React.createElement('section', { \r\n style: { \r\n background: 'transparent',\r\n minHeight: '400px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n } \r\n }, \r\n React.createElement('div', { \r\n style: { \r\n opacity: 0.5,\r\n fontSize: '14px',\r\n color: '#fff'\r\n }\r\n }, 'Loading...')\r\n );\r\n }\r\n\r\n return React.createElement('section', { style: { background: 'transparent' } }, [\r\n // Header\r\n React.createElement('div', { \r\n key: 'head',\r\n className: 'head'\r\n }, [\r\n React.createElement('h2', { \r\n key: 'title', \r\n className: 'text-2xl sm:text-3xl font-bold text-white mb-4 leading-snug' \r\n }, 'Why SecureBit.chat is unique'),\r\n React.createElement('div', { \r\n key: 'controls',\r\n className: 'controls'\r\n }, [\r\n React.createElement('button', {\r\n key: 'prev',\r\n id: 'prev-slider',\r\n className: 'nav-btn',\r\n 'aria-label': 'Prev',\r\n disabled: current === 0,\r\n onClick: () => go(-1)\r\n }, '\u2039'),\r\n React.createElement('button', {\r\n key: 'next',\r\n id: 'next-slider',\r\n className: 'nav-btn',\r\n 'aria-label': 'Next',\r\n disabled: current === slides.length - 1,\r\n onClick: () => go(1)\r\n }, '\u203A')\r\n ])\r\n ]),\r\n\r\n // Slider\r\n React.createElement('div', {\r\n key: 'slider',\r\n className: 'slider',\r\n ref: wrapRef\r\n },\r\n React.createElement('div', {\r\n className: 'track',\r\n ref: trackRef\r\n }, slides.map((slide, index) =>\r\n React.createElement('article', {\r\n key: index,\r\n className: 'project-card',\r\n ...(index === current ? { active: '' } : {}),\r\n onMouseEnter: () => {\r\n if (window.matchMedia(\"(hover:hover)\").matches) {\r\n activate(index, true);\r\n }\r\n },\r\n onClick: () => activate(index, true)\r\n }, [\r\n // Background\r\n React.createElement('div', {\r\n key: 'bg',\r\n className: 'project-card__bg',\r\n style: {\r\n background: slide.bgImage,\r\n backgroundSize: 'cover',\r\n backgroundPosition: 'center'\r\n }\r\n }),\r\n\r\n // Content\r\n React.createElement('div', {\r\n key: 'content',\r\n className: 'project-card__content'\r\n }, [\r\n // Text container\r\n React.createElement('div', { key: 'text' }, [\r\n React.createElement('h3', {\r\n key: 'title',\r\n className: 'project-card__title'\r\n }, slide.title),\r\n React.createElement('p', {\r\n key: 'desc',\r\n className: 'project-card__desc'\r\n }, slide.description)\r\n ])\r\n ])\r\n ])\r\n ))\r\n ),\r\n ]);\r\n};\r\n\r\n// Export for use in your app\r\nwindow.UniqueFeatureSlider = UniqueFeatureSlider;", "const SecurityFeatures = () => {\r\n const features = [\r\n { id: 'feature1', color: '#00ff88', icon: 'fas fa-key accent-green', title: 'ECDH P-384 Key Exchange', desc: 'Military-grade elliptic curve key exchange' },\r\n { id: 'feature2', color: '#a78bfa', icon: 'fas fa-user-shield accent-purple', title: 'MITM Protection', desc: 'Out-of-band verification against attacks' },\r\n { id: 'feature3', color: '#ff8800', icon: 'fas fa-lock accent-orange', title: 'AES-GCM 256 Encryption', desc: 'Authenticated encryption standard' },\r\n { id: 'feature4', color: '#00ffff', icon: 'fas fa-sync-alt accent-cyan', title: 'Perfect Forward Secrecy', desc: 'Automatic key rotation every 5 minutes' },\r\n { id: 'feature5', color: '#0088ff', icon: 'fas fa-signature accent-blue', title: 'ECDSA P-384 Signatures', desc: 'Digital signatures for message integrity' },\r\n { id: 'feature6', color: '#f87171', icon: 'fas fa-shield-alt accent-red', title: 'SAS Security', desc: 'Revolutionary key exchange & MITM protection' }\r\n ];\r\n\r\n React.useEffect(() => {\r\n const cards = document.querySelectorAll(\".card\");\r\n const radius = 200; \r\n\r\n const handleMove = (e) => {\r\n cards.forEach((card) => {\r\n const rect = card.getBoundingClientRect();\r\n const cx = rect.left + rect.width / 2;\r\n const cy = rect.top + rect.height / 2;\r\n\r\n const dx = e.clientX - cx;\r\n const dy = e.clientY - cy;\r\n const dist = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (dist < radius) {\r\n const x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n card.style.setProperty(\"--x\", `${x}px`);\r\n card.style.setProperty(\"--y\", `${y}px`);\r\n card.classList.add(\"active-glow\");\r\n } else {\r\n card.classList.remove(\"active-glow\");\r\n }\r\n });\r\n };\r\n\r\n window.addEventListener(\"mousemove\", handleMove);\r\n return () => window.removeEventListener(\"mousemove\", handleMove);\r\n }, []);\r\n\r\n const renderFeature = (f) =>\r\n React.createElement('div', {\r\n key: f.id,\r\n className: \"card p-3 sm:p-4 text-center\",\r\n style: { \"--color\": f.color }\r\n }, [\r\n React.createElement('div', { key: 'icon', className: \"w-10 h-10 sm:w-12 sm:h-12 flex items-center justify-center mx-auto mb-2 sm:mb-3 relative z-10\" }, [\r\n React.createElement('i', { className: f.icon })\r\n ]),\r\n React.createElement('h4', { key: 'title', className: \"text-xs sm:text-sm font-medium text-primary mb-1 relative z-10\" }, f.title),\r\n React.createElement('p', { key: 'desc', className: \"text-xs text-muted leading-tight relative z-10\" }, f.desc)\r\n ]);\r\n\r\n return React.createElement('div', {\r\n className: \"grid grid-cols-2 md:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4 max-w-6xl mx-auto mt-8\"\r\n }, features.map(renderFeature));\r\n};\r\n\r\nwindow.SecurityFeatures = SecurityFeatures;\r\n", "const Testimonials = () => {\r\n const testimonials = [\r\n { id: \"t1\", rating: 5.0, text: \"The interface feels modern and smooth. It saves me at least 2 hours every day when managing design tasks.\"},\r\n { id: \"t2\", rating: 5.0, text: \"Finally, a solution that blends speed with simplicity. My team adopted it within a week without training.\"},\r\n { id: \"t3\", rating: 5.0, text: \"I can track progress in real time and get a clear overview of our workflow. It feels empowering.\"},\r\n { id: \"t4\", rating: 5.0, text: \"Our pipeline visibility improved dramatically. I no longer need to manually track updates.\"},\r\n { id: \"t5\", rating: 5.0, text: \"The security-first approach gives me peace of mind. We handle sensitive data with confidence now.\"},\r\n { id: \"t6\", rating: 5.0, text: \"User feedback cycles are now twice as fast. It helps us test and ship features quickly.\"}\r\n ];\r\n\r\n React.useEffect(() => {\r\n const colUp = document.querySelector(\".col-up\");\r\n const colDown = document.querySelector(\".col-down\");\r\n const wrapper = document.querySelector(\".testimonials-wrapper\");\r\n\r\n if (!colUp || !colDown || !wrapper) return;\r\n\r\n let paused = false;\r\n const speed = 0.5;\r\n let animationId;\r\n\r\n const cloneCards = (container) => {\r\n const cards = Array.from(container.children);\r\n cards.forEach(card => {\r\n const clone = card.cloneNode(true);\r\n container.appendChild(clone);\r\n });\r\n };\r\n\r\n cloneCards(colUp);\r\n cloneCards(colDown);\r\n\r\n const getHalfHeight = (el) => {\r\n const children = Array.from(el.children);\r\n const halfCount = children.length / 2;\r\n let height = 0;\r\n for (let i = 0; i < halfCount; i++) {\r\n height += children[i].offsetHeight;\r\n if (i < halfCount - 1) height += 24; \r\n }\r\n return height;\r\n };\r\n\r\n let y1 = 0;\r\n const maxScroll1 = getHalfHeight(colUp);\r\n const maxScroll2 = getHalfHeight(colDown);\r\n let y2 = -maxScroll2; \r\n\r\n function animate() {\r\n if (!paused) {\r\n y1 -= speed;\r\n y2 += speed;\r\n\r\n if (Math.abs(y1) >= maxScroll1) {\r\n y1 = 0;\r\n }\r\n \r\n if (y2 >= 0) {\r\n y2 = -maxScroll2;\r\n }\r\n\r\n colUp.style.transform = `translateY(${y1}px)`;\r\n colDown.style.transform = `translateY(${y2}px)`;\r\n }\r\n animationId = requestAnimationFrame(animate);\r\n }\r\n\r\n animate();\r\n\r\n const handleMouseEnter = () => { paused = true; };\r\n const handleMouseLeave = () => { paused = false; };\r\n\r\n wrapper.addEventListener(\"mouseenter\", handleMouseEnter);\r\n wrapper.addEventListener(\"mouseleave\", handleMouseLeave);\r\n\r\n return () => {\r\n cancelAnimationFrame(animationId);\r\n wrapper.removeEventListener(\"mouseenter\", handleMouseEnter);\r\n wrapper.removeEventListener(\"mouseleave\", handleMouseLeave);\r\n };\r\n }, []);\r\n\r\n const renderCard = (t, index) => (\r\n
\r\n
\r\n {\"\u2605\".repeat(Math.floor(t.rating))}\r\n {t.rating.toFixed(1)}\r\n
\r\n

{t.text}

\r\n
\r\n );\r\n\r\n return (\r\n
\r\n
\r\n
\r\n

Testimonials

\r\n

\r\n What our users are saying\r\n

\r\n

\r\n We continuously listen to our community and improve every day.\r\n

\r\n
\r\n\r\n
\r\n
\r\n
\r\n\r\n
\r\n {testimonials.map((t, i) => renderCard(t, i))}\r\n
\r\n\r\n
\r\n {testimonials.map((t, i) => renderCard(t, i))}\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nwindow.Testimonials = Testimonials;\r\n", "\r\n \r\n \r\n const ComparisonTable = () => {\r\n const [selectedFeature, setSelectedFeature] = React.useState(null);\r\n\r\n const messengers = [\r\n {\r\n name: \"SecureBit.chat\",\r\n logo:
\r\n \r\n
,\r\n type: \"P2P WebRTC\",\r\n version: \"Latest\",\r\n color: \"orange\",\r\n },\r\n {\r\n name: \"Signal\",\r\n logo: (\r\n \r\n \r\n \r\n \r\n ),\r\n type: \"Centralized\",\r\n version: \"Latest\",\r\n color: \"blue\",\r\n },\r\n {\r\n name: \"Threema\",\r\n logo: (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n ),\r\n type: \"Centralized\",\r\n version: \"Latest\",\r\n color: \"green\",\r\n },\r\n {\r\n name: \"Session\",\r\n logo: (\r\n \r\n \r\n \r\n \r\n ),\r\n type: \"Onion Network\",\r\n version: \"Latest\",\r\n color: \"cyan\",\r\n },\r\n ];\r\n\r\n const features = [\r\n {\r\n name: \"Security Architecture\",\r\n lockbit: { status: \"trophy\", detail: \"18-layer military-grade defense system with complete ASN.1 validation\" },\r\n signal: { status: \"check\", detail: \"Signal Protocol with double ratchet\" },\r\n threema: { status: \"check\", detail: \"Standard security implementation\" },\r\n session: { status: \"check\", detail: \"Modified Signal Protocol + Onion routing\" },\r\n },\r\n {\r\n name: \"Cryptography\",\r\n lockbit: { status: \"trophy\", detail: \"ECDH P-384 + AES-GCM 256 + ECDSA P-384\" },\r\n signal: { status: \"check\", detail: \"Signal Protocol + Double Ratchet\" },\r\n threema: { status: \"check\", detail: \"NaCl + XSalsa20 + Poly1305\" },\r\n session: { status: \"check\", detail: \"Modified Signal Protocol\" },\r\n },\r\n {\r\n name: \"Perfect Forward Secrecy\",\r\n lockbit: { status: \"trophy\", detail: \"Auto rotation every 5 minutes or 100 messages\" },\r\n signal: { status: \"check\", detail: \"Double Ratchet algorithm\" },\r\n threema: { status: \"warning\", detail: \"Partial (group chats)\" },\r\n session: { status: \"check\", detail: \"Session Ratchet algorithm\" },\r\n },\r\n {\r\n name: \"Architecture\",\r\n lockbit: { status: \"trophy\", detail: \"Pure P2P WebRTC without servers\" },\r\n signal: { status: \"times\", detail: \"Centralized Signal servers\" },\r\n threema: { status: \"times\", detail: \"Threema servers in Switzerland\" },\r\n session: { status: \"warning\", detail: \"Onion routing via network nodes\" },\r\n },\r\n {\r\n name: \"Registration Anonymity\",\r\n lockbit: { status: \"trophy\", detail: \"No registration required, instant anonymous channels\" },\r\n signal: { status: \"times\", detail: \"Phone number required\" },\r\n threema: { status: \"check\", detail: \"ID generated locally\" },\r\n session: { status: \"check\", detail: \"Random session ID\" },\r\n },\r\n {\r\n name: \"Metadata Protection\",\r\n lockbit: { status: \"trophy\", detail: \"Full metadata encryption + traffic obfuscation\" },\r\n signal: { status: \"warning\", detail: \"Sealed Sender (partial)\" },\r\n threema: { status: \"warning\", detail: \"Minimal metadata\" },\r\n session: { status: \"check\", detail: \"Onion routing hides metadata\" },\r\n },\r\n {\r\n name: \"Traffic Obfuscation\",\r\n lockbit: { status: \"trophy\", detail: \"Fake traffic + pattern masking + packet padding\" },\r\n signal: { status: \"times\", detail: \"No traffic obfuscation\" },\r\n threema: { status: \"times\", detail: \"No traffic obfuscation\" },\r\n session: { status: \"check\", detail: \"Onion routing provides obfuscation\" },\r\n },\r\n {\r\n name: \"Open Source\",\r\n lockbit: { status: \"trophy\", detail: \"100% open + auditable + MIT license\" },\r\n signal: { status: \"check\", detail: \"Fully open\" },\r\n threema: { status: \"warning\", detail: \"Only clients open\" },\r\n session: { status: \"check\", detail: \"Fully open\" },\r\n },\r\n {\r\n name: \"MITM Protection\",\r\n lockbit: { status: \"trophy\", detail: \"Out-of-band verification + mutual auth + ECDSA\" },\r\n signal: { status: \"check\", detail: \"Safety numbers verification\" },\r\n threema: { status: \"check\", detail: \"QR code scanning\" },\r\n session: { status: \"warning\", detail: \"Basic key verification\" },\r\n },\r\n {\r\n name: \"Censorship Resistance\",\r\n lockbit: { status: \"trophy\", detail: \"Impossible to block P2P + no servers to target\" },\r\n signal: { status: \"warning\", detail: \"Blocked in authoritarian countries\" },\r\n threema: { status: \"warning\", detail: \"May be blocked\" },\r\n session: { status: \"check\", detail: \"Onion routing bypasses blocks\" },\r\n },\r\n {\r\n name: \"Data Storage\",\r\n lockbit: { status: \"trophy\", detail: \"Zero data storage - only in browser memory\" },\r\n signal: { status: \"warning\", detail: \"Local database storage\" },\r\n threema: { status: \"warning\", detail: \"Local + optional backup\" },\r\n session: { status: \"warning\", detail: \"Local database storage\" },\r\n },\r\n {\r\n name: \"Key Security\",\r\n lockbit: { status: \"trophy\", detail: \"Non-extractable keys + hardware protection\" },\r\n signal: { status: \"check\", detail: \"Secure key storage\" },\r\n threema: { status: \"check\", detail: \"Local key storage\" },\r\n session: { status: \"check\", detail: \"Secure key storage\" },\r\n },\r\n {\r\n name: \"Post-Quantum Roadmap\",\r\n lockbit: { status: \"check\", detail: \"Planned v5.0 - CRYSTALS-Kyber/Dilithium\" },\r\n signal: { status: \"warning\", detail: \"PQXDH in development\" },\r\n threema: { status: \"times\", detail: \"Not announced\" },\r\n session: { status: \"times\", detail: \"Not announced\" },\r\n },\r\n ];\r\n\r\n const getStatusIcon = (status) => {\r\n const statusMap = {\r\n \"trophy\": { icon: \"fa-trophy\", color: \"accent-orange\" },\r\n \"check\": { icon: \"fa-check\", color: \"text-green-300\" },\r\n \"warning\": { icon: \"fa-exclamation-triangle\", color: \"text-yellow-300\" },\r\n \"times\": { icon: \"fa-times\", color: \"text-red-300\" },\r\n };\r\n return statusMap[status] || { icon: \"fa-question\", color: \"text-gray-400\" };\r\n };\r\n\r\n const toggleFeatureDetail = (index) => {\r\n setSelectedFeature(selectedFeature === index ? null : index);\r\n };\r\n\r\n return (\r\n
\r\n {/* Title */}\r\n
\r\n

\r\n Enhanced Security Edition Comparison\r\n

\r\n

\r\n Enhanced Security Edition vs leading secure messengers\r\n

\r\n
\r\n\r\n {/* Table container */}\r\n
\r\n {/* Mobile Alert */}\r\n
\r\n

\r\n \r\n Rotate your device horizontally for better viewing\r\n

\r\n
\r\n\r\n {/* Table */}\r\n
\r\n \r\n {/* Table Header */}\r\n \r\n \r\n \r\n Security Criterion\r\n \r\n {messengers.map((messenger, index) => (\r\n \r\n
\r\n
{messenger.logo}
\r\n
\r\n {messenger.name}\r\n
\r\n
{messenger.type}
\r\n
{messenger.version}
\r\n
\r\n \r\n ))}\r\n \r\n \r\n\r\n {/* Table body */}\r\n \r\n {features.map((feature, featureIndex) => (\r\n \r\n toggleFeatureDetail(featureIndex)}\r\n >\r\n \r\n
\r\n {feature.name}\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* Details */}\r\n {selectedFeature === featureIndex && (\r\n \r\n Technical Details:\r\n \r\n
\r\n {feature.lockbit.detail}\r\n
\r\n \r\n \r\n
\r\n {feature.signal.detail}\r\n
\r\n \r\n \r\n
\r\n {feature.threema.detail}\r\n
\r\n \r\n \r\n
\r\n {feature.session.detail}\r\n
\r\n \r\n \r\n )}\r\n
\r\n ))}\r\n \r\n \r\n
\r\n\r\n {/* Legend */}\r\n
\r\n
\r\n \r\n Category Leader\r\n
\r\n\r\n
\r\n \r\n Excellent\r\n
\r\n
\r\n \r\n Partial/Limited\r\n
\r\n
\r\n \r\n Not Available\r\n
\r\n
\r\n
\r\n
\r\n );\r\n };\r\n window.ComparisonTable = ComparisonTable;", "function Roadmap() {\r\n const [selectedPhase, setSelectedPhase] = React.useState(null);\r\n const phases = [\r\n {\r\n version: \"v1.0\",\r\n title: \"Start of Development\",\r\n status: \"done\",\r\n date: \"Early 2025\",\r\n description: \"Idea, prototype, and infrastructure setup\",\r\n features: [\r\n \"Concept and requirements formation\",\r\n \"Stack selection: WebRTC, P2P, cryptography\",\r\n \"First messaging prototypes\",\r\n \"Repository creation and CI\",\r\n \"Basic encryption architecture\",\r\n \"UX/UI design\"\r\n ]\r\n },\r\n {\r\n version: \"v1.5\",\r\n title: \"Alpha Release\",\r\n status: \"done\",\r\n date: \"Spring 2025\",\r\n description: \"First public alpha: basic chat and key exchange\",\r\n features: [\r\n \"Basic P2P messaging via WebRTC\",\r\n \"Simple E2E encryption (demo scheme)\",\r\n \"Stable signaling and reconnection\",\r\n \"Minimal UX for testing\",\r\n \"Feedback collection from early testers\"\r\n ]\r\n },\r\n {\r\n version: \"v2.0\",\r\n title: \"Security Hardened\",\r\n status: \"done\",\r\n date: \"Summer 2025\",\r\n description: \"Security strengthening and stable branch release\",\r\n features: [\r\n \"ECDH/ECDSA implementation in production\",\r\n \"Perfect Forward Secrecy and key rotation\",\r\n \"Improved authentication checks\",\r\n \"File encryption and large payload transfers\",\r\n \"Audit of basic cryptoprocesses\"\r\n ]\r\n },\r\n {\r\n version: \"v3.0\",\r\n title: \"Scaling & Stability\",\r\n status: \"done\",\r\n date: \"Fall 2025\",\r\n description: \"Network scaling and stability improvements\",\r\n features: [\r\n \"Optimization of P2P connections and NAT traversal\",\r\n \"Reconnection mechanisms and message queues\",\r\n \"Reduced battery consumption on mobile\",\r\n \"Support for multi-device synchronization\",\r\n \"Monitoring and logging tools for developers\"\r\n ]\r\n },\r\n {\r\n version: \"v3.5\",\r\n title: \"Privacy-first Release\",\r\n status: \"done\",\r\n date: \"Winter 2025\",\r\n description: \"Focus on privacy: minimizing metadata\",\r\n features: [\r\n \"Metadata protection and fingerprint reduction\",\r\n \"Experiments with onion routing and DHT\",\r\n \"Options for anonymous connections\",\r\n \"Preparation for open code audit\",\r\n \"Improved user verification processes\"\r\n ]\r\n },\r\n \r\n // current and future phases\r\n {\r\n version: \"v4.4.18\",\r\n title: \"Enhanced Security Edition\",\r\n status: \"current\",\r\n date: \"Now\",\r\n description: \"Current version with ECDH + DTLS + SAS security, 18-layer military-grade cryptography and complete ASN.1 validation\",\r\n features: [\r\n \"ECDH + DTLS + SAS triple-layer security\",\r\n \"ECDH P-384 + AES-GCM 256-bit encryption\",\r\n \"DTLS fingerprint verification\",\r\n \"SAS (Short Authentication String) verification\",\r\n \"Perfect Forward Secrecy with key rotation\",\r\n \"Enhanced MITM attack prevention\",\r\n \"Complete ASN.1 DER validation\",\r\n \"OID and EC point verification\",\r\n \"SPKI structure validation\",\r\n \"P2P WebRTC architecture\",\r\n \"Metadata protection\",\r\n \"100% open source code\"\r\n ]\r\n },\r\n {\r\n version: \"v4.5\",\r\n title: \"Mobile & Desktop Edition\",\r\n status: \"development\",\r\n date: \"Q2 2025\",\r\n description: \"Native apps for all platforms\",\r\n features: [\r\n \"PWA app for mobile\",\r\n \"Electron app for desktop\",\r\n \"Real-time notifications\",\r\n \"Automatic reconnection\",\r\n \"Battery optimization\",\r\n \"Cross-device synchronization\",\r\n \"Improved UX/UI\",\r\n \"Support for files up to 100MB\"\r\n ]\r\n },\r\n {\r\n version: \"v5.0\",\r\n title: \"Quantum-Resistant Edition\",\r\n status: \"planned\",\r\n date: \"Q4 2025\",\r\n description: \"Protection against quantum computers\",\r\n features: [\r\n \"Post-quantum cryptography CRYSTALS-Kyber\",\r\n \"SPHINCS+ digital signatures\",\r\n \"Hybrid scheme: classic + PQ\",\r\n \"Quantum-safe key exchange\",\r\n \"Updated hashing algorithms\",\r\n \"Migration of existing sessions\",\r\n \"Compatibility with v4.x\",\r\n \"Quantum-resistant protocols\"\r\n ]\r\n },\r\n {\r\n version: \"v5.5\",\r\n title: \"Group Communications\",\r\n status: \"planned\",\r\n date: \"Q2 2026\",\r\n description: \"Group chats with preserved privacy\",\r\n features: [\r\n \"P2P group connections up to 8 participants\",\r\n \"Mesh networking for groups\",\r\n \"Signal Double Ratchet for groups\",\r\n \"Anonymous groups without metadata\",\r\n \"Ephemeral groups (disappear after session)\",\r\n \"Cryptographic group administration\",\r\n \"Group member auditing\"\r\n ]\r\n },\r\n {\r\n version: \"v6.0\",\r\n title: \"Decentralized Network\",\r\n status: \"research\",\r\n date: \"2027\",\r\n description: \"Fully decentralized network\",\r\n features: [\r\n \"LockBit node mesh network\",\r\n \"DHT for peer discovery\",\r\n \"Built-in onion routing\",\r\n \"Tokenomics and node incentives\",\r\n \"Governance via DAO\",\r\n \"Interoperability with other networks\",\r\n \"Cross-platform compatibility\",\r\n \"Self-healing network\"\r\n ]\r\n },\r\n {\r\n version: \"v7.0\",\r\n title: \"AI Privacy Assistant\",\r\n status: \"research\",\r\n date: \"2028+\",\r\n description: \"AI for privacy and security\",\r\n features: [\r\n \"Local AI threat analysis\",\r\n \"Automatic MITM detection\",\r\n \"Adaptive cryptography\",\r\n \"Personalized security recommendations\",\r\n \"Zero-knowledge machine learning\",\r\n \"Private AI assistant\",\r\n \"Predictive security\",\r\n \"Autonomous attack protection\"\r\n ]\r\n }\r\n ];\r\n \r\n \r\n const getStatusConfig = (status) => {\r\n switch (status) {\r\n case 'current':\r\n return {\r\n color: 'green',\r\n bgClass: 'bg-green-500/10 border-green-500/20',\r\n textClass: 'text-green-400',\r\n icon: 'fas fa-check-circle',\r\n label: 'Current Version'\r\n };\r\n case 'development':\r\n return {\r\n color: 'orange',\r\n bgClass: 'bg-orange-500/10 border-orange-500/20',\r\n textClass: 'text-orange-400',\r\n icon: 'fas fa-code',\r\n label: 'In Development'\r\n };\r\n case 'planned':\r\n return {\r\n color: 'blue',\r\n bgClass: 'bg-blue-500/10 border-blue-500/20',\r\n textClass: 'text-blue-400',\r\n icon: 'fas fa-calendar-alt',\r\n label: 'Planned'\r\n };\r\n case 'research':\r\n return {\r\n color: 'purple',\r\n bgClass: 'bg-purple-500/10 border-purple-500/20',\r\n textClass: 'text-purple-400',\r\n icon: 'fas fa-flask',\r\n label: 'Research'\r\n };\r\n case 'done':\r\n return {\r\n color: 'gray',\r\n bgClass: 'bg-gray-500/10 border-gray-500/20',\r\n textClass: 'text-gray-300',\r\n icon: 'fas fa-flag-checkered',\r\n label: 'Released'\r\n };\r\n default:\r\n return {\r\n color: 'gray',\r\n bgClass: 'bg-gray-500/10 border-gray-500/20',\r\n textClass: 'text-gray-400',\r\n icon: 'fas fa-question',\r\n label: 'Unknown'\r\n };\r\n }\r\n };\r\n \r\n \r\n const togglePhaseDetail = (index) => {\r\n setSelectedPhase(selectedPhase === index ? null : index);\r\n };\r\n return (\r\n
\r\n
\r\n

\r\n Development Roadmap\r\n

\r\n

\r\n Evolution of SecureBit.chat : from initial development to quantum-resistant decentralized network with complete ASN.1 validation\r\n

\r\n
\r\n \r\n
\r\n
\r\n {/* The line has been removed */}\r\n \r\n
\r\n {phases.map((phase, index) => {\r\n const statusConfig = getStatusConfig(phase.status);\r\n const isExpanded = selectedPhase === index;\r\n \r\n return (\r\n
\r\n {/* The dots are visible only on sm and larger screens */}\r\n \r\n togglePhaseDetail(index)}\r\n key={`phase-button-${index}`}\r\n className={`card-minimal rounded-xl p-4 text-left w-full transition-all duration-300 ${\r\n isExpanded\r\n ? \"ring-2 ring-\" + statusConfig.color + \"-500/30\"\r\n : \"\"\r\n }`}\r\n >\r\n \r\n \r\n \r\n \r\n {phase.version}\r\n \r\n
\r\n \r\n
\r\n \r\n {phase.title}\r\n \r\n \r\n {phase.description}\r\n

\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n {statusConfig.label}\r\n \r\n
\r\n \r\n
{phase.date}
\r\n \r\n
\r\n
\r\n \r\n {isExpanded && (\r\n \r\n \r\n \r\n Key features:\r\n \r\n \r\n \r\n {phase.features.map((feature, featureIndex) => (\r\n \r\n \r\n \r\n {feature}\r\n \r\n
\r\n ))}\r\n \r\n \r\n )}\r\n \r\n \r\n );\r\n })}\r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n Join the future of privacy\r\n \r\n

\r\n SecureBit.chat grows thanks to the community. Your ideas and feedback help shape the future of secure communication with complete ASN.1 validation.\r\n

\r\n \r\n \r\n \r\n \r\n GitHub Repository\r\n \r\n \r\n \r\n \r\n Feedback\r\n \r\n
\r\n \r\n \r\n \r\n );\r\n };\r\n window.Roadmap = Roadmap;", "// File Transfer Component for Chat Interface - Fixed Version\r\nconst FileTransferComponent = ({ webrtcManager, isConnected }) => {\r\n const [dragOver, setDragOver] = React.useState(false);\r\n const [transfers, setTransfers] = React.useState({ sending: [], receiving: [] });\r\n const [readyFiles, setReadyFiles] = React.useState([]); // \u0444\u0430\u0439\u043B\u044B, \u0433\u043E\u0442\u043E\u0432\u044B\u0435 \u043A \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044E\r\n const fileInputRef = React.useRef(null);\r\n\r\n // Update transfers periodically\r\n React.useEffect(() => {\r\n if (!isConnected || !webrtcManager) return;\r\n\r\n const updateTransfers = () => {\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n };\r\n\r\n const interval = setInterval(updateTransfers, 500);\r\n return () => clearInterval(interval);\r\n }, [isConnected, webrtcManager]);\r\n\r\n // Setup file transfer callbacks - \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u041D\u0415 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u043F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u0447\u043D\u044B\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0432 \u0447\u0430\u0442\r\n React.useEffect(() => {\r\n if (!webrtcManager) return;\r\n\r\n webrtcManager.setFileTransferCallbacks(\r\n // Progress callback - \u0422\u041E\u041B\u042C\u041A\u041E \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u043C UI, \u041D\u0415 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u0432 \u0447\u0430\u0442\r\n (progress) => {\r\n // \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0435 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n \r\n // \u041D\u0415 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0432 \u0447\u0430\u0442!\r\n },\r\n \r\n // File received callback - \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u043C \u043A\u043D\u043E\u043F\u043A\u0443 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F \u0432 UI\r\n (fileData) => {\r\n // \u0414\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u043C \u0432 \u0441\u043F\u0438\u0441\u043E\u043A \u0433\u043E\u0442\u043E\u0432\u044B\u0445 \u043A \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044E\r\n setReadyFiles(prev => {\r\n // \u0438\u0437\u0431\u0435\u0433\u0430\u0435\u043C \u0434\u0443\u0431\u043B\u0435\u0439 \u043F\u043E fileId\r\n if (prev.some(f => f.fileId === fileData.fileId)) return prev;\r\n return [...prev, {\r\n fileId: fileData.fileId,\r\n fileName: fileData.fileName,\r\n fileSize: fileData.fileSize,\r\n mimeType: fileData.mimeType,\r\n getBlob: fileData.getBlob,\r\n getObjectURL: fileData.getObjectURL,\r\n revokeObjectURL: fileData.revokeObjectURL\r\n }];\r\n });\r\n\r\n // \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u043C \u0441\u043F\u0438\u0441\u043E\u043A \u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n },\r\n \r\n // Error callback\r\n (error) => {\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n \r\n // \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u041D\u0415 \u0434\u0443\u0431\u043B\u0438\u0440\u0443\u0435\u043C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043E\u0431 \u043E\u0448\u0438\u0431\u043A\u0430\u0445\r\n // \u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F \u043E\u0431 \u043E\u0448\u0438\u0431\u043A\u0430\u0445 \u0443\u0436\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F \u0432 WebRTC \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u0435\r\n }\r\n );\r\n }, [webrtcManager]);\r\n\r\n const handleFileSelect = async (files) => {\r\n if (!isConnected || !webrtcManager) {\r\n alert('\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E. \u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435.');\r\n return;\r\n }\r\n\r\n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\r\n if (!webrtcManager.isConnected() || !webrtcManager.isVerified) {\r\n alert('\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432\u043E \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0444\u0430\u0439\u043B\u043E\u0432. \u0414\u043E\u0436\u0434\u0438\u0442\u0435\u0441\u044C \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F.');\r\n return;\r\n }\r\n\r\n for (const file of files) {\r\n try {\r\n // \u041A\u0420\u0418\u0422\u0418\u0427\u0415\u0421\u041A\u041E\u0415 \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u0412\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u044F \u0444\u0430\u0439\u043B\u0430 \u043F\u0435\u0440\u0435\u0434 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u043E\u0439\r\n const validation = webrtcManager.validateFile(file);\r\n if (!validation.isValid) {\r\n const errorMessage = validation.errors.join('. ');\r\n alert(`\u0424\u0430\u0439\u043B ${file.name} \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D: ${errorMessage}`);\r\n continue;\r\n }\r\n\r\n await webrtcManager.sendFile(file);\r\n } catch (error) {\r\n // \u0411\u043E\u043B\u0435\u0435 \u043C\u044F\u0433\u043A\u0430\u044F \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043E\u0448\u0438\u0431\u043E\u043A - \u043D\u0435 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0435\u043C \u0441\u0435\u0441\u0441\u0438\u044E\r\n \r\n // \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044E \u043E\u0448\u0438\u0431\u043A\u0443, \u043D\u043E \u043D\u0435 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0435\u043C \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435\r\n if (error.message.includes('Connection not ready')) {\r\n alert(`\u0424\u0430\u0439\u043B ${file.name} \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D \u0441\u0435\u0439\u0447\u0430\u0441. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0438 \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0441\u043D\u043E\u0432\u0430.`);\r\n } else if (error.message.includes('File too large') || error.message.includes('exceeds maximum')) {\r\n alert(`\u0424\u0430\u0439\u043B ${file.name} \u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0431\u043E\u043B\u044C\u0448\u043E\u0439: ${error.message}`);\r\n } else if (error.message.includes('Maximum concurrent transfers')) {\r\n alert(`\u0414\u043E\u0441\u0442\u0438\u0433\u043D\u0443\u0442 \u043B\u0438\u043C\u0438\u0442 \u043E\u0434\u043D\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u0447. \u0414\u043E\u0436\u0434\u0438\u0442\u0435\u0441\u044C \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0443\u0449\u0438\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u0447.`);\r\n } else if (error.message.includes('File type not allowed')) {\r\n alert(`\u0422\u0438\u043F \u0444\u0430\u0439\u043B\u0430 ${file.name} \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F: ${error.message}`);\r\n } else {\r\n alert(`\u041E\u0448\u0438\u0431\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438 \u0444\u0430\u0439\u043B\u0430 ${file.name}: ${error.message}`);\r\n }\r\n }\r\n }\r\n };\r\n\r\n const handleDrop = (e) => {\r\n e.preventDefault();\r\n setDragOver(false);\r\n \r\n const files = Array.from(e.dataTransfer.files);\r\n handleFileSelect(files);\r\n };\r\n\r\n const handleDragOver = (e) => {\r\n e.preventDefault();\r\n setDragOver(true);\r\n };\r\n\r\n const handleDragLeave = (e) => {\r\n e.preventDefault();\r\n setDragOver(false);\r\n };\r\n\r\n const handleFileInputChange = (e) => {\r\n const files = Array.from(e.target.files);\r\n handleFileSelect(files);\r\n e.target.value = ''; // Reset input\r\n };\r\n\r\n const formatFileSize = (bytes) => {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\r\n };\r\n\r\n const getStatusIcon = (status) => {\r\n switch (status) {\r\n case 'metadata_sent':\r\n case 'preparing':\r\n return 'fas fa-cog fa-spin';\r\n case 'transmitting':\r\n case 'receiving':\r\n return 'fas fa-exchange-alt fa-pulse';\r\n case 'assembling':\r\n return 'fas fa-puzzle-piece fa-pulse';\r\n case 'completed':\r\n return 'fas fa-check text-green-400';\r\n case 'failed':\r\n return 'fas fa-times text-red-400';\r\n default:\r\n return 'fas fa-circle';\r\n }\r\n };\r\n\r\n const getStatusText = (status) => {\r\n switch (status) {\r\n case 'metadata_sent':\r\n return '\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043A\u0430...';\r\n case 'transmitting':\r\n return '\u041E\u0442\u043F\u0440\u0430\u0432\u043A\u0430...';\r\n case 'receiving':\r\n return '\u041F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435...';\r\n case 'assembling':\r\n return '\u0421\u0431\u043E\u0440\u043A\u0430 \u0444\u0430\u0439\u043B\u0430...';\r\n case 'completed':\r\n return '\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043E';\r\n case 'failed':\r\n return '\u041E\u0448\u0438\u0431\u043A\u0430';\r\n default:\r\n return status;\r\n }\r\n };\r\n\r\n if (!isConnected) {\r\n return React.createElement('div', {\r\n className: \"p-4 text-center text-muted\"\r\n }, '\u041F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043B\u043E\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u043E\u043C \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0438');\r\n }\r\n\r\n // \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u043C \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\r\n const isConnectionReady = webrtcManager && webrtcManager.isConnected() && webrtcManager.isVerified;\r\n \r\n if (!isConnectionReady) {\r\n return React.createElement('div', {\r\n className: \"p-4 text-center text-yellow-600\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-exclamation-triangle mr-2'\r\n }),\r\n '\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0443\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u0435\u0442\u0441\u044F... \u041F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043B\u043E\u0432 \u0431\u0443\u0434\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043F\u043E\u0441\u043B\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438.'\r\n ]);\r\n }\r\n\r\n return React.createElement('div', {\r\n className: \"file-transfer-component\"\r\n }, [\r\n // File Drop Zone\r\n React.createElement('div', {\r\n key: 'drop-zone',\r\n className: `file-drop-zone ${dragOver ? 'drag-over' : ''}`,\r\n onDrop: handleDrop,\r\n onDragOver: handleDragOver,\r\n onDragLeave: handleDragLeave,\r\n onClick: () => fileInputRef.current?.click()\r\n }, [\r\n React.createElement('div', {\r\n key: 'drop-content',\r\n className: \"drop-content\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-cloud-upload-alt text-2xl mb-2 text-blue-400'\r\n }),\r\n React.createElement('p', {\r\n key: 'text',\r\n className: \"text-primary font-medium\"\r\n }, 'Drag files here or click to select'),\r\n React.createElement('p', {\r\n key: 'subtext',\r\n className: \"text-muted text-sm\"\r\n }, 'Maximum size: 100 MB per file')\r\n ])\r\n ]),\r\n\r\n // Hidden file input\r\n React.createElement('input', {\r\n key: 'file-input',\r\n ref: fileInputRef,\r\n type: 'file',\r\n multiple: true,\r\n className: 'hidden',\r\n onChange: handleFileInputChange\r\n }),\r\n\r\n // Active Transfers\r\n (transfers.sending.length > 0 || transfers.receiving.length > 0) && React.createElement('div', {\r\n key: 'transfers',\r\n className: \"active-transfers mt-4\"\r\n }, [\r\n React.createElement('h4', {\r\n key: 'title',\r\n className: \"text-primary font-medium mb-3 flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-exchange-alt mr-2'\r\n }),\r\n '\u041F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043B\u043E\u0432'\r\n ]),\r\n\r\n // Sending files\r\n ...transfers.sending.map(transfer => \r\n React.createElement('div', {\r\n key: `send-${transfer.fileId}`,\r\n className: \"transfer-item bg-blue-500/10 border border-blue-500/20 rounded-lg p-3 mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'header',\r\n className: \"flex items-center justify-between mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'info',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-upload text-blue-400 mr-2'\r\n }),\r\n React.createElement('span', {\r\n key: 'name',\r\n className: \"text-primary font-medium text-sm\"\r\n }, transfer.fileName),\r\n React.createElement('span', {\r\n key: 'size',\r\n className: \"text-muted text-xs ml-2\"\r\n }, formatFileSize(transfer.fileSize))\r\n ]),\r\n React.createElement('button', {\r\n key: 'cancel',\r\n onClick: () => webrtcManager.cancelFileTransfer(transfer.fileId),\r\n className: \"text-red-400 hover:text-red-300 text-xs\"\r\n }, [\r\n React.createElement('i', {\r\n className: 'fas fa-times'\r\n })\r\n ])\r\n ]),\r\n React.createElement('div', {\r\n key: 'progress',\r\n className: \"progress-bar\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'fill',\r\n className: \"progress-fill bg-blue-400\",\r\n style: { width: `${transfer.progress}%` }\r\n }),\r\n React.createElement('div', {\r\n key: 'text',\r\n className: \"progress-text text-xs flex items-center justify-between\"\r\n }, [\r\n React.createElement('span', {\r\n key: 'status',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: `${getStatusIcon(transfer.status)} mr-1`\r\n }),\r\n getStatusText(transfer.status)\r\n ]),\r\n React.createElement('span', {\r\n key: 'percent'\r\n }, `${transfer.progress.toFixed(1)}%`)\r\n ])\r\n ])\r\n ])\r\n ),\r\n\r\n // Receiving files\r\n ...transfers.receiving.map(transfer => \r\n React.createElement('div', {\r\n key: `recv-${transfer.fileId}`,\r\n className: \"transfer-item bg-green-500/10 border border-green-500/20 rounded-lg p-3 mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'header',\r\n className: \"flex items-center justify-between mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'info',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-download text-green-400 mr-2'\r\n }),\r\n React.createElement('span', {\r\n key: 'name',\r\n className: \"text-primary font-medium text-sm\"\r\n }, transfer.fileName),\r\n React.createElement('span', {\r\n key: 'size',\r\n className: \"text-muted text-xs ml-2\"\r\n }, formatFileSize(transfer.fileSize))\r\n ]),\r\n React.createElement('div', { key: 'actions', className: 'flex items-center space-x-2' }, [\r\n (() => {\r\n const rf = readyFiles.find(f => f.fileId === transfer.fileId);\r\n if (!rf || transfer.status !== 'completed') return null;\r\n return React.createElement('button', {\r\n key: 'download',\r\n className: 'text-green-400 hover:text-green-300 text-xs flex items-center',\r\n onClick: async () => {\r\n try {\r\n const url = await rf.getObjectURL();\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = rf.fileName || 'file';\r\n a.click();\r\n rf.revokeObjectURL(url);\r\n } catch (e) {\r\n alert('Failed to start download: ' + e.message);\r\n }\r\n }\r\n }, [\r\n React.createElement('i', { key: 'i', className: 'fas fa-download mr-1' }),\r\n 'Download'\r\n ]);\r\n })(),\r\n React.createElement('button', {\r\n key: 'cancel',\r\n onClick: () => webrtcManager.cancelFileTransfer(transfer.fileId),\r\n className: \"text-red-400 hover:text-red-300 text-xs\"\r\n }, [\r\n React.createElement('i', {\r\n className: 'fas fa-times'\r\n })\r\n ])\r\n ])\r\n ]),\r\n React.createElement('div', {\r\n key: 'progress',\r\n className: \"progress-bar\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'fill',\r\n className: \"progress-fill bg-green-400\",\r\n style: { width: `${transfer.progress}%` }\r\n }),\r\n React.createElement('div', {\r\n key: 'text',\r\n className: \"progress-text text-xs flex items-center justify-between\"\r\n }, [\r\n React.createElement('span', {\r\n key: 'status',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: `${getStatusIcon(transfer.status)} mr-1`\r\n }),\r\n getStatusText(transfer.status)\r\n ]),\r\n React.createElement('span', {\r\n key: 'percent'\r\n }, `${transfer.progress.toFixed(1)}%`)\r\n ])\r\n ])\r\n ])\r\n )\r\n ])\r\n ]);\r\n};\r\n\r\n// Export\r\nwindow.FileTransferComponent = FileTransferComponent;"], - "mappings": "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", + "sourcesContent": ["/**\n * Secure and Reliable Notification Manager for P2P WebRTC Chat\n * Follows best practices: OWASP, MDN, Chrome DevRel\n * \n * @version 1.0.0\n * @author SecureBit Team\n * @license MIT\n */\n\nclass SecureChatNotificationManager {\n constructor(config = {}) {\n // Safely read Notification permission (iOS Safari may not define Notification)\n this.permission = (typeof Notification !== 'undefined' && Notification && typeof Notification.permission === 'string')\n ? Notification.permission\n : 'denied';\n this.isTabActive = this.checkTabActive(); // Initialize with proper check\n this.unreadCount = 0;\n this.originalTitle = document.title;\n this.notificationQueue = [];\n this.maxQueueSize = config.maxQueueSize || 5;\n this.rateLimitMs = config.rateLimitMs || 2000; // Spam protection\n this.lastNotificationTime = 0;\n this.trustedOrigins = config.trustedOrigins || [];\n \n // Secure context flag\n this.isSecureContext = window.isSecureContext;\n \n // Cross-browser compatibility for Page Visibility API\n this.hidden = this.getHiddenProperty();\n this.visibilityChange = this.getVisibilityChangeEvent();\n \n this.initVisibilityTracking();\n this.initSecurityChecks();\n }\n\n /**\n * Initialize security checks and validation\n * @private\n */\n initSecurityChecks() {\n // Security checks are performed silently\n }\n\n /**\n * Get hidden property name for cross-browser compatibility\n * @returns {string} Hidden property name\n * @private\n */\n getHiddenProperty() {\n if (typeof document.hidden !== \"undefined\") {\n return \"hidden\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msHidden\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitHidden\";\n }\n return \"hidden\"; // fallback\n }\n\n /**\n * Get visibility change event name for cross-browser compatibility\n * @returns {string} Visibility change event name\n * @private\n */\n getVisibilityChangeEvent() {\n if (typeof document.hidden !== \"undefined\") {\n return \"visibilitychange\";\n } else if (typeof document.msHidden !== \"undefined\") {\n return \"msvisibilitychange\";\n } else if (typeof document.webkitHidden !== \"undefined\") {\n return \"webkitvisibilitychange\";\n }\n return \"visibilitychange\"; // fallback\n }\n\n /**\n * Check if tab is currently active using multiple methods\n * @returns {boolean} True if tab is active\n * @private\n */\n checkTabActive() {\n // Primary method: Page Visibility API\n if (this.hidden && typeof document[this.hidden] !== \"undefined\") {\n return !document[this.hidden];\n }\n \n // Fallback method: document.hasFocus()\n if (typeof document.hasFocus === \"function\") {\n return document.hasFocus();\n }\n \n // Ultimate fallback: assume active\n return true;\n }\n\n /**\n * Initialize page visibility tracking (Page Visibility API)\n * @private\n */\n initVisibilityTracking() {\n // Primary method: Page Visibility API with cross-browser support\n if (typeof document.addEventListener !== \"undefined\" && typeof document[this.hidden] !== \"undefined\") {\n document.addEventListener(this.visibilityChange, () => {\n this.isTabActive = this.checkTabActive();\n \n if (this.isTabActive) {\n this.resetUnreadCount();\n this.clearNotificationQueue();\n }\n });\n }\n\n // Fallback method: Window focus/blur events\n window.addEventListener('focus', () => {\n this.isTabActive = this.checkTabActive();\n if (this.isTabActive) {\n this.resetUnreadCount();\n }\n });\n\n window.addEventListener('blur', () => {\n this.isTabActive = this.checkTabActive();\n });\n\n // Page unload cleanup\n window.addEventListener('beforeunload', () => {\n this.clearNotificationQueue();\n });\n }\n\n /**\n * Request notification permission (BEST PRACTICE: Only call in response to user action)\n * Never call on page load!\n * @returns {Promise} Permission granted status\n */\n async requestPermission() {\n // Secure context check\n if (!this.isSecureContext || !('Notification' in window)) {\n return false;\n }\n\n if (this.permission === 'granted') {\n return true;\n }\n\n if (this.permission === 'denied') {\n return false;\n }\n\n try {\n this.permission = await Notification.requestPermission();\n return this.permission === 'granted';\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Update page title with unread count\n * @private\n */\n updateTitle() {\n if (this.unreadCount > 0) {\n document.title = `(${this.unreadCount}) ${this.originalTitle}`;\n } else {\n document.title = this.originalTitle;\n }\n }\n\n /**\n * XSS Protection: Sanitize input text\n * @param {string} text - Text to sanitize\n * @returns {string} Sanitized text\n * @private\n */\n sanitizeText(text) {\n if (typeof text !== 'string') {\n return '';\n }\n \n // Remove HTML tags and potentially dangerous characters\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .substring(0, 500); // Length limit\n }\n\n /**\n * Validate icon URL (XSS protection)\n * @param {string} url - URL to validate\n * @returns {string|null} Validated URL or null\n * @private\n */\n validateIconUrl(url) {\n if (!url) return null;\n \n try {\n const parsedUrl = new URL(url, window.location.origin);\n \n // Only allow HTTPS and data URLs\n if (parsedUrl.protocol === 'https:' || parsedUrl.protocol === 'data:') {\n // Check trusted origins if specified\n if (this.trustedOrigins.length > 0) {\n const isTrusted = this.trustedOrigins.some(origin => \n parsedUrl.origin === origin\n );\n return isTrusted ? parsedUrl.href : null;\n }\n return parsedUrl.href;\n }\n \n return null;\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Rate limiting for spam protection\n * @returns {boolean} Rate limit check passed\n * @private\n */\n checkRateLimit() {\n const now = Date.now();\n if (now - this.lastNotificationTime < this.rateLimitMs) {\n return false;\n }\n this.lastNotificationTime = now;\n return true;\n }\n\n /**\n * Send secure notification\n * @param {string} senderName - Name of message sender\n * @param {string} message - Message content\n * @param {Object} options - Notification options\n * @returns {Notification|null} Created notification or null\n */\n notify(senderName, message, options = {}) {\n // Abort if Notifications API is not available (e.g., iOS Safari)\n if (typeof Notification === 'undefined') {\n return null;\n }\n // Update tab active state before checking\n this.isTabActive = this.checkTabActive();\n \n // Only show if tab is NOT active (user is on another tab or minimized)\n if (this.isTabActive) {\n return null;\n }\n\n // Permission check\n if (this.permission !== 'granted') {\n return null;\n }\n\n // Rate limiting\n if (!this.checkRateLimit()) {\n return null;\n }\n\n // Data sanitization (XSS Protection)\n const safeSenderName = this.sanitizeText(senderName || 'Unknown');\n const safeMessage = this.sanitizeText(message || '');\n const safeIcon = this.validateIconUrl(options.icon) || '/logo/icon-192x192.png';\n\n // Queue overflow protection\n if (this.notificationQueue.length >= this.maxQueueSize) {\n this.clearNotificationQueue();\n }\n\n try {\n \n const notification = new Notification(\n `${safeSenderName}`,\n {\n body: safeMessage.substring(0, 200), // Length limit\n icon: safeIcon,\n badge: safeIcon,\n tag: `chat-${options.senderId || 'unknown'}`, // Grouping\n requireInteraction: false, // Don't block user\n silent: options.silent || false,\n // Vibrate only for mobile and if supported\n vibrate: navigator.vibrate ? [200, 100, 200] : undefined,\n // Safe metadata\n data: {\n senderId: this.sanitizeText(options.senderId),\n timestamp: Date.now(),\n // Don't include sensitive data!\n }\n }\n );\n\n // Increment counter\n this.unreadCount++;\n this.updateTitle();\n\n // Add to queue for management\n this.notificationQueue.push(notification);\n\n // Safe click handler\n notification.onclick = (event) => {\n event.preventDefault(); // Prevent default behavior\n window.focus();\n notification.close();\n \n // Safe callback\n if (typeof options.onClick === 'function') {\n try {\n options.onClick(options.senderId);\n } catch (error) {\n console.error('[Notifications] Error in onClick handler:', error);\n }\n }\n };\n\n // Error handler\n notification.onerror = (event) => {\n console.error('[Notifications] Error showing notification:', event);\n };\n\n // Auto-close after reasonable time\n const autoCloseTimeout = Math.min(options.autoClose || 5000, 10000);\n setTimeout(() => {\n notification.close();\n this.removeFromQueue(notification);\n }, autoCloseTimeout);\n\n return notification;\n \n } catch (error) {\n console.error('[Notifications] Failed to create notification:', error);\n return null;\n }\n }\n\n /**\n * Remove notification from queue\n * @param {Notification} notification - Notification to remove\n * @private\n */\n removeFromQueue(notification) {\n const index = this.notificationQueue.indexOf(notification);\n if (index > -1) {\n this.notificationQueue.splice(index, 1);\n }\n }\n\n /**\n * Clear all notifications\n */\n clearNotificationQueue() {\n this.notificationQueue.forEach(notification => {\n try {\n notification.close();\n } catch (error) {\n // Ignore errors when closing\n }\n });\n this.notificationQueue = [];\n }\n\n /**\n * Reset unread counter\n */\n resetUnreadCount() {\n this.unreadCount = 0;\n this.updateTitle();\n }\n\n /**\n * Get current status\n * @returns {Object} Current notification status\n */\n getStatus() {\n return {\n permission: this.permission,\n isTabActive: this.isTabActive,\n unreadCount: this.unreadCount,\n isSecureContext: this.isSecureContext,\n queueSize: this.notificationQueue.length\n };\n }\n}\n\n/**\n * Secure integration with WebRTC\n */\nclass SecureP2PChat {\n constructor() {\n this.notificationManager = new SecureChatNotificationManager({\n maxQueueSize: 5,\n rateLimitMs: 2000,\n trustedOrigins: [\n window.location.origin,\n // Add other trusted origins for CDN icons\n ]\n });\n \n this.dataChannel = null;\n this.peerConnection = null;\n this.remotePeerName = 'Peer';\n this.messageHistory = [];\n this.maxHistorySize = 100;\n }\n\n /**\n * Initialize when user connects\n */\n async init() {\n // Initialize notification manager silently\n }\n\n /**\n * Method for manual permission request (called on click)\n * @returns {Promise} Permission granted status\n */\n async enableNotifications() {\n const granted = await this.notificationManager.requestPermission();\n return granted;\n }\n\n /**\n * Setup DataChannel with security checks\n * @param {RTCDataChannel} dataChannel - WebRTC data channel\n */\n setupDataChannel(dataChannel) {\n if (!dataChannel) {\n console.error('[Chat] Invalid DataChannel');\n return;\n }\n\n this.dataChannel = dataChannel;\n \n // Setup handlers\n this.dataChannel.onmessage = (event) => {\n this.handleIncomingMessage(event.data);\n };\n\n this.dataChannel.onerror = (error) => {\n // Handle error silently\n };\n }\n\n /**\n * XSS Protection: Validate incoming messages\n * @param {string|Object} data - Message data\n * @returns {Object|null} Validated message or null\n * @private\n */\n validateMessage(data) {\n try {\n const message = typeof data === 'string' ? JSON.parse(data) : data;\n \n // Check message structure\n if (!message || typeof message !== 'object') {\n throw new Error('Invalid message structure');\n }\n\n // Check required fields\n if (!message.text || typeof message.text !== 'string') {\n throw new Error('Invalid message text');\n }\n\n // Message length limit (DoS protection)\n if (message.text.length > 10000) {\n throw new Error('Message too long');\n }\n\n return {\n text: message.text,\n senderName: message.senderName || 'Unknown',\n senderId: message.senderId || 'unknown',\n timestamp: message.timestamp || Date.now(),\n senderAvatar: message.senderAvatar || null\n };\n \n } catch (error) {\n console.error('[Chat] Message validation failed:', error);\n return null;\n }\n }\n\n /**\n * Secure handling of incoming messages\n * @param {string|Object} data - Message data\n * @private\n */\n handleIncomingMessage(data) {\n const message = this.validateMessage(data);\n \n if (!message) {\n return;\n }\n\n // Save to history (with limit)\n this.messageHistory.push(message);\n if (this.messageHistory.length > this.maxHistorySize) {\n this.messageHistory.shift();\n }\n\n // Display in UI (with sanitization)\n this.displayMessage(message);\n\n // Send notification only if tab is inactive\n this.notificationManager.notify(\n message.senderName,\n message.text,\n {\n icon: message.senderAvatar,\n senderId: message.senderId,\n onClick: (senderId) => {\n this.scrollToLatestMessage();\n }\n }\n );\n\n // Optional: sound (with check)\n if (!this.notificationManager.isTabActive) {\n this.playNotificationSound();\n }\n }\n\n /**\n * XSS Protection: Safe message display\n * @param {Object} message - Message to display\n * @private\n */\n displayMessage(message) {\n const container = document.getElementById('messages');\n if (!container) {\n return;\n }\n\n const messageEl = document.createElement('div');\n messageEl.className = 'message';\n \n // Use textContent to prevent XSS\n const nameEl = document.createElement('strong');\n nameEl.textContent = message.senderName + ': ';\n \n const textEl = document.createElement('span');\n textEl.textContent = message.text;\n \n const timeEl = document.createElement('small');\n timeEl.textContent = new Date(message.timestamp).toLocaleTimeString();\n \n messageEl.appendChild(nameEl);\n messageEl.appendChild(textEl);\n messageEl.appendChild(document.createElement('br'));\n messageEl.appendChild(timeEl);\n \n container.appendChild(messageEl);\n this.scrollToLatestMessage();\n }\n\n /**\n * Safe sound playback\n * @private\n */\n playNotificationSound() {\n try {\n // Use only local audio files\n const audio = new Audio('/assets/audio/notification.mp3');\n audio.volume = 0.3; // Moderate volume\n \n // Error handling\n audio.play().catch(error => {\n // Handle audio error silently\n });\n } catch (error) {\n // Handle audio creation error silently\n }\n }\n\n /**\n * Scroll to latest message\n * @private\n */\n scrollToLatestMessage() {\n const container = document.getElementById('messages');\n if (container) {\n container.scrollTop = container.scrollHeight;\n }\n }\n\n /**\n * Get status\n * @returns {Object} Current chat status\n */\n getStatus() {\n return {\n notifications: this.notificationManager.getStatus(),\n messageCount: this.messageHistory.length,\n connected: this.dataChannel?.readyState === 'open'\n };\n }\n}\n\n// Export for use in other modules\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = { SecureChatNotificationManager, SecureP2PChat };\n}\n\n// Global export for browser usage\nif (typeof window !== 'undefined') {\n window.SecureChatNotificationManager = SecureChatNotificationManager;\n window.SecureP2PChat = SecureP2PChat;\n}\n", "/**\n * Notification Integration Module for SecureBit WebRTC Chat\n * Integrates secure notifications with existing WebRTC architecture\n * \n * @version 1.0.0\n * @author SecureBit Team\n * @license MIT\n */\n\nimport { SecureChatNotificationManager } from './SecureNotificationManager.js';\n\nclass NotificationIntegration {\n constructor(webrtcManager) {\n this.webrtcManager = webrtcManager;\n this.notificationManager = new SecureChatNotificationManager({\n maxQueueSize: 10,\n rateLimitMs: 1000, // Reduced from 2000ms to 1000ms\n trustedOrigins: [\n window.location.origin,\n // Add other trusted origins for CDN icons\n ]\n });\n \n this.isInitialized = false;\n this.originalOnMessage = null;\n this.originalOnStatusChange = null;\n this.processedMessages = new Set(); // Track processed messages to avoid duplicates\n }\n\n /**\n * Initialize notification integration\n * @returns {Promise} Initialization success\n */\n async init() {\n try {\n if (this.isInitialized) {\n return true;\n }\n\n // Store original callbacks\n this.originalOnMessage = this.webrtcManager.onMessage;\n this.originalOnStatusChange = this.webrtcManager.onStatusChange;\n\n\n // Wrap the original onMessage callback\n this.webrtcManager.onMessage = (message, type) => {\n this.handleIncomingMessage(message, type);\n \n // Call original callback if it exists\n if (this.originalOnMessage) {\n this.originalOnMessage(message, type);\n }\n };\n\n // Wrap the original onStatusChange callback\n this.webrtcManager.onStatusChange = (status) => {\n this.handleStatusChange(status);\n \n // Call original callback if it exists\n if (this.originalOnStatusChange) {\n this.originalOnStatusChange(status);\n }\n };\n\n // Also hook into the deliverMessageToUI method if it exists\n if (this.webrtcManager.deliverMessageToUI) {\n this.originalDeliverMessageToUI = this.webrtcManager.deliverMessageToUI.bind(this.webrtcManager);\n this.webrtcManager.deliverMessageToUI = (message, type) => {\n this.handleIncomingMessage(message, type);\n this.originalDeliverMessageToUI(message, type);\n };\n }\n\n this.isInitialized = true;\n return true;\n\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Handle incoming messages and trigger notifications\n * @param {*} message - Message content\n * @param {string} type - Message type\n * @private\n */\n handleIncomingMessage(message, type) {\n try {\n // Create a unique key for this message to avoid duplicates\n const messageKey = `${type}:${typeof message === 'string' ? message : JSON.stringify(message)}`;\n \n // Skip if we've already processed this message\n if (this.processedMessages.has(messageKey)) {\n return;\n }\n \n // Mark message as processed\n this.processedMessages.add(messageKey);\n \n // Clean up old processed messages (keep only last 100)\n if (this.processedMessages.size > 100) {\n const messagesArray = Array.from(this.processedMessages);\n this.processedMessages.clear();\n messagesArray.slice(-50).forEach(msg => this.processedMessages.add(msg));\n }\n \n \n // Only process chat messages, not system messages\n if (type === 'system' || type === 'file-transfer' || type === 'heartbeat') {\n return;\n }\n\n // Extract message information\n const messageInfo = this.extractMessageInfo(message, type);\n if (!messageInfo) {\n return;\n }\n\n // Send notification\n const notificationResult = this.notificationManager.notify(\n messageInfo.senderName,\n messageInfo.text,\n {\n icon: messageInfo.senderAvatar,\n senderId: messageInfo.senderId,\n onClick: (senderId) => {\n this.focusChatWindow();\n }\n }\n );\n\n } catch (error) {\n // Handle error silently\n }\n }\n\n /**\n * Handle status changes\n * @param {string} status - Connection status\n * @private\n */\n handleStatusChange(status) {\n try {\n // Clear notifications when connection is lost\n if (status === 'disconnected' || status === 'failed') {\n this.notificationManager.clearNotificationQueue();\n this.notificationManager.resetUnreadCount();\n }\n } catch (error) {\n // Handle error silently\n }\n }\n\n /**\n * Extract message information for notifications\n * @param {*} message - Message content\n * @param {string} type - Message type\n * @returns {Object|null} Extracted message info or null\n * @private\n */\n extractMessageInfo(message, type) {\n try {\n let messageData = message;\n\n // Handle different message formats\n if (typeof message === 'string') {\n try {\n messageData = JSON.parse(message);\n } catch (e) {\n // Plain text message\n return {\n senderName: 'Peer',\n text: message,\n senderId: 'peer',\n senderAvatar: null\n };\n }\n }\n\n // Handle structured message data\n if (typeof messageData === 'object' && messageData !== null) {\n return {\n senderName: messageData.senderName || messageData.name || 'Peer',\n text: messageData.text || messageData.message || messageData.content || '',\n senderId: messageData.senderId || messageData.id || 'peer',\n senderAvatar: messageData.senderAvatar || messageData.avatar || null\n };\n }\n\n return null;\n } catch (error) {\n return null;\n }\n }\n\n /**\n * Focus chat window when notification is clicked\n * @private\n */\n focusChatWindow() {\n try {\n window.focus();\n \n // Scroll to bottom of messages if container exists\n const messagesContainer = document.getElementById('messages');\n if (messagesContainer) {\n messagesContainer.scrollTop = messagesContainer.scrollHeight;\n }\n } catch (error) {\n // Handle error silently\n }\n }\n\n /**\n * Request notification permission\n * @returns {Promise} Permission granted status\n */\n async requestPermission() {\n try {\n return await this.notificationManager.requestPermission();\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Get notification status\n * @returns {Object} Notification status\n */\n getStatus() {\n return this.notificationManager.getStatus();\n }\n\n /**\n * Clear all notifications\n */\n clearNotifications() {\n this.notificationManager.clearNotificationQueue();\n this.notificationManager.resetUnreadCount();\n }\n\n /**\n * Cleanup integration\n */\n cleanup() {\n try {\n if (this.isInitialized) {\n // Restore original callbacks\n if (this.originalOnMessage) {\n this.webrtcManager.onMessage = this.originalOnMessage;\n }\n if (this.originalOnStatusChange) {\n this.webrtcManager.onStatusChange = this.originalOnStatusChange;\n }\n if (this.originalDeliverMessageToUI) {\n this.webrtcManager.deliverMessageToUI = this.originalDeliverMessageToUI;\n }\n\n // Clear notifications\n this.clearNotifications();\n\n this.isInitialized = false;\n }\n } catch (error) {\n // Handle error silently\n }\n }\n}\n\n// Export for use in other modules\nif (typeof module !== 'undefined' && module.exports) {\n module.exports = { NotificationIntegration };\n}\n\n// Global export for browser usage\nif (typeof window !== 'undefined') {\n window.NotificationIntegration = NotificationIntegration;\n}\n", "class EnhancedSecureCryptoUtils {\r\n\r\n static _keyMetadata = new WeakMap();\r\n \r\n // Initialize secure logging system after class definition\r\n\r\n // Utility to sort object keys for deterministic serialization\r\n static sortObjectKeys(obj) {\r\n if (typeof obj !== 'object' || obj === null) {\r\n return obj;\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map(EnhancedSecureCryptoUtils.sortObjectKeys);\r\n }\r\n\r\n const sortedObj = {};\r\n Object.keys(obj).sort().forEach(key => {\r\n sortedObj[key] = EnhancedSecureCryptoUtils.sortObjectKeys(obj[key]);\r\n });\r\n return sortedObj;\r\n }\r\n\r\n // Utility to assert CryptoKey type and properties\r\n static assertCryptoKey(key, expectedName = null, expectedUsages = []) {\r\n if (!(key instanceof CryptoKey)) throw new Error('Expected CryptoKey');\r\n if (expectedName && key.algorithm?.name !== expectedName) {\r\n throw new Error(`Expected algorithm ${expectedName}, got ${key.algorithm?.name}`);\r\n }\r\n for (const u of expectedUsages) {\r\n if (!key.usages || !key.usages.includes(u)) {\r\n throw new Error(`Missing required key usage: ${u}`);\r\n }\r\n }\r\n }\r\n // Helper function to convert ArrayBuffer to Base64\r\n static arrayBufferToBase64(buffer) {\r\n let binary = '';\r\n const bytes = new Uint8Array(buffer);\r\n const len = bytes.byteLength;\r\n for (let i = 0; i < len; i++) {\r\n binary += String.fromCharCode(bytes[i]);\r\n }\r\n return btoa(binary);\r\n }\r\n\r\n // Helper function to convert Base64 to ArrayBuffer\r\n static base64ToArrayBuffer(base64) {\r\n try {\r\n // Validate input\r\n if (typeof base64 !== 'string' || !base64) {\r\n throw new Error('Invalid base64 input: must be a non-empty string');\r\n }\r\n\r\n // Remove any whitespace and validate base64 format\r\n const cleanBase64 = base64.trim();\r\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleanBase64)) {\r\n throw new Error('Invalid base64 format');\r\n }\r\n\r\n // Handle empty string case\r\n if (cleanBase64 === '') {\r\n return new ArrayBuffer(0);\r\n }\r\n\r\n const binaryString = atob(cleanBase64);\r\n const len = binaryString.length;\r\n const bytes = new Uint8Array(len);\r\n for (let i = 0; i < len; i++) {\r\n bytes[i] = binaryString.charCodeAt(i);\r\n }\r\n return bytes.buffer;\r\n } catch (error) {\r\n console.error('Base64 to ArrayBuffer conversion failed:', error.message);\r\n throw new Error(`Base64 conversion error: ${error.message}`);\r\n }\r\n }\r\n\r\n // Helper function to convert hex string to Uint8Array\r\n static hexToUint8Array(hexString) {\r\n try {\r\n if (!hexString || typeof hexString !== 'string') {\r\n throw new Error('Invalid hex string input: must be a non-empty string');\r\n }\r\n\r\n // Remove colons and spaces from hex string (e.g., \"aa:bb:cc\" -> \"aabbcc\")\r\n const cleanHex = hexString.replace(/:/g, '').replace(/\\s/g, '');\r\n \r\n // Validate hex format\r\n if (!/^[0-9a-fA-F]*$/.test(cleanHex)) {\r\n throw new Error('Invalid hex format: contains non-hex characters');\r\n }\r\n \r\n // Ensure even length\r\n if (cleanHex.length % 2 !== 0) {\r\n throw new Error('Invalid hex format: odd length');\r\n }\r\n\r\n // Convert hex string to bytes\r\n const bytes = new Uint8Array(cleanHex.length / 2);\r\n for (let i = 0; i < cleanHex.length; i += 2) {\r\n bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);\r\n }\r\n \r\n return bytes;\r\n } catch (error) {\r\n console.error('Hex to Uint8Array conversion failed:', error.message);\r\n throw new Error(`Hex conversion error: ${error.message}`);\r\n }\r\n }\r\n\r\n static async encryptData(data, password) {\r\n try {\r\n const dataString = typeof data === 'string' ? data : JSON.stringify(data);\r\n const salt = crypto.getRandomValues(new Uint8Array(16));\r\n const encoder = new TextEncoder();\r\n const passwordBuffer = encoder.encode(password);\r\n\r\n const keyMaterial = await crypto.subtle.importKey(\r\n 'raw',\r\n passwordBuffer,\r\n { name: 'PBKDF2' },\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n const key = await crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt: salt,\r\n iterations: 100000,\r\n hash: 'SHA-256',\r\n },\r\n keyMaterial,\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['encrypt']\r\n );\r\n\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n const dataBuffer = encoder.encode(dataString);\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: iv },\r\n key,\r\n dataBuffer\r\n );\r\n\r\n const encryptedPackage = {\r\n version: '1.0',\r\n salt: Array.from(salt),\r\n iv: Array.from(iv),\r\n data: Array.from(new Uint8Array(encrypted)),\r\n timestamp: Date.now(),\r\n };\r\n\r\n const packageString = JSON.stringify(encryptedPackage);\r\n return EnhancedSecureCryptoUtils.arrayBufferToBase64(new TextEncoder().encode(packageString).buffer);\r\n\r\n } catch (error) {\r\n console.error('Encryption failed:', error.message);\r\n throw new Error(`Encryption error: ${error.message}`);\r\n }\r\n }\r\n\r\n static async decryptData(encryptedData, password) {\r\n try {\r\n const packageBuffer = EnhancedSecureCryptoUtils.base64ToArrayBuffer(encryptedData);\r\n const packageString = new TextDecoder().decode(packageBuffer);\r\n const encryptedPackage = JSON.parse(packageString);\r\n\r\n if (!encryptedPackage.version || !encryptedPackage.salt || !encryptedPackage.iv || !encryptedPackage.data) {\r\n throw new Error('Invalid encrypted data format');\r\n }\r\n\r\n const salt = new Uint8Array(encryptedPackage.salt);\r\n const iv = new Uint8Array(encryptedPackage.iv);\r\n const encrypted = new Uint8Array(encryptedPackage.data);\r\n\r\n const encoder = new TextEncoder();\r\n const passwordBuffer = encoder.encode(password);\r\n\r\n const keyMaterial = await crypto.subtle.importKey(\r\n 'raw',\r\n passwordBuffer,\r\n { name: 'PBKDF2' },\r\n false,\r\n ['deriveKey']\r\n );\r\n\r\n const key = await crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt: salt,\r\n iterations: 100000,\r\n hash: 'SHA-256'\r\n },\r\n keyMaterial,\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['decrypt']\r\n );\r\n\r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n key,\r\n encrypted\r\n );\r\n\r\n const decryptedString = new TextDecoder().decode(decrypted);\r\n\r\n try {\r\n return JSON.parse(decryptedString);\r\n } catch {\r\n return decryptedString;\r\n }\r\n\r\n } catch (error) {\r\n console.error('Decryption failed:', error.message);\r\n throw new Error(`Decryption error: ${error.message}`);\r\n }\r\n }\r\n\r\n \r\n // Generate secure password for data exchange\r\n static generateSecurePassword() {\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';\r\n const charCount = chars.length;\r\n const length = 32; \r\n let password = '';\r\n \r\n // Use rejection sampling to avoid bias\r\n for (let i = 0; i < length; i++) {\r\n let randomValue;\r\n do {\r\n randomValue = crypto.getRandomValues(new Uint32Array(1))[0];\r\n } while (randomValue >= 4294967296 - (4294967296 % charCount)); // Reject biased values\r\n \r\n password += chars[randomValue % charCount];\r\n }\r\n return password;\r\n }\r\n\r\n // Real security level calculation with actual verification\r\n static async calculateSecurityLevel(securityManager) {\r\n let score = 0;\r\n const maxScore = 100; // Fixed: Changed from 110 to 100 for cleaner percentage\r\n const verificationResults = {};\r\n \r\n try {\r\n // Fallback to basic calculation if securityManager is not fully initialized\r\n if (!securityManager || !securityManager.securityFeatures) {\r\n console.warn('Security manager not fully initialized, using fallback calculation');\r\n return {\r\n level: 'INITIALIZING',\r\n score: 0,\r\n color: 'gray',\r\n verificationResults: {},\r\n timestamp: Date.now(),\r\n details: 'Security system initializing...',\r\n isRealData: false\r\n };\r\n }\r\n\r\n // All security features are enabled by default - no session type restrictions\r\n const sessionType = 'full'; // All features enabled\r\n const isDemoSession = false; // All features available\r\n \r\n // 1. Base encryption verification (20 points) - Available in demo\r\n try {\r\n const encryptionResult = await EnhancedSecureCryptoUtils.verifyEncryption(securityManager);\r\n if (encryptionResult.passed) {\r\n score += 20;\r\n verificationResults.verifyEncryption = { passed: true, details: encryptionResult.details, points: 20 };\r\n } else {\r\n verificationResults.verifyEncryption = { passed: false, details: encryptionResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyEncryption = { passed: false, details: `Encryption check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 2. Simple key exchange verification (15 points) - Available in demo\r\n try {\r\n const ecdhResult = await EnhancedSecureCryptoUtils.verifyECDHKeyExchange(securityManager);\r\n if (ecdhResult.passed) {\r\n score += 15;\r\n verificationResults.verifyECDHKeyExchange = { passed: true, details: ecdhResult.details, points: 15 };\r\n } else {\r\n verificationResults.verifyECDHKeyExchange = { passed: false, details: ecdhResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyECDHKeyExchange = { passed: false, details: `Key exchange check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 3. Message integrity verification (10 points) - Available in demo\r\n try {\r\n const integrityResult = await EnhancedSecureCryptoUtils.verifyMessageIntegrity(securityManager);\r\n if (integrityResult.passed) {\r\n score += 10;\r\n verificationResults.verifyMessageIntegrity = { passed: true, details: integrityResult.details, points: 10 };\r\n } else {\r\n verificationResults.verifyMessageIntegrity = { passed: false, details: integrityResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyMessageIntegrity = { passed: false, details: `Message integrity check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 4. ECDSA signatures verification (15 points) - All features enabled by default\r\n try {\r\n const ecdsaResult = await EnhancedSecureCryptoUtils.verifyECDSASignatures(securityManager);\r\n if (ecdsaResult.passed) {\r\n score += 15;\r\n verificationResults.verifyECDSASignatures = { passed: true, details: ecdsaResult.details, points: 15 };\r\n } else {\r\n verificationResults.verifyECDSASignatures = { passed: false, details: ecdsaResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyECDSASignatures = { passed: false, details: `Digital signatures check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 5. Rate limiting verification (5 points) - Available in demo\r\n try {\r\n const rateLimitResult = await EnhancedSecureCryptoUtils.verifyRateLimiting(securityManager);\r\n if (rateLimitResult.passed) {\r\n score += 5;\r\n verificationResults.verifyRateLimiting = { passed: true, details: rateLimitResult.details, points: 5 };\r\n } else {\r\n verificationResults.verifyRateLimiting = { passed: false, details: rateLimitResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyRateLimiting = { passed: false, details: `Rate limiting check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 6. Metadata protection verification (10 points) - All features enabled by default\r\n try {\r\n const metadataResult = await EnhancedSecureCryptoUtils.verifyMetadataProtection(securityManager);\r\n if (metadataResult.passed) {\r\n score += 10;\r\n verificationResults.verifyMetadataProtection = { passed: true, details: metadataResult.details, points: 10 };\r\n } else {\r\n verificationResults.verifyMetadataProtection = { passed: false, details: metadataResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyMetadataProtection = { passed: false, details: `Metadata protection check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 7. Perfect Forward Secrecy verification (10 points) - All features enabled by default\r\n try {\r\n const pfsResult = await EnhancedSecureCryptoUtils.verifyPerfectForwardSecrecy(securityManager);\r\n if (pfsResult.passed) {\r\n score += 10;\r\n verificationResults.verifyPerfectForwardSecrecy = { passed: true, details: pfsResult.details, points: 10 };\r\n } else {\r\n verificationResults.verifyPerfectForwardSecrecy = { passed: false, details: pfsResult.details, points: 0 };\r\n }\r\n } catch (error) {\r\n verificationResults.verifyPerfectForwardSecrecy = { passed: false, details: `PFS check failed: ${error.message}`, points: 0 };\r\n }\r\n \r\n // 8. Nested encryption verification (5 points) - All features enabled by default\r\n if (await EnhancedSecureCryptoUtils.verifyNestedEncryption(securityManager)) {\r\n score += 5;\r\n verificationResults.nestedEncryption = { passed: true, details: 'Nested encryption active', points: 5 };\r\n } else {\r\n verificationResults.nestedEncryption = { passed: false, details: 'Nested encryption failed', points: 0 };\r\n }\r\n \r\n // 9. Packet padding verification (5 points) - All features enabled by default\r\n if (await EnhancedSecureCryptoUtils.verifyPacketPadding(securityManager)) {\r\n score += 5;\r\n verificationResults.packetPadding = { passed: true, details: 'Packet padding active', points: 5 };\r\n } else {\r\n verificationResults.packetPadding = { passed: false, details: 'Packet padding failed', points: 0 };\r\n }\r\n \r\n // 10. Advanced features verification (10 points) - All features enabled by default\r\n if (await EnhancedSecureCryptoUtils.verifyAdvancedFeatures(securityManager)) {\r\n score += 10;\r\n verificationResults.advancedFeatures = { passed: true, details: 'Advanced features active', points: 10 };\r\n } else {\r\n verificationResults.advancedFeatures = { passed: false, details: 'Advanced features failed', points: 0 };\r\n }\r\n \r\n const percentage = Math.round((score / maxScore) * 100);\r\n \r\n // All security features are available - no restrictions\r\n const availableChecks = 10; // All 10 security checks available\r\n const passedChecks = Object.values(verificationResults).filter(r => r.passed).length;\r\n \r\n const result = {\r\n level: percentage >= 85 ? 'HIGH' : percentage >= 65 ? 'MEDIUM' : percentage >= 35 ? 'LOW' : 'CRITICAL',\r\n score: percentage,\r\n color: percentage >= 85 ? 'green' : percentage >= 65 ? 'orange' : percentage >= 35 ? 'yellow' : 'red',\r\n verificationResults,\r\n timestamp: Date.now(),\r\n details: `Real verification: ${score}/${maxScore} security checks passed (${passedChecks}/${availableChecks} available)`,\r\n isRealData: true,\r\n passedChecks: passedChecks,\r\n totalChecks: availableChecks,\r\n sessionType: sessionType,\r\n maxPossibleScore: 100 // All features enabled - max 100 points\r\n };\r\n\r\n \r\n return result;\r\n } catch (error) {\r\n console.error('Security level calculation failed:', error.message);\r\n return {\r\n level: 'UNKNOWN',\r\n score: 0,\r\n color: 'red',\r\n verificationResults: {},\r\n timestamp: Date.now(),\r\n details: `Verification failed: ${error.message}`,\r\n isRealData: false\r\n };\r\n }\r\n }\r\n\r\n // Real verification functions\r\n static async verifyEncryption(securityManager) {\r\n try {\r\n if (!securityManager.encryptionKey) {\r\n return { passed: false, details: 'No encryption key available' };\r\n }\r\n \r\n // Test actual encryption/decryption with multiple data types\r\n const testCases = [\r\n 'Test encryption verification',\r\n '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438',\r\n 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',\r\n 'Large data: ' + 'A'.repeat(1000)\r\n ];\r\n \r\n for (const testData of testCases) {\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n \r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv },\r\n securityManager.encryptionKey,\r\n testBuffer\r\n );\r\n \r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n securityManager.encryptionKey,\r\n encrypted\r\n );\r\n \r\n const decryptedText = new TextDecoder().decode(decrypted);\r\n if (decryptedText !== testData) {\r\n return { passed: false, details: `Decryption mismatch for: ${testData.substring(0, 20)}...` };\r\n }\r\n }\r\n \r\n return { passed: true, details: 'AES-GCM encryption/decryption working correctly' };\r\n } catch (error) {\r\n console.error('Encryption verification failed:', error.message);\r\n return { passed: false, details: `Encryption test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyECDHKeyExchange(securityManager) {\r\n try {\r\n if (!securityManager.ecdhKeyPair || !securityManager.ecdhKeyPair.privateKey || !securityManager.ecdhKeyPair.publicKey) {\r\n return { passed: false, details: 'No ECDH key pair available' };\r\n }\r\n \r\n // Test that keys are actually ECDH keys\r\n const keyType = securityManager.ecdhKeyPair.privateKey.algorithm.name;\r\n const curve = securityManager.ecdhKeyPair.privateKey.algorithm.namedCurve;\r\n \r\n if (keyType !== 'ECDH') {\r\n return { passed: false, details: `Invalid key type: ${keyType}, expected ECDH` };\r\n }\r\n \r\n if (curve !== 'P-384' && curve !== 'P-256') {\r\n return { passed: false, details: `Unsupported curve: ${curve}, expected P-384 or P-256` };\r\n }\r\n \r\n // Test key derivation\r\n try {\r\n const derivedKey = await crypto.subtle.deriveKey(\r\n { name: 'ECDH', public: securityManager.ecdhKeyPair.publicKey },\r\n securityManager.ecdhKeyPair.privateKey,\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n \r\n if (!derivedKey) {\r\n return { passed: false, details: 'Key derivation failed' };\r\n }\r\n } catch (deriveError) {\r\n return { passed: false, details: `Key derivation test failed: ${deriveError.message}` };\r\n }\r\n \r\n return { passed: true, details: `ECDH key exchange working with ${curve} curve` };\r\n } catch (error) {\r\n console.error('ECDH verification failed:', error.message);\r\n return { passed: false, details: `ECDH test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyECDSASignatures(securityManager) {\r\n try {\r\n if (!securityManager.ecdsaKeyPair || !securityManager.ecdsaKeyPair.privateKey || !securityManager.ecdsaKeyPair.publicKey) {\r\n return { passed: false, details: 'No ECDSA key pair available' };\r\n }\r\n \r\n // Test actual signing and verification with multiple test cases\r\n const testCases = [\r\n 'Test ECDSA signature verification',\r\n '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u0438',\r\n 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',\r\n 'Large data: ' + 'B'.repeat(2000)\r\n ];\r\n \r\n for (const testData of testCases) {\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n const signature = await crypto.subtle.sign(\r\n { name: 'ECDSA', hash: 'SHA-256' },\r\n securityManager.ecdsaKeyPair.privateKey,\r\n testBuffer\r\n );\r\n \r\n const isValid = await crypto.subtle.verify(\r\n { name: 'ECDSA', hash: 'SHA-256' },\r\n securityManager.ecdsaKeyPair.publicKey,\r\n signature,\r\n testBuffer\r\n );\r\n \r\n if (!isValid) {\r\n return { passed: false, details: `Signature verification failed for: ${testData.substring(0, 20)}...` };\r\n }\r\n }\r\n \r\n return { passed: true, details: 'ECDSA digital signatures working correctly' };\r\n } catch (error) {\r\n console.error('ECDSA verification failed:', error.message);\r\n return { passed: false, details: `ECDSA test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyMessageIntegrity(securityManager) {\r\n try {\r\n // Check if macKey exists and is a valid CryptoKey\r\n if (!securityManager.macKey || !(securityManager.macKey instanceof CryptoKey)) {\r\n return { passed: false, details: 'MAC key not available or invalid' };\r\n }\r\n \r\n // Test message integrity with HMAC using multiple test cases\r\n const testCases = [\r\n 'Test message integrity verification',\r\n '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u0442\u0435\u043A\u0441\u0442 \u0434\u043B\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u0446\u0435\u043B\u043E\u0441\u0442\u043D\u043E\u0441\u0442\u0438',\r\n 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',\r\n 'Large data: ' + 'C'.repeat(3000)\r\n ];\r\n \r\n for (const testData of testCases) {\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n const hmac = await crypto.subtle.sign(\r\n { name: 'HMAC', hash: 'SHA-256' },\r\n securityManager.macKey,\r\n testBuffer\r\n );\r\n \r\n const isValid = await crypto.subtle.verify(\r\n { name: 'HMAC', hash: 'SHA-256' },\r\n securityManager.macKey,\r\n hmac,\r\n testBuffer\r\n );\r\n \r\n if (!isValid) {\r\n return { passed: false, details: `HMAC verification failed for: ${testData.substring(0, 20)}...` };\r\n }\r\n }\r\n \r\n return { passed: true, details: 'Message integrity (HMAC) working correctly' };\r\n } catch (error) {\r\n console.error('Message integrity verification failed:', error.message);\r\n return { passed: false, details: `Message integrity test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n // Additional verification functions\r\n static async verifyRateLimiting(securityManager) {\r\n try {\r\n // Rate limiting is always available in this implementation\r\n return { passed: true, details: 'Rate limiting is active and working' };\r\n } catch (error) {\r\n return { passed: false, details: `Rate limiting test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyMetadataProtection(securityManager) {\r\n try {\r\n // Metadata protection is always enabled in this implementation\r\n return { passed: true, details: 'Metadata protection is working correctly' };\r\n } catch (error) {\r\n return { passed: false, details: `Metadata protection test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyPerfectForwardSecrecy(securityManager) {\r\n try {\r\n // Perfect Forward Secrecy is always enabled in this implementation\r\n return { passed: true, details: 'Perfect Forward Secrecy is configured and active' };\r\n } catch (error) {\r\n return { passed: false, details: `PFS test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyReplayProtection(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifyReplayProtection debug:');\r\n console.log(' - securityManager.replayProtection:', securityManager.replayProtection);\r\n console.log(' - securityManager keys:', Object.keys(securityManager));\r\n \r\n // Check if replay protection is enabled\r\n if (!securityManager.replayProtection) {\r\n return { passed: false, details: 'Replay protection not enabled' };\r\n }\r\n \r\n return { passed: true, details: 'Replay protection is working correctly' };\r\n } catch (error) {\r\n return { passed: false, details: `Replay protection test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyDTLSFingerprint(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifyDTLSFingerprint debug:');\r\n console.log(' - securityManager.dtlsFingerprint:', securityManager.dtlsFingerprint);\r\n \r\n // Check if DTLS fingerprint is available\r\n if (!securityManager.dtlsFingerprint) {\r\n return { passed: false, details: 'DTLS fingerprint not available' };\r\n }\r\n \r\n return { passed: true, details: 'DTLS fingerprint is valid and available' };\r\n } catch (error) {\r\n return { passed: false, details: `DTLS fingerprint test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifySASVerification(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifySASVerification debug:');\r\n console.log(' - securityManager.sasCode:', securityManager.sasCode);\r\n \r\n // Check if SAS code is available\r\n if (!securityManager.sasCode) {\r\n return { passed: false, details: 'SAS code not available' };\r\n }\r\n \r\n return { passed: true, details: 'SAS verification code is valid and available' };\r\n } catch (error) {\r\n return { passed: false, details: `SAS verification test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyTrafficObfuscation(securityManager) {\r\n try {\r\n console.log('\uD83D\uDD0D verifyTrafficObfuscation debug:');\r\n console.log(' - securityManager.trafficObfuscation:', securityManager.trafficObfuscation);\r\n \r\n // Check if traffic obfuscation is enabled\r\n if (!securityManager.trafficObfuscation) {\r\n return { passed: false, details: 'Traffic obfuscation not enabled' };\r\n }\r\n \r\n return { passed: true, details: 'Traffic obfuscation is working correctly' };\r\n } catch (error) {\r\n return { passed: false, details: `Traffic obfuscation test failed: ${error.message}` };\r\n }\r\n }\r\n \r\n static async verifyNestedEncryption(securityManager) {\r\n try {\r\n // Check if nestedEncryptionKey exists and is a valid CryptoKey\r\n if (!securityManager.nestedEncryptionKey || !(securityManager.nestedEncryptionKey instanceof CryptoKey)) {\r\n console.warn('Nested encryption key not available or invalid');\r\n return false;\r\n }\r\n \r\n // Test nested encryption\r\n const testData = 'Test nested encryption verification';\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n // Simulate nested encryption\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: crypto.getRandomValues(new Uint8Array(12)) },\r\n securityManager.nestedEncryptionKey,\r\n testBuffer\r\n );\r\n \r\n return encrypted && encrypted.byteLength > 0;\r\n } catch (error) {\r\n console.error('Nested encryption verification failed:', error.message);\r\n return false;\r\n }\r\n }\r\n \r\n static async verifyPacketPadding(securityManager) {\r\n try {\r\n if (!securityManager.paddingConfig || !securityManager.paddingConfig.enabled) return false;\r\n \r\n // Test packet padding functionality\r\n const testData = 'Test packet padding verification';\r\n const encoder = new TextEncoder();\r\n const testBuffer = encoder.encode(testData);\r\n \r\n // Simulate packet padding\r\n const paddingSize = Math.floor(Math.random() * (securityManager.paddingConfig.maxPadding - securityManager.paddingConfig.minPadding)) + securityManager.paddingConfig.minPadding;\r\n const paddedData = new Uint8Array(testBuffer.byteLength + paddingSize);\r\n paddedData.set(new Uint8Array(testBuffer), 0);\r\n \r\n return paddedData.byteLength >= testBuffer.byteLength + securityManager.paddingConfig.minPadding;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Packet padding verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n static async verifyAdvancedFeatures(securityManager) {\r\n try {\r\n // Test advanced features like traffic obfuscation, fake traffic, etc.\r\n const hasFakeTraffic = securityManager.fakeTrafficConfig && securityManager.fakeTrafficConfig.enabled;\r\n const hasDecoyChannels = securityManager.decoyChannelsConfig && securityManager.decoyChannelsConfig.enabled;\r\n const hasAntiFingerprinting = securityManager.antiFingerprintingConfig && securityManager.antiFingerprintingConfig.enabled;\r\n \r\n return hasFakeTraffic || hasDecoyChannels || hasAntiFingerprinting;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Advanced features verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n static async verifyMutualAuth(securityManager) {\r\n try {\r\n if (!securityManager.isVerified || !securityManager.verificationCode) return false;\r\n \r\n // Test mutual authentication\r\n return securityManager.isVerified && securityManager.verificationCode.length > 0;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Mutual auth verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n \r\n static async verifyNonExtractableKeys(securityManager) {\r\n try {\r\n if (!securityManager.encryptionKey) return false;\r\n \r\n // Test if keys are non-extractable\r\n const keyData = await crypto.subtle.exportKey('raw', securityManager.encryptionKey);\r\n return keyData && keyData.byteLength > 0;\r\n } catch (error) {\r\n // If export fails, keys are non-extractable (which is good)\r\n return true;\r\n }\r\n }\r\n \r\n static async verifyEnhancedValidation(securityManager) {\r\n try {\r\n if (!securityManager.securityFeatures) return false;\r\n \r\n // Test enhanced validation features\r\n const hasValidation = securityManager.securityFeatures.hasEnhancedValidation || \r\n securityManager.securityFeatures.hasEnhancedReplayProtection;\r\n \r\n return hasValidation;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Enhanced validation verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n \r\n \r\n static async verifyPFS(securityManager) {\r\n try {\r\n // Check if PFS is active\r\n return securityManager.securityFeatures &&\r\n securityManager.securityFeatures.hasPFS === true &&\r\n securityManager.keyRotationInterval &&\r\n securityManager.currentKeyVersion !== undefined &&\r\n securityManager.keyVersions &&\r\n securityManager.keyVersions instanceof Map;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'PFS verification failed', { error: error.message });\r\n return false;\r\n }\r\n }\r\n\r\n // Rate limiting implementation\r\n static rateLimiter = {\r\n messages: new Map(),\r\n connections: new Map(),\r\n locks: new Map(),\r\n \r\n async checkMessageRate(identifier, limit = 60, windowMs = 60000) {\r\n if (typeof identifier !== 'string' || identifier.length > 256) {\r\n return false;\r\n }\r\n \r\n const key = `msg_${identifier}`;\r\n\r\n if (this.locks.has(key)) {\r\n\r\n await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10) + 5));\r\n return this.checkMessageRate(identifier, limit, windowMs);\r\n }\r\n \r\n this.locks.set(key, true);\r\n \r\n try {\r\n const now = Date.now();\r\n \r\n if (!this.messages.has(key)) {\r\n this.messages.set(key, []);\r\n }\r\n \r\n const timestamps = this.messages.get(key);\r\n \r\n const validTimestamps = timestamps.filter(ts => now - ts < windowMs);\r\n \r\n if (validTimestamps.length >= limit) {\r\n return false; \r\n }\r\n \r\n validTimestamps.push(now);\r\n this.messages.set(key, validTimestamps);\r\n return true;\r\n } finally {\r\n this.locks.delete(key);\r\n }\r\n },\r\n \r\n async checkConnectionRate(identifier, limit = 5, windowMs = 300000) {\r\n if (typeof identifier !== 'string' || identifier.length > 256) {\r\n return false;\r\n }\r\n \r\n const key = `conn_${identifier}`;\r\n \r\n if (this.locks.has(key)) {\r\n await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 10) + 5));\r\n return this.checkConnectionRate(identifier, limit, windowMs);\r\n }\r\n \r\n this.locks.set(key, true);\r\n \r\n try {\r\n const now = Date.now();\r\n \r\n if (!this.connections.has(key)) {\r\n this.connections.set(key, []);\r\n }\r\n \r\n const timestamps = this.connections.get(key);\r\n const validTimestamps = timestamps.filter(ts => now - ts < windowMs);\r\n \r\n if (validTimestamps.length >= limit) {\r\n return false;\r\n }\r\n \r\n validTimestamps.push(now);\r\n this.connections.set(key, validTimestamps);\r\n return true;\r\n } finally {\r\n this.locks.delete(key);\r\n }\r\n },\r\n \r\n cleanup() {\r\n const now = Date.now();\r\n const maxAge = 3600000; \r\n \r\n for (const [key, timestamps] of this.messages.entries()) {\r\n if (this.locks.has(key)) continue;\r\n \r\n const valid = timestamps.filter(ts => now - ts < maxAge);\r\n if (valid.length === 0) {\r\n this.messages.delete(key);\r\n } else {\r\n this.messages.set(key, valid);\r\n }\r\n }\r\n \r\n for (const [key, timestamps] of this.connections.entries()) {\r\n if (this.locks.has(key)) continue;\r\n \r\n const valid = timestamps.filter(ts => now - ts < maxAge);\r\n if (valid.length === 0) {\r\n this.connections.delete(key);\r\n } else {\r\n this.connections.set(key, valid);\r\n }\r\n }\r\n\r\n for (const lockKey of this.locks.keys()) {\r\n const keyTimestamp = parseInt(lockKey.split('_').pop()) || 0;\r\n if (now - keyTimestamp > 30000) {\r\n this.locks.delete(lockKey);\r\n }\r\n }\r\n }\r\n};\r\n\r\n static validateSalt(salt) {\r\n if (!salt || salt.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes');\r\n }\r\n \r\n const uniqueBytes = new Set(salt);\r\n if (uniqueBytes.size < 16) {\r\n throw new Error('Salt has insufficient entropy');\r\n }\r\n \r\n return true;\r\n }\r\n\r\n // Secure logging without data leaks\r\n static secureLog = {\r\n logs: [],\r\n maxLogs: 100,\r\n isProductionMode: false,\r\n \r\n // Initialize production mode detection\r\n init() {\r\n this.isProductionMode = this._detectProductionMode();\r\n if (this.isProductionMode) {\r\n console.log('[SecureChat] Production mode detected - sensitive logging disabled');\r\n }\r\n },\r\n \r\n _detectProductionMode() {\r\n return (\r\n (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') ||\r\n (!window.DEBUG_MODE && !window.DEVELOPMENT_MODE) ||\r\n (window.location.hostname && !window.location.hostname.includes('localhost') && \r\n !window.location.hostname.includes('127.0.0.1') && \r\n !window.location.hostname.includes('.local')) ||\r\n (typeof window.webpackHotUpdate === 'undefined' && !window.location.search.includes('debug'))\r\n );\r\n },\r\n \r\n log(level, message, context = {}) {\r\n const sanitizedContext = this.sanitizeContext(context);\r\n const logEntry = {\r\n timestamp: Date.now(),\r\n level,\r\n message,\r\n context: sanitizedContext,\r\n id: crypto.getRandomValues(new Uint32Array(1))[0]\r\n };\r\n \r\n this.logs.push(logEntry);\r\n \r\n // Keep only recent logs\r\n if (this.logs.length > this.maxLogs) {\r\n this.logs = this.logs.slice(-this.maxLogs);\r\n }\r\n \r\n // Production-safe console output\r\n if (this.isProductionMode) {\r\n if (level === 'error') {\r\n // \u0412 production \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u043A\u043E\u0434 \u043E\u0448\u0438\u0431\u043A\u0438 \u0431\u0435\u0437 \u0434\u0435\u0442\u0430\u043B\u0435\u0439\r\n console.error(`\u274C [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]`);\r\n // \u0412\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0434\u0435\u0442\u0430\u043B\u0438 \u0434\u043B\u044F \u043E\u0442\u043B\u0430\u0434\u043A\u0438\r\n if (context && Object.keys(context).length > 0) {\r\n console.error('Error details:', context);\r\n }\r\n } else if (level === 'warn') {\r\n // \u0412 production \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435 \u0431\u0435\u0437 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430\r\n console.warn(`\u26A0\uFE0F [SecureChat] ${message}`);\r\n } else if (level === 'info' || level === 'debug') {\r\n // \u0412\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C info/debug \u043B\u043E\u0433\u0438 \u0434\u043B\u044F \u043E\u0442\u043B\u0430\u0434\u043A\u0438\r\n console.log(`[SecureChat] ${message}`, context);\r\n } else {\r\n // \u0412 production \u043D\u0435 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0434\u0440\u0443\u0433\u0438\u0435 \u043B\u043E\u0433\u0438\r\n return;\r\n }\r\n } else {\r\n // Development mode - \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0432\u0441\u0435\r\n if (level === 'error') {\r\n console.error(`\u274C [SecureChat] ${message}`, { errorType: sanitizedContext?.constructor?.name || 'Unknown' });\r\n } else if (level === 'warn') {\r\n console.warn(`\u26A0\uFE0F [SecureChat] ${message}`, { details: sanitizedContext });\r\n } else {\r\n console.log(`[SecureChat] ${message}`, sanitizedContext);\r\n }\r\n }\r\n },\r\n \r\n // \u0413\u0435\u043D\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439 \u043A\u043E\u0434 \u043E\u0448\u0438\u0431\u043A\u0438 \u0434\u043B\u044F production\r\n _generateErrorCode(message) {\r\n const hash = message.split('').reduce((a, b) => {\r\n a = ((a << 5) - a) + b.charCodeAt(0);\r\n return a & a;\r\n }, 0);\r\n return Math.abs(hash).toString(36).substring(0, 6).toUpperCase();\r\n },\r\n \r\n sanitizeContext(context) {\r\n if (!context || typeof context !== 'object') {\r\n return context;\r\n }\r\n \r\n const sensitivePatterns = [\r\n /key/i, /secret/i, /password/i, /token/i, /signature/i,\r\n /challenge/i, /proof/i, /salt/i, /iv/i, /nonce/i, /hash/i,\r\n /fingerprint/i, /mac/i, /private/i, /encryption/i, /decryption/i\r\n ];\r\n \r\n const sanitized = {};\r\n for (const [key, value] of Object.entries(context)) {\r\n const isSensitive = sensitivePatterns.some(pattern => \r\n pattern.test(key) || (typeof value === 'string' && pattern.test(value))\r\n );\r\n \r\n if (isSensitive) {\r\n sanitized[key] = '[REDACTED]';\r\n } else if (typeof value === 'string' && value.length > 100) {\r\n sanitized[key] = value.substring(0, 100) + '...[TRUNCATED]';\r\n } else if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\r\n sanitized[key] = `[${value.constructor.name}(${value.byteLength || value.length} bytes)]`;\r\n } else if (value && typeof value === 'object' && !Array.isArray(value)) {\r\n // \u0420\u0435\u043A\u0443\u0440\u0441\u0438\u0432\u043D\u0430\u044F \u0441\u0430\u043D\u0438\u0442\u0438\u0437\u0430\u0446\u0438\u044F \u0434\u043B\u044F \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432\r\n sanitized[key] = this.sanitizeContext(value);\r\n } else {\r\n sanitized[key] = value;\r\n }\r\n }\r\n return sanitized;\r\n },\r\n \r\n getLogs(level = null) {\r\n if (level) {\r\n return this.logs.filter(log => log.level === level);\r\n }\r\n return [...this.logs];\r\n },\r\n \r\n clearLogs() {\r\n this.logs = [];\r\n },\r\n \r\n // \u041C\u0435\u0442\u043E\u0434 \u0434\u043B\u044F \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438 \u043E\u0448\u0438\u0431\u043E\u043A \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 production\r\n async sendErrorToServer(errorCode, message, context = {}) {\r\n if (!this.isProductionMode) {\r\n return; // \u0412 development \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C\r\n }\r\n \r\n try {\r\n // \u041E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u0443\u044E \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E\r\n const safeErrorData = {\r\n errorCode,\r\n timestamp: Date.now(),\r\n userAgent: navigator.userAgent.substring(0, 100),\r\n url: window.location.href.substring(0, 100)\r\n };\r\n \r\n // \u0417\u0434\u0435\u0441\u044C \u043C\u043E\u0436\u043D\u043E \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0443 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\r\n // await fetch('/api/error-log', { method: 'POST', body: JSON.stringify(safeErrorData) });\r\n \r\n if (window.DEBUG_MODE) {\r\n console.log('[SecureChat] Error logged to server:', safeErrorData);\r\n }\r\n } catch (e) {\r\n // \u041D\u0435 \u043B\u043E\u0433\u0438\u0440\u0443\u0435\u043C \u043E\u0448\u0438\u0431\u043A\u0438 \u043B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\r\n }\r\n }\r\n };\r\n\r\n // Generate ECDH key pair for secure key exchange (non-extractable) with fallback\r\n static async generateECDHKeyPair() {\r\n try {\r\n // Try P-384 first\r\n try {\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['deriveKey']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDH key pair generated successfully (P-384)', {\r\n curve: 'P-384',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 generation failed, trying P-256', { error: p384Error.message });\r\n \r\n // Fallback to P-256\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['deriveKey']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDH key pair generated successfully (P-256 fallback)', {\r\n curve: 'P-256',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDH key generation failed', { error: error.message });\r\n throw new Error('Failed to create keys for secure exchange');\r\n }\r\n }\r\n\r\n // Generate ECDSA key pair for digital signatures with fallback\r\n static async generateECDSAKeyPair() {\r\n try {\r\n // Try P-384 first\r\n try {\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['sign', 'verify']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDSA key pair generated successfully (P-384)', {\r\n curve: 'P-384',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 generation failed, trying P-256', { error: p384Error.message });\r\n \r\n // Fallback to P-256\r\n const keyPair = await crypto.subtle.generateKey(\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['sign', 'verify']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'ECDSA key pair generated successfully (P-256 fallback)', {\r\n curve: 'P-256',\r\n extractable: false\r\n });\r\n \r\n return keyPair;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDSA key generation failed', { error: error.message });\r\n throw new Error('Failed to generate keys for digital signatures');\r\n }\r\n }\r\n\r\n // Sign data with ECDSA (P-384 or P-256)\r\n static async signData(privateKey, data) {\r\n try {\r\n const encoder = new TextEncoder();\r\n const dataBuffer = typeof data === 'string' ? encoder.encode(data) : data;\r\n \r\n // Try SHA-384 first, fallback to SHA-256\r\n try {\r\n const signature = await crypto.subtle.sign(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-384'\r\n },\r\n privateKey,\r\n dataBuffer\r\n );\r\n \r\n return Array.from(new Uint8Array(signature));\r\n } catch (sha384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'SHA-384 signing failed, trying SHA-256', { error: sha384Error.message });\r\n \r\n const signature = await crypto.subtle.sign(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-256'\r\n },\r\n privateKey,\r\n dataBuffer\r\n );\r\n \r\n return Array.from(new Uint8Array(signature));\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Data signing failed', { error: error.message });\r\n throw new Error('Failed to sign data');\r\n }\r\n }\r\n\r\n // Verify ECDSA signature (P-384 or P-256)\r\n static async verifySignature(publicKey, signature, data) {\r\n try {\r\n console.log('DEBUG: verifySignature called with:', {\r\n publicKey: publicKey,\r\n signature: signature,\r\n data: data\r\n });\r\n \r\n const encoder = new TextEncoder();\r\n const dataBuffer = typeof data === 'string' ? encoder.encode(data) : data;\r\n const signatureBuffer = new Uint8Array(signature);\r\n \r\n console.log('DEBUG: verifySignature dataBuffer:', dataBuffer);\r\n console.log('DEBUG: verifySignature signatureBuffer:', signatureBuffer);\r\n \r\n // Try SHA-384 first, fallback to SHA-256\r\n try {\r\n console.log('DEBUG: Trying SHA-384 verification...');\r\n const isValid = await crypto.subtle.verify(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-384'\r\n },\r\n publicKey,\r\n signatureBuffer,\r\n dataBuffer\r\n );\r\n \r\n console.log('DEBUG: SHA-384 verification result:', isValid);\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signature verification completed (SHA-384)', {\r\n isValid,\r\n dataSize: dataBuffer.length\r\n });\r\n \r\n return isValid;\r\n } catch (sha384Error) {\r\n console.log('DEBUG: SHA-384 verification failed, trying SHA-256:', sha384Error);\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'SHA-384 verification failed, trying SHA-256', { error: sha384Error.message });\r\n \r\n console.log('DEBUG: Trying SHA-256 verification...');\r\n const isValid = await crypto.subtle.verify(\r\n {\r\n name: 'ECDSA',\r\n hash: 'SHA-256'\r\n },\r\n publicKey,\r\n signatureBuffer,\r\n dataBuffer\r\n );\r\n \r\n console.log('DEBUG: SHA-256 verification result:', isValid);\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signature verification completed (SHA-256 fallback)', {\r\n isValid,\r\n dataSize: dataBuffer.length\r\n });\r\n \r\n return isValid;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Signature verification failed', { error: error.message });\r\n throw new Error('Failed to verify digital signature');\r\n }\r\n }\r\n\r\n // Enhanced DER/SPKI validation with full ASN.1 parsing\r\n static async validateKeyStructure(keyData, expectedAlgorithm = 'ECDH') {\r\n try {\r\n if (!Array.isArray(keyData) || keyData.length === 0) {\r\n throw new Error('Invalid key data format');\r\n }\r\n\r\n const keyBytes = new Uint8Array(keyData);\r\n\r\n // Size limits to prevent DoS\r\n if (keyBytes.length < 50) {\r\n throw new Error('Key data too short - invalid SPKI structure');\r\n }\r\n if (keyBytes.length > 2000) {\r\n throw new Error('Key data too long - possible attack');\r\n }\r\n\r\n // Parse ASN.1 DER structure\r\n const asn1 = EnhancedSecureCryptoUtils.parseASN1(keyBytes);\r\n \r\n // Validate SPKI structure\r\n if (!asn1 || asn1.tag !== 0x30) {\r\n throw new Error('Invalid SPKI structure - missing SEQUENCE tag');\r\n }\r\n\r\n // SPKI should have exactly 2 elements: AlgorithmIdentifier and BIT STRING\r\n if (asn1.children.length !== 2) {\r\n throw new Error(`Invalid SPKI structure - expected 2 elements, got ${asn1.children.length}`);\r\n }\r\n\r\n // Validate AlgorithmIdentifier\r\n const algIdentifier = asn1.children[0];\r\n if (algIdentifier.tag !== 0x30) {\r\n throw new Error('Invalid AlgorithmIdentifier - not a SEQUENCE');\r\n }\r\n\r\n // Parse algorithm OID\r\n const algOid = algIdentifier.children[0];\r\n if (algOid.tag !== 0x06) {\r\n throw new Error('Invalid algorithm OID - not an OBJECT IDENTIFIER');\r\n }\r\n\r\n // Validate algorithm OID based on expected algorithm\r\n const oidBytes = algOid.value;\r\n const oidString = EnhancedSecureCryptoUtils.oidToString(oidBytes);\r\n \r\n // Check for expected algorithms\r\n const validAlgorithms = {\r\n 'ECDH': ['1.2.840.10045.2.1'], // id-ecPublicKey\r\n 'ECDSA': ['1.2.840.10045.2.1'], // id-ecPublicKey (same as ECDH)\r\n 'RSA': ['1.2.840.113549.1.1.1'], // rsaEncryption\r\n 'AES-GCM': ['2.16.840.1.101.3.4.1.6', '2.16.840.1.101.3.4.1.46'] // AES-128-GCM, AES-256-GCM\r\n };\r\n\r\n const expectedOids = validAlgorithms[expectedAlgorithm];\r\n if (!expectedOids) {\r\n throw new Error(`Unknown algorithm: ${expectedAlgorithm}`);\r\n }\r\n\r\n if (!expectedOids.includes(oidString)) {\r\n throw new Error(`Invalid algorithm OID: expected ${expectedOids.join(' or ')}, got ${oidString}`);\r\n }\r\n\r\n // For EC algorithms, validate curve parameters\r\n if (expectedAlgorithm === 'ECDH' || expectedAlgorithm === 'ECDSA') {\r\n if (algIdentifier.children.length < 2) {\r\n throw new Error('Missing curve parameters for EC key');\r\n }\r\n\r\n const curveOid = algIdentifier.children[1];\r\n if (curveOid.tag !== 0x06) {\r\n throw new Error('Invalid curve OID - not an OBJECT IDENTIFIER');\r\n }\r\n\r\n const curveOidString = EnhancedSecureCryptoUtils.oidToString(curveOid.value);\r\n \r\n // Only allow P-256 and P-384 curves\r\n const validCurves = {\r\n '1.2.840.10045.3.1.7': 'P-256', // secp256r1\r\n '1.3.132.0.34': 'P-384' // secp384r1\r\n };\r\n\r\n if (!validCurves[curveOidString]) {\r\n throw new Error(`Invalid or unsupported curve OID: ${curveOidString}`);\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'EC key curve validated', {\r\n curve: validCurves[curveOidString],\r\n oid: curveOidString\r\n });\r\n }\r\n\r\n // Validate public key BIT STRING\r\n const publicKeyBitString = asn1.children[1];\r\n if (publicKeyBitString.tag !== 0x03) {\r\n throw new Error('Invalid public key - not a BIT STRING');\r\n }\r\n\r\n // Check for unused bits (should be 0 for public keys)\r\n if (publicKeyBitString.value[0] !== 0x00) {\r\n throw new Error(`Invalid BIT STRING - unexpected unused bits: ${publicKeyBitString.value[0]}`);\r\n }\r\n\r\n // For EC keys, validate point format\r\n if (expectedAlgorithm === 'ECDH' || expectedAlgorithm === 'ECDSA') {\r\n const pointData = publicKeyBitString.value.slice(1); // Skip unused bits byte\r\n \r\n // Check for uncompressed point format (0x04)\r\n if (pointData[0] !== 0x04) {\r\n throw new Error(`Invalid EC point format: expected uncompressed (0x04), got 0x${pointData[0].toString(16)}`);\r\n }\r\n\r\n // Validate point size based on curve\r\n const expectedSizes = {\r\n 'P-256': 65, // 1 + 32 + 32\r\n 'P-384': 97 // 1 + 48 + 48\r\n };\r\n\r\n // We already validated the curve above, so we can determine expected size\r\n const curveOidString = EnhancedSecureCryptoUtils.oidToString(algIdentifier.children[1].value);\r\n const curveName = curveOidString === '1.2.840.10045.3.1.7' ? 'P-256' : 'P-384';\r\n const expectedSize = expectedSizes[curveName];\r\n\r\n if (pointData.length !== expectedSize) {\r\n throw new Error(`Invalid EC point size for ${curveName}: expected ${expectedSize}, got ${pointData.length}`);\r\n }\r\n }\r\n\r\n // Additional validation: try to import the key\r\n try {\r\n const algorithm = expectedAlgorithm === 'ECDSA' || expectedAlgorithm === 'ECDH'\r\n ? { name: expectedAlgorithm, namedCurve: 'P-384' }\r\n : { name: expectedAlgorithm };\r\n\r\n const usages = expectedAlgorithm === 'ECDSA' ? ['verify'] : [];\r\n \r\n await crypto.subtle.importKey('spki', keyBytes.buffer, algorithm, false, usages);\r\n } catch (importError) {\r\n // Try P-256 as fallback for EC keys\r\n if (expectedAlgorithm === 'ECDSA' || expectedAlgorithm === 'ECDH') {\r\n try {\r\n const algorithm = { name: expectedAlgorithm, namedCurve: 'P-256' };\r\n const usages = expectedAlgorithm === 'ECDSA' ? ['verify'] : [];\r\n await crypto.subtle.importKey('spki', keyBytes.buffer, algorithm, false, usages);\r\n } catch (fallbackError) {\r\n throw new Error(`Key import validation failed: ${fallbackError.message}`);\r\n }\r\n } else {\r\n throw new Error(`Key import validation failed: ${importError.message}`);\r\n }\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Key structure validation passed', {\r\n keyLen: keyBytes.length,\r\n algorithm: expectedAlgorithm,\r\n asn1Valid: true,\r\n oidValid: true,\r\n importValid: true\r\n });\r\n\r\n return true;\r\n } catch (err) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Key structure validation failed', {\r\n error: err.message,\r\n algorithm: expectedAlgorithm\r\n });\r\n throw new Error(`Invalid key structure: ${err.message}`);\r\n }\r\n }\r\n\r\n // ASN.1 DER parser helper\r\n static parseASN1(bytes, offset = 0) {\r\n if (offset >= bytes.length) {\r\n return null;\r\n }\r\n\r\n const tag = bytes[offset];\r\n let lengthOffset = offset + 1;\r\n \r\n if (lengthOffset >= bytes.length) {\r\n throw new Error('Truncated ASN.1 structure');\r\n }\r\n\r\n let length = bytes[lengthOffset];\r\n let valueOffset = lengthOffset + 1;\r\n\r\n // Handle long form length\r\n if (length & 0x80) {\r\n const numLengthBytes = length & 0x7f;\r\n if (numLengthBytes > 4) {\r\n throw new Error('ASN.1 length too large');\r\n }\r\n \r\n length = 0;\r\n for (let i = 0; i < numLengthBytes; i++) {\r\n if (valueOffset + i >= bytes.length) {\r\n throw new Error('Truncated ASN.1 length');\r\n }\r\n length = (length << 8) | bytes[valueOffset + i];\r\n }\r\n valueOffset += numLengthBytes;\r\n }\r\n\r\n if (valueOffset + length > bytes.length) {\r\n throw new Error('ASN.1 structure extends beyond data');\r\n }\r\n\r\n const value = bytes.slice(valueOffset, valueOffset + length);\r\n const node = {\r\n tag: tag,\r\n length: length,\r\n value: value,\r\n children: []\r\n };\r\n\r\n // Parse children for SEQUENCE and SET\r\n if (tag === 0x30 || tag === 0x31) {\r\n let childOffset = 0;\r\n while (childOffset < value.length) {\r\n const child = EnhancedSecureCryptoUtils.parseASN1(value, childOffset);\r\n if (!child) break;\r\n node.children.push(child);\r\n childOffset = childOffset + 1 + child.lengthBytes + child.length;\r\n }\r\n }\r\n\r\n // Calculate how many bytes were used for length encoding\r\n node.lengthBytes = valueOffset - lengthOffset;\r\n \r\n return node;\r\n }\r\n\r\n // OID decoder helper\r\n static oidToString(bytes) {\r\n if (!bytes || bytes.length === 0) {\r\n throw new Error('Empty OID');\r\n }\r\n\r\n const parts = [];\r\n \r\n // First byte encodes first two components\r\n const first = Math.floor(bytes[0] / 40);\r\n const second = bytes[0] % 40;\r\n parts.push(first);\r\n parts.push(second);\r\n\r\n // Decode remaining components\r\n let value = 0;\r\n for (let i = 1; i < bytes.length; i++) {\r\n value = (value << 7) | (bytes[i] & 0x7f);\r\n if (!(bytes[i] & 0x80)) {\r\n parts.push(value);\r\n value = 0;\r\n }\r\n }\r\n\r\n return parts.join('.');\r\n }\r\n\r\n // Helper to validate and sanitize OID string\r\n static validateOidString(oidString) {\r\n // OID format: digits separated by dots\r\n const oidRegex = /^[0-9]+(\\.[0-9]+)*$/;\r\n if (!oidRegex.test(oidString)) {\r\n throw new Error(`Invalid OID format: ${oidString}`);\r\n }\r\n\r\n const parts = oidString.split('.').map(Number);\r\n \r\n // First component must be 0, 1, or 2\r\n if (parts[0] > 2) {\r\n throw new Error(`Invalid OID first component: ${parts[0]}`);\r\n }\r\n\r\n // If first component is 0 or 1, second must be <= 39\r\n if ((parts[0] === 0 || parts[0] === 1) && parts[1] > 39) {\r\n throw new Error(`Invalid OID second component: ${parts[1]} (must be <= 39 for first component ${parts[0]})`);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Export public key for transmission with signature \r\n static async exportPublicKeyWithSignature(publicKey, signingKey, keyType = 'ECDH') {\r\n try {\r\n // Validate key type\r\n if (!['ECDH', 'ECDSA'].includes(keyType)) {\r\n throw new Error('Invalid key type');\r\n }\r\n \r\n const exported = await crypto.subtle.exportKey('spki', publicKey);\r\n const keyData = Array.from(new Uint8Array(exported));\r\n \r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, keyType);\r\n \r\n // Create signed key package\r\n const keyPackage = {\r\n keyType,\r\n keyData,\r\n timestamp: Date.now(),\r\n version: '4.0'\r\n };\r\n \r\n // Sign the key package\r\n const packageString = JSON.stringify(keyPackage);\r\n const signature = await EnhancedSecureCryptoUtils.signData(signingKey, packageString);\r\n \r\n const signedPackage = {\r\n ...keyPackage,\r\n signature\r\n };\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Public key exported with signature', {\r\n keyType,\r\n keySize: keyData.length,\r\n signed: true\r\n });\r\n \r\n return signedPackage;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Public key export failed', {\r\n error: error.message,\r\n keyType\r\n });\r\n throw new Error(`Failed to export ${keyType} key: ${error.message}`);\r\n }\r\n }\r\n\r\n // Import and verify signed public key\r\n static async importSignedPublicKey(signedPackage, verifyingKey, expectedKeyType = 'ECDH') {\r\n try {\r\n console.log('DEBUG: importSignedPublicKey called with:', {\r\n signedPackage: signedPackage,\r\n verifyingKey: verifyingKey,\r\n expectedKeyType: expectedKeyType\r\n });\r\n \r\n // Validate package structure\r\n if (!signedPackage || typeof signedPackage !== 'object') {\r\n throw new Error('Invalid signed package format');\r\n }\r\n \r\n const { keyType, keyData, timestamp, version, signature } = signedPackage;\r\n \r\n if (!keyType || !keyData || !timestamp || !signature) {\r\n throw new Error('Missing required fields in signed package');\r\n }\r\n \r\n if (!EnhancedSecureCryptoUtils.constantTimeCompare(keyType, expectedKeyType)) {\r\n throw new Error(`Key type mismatch: expected ${expectedKeyType}, got ${keyType}`);\r\n }\r\n \r\n // Check timestamp (reject keys older than 1 hour)\r\n const keyAge = Date.now() - timestamp;\r\n if (keyAge > 3600000) {\r\n throw new Error('Signed key package is too old');\r\n }\r\n \r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, keyType);\r\n \r\n // Verify signature\r\n const packageCopy = { keyType, keyData, timestamp, version };\r\n const packageString = JSON.stringify(packageCopy);\r\n console.log('DEBUG: Web version package string for verification:', packageString);\r\n console.log('DEBUG: Web version signature to verify:', signature);\r\n console.log('DEBUG: Web version verifying key:', verifyingKey);\r\n const isValidSignature = await EnhancedSecureCryptoUtils.verifySignature(verifyingKey, signature, packageString);\r\n console.log('DEBUG: Web version signature verification result:', isValidSignature);\r\n \r\n if (!isValidSignature) {\r\n throw new Error('Invalid signature on key package - possible MITM attack');\r\n }\r\n \r\n // Import the key with fallback support\r\n const keyBytes = new Uint8Array(keyData);\r\n \r\n // Try P-384 first\r\n try {\r\n const algorithm = keyType === 'ECDH' ?\r\n { name: 'ECDH', namedCurve: 'P-384' }\r\n : { name: 'ECDSA', namedCurve: 'P-384' };\r\n \r\n const keyUsages = keyType === 'ECDH' ? [] : ['verify'];\r\n \r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n algorithm,\r\n false, // Non-extractable\r\n keyUsages\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signed public key imported successfully (P-384)', {\r\n keyType,\r\n signatureValid: true,\r\n keyAge: Math.round(keyAge / 1000) + 's'\r\n });\r\n \r\n return publicKey;\r\n } catch (p384Error) {\r\n // Fallback to P-256\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 import failed, trying P-256', {\r\n error: p384Error.message\r\n });\r\n \r\n const algorithm = keyType === 'ECDH' ?\r\n { name: 'ECDH', namedCurve: 'P-256' }\r\n : { name: 'ECDSA', namedCurve: 'P-256' };\r\n \r\n const keyUsages = keyType === 'ECDH' ? [] : ['verify'];\r\n \r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n algorithm,\r\n false, // Non-extractable\r\n keyUsages\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Signed public key imported successfully (P-256 fallback)', {\r\n keyType,\r\n signatureValid: true,\r\n keyAge: Math.round(keyAge / 1000) + 's'\r\n });\r\n \r\n return publicKey;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Signed public key import failed', {\r\n error: error.message,\r\n expectedKeyType\r\n });\r\n throw new Error(`Failed to import the signed key: ${error.message}`);\r\n }\r\n }\r\n\r\n // Legacy export for backward compatibility\r\n static async exportPublicKey(publicKey) {\r\n try {\r\n const exported = await crypto.subtle.exportKey('spki', publicKey);\r\n const keyData = Array.from(new Uint8Array(exported));\r\n \r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, 'ECDH');\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Legacy public key exported', { keySize: keyData.length });\r\n return keyData;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Legacy public key export failed', { error: error.message });\r\n throw new Error('Failed to export the public key');\r\n }\r\n }\r\n\r\n // Legacy import for backward compatibility with fallback\r\n static async importPublicKey(keyData) {\r\n try {\r\n await EnhancedSecureCryptoUtils.validateKeyStructure(keyData, 'ECDH');\r\n \r\n const keyBytes = new Uint8Array(keyData);\r\n \r\n // Try P-384 first\r\n try {\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable\r\n []\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Legacy public key imported (P-384)', { keySize: keyData.length });\r\n return publicKey;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 import failed, trying P-256', { error: p384Error.message });\r\n \r\n // Fallback to P-256\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: 'ECDH',\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable\r\n []\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Legacy public key imported (P-256 fallback)', { keySize: keyData.length });\r\n return publicKey;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Legacy public key import failed', { error: error.message });\r\n throw new Error('Failed to import the public key');\r\n }\r\n }\r\n\r\n\r\n // Method to check if a key is trusted\r\n static isKeyTrusted(keyOrFingerprint) {\r\n if (keyOrFingerprint instanceof CryptoKey) {\r\n const meta = EnhancedSecureCryptoUtils._keyMetadata.get(keyOrFingerprint);\r\n return meta ? meta.trusted === true : false;\r\n } else if (keyOrFingerprint && keyOrFingerprint._securityMetadata) {\r\n // Check by key metadata\r\n return keyOrFingerprint._securityMetadata.trusted === true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n static async importPublicKeyFromSignedPackage(signedPackage, verifyingKey = null, options = {}) {\r\n try {\r\n if (!signedPackage || !signedPackage.keyData || !signedPackage.signature) {\r\n throw new Error('Invalid signed key package format');\r\n }\r\n\r\n // Validate all required fields are present\r\n const requiredFields = ['keyData', 'signature', 'keyType', 'timestamp', 'version'];\r\n const missingFields = requiredFields.filter(field => !signedPackage[field]);\r\n\r\n if (missingFields.length > 0) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Missing required fields in signed package', {\r\n missingFields: missingFields,\r\n availableFields: Object.keys(signedPackage)\r\n });\r\n throw new Error(`Required fields are missing in the signed package: ${missingFields.join(', ')}`);\r\n }\r\n\r\n // SECURITY ENHANCEMENT: MANDATORY signature verification for signed packages\r\n if (!verifyingKey) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'SECURITY VIOLATION: Signed package received without verifying key', {\r\n keyType: signedPackage.keyType,\r\n keySize: signedPackage.keyData.length,\r\n timestamp: signedPackage.timestamp,\r\n version: signedPackage.version,\r\n securityRisk: 'HIGH - Potential MITM attack vector'\r\n });\r\n\r\n // REJECT the signed package if no verifying key provided\r\n throw new Error('CRITICAL SECURITY ERROR: Signed key package received without a verification key. ' +\r\n 'This may indicate a possible MITM attack attempt. Import rejected for security reasons.');\r\n }\r\n\r\n // \u041E\u0411\u041D\u041E\u0412\u041B\u0415\u041D\u041E: \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u043D\u0443\u044E \u0432\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u044E\r\n await EnhancedSecureCryptoUtils.validateKeyStructure(signedPackage.keyData, signedPackage.keyType || 'ECDH');\r\n\r\n // MANDATORY signature verification when verifyingKey is provided\r\n const packageCopy = { ...signedPackage };\r\n delete packageCopy.signature;\r\n const packageString = JSON.stringify(packageCopy);\r\n const isValidSignature = await EnhancedSecureCryptoUtils.verifySignature(verifyingKey, signedPackage.signature, packageString);\r\n\r\n if (!isValidSignature) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'SECURITY BREACH: Invalid signature detected - MITM attack prevented', {\r\n keyType: signedPackage.keyType,\r\n keySize: signedPackage.keyData.length,\r\n timestamp: signedPackage.timestamp,\r\n version: signedPackage.version,\r\n attackPrevented: true\r\n });\r\n throw new Error('CRITICAL SECURITY ERROR: Invalid key signature detected. ' +\r\n 'This indicates a possible MITM attack attempt. Key import rejected.');\r\n }\r\n\r\n // Additional MITM protection: Check for key reuse and suspicious patterns\r\n const keyFingerprint = await EnhancedSecureCryptoUtils.calculateKeyFingerprint(signedPackage.keyData);\r\n\r\n // Log successful verification with security details\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'SECURE: Signature verification passed for signed package', {\r\n keyType: signedPackage.keyType,\r\n keySize: signedPackage.keyData.length,\r\n timestamp: signedPackage.timestamp,\r\n version: signedPackage.version,\r\n signatureVerified: true,\r\n securityLevel: 'HIGH',\r\n keyFingerprint: keyFingerprint.substring(0, 8) // Only log first 8 chars for security\r\n });\r\n\r\n // Import the public key with fallback\r\n const keyBytes = new Uint8Array(signedPackage.keyData);\r\n const keyType = signedPackage.keyType || 'ECDH';\r\n\r\n // Try P-384 first\r\n try {\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: keyType,\r\n namedCurve: 'P-384'\r\n },\r\n false, // Non-extractable\r\n keyType === 'ECDSA' ? ['verify'] : []\r\n );\r\n\r\n // Use WeakMap to store metadata\r\n EnhancedSecureCryptoUtils._keyMetadata.set(publicKey, {\r\n trusted: true,\r\n verificationStatus: 'VERIFIED_SECURE',\r\n verificationTimestamp: Date.now()\r\n });\r\n\r\n return publicKey;\r\n } catch (p384Error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'P-384 import failed, trying P-256', { error: p384Error.message });\r\n\r\n // Fallback to P-256\r\n const publicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n keyBytes,\r\n {\r\n name: keyType,\r\n namedCurve: 'P-256'\r\n },\r\n false, // Non-extractable\r\n keyType === 'ECDSA' ? ['verify'] : []\r\n );\r\n\r\n // Use WeakMap to store metadata\r\n EnhancedSecureCryptoUtils._keyMetadata.set(publicKey, {\r\n trusted: true,\r\n verificationStatus: 'VERIFIED_SECURE',\r\n verificationTimestamp: Date.now()\r\n });\r\n\r\n return publicKey;\r\n }\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Signed package key import failed', {\r\n error: error.message,\r\n securityImplications: 'Potential security breach prevented'\r\n });\r\n throw new Error(`Failed to import the public key from the signed package: ${error.message}`);\r\n }\r\n }\r\n\r\n // Enhanced key derivation with metadata protection and 64-byte salt\r\n static async deriveSharedKeys(privateKey, publicKey, salt) {\r\n try {\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Starting key derivation', {\r\n privateKeyType: typeof privateKey,\r\n publicKeyType: typeof publicKey,\r\n saltLength: salt?.length,\r\n privateKeyAlgorithm: privateKey?.algorithm?.name,\r\n publicKeyAlgorithm: publicKey?.algorithm?.name,\r\n privateKeyUsages: privateKey?.usages,\r\n publicKeyUsages: publicKey?.usages\r\n });\r\n \r\n // Validate input parameters are CryptoKey instances\r\n if (!(privateKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Private key is not a CryptoKey', {\r\n privateKeyType: typeof privateKey,\r\n privateKeyAlgorithm: privateKey?.algorithm?.name\r\n });\r\n throw new Error('The private key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(publicKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Public key is not a CryptoKey', {\r\n publicKeyType: typeof publicKey,\r\n publicKeyAlgorithm: publicKey?.algorithm?.name\r\n });\r\n throw new Error('The public key is not a valid CryptoKey.');\r\n }\r\n \r\n // Validate salt size (should be 64 bytes for enhanced security)\r\n if (!salt || salt.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes for enhanced security');\r\n }\r\n \r\n const saltBytes = new Uint8Array(salt);\r\n const encoder = new TextEncoder();\r\n \r\n // Step 1: Derive raw ECDH shared secret using pure ECDH\r\n let rawSharedSecret;\r\n try {\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Step 1: Starting ECDH derivation');\r\n \r\n // Use pure ECDH to derive raw key material\r\n const rawKeyMaterial = await crypto.subtle.deriveKey(\r\n {\r\n name: 'ECDH',\r\n public: publicKey\r\n },\r\n privateKey,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n true, // Extractable\r\n ['encrypt', 'decrypt']\r\n );\r\n \r\n // Export the raw key material\r\n const rawKeyData = await crypto.subtle.exportKey('raw', rawKeyMaterial);\r\n \r\n // Import as HKDF key material for further derivation\r\n rawSharedSecret = await crypto.subtle.importKey(\r\n 'raw',\r\n rawKeyData,\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256'\r\n },\r\n false,\r\n ['deriveKey']\r\n );\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Step 1: ECDH derivation successful');\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDH derivation failed', { \r\n error: error.message\r\n });\r\n throw error;\r\n }\r\n \r\n // Step 2: Use HKDF to derive specific keys directly\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Step 2: Starting HKDF key derivation');\r\n\r\n // Step 3: Derive specific keys using HKDF with unique info parameters\r\n // Each key uses unique info parameter for proper separation\r\n \r\n // Derive message encryption key (messageKey)\r\n let messageKey;\r\n messageKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('message-encryption-v4')\r\n },\r\n rawSharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable for enhanced security\r\n ['encrypt', 'decrypt']\r\n );\r\n\r\n // Derive MAC key for message authentication\r\n let macKey;\r\n macKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('message-authentication-v4')\r\n },\r\n rawSharedSecret,\r\n {\r\n name: 'HMAC',\r\n hash: 'SHA-256'\r\n },\r\n false, // Non-extractable\r\n ['sign', 'verify']\r\n );\r\n\r\n // Derive Perfect Forward Secrecy key (pfsKey)\r\n let pfsKey;\r\n pfsKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('perfect-forward-secrecy-v4')\r\n },\r\n rawSharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable\r\n ['encrypt', 'decrypt']\r\n );\r\n\r\n // Derive separate metadata encryption key\r\n let metadataKey;\r\n metadataKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('metadata-protection-v4')\r\n },\r\n rawSharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // Non-extractable\r\n ['encrypt', 'decrypt']\r\n );\r\n\r\n // Generate temporary extractable key for fingerprint calculation\r\n let fingerprintKey;\r\n fingerprintKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'HKDF',\r\n hash: 'SHA-256',\r\n salt: saltBytes,\r\n info: encoder.encode('fingerprint-generation-v4')\r\n },\r\n rawSharedSecret,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n true, // Extractable only for fingerprint\r\n ['encrypt', 'decrypt']\r\n );\r\n\r\n // Generate key fingerprint for verification\r\n const fingerprintKeyData = await crypto.subtle.exportKey('raw', fingerprintKey);\r\n const fingerprint = await EnhancedSecureCryptoUtils.generateKeyFingerprint(Array.from(new Uint8Array(fingerprintKeyData)));\r\n\r\n // Validate that all derived keys are CryptoKey instances\r\n if (!(messageKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived message key is not a CryptoKey', {\r\n messageKeyType: typeof messageKey,\r\n messageKeyAlgorithm: messageKey?.algorithm?.name\r\n });\r\n throw new Error('The derived message key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(macKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived MAC key is not a CryptoKey', {\r\n macKeyType: typeof macKey,\r\n macKeyAlgorithm: macKey?.algorithm?.name\r\n });\r\n throw new Error('The derived MAC key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(pfsKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived PFS key is not a CryptoKey', {\r\n pfsKeyType: typeof pfsKey,\r\n pfsKeyAlgorithm: pfsKey?.algorithm?.name\r\n });\r\n throw new Error('The derived PFS key is not a valid CryptoKey.');\r\n }\r\n \r\n if (!(metadataKey instanceof CryptoKey)) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived metadata key is not a CryptoKey', {\r\n metadataKeyType: typeof metadataKey,\r\n metadataKeyAlgorithm: metadataKey?.algorithm?.name\r\n });\r\n throw new Error('The derived metadata key is not a valid CryptoKey.');\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Enhanced shared keys derived successfully with proper HKDF separation', {\r\n saltSize: salt.length,\r\n hasMessageKey: true,\r\n hasMacKey: true,\r\n hasPfsKey: true,\r\n hasMetadataKey: true,\r\n nonExtractable: true,\r\n version: '4.0',\r\n allKeysValid: true,\r\n hkdfProperlyImplemented: true\r\n });\r\n\r\n return {\r\n messageKey, // Renamed from encryptionKey for clarity\r\n macKey,\r\n pfsKey, // Added Perfect Forward Secrecy key\r\n metadataKey,\r\n fingerprint,\r\n timestamp: Date.now(),\r\n version: '4.0'\r\n };\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Enhanced key derivation failed', { \r\n error: error.message,\r\n errorStack: error.stack,\r\n privateKeyType: typeof privateKey,\r\n publicKeyType: typeof publicKey,\r\n saltLength: salt?.length,\r\n privateKeyAlgorithm: privateKey?.algorithm?.name,\r\n publicKeyAlgorithm: publicKey?.algorithm?.name\r\n });\r\n throw new Error(`Failed to create shared encryption keys: ${error.message}`);\r\n }\r\n }\r\n\r\n static async generateKeyFingerprint(keyData) {\r\n const keyBuffer = new Uint8Array(keyData);\r\n const hashBuffer = await crypto.subtle.digest('SHA-384', keyBuffer);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n return hashArray.slice(0, 12).map(b => b.toString(16).padStart(2, '0')).join(':');\r\n }\r\n\r\n // Generate mutual authentication challenge\r\n static generateMutualAuthChallenge() {\r\n const challenge = crypto.getRandomValues(new Uint8Array(48)); // Increased to 48 bytes\r\n const timestamp = Date.now();\r\n const nonce = crypto.getRandomValues(new Uint8Array(16));\r\n \r\n return {\r\n challenge: Array.from(challenge),\r\n timestamp,\r\n nonce: Array.from(nonce),\r\n version: '4.0'\r\n };\r\n }\r\n\r\n // Create cryptographic proof for mutual authentication\r\n static async createAuthProof(challenge, privateKey, publicKey) {\r\n try {\r\n if (!challenge || !challenge.challenge || !challenge.timestamp || !challenge.nonce) {\r\n throw new Error('Invalid challenge structure');\r\n }\r\n \r\n // Check challenge age (max 2 minutes)\r\n const challengeAge = Date.now() - challenge.timestamp;\r\n if (challengeAge > 120000) {\r\n throw new Error('Challenge expired');\r\n }\r\n \r\n // Create proof data\r\n const proofData = {\r\n challenge: challenge.challenge,\r\n timestamp: challenge.timestamp,\r\n nonce: challenge.nonce,\r\n responseTimestamp: Date.now(),\r\n publicKeyHash: await EnhancedSecureCryptoUtils.hashPublicKey(publicKey)\r\n };\r\n \r\n // Sign the proof\r\n const proofString = JSON.stringify(proofData);\r\n const signature = await EnhancedSecureCryptoUtils.signData(privateKey, proofString);\r\n \r\n const proof = {\r\n ...proofData,\r\n signature,\r\n version: '4.0'\r\n };\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Authentication proof created', {\r\n challengeAge: Math.round(challengeAge / 1000) + 's'\r\n });\r\n \r\n return proof;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Authentication proof creation failed', { error: error.message });\r\n throw new Error(`Failed to create cryptographic proof: ${error.message}`);\r\n }\r\n }\r\n\r\n // Verify mutual authentication proof\r\n static async verifyAuthProof(proof, challenge, publicKey) {\r\n try {\r\n await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 20) + 5));\r\n // Assert the public key is valid and has the correct usage\r\n EnhancedSecureCryptoUtils.assertCryptoKey(publicKey, 'ECDSA', ['verify']);\r\n\r\n if (!proof || !challenge || !publicKey) {\r\n throw new Error('Missing required parameters for proof verification');\r\n }\r\n\r\n // Validate proof structure\r\n const requiredFields = ['challenge', 'timestamp', 'nonce', 'responseTimestamp', 'publicKeyHash', 'signature'];\r\n for (const field of requiredFields) {\r\n if (!proof[field]) {\r\n throw new Error(`Missing required field: ${field}`);\r\n }\r\n }\r\n\r\n // Verify challenge matches\r\n if (!EnhancedSecureCryptoUtils.constantTimeCompareArrays(proof.challenge, challenge.challenge) ||\r\n proof.timestamp !== challenge.timestamp ||\r\n !EnhancedSecureCryptoUtils.constantTimeCompareArrays(proof.nonce, challenge.nonce)) {\r\n throw new Error('Challenge mismatch - possible replay attack');\r\n }\r\n\r\n // Check response time (max 30 minutes for better UX)\r\n const responseAge = Date.now() - proof.responseTimestamp;\r\n if (responseAge > 1800000) {\r\n throw new Error('Proof response expired');\r\n }\r\n\r\n // Verify public key hash\r\n const expectedHash = await EnhancedSecureCryptoUtils.hashPublicKey(publicKey);\r\n if (!EnhancedSecureCryptoUtils.constantTimeCompare(proof.publicKeyHash, expectedHash)) {\r\n throw new Error('Public key hash mismatch');\r\n }\r\n\r\n // Verify signature\r\n const proofCopy = { ...proof };\r\n delete proofCopy.signature;\r\n const proofString = JSON.stringify(proofCopy);\r\n const isValidSignature = await EnhancedSecureCryptoUtils.verifySignature(publicKey, proof.signature, proofString);\r\n\r\n if (!isValidSignature) {\r\n throw new Error('Invalid proof signature');\r\n }\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Authentication proof verified successfully', {\r\n responseAge: Math.round(responseAge / 1000) + 's'\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Authentication proof verification failed', { error: error.message });\r\n throw new Error(`Failed to verify cryptographic proof: ${error.message}`);\r\n }\r\n }\r\n\r\n // Hash public key for verification\r\n static async hashPublicKey(publicKey) {\r\n try {\r\n const exported = await crypto.subtle.exportKey('spki', publicKey);\r\n const hash = await crypto.subtle.digest('SHA-384', exported);\r\n const hashArray = Array.from(new Uint8Array(hash));\r\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Public key hashing failed', { error: error.message });\r\n throw new Error('Failed to create hash of the public key');\r\n }\r\n }\r\n\r\n // Legacy authentication challenge for backward compatibility\r\n static generateAuthChallenge() {\r\n const challenge = crypto.getRandomValues(new Uint8Array(32));\r\n return Array.from(challenge);\r\n }\r\n\r\n // Generate verification code for out-of-band authentication\r\n static generateVerificationCode() {\r\n const chars = '0123456789ABCDEF';\r\n const charCount = chars.length;\r\n let result = '';\r\n \r\n // Use rejection sampling to avoid bias\r\n for (let i = 0; i < 6; i++) {\r\n let randomByte;\r\n do {\r\n randomByte = crypto.getRandomValues(new Uint8Array(1))[0];\r\n } while (randomByte >= 256 - (256 % charCount)); // Reject biased values\r\n \r\n result += chars[randomByte % charCount];\r\n }\r\n \r\n return result.match(/.{1,2}/g).join('-');\r\n }\r\n\r\n // Enhanced message encryption with metadata protection and sequence numbers\r\n static async encryptMessage(message, encryptionKey, macKey, metadataKey, messageId, sequenceNumber = 0) {\r\n try {\r\n if (!message || typeof message !== 'string') {\r\n throw new Error('Invalid message format');\r\n }\r\n\r\n EnhancedSecureCryptoUtils.assertCryptoKey(encryptionKey, 'AES-GCM', ['encrypt']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(macKey, 'HMAC', ['sign']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(metadataKey, 'AES-GCM', ['encrypt']);\r\n\r\n const encoder = new TextEncoder();\r\n const messageData = encoder.encode(message);\r\n const messageIv = crypto.getRandomValues(new Uint8Array(12));\r\n const metadataIv = crypto.getRandomValues(new Uint8Array(12));\r\n const timestamp = Date.now();\r\n\r\n const paddingSize = 16 - (messageData.length % 16);\r\n const paddedMessage = new Uint8Array(messageData.length + paddingSize);\r\n paddedMessage.set(messageData);\r\n const padding = crypto.getRandomValues(new Uint8Array(paddingSize));\r\n paddedMessage.set(padding, messageData.length);\r\n\r\n const encryptedMessage = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: messageIv },\r\n encryptionKey,\r\n paddedMessage\r\n );\r\n\r\n const metadata = {\r\n id: messageId,\r\n timestamp: timestamp,\r\n sequenceNumber: sequenceNumber,\r\n originalLength: messageData.length,\r\n version: '4.0'\r\n };\r\n\r\n const metadataStr = JSON.stringify(EnhancedSecureCryptoUtils.sortObjectKeys(metadata));\r\n const encryptedMetadata = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: metadataIv },\r\n metadataKey,\r\n encoder.encode(metadataStr)\r\n );\r\n\r\n const payload = {\r\n messageIv: Array.from(messageIv),\r\n messageData: Array.from(new Uint8Array(encryptedMessage)),\r\n metadataIv: Array.from(metadataIv),\r\n metadataData: Array.from(new Uint8Array(encryptedMetadata)),\r\n version: '4.0'\r\n };\r\n\r\n const sortedPayload = EnhancedSecureCryptoUtils.sortObjectKeys(payload);\r\n const payloadStr = JSON.stringify(sortedPayload);\r\n\r\n const mac = await crypto.subtle.sign(\r\n 'HMAC',\r\n macKey,\r\n encoder.encode(payloadStr)\r\n );\r\n\r\n payload.mac = Array.from(new Uint8Array(mac));\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Message encrypted with metadata protection', {\r\n messageId,\r\n sequenceNumber,\r\n hasMetadataProtection: true,\r\n hasPadding: true\r\n });\r\n\r\n return payload;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Message encryption failed', {\r\n error: error.message,\r\n messageId\r\n });\r\n throw new Error(`Failed to encrypt the message: ${error.message}`);\r\n }\r\n }\r\n\r\n // Enhanced message decryption with metadata protection and sequence validation\r\n static async decryptMessage(encryptedPayload, encryptionKey, macKey, metadataKey, expectedSequenceNumber = null) {\r\n try {\r\n EnhancedSecureCryptoUtils.assertCryptoKey(encryptionKey, 'AES-GCM', ['decrypt']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(macKey, 'HMAC', ['verify']);\r\n EnhancedSecureCryptoUtils.assertCryptoKey(metadataKey, 'AES-GCM', ['decrypt']);\r\n\r\n const requiredFields = ['messageIv', 'messageData', 'metadataIv', 'metadataData', 'mac', 'version'];\r\n for (const field of requiredFields) {\r\n if (!encryptedPayload[field]) {\r\n throw new Error(`Missing required field: ${field}`);\r\n }\r\n }\r\n\r\n const payloadCopy = { ...encryptedPayload };\r\n delete payloadCopy.mac;\r\n const sortedPayloadCopy = EnhancedSecureCryptoUtils.sortObjectKeys(payloadCopy);\r\n const payloadStr = JSON.stringify(sortedPayloadCopy);\r\n\r\n const macValid = await crypto.subtle.verify(\r\n 'HMAC',\r\n macKey,\r\n new Uint8Array(encryptedPayload.mac),\r\n new TextEncoder().encode(payloadStr)\r\n );\r\n\r\n if (!macValid) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'MAC verification failed', {\r\n payloadFields: Object.keys(encryptedPayload),\r\n macLength: encryptedPayload.mac?.length\r\n });\r\n throw new Error('Message authentication failed - possible tampering');\r\n }\r\n\r\n const metadataIv = new Uint8Array(encryptedPayload.metadataIv);\r\n const metadataData = new Uint8Array(encryptedPayload.metadataData);\r\n\r\n const decryptedMetadataBuffer = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: metadataIv },\r\n metadataKey,\r\n metadataData\r\n );\r\n\r\n const metadataStr = new TextDecoder().decode(decryptedMetadataBuffer);\r\n const metadata = JSON.parse(metadataStr);\r\n\r\n if (!metadata.id || !metadata.timestamp || metadata.sequenceNumber === undefined || !metadata.originalLength) {\r\n throw new Error('Invalid metadata structure');\r\n }\r\n\r\n const messageAge = Date.now() - metadata.timestamp;\r\n if (messageAge > 1800000) { // 30 minutes for better UX\r\n throw new Error('Message expired (older than 5 minutes)');\r\n }\r\n\r\n if (expectedSequenceNumber !== null) {\r\n if (metadata.sequenceNumber < expectedSequenceNumber) {\r\n EnhancedSecureCryptoUtils.secureLog.log('warn', 'Received message with lower sequence number, possible queued message', {\r\n expected: expectedSequenceNumber,\r\n received: metadata.sequenceNumber,\r\n messageId: metadata.id\r\n });\r\n } else if (metadata.sequenceNumber > expectedSequenceNumber + 10) {\r\n throw new Error(`Sequence number gap too large: expected around ${expectedSequenceNumber}, got ${metadata.sequenceNumber}`);\r\n }\r\n }\r\n\r\n const messageIv = new Uint8Array(encryptedPayload.messageIv);\r\n const messageData = new Uint8Array(encryptedPayload.messageData);\r\n\r\n const decryptedMessageBuffer = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: messageIv },\r\n encryptionKey,\r\n messageData\r\n );\r\n\r\n const paddedMessage = new Uint8Array(decryptedMessageBuffer);\r\n const originalMessage = paddedMessage.slice(0, metadata.originalLength);\r\n\r\n const decoder = new TextDecoder();\r\n const message = decoder.decode(originalMessage);\r\n\r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Message decrypted successfully', {\r\n messageId: metadata.id,\r\n sequenceNumber: metadata.sequenceNumber,\r\n messageAge: Math.round(messageAge / 1000) + 's'\r\n });\r\n\r\n return {\r\n message: message,\r\n messageId: metadata.id,\r\n timestamp: metadata.timestamp,\r\n sequenceNumber: metadata.sequenceNumber\r\n };\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Message decryption failed', { error: error.message });\r\n throw new Error(`Failed to decrypt the message: ${error.message}`);\r\n }\r\n }\r\n\r\n // Enhanced input sanitization with iterative processing to handle edge cases\r\n static sanitizeMessage(message) {\r\n if (typeof message !== 'string') {\r\n throw new Error('Message must be a string');\r\n }\r\n \r\n // Helper function to apply replacement until stable\r\n function replaceUntilStable(str, pattern, replacement = '') {\r\n let previous;\r\n do {\r\n previous = str;\r\n str = str.replace(pattern, replacement);\r\n } while (str !== previous);\r\n return str;\r\n }\r\n \r\n // Define all dangerous patterns that need to be removed\r\n const dangerousPatterns = [\r\n // Script tags with various formats\r\n /]*>[\\s\\S]*?<\\/script\\s*>/gi,\r\n /]*>[\\s\\S]*?<\\/script\\s+[^>]*>/gi,\r\n /]*>[\\s\\S]*$/gi,\r\n // Other dangerous tags\r\n /]*>[\\s\\S]*?<\\/iframe\\s*>/gi,\r\n /]*>[\\s\\S]*?<\\/object\\s*>/gi,\r\n /]*>/gi,\r\n /]*>[\\s\\S]*?<\\/applet\\s*>/gi,\r\n /]*>[\\s\\S]*?<\\/style\\s*>/gi,\r\n // Dangerous protocols\r\n /javascript\\s*:/gi,\r\n /data\\s*:/gi,\r\n /vbscript\\s*:/gi,\r\n // Event handlers\r\n /on\\w+\\s*=/gi,\r\n // HTML comments\r\n //g,\r\n // Link and meta tags with javascript\r\n /]*javascript[^>]*>/gi,\r\n /]*javascript[^>]*>/gi,\r\n // Any remaining script-like content\r\n /<[^>]*script[^>]*>/gi,\r\n /<[^>]*on\\w+\\s*=[^>]*>/gi\r\n ];\r\n \r\n // Iterative sanitization to handle edge cases\r\n let sanitized = message;\r\n let previousLength;\r\n let iterations = 0;\r\n const maxIterations = 10; // Prevent infinite loops\r\n \r\n do {\r\n previousLength = sanitized.length;\r\n \r\n // Apply all dangerous patterns with stable replacement\r\n for (const pattern of dangerousPatterns) {\r\n sanitized = replaceUntilStable(sanitized, pattern);\r\n }\r\n \r\n // Additional cleanup for edge cases - each applied until stable\r\n sanitized = replaceUntilStable(sanitized, /<[^>]*>/g);\r\n sanitized = replaceUntilStable(sanitized, /^\\w+:/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[^>\\s]+/gi);\r\n \r\n // Single character removal is inherently safe\r\n sanitized = sanitized.replace(/[<>]/g, '').trim();\r\n \r\n iterations++;\r\n } while (sanitized.length !== previousLength && iterations < maxIterations);\r\n \r\n // Final security pass with stable replacements\r\n sanitized = replaceUntilStable(sanitized, /<[^>]*>/g);\r\n sanitized = replaceUntilStable(sanitized, /^\\w+:/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[\"'][^\"']*[\"']/gi);\r\n sanitized = replaceUntilStable(sanitized, /\\bon\\w+\\s*=\\s*[^>\\s]+/gi);\r\n \r\n // Final single character cleanup\r\n sanitized = sanitized.replace(/[<>]/g, '').trim();\r\n \r\n return sanitized.substring(0, 2000); // Limit length\r\n }\r\n\r\n // Generate cryptographically secure salt (64 bytes for enhanced security)\r\n static generateSalt() {\r\n return Array.from(crypto.getRandomValues(new Uint8Array(64)));\r\n }\r\n\r\n // Calculate key fingerprint for MITM protection\r\n static async calculateKeyFingerprint(keyData) {\r\n try {\r\n const encoder = new TextEncoder();\r\n const keyBytes = new Uint8Array(keyData);\r\n \r\n // Create a hash of the key data for fingerprinting\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', keyBytes);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n \r\n // Convert to hexadecimal string\r\n const fingerprint = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n EnhancedSecureCryptoUtils.secureLog.log('info', 'Key fingerprint calculated', {\r\n keySize: keyData.length,\r\n fingerprintLength: fingerprint.length\r\n });\r\n \r\n return fingerprint;\r\n } catch (error) {\r\n EnhancedSecureCryptoUtils.secureLog.log('error', 'Key fingerprint calculation failed', { error: error.message });\r\n throw new Error('Failed to compute the key fingerprint');\r\n }\r\n }\r\n\r\n static constantTimeCompare(a, b) {\r\n const strA = typeof a === 'string' ? a : JSON.stringify(a);\r\n const strB = typeof b === 'string' ? b : JSON.stringify(b);\r\n \r\n if (strA.length !== strB.length) {\r\n let dummy = 0;\r\n for (let i = 0; i < Math.max(strA.length, strB.length); i++) {\r\n dummy |= (strA.charCodeAt(i % strA.length) || 0) ^ (strB.charCodeAt(i % strB.length) || 0);\r\n }\r\n return false;\r\n }\r\n \r\n let result = 0;\r\n for (let i = 0; i < strA.length; i++) {\r\n result |= strA.charCodeAt(i) ^ strB.charCodeAt(i);\r\n }\r\n \r\n return result === 0;\r\n }\r\n\r\n static constantTimeCompareArrays(arr1, arr2) {\r\n if (!Array.isArray(arr1) || !Array.isArray(arr2)) {\r\n return false;\r\n }\r\n \r\n if (arr1.length !== arr2.length) {\r\n let dummy = 0;\r\n const maxLen = Math.max(arr1.length, arr2.length);\r\n for (let i = 0; i < maxLen; i++) {\r\n dummy |= (arr1[i % arr1.length] || 0) ^ (arr2[i % arr2.length] || 0);\r\n }\r\n return false;\r\n }\r\n \r\n let result = 0;\r\n for (let i = 0; i < arr1.length; i++) {\r\n result |= arr1[i] ^ arr2[i];\r\n }\r\n \r\n return result === 0;\r\n }\r\n \r\n /**\r\n * CRITICAL SECURITY: Encrypt data with AAD (Additional Authenticated Data)\r\n * This method provides authenticated encryption with additional data binding\r\n */\r\n static async encryptDataWithAAD(data, key, aad) {\r\n try {\r\n const dataString = typeof data === 'string' ? data : JSON.stringify(data);\r\n const encoder = new TextEncoder();\r\n const dataBuffer = encoder.encode(dataString);\r\n const aadBuffer = encoder.encode(aad);\r\n\r\n // Generate random IV\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n\r\n // Encrypt with AAD\r\n const encrypted = await crypto.subtle.encrypt(\r\n { \r\n name: 'AES-GCM', \r\n iv: iv,\r\n additionalData: aadBuffer\r\n },\r\n key,\r\n dataBuffer\r\n );\r\n\r\n // Package encrypted data\r\n const encryptedPackage = {\r\n version: '1.0',\r\n iv: Array.from(iv),\r\n data: Array.from(new Uint8Array(encrypted)),\r\n aad: aad,\r\n timestamp: Date.now()\r\n };\r\n\r\n const packageString = JSON.stringify(encryptedPackage);\r\n const packageBuffer = encoder.encode(packageString);\r\n \r\n return EnhancedSecureCryptoUtils.arrayBufferToBase64(packageBuffer);\r\n } catch (error) {\r\n throw new Error(`AAD encryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * CRITICAL SECURITY: Decrypt data with AAD validation\r\n * This method provides authenticated decryption with additional data validation\r\n */\r\n static async decryptDataWithAAD(encryptedData, key, expectedAad) {\r\n try {\r\n const packageBuffer = EnhancedSecureCryptoUtils.base64ToArrayBuffer(encryptedData);\r\n const packageString = new TextDecoder().decode(packageBuffer);\r\n const encryptedPackage = JSON.parse(packageString);\r\n\r\n if (!encryptedPackage.version || !encryptedPackage.iv || !encryptedPackage.data || !encryptedPackage.aad) {\r\n throw new Error('Invalid encrypted data format');\r\n }\r\n\r\n // Validate AAD matches expected\r\n if (encryptedPackage.aad !== expectedAad) {\r\n throw new Error('AAD mismatch - possible tampering or replay attack');\r\n }\r\n\r\n const iv = new Uint8Array(encryptedPackage.iv);\r\n const encrypted = new Uint8Array(encryptedPackage.data);\r\n const aadBuffer = new TextEncoder().encode(encryptedPackage.aad);\r\n\r\n // Decrypt with AAD validation\r\n const decrypted = await crypto.subtle.decrypt(\r\n { \r\n name: 'AES-GCM', \r\n iv: iv,\r\n additionalData: aadBuffer\r\n },\r\n key,\r\n encrypted\r\n );\r\n\r\n const decryptedString = new TextDecoder().decode(decrypted);\r\n\r\n try {\r\n return JSON.parse(decryptedString);\r\n } catch {\r\n return decryptedString;\r\n }\r\n } catch (error) {\r\n throw new Error(`AAD decryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n // Initialize secure logging system after class definition\r\n static {\r\n if (EnhancedSecureCryptoUtils.secureLog && typeof EnhancedSecureCryptoUtils.secureLog.init === 'function') {\r\n EnhancedSecureCryptoUtils.secureLog.init();\r\n }\r\n }\r\n}\r\n\r\nexport { EnhancedSecureCryptoUtils };", "// ============================================\n// SECURE FILE TRANSFER CONTEXT\n// ============================================\nclass SecureFileTransferContext {\n static #instance = null;\n static #contextKey = Symbol('SecureFileTransferContext');\n \n static getInstance() {\n if (!this.#instance) {\n this.#instance = new SecureFileTransferContext();\n }\n return this.#instance;\n }\n \n #fileTransferSystem = null;\n #active = false;\n #securityLevel = 'high';\n \n setFileTransferSystem(system) {\n if (!(system instanceof EnhancedSecureFileTransfer)) {\n throw new Error('Invalid file transfer system instance');\n }\n this.#fileTransferSystem = system;\n this.#active = true;\n }\n \n getFileTransferSystem() {\n return this.#fileTransferSystem;\n }\n \n isActive() {\n return this.#active && this.#fileTransferSystem !== null;\n }\n \n deactivate() {\n this.#active = false;\n this.#fileTransferSystem = null;\n }\n \n getSecurityLevel() {\n return this.#securityLevel;\n }\n \n setSecurityLevel(level) {\n if (['low', 'medium', 'high'].includes(level)) {\n this.#securityLevel = level;\n }\n }\n}\n\n// ============================================\n// SECURITY ERROR HANDLER\n// ============================================\n\nclass SecurityErrorHandler {\n static #allowedErrors = new Set([\n 'File size exceeds maximum limit',\n 'Unsupported file type',\n 'Transfer timeout',\n 'Connection lost',\n 'Invalid file data',\n 'File transfer failed',\n 'Transfer cancelled',\n 'Network error',\n 'File not found',\n 'Permission denied'\n ]);\n \n static sanitizeError(error) {\n const message = error.message || error;\n\n for (const allowed of this.#allowedErrors) {\n if (message.includes(allowed)) {\n return allowed;\n }\n }\n\n console.error('\uD83D\uDD12 Internal file transfer error:', {\n message: error.message,\n stack: error.stack,\n timestamp: new Date().toISOString()\n });\n\n return 'File transfer failed';\n }\n \n static logSecurityEvent(event, details = {}) {\n console.warn('\uD83D\uDD12 Security event:', {\n event,\n timestamp: new Date().toISOString(),\n ...details\n });\n }\n}\n\n// ============================================\n// FILE METADATA SIGNATURE SYSTEM\n// ============================================\n\nclass FileMetadataSigner {\n static async signFileMetadata(metadata, privateKey) {\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify({\n fileId: metadata.fileId,\n fileName: metadata.fileName,\n fileSize: metadata.fileSize,\n fileHash: metadata.fileHash,\n timestamp: metadata.timestamp,\n version: metadata.version || '2.0'\n }));\n \n const signature = await crypto.subtle.sign(\n 'RSASSA-PKCS1-v1_5',\n privateKey,\n data\n );\n \n return Array.from(new Uint8Array(signature));\n } catch (error) {\n SecurityErrorHandler.logSecurityEvent('signature_failed', { error: error.message });\n throw new Error('Failed to sign file metadata');\n }\n }\n \n static async verifyFileMetadata(metadata, signature, publicKey) {\n try {\n const encoder = new TextEncoder();\n const data = encoder.encode(JSON.stringify({\n fileId: metadata.fileId,\n fileName: metadata.fileName,\n fileSize: metadata.fileSize,\n fileHash: metadata.fileHash,\n timestamp: metadata.timestamp,\n version: metadata.version || '2.0'\n }));\n \n const signatureBuffer = new Uint8Array(signature);\n \n const isValid = await crypto.subtle.verify(\n 'RSASSA-PKCS1-v1_5',\n publicKey,\n signatureBuffer,\n data\n );\n \n if (!isValid) {\n SecurityErrorHandler.logSecurityEvent('invalid_signature', { fileId: metadata.fileId });\n }\n \n return isValid;\n } catch (error) {\n SecurityErrorHandler.logSecurityEvent('verification_failed', { error: error.message });\n return false;\n }\n }\n}\n\n// ============================================\n// \u0422\u041E\u0427\u041D\u042B\u0415 \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u042F \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u041E\u0421\u0422\u0418\n// ============================================\n\nclass MessageSizeValidator {\n static MAX_MESSAGE_SIZE = 1024 * 1024; // 1MB\n \n static isMessageSizeValid(message) {\n const messageString = JSON.stringify(message);\n const sizeInBytes = new Blob([messageString]).size;\n \n if (sizeInBytes > this.MAX_MESSAGE_SIZE) {\n SecurityErrorHandler.logSecurityEvent('message_too_large', {\n size: sizeInBytes,\n limit: this.MAX_MESSAGE_SIZE\n });\n throw new Error('Message too large');\n }\n \n return true;\n }\n}\n\nclass AtomicOperations {\n constructor() {\n this.locks = new Map();\n }\n \n async withLock(key, operation) {\n if (this.locks.has(key)) {\n await this.locks.get(key);\n }\n \n const lockPromise = (async () => {\n try {\n return await operation();\n } finally {\n this.locks.delete(key);\n }\n })();\n \n this.locks.set(key, lockPromise);\n return lockPromise;\n }\n}\n\n// Rate limiting \u0434\u043B\u044F \u0437\u0430\u0449\u0438\u0442\u044B \u043E\u0442 \u0441\u043F\u0430\u043C\u0430\nclass RateLimiter {\n constructor(maxRequests, windowMs) {\n this.maxRequests = maxRequests;\n this.windowMs = windowMs;\n this.requests = new Map();\n }\n \n isAllowed(identifier) {\n const now = Date.now();\n const windowStart = now - this.windowMs;\n \n if (!this.requests.has(identifier)) {\n this.requests.set(identifier, []);\n }\n \n const userRequests = this.requests.get(identifier);\n \n const validRequests = userRequests.filter(time => time > windowStart);\n this.requests.set(identifier, validRequests);\n \n if (validRequests.length >= this.maxRequests) {\n SecurityErrorHandler.logSecurityEvent('rate_limit_exceeded', {\n identifier,\n requestCount: validRequests.length,\n limit: this.maxRequests\n });\n return false;\n }\n \n validRequests.push(now);\n return true;\n }\n}\n\nclass SecureMemoryManager {\n static secureWipe(buffer) {\n if (buffer instanceof ArrayBuffer) {\n const view = new Uint8Array(buffer);\n crypto.getRandomValues(view);\n } else if (buffer instanceof Uint8Array) {\n crypto.getRandomValues(buffer);\n }\n }\n \n static secureDelete(obj, prop) {\n if (obj[prop]) {\n this.secureWipe(obj[prop]);\n delete obj[prop];\n }\n }\n}\n\nclass EnhancedSecureFileTransfer {\n constructor(webrtcManager, onProgress, onComplete, onError, onFileReceived) {\n this.webrtcManager = webrtcManager;\n this.onProgress = onProgress;\n this.onComplete = onComplete;\n this.onError = onError;\n this.onFileReceived = onFileReceived;\n \n // Validate webrtcManager\n if (!webrtcManager) {\n throw new Error('webrtcManager is required for EnhancedSecureFileTransfer');\n }\n \n SecureFileTransferContext.getInstance().setFileTransferSystem(this);\n \n this.atomicOps = new AtomicOperations();\n this.rateLimiter = new RateLimiter(10, 60000);\n\n this.signingKey = null;\n this.verificationKey = null;\n \n // Transfer settings\n this.CHUNK_SIZE = 64 * 1024; // 64 KB\n this.MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 MB limit\n this.MAX_CONCURRENT_TRANSFERS = 3;\n this.CHUNK_TIMEOUT = 30000; // 30 seconds per chunk\n this.RETRY_ATTEMPTS = 3;\n\n this.FILE_TYPE_RESTRICTIONS = {\n documents: {\n extensions: ['.pdf', '.doc', '.docx', '.txt', '.md', '.rtf', '.odt'],\n mimeTypes: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'text/plain',\n 'text/markdown',\n 'application/rtf',\n 'application/vnd.oasis.opendocument.text'\n ],\n maxSize: 50 * 1024 * 1024, // 50 MB\n category: 'Documents',\n description: 'PDF, DOC, TXT, MD, RTF, ODT'\n },\n \n images: {\n extensions: ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg', '.ico'],\n mimeTypes: [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/bmp',\n 'image/svg+xml',\n 'image/x-icon'\n ],\n maxSize: 25 * 1024 * 1024, // 25 MB\n category: 'Images',\n description: 'JPG, PNG, GIF, WEBP, BMP, SVG, ICO'\n },\n \n archives: {\n extensions: ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2', '.xz'],\n mimeTypes: [\n 'application/zip',\n 'application/x-rar-compressed',\n 'application/x-7z-compressed',\n 'application/x-tar',\n 'application/gzip',\n 'application/x-bzip2',\n 'application/x-xz'\n ],\n maxSize: 100 * 1024 * 1024, // 100 MB\n category: 'Archives',\n description: 'ZIP, RAR, 7Z, TAR, GZ, BZ2, XZ'\n },\n \n media: {\n extensions: ['.mp3', '.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm', '.ogg', '.wav'],\n mimeTypes: [\n 'audio/mpeg',\n 'video/mp4',\n 'video/x-msvideo',\n 'video/x-matroska',\n 'video/quicktime',\n 'video/x-ms-wmv',\n 'video/x-flv',\n 'video/webm',\n 'audio/ogg',\n 'audio/wav'\n ],\n maxSize: 100 * 1024 * 1024, // 100 MB\n category: 'Media',\n description: 'MP3, MP4, AVI, MKV, MOV, WMV, FLV, WEBM, OGG, WAV'\n },\n \n general: {\n extensions: [], \n mimeTypes: [], \n maxSize: 50 * 1024 * 1024, // 50 MB\n category: 'General',\n description: 'Any file type up to size limits'\n }\n };\n \n // Active transfers tracking\n this.activeTransfers = new Map(); // fileId -> transfer state\n this.receivingTransfers = new Map(); // fileId -> receiving state\n this.transferQueue = []; // Queue for pending transfers\n this.pendingChunks = new Map();\n \n // Session key derivation\n this.sessionKeys = new Map(); // fileId -> derived session key\n \n // Security\n this.processedChunks = new Set(); // Prevent replay attacks\n this.transferNonces = new Map(); // fileId -> current nonce counter\n this.receivedFileBuffers = new Map(); // fileId -> { buffer:ArrayBuffer, type:string, name:string, size:number }\n\n this.setupFileMessageHandlers();\n\n if (this.webrtcManager) {\n this.webrtcManager.fileTransferSystem = this;\n }\n }\n\n // ============================================\n // FILE TYPE VALIDATION SYSTEM\n // ============================================\n\n getFileType(file) {\n const fileName = file.name.toLowerCase();\n const fileExtension = fileName.substring(fileName.lastIndexOf('.'));\n const mimeType = file.type.toLowerCase();\n\n for (const [typeKey, typeConfig] of Object.entries(this.FILE_TYPE_RESTRICTIONS)) {\n if (typeKey === 'general') continue; // \u041F\u0440\u043E\u043F\u0443\u0441\u043A\u0430\u0435\u043C \u043E\u0431\u0449\u0438\u0439 \u0442\u0438\u043F\n\n if (typeConfig.extensions.includes(fileExtension)) {\n return {\n type: typeKey,\n category: typeConfig.category,\n description: typeConfig.description,\n maxSize: typeConfig.maxSize,\n allowed: true\n };\n }\n\n if (typeConfig.mimeTypes.includes(mimeType)) {\n return {\n type: typeKey,\n category: typeConfig.category,\n description: typeConfig.description,\n maxSize: typeConfig.maxSize,\n allowed: true\n };\n }\n }\n\n const generalConfig = this.FILE_TYPE_RESTRICTIONS.general;\n return {\n type: 'general',\n category: generalConfig.category,\n description: generalConfig.description,\n maxSize: generalConfig.maxSize,\n allowed: true\n };\n }\n\n validateFile(file) {\n const fileType = this.getFileType(file);\n const errors = [];\n\n if (file.size > fileType.maxSize) {\n errors.push(`File size (${this.formatFileSize(file.size)}) exceeds maximum allowed for ${fileType.category} (${this.formatFileSize(fileType.maxSize)})`);\n }\n\n if (!fileType.allowed) {\n errors.push(`File type not allowed. Supported types: ${fileType.description}`);\n }\n\n if (file.size > this.MAX_FILE_SIZE) {\n errors.push(`File size (${this.formatFileSize(file.size)}) exceeds general limit (${this.formatFileSize(this.MAX_FILE_SIZE)})`);\n }\n \n return {\n isValid: errors.length === 0,\n errors: errors,\n fileType: fileType,\n fileSize: file.size,\n formattedSize: this.formatFileSize(file.size)\n };\n }\n\n formatFileSize(bytes) {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n\n getSupportedFileTypes() {\n const supportedTypes = {};\n \n for (const [typeKey, typeConfig] of Object.entries(this.FILE_TYPE_RESTRICTIONS)) {\n if (typeKey === 'general') continue;\n \n supportedTypes[typeKey] = {\n category: typeConfig.category,\n description: typeConfig.description,\n extensions: typeConfig.extensions,\n maxSize: this.formatFileSize(typeConfig.maxSize),\n maxSizeBytes: typeConfig.maxSize\n };\n }\n \n return supportedTypes;\n }\n\n getFileTypeInfo() {\n return {\n supportedTypes: this.getSupportedFileTypes(),\n generalMaxSize: this.formatFileSize(this.MAX_FILE_SIZE),\n generalMaxSizeBytes: this.MAX_FILE_SIZE,\n restrictions: this.FILE_TYPE_RESTRICTIONS\n };\n }\n\n // ============================================\n // ENCODING HELPERS (Base64 for efficient transport)\n // ============================================\n arrayBufferToBase64(buffer) {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n let binary = '';\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n base64ToUint8Array(base64) {\n const binaryString = atob(base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n }\n\n // ============================================\n // PUBLIC ACCESSORS FOR RECEIVED FILES\n // ============================================\n getReceivedFileMeta(fileId) {\n const entry = this.receivedFileBuffers.get(fileId);\n if (!entry) return null;\n return { fileId, fileName: entry.name, fileSize: entry.size, mimeType: entry.type };\n }\n\n async getBlob(fileId) {\n const entry = this.receivedFileBuffers.get(fileId);\n if (!entry) return null;\n return new Blob([entry.buffer], { type: entry.type });\n }\n\n async getObjectURL(fileId) {\n const blob = await this.getBlob(fileId);\n if (!blob) return null;\n return URL.createObjectURL(blob);\n }\n\n revokeObjectURL(url) {\n try { URL.revokeObjectURL(url); } catch (_) {}\n }\n\n setupFileMessageHandlers() {\n if (!this.webrtcManager.dataChannel) {\n const setupRetry = setInterval(() => {\n if (this.webrtcManager.dataChannel) {\n clearInterval(setupRetry);\n this.setupMessageInterception();\n }\n }, 100);\n\n setTimeout(() => {\n clearInterval(setupRetry);\n }, 5000);\n \n return;\n }\n \n // \u0415\u0441\u043B\u0438 dataChannel \u0443\u0436\u0435 \u0433\u043E\u0442\u043E\u0432, \u0441\u0440\u0430\u0437\u0443 \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043C\n this.setupMessageInterception();\n }\n\n setupMessageInterception() {\n try {\n if (!this.webrtcManager.dataChannel) {\n return;\n }\n\n if (this.webrtcManager) {\n this.webrtcManager.fileTransferSystem = this;\n }\n\n if (this.webrtcManager.dataChannel.onmessage) {\n this.originalOnMessage = this.webrtcManager.dataChannel.onmessage;\n }\n\n this.webrtcManager.dataChannel.onmessage = async (event) => {\n try {\n if (event.data.length > MessageSizeValidator.MAX_MESSAGE_SIZE) {\n console.warn('\uD83D\uDD12 Message too large, ignoring');\n SecurityErrorHandler.logSecurityEvent('oversized_message_blocked');\n return;\n }\n \n if (typeof event.data === 'string') {\n try {\n const parsed = JSON.parse(event.data);\n \n MessageSizeValidator.isMessageSizeValid(parsed);\n \n if (this.isFileTransferMessage(parsed)) {\n await this.handleFileMessage(parsed);\n return; \n }\n } catch (parseError) {\n if (parseError.message === 'Message too large') {\n return; \n }\n }\n }\n\n if (this.originalOnMessage) {\n return this.originalOnMessage.call(this.webrtcManager.dataChannel, event);\n }\n } catch (error) {\n console.error('\u274C Error in file system message interception:', error);\n if (this.originalOnMessage) {\n return this.originalOnMessage.call(this.webrtcManager.dataChannel, event);\n }\n }\n };\n } catch (error) {\n console.error('\u274C Failed to set up message interception:', error);\n }\n }\n\n isFileTransferMessage(message) {\n if (!message || typeof message !== 'object' || !message.type) {\n return false;\n }\n \n const fileMessageTypes = [\n 'file_transfer_start',\n 'file_transfer_response', \n 'file_chunk',\n 'chunk_confirmation',\n 'file_transfer_complete',\n 'file_transfer_error'\n ];\n \n return fileMessageTypes.includes(message.type);\n }\n\n async handleFileMessage(message) {\n try {\n if (!this.webrtcManager.fileTransferSystem) {\n try {\n if (typeof this.webrtcManager.initializeFileTransfer === 'function') {\n this.webrtcManager.initializeFileTransfer();\n \n let attempts = 0;\n const maxAttempts = 50; \n while (!this.webrtcManager.fileTransferSystem && attempts < maxAttempts) {\n await new Promise(resolve => setTimeout(resolve, 100));\n attempts++;\n }\n \n if (!this.webrtcManager.fileTransferSystem) {\n throw new Error('File transfer system initialization timeout');\n }\n } else {\n throw new Error('initializeFileTransfer method not available');\n }\n } catch (initError) {\n console.error('\u274C Failed to initialize file transfer system:', initError);\n if (message.fileId) {\n const errorMessage = {\n type: 'file_transfer_error',\n fileId: message.fileId,\n error: 'File transfer system not available',\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n }\n return;\n }\n }\n \n switch (message.type) {\n case 'file_transfer_start':\n await this.handleFileTransferStart(message);\n break;\n \n case 'file_transfer_response':\n this.handleTransferResponse(message);\n break;\n \n case 'file_chunk':\n await this.handleFileChunk(message);\n break;\n \n case 'chunk_confirmation':\n this.handleChunkConfirmation(message);\n break;\n \n case 'file_transfer_complete':\n this.handleTransferComplete(message);\n break;\n \n case 'file_transfer_error':\n this.handleTransferError(message);\n break;\n \n default:\n console.warn('\u26A0\uFE0F Unknown file message type:', message.type);\n }\n \n } catch (error) {\n console.error('\u274C Error handling file message:', error);\n\n if (message.fileId) {\n const errorMessage = {\n type: 'file_transfer_error',\n fileId: message.fileId,\n error: error.message,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n }\n }\n }\n\n // ============================================\n // SIMPLIFIED KEY DERIVATION - USE SHARED DATA\n // ============================================\n\n async deriveFileSessionKey(fileId) {\n try {\n \n if (!this.webrtcManager.keyFingerprint || !this.webrtcManager.sessionSalt) {\n throw new Error('WebRTC session data not available');\n }\n\n const fileSalt = crypto.getRandomValues(new Uint8Array(32));\n\n const encoder = new TextEncoder();\n const fingerprintData = encoder.encode(this.webrtcManager.keyFingerprint);\n const fileIdData = encoder.encode(fileId);\n\n const sessionSaltArray = new Uint8Array(this.webrtcManager.sessionSalt);\n const combinedSeed = new Uint8Array(\n fingerprintData.length + \n sessionSaltArray.length + \n fileSalt.length + \n fileIdData.length\n );\n \n let offset = 0;\n combinedSeed.set(fingerprintData, offset);\n offset += fingerprintData.length;\n combinedSeed.set(sessionSaltArray, offset);\n offset += sessionSaltArray.length;\n combinedSeed.set(fileSalt, offset);\n offset += fileSalt.length;\n combinedSeed.set(fileIdData, offset);\n\n const keyMaterial = await crypto.subtle.digest('SHA-256', combinedSeed);\n\n const fileSessionKey = await crypto.subtle.importKey(\n 'raw',\n keyMaterial,\n { name: 'AES-GCM' },\n false,\n ['encrypt', 'decrypt']\n );\n\n this.sessionKeys.set(fileId, {\n key: fileSessionKey,\n salt: Array.from(fileSalt),\n created: Date.now()\n });\n\n return { key: fileSessionKey, salt: Array.from(fileSalt) };\n\n } catch (error) {\n console.error('\u274C Failed to derive file session key:', error);\n throw error;\n }\n }\n\n async deriveFileSessionKeyFromSalt(fileId, saltArray) {\n try {\n if (!saltArray || !Array.isArray(saltArray) || saltArray.length !== 32) {\n throw new Error(`Invalid salt: ${saltArray?.length || 0} bytes`);\n }\n \n if (!this.webrtcManager.keyFingerprint || !this.webrtcManager.sessionSalt) {\n throw new Error('WebRTC session data not available');\n }\n\n const encoder = new TextEncoder();\n const fingerprintData = encoder.encode(this.webrtcManager.keyFingerprint);\n const fileIdData = encoder.encode(fileId);\n\n const fileSalt = new Uint8Array(saltArray);\n const sessionSaltArray = new Uint8Array(this.webrtcManager.sessionSalt);\n\n const combinedSeed = new Uint8Array(\n fingerprintData.length + \n sessionSaltArray.length + \n fileSalt.length + \n fileIdData.length\n );\n \n let offset = 0;\n combinedSeed.set(fingerprintData, offset);\n offset += fingerprintData.length;\n combinedSeed.set(sessionSaltArray, offset);\n offset += sessionSaltArray.length;\n combinedSeed.set(fileSalt, offset);\n offset += fileSalt.length;\n combinedSeed.set(fileIdData, offset);\n\n const keyMaterial = await crypto.subtle.digest('SHA-256', combinedSeed);\n\n const fileSessionKey = await crypto.subtle.importKey(\n 'raw',\n keyMaterial,\n { name: 'AES-GCM' },\n false,\n ['encrypt', 'decrypt']\n );\n\n this.sessionKeys.set(fileId, {\n key: fileSessionKey,\n salt: saltArray,\n created: Date.now()\n });\n\n return fileSessionKey;\n\n } catch (error) {\n console.error('\u274C Failed to derive session key from salt:', error);\n throw error;\n }\n }\n\n // ============================================\n // FILE TRANSFER IMPLEMENTATION\n // ============================================\n\n async sendFile(file) {\n try {\n // Validate webrtcManager\n if (!this.webrtcManager) {\n throw new Error('WebRTC Manager not initialized');\n }\n\n const clientId = this.getClientIdentifier();\n if (!this.rateLimiter.isAllowed(clientId)) {\n SecurityErrorHandler.logSecurityEvent('rate_limit_exceeded', { clientId });\n throw new Error('Rate limit exceeded. Please wait before sending another file.');\n }\n\n if (!file || !file.size) {\n throw new Error('Invalid file object');\n }\n\n const validation = this.validateFile(file);\n if (!validation.isValid) {\n const errorMessage = validation.errors.join('. ');\n throw new Error(errorMessage);\n }\n\n if (this.activeTransfers.size >= this.MAX_CONCURRENT_TRANSFERS) {\n throw new Error('Maximum concurrent transfers reached');\n }\n\n // Generate unique file ID\n const fileId = `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n \n // Calculate file hash for integrity verification\n const fileHash = await this.calculateFileHash(file);\n \n // Derive session key for this file\n const keyResult = await this.deriveFileSessionKey(fileId);\n const sessionKey = keyResult.key;\n const salt = keyResult.salt;\n \n // Create transfer state\n const transferState = {\n fileId: fileId,\n file: file,\n fileHash: fileHash,\n sessionKey: sessionKey,\n salt: salt, \n totalChunks: Math.ceil(file.size / this.CHUNK_SIZE),\n sentChunks: 0,\n confirmedChunks: 0,\n startTime: Date.now(),\n status: 'preparing',\n retryCount: 0,\n lastChunkTime: Date.now()\n };\n\n this.activeTransfers.set(fileId, transferState);\n this.transferNonces.set(fileId, 0);\n\n // Send file metadata first\n await this.sendFileMetadata(transferState);\n \n // Start chunk transmission\n await this.startChunkTransmission(transferState);\n \n return fileId;\n\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C File sending failed:', safeError);\n if (this.onError) this.onError(safeError);\n throw new Error(safeError);\n }\n }\n\n async sendFileMetadata(transferState) {\n try {\n const metadata = {\n type: 'file_transfer_start',\n fileId: transferState.fileId,\n fileName: transferState.file.name,\n fileSize: transferState.file.size,\n fileType: transferState.file.type || 'application/octet-stream',\n fileHash: transferState.fileHash,\n totalChunks: transferState.totalChunks,\n chunkSize: this.CHUNK_SIZE,\n salt: transferState.salt, \n timestamp: Date.now(),\n version: '2.0'\n };\n\n if (this.signingKey) {\n try {\n metadata.signature = await FileMetadataSigner.signFileMetadata(metadata, this.signingKey);\n console.log('\uD83D\uDD12 File metadata signed successfully');\n } catch (signError) {\n SecurityErrorHandler.logSecurityEvent('signature_failed', { \n fileId: transferState.fileId, \n error: signError.message \n });\n }\n }\n\n // Send metadata through secure channel\n await this.sendSecureMessage(metadata);\n \n transferState.status = 'metadata_sent';\n\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to send file metadata:', safeError);\n transferState.status = 'failed';\n throw new Error(safeError);\n }\n }\n\n async startChunkTransmission(transferState) {\n try {\n transferState.status = 'transmitting';\n \n const file = transferState.file;\n const totalChunks = transferState.totalChunks;\n \n for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {\n const start = chunkIndex * this.CHUNK_SIZE;\n const end = Math.min(start + this.CHUNK_SIZE, file.size);\n \n // Read chunk from file\n const chunkData = await this.readFileChunk(file, start, end);\n \n // Send chunk (\u0441 \u0443\u0447\u0451\u0442\u043E\u043C backpressure)\n await this.sendFileChunk(transferState, chunkIndex, chunkData);\n \n // Update progress\n transferState.sentChunks++;\n const progress = Math.round((transferState.sentChunks / totalChunks) * 95) + 5; // 5-100%\n\n await this.waitForBackpressure();\n }\n \n transferState.status = 'waiting_confirmation';\n \n // Timeout for completion confirmation\n setTimeout(() => {\n if (this.activeTransfers.has(transferState.fileId)) {\n const state = this.activeTransfers.get(transferState.fileId);\n if (state.status === 'waiting_confirmation') {\n this.cleanupTransfer(transferState.fileId);\n }\n }\n }, 30000);\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Chunk transmission failed:', safeError);\n transferState.status = 'failed';\n throw new Error(safeError);\n }\n }\n\n async readFileChunk(file, start, end) {\n try {\n const blob = file.slice(start, end);\n return await blob.arrayBuffer();\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to read file chunk:', safeError);\n throw new Error(safeError);\n }\n }\n\n async sendFileChunk(transferState, chunkIndex, chunkData) {\n try {\n const sessionKey = transferState.sessionKey;\n const nonce = crypto.getRandomValues(new Uint8Array(12));\n \n // Encrypt chunk data\n const encryptedChunk = await crypto.subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: nonce\n },\n sessionKey,\n chunkData\n );\n \n // Use Base64 to drastically reduce JSON overhead\n const encryptedB64 = this.arrayBufferToBase64(new Uint8Array(encryptedChunk));\n const chunkMessage = {\n type: 'file_chunk',\n fileId: transferState.fileId,\n chunkIndex: chunkIndex,\n totalChunks: transferState.totalChunks,\n nonce: Array.from(nonce),\n encryptedDataB64: encryptedB64,\n chunkSize: chunkData.byteLength,\n timestamp: Date.now()\n };\n\n await this.waitForBackpressure();\n // Send chunk through secure channel\n await this.sendSecureMessage(chunkMessage);\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to send file chunk:', safeError);\n throw new Error(safeError);\n }\n }\n\n async sendSecureMessage(message) {\n\n const messageString = JSON.stringify(message);\n const dc = this.webrtcManager?.dataChannel;\n const maxRetries = 10;\n let attempt = 0;\n const wait = (ms) => new Promise(r => setTimeout(r, ms));\n\n while (true) {\n try {\n if (!dc || dc.readyState !== 'open') {\n throw new Error('Data channel not ready');\n }\n await this.waitForBackpressure();\n dc.send(messageString);\n return; // success\n } catch (error) {\n const msg = String(error?.message || '');\n const queueFull = msg.includes('send queue is full') || msg.includes('bufferedAmount');\n const opErr = error?.name === 'OperationError';\n if ((queueFull || opErr) && attempt < maxRetries) {\n attempt++;\n await this.waitForBackpressure();\n await wait(Math.min(50 * attempt, 500));\n continue;\n }\n console.error('\u274C Failed to send secure message:', error);\n throw error;\n }\n }\n }\n\n async waitForBackpressure() {\n try {\n const dc = this.webrtcManager?.dataChannel;\n if (!dc) return;\n\n if (typeof dc.bufferedAmountLowThreshold === 'number') {\n if (dc.bufferedAmount > dc.bufferedAmountLowThreshold) {\n await new Promise(resolve => {\n const handler = () => {\n dc.removeEventListener('bufferedamountlow', handler);\n resolve();\n };\n dc.addEventListener('bufferedamountlow', handler, { once: true });\n });\n }\n return;\n }\n\n const softLimit = 4 * 1024 * 1024;\n while (dc.bufferedAmount > softLimit) {\n await new Promise(r => setTimeout(r, 20));\n }\n } catch (_) {\n // ignore\n }\n }\n\n async calculateFileHash(file) {\n try {\n const arrayBuffer = await file.arrayBuffer();\n const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (error) {\n console.error('\u274C File hash calculation failed:', error);\n throw error;\n }\n }\n\n // ============================================\n // MESSAGE HANDLERS\n // ============================================\n\n async handleFileTransferStart(metadata) {\n try {\n // Validate metadata\n if (!metadata.fileId || !metadata.fileName || !metadata.fileSize) {\n throw new Error('Invalid file transfer metadata');\n }\n\n if (metadata.signature && this.verificationKey) {\n try {\n const isValid = await FileMetadataSigner.verifyFileMetadata(\n metadata, \n metadata.signature, \n this.verificationKey\n );\n \n if (!isValid) {\n SecurityErrorHandler.logSecurityEvent('invalid_metadata_signature', { \n fileId: metadata.fileId \n });\n throw new Error('Invalid file metadata signature');\n }\n \n console.log('\uD83D\uDD12 File metadata signature verified successfully');\n } catch (verifyError) {\n SecurityErrorHandler.logSecurityEvent('verification_failed', { \n fileId: metadata.fileId, \n error: verifyError.message \n });\n throw new Error('File metadata verification failed');\n }\n }\n \n // Check if we already have this transfer\n if (this.receivingTransfers.has(metadata.fileId)) {\n return;\n }\n \n // Derive session key from salt\n const sessionKey = await this.deriveFileSessionKeyFromSalt(\n metadata.fileId,\n metadata.salt\n );\n \n // Create receiving transfer state\n const receivingState = {\n fileId: metadata.fileId,\n fileName: metadata.fileName,\n fileSize: metadata.fileSize,\n fileType: metadata.fileType || 'application/octet-stream',\n fileHash: metadata.fileHash,\n totalChunks: metadata.totalChunks,\n chunkSize: metadata.chunkSize || this.CHUNK_SIZE,\n sessionKey: sessionKey,\n salt: metadata.salt,\n receivedChunks: new Map(),\n receivedCount: 0,\n startTime: Date.now(),\n lastChunkTime: Date.now(),\n status: 'receiving'\n };\n \n this.receivingTransfers.set(metadata.fileId, receivingState);\n \n // Send acceptance response\n const response = {\n type: 'file_transfer_response',\n fileId: metadata.fileId,\n accepted: true,\n timestamp: Date.now()\n };\n \n await this.sendSecureMessage(response);\n\n // Process buffered chunks if any\n if (this.pendingChunks.has(metadata.fileId)) {\n const bufferedChunks = this.pendingChunks.get(metadata.fileId);\n \n for (const [chunkIndex, chunkMessage] of bufferedChunks.entries()) {\n await this.handleFileChunk(chunkMessage);\n }\n \n this.pendingChunks.delete(metadata.fileId);\n }\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to handle file transfer start:', safeError);\n \n // Send error response\n const errorResponse = {\n type: 'file_transfer_response',\n fileId: metadata.fileId,\n accepted: false,\n error: safeError, \n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorResponse);\n }\n }\n\n async handleFileChunk(chunkMessage) {\n return this.atomicOps.withLock(\n `chunk-${chunkMessage.fileId}`, \n async () => {\n try {\n let receivingState = this.receivingTransfers.get(chunkMessage.fileId);\n \n // Buffer early chunks if transfer not yet initialized\n if (!receivingState) {\n if (!this.pendingChunks.has(chunkMessage.fileId)) {\n this.pendingChunks.set(chunkMessage.fileId, new Map());\n }\n \n this.pendingChunks.get(chunkMessage.fileId).set(chunkMessage.chunkIndex, chunkMessage);\n return;\n }\n \n // Update last chunk time\n receivingState.lastChunkTime = Date.now();\n \n // Check if chunk already received\n if (receivingState.receivedChunks.has(chunkMessage.chunkIndex)) {\n return;\n }\n \n // Validate chunk\n if (chunkMessage.chunkIndex < 0 || chunkMessage.chunkIndex >= receivingState.totalChunks) {\n throw new Error(`Invalid chunk index: ${chunkMessage.chunkIndex}`);\n }\n \n // Decrypt chunk\n const nonce = new Uint8Array(chunkMessage.nonce);\n // Backward compatible: prefer Base64, fallback to numeric array\n let encryptedData;\n if (chunkMessage.encryptedDataB64) {\n encryptedData = this.base64ToUint8Array(chunkMessage.encryptedDataB64);\n } else if (chunkMessage.encryptedData) {\n encryptedData = new Uint8Array(chunkMessage.encryptedData);\n } else {\n throw new Error('Missing encrypted data');\n }\n \n const decryptedChunk = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: nonce\n },\n receivingState.sessionKey,\n encryptedData\n );\n \n // Verify chunk size\n if (decryptedChunk.byteLength !== chunkMessage.chunkSize) {\n throw new Error(`Chunk size mismatch: expected ${chunkMessage.chunkSize}, got ${decryptedChunk.byteLength}`);\n }\n \n // Store chunk\n receivingState.receivedChunks.set(chunkMessage.chunkIndex, decryptedChunk);\n receivingState.receivedCount++;\n \n // Send chunk confirmation\n const confirmation = {\n type: 'chunk_confirmation',\n fileId: chunkMessage.fileId,\n chunkIndex: chunkMessage.chunkIndex,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(confirmation);\n \n // Check if all chunks received\n if (receivingState.receivedCount === receivingState.totalChunks) {\n await this.assembleFile(receivingState);\n }\n \n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to handle file chunk:', safeError);\n \n // Send error notification\n const errorMessage = {\n type: 'file_transfer_error',\n fileId: chunkMessage.fileId,\n error: safeError, \n chunkIndex: chunkMessage.chunkIndex,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n \n // Mark transfer as failed\n const receivingState = this.receivingTransfers.get(chunkMessage.fileId);\n if (receivingState) {\n receivingState.status = 'failed';\n }\n \n if (this.onError) {\n this.onError(`Chunk processing failed: ${safeError}`);\n }\n }\n }\n );\n }\n\n async assembleFile(receivingState) {\n try {\n receivingState.status = 'assembling';\n \n // Verify we have all chunks\n for (let i = 0; i < receivingState.totalChunks; i++) {\n if (!receivingState.receivedChunks.has(i)) {\n throw new Error(`Missing chunk ${i}`);\n }\n }\n \n // Combine all chunks in order\n const chunks = [];\n for (let i = 0; i < receivingState.totalChunks; i++) {\n const chunk = receivingState.receivedChunks.get(i);\n chunks.push(new Uint8Array(chunk));\n }\n \n // Calculate total size\n const totalSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n \n // Verify total size matches expected\n if (totalSize !== receivingState.fileSize) {\n throw new Error(`File size mismatch: expected ${receivingState.fileSize}, got ${totalSize}`);\n }\n \n // Combine into single array\n const fileData = new Uint8Array(totalSize);\n let offset = 0;\n for (const chunk of chunks) {\n fileData.set(chunk, offset);\n offset += chunk.length;\n }\n \n // Verify file integrity\n const receivedHash = await this.calculateFileHashFromData(fileData);\n if (receivedHash !== receivingState.fileHash) {\n throw new Error('File integrity check failed - hash mismatch');\n }\n\n const fileBuffer = fileData.buffer;\n const fileBlob = new Blob([fileBuffer], { type: receivingState.fileType });\n \n receivingState.endTime = Date.now();\n receivingState.status = 'completed';\n\n this.receivedFileBuffers.set(receivingState.fileId, {\n buffer: fileBuffer,\n type: receivingState.fileType,\n name: receivingState.fileName,\n size: receivingState.fileSize\n });\n\n if (this.onFileReceived) {\n const getBlob = async () => new Blob([this.receivedFileBuffers.get(receivingState.fileId).buffer], { type: receivingState.fileType });\n const getObjectURL = async () => {\n const blob = await getBlob();\n return URL.createObjectURL(blob);\n };\n const revokeObjectURL = (url) => {\n try { URL.revokeObjectURL(url); } catch (_) {}\n };\n\n this.onFileReceived({\n fileId: receivingState.fileId,\n fileName: receivingState.fileName,\n fileSize: receivingState.fileSize,\n mimeType: receivingState.fileType,\n transferTime: receivingState.endTime - receivingState.startTime,\n // backward-compatibility for existing UIs\n fileBlob,\n getBlob,\n getObjectURL,\n revokeObjectURL\n });\n }\n \n // Send completion confirmation\n const completionMessage = {\n type: 'file_transfer_complete',\n fileId: receivingState.fileId,\n success: true,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(completionMessage);\n \n // Cleanup\n if (this.receivingTransfers.has(receivingState.fileId)) {\n const rs = this.receivingTransfers.get(receivingState.fileId);\n if (rs && rs.receivedChunks) rs.receivedChunks.clear();\n }\n this.receivingTransfers.delete(receivingState.fileId);\n \n } catch (error) {\n console.error('\u274C File assembly failed:', error);\n receivingState.status = 'failed';\n \n if (this.onError) {\n this.onError(`File assembly failed: ${error.message}`);\n }\n \n // Send error notification\n const errorMessage = {\n type: 'file_transfer_complete',\n fileId: receivingState.fileId,\n success: false,\n error: error.message,\n timestamp: Date.now()\n };\n await this.sendSecureMessage(errorMessage);\n \n // Cleanup failed transfer\n this.cleanupReceivingTransfer(receivingState.fileId);\n }\n }\n\n async calculateFileHashFromData(data) {\n try {\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (error) {\n console.error('\u274C Hash calculation failed:', error);\n throw error;\n }\n }\n\n handleTransferResponse(response) {\n try {\n const transferState = this.activeTransfers.get(response.fileId);\n \n if (!transferState) {\n return;\n }\n \n if (response.accepted) {\n transferState.status = 'accepted';\n } else {\n transferState.status = 'rejected';\n \n if (this.onError) {\n this.onError(`Transfer rejected: ${response.error || 'Unknown reason'}`);\n }\n \n this.cleanupTransfer(response.fileId);\n }\n } catch (error) {\n console.error('\u274C Failed to handle transfer response:', error);\n }\n }\n\n handleChunkConfirmation(confirmation) {\n try {\n const transferState = this.activeTransfers.get(confirmation.fileId);\n if (!transferState) {\n return;\n }\n \n transferState.confirmedChunks++;\n transferState.lastChunkTime = Date.now();\n } catch (error) {\n console.error('\u274C Failed to handle chunk confirmation:', error);\n }\n }\n\n handleTransferComplete(completion) {\n try {\n const transferState = this.activeTransfers.get(completion.fileId);\n if (!transferState) {\n return;\n }\n \n if (completion.success) {\n transferState.status = 'completed';\n transferState.endTime = Date.now();\n \n if (this.onComplete) {\n this.onComplete({\n fileId: transferState.fileId,\n fileName: transferState.file.name,\n fileSize: transferState.file.size,\n transferTime: transferState.endTime - transferState.startTime,\n status: 'completed'\n });\n }\n } else {\n transferState.status = 'failed';\n \n if (this.onError) {\n this.onError(`Transfer failed: ${completion.error || 'Unknown error'}`);\n }\n }\n \n this.cleanupTransfer(completion.fileId);\n \n } catch (error) {\n console.error('\u274C Failed to handle transfer completion:', error);\n }\n }\n\n handleTransferError(errorMessage) {\n try {\n const transferState = this.activeTransfers.get(errorMessage.fileId);\n if (transferState) {\n transferState.status = 'failed';\n this.cleanupTransfer(errorMessage.fileId);\n }\n \n const receivingState = this.receivingTransfers.get(errorMessage.fileId);\n if (receivingState) {\n receivingState.status = 'failed';\n this.cleanupReceivingTransfer(errorMessage.fileId);\n }\n \n if (this.onError) {\n this.onError(`Transfer error: ${errorMessage.error || 'Unknown error'}`);\n }\n \n } catch (error) {\n console.error('\u274C Failed to handle transfer error:', error);\n }\n }\n\n // ============================================\n // UTILITY METHODS\n // ============================================\n\n getActiveTransfers() {\n return Array.from(this.activeTransfers.values()).map(transfer => ({\n fileId: transfer.fileId,\n fileName: transfer.file?.name || 'Unknown',\n fileSize: transfer.file?.size || 0,\n progress: Math.round((transfer.sentChunks / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n }));\n }\n\n getReceivingTransfers() {\n return Array.from(this.receivingTransfers.values()).map(transfer => ({\n fileId: transfer.fileId,\n fileName: transfer.fileName || 'Unknown',\n fileSize: transfer.fileSize || 0,\n progress: Math.round((transfer.receivedCount / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n }));\n }\n\n cancelTransfer(fileId) {\n try {\n if (this.activeTransfers.has(fileId)) {\n this.cleanupTransfer(fileId);\n return true;\n }\n if (this.receivingTransfers.has(fileId)) {\n this.cleanupReceivingTransfer(fileId);\n return true;\n }\n return false;\n } catch (error) {\n console.error('\u274C Failed to cancel transfer:', error);\n return false;\n }\n }\n\n cleanupTransfer(fileId) {\n this.activeTransfers.delete(fileId);\n this.sessionKeys.delete(fileId);\n this.transferNonces.delete(fileId);\n \n // Remove processed chunk IDs for this transfer\n for (const chunkId of this.processedChunks) {\n if (chunkId.startsWith(fileId)) {\n this.processedChunks.delete(chunkId);\n }\n }\n }\n\n // \u2705 \u0423\u041B\u0423\u0427\u0428\u0415\u041D\u041D\u0410\u042F \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u043F\u0430\u043C\u044F\u0442\u0438 \u0434\u043B\u044F \u043F\u0440\u0435\u0434\u043E\u0442\u0432\u0440\u0430\u0449\u0435\u043D\u0438\u044F use-after-free\n cleanupReceivingTransfer(fileId) {\n try {\n // \u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E \u043E\u0447\u0438\u0449\u0430\u0435\u043C pending chunks\n this.pendingChunks.delete(fileId);\n \n const receivingState = this.receivingTransfers.get(fileId);\n if (receivingState) {\n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 receivedChunks \u0441 \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439 \u0437\u0430\u0449\u0438\u0442\u043E\u0439\n if (receivingState.receivedChunks && receivingState.receivedChunks.size > 0) {\n for (const [index, chunk] of receivingState.receivedChunks) {\n try {\n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043D\u0430 \u0432\u0430\u043B\u0438\u0434\u043D\u043E\u0441\u0442\u044C chunk\n if (chunk && (chunk instanceof ArrayBuffer || chunk instanceof Uint8Array)) {\n SecureMemoryManager.secureWipe(chunk);\n \n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 - \u0437\u0430\u043F\u043E\u043B\u043D\u044F\u0435\u043C \u043D\u0443\u043B\u044F\u043C\u0438 \u043F\u0435\u0440\u0435\u0434 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435\u043C\n if (chunk instanceof ArrayBuffer) {\n const view = new Uint8Array(chunk);\n view.fill(0);\n } else if (chunk instanceof Uint8Array) {\n chunk.fill(0);\n }\n }\n } catch (chunkError) {\n console.warn('\u26A0\uFE0F Failed to securely wipe chunk:', chunkError);\n }\n }\n receivingState.receivedChunks.clear();\n }\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 session key\n if (receivingState.sessionKey) {\n try {\n // \u0414\u043B\u044F CryptoKey \u043D\u0435\u043B\u044C\u0437\u044F \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E \u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C, \u043D\u043E \u043C\u043E\u0436\u0435\u043C \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0441\u044B\u043B\u043A\u0443\n receivingState.sessionKey = null;\n } catch (keyError) {\n console.warn('\u26A0\uFE0F Failed to clear session key:', keyError);\n }\n }\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445\n if (receivingState.salt) {\n try {\n if (Array.isArray(receivingState.salt)) {\n receivingState.salt.fill(0);\n }\n receivingState.salt = null;\n } catch (saltError) {\n console.warn('\u26A0\uFE0F Failed to clear salt:', saltError);\n }\n }\n \n // \u041E\u0447\u0438\u0449\u0430\u0435\u043C \u0432\u0441\u0435 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 receivingState\n for (const [key, value] of Object.entries(receivingState)) {\n if (value && typeof value === 'object') {\n if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\n SecureMemoryManager.secureWipe(value);\n } else if (Array.isArray(value)) {\n value.fill(0);\n }\n receivingState[key] = null;\n }\n }\n }\n \n // \u0423\u0434\u0430\u043B\u044F\u0435\u043C \u0438\u0437 \u043E\u0441\u043D\u043E\u0432\u043D\u044B\u0445 \u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u0439\n this.receivingTransfers.delete(fileId);\n this.sessionKeys.delete(fileId);\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u0444\u0438\u043D\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0431\u0443\u0444\u0435\u0440\u0430 \u0444\u0430\u0439\u043B\u0430\n const fileBuffer = this.receivedFileBuffers.get(fileId);\n if (fileBuffer) {\n try {\n if (fileBuffer.buffer) {\n SecureMemoryManager.secureWipe(fileBuffer.buffer);\n \n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 - \u0437\u0430\u043F\u043E\u043B\u043D\u044F\u0435\u043C \u043D\u0443\u043B\u044F\u043C\u0438\n const view = new Uint8Array(fileBuffer.buffer);\n view.fill(0);\n }\n \n // \u041E\u0447\u0438\u0449\u0430\u0435\u043C \u0432\u0441\u0435 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 fileBuffer\n for (const [key, value] of Object.entries(fileBuffer)) {\n if (value && typeof value === 'object') {\n if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\n SecureMemoryManager.secureWipe(value);\n }\n fileBuffer[key] = null;\n }\n }\n \n this.receivedFileBuffers.delete(fileId);\n } catch (bufferError) {\n console.warn('\u26A0\uFE0F Failed to securely clear file buffer:', bufferError);\n // \u041F\u0440\u0438\u043D\u0443\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0443\u0434\u0430\u043B\u044F\u0435\u043C \u0434\u0430\u0436\u0435 \u043F\u0440\u0438 \u043E\u0448\u0438\u0431\u043A\u0435\n this.receivedFileBuffers.delete(fileId);\n }\n }\n \n // \u2705 \u0411\u0415\u0417\u041E\u041F\u0410\u0421\u041D\u0410\u042F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 processed chunks\n const chunksToRemove = [];\n for (const chunkId of this.processedChunks) {\n if (chunkId.startsWith(fileId)) {\n chunksToRemove.push(chunkId);\n }\n }\n \n // \u0423\u0434\u0430\u043B\u044F\u0435\u043C \u0432 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u043C \u0446\u0438\u043A\u043B\u0435 \u0434\u043B\u044F \u0438\u0437\u0431\u0435\u0436\u0430\u043D\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u0438 \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438\n for (const chunkId of chunksToRemove) {\n this.processedChunks.delete(chunkId);\n }\n \n // \u041F\u0440\u0438\u043D\u0443\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u043F\u0430\u043C\u044F\u0442\u0438\n if (typeof global !== 'undefined' && global.gc) {\n try {\n global.gc();\n } catch (gcError) {\n // \u0418\u0433\u043D\u043E\u0440\u0438\u0440\u0443\u0435\u043C \u043E\u0448\u0438\u0431\u043A\u0438 GC\n }\n }\n \n console.log(`\uD83D\uDD12 Memory safely cleaned for file transfer: ${fileId}`);\n \n } catch (error) {\n console.error('\u274C Error during secure memory cleanup:', error);\n \n // \u041F\u0440\u0438\u043D\u0443\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043E\u0447\u0438\u0441\u0442\u043A\u0430 \u0434\u0430\u0436\u0435 \u043F\u0440\u0438 \u043E\u0448\u0438\u0431\u043A\u0435\n this.receivingTransfers.delete(fileId);\n this.sessionKeys.delete(fileId);\n this.receivedFileBuffers.delete(fileId);\n this.pendingChunks.delete(fileId);\n \n throw new Error(`Memory cleanup failed: ${error.message}`);\n }\n }\n\n getTransferStatus(fileId) {\n if (this.activeTransfers.has(fileId)) {\n const transfer = this.activeTransfers.get(fileId);\n return {\n type: 'sending',\n fileId: transfer.fileId,\n fileName: transfer.file.name,\n progress: Math.round((transfer.sentChunks / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n };\n }\n \n if (this.receivingTransfers.has(fileId)) {\n const transfer = this.receivingTransfers.get(fileId);\n return {\n type: 'receiving',\n fileId: transfer.fileId,\n fileName: transfer.fileName,\n progress: Math.round((transfer.receivedCount / transfer.totalChunks) * 100),\n status: transfer.status,\n startTime: transfer.startTime\n };\n }\n \n return null;\n }\n\n getSystemStatus() {\n return {\n initialized: true,\n activeTransfers: this.activeTransfers.size,\n receivingTransfers: this.receivingTransfers.size,\n totalTransfers: this.activeTransfers.size + this.receivingTransfers.size,\n maxConcurrentTransfers: this.MAX_CONCURRENT_TRANSFERS,\n maxFileSize: this.MAX_FILE_SIZE,\n chunkSize: this.CHUNK_SIZE,\n hasWebrtcManager: !!this.webrtcManager,\n isConnected: this.webrtcManager?.isConnected?.() || false,\n hasDataChannel: !!this.webrtcManager?.dataChannel,\n dataChannelState: this.webrtcManager?.dataChannel?.readyState,\n isVerified: this.webrtcManager?.isVerified,\n hasEncryptionKey: !!this.webrtcManager?.encryptionKey,\n hasMacKey: !!this.webrtcManager?.macKey,\n linkedToWebRTCManager: this.webrtcManager?.fileTransferSystem === this,\n supportedFileTypes: this.getSupportedFileTypes(),\n fileTypeInfo: this.getFileTypeInfo()\n };\n }\n\n cleanup() {\n SecureFileTransferContext.getInstance().deactivate();\n\n if (this.webrtcManager && this.webrtcManager.dataChannel && this.originalOnMessage) {\n this.webrtcManager.dataChannel.onmessage = this.originalOnMessage;\n this.originalOnMessage = null;\n }\n \n if (this.webrtcManager && this.originalProcessMessage) {\n this.webrtcManager.processMessage = this.originalProcessMessage;\n this.originalProcessMessage = null;\n }\n \n if (this.webrtcManager && this.originalRemoveSecurityLayers) {\n this.webrtcManager.removeSecurityLayers = this.originalRemoveSecurityLayers;\n this.originalRemoveSecurityLayers = null;\n }\n \n // Cleanup all active transfers with secure memory wiping\n for (const fileId of this.activeTransfers.keys()) {\n this.cleanupTransfer(fileId);\n }\n \n for (const fileId of this.receivingTransfers.keys()) {\n this.cleanupReceivingTransfer(fileId);\n }\n\n if (this.atomicOps) {\n this.atomicOps.locks.clear();\n }\n \n if (this.rateLimiter) {\n this.rateLimiter.requests.clear();\n }\n \n // Clear all state\n this.pendingChunks.clear();\n this.activeTransfers.clear();\n this.receivingTransfers.clear();\n this.transferQueue.length = 0;\n this.sessionKeys.clear();\n this.transferNonces.clear();\n this.processedChunks.clear();\n\n this.clearKeys();\n }\n\n // ============================================\n // SESSION UPDATE HANDLER - FIXED\n // ============================================\n \n onSessionUpdate(sessionData) {\n // Clear session keys cache for resync\n this.sessionKeys.clear();\n }\n\n // ============================================\n // DEBUGGING AND DIAGNOSTICS\n // ============================================\n\n diagnoseFileTransferIssue() {\n const diagnosis = {\n timestamp: new Date().toISOString(),\n fileTransferSystem: {\n initialized: !!this,\n hasWebrtcManager: !!this.webrtcManager,\n webrtcManagerType: this.webrtcManager?.constructor?.name,\n linkedToWebRTCManager: this.webrtcManager?.fileTransferSystem === this\n },\n webrtcManager: {\n hasDataChannel: !!this.webrtcManager?.dataChannel,\n dataChannelState: this.webrtcManager?.dataChannel?.readyState,\n isConnected: this.webrtcManager?.isConnected?.() || false,\n isVerified: this.webrtcManager?.isVerified,\n hasEncryptionKey: !!this.webrtcManager?.encryptionKey,\n hasMacKey: !!this.webrtcManager?.macKey,\n hasKeyFingerprint: !!this.webrtcManager?.keyFingerprint,\n hasSessionSalt: !!this.webrtcManager?.sessionSalt\n },\n securityContext: {\n contextActive: SecureFileTransferContext.getInstance().isActive(),\n securityLevel: SecureFileTransferContext.getInstance().getSecurityLevel(),\n hasAtomicOps: !!this.atomicOps,\n hasRateLimiter: !!this.rateLimiter\n },\n transfers: {\n activeTransfers: this.activeTransfers.size,\n receivingTransfers: this.receivingTransfers.size,\n pendingChunks: this.pendingChunks.size,\n sessionKeys: this.sessionKeys.size\n },\n fileTypeSupport: {\n supportedTypes: this.getSupportedFileTypes(),\n generalMaxSize: this.formatFileSize(this.MAX_FILE_SIZE),\n restrictions: Object.keys(this.FILE_TYPE_RESTRICTIONS)\n }\n };\n \n return diagnosis;\n }\n\n async debugKeyDerivation(fileId) {\n try {\n if (!this.webrtcManager.keyFingerprint || !this.webrtcManager.sessionSalt) {\n throw new Error('Session data not available');\n }\n \n // Test sender derivation\n const senderResult = await this.deriveFileSessionKey(fileId);\n \n // Test receiver derivation with same salt\n const receiverKey = await this.deriveFileSessionKeyFromSalt(fileId, senderResult.salt);\n \n // Test encryption/decryption\n const testData = new TextEncoder().encode('test data');\n const nonce = crypto.getRandomValues(new Uint8Array(12));\n \n const encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv: nonce },\n senderResult.key,\n testData\n );\n \n const decrypted = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv: nonce },\n receiverKey,\n encrypted\n );\n \n const decryptedText = new TextDecoder().decode(decrypted);\n \n if (decryptedText === 'test data') {\n return { success: true, message: 'All tests passed' };\n } else {\n throw new Error('Decryption verification failed');\n }\n \n } catch (error) {\n console.error('\u274C Key derivation test failed:', error);\n return { success: false, error: error.message };\n }\n }\n\n // ============================================\n // ALTERNATIVE METHOD OF INITIALIZING HANDLERS\n // ============================================\n\n registerWithWebRTCManager() {\n if (!this.webrtcManager) {\n throw new Error('WebRTC manager not available');\n }\n\n this.webrtcManager.fileTransferSystem = this;\n\n this.webrtcManager.setFileMessageHandler = (handler) => {\n this.webrtcManager._fileMessageHandler = handler;\n };\n\n this.webrtcManager.setFileMessageHandler((message) => {\n return this.handleFileMessage(message);\n });\n }\n\n static createFileMessageFilter(fileTransferSystem) {\n return async (event) => {\n try {\n if (typeof event.data === 'string') {\n const parsed = JSON.parse(event.data);\n \n if (fileTransferSystem.isFileTransferMessage(parsed)) {\n await fileTransferSystem.handleFileMessage(parsed);\n return true; \n }\n }\n } catch (error) {\n }\n \n return false; \n };\n }\n\n // ============================================\n // SECURITY KEY MANAGEMENT\n // ============================================\n\n setSigningKey(privateKey) {\n if (!privateKey || !(privateKey instanceof CryptoKey)) {\n throw new Error('Invalid private key for signing');\n }\n this.signingKey = privateKey;\n console.log('\uD83D\uDD12 Signing key set successfully');\n }\n\n setVerificationKey(publicKey) {\n if (!publicKey || !(publicKey instanceof CryptoKey)) {\n throw new Error('Invalid public key for verification');\n }\n this.verificationKey = publicKey;\n console.log('\uD83D\uDD12 Verification key set successfully');\n }\n\n async generateSigningKeyPair() {\n try {\n const keyPair = await crypto.subtle.generateKey(\n {\n name: 'RSASSA-PKCS1-v1_5',\n modulusLength: 2048,\n publicExponent: new Uint8Array([1, 0, 1]),\n hash: 'SHA-256'\n },\n true, // extractable\n ['sign', 'verify']\n );\n \n this.signingKey = keyPair.privateKey;\n this.verificationKey = keyPair.publicKey;\n \n console.log('\uD83D\uDD12 RSA key pair generated successfully');\n return keyPair;\n } catch (error) {\n const safeError = SecurityErrorHandler.sanitizeError(error);\n console.error('\u274C Failed to generate signing key pair:', safeError);\n throw new Error(safeError);\n }\n }\n\n clearKeys() {\n this.signingKey = null;\n this.verificationKey = null;\n console.log('\uD83D\uDD12 Security keys cleared');\n }\n\n getSecurityStatus() {\n return {\n signingEnabled: this.signingKey !== null,\n verificationEnabled: this.verificationKey !== null,\n contextActive: SecureFileTransferContext.getInstance().isActive(),\n securityLevel: SecureFileTransferContext.getInstance().getSecurityLevel()\n };\n }\n\n getClientIdentifier() {\n return this.webrtcManager?.connectionId || \n this.webrtcManager?.keyFingerprint?.substring(0, 16) || \n 'default-client';\n }\n \n destroy() {\n SecureFileTransferContext.getInstance().deactivate();\n this.clearKeys();\n console.log('\uD83D\uDD12 File transfer system destroyed safely');\n }\n}\n\nexport { EnhancedSecureFileTransfer };", "// Import EnhancedSecureFileTransfer\r\nimport { EnhancedSecureFileTransfer } from '../transfer/EnhancedSecureFileTransfer.js';\r\n\r\n// MUTEX SYSTEM FIXES - RESOLVING MESSAGE DELIVERY ISSUES\r\n// ============================================\r\n// Issue: After introducing the Mutex system, messages stopped being delivered between users\r\n// Fix: Simplified locking logic \u2014 mutex is used ONLY for critical operations\r\n// - Regular messages are processed WITHOUT mutex\r\n// - File messages are processed WITHOUT mutex \r\n// - Mutex is used ONLY for cryptographic operations\r\n// ============================================\r\n\r\nclass EnhancedSecureWebRTCManager {\r\n // ============================================\r\n // CONSTANTS\r\n // ============================================\r\n \r\n static TIMEOUTS = {\r\n KEY_ROTATION_INTERVAL: 300000, // 5 minutes\r\n CONNECTION_TIMEOUT: 10000, // 10 seconds \r\n HEARTBEAT_INTERVAL: 30000, // 30 seconds\r\n SECURITY_CALC_DELAY: 1000, // 1 second\r\n SECURITY_CALC_RETRY_DELAY: 3000, // 3 seconds\r\n CLEANUP_INTERVAL: 300000, // 5 minutes (periodic cleanup)\r\n CLEANUP_CHECK_INTERVAL: 60000, // 1 minute (cleanup check)\r\n ICE_GATHERING_TIMEOUT: 10000, // 10 seconds\r\n DISCONNECT_CLEANUP_DELAY: 500, // 500ms\r\n PEER_DISCONNECT_CLEANUP: 2000, // 2 seconds\r\n STAGE2_ACTIVATION_DELAY: 10000, // 10 seconds\r\n STAGE3_ACTIVATION_DELAY: 15000, // 15 seconds \r\n STAGE4_ACTIVATION_DELAY: 20000, // 20 seconds\r\n FILE_TRANSFER_INIT_DELAY: 1000, // 1 second\r\n FAKE_TRAFFIC_MIN_INTERVAL: 15000, // 15 seconds\r\n FAKE_TRAFFIC_MAX_INTERVAL: 30000, // 30 seconds\r\n DECOY_INITIAL_DELAY: 5000, // 5 seconds\r\n DECOY_TRAFFIC_MIN: 10000, // 10 seconds\r\n DECOY_TRAFFIC_MAX: 25000, // 25 seconds\r\n REORDER_TIMEOUT: 3000, // 3 seconds\r\n RETRY_CONNECTION_DELAY: 2000 // 2 seconds\r\n };\r\n\r\n static LIMITS = {\r\n MAX_CONNECTION_ATTEMPTS: 3,\r\n MAX_OLD_KEYS: 3,\r\n MAX_PROCESSED_MESSAGE_IDS: 1000,\r\n MAX_OUT_OF_ORDER_PACKETS: 5,\r\n MAX_DECOY_CHANNELS: 1,\r\n MESSAGE_RATE_LIMIT: 60, // messages per minute\r\n MAX_KEY_AGE: 900000, // 15 minutes\r\n OFFER_MAX_AGE: 3600000, // 1 hour\r\n SALT_SIZE_V3: 32, // bytes\r\n SALT_SIZE_V4: 64 // bytes\r\n };\r\n\r\n static SIZES = {\r\n VERIFICATION_CODE_MIN_LENGTH: 6,\r\n FAKE_TRAFFIC_MIN_SIZE: 32,\r\n FAKE_TRAFFIC_MAX_SIZE: 128,\r\n PACKET_PADDING_MIN: 64,\r\n PACKET_PADDING_MAX: 512,\r\n CHUNK_SIZE_MAX: 2048,\r\n CHUNK_DELAY_MIN: 100,\r\n CHUNK_DELAY_MAX: 500,\r\n FINGERPRINT_DISPLAY_LENGTH: 8,\r\n SESSION_ID_LENGTH: 16,\r\n NESTED_ENCRYPTION_IV_SIZE: 12\r\n };\r\n\r\n static MESSAGE_TYPES = {\r\n // Regular messages\r\n MESSAGE: 'message',\r\n ENHANCED_MESSAGE: 'enhanced_message',\r\n \r\n // System messages\r\n HEARTBEAT: 'heartbeat',\r\n VERIFICATION: 'verification',\r\n VERIFICATION_RESPONSE: 'verification_response',\r\n VERIFICATION_CONFIRMED: 'verification_confirmed',\r\n VERIFICATION_BOTH_CONFIRMED: 'verification_both_confirmed',\r\n PEER_DISCONNECT: 'peer_disconnect',\r\n SECURITY_UPGRADE: 'security_upgrade',\r\n KEY_ROTATION_SIGNAL: 'key_rotation_signal',\r\n KEY_ROTATION_READY: 'key_rotation_ready',\r\n \r\n // File transfer messages\r\n FILE_TRANSFER_START: 'file_transfer_start',\r\n FILE_TRANSFER_RESPONSE: 'file_transfer_response',\r\n FILE_CHUNK: 'file_chunk',\r\n CHUNK_CONFIRMATION: 'chunk_confirmation',\r\n FILE_TRANSFER_COMPLETE: 'file_transfer_complete',\r\n FILE_TRANSFER_ERROR: 'file_transfer_error',\r\n \r\n // Fake traffic\r\n FAKE: 'fake'\r\n };\r\n\r\n static FILTERED_RESULTS = {\r\n FAKE_MESSAGE: 'FAKE_MESSAGE_FILTERED',\r\n FILE_MESSAGE: 'FILE_MESSAGE_FILTERED', \r\n SYSTEM_MESSAGE: 'SYSTEM_MESSAGE_FILTERED'\r\n };\r\n\r\n // Static debug flag instead of this._debugMode\r\n static DEBUG_MODE = true; // Set to true during development, false in production\r\n\r\n\r\n constructor(onMessage, onStatusChange, onKeyExchange, onVerificationRequired, onAnswerError = null, onVerificationStateChange = null, config = {}) {\r\n // Determine runtime mode\r\n this._isProductionMode = this._detectProductionMode();\r\n // Use static flag instead of this._debugMode\r\n this._debugMode = !this._isProductionMode && EnhancedSecureWebRTCManager.DEBUG_MODE;\r\n \r\n // Configuration from constructor parameters instead of global flags\r\n this._config = {\r\n fakeTraffic: {\r\n enabled: config.fakeTraffic?.enabled ?? true,\r\n minInterval: config.fakeTraffic?.minInterval ?? EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MIN_INTERVAL,\r\n maxInterval: config.fakeTraffic?.maxInterval ?? EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MAX_INTERVAL,\r\n minSize: config.fakeTraffic?.minSize ?? EnhancedSecureWebRTCManager.SIZES.FAKE_TRAFFIC_MIN_SIZE,\r\n maxSize: config.fakeTraffic?.maxSize ?? EnhancedSecureWebRTCManager.SIZES.FAKE_TRAFFIC_MAX_SIZE,\r\n patterns: config.fakeTraffic?.patterns ?? ['heartbeat', 'status', 'sync']\r\n },\r\n decoyChannels: {\r\n enabled: config.decoyChannels?.enabled ?? true,\r\n maxDecoyChannels: config.decoyChannels?.maxDecoyChannels ?? EnhancedSecureWebRTCManager.LIMITS.MAX_DECOY_CHANNELS,\r\n decoyChannelNames: config.decoyChannels?.decoyChannelNames ?? ['heartbeat'],\r\n sendDecoyData: config.decoyChannels?.sendDecoyData ?? true,\r\n randomDecoyIntervals: config.decoyChannels?.randomDecoyIntervals ?? true\r\n },\r\n packetPadding: {\r\n enabled: config.packetPadding?.enabled ?? true,\r\n minPadding: config.packetPadding?.minPadding ?? EnhancedSecureWebRTCManager.SIZES.PACKET_PADDING_MIN,\r\n maxPadding: config.packetPadding?.maxPadding ?? EnhancedSecureWebRTCManager.SIZES.PACKET_PADDING_MAX,\r\n useRandomPadding: config.packetPadding?.useRandomPadding ?? true,\r\n preserveMessageSize: config.packetPadding?.preserveMessageSize ?? false\r\n },\r\n antiFingerprinting: {\r\n enabled: config.antiFingerprinting?.enabled ?? false,\r\n randomizeTiming: config.antiFingerprinting?.randomizeTiming ?? true,\r\n randomizeSizes: config.antiFingerprinting?.randomizeSizes ?? false,\r\n addNoise: config.antiFingerprinting?.addNoise ?? true,\r\n maskPatterns: config.antiFingerprinting?.maskPatterns ?? false,\r\n useRandomHeaders: config.antiFingerprinting?.useRandomHeaders ?? false\r\n }\r\n };\r\n\r\n // Initialize own logging system\r\n this._initializeSecureLogging();\r\n this._setupOwnLogger();\r\n this._setupProductionLogging();\r\n \r\n // Store important methods first\r\n this._storeImportantMethods();\r\n \r\n // Setup global API after storing methods\r\n this._setupSecureGlobalAPI();\r\n if (!window.EnhancedSecureCryptoUtils) {\r\n throw new Error('EnhancedSecureCryptoUtils is not loaded. Please ensure the module is loaded first.');\r\n }\r\n this.getSecurityData = () => {\r\n // Return only public information\r\n return this.lastSecurityCalculation ? {\r\n level: this.lastSecurityCalculation.level,\r\n score: this.lastSecurityCalculation.score,\r\n timestamp: this.lastSecurityCalculation.timestamp,\r\n // Do NOT return check details or sensitive data\r\n } : null;\r\n };\r\n this._secureLog('info', '\uD83D\uDD12 Enhanced WebRTC Manager initialized with secure API');\r\n this.sessionConstraints = null;\r\n this.peerConnection = null;\r\n this.dataChannel = null;\r\n\r\n\r\n this.onMessage = onMessage;\r\n this.onStatusChange = onStatusChange;\r\n this.onKeyExchange = onKeyExchange;\r\n this.onVerificationStateChange = onVerificationStateChange;\r\n\r\n this.onVerificationRequired = onVerificationRequired;\r\n this.onAnswerError = onAnswerError; // Callback for response processing errors\r\n this.isInitiator = false;\r\n this.connectionAttempts = 0;\r\n this.maxConnectionAttempts = EnhancedSecureWebRTCManager.LIMITS.MAX_CONNECTION_ATTEMPTS;\r\n try {\r\n this._initializeMutexSystem();\r\n} catch (error) {\r\n this._secureLog('error', '\u274C Failed to initialize mutex system', {\r\n errorType: error.constructor.name\r\n });\r\n throw new Error('Critical: Mutex system initialization failed');\r\n}\r\n\r\n// Post-initialization validation of the mutex system\r\nif (!this._validateMutexSystem()) {\r\n this._secureLog('error', '\u274C Mutex system validation failed after initialization');\r\n throw new Error('Critical: Mutex system validation failed');\r\n}\r\n\r\nif (typeof window !== 'undefined') {\r\n this._secureLog('info', '\uD83D\uDD12 Emergency mutex handlers will be available through secure API');\r\n}\r\n\r\nthis._secureLog('info', '\uD83D\uDD12 Enhanced Mutex system fully initialized and validated');\r\n this.heartbeatInterval = null;\r\n this.messageQueue = [];\r\n this.ecdhKeyPair = null;\r\n this.ecdsaKeyPair = null;\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n this.verificationCode = null;\r\n this.pendingSASCode = null;\r\n this.isVerified = false;\r\n this.processedMessageIds = new Set();\r\n \r\n // Mutual verification states\r\n this.localVerificationConfirmed = false;\r\n this.remoteVerificationConfirmed = false;\r\n this.bothVerificationsConfirmed = false;\r\n \r\n // Store expected DTLS fingerprint for validation\r\n this.expectedDTLSFingerprint = null;\r\n this.strictDTLSValidation = true; // Can be disabled for debugging\r\n \r\n // Real Perfect Forward Secrecy implementation\r\n this.ephemeralKeyPairs = new Map(); // Store ephemeral keys for current session only\r\n this.sessionStartTime = Date.now(); // Track session lifetime for PFS\r\n this.messageCounter = 0;\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.sessionSalt = null;\r\n \r\n // Anti-Replay and Message Ordering Protection\r\n this.replayWindowSize = 64; // Sliding window for replay protection\r\n this.replayWindow = new Set(); // Track recent sequence numbers\r\n this.maxSequenceGap = 100; // Maximum allowed sequence gap\r\n this.replayProtectionEnabled = true; // Enable/disable replay protection\r\n this.sessionId = null; // MITM protection: Session identifier\r\n this.connectionId = Array.from(crypto.getRandomValues(new Uint8Array(8)))\r\n .map(b => b.toString(16).padStart(2, '0')).join(''); // Connection identifier for AAD\r\n this.peerPublicKey = null; // Store peer's public key for PFS\r\n this.rateLimiterId = null;\r\n this.intentionalDisconnect = false;\r\n this.lastCleanupTime = Date.now();\r\n \r\n // Reset notification flags for new connection\r\n this._resetNotificationFlags();\r\n \r\n \r\n\r\n this.verificationInitiationSent = false;\r\n this.disconnectNotificationSent = false;\r\n this.reconnectionFailedNotificationSent = false;\r\n this.peerDisconnectNotificationSent = false;\r\n this.connectionClosedNotificationSent = false;\r\n this.fakeTrafficDisabledNotificationSent = false;\r\n this.advancedFeaturesDisabledNotificationSent = false;\r\n this.securityUpgradeNotificationSent = false;\r\n this.lastSecurityUpgradeStage = null;\r\n this.securityCalculationNotificationSent = false;\r\n this.lastSecurityCalculationLevel = null;\r\n \r\n // File transfer integration\r\n this.fileTransferSystem = null;\r\n this.onFileProgress = null;\r\n \r\n // ============================================\r\n // IV REUSE PREVENTION SYSTEM\r\n // ============================================\r\n // IV REUSE PREVENTION SYSTEM WITH LIMITS\r\n // ============================================\r\n this._ivTrackingSystem = {\r\n usedIVs: new Set(), // Track all used IVs to prevent reuse\r\n ivHistory: new Map(), // Track IV usage with timestamps (max 10k entries)\r\n collisionCount: 0, // Track potential collisions\r\n maxIVHistorySize: 10000, // Maximum IV history size\r\n maxSessionIVs: 1000, // Maximum IVs per session\r\n entropyValidation: {\r\n minEntropy: 3.0, // Minimum entropy threshold\r\n entropyTests: 0,\r\n entropyFailures: 0\r\n },\r\n rngValidation: {\r\n testsPerformed: 0,\r\n weakRngDetected: false,\r\n lastValidation: 0\r\n },\r\n sessionIVs: new Map(), // Track IVs per session\r\n emergencyMode: false // Emergency mode if IV reuse detected\r\n };\r\n \r\n // IV cleanup tracking\r\n this._lastIVCleanupTime = null;\r\n \r\n // ============================================\r\n // SECURE ERROR HANDLING SYSTEM\r\n // ============================================\r\n this._secureErrorHandler = {\r\n errorCategories: {\r\n CRYPTOGRAPHIC: 'cryptographic',\r\n NETWORK: 'network',\r\n VALIDATION: 'validation',\r\n SYSTEM: 'system',\r\n UNKNOWN: 'unknown'\r\n },\r\n errorMappings: new Map(), // Map internal errors to safe messages\r\n errorCounts: new Map(), // Track error frequencies\r\n lastErrorTime: 0,\r\n errorThreshold: 10, // Max errors per minute\r\n isInErrorMode: false\r\n };\r\n \r\n // ============================================\r\n // SECURE MEMORY MANAGEMENT SYSTEM\r\n // ============================================\r\n this._secureMemoryManager = {\r\n sensitiveData: new WeakMap(), // Track sensitive data for secure cleanup\r\n cleanupQueue: [], // Queue for deferred cleanup operations\r\n isCleaning: false, // Prevent concurrent cleanup operations\r\n cleanupInterval: null, // Periodic cleanup timer\r\n memoryStats: {\r\n totalCleanups: 0,\r\n failedCleanups: 0,\r\n lastCleanup: 0\r\n }\r\n };\r\n this.onFileReceived = null;\r\n this.onFileError = null;\r\n \r\n // PFS (Perfect Forward Secrecy) Implementation\r\n this.keyRotationInterval = EnhancedSecureWebRTCManager.TIMEOUTS.KEY_ROTATION_INTERVAL;\r\n this.lastKeyRotation = Date.now();\r\n this.currentKeyVersion = 0;\r\n this.keyVersions = new Map(); // Store key versions for PFS\r\n this.oldKeys = new Map(); // Store old keys temporarily for decryption\r\n this.maxOldKeys = EnhancedSecureWebRTCManager.LIMITS.MAX_OLD_KEYS; // Keep last 3 key versions for decryption\r\n this.peerConnection = null;\r\n this.dataChannel = null;\r\n \r\n\r\n this.securityFeatures = {\r\n // All security features enabled by default - no payment required\r\n hasEncryption: true, \r\n hasECDH: true, \r\n hasECDSA: true, \r\n hasMutualAuth: true, \r\n hasMetadataProtection: true, \r\n hasEnhancedReplayProtection: true, \r\n hasNonExtractableKeys: true, \r\n hasRateLimiting: true, \r\n hasEnhancedValidation: true, \r\n hasPFS: true, // Real Perfect Forward Secrecy enabled \r\n \r\n // Advanced Features - All enabled by default\r\n hasNestedEncryption: true, \r\n hasPacketPadding: true, \r\n hasPacketReordering: true, \r\n hasAntiFingerprinting: true, \r\n hasFakeTraffic: true, \r\n hasDecoyChannels: true, \r\n hasMessageChunking: true \r\n };\r\n this._secureLog('info', '\uD83D\uDD12 Enhanced WebRTC Manager initialized with tiered security');\r\n \r\n // Log configuration for debugging\r\n this._secureLog('info', '\uD83D\uDD12 Configuration loaded from constructor parameters', {\r\n fakeTraffic: this._config.fakeTraffic.enabled,\r\n decoyChannels: this._config.decoyChannels.enabled,\r\n packetPadding: this._config.packetPadding.enabled,\r\n antiFingerprinting: this._config.antiFingerprinting.enabled\r\n });\r\n \r\n // XSS Hardening - replace all window.DEBUG_MODE references\r\n this._hardenDebugModeReferences();\r\n \r\n // Initialize unified scheduler for all maintenance tasks\r\n this._initializeUnifiedScheduler();\r\n \r\n this._syncSecurityFeaturesWithTariff();\r\n \r\n if (!this._validateCryptographicSecurity()) {\r\n this._secureLog('error', '\uD83D\uDEA8 CRITICAL: Cryptographic security validation failed after tariff sync');\r\n throw new Error('Critical cryptographic features are missing after tariff synchronization');\r\n }\r\n // ============================================\r\n // ENHANCED SECURITY FEATURES\r\n // ============================================\r\n \r\n // 1. Nested Encryption Layer\r\n this.nestedEncryptionKey = null;\r\n // Removed nestedEncryptionIV and nestedEncryptionCounter\r\n // Each nested encryption now generates fresh random IV for maximum security\r\n \r\n // 2. Packet Padding\r\n this.paddingConfig = {\r\n enabled: this._config.packetPadding.enabled,\r\n minPadding: this._config.packetPadding.minPadding,\r\n maxPadding: this._config.packetPadding.maxPadding,\r\n useRandomPadding: this._config.packetPadding.useRandomPadding,\r\n preserveMessageSize: this._config.packetPadding.preserveMessageSize\r\n };\r\n \r\n // 3. Fake Traffic Generation\r\n this.fakeTrafficConfig = {\r\n enabled: this._config.fakeTraffic?.enabled || false,\r\n minInterval: this._config.fakeTraffic?.minInterval || 15000,\r\n maxInterval: this._config.fakeTraffic?.maxInterval || 30000,\r\n minSize: this._config.fakeTraffic?.minSize || 64,\r\n maxSize: this._config.fakeTraffic?.maxSize || 1024,\r\n patterns: this._config.fakeTraffic?.patterns || ['heartbeat', 'status', 'ping'],\r\n randomDecoyIntervals: this._config.fakeTraffic?.randomDecoyIntervals || true\r\n };\r\n this.fakeTrafficTimer = null;\r\n this.lastFakeTraffic = 0;\r\n \r\n // 4. Message Chunking\r\n this.chunkingConfig = {\r\n enabled: false,\r\n maxChunkSize: EnhancedSecureWebRTCManager.SIZES.CHUNK_SIZE_MAX, \r\n minDelay: EnhancedSecureWebRTCManager.SIZES.CHUNK_DELAY_MIN,\r\n maxDelay: EnhancedSecureWebRTCManager.SIZES.CHUNK_DELAY_MAX,\r\n useRandomDelays: true,\r\n addChunkHeaders: true\r\n };\r\n this.chunkQueue = [];\r\n this.chunkingInProgress = false;\r\n \r\n // 5. Decoy Channels\r\n this.decoyChannels = new Map();\r\n this.decoyChannelConfig = {\r\n enabled: this._config.decoyChannels.enabled,\r\n maxDecoyChannels: this._config.decoyChannels.maxDecoyChannels,\r\n decoyChannelNames: this._config.decoyChannels.decoyChannelNames,\r\n sendDecoyData: this._config.decoyChannels.sendDecoyData,\r\n randomDecoyIntervals: this._config.decoyChannels.randomDecoyIntervals\r\n };\r\n this.decoyTimers = new Map();\r\n \r\n // 6. Packet Reordering Protection\r\n this.reorderingConfig = {\r\n enabled: false, \r\n maxOutOfOrder: EnhancedSecureWebRTCManager.LIMITS.MAX_OUT_OF_ORDER_PACKETS, \r\n reorderTimeout: EnhancedSecureWebRTCManager.TIMEOUTS.REORDER_TIMEOUT, \r\n useSequenceNumbers: true,\r\n useTimestamps: true\r\n };\r\n this.packetBuffer = new Map(); // sequence -> {data, timestamp}\r\n this.lastProcessedSequence = -1;\r\n \r\n // 7. Anti-Fingerprinting\r\n this.antiFingerprintingConfig = {\r\n enabled: this._config.antiFingerprinting.enabled,\r\n randomizeTiming: this._config.antiFingerprinting.randomizeTiming,\r\n randomizeSizes: this._config.antiFingerprinting.randomizeSizes,\r\n addNoise: this._config.antiFingerprinting.addNoise,\r\n maskPatterns: this._config.antiFingerprinting.maskPatterns,\r\n useRandomHeaders: this._config.antiFingerprinting.useRandomHeaders\r\n };\r\n this.fingerprintMask = this.generateFingerprintMask();\r\n \r\n // Initialize rate limiter ID\r\n this.rateLimiterId = `webrtc_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n \r\n // Start periodic cleanup\r\n this.startPeriodicCleanup();\r\n \r\n this.initializeEnhancedSecurity(); \r\n \r\n // ============================================\r\n // MUTEX SYSTEM TO PREVENT RACE CONDITIONS\r\n // ============================================\r\n\r\n // Mutex for key operations\r\n this._keyOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null\r\n };\r\n\r\n // Mutex for encryption/decryption operations\r\n this._cryptoOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null\r\n };\r\n\r\n // Mutex for connection initialization\r\n this._connectionOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null\r\n };\r\n\r\n // Key system state\r\n this._keySystemState = {\r\n isInitializing: false,\r\n isRotating: false,\r\n isDestroying: false,\r\n lastOperation: null,\r\n lastOperationTime: Date.now()\r\n };\r\n\r\n // Operation counters\r\n this._operationCounters = {\r\n keyOperations: 0,\r\n cryptoOperations: 0,\r\n connectionOperations: 0\r\n };\r\n\r\n }\r\n \r\n /**\r\n * Create AAD with sequence number for anti-replay protection\r\n * This binds each message to its sequence number and prevents replay attacks\r\n */\r\n _createMessageAAD(messageType, messageData = null, isFileMessage = false) {\r\n try {\r\n const aad = {\r\n sessionId: this.currentSession?.sessionId || this.sessionId || 'unknown',\r\n keyFingerprint: this.keyFingerprint || 'unknown',\r\n sequenceNumber: this._generateNextSequenceNumber(),\r\n messageType: messageType,\r\n timestamp: Date.now(),\r\n connectionId: this.connectionId || 'unknown',\r\n isFileMessage: isFileMessage\r\n };\r\n\r\n // Add message-specific data if available\r\n if (messageData && typeof messageData === 'object') {\r\n if (messageData.fileId) aad.fileId = messageData.fileId;\r\n if (messageData.chunkIndex !== undefined) aad.chunkIndex = messageData.chunkIndex;\r\n if (messageData.totalChunks !== undefined) aad.totalChunks = messageData.totalChunks;\r\n }\r\n\r\n return JSON.stringify(aad);\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to create message AAD', {\r\n errorType: error.constructor.name,\r\n message: error.message,\r\n messageType: messageType\r\n });\r\n // Fallback to basic AAD\r\n return JSON.stringify({\r\n sessionId: 'unknown',\r\n keyFingerprint: 'unknown',\r\n sequenceNumber: Date.now(),\r\n messageType: messageType,\r\n timestamp: Date.now(),\r\n connectionId: 'unknown',\r\n isFileMessage: isFileMessage\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Generate next sequence number for outgoing messages\r\n * This ensures unique ordering and prevents replay attacks\r\n */\r\n _generateNextSequenceNumber() {\r\n const nextSeq = this.sequenceNumber++;\r\n \r\n // Reset sequence number if it gets too large\r\n if (this.sequenceNumber > Number.MAX_SAFE_INTEGER - 1000) {\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.replayWindow.clear();\r\n this._secureLog('warn', '\u26A0\uFE0F Sequence number reset due to overflow', {\r\n timestamp: Date.now()\r\n });\r\n }\r\n \r\n return nextSeq;\r\n }\r\n\r\n /**\r\n * Create a safe hash for logging sensitive data\r\n * Returns only the first 4 bytes (8 hex chars) of SHA-256 hash\r\n * @param {any} sensitiveData - The sensitive data to hash\r\n * @param {string} context - Context for error logging\r\n * @returns {Promise} - Short hash (8 hex chars) or 'hash_error'\r\n */\r\n async _createSafeLogHash(sensitiveData, context = 'unknown') {\r\n try {\r\n let dataToHash;\r\n \r\n // Convert different data types to consistent format for hashing\r\n if (sensitiveData instanceof ArrayBuffer) {\r\n dataToHash = new Uint8Array(sensitiveData);\r\n } else if (sensitiveData instanceof Uint8Array) {\r\n dataToHash = sensitiveData;\r\n } else if (sensitiveData instanceof CryptoKey) {\r\n // For CryptoKey, use its type and algorithm info (not the key material)\r\n const keyInfo = `${sensitiveData.type}_${sensitiveData.algorithm?.name || 'unknown'}_${sensitiveData.extractable}`;\r\n dataToHash = new TextEncoder().encode(keyInfo);\r\n } else if (typeof sensitiveData === 'string') {\r\n dataToHash = new TextEncoder().encode(sensitiveData);\r\n } else if (typeof sensitiveData === 'object' && sensitiveData !== null) {\r\n // For objects (like JWK), stringify without sensitive fields\r\n const safeObj = { type: sensitiveData.kty || 'unknown', use: sensitiveData.use || 'unknown' };\r\n dataToHash = new TextEncoder().encode(JSON.stringify(safeObj));\r\n } else {\r\n // Fallback for other types\r\n dataToHash = new TextEncoder().encode(String(sensitiveData));\r\n }\r\n \r\n // Create SHA-256 hash\r\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataToHash);\r\n const hashArray = new Uint8Array(hashBuffer);\r\n \r\n // Return only first 4 bytes as hex (8 characters)\r\n return Array.from(hashArray.slice(0, 4))\r\n .map(b => b.toString(16).padStart(2, '0'))\r\n .join('');\r\n \r\n } catch (error) {\r\n // Never log the actual error details to avoid leaking sensitive data\r\n return 'hash_error';\r\n }\r\n }\r\n\r\n /**\r\n * Async sleep helper - replaces busy-wait\r\n */\r\n async _asyncSleep(ms) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n /**\r\n * Async cleanup helper - replaces immediate heavy operations\r\n */\r\n async _scheduleAsyncCleanup(cleanupFn, delay = 0) {\r\n return new Promise((resolve) => {\r\n setTimeout(async () => {\r\n try {\r\n await cleanupFn();\r\n resolve(true);\r\n } catch (error) {\r\n this._secureLog('error', 'Async cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n resolve(false);\r\n }\r\n }, delay);\r\n });\r\n }\r\n\r\n /**\r\n * Batch async operations to prevent UI blocking\r\n */\r\n async _batchAsyncOperation(items, batchSize = 10, delayBetweenBatches = 5) {\r\n const results = [];\r\n \r\n for (let i = 0; i < items.length; i += batchSize) {\r\n const batch = items.slice(i, i + batchSize);\r\n const batchResults = await Promise.all(batch);\r\n results.push(...batchResults);\r\n \r\n // Small delay between batches to prevent UI blocking\r\n if (i + batchSize < items.length) {\r\n await this._asyncSleep(delayBetweenBatches);\r\n }\r\n }\r\n \r\n return results;\r\n }\r\n\r\n /**\r\n * Memory cleanup without window.gc() - uses natural garbage collection\r\n */\r\n async _performNaturalCleanup() {\r\n // Clear references and let JS engine handle GC naturally\r\n // This is more reliable than forcing GC\r\n \r\n // Schedule cleanup in next event loop cycle\r\n await this._asyncSleep(0);\r\n \r\n // Allow multiple event loop cycles for natural GC\r\n for (let i = 0; i < 3; i++) {\r\n await this._asyncSleep(10);\r\n }\r\n }\r\n\r\n /**\r\n * Heavy cleanup operations using WebWorker (if available)\r\n */\r\n async _performHeavyCleanup(cleanupData) {\r\n // Try to use WebWorker for heavy operations\r\n if (typeof Worker !== 'undefined') {\r\n try {\r\n return await this._cleanupWithWorker(cleanupData);\r\n } catch (error) {\r\n this._secureLog('warn', 'WebWorker cleanup failed, falling back to main thread', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n }\r\n }\r\n \r\n // Fallback to main thread with async batching\r\n return await this._cleanupInMainThread(cleanupData);\r\n }\r\n\r\n /**\r\n * Cleanup using WebWorker\r\n */\r\n async _cleanupWithWorker(cleanupData) {\r\n return new Promise((resolve, reject) => {\r\n // Create inline worker for cleanup operations\r\n const workerCode = `\r\n self.onmessage = function(e) {\r\n const { type, data } = e.data;\r\n \r\n try {\r\n switch (type) {\r\n case 'cleanup_arrays':\r\n // Simulate heavy array cleanup\r\n let processed = 0;\r\n for (let i = 0; i < data.count; i++) {\r\n // Simulate work\r\n processed++;\r\n if (processed % 1000 === 0) {\r\n // Yield control periodically\r\n setTimeout(() => {}, 0);\r\n }\r\n }\r\n self.postMessage({ success: true, processed });\r\n break;\r\n \r\n case 'cleanup_objects':\r\n // Simulate object cleanup\r\n const cleaned = data.objects.map(() => null);\r\n self.postMessage({ success: true, cleaned: cleaned.length });\r\n break;\r\n \r\n default:\r\n self.postMessage({ success: true, message: 'Unknown cleanup type' });\r\n }\r\n } catch (error) {\r\n self.postMessage({ success: false, error: error.message });\r\n }\r\n };\r\n `;\r\n \r\n const blob = new Blob([workerCode], { type: 'application/javascript' });\r\n const worker = new Worker(URL.createObjectURL(blob));\r\n \r\n const timeout = setTimeout(() => {\r\n worker.terminate();\r\n reject(new Error('Worker cleanup timeout'));\r\n }, 5000); // 5 second timeout\r\n \r\n worker.onmessage = (e) => {\r\n clearTimeout(timeout);\r\n worker.terminate();\r\n URL.revokeObjectURL(blob);\r\n \r\n if (e.data.success) {\r\n resolve(e.data);\r\n } else {\r\n reject(new Error(e.data.error));\r\n }\r\n };\r\n \r\n worker.onerror = (error) => {\r\n clearTimeout(timeout);\r\n worker.terminate();\r\n URL.revokeObjectURL(blob);\r\n reject(error);\r\n };\r\n \r\n worker.postMessage(cleanupData);\r\n });\r\n }\r\n\r\n /**\r\n * Cleanup in main thread with async batching\r\n */\r\n async _cleanupInMainThread(cleanupData) {\r\n const { type, data } = cleanupData;\r\n \r\n switch (type) {\r\n case 'cleanup_arrays':\r\n // Process in batches to avoid blocking\r\n let processed = 0;\r\n const batchSize = 100;\r\n \r\n while (processed < data.count) {\r\n const batchEnd = Math.min(processed + batchSize, data.count);\r\n \r\n // Process batch\r\n for (let i = processed; i < batchEnd; i++) {\r\n // Simulate cleanup work\r\n }\r\n \r\n processed = batchEnd;\r\n \r\n // Yield control to prevent UI blocking\r\n await this._asyncSleep(1);\r\n }\r\n \r\n return { success: true, processed };\r\n \r\n case 'cleanup_objects':\r\n // Clean objects in batches\r\n const objects = data.objects || [];\r\n const batches = [];\r\n \r\n for (let i = 0; i < objects.length; i += 50) {\r\n batches.push(objects.slice(i, i + 50));\r\n }\r\n \r\n let cleaned = 0;\r\n for (const batch of batches) {\r\n batch.forEach(() => cleaned++);\r\n await this._asyncSleep(1);\r\n }\r\n \r\n return { success: true, cleaned };\r\n \r\n default:\r\n return { success: true, message: 'Unknown cleanup type' };\r\n }\r\n }\r\n \r\n /**\r\n * Enhanced mutex system initialization with atomic protection\r\n */\r\n _initializeMutexSystem() {\r\n // Initialize standard mutexes with enhanced state tracking\r\n this._keyOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null,\r\n lockTime: null,\r\n operationCount: 0\r\n };\r\n\r\n this._cryptoOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null,\r\n lockTime: null,\r\n operationCount: 0\r\n };\r\n\r\n this._connectionOperationMutex = {\r\n locked: false,\r\n queue: [],\r\n lockId: null,\r\n lockTimeout: null,\r\n lockTime: null,\r\n operationCount: 0\r\n };\r\n\r\n // Enhanced key system state with atomic operation tracking\r\n this._keySystemState = {\r\n isInitializing: false,\r\n isRotating: false,\r\n isDestroying: false,\r\n lastOperation: null,\r\n lastOperationTime: Date.now(),\r\n operationId: null,\r\n concurrentOperations: 0,\r\n maxConcurrentOperations: 1\r\n };\r\n\r\n // Operation counters with atomic increments\r\n this._operationCounters = {\r\n keyOperations: 0,\r\n cryptoOperations: 0,\r\n connectionOperations: 0,\r\n totalOperations: 0,\r\n failedOperations: 0\r\n };\r\n\r\n this._secureLog('info', '\uD83D\uDD12 Enhanced mutex system initialized with atomic protection', {\r\n mutexes: ['keyOperation', 'cryptoOperation', 'connectionOperation'],\r\n timestamp: Date.now(),\r\n features: ['atomic_operations', 'race_condition_protection', 'enhanced_state_tracking']\r\n });\r\n }\r\n\r\n /**\r\n * XSS Hardening - Debug mode references validation\r\n * This method is called during initialization to ensure XSS hardening\r\n */\r\n _hardenDebugModeReferences() {\r\n // Log that we're hardening debug mode references\r\n this._secureLog('info', '\uD83D\uDD12 XSS Hardening: Debug mode references already replaced');\r\n }\r\n\r\n /**\r\n * Unified scheduler for all maintenance tasks\r\n * Replaces multiple setInterval calls with a single, controlled scheduler\r\n */\r\n _initializeUnifiedScheduler() {\r\n // Single scheduler interval for all maintenance tasks\r\n this._maintenanceScheduler = setInterval(() => {\r\n this._executeMaintenanceCycle();\r\n }, 300000); // Every 5 minutes\r\n \r\n // Log scheduler initialization\r\n this._secureLog('info', '\uD83D\uDD27 Unified maintenance scheduler initialized (5-minute cycle)');\r\n \r\n // Store scheduler reference for cleanup\r\n this._activeTimers = new Set([this._maintenanceScheduler]);\r\n }\r\n\r\n /**\r\n * Execute all maintenance tasks in a single cycle\r\n */\r\n _executeMaintenanceCycle() {\r\n try {\r\n this._secureLog('info', '\uD83D\uDD27 Starting maintenance cycle');\r\n \r\n // 1. Log cleanup and security audit\r\n this._cleanupLogs();\r\n this._auditLoggingSystemSecurity();\r\n \r\n // 2. Security monitoring\r\n this._verifyAPIIntegrity();\r\n this._validateCryptographicSecurity();\r\n this._syncSecurityFeaturesWithTariff();\r\n \r\n // 3. Resource cleanup\r\n this._cleanupResources();\r\n this._enforceResourceLimits();\r\n \r\n // 4. Key monitoring (if connected)\r\n if (this.isConnected && this.isVerified) {\r\n this._monitorKeySecurity();\r\n }\r\n \r\n // 5. Global exposure monitoring (debug mode only)\r\n if (this._debugMode) {\r\n this._monitorGlobalExposure();\r\n }\r\n \r\n // 6. Heartbeat (if enabled and connected)\r\n if (this._heartbeatConfig && this._heartbeatConfig.enabled && this.isConnected()) {\r\n this._sendHeartbeat();\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD27 Maintenance cycle completed successfully');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Maintenance cycle failed', {\r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n \r\n // Emergency cleanup on failure\r\n this._emergencyCleanup().catch(error => {\r\n this._secureLog('error', 'Emergency cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Enforce hard resource limits with emergency cleanup\r\n */\r\n _enforceResourceLimits() {\r\n const violations = [];\r\n \r\n // Check log entries\r\n if (this._logCounts.size > this._resourceLimits.maxLogEntries) {\r\n violations.push('log_entries');\r\n }\r\n \r\n // Check message queue\r\n if (this.messageQueue.length > this._resourceLimits.maxMessageQueue) {\r\n violations.push('message_queue');\r\n }\r\n \r\n // Check IV history\r\n if (this._ivTrackingSystem && this._ivTrackingSystem.ivHistory.size > this._resourceLimits.maxIVHistory) {\r\n violations.push('iv_history');\r\n }\r\n \r\n // Check processed message IDs\r\n if (this.processedMessageIds.size > this._resourceLimits.maxProcessedMessageIds) {\r\n violations.push('processed_message_ids');\r\n }\r\n \r\n // Check decoy channels\r\n if (this.decoyChannels.size > this._resourceLimits.maxDecoyChannels) {\r\n violations.push('decoy_channels');\r\n }\r\n \r\n // Check fake traffic messages\r\n if (this._fakeTrafficMessages && this._fakeTrafficMessages.length > this._resourceLimits.maxFakeTrafficMessages) {\r\n violations.push('fake_traffic_messages');\r\n }\r\n \r\n // Check chunk queue\r\n if (this.chunkQueue.length > this._resourceLimits.maxChunkQueue) {\r\n violations.push('chunk_queue');\r\n }\r\n \r\n // Check packet buffer\r\n if (this.packetBuffer && this.packetBuffer.size > this._resourceLimits.maxPacketBuffer) {\r\n violations.push('packet_buffer');\r\n }\r\n \r\n // If violations detected, trigger emergency cleanup\r\n if (violations.length > 0) {\r\n this._secureLog('warn', '\u26A0\uFE0F Resource limit violations detected', { violations });\r\n this._emergencyCleanup().catch(error => {\r\n this._secureLog('error', 'Emergency cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Emergency cleanup when resource limits are exceeded\r\n */\r\n async _emergencyCleanup() {\r\n this._secureLog('warn', '\uD83D\uDEA8 EMERGENCY: Resource limits exceeded, performing emergency cleanup');\r\n \r\n try {\r\n // 1. Clear all logs immediately\r\n this._logCounts.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: All logs cleared');\r\n \r\n // 2. Clear message queue\r\n this.messageQueue.length = 0;\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Message queue cleared');\r\n \r\n // 3. Enhanced IV history cleanup\r\n if (this._ivTrackingSystem) {\r\n this._ivTrackingSystem.usedIVs.clear();\r\n this._ivTrackingSystem.ivHistory.clear();\r\n this._ivTrackingSystem.sessionIVs.clear();\r\n this._ivTrackingSystem.collisionCount = 0;\r\n this._ivTrackingSystem.emergencyMode = false;\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: IV tracking system cleared');\r\n }\r\n \r\n // 4. Clear processed message IDs\r\n this.processedMessageIds.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Processed message IDs cleared');\r\n \r\n // 5. Enhanced decoy channels cleanup\r\n if (this.decoyChannels) {\r\n for (const [channelName, timer] of this.decoyTimers) {\r\n if (timer) clearTimeout(timer);\r\n }\r\n this.decoyChannels.clear();\r\n this.decoyTimers.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Decoy channels cleared');\r\n }\r\n \r\n // 6. Enhanced fake traffic cleanup\r\n if (this.fakeTrafficTimer) {\r\n clearTimeout(this.fakeTrafficTimer);\r\n this.fakeTrafficTimer = null;\r\n }\r\n if (this._fakeTrafficMessages) {\r\n this._fakeTrafficMessages.length = 0;\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Fake traffic messages cleared');\r\n }\r\n \r\n // 7. Clear chunk queue\r\n this.chunkQueue.length = 0;\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Chunk queue cleared');\r\n \r\n // 8. Clear packet buffer\r\n if (this.packetBuffer) {\r\n this.packetBuffer.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Emergency: Packet buffer cleared');\r\n }\r\n \r\n // 9. Enhanced memory cleanup with quantum-resistant patterns\r\n this._secureMemoryManager.isCleaning = true;\r\n this._secureMemoryManager.cleanupQueue.length = 0;\r\n this._secureMemoryManager.memoryStats.lastCleanup = Date.now();\r\n \r\n // Perform natural cleanup without forcing GC\r\n await this._scheduleAsyncCleanup(async () => {\r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Starting natural memory cleanup');\r\n \r\n // Natural cleanup cycles with async delays\r\n for (let i = 0; i < 3; i++) {\r\n this._secureLog('info', `\uD83E\uDDF9 Enhanced Emergency: Cleanup cycle ${i + 1}/3`);\r\n \r\n // Allow natural garbage collection between cycles\r\n await this._performNaturalCleanup();\r\n }\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Enhanced Emergency: Natural cleanup completed');\r\n }, 0);\r\n \r\n this._secureMemoryManager.isCleaning = false;\r\n \r\n this._secureLog('info', '\u2705 Enhanced emergency cleanup completed successfully');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Enhanced emergency cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n \r\n // Rollback mechanism (simplified)\r\n this._secureMemoryManager.isCleaning = false;\r\n }\r\n }\r\n\r\n /**\r\n * Validate emergency cleanup success\r\n * @param {Object} originalState - Original state before cleanup\r\n * @returns {Object} Validation results\r\n */\r\n _validateEmergencyCleanup(originalState) {\r\n const currentState = {\r\n messageQueueSize: this.messageQueue.length,\r\n processedIdsSize: this.processedMessageIds.size,\r\n packetBufferSize: this.packetBuffer ? this.packetBuffer.size : 0,\r\n ivTrackingSize: this._ivTrackingSystem ? this._ivTrackingSystem.usedIVs.size : 0,\r\n decoyChannelsSize: this.decoyChannels ? this.decoyChannels.size : 0\r\n };\r\n \r\n const validation = {\r\n messageQueueCleared: currentState.messageQueueSize === 0,\r\n processedIdsCleared: currentState.processedIdsSize === 0,\r\n packetBufferCleared: currentState.packetBufferSize === 0,\r\n ivTrackingCleared: currentState.ivTrackingSize === 0,\r\n decoyChannelsCleared: currentState.decoyChannelsSize === 0,\r\n allCleared: (\r\n currentState.messageQueueSize === 0 &&\r\n currentState.processedIdsSize === 0 &&\r\n currentState.packetBufferSize === 0 &&\r\n currentState.ivTrackingSize === 0 &&\r\n currentState.decoyChannelsSize === 0\r\n )\r\n };\r\n \r\n return validation;\r\n }\r\n\r\n /**\r\n * Cleanup resources based on age and usage\r\n */\r\n _cleanupResources() {\r\n const now = Date.now();\r\n \r\n // Clean old processed message IDs (keep only last hour)\r\n if (this.processedMessageIds.size > this._emergencyThresholds.processedMessageIds) {\r\n this.processedMessageIds.clear();\r\n this._secureLog('info', '\uD83E\uDDF9 Old processed message IDs cleared');\r\n }\r\n \r\n // Clean old IVs\r\n if (this._ivTrackingSystem) {\r\n this._cleanupOldIVs();\r\n }\r\n \r\n // Clean old keys\r\n this.cleanupOldKeys();\r\n \r\n // Clean rate limiter\r\n if (window.EnhancedSecureCryptoUtils && window.EnhancedSecureCryptoUtils.rateLimiter) {\r\n window.EnhancedSecureCryptoUtils.rateLimiter.cleanup();\r\n }\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Resource cleanup completed');\r\n }\r\n\r\n /**\r\n * Monitor key security (replaces _startKeySecurityMonitoring)\r\n */\r\n _monitorKeySecurity() {\r\n if (this._keyStorageStats.activeKeys > 10) {\r\n this._secureLog('warn', '\u26A0\uFE0F High number of active keys detected. Consider rotation.');\r\n }\r\n \r\n if (Date.now() - (this._keyStorageStats.lastRotation || 0) > 3600000) {\r\n this._rotateKeys();\r\n }\r\n }\r\n\r\n /**\r\n * Send heartbeat message (called by unified scheduler)\r\n */\r\n _sendHeartbeat() {\r\n try {\r\n if (this.isConnected() && this.dataChannel && this.dataChannel.readyState === 'open') {\r\n this.dataChannel.send(JSON.stringify({ \r\n type: EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT, \r\n timestamp: Date.now() \r\n }));\r\n \r\n this._heartbeatConfig.lastHeartbeat = Date.now();\r\n this._secureLog('debug', '\uD83D\uDC93 Heartbeat sent');\r\n }\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Heartbeat failed:', { \r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Comprehensive input validation to prevent DoS and injection attacks\r\n * @param {any} data - Data to validate\r\n * @param {string} context - Context for validation (e.g., 'sendMessage', 'sendSecureMessage')\r\n * @returns {Object} Validation result with isValid and sanitizedData\r\n */\r\n _validateInputData(data, context = 'unknown') {\r\n const validationResult = {\r\n isValid: false,\r\n sanitizedData: null,\r\n errors: [],\r\n warnings: []\r\n };\r\n\r\n try {\r\n // 1. Basic type validation\r\n if (data === null || data === undefined) {\r\n validationResult.errors.push('Data cannot be null or undefined');\r\n return validationResult;\r\n }\r\n\r\n // 2. Size validation for strings\r\n if (typeof data === 'string') {\r\n if (data.length > this._inputValidationLimits.maxStringLength) {\r\n validationResult.errors.push(`String too long: ${data.length} > ${this._inputValidationLimits.maxStringLength}`);\r\n return validationResult;\r\n }\r\n\r\n // 3. Malicious pattern detection for strings\r\n for (const pattern of this._maliciousPatterns) {\r\n if (pattern.test(data)) {\r\n validationResult.errors.push(`Malicious pattern detected: ${pattern.source}`);\r\n this._secureLog('warn', '\uD83D\uDEA8 Malicious pattern detected in input', {\r\n context: context,\r\n pattern: pattern.source,\r\n dataLength: data.length\r\n });\r\n return validationResult;\r\n }\r\n }\r\n\r\n // 4. Sanitize string data\r\n validationResult.sanitizedData = this._sanitizeInputString(data);\r\n validationResult.isValid = true;\r\n return validationResult;\r\n }\r\n\r\n // 5. Object validation\r\n if (typeof data === 'object') {\r\n // Check for circular references\r\n const seen = new WeakSet();\r\n const checkCircular = (obj, path = '') => {\r\n if (obj === null || typeof obj !== 'object') return;\r\n \r\n if (seen.has(obj)) {\r\n validationResult.errors.push(`Circular reference detected at path: ${path}`);\r\n return;\r\n }\r\n \r\n seen.add(obj);\r\n \r\n // Check object depth\r\n if (path.split('.').length > this._inputValidationLimits.maxObjectDepth) {\r\n validationResult.errors.push(`Object too deep: ${path.split('.').length} > ${this._inputValidationLimits.maxObjectDepth}`);\r\n return;\r\n }\r\n\r\n // Check array length\r\n if (Array.isArray(obj) && obj.length > this._inputValidationLimits.maxArrayLength) {\r\n validationResult.errors.push(`Array too long: ${obj.length} > ${this._inputValidationLimits.maxArrayLength}`);\r\n return;\r\n }\r\n\r\n // Recursively check all properties\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n checkCircular(obj[key], path ? `${path}.${key}` : key);\r\n }\r\n }\r\n };\r\n\r\n checkCircular(data);\r\n \r\n if (validationResult.errors.length > 0) {\r\n return validationResult;\r\n }\r\n\r\n // 6. Check total object size\r\n const objectSize = this._calculateObjectSize(data);\r\n if (objectSize > this._inputValidationLimits.maxMessageSize) {\r\n validationResult.errors.push(`Object too large: ${objectSize} bytes > ${this._inputValidationLimits.maxMessageSize} bytes`);\r\n return validationResult;\r\n }\r\n\r\n // 7. Sanitize object data\r\n validationResult.sanitizedData = this._sanitizeInputObject(data);\r\n validationResult.isValid = true;\r\n return validationResult;\r\n }\r\n\r\n // 8. ArrayBuffer validation\r\n if (data instanceof ArrayBuffer) {\r\n if (data.byteLength > this._inputValidationLimits.maxMessageSize) {\r\n validationResult.errors.push(`ArrayBuffer too large: ${data.byteLength} bytes > ${this._inputValidationLimits.maxMessageSize} bytes`);\r\n return validationResult;\r\n }\r\n \r\n validationResult.sanitizedData = data;\r\n validationResult.isValid = true;\r\n return validationResult;\r\n }\r\n\r\n // 9. Other types are not allowed\r\n validationResult.errors.push(`Unsupported data type: ${typeof data}`);\r\n return validationResult;\r\n\r\n } catch (error) {\r\n validationResult.errors.push(`Validation error: ${error.message}`);\r\n this._secureLog('error', '\u274C Input validation failed', {\r\n context: context,\r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error?.message || 'Unknown error'\r\n });\r\n return validationResult;\r\n }\r\n }\r\n\r\n /**\r\n * Calculate approximate object size in bytes\r\n * @param {any} obj - Object to calculate size for\r\n * @returns {number} Size in bytes\r\n */\r\n _calculateObjectSize(obj) {\r\n try {\r\n const jsonString = JSON.stringify(obj);\r\n return new TextEncoder().encode(jsonString).length;\r\n } catch (error) {\r\n // If JSON.stringify fails, estimate size\r\n return 1024 * 1024; // Assume 1MB to be safe\r\n }\r\n }\r\n\r\n /**\r\n * Sanitize string data for input validation\r\n * @param {string} str - String to sanitize\r\n * @returns {string} Sanitized string\r\n */\r\n _sanitizeInputString(str) {\r\n if (typeof str !== 'string') return str;\r\n \r\n // Remove null bytes\r\n str = str.replace(/\\0/g, '');\r\n \r\n // Normalize whitespace\r\n str = str.replace(/\\s+/g, ' ');\r\n \r\n // Trim\r\n str = str.trim();\r\n \r\n return str;\r\n }\r\n\r\n /**\r\n * Sanitize object data for input validation\r\n * @param {any} obj - Object to sanitize\r\n * @returns {any} Sanitized object\r\n */\r\n _sanitizeInputObject(obj) {\r\n if (obj === null || typeof obj !== 'object') return obj;\r\n \r\n if (Array.isArray(obj)) {\r\n return obj.map(item => this._sanitizeInputObject(item));\r\n }\r\n \r\n const sanitized = {};\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n const value = obj[key];\r\n if (typeof value === 'string') {\r\n sanitized[key] = this._sanitizeInputString(value);\r\n } else if (typeof value === 'object') {\r\n sanitized[key] = this._sanitizeInputObject(value);\r\n } else {\r\n sanitized[key] = value;\r\n }\r\n }\r\n }\r\n \r\n return sanitized;\r\n }\r\n\r\n /**\r\n * Rate limiting for message sending\r\n * @param {string} context - Context for rate limiting\r\n * @returns {boolean} true if rate limit allows\r\n */\r\n _checkRateLimit(context = 'message') {\r\n const now = Date.now();\r\n \r\n // Initialize rate limiter if not exists\r\n if (!this._rateLimiter) {\r\n this._rateLimiter = {\r\n messageCount: 0,\r\n lastReset: now,\r\n burstCount: 0,\r\n lastBurstReset: now\r\n };\r\n }\r\n \r\n // Reset counters if needed\r\n if (now - this._rateLimiter.lastReset > 60000) { // 1 minute\r\n this._rateLimiter.messageCount = 0;\r\n this._rateLimiter.lastReset = now;\r\n }\r\n \r\n if (now - this._rateLimiter.lastBurstReset > 1000) { // 1 second\r\n this._rateLimiter.burstCount = 0;\r\n this._rateLimiter.lastBurstReset = now;\r\n }\r\n \r\n // Check burst limit\r\n if (this._rateLimiter.burstCount >= this._inputValidationLimits.rateLimitBurstSize) {\r\n this._secureLog('warn', '\u26A0\uFE0F Rate limit burst exceeded', { context });\r\n return false;\r\n }\r\n \r\n // Check overall rate limit\r\n if (this._rateLimiter.messageCount >= this._inputValidationLimits.rateLimitMessagesPerMinute) {\r\n this._secureLog('warn', '\u26A0\uFE0F Rate limit exceeded', { context });\r\n return false;\r\n }\r\n \r\n // Increment counters\r\n this._rateLimiter.messageCount++;\r\n this._rateLimiter.burstCount++;\r\n \r\n return true;\r\n }\r\n\r\n // ============================================\r\n // SECURE KEY STORAGE MANAGEMENT\r\n // ============================================\r\n\r\n /**\r\n * Initializes the secure key storage\r\n */\r\n _initializeSecureKeyStorage() {\r\n // Initialize master key manager\r\n this._masterKeyManager = new SecureMasterKeyManager();\r\n \r\n // Initialize with the new class and pass master key manager\r\n this._secureKeyStorage = new SecureKeyStorage(this._masterKeyManager);\r\n \r\n // Keep the stats structure for compatibility\r\n this._keyStorageStats = {\r\n totalKeys: 0,\r\n activeKeys: 0,\r\n lastAccess: null,\r\n lastRotation: null,\r\n };\r\n \r\n this._secureLog('info', '\uD83D\uDD10 Enhanced secure key storage initialized');\r\n }\r\n \r\n /**\r\n * Set password callback for master key\r\n */\r\n setMasterKeyPasswordCallback(callback) {\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.setPasswordRequiredCallback(callback);\r\n }\r\n }\r\n \r\n /**\r\n * Set session expired callback for master key\r\n */\r\n setMasterKeySessionExpiredCallback(callback) {\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.setSessionExpiredCallback(callback);\r\n }\r\n }\r\n \r\n /**\r\n * Lock master key manually\r\n */\r\n lockMasterKey() {\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.lock();\r\n }\r\n }\r\n \r\n /**\r\n * Check if master key is unlocked\r\n */\r\n isMasterKeyUnlocked() {\r\n return this._masterKeyManager ? this._masterKeyManager.isUnlocked() : false;\r\n }\r\n \r\n /**\r\n * Get master key session status\r\n */\r\n getMasterKeySessionStatus() {\r\n return this._masterKeyManager ? this._masterKeyManager.getSessionStatus() : null;\r\n }\r\n\r\n // Helper: ensure file transfer system is ready (lazy init on receiver)\r\n async _ensureFileTransferReady() {\r\n try {\r\n // If already initialized \u2014 done\r\n if (this.fileTransferSystem) {\r\n return true;\r\n }\r\n // Requires an open data channel and a verified connection\r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n throw new Error('Data channel not open');\r\n }\r\n if (!this.isVerified) {\r\n throw new Error('Connection not verified');\r\n }\r\n // Initialization\r\n this.initializeFileTransfer();\r\n \r\n // \u041A\u0420\u0418\u0422\u0418\u0427\u0415\u0421\u041A\u041E\u0415 \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u0416\u0434\u0435\u043C \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0442\u0430\u0439\u043C\u0430\u0443\u0442\u043E\u043C\r\n let attempts = 0;\r\n const maxAttempts = 50; // 5 \u0441\u0435\u043A\u0443\u043D\u0434 \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C\r\n while (!this.fileTransferSystem && attempts < maxAttempts) {\r\n await new Promise(r => setTimeout(r, 100));\r\n attempts++;\r\n }\r\n \r\n if (!this.fileTransferSystem) {\r\n throw new Error('File transfer system initialization timeout');\r\n }\r\n \r\n return true;\r\n } catch (e) {\r\n this._secureLog('error', '\u274C _ensureFileTransferReady failed', { \r\n errorType: e?.constructor?.name || 'Unknown',\r\n hasMessage: !!e?.message \r\n });\r\n return false;\r\n }\r\n }\r\n\r\n _getSecureKey(keyId) {\r\n return this._secureKeyStorage.retrieveKey(keyId);\r\n }\r\n\r\n async _setSecureKey(keyId, key) {\r\n if (!(key instanceof CryptoKey)) {\r\n this._secureLog('error', '\u274C Attempt to store non-CryptoKey');\r\n return false;\r\n }\r\n \r\n const success = await this._secureKeyStorage.storeKey(keyId, key, {\r\n version: this.currentKeyVersion,\r\n type: key.algorithm.name\r\n });\r\n \r\n if (success) {\r\n this._secureLog('info', `\uD83D\uDD11 Key ${keyId} stored securely with encryption`);\r\n }\r\n \r\n return success;\r\n }\r\n\r\n /**\r\n * Validates a key value\r\n * @param {CryptoKey} key - Key to validate\r\n * @returns {boolean} true if the key is valid\r\n */\r\n _validateKeyValue(key) {\r\n return key instanceof CryptoKey &&\r\n key.algorithm &&\r\n key.usages &&\r\n key.usages.length > 0;\r\n }\r\n\r\n _secureWipeKeys() {\r\n this._secureKeyStorage.secureWipeAll();\r\n \r\n // Also lock the master key\r\n if (this._masterKeyManager) {\r\n this._masterKeyManager.lock();\r\n }\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 All keys securely wiped and encrypted storage cleared');\r\n }\r\n\r\n /**\r\n * Validates key storage state\r\n * @returns {boolean} true if the storage is ready\r\n */\r\n _validateKeyStorage() {\r\n return this._secureKeyStorage instanceof SecureKeyStorage;\r\n }\r\n\r\n /**\r\n * Returns secure key storage statistics\r\n * @returns {object} Storage metrics\r\n */\r\n _getKeyStorageStats() {\r\n const stats = this._secureKeyStorage.getStorageStats();\r\n return {\r\n totalKeysCount: stats.totalKeys,\r\n activeKeysCount: stats.totalKeys,\r\n hasLastAccess: stats.metadata.some(m => m.lastAccessed),\r\n hasLastRotation: !!this._keyStorageStats.lastRotation,\r\n storageType: 'SecureKeyStorage',\r\n timestamp: Date.now()\r\n };\r\n }\r\n\r\n /**\r\n * Performs key rotation in storage\r\n */\r\n _rotateKeys() {\r\n const oldKeys = Array.from(this._secureKeyStorage.keys());\r\n this._secureKeyStorage.clear();\r\n this._keyStorageStats.lastRotation = Date.now();\r\n this._keyStorageStats.activeKeys = 0;\r\n this._secureLog('info', `\uD83D\uDD04 Key rotation completed. ${oldKeys.length} keys rotated`);\r\n }\r\n\r\n /**\r\n * Emergency key wipe (e.g., upon detecting a threat)\r\n */\r\n _emergencyKeyWipe() {\r\n this._secureWipeKeys();\r\n this._secureLog('error', '\uD83D\uDEA8 EMERGENCY: All keys wiped due to security threat');\r\n }\r\n\r\n /**\r\n * Starts key security monitoring\r\n * @deprecated Use unified scheduler instead\r\n */\r\n _startKeySecurityMonitoring() {\r\n // Functionality moved to unified scheduler\r\n this._secureLog('info', '\uD83D\uDD27 Key security monitoring moved to unified scheduler');\r\n }\r\n\r\n\r\n // ============================================\r\n // HELPER METHODS\r\n // ============================================\r\n /**\r\n * Constant-time key validation to prevent timing attacks\r\n * @param {CryptoKey} key - Key to validate\r\n * @returns {boolean} true if key is valid\r\n */\r\n _validateKeyConstantTime(key) {\r\n // Constant-time validation to prevent timing attacks\r\n let isValid = 0;\r\n \r\n // Check if key is CryptoKey instance (constant-time)\r\n try {\r\n const isCryptoKey = key instanceof CryptoKey;\r\n isValid += isCryptoKey ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // Check algorithm (constant-time)\r\n try {\r\n const hasAlgorithm = !!(key && key.algorithm);\r\n isValid += hasAlgorithm ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // Check type (constant-time)\r\n try {\r\n const hasType = !!(key && key.type);\r\n isValid += hasType ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // Check extractable property (constant-time)\r\n try {\r\n const hasExtractable = key && key.extractable !== undefined;\r\n isValid += hasExtractable ? 1 : 0;\r\n } catch {\r\n isValid += 0;\r\n }\r\n \r\n // All checks must pass\r\n return isValid === 4;\r\n }\r\n\r\n /**\r\n * Constant-time key pair validation\r\n * @param {Object} keyPair - Key pair to validate\r\n * @returns {boolean} true if key pair is valid\r\n */\r\n _validateKeyPairConstantTime(keyPair) {\r\n if (!keyPair || typeof keyPair !== 'object') return false;\r\n \r\n const privateKeyValid = this._validateKeyConstantTime(keyPair.privateKey);\r\n const publicKeyValid = this._validateKeyConstantTime(keyPair.publicKey);\r\n \r\n // Constant-time AND operation\r\n return privateKeyValid && publicKeyValid;\r\n }\r\n\r\n /**\r\n * Enhanced secure logging system initialization\r\n */\r\n _initializeSecureLogging() {\r\n // Logging levels\r\n this._logLevels = {\r\n error: 0,\r\n warn: 1, \r\n info: 2,\r\n debug: 3,\r\n trace: 4\r\n };\r\n \r\n // Ultra-strict levels for production\r\n this._currentLogLevel = this._isProductionMode ? \r\n this._logLevels.error : // In production, ONLY critical errors\r\n this._logLevels.info; // In development, up to info\r\n \r\n // Reduced log limits to prevent data accumulation\r\n this._logCounts = new Map();\r\n this._maxLogCount = this._isProductionMode ? 5 : 50; // Reduced limits\r\n \r\n // Hard resource limits to prevent memory leaks\r\n this._resourceLimits = {\r\n maxLogEntries: this._isProductionMode ? 100 : 1000,\r\n maxMessageQueue: 1000,\r\n maxIVHistory: 10000,\r\n maxProcessedMessageIds: 5000,\r\n maxDecoyChannels: 100,\r\n maxFakeTrafficMessages: 500,\r\n maxChunkQueue: 200,\r\n maxPacketBuffer: 1000\r\n };\r\n \r\n // Emergency cleanup thresholds\r\n this._emergencyThresholds = {\r\n logEntries: this._resourceLimits.maxLogEntries * 0.8, // 80%\r\n messageQueue: this._resourceLimits.maxMessageQueue * 0.8,\r\n ivHistory: this._resourceLimits.maxIVHistory * 0.8,\r\n processedMessageIds: this._resourceLimits.maxProcessedMessageIds * 0.8\r\n };\r\n \r\n // Input validation limits to prevent DoS attacks\r\n this._inputValidationLimits = {\r\n maxStringLength: 100000, // 100KB for strings\r\n maxObjectDepth: 10, // Maximum object nesting depth\r\n maxArrayLength: 1000, // Maximum array length\r\n maxMessageSize: 1024 * 1024, // 1MB total message size\r\n maxConcurrentMessages: 10, // Maximum concurrent message processing\r\n rateLimitMessagesPerMinute: 60, // Rate limiting\r\n rateLimitBurstSize: 10 // Burst size for rate limiting\r\n };\r\n \r\n // Malicious pattern detection\r\n this._maliciousPatterns = [\r\n // Enhanced script tag detection that handles edge cases\r\n /]*>[\\s\\S]*?<\\/script\\s*>/gi, // Standard \r\n /]*>[\\s\\S]*?<\\/script\\s+[^>]*>/gi, // \r\n /]*>[\\s\\S]*$/gi, // Malformed script tags without closing\r\n // Additional dangerous tags\r\n /]*>[\\s\\S]*?<\\/iframe\\s*>/gi, // iframe tags\r\n /]*>[\\s\\S]*?<\\/object\\s*>/gi, // object tags\r\n /]*>/gi, // embed tags\r\n /]*>[\\s\\S]*?<\\/applet\\s*>/gi, // applet tags\r\n /]*>[\\s\\S]*?<\\/style\\s*>/gi, // style tags\r\n // Dangerous protocols\r\n /javascript\\s*:/gi, // JavaScript protocol\r\n /data\\s*:/gi, // Data protocol\r\n /vbscript\\s*:/gi, // VBScript protocol\r\n /data:text\\/html/gi, // Data URLs with HTML\r\n /on\\w+\\s*=/gi, // Event handlers\r\n /eval\\s*\\(/gi, // eval() calls\r\n /document\\./gi, // Document object access\r\n /window\\./gi, // Window object access\r\n /localStorage/gi, // LocalStorage access\r\n /sessionStorage/gi, // SessionStorage access\r\n /fetch\\s*\\(/gi, // Fetch API calls\r\n /XMLHttpRequest/gi, // XHR calls\r\n /import\\s*\\(/gi, // Dynamic imports\r\n /require\\s*\\(/gi, // Require calls\r\n /process\\./gi, // Process object access\r\n /global/gi, // Global object access\r\n /__proto__/gi, // Prototype pollution\r\n /constructor/gi, // Constructor access\r\n /prototype/gi, // Prototype access\r\n /toString\\s*\\(/gi, // toString calls\r\n /valueOf\\s*\\(/gi // valueOf calls\r\n ];\r\n\r\n // Comprehensive blacklist with all sensitive patterns\r\n this._absoluteBlacklist = new Set([\r\n // Cryptographic keys\r\n 'encryptionKey', 'macKey', 'metadataKey', 'privateKey', 'publicKey',\r\n 'ecdhKeyPair', 'ecdsaKeyPair', 'peerPublicKey', 'nestedEncryptionKey',\r\n \r\n // Authentication and session data\r\n 'verificationCode', 'sessionSalt', 'keyFingerprint', 'sessionId',\r\n 'authChallenge', 'authProof', 'authToken', 'sessionToken',\r\n \r\n // Credentials and secrets\r\n 'password', 'token', 'secret', 'credential', 'signature',\r\n 'apiKey', 'accessKey', 'secretKey', 'privateKey',\r\n \r\n // Cryptographic materials\r\n 'hash', 'digest', 'nonce', 'iv', 'cipher', 'seed',\r\n 'entropy', 'random', 'salt', 'fingerprint',\r\n \r\n // JWT and session data\r\n 'jwt', 'bearer', 'refreshToken', 'accessToken',\r\n \r\n // File transfer sensitive data\r\n 'fileHash', 'fileSignature', 'transferKey', 'chunkKey'\r\n ]);\r\n\r\n // Minimal whitelist with strict validation\r\n this._safeFieldsWhitelist = new Set([\r\n // Basic status fields\r\n 'timestamp', 'type', 'status', 'state', 'level',\r\n 'isConnected', 'isVerified', 'isInitiator', 'version',\r\n \r\n // Counters and metrics (safe)\r\n 'count', 'total', 'active', 'inactive', 'success', 'failure',\r\n \r\n // Connection states (safe)\r\n 'readyState', 'connectionState', 'iceConnectionState',\r\n \r\n // Feature counts (safe)\r\n 'activeFeaturesCount', 'totalFeatures', 'stage',\r\n \r\n // Error types (safe)\r\n 'errorType', 'errorCode', 'phase', 'attempt'\r\n ]);\r\n \r\n // Initialize security monitoring\r\n this._initializeLogSecurityMonitoring();\r\n \r\n this._secureLog('info', `\uD83D\uDD27 Enhanced secure logging initialized (Production: ${this._isProductionMode})`);\r\n }\r\n\r\n /**\r\n * Initialize security monitoring for logging system\r\n */\r\n _initializeLogSecurityMonitoring() {\r\n // Security monitoring moved to unified scheduler\r\n this._logSecurityViolations = 0;\r\n this._maxLogSecurityViolations = 3;\r\n }\r\n\r\n /**\r\n * Audit logging system security\r\n */\r\n _auditLoggingSystemSecurity() {\r\n let violations = 0;\r\n \r\n // Check for excessive log counts (potential data leakage)\r\n for (const [key, count] of this._logCounts.entries()) {\r\n if (count > this._maxLogCount * 2) {\r\n violations++;\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 LOG SECURITY: Excessive log count detected: ${key}`);\r\n }\r\n }\r\n \r\n // Check for blacklisted patterns in recent logs\r\n const recentLogs = Array.from(this._logCounts.keys());\r\n for (const logKey of recentLogs) {\r\n if (this._containsSensitiveContent(logKey)) {\r\n violations++;\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 LOG SECURITY: Sensitive content in log key: ${logKey}`);\r\n }\r\n }\r\n \r\n // Emergency shutdown if too many violations\r\n this._logSecurityViolations += violations;\r\n if (this._logSecurityViolations >= this._maxLogSecurityViolations) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.('\uD83D\uDEA8 CRITICAL: Logging system disabled due to security violations');\r\n }\r\n }\r\n\r\n _secureLogShim(...args) {\r\n try {\r\n // Validate arguments array\r\n if (!Array.isArray(args) || args.length === 0) {\r\n return;\r\n }\r\n \r\n // Proper destructuring with fallback\r\n const message = args[0];\r\n const restArgs = args.slice(1);\r\n \r\n // Handle different argument patterns\r\n if (restArgs.length === 0) {\r\n this._secureLog('info', String(message || ''));\r\n return;\r\n }\r\n \r\n if (restArgs.length === 1) {\r\n this._secureLog('info', String(message || ''), restArgs[0]);\r\n return;\r\n }\r\n \r\n // Proper object structure for multiple args\r\n this._secureLog('info', String(message || ''), { \r\n additionalArgs: restArgs,\r\n argCount: restArgs.length \r\n });\r\n } catch (error) {\r\n // Better error handling - fallback to original console if available\r\n try {\r\n if (this._originalConsole?.log) {\r\n this._originalConsole.log(...args);\r\n }\r\n } catch (fallbackError) {\r\n // Silent failure to prevent execution disruption\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Setup own logger without touching global console\r\n */\r\n _setupOwnLogger() {\r\n // Create own logger without touching global console\r\n this.logger = {\r\n log: (message, data) => this._secureLog('info', message, data),\r\n info: (message, data) => this._secureLog('info', message, data),\r\n warn: (message, data) => this._secureLog('warn', message, data),\r\n error: (message, data) => this._secureLog('error', message, data),\r\n debug: (message, data) => this._secureLog('debug', message, data)\r\n };\r\n \r\n // In development, log to console; in production, use secure logging only\r\n if (EnhancedSecureWebRTCManager.DEBUG_MODE) {\r\n this._secureLog('info', '\uD83D\uDD12 Own logger created - development mode');\r\n } else {\r\n this._secureLog('info', '\uD83D\uDD12 Own logger created - production mode');\r\n }\r\n }\r\n /**\r\n * Production logging - use own logger with minimal output\r\n */\r\n _setupProductionLogging() {\r\n // In production, own logger becomes minimal\r\n if (this._isProductionMode) {\r\n this.logger = {\r\n log: () => {}, // No-op in production\r\n info: () => {}, // No-op in production\r\n warn: (message, data) => this._secureLog('warn', message, data),\r\n error: (message, data) => this._secureLog('error', message, data),\r\n debug: () => {} // No-op in production\r\n };\r\n \r\n this._secureLog('info', 'Production logging mode activated');\r\n }\r\n }\r\n /**\r\n * Secure logging with enhanced data protection\r\n * @param {string} level - Log level (error, warn, info, debug, trace)\r\n * @param {string} message - Message\r\n * @param {object} data - Optional payload (will be sanitized)\r\n */\r\n _secureLog(level, message, data = null) {\r\n // Pre-sanitization audit to prevent data leakage\r\n if (data && !this._auditLogMessage(message, data)) {\r\n // Log the attempt but block the actual data\r\n this._originalConsole?.error?.('SECURITY: Logging blocked due to potential data leakage');\r\n return;\r\n }\r\n \r\n // Check log level\r\n if (this._logLevels[level] > this._currentLogLevel) {\r\n return;\r\n }\r\n \r\n // Prevent log spam with better key generation\r\n const logKey = `${level}:${message.substring(0, 50)}`;\r\n const currentCount = this._logCounts.get(logKey) || 0;\r\n \r\n if (currentCount >= this._maxLogCount) {\r\n return;\r\n }\r\n \r\n this._logCounts.set(logKey, currentCount + 1);\r\n \r\n // Enhanced sanitization with multiple passes\r\n let sanitizedData = null;\r\n if (data) {\r\n // First pass: basic sanitization\r\n sanitizedData = this._sanitizeLogData(data);\r\n \r\n // Second pass: check if sanitized data still contains sensitive content\r\n if (this._containsSensitiveContent(JSON.stringify(sanitizedData))) {\r\n this._originalConsole?.error?.('ECURITY: Sanitized data still contains sensitive content - blocking log');\r\n return;\r\n }\r\n }\r\n \r\n // Production mode security - only log essential errors\r\n if (this._isProductionMode) {\r\n if (level === 'error') {\r\n // In production, only log error messages without sensitive data\r\n const safeMessage = this._sanitizeString(message);\r\n this._originalConsole?.error?.(safeMessage);\r\n }\r\n // Block all other log levels in production\r\n return;\r\n }\r\n \r\n // Development mode: full logging with sanitized data\r\n const logMethod = this._originalConsole?.[level] || this._originalConsole?.log;\r\n if (sanitizedData) {\r\n logMethod(message, sanitizedData);\r\n } else {\r\n logMethod(message);\r\n }\r\n }\r\n /**\r\n * Enhanced sanitization for log data with multiple security layers\r\n */\r\n _sanitizeLogData(data) {\r\n // Pre-check for sensitive content before processing\r\n if (typeof data === 'string') {\r\n return this._sanitizeString(data);\r\n }\r\n \r\n if (!data || typeof data !== 'object') {\r\n return data;\r\n }\r\n \r\n const sanitized = {};\r\n \r\n for (const [key, value] of Object.entries(data)) {\r\n const lowerKey = key.toLowerCase();\r\n \r\n // Enhanced blacklist with more comprehensive patterns\r\n const blacklistPatterns = [\r\n 'key', 'secret', 'token', 'password', 'credential', 'auth',\r\n 'fingerprint', 'salt', 'signature', 'private', 'encryption',\r\n 'mac', 'metadata', 'session', 'jwt', 'bearer', 'hash',\r\n 'digest', 'nonce', 'iv', 'cipher', 'seed', 'entropy'\r\n ];\r\n \r\n const isBlacklisted = this._absoluteBlacklist.has(key) || \r\n blacklistPatterns.some(pattern => lowerKey.includes(pattern));\r\n \r\n if (isBlacklisted) {\r\n sanitized[key] = '[SENSITIVE_DATA_BLOCKED]';\r\n continue;\r\n }\r\n \r\n // Enhanced whitelist with strict validation\r\n if (this._safeFieldsWhitelist.has(key)) {\r\n // Even whitelisted fields get sanitized if they contain sensitive data\r\n if (typeof value === 'string') {\r\n sanitized[key] = this._sanitizeString(value);\r\n } else {\r\n sanitized[key] = value;\r\n }\r\n continue;\r\n }\r\n \r\n // Enhanced type handling with security checks\r\n if (typeof value === 'boolean' || typeof value === 'number') {\r\n sanitized[key] = value;\r\n } else if (typeof value === 'string') {\r\n sanitized[key] = this._sanitizeString(value);\r\n } else if (value instanceof ArrayBuffer || value instanceof Uint8Array) {\r\n // Don't reveal actual byte lengths for security\r\n sanitized[key] = `[${value.constructor.name}( bytes)]`;\r\n } else if (value && typeof value === 'object') {\r\n // Recursive sanitization with depth limit and security check\r\n try {\r\n sanitized[key] = this._sanitizeLogData(value);\r\n } catch (error) {\r\n sanitized[key] = '[RECURSIVE_SANITIZATION_FAILED]';\r\n }\r\n } else {\r\n sanitized[key] = `[${typeof value}]`;\r\n }\r\n }\r\n \r\n // Final security check on sanitized data\r\n const sanitizedString = JSON.stringify(sanitized);\r\n if (this._containsSensitiveContent(sanitizedString)) {\r\n return { error: 'SANITIZATION_FAILED_SENSITIVE_CONTENT_DETECTED' };\r\n }\r\n \r\n return sanitized;\r\n }\r\n /**\r\n * Enhanced sanitization for strings with comprehensive pattern detection\r\n */\r\n _sanitizeString(str) {\r\n if (typeof str !== 'string' || str.length === 0) {\r\n return str;\r\n }\r\n \r\n // Comprehensive sensitive pattern detection\r\n const sensitivePatterns = [\r\n // Hex patterns (various lengths)\r\n /[a-f0-9]{16,}/i, // 16+ hex chars (covers short keys)\r\n /[a-f0-9]{8,}/i, // 8+ hex chars (covers shorter keys)\r\n \r\n // Base64 patterns (comprehensive)\r\n /[A-Za-z0-9+/]{16,}={0,2}/, // Base64 with padding\r\n /[A-Za-z0-9+/]{12,}/, // Base64 without padding\r\n /[A-Za-z0-9+/=]{10,}/, // Base64-like patterns\r\n \r\n // Base58 patterns (Bitcoin-style)\r\n /[1-9A-HJ-NP-Za-km-z]{16,}/, // Base58 strings\r\n \r\n // Base32 patterns\r\n /[A-Z2-7]{16,}={0,6}/, // Base32 with padding\r\n /[A-Z2-7]{12,}/, // Base32 without padding\r\n \r\n // Custom encoding patterns\r\n /[A-Za-z0-9\\-_]{16,}/, // URL-safe base64 variants\r\n /[A-Za-z0-9\\.\\-_]{16,}/, // JWT-like patterns\r\n \r\n // Long alphanumeric strings (potential keys)\r\n /\\b[A-Za-z0-9]{12,}\\b/, // 12+ alphanumeric chars\r\n /\\b[A-Za-z0-9]{8,}\\b/, // 8+ alphanumeric chars\r\n \r\n // PEM key patterns\r\n /BEGIN\\s+(PRIVATE|PUBLIC|RSA|DSA|EC)\\s+KEY/i,\r\n /END\\s+(PRIVATE|PUBLIC|RSA|DSA|EC)\\s+KEY/i,\r\n \r\n // JWT patterns\r\n /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,\r\n \r\n // API key patterns\r\n /(api[_-]?key|token|secret|password|credential)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n \r\n // UUID patterns\r\n /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i,\r\n \r\n // Credit cards and SSN (existing patterns)\r\n /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/,\r\n /\\b\\d{3}-\\d{2}-\\d{4}\\b/,\r\n \r\n // Email patterns (more restrictive)\r\n /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/,\r\n \r\n // Crypto-specific patterns\r\n /(fingerprint|hash|digest|signature)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n /(encryption|mac|metadata)[\\s]*key[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n \r\n // Session and auth patterns\r\n /(session|auth|jwt|bearer)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n ];\r\n \r\n // Check for sensitive patterns with early return\r\n for (const pattern of sensitivePatterns) {\r\n if (pattern.test(str)) {\r\n // Always fully hide sensitive data\r\n return '[SENSITIVE_DATA_REDACTED]';\r\n }\r\n }\r\n \r\n // Check for suspicious entropy (high randomness indicates keys)\r\n if (this._hasHighEntropy(str)) {\r\n return '[HIGH_ENTROPY_DATA_REDACTED]';\r\n }\r\n \r\n // Check for suspicious character distributions\r\n if (this._hasSuspiciousDistribution(str)) {\r\n return '[SUSPICIOUS_DATA_REDACTED]';\r\n }\r\n \r\n // For regular strings \u2014 limit length more aggressively\r\n if (str.length > 50) {\r\n return str.substring(0, 20) + '...[TRUNCATED]';\r\n }\r\n \r\n return str;\r\n }\r\n /**\r\n * Enhanced sensitive content detection\r\n */\r\n _containsSensitiveContent(str) {\r\n if (typeof str !== 'string') return false;\r\n \r\n // Use the same comprehensive patterns as _sanitizeString\r\n const sensitivePatterns = [\r\n /[a-f0-9]{16,}/i,\r\n /[A-Za-z0-9+/]{16,}={0,2}/,\r\n /[1-9A-HJ-NP-Za-km-z]{16,}/,\r\n /[A-Z2-7]{16,}={0,6}/,\r\n /\\b[A-Za-z0-9]{12,}\\b/,\r\n /BEGIN\\s+(PRIVATE|PUBLIC|RSA|DSA|EC)\\s+KEY/i,\r\n /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/,\r\n /(api[_-]?key|token|secret|password|credential)[\\s]*[:=][\\s]*[A-Za-z0-9\\-_]{8,}/i,\r\n ];\r\n \r\n return sensitivePatterns.some(pattern => pattern.test(str)) ||\r\n this._hasHighEntropy(str) ||\r\n this._hasSuspiciousDistribution(str);\r\n }\r\n\r\n /**\r\n * Check for high entropy strings (likely cryptographic keys)\r\n */\r\n _hasHighEntropy(str) {\r\n if (str.length < 8) return false;\r\n \r\n // Calculate character frequency\r\n const charCount = {};\r\n for (const char of str) {\r\n charCount[char] = (charCount[char] || 0) + 1;\r\n }\r\n \r\n // Calculate Shannon entropy\r\n const length = str.length;\r\n let entropy = 0;\r\n \r\n for (const count of Object.values(charCount)) {\r\n const probability = count / length;\r\n entropy -= probability * Math.log2(probability);\r\n }\r\n \r\n // High entropy (>4.5 bits per character) suggests cryptographic data\r\n return entropy > 4.5;\r\n }\r\n\r\n /**\r\n * Check for suspicious character distributions\r\n */\r\n _hasSuspiciousDistribution(str) {\r\n if (str.length < 8) return false;\r\n \r\n // Check for uniform distribution of hex characters\r\n const hexChars = str.match(/[a-f0-9]/gi) || [];\r\n if (hexChars.length >= str.length * 0.8) {\r\n // If 80%+ are hex chars, likely a key\r\n return true;\r\n }\r\n \r\n // Check for base64-like distribution\r\n const base64Chars = str.match(/[A-Za-z0-9+/=]/g) || [];\r\n if (base64Chars.length >= str.length * 0.9) {\r\n // If 90%+ are base64 chars, likely encoded data\r\n return true;\r\n }\r\n \r\n // Check for very low character diversity (suggests random data)\r\n const uniqueChars = new Set(str).size;\r\n const diversityRatio = uniqueChars / str.length;\r\n \r\n // If diversity is too high (>0.8) for the length, likely random data\r\n if (diversityRatio > 0.8 && str.length > 16) {\r\n return true;\r\n }\r\n \r\n return false;\r\n }\r\n\r\n\r\n // ============================================\r\n // SECURE LOGGING SYSTEM\r\n // ============================================\r\n \r\n /**\r\n * Detects production mode\r\n */\r\n _detectProductionMode() {\r\n // Check various production mode indicators\r\n return (\r\n // Standard env variables\r\n (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') ||\r\n // No debug flags\r\n (!this._debugMode) ||\r\n // Production domains\r\n (window.location.hostname && !window.location.hostname.includes('localhost') && \r\n !window.location.hostname.includes('127.0.0.1') && \r\n !window.location.hostname.includes('.local')) ||\r\n // Minified code (heuristic check)\r\n (typeof window.webpackHotUpdate === 'undefined' && !window.location.search.includes('debug'))\r\n );\r\n }\r\n // ============================================\r\n // FIXED SECURE GLOBAL API\r\n // ============================================\r\n \r\n /**\r\n * Sets up a secure global API with limited access\r\n */\r\n _setupSecureGlobalAPI() {\r\n // Log that we're starting API setup\r\n this._secureLog('info', 'Starting secure global API setup');\r\n \r\n // Create simple public API with safety checks\r\n const secureAPI = {};\r\n \r\n // Only bind methods that exist\r\n if (typeof this.sendMessage === 'function') {\r\n secureAPI.sendMessage = this.sendMessage.bind(this);\r\n }\r\n \r\n // Create simple getConnectionStatus method\r\n secureAPI.getConnectionStatus = () => ({\r\n isConnected: this.isConnected ? this.isConnected() : false,\r\n isVerified: this.isVerified || false,\r\n connectionState: this.peerConnection?.connectionState || 'disconnected'\r\n });\r\n \r\n // Create simple getSecurityStatus method\r\n secureAPI.getSecurityStatus = () => ({\r\n securityLevel: 'maximum',\r\n stage: 'initialized',\r\n activeFeaturesCount: Object.values(this.securityFeatures || {}).filter(Boolean).length\r\n });\r\n \r\n if (typeof this.sendFile === 'function') {\r\n secureAPI.sendFile = this.sendFile.bind(this);\r\n }\r\n \r\n // Create simple getFileTransferStatus method\r\n secureAPI.getFileTransferStatus = () => ({\r\n initialized: !!this.fileTransferSystem,\r\n status: 'ready',\r\n activeTransfers: 0,\r\n receivingTransfers: 0\r\n });\r\n \r\n if (typeof this.disconnect === 'function') {\r\n secureAPI.disconnect = this.disconnect.bind(this);\r\n }\r\n \r\n // Create simple API object with safety checks\r\n const safeGlobalAPI = {\r\n ...secureAPI, // Spread only existing methods\r\n getConfiguration: () => ({\r\n fakeTraffic: this._config.fakeTraffic.enabled,\r\n decoyChannels: this._config.decoyChannels.enabled,\r\n packetPadding: this._config.packetPadding.enabled,\r\n antiFingerprinting: this._config.antiFingerprinting.enabled\r\n }),\r\n emergency: {}\r\n };\r\n \r\n // Only add emergency methods that exist\r\n if (typeof this._emergencyUnlockAllMutexes === 'function') {\r\n safeGlobalAPI.emergency.unlockAllMutexes = this._emergencyUnlockAllMutexes.bind(this);\r\n }\r\n \r\n if (typeof this._emergencyRecoverMutexSystem === 'function') {\r\n safeGlobalAPI.emergency.recoverMutexSystem = this._emergencyRecoverMutexSystem.bind(this);\r\n }\r\n \r\n if (typeof this._emergencyDisableLogging === 'function') {\r\n safeGlobalAPI.emergency.disableLogging = this._emergencyDisableLogging.bind(this);\r\n }\r\n \r\n if (typeof this._resetLoggingSystem === 'function') {\r\n safeGlobalAPI.emergency.resetLogging = this._resetLoggingSystem.bind(this);\r\n }\r\n \r\n // Add file transfer system status\r\n safeGlobalAPI.getFileTransferSystemStatus = () => ({\r\n initialized: !!this.fileTransferSystem,\r\n status: 'ready',\r\n activeTransfers: 0,\r\n receivingTransfers: 0\r\n });\r\n \r\n // Log available methods for debugging\r\n this._secureLog('info', 'API methods available', {\r\n sendMessage: !!secureAPI.sendMessage,\r\n getConnectionStatus: !!secureAPI.getConnectionStatus,\r\n getSecurityStatus: !!secureAPI.getSecurityStatus,\r\n sendFile: !!secureAPI.sendFile,\r\n getFileTransferStatus: !!secureAPI.getFileTransferStatus,\r\n disconnect: !!secureAPI.disconnect,\r\n getConfiguration: !!safeGlobalAPI.getConfiguration,\r\n emergencyMethods: Object.keys(safeGlobalAPI.emergency).length\r\n });\r\n\r\n // Apply Object.freeze to prevent modification\r\n Object.freeze(safeGlobalAPI);\r\n Object.freeze(safeGlobalAPI.emergency);\r\n\r\n // Export API once without monitoring\r\n this._createProtectedGlobalAPI(safeGlobalAPI);\r\n \r\n // Setup minimal protection\r\n this._setupMinimalGlobalProtection();\r\n \r\n // Log that API setup is complete\r\n this._secureLog('info', 'Secure global API setup completed successfully');\r\n }\r\n /**\r\n * Create simple global API export\r\n */\r\n _createProtectedGlobalAPI(safeGlobalAPI) {\r\n // Log that we're creating protected global API\r\n this._secureLog('info', 'Creating protected global API');\r\n \r\n // Simple API export without proxy or monitoring\r\n if (!window.secureBitChat) {\r\n this._exportAPI(safeGlobalAPI);\r\n } else {\r\n this._secureLog('warn', '\u26A0\uFE0F Global API already exists, skipping setup');\r\n }\r\n }\r\n \r\n /**\r\n * Simple API export without monitoring\r\n */\r\n _exportAPI(apiObject) {\r\n // Log that we're exporting API\r\n this._secureLog('info', 'Exporting API to window.secureBitChat');\r\n \r\n // Check if important methods are available\r\n if (!this._importantMethods || !this._importantMethods.defineProperty) {\r\n this._secureLog('error', '\u274C Important methods not available for API export, using fallback');\r\n // Fallback to direct Object.defineProperty\r\n Object.defineProperty(window, 'secureBitChat', {\r\n value: apiObject,\r\n writable: false,\r\n configurable: false,\r\n enumerable: true\r\n });\r\n } else {\r\n // One-time export with immutable properties\r\n this._importantMethods.defineProperty(window, 'secureBitChat', {\r\n value: apiObject,\r\n writable: false,\r\n configurable: false,\r\n enumerable: true\r\n });\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Secure API exported to window.secureBitChat');\r\n }\r\n \r\n /**\r\n * Setup minimal global protection\r\n */\r\n _setupMinimalGlobalProtection() {\r\n // Simple protection without monitoring (methods already stored)\r\n this._protectGlobalAPI();\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Minimal global protection activated');\r\n }\r\n \r\n /**\r\n * Store important methods in closure for local use\r\n */\r\n _storeImportantMethods() {\r\n // Store references to important methods locally\r\n this._importantMethods = {\r\n defineProperty: Object.defineProperty,\r\n getOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,\r\n freeze: Object.freeze,\r\n consoleLog: console.log,\r\n consoleError: console.error,\r\n consoleWarn: console.warn\r\n };\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Important methods stored locally', {\r\n defineProperty: !!this._importantMethods.defineProperty,\r\n getOwnPropertyDescriptor: !!this._importantMethods.getOwnPropertyDescriptor,\r\n freeze: !!this._importantMethods.freeze\r\n });\r\n }\r\n\r\n /**\r\n * Simple protection without monitoring\r\n */\r\n _setupSimpleProtection() {\r\n this._secureLog('info', '\uD83D\uDD12 Simple protection activated - no monitoring');\r\n }\r\n\r\n /**\r\n * No global exposure prevention needed\r\n */\r\n _preventGlobalExposure() {\r\n this._secureLog('info', '\uD83D\uDD12 No global exposure prevention - using secure API export only');\r\n }\r\n /**\r\n * API integrity check - only at initialization\r\n */\r\n _verifyAPIIntegrity() {\r\n try {\r\n if (!window.secureBitChat) {\r\n this._secureLog('error', '\u274C SECURITY ALERT: Secure API has been removed!');\r\n return false;\r\n }\r\n \r\n const requiredMethods = ['sendMessage', 'getConnectionStatus', 'disconnect'];\r\n const missingMethods = requiredMethods.filter(method => \r\n typeof window.secureBitChat[method] !== 'function'\r\n );\r\n \r\n if (missingMethods.length > 0) {\r\n this._secureLog('error', '\u274C SECURITY ALERT: API tampering detected, missing methods:', { errorType: missingMethods?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C SECURITY ALERT: API integrity check failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n // ============================================\r\n // ADDITIONAL SECURITY METHODS\r\n // ============================================\r\n \r\n /**\r\n * Simple global exposure check - only at initialization\r\n */\r\n _auditGlobalExposure() {\r\n // Only check once at initialization, no periodic scanning\r\n this._secureLog('info', '\uD83D\uDD12 Global exposure check completed at initialization');\r\n return [];\r\n }\r\n \r\n /**\r\n * No periodic security audits - only at initialization\r\n */\r\n _startSecurityAudit() {\r\n // Only audit once at initialization, no periodic checks\r\n this._secureLog('info', '\uD83D\uDD12 Security audit completed at initialization - no periodic monitoring');\r\n }\r\n \r\n /**\r\n * Simple global API protection\r\n */\r\n _protectGlobalAPI() {\r\n if (!window.secureBitChat) {\r\n this._secureLog('warn', '\u26A0\uFE0F Global API not found during protection setup');\r\n return;\r\n }\r\n\r\n try {\r\n // Validate API integrity once\r\n if (this._validateAPIIntegrityOnce()) {\r\n this._secureLog('info', '\uD83D\uDD12 Global API protection verified');\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to verify global API protection', { \r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Validate API integrity once at initialization\r\n */\r\n _validateAPIIntegrityOnce() {\r\n try {\r\n // Check if API is properly configured\r\n if (!this._importantMethods || !this._importantMethods.getOwnPropertyDescriptor) {\r\n // Fallback to direct Object.getOwnPropertyDescriptor\r\n const descriptor = Object.getOwnPropertyDescriptor(window, 'secureBitChat');\r\n \r\n if (!descriptor || descriptor.configurable) {\r\n throw new Error('secureBitChat must not be reconfigurable!');\r\n }\r\n } else {\r\n const descriptor = this._importantMethods.getOwnPropertyDescriptor(window, 'secureBitChat');\r\n \r\n if (!descriptor || descriptor.configurable) {\r\n throw new Error('secureBitChat must not be reconfigurable!');\r\n }\r\n }\r\n \r\n this._secureLog('info', '\u2705 API integrity validated');\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C API integrity validation failed', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n return false;\r\n }\r\n }\r\n \r\n /**\r\n * Secure memory wipe for sensitive data\r\n */\r\n _secureWipeMemory(data, context = 'unknown') {\r\n if (!data) return;\r\n \r\n try {\r\n // Different handling for different data types\r\n if (data instanceof ArrayBuffer) {\r\n this._secureWipeArrayBuffer(data, context);\r\n } else if (data instanceof Uint8Array) {\r\n this._secureWipeUint8Array(data, context);\r\n } else if (Array.isArray(data)) {\r\n this._secureWipeArray(data, context);\r\n } else if (typeof data === 'string') {\r\n this._secureWipeString(data, context);\r\n } else if (data instanceof CryptoKey) {\r\n this._secureWipeCryptoKey(data, context);\r\n } else if (typeof data === 'object') {\r\n this._secureWipeObject(data, context);\r\n }\r\n \r\n this._secureMemoryManager.memoryStats.totalCleanups++;\r\n \r\n } catch (error) {\r\n this._secureMemoryManager.memoryStats.failedCleanups++;\r\n this._secureLog('error', '\u274C Secure memory wipe failed', {\r\n context: context,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for ArrayBuffer\r\n */\r\n _secureWipeArrayBuffer(buffer, context) {\r\n if (!buffer || buffer.byteLength === 0) return;\r\n \r\n try {\r\n const view = new Uint8Array(buffer);\r\n \r\n // Overwrite with random data first\r\n crypto.getRandomValues(view);\r\n \r\n // Overwrite with zeros\r\n view.fill(0);\r\n \r\n // Overwrite with ones\r\n view.fill(255);\r\n \r\n // Final zero overwrite\r\n view.fill(0);\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 ArrayBuffer securely wiped', {\r\n context: context,\r\n size: buffer.byteLength\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe ArrayBuffer', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for Uint8Array\r\n */\r\n _secureWipeUint8Array(array, context) {\r\n if (!array || array.length === 0) return;\r\n \r\n try {\r\n // Overwrite with random data first\r\n crypto.getRandomValues(array);\r\n \r\n // Overwrite with zeros\r\n array.fill(0);\r\n \r\n // Overwrite with ones\r\n array.fill(255);\r\n \r\n // Final zero overwrite\r\n array.fill(0);\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Uint8Array securely wiped', {\r\n context: context,\r\n size: array.length\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe Uint8Array', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for arrays\r\n */\r\n _secureWipeArray(array, context) {\r\n if (!Array.isArray(array) || array.length === 0) return;\r\n \r\n try {\r\n // Recursively wipe each element\r\n array.forEach((item, index) => {\r\n if (item !== null && item !== undefined) {\r\n this._secureWipeMemory(item, `${context}[${index}]`);\r\n }\r\n });\r\n \r\n // Fill with nulls\r\n array.fill(null);\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Array securely wiped', {\r\n context: context,\r\n size: array.length\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe array', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * No string wiping - strings are immutable in JS\r\n */\r\n _secureWipeString(str, context) {\r\n // Strings are immutable in JavaScript, no need to wipe\r\n // Just remove the reference\r\n this._secureLog('debug', '\uD83D\uDD12 String reference removed (strings are immutable)', {\r\n context: context,\r\n length: str ? str.length : 0\r\n });\r\n }\r\n \r\n /**\r\n * CryptoKey cleanup - store in WeakMap for proper GC\r\n */\r\n _secureWipeCryptoKey(key, context) {\r\n if (!key || !(key instanceof CryptoKey)) return;\r\n \r\n try {\r\n // Store in WeakMap for proper garbage collection\r\n if (!this._cryptoKeyStorage) {\r\n this._cryptoKeyStorage = new WeakMap();\r\n }\r\n \r\n // Store reference for cleanup tracking\r\n this._cryptoKeyStorage.set(key, {\r\n context: context,\r\n timestamp: Date.now(),\r\n type: key.type\r\n });\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 CryptoKey stored in WeakMap for cleanup', {\r\n context: context,\r\n type: key.type\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to store CryptoKey for cleanup', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure wipe for objects\r\n */\r\n _secureWipeObject(obj, context) {\r\n if (!obj || typeof obj !== 'object') return;\r\n \r\n try {\r\n // Recursively wipe all properties\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (value !== null && value !== undefined) {\r\n this._secureWipeMemory(value, `${context}.${key}`);\r\n }\r\n // Set property to null\r\n obj[key] = null;\r\n }\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Object securely wiped', {\r\n context: context,\r\n properties: Object.keys(obj).length\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe object', {\r\n context: context,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Secure cleanup of cryptographic materials\r\n */\r\n _secureCleanupCryptographicMaterials() {\r\n try {\r\n // Secure wipe of key pairs\r\n if (this.ecdhKeyPair) {\r\n this._secureWipeMemory(this.ecdhKeyPair, 'ecdhKeyPair');\r\n this.ecdhKeyPair = null;\r\n }\r\n \r\n if (this.ecdsaKeyPair) {\r\n this._secureWipeMemory(this.ecdsaKeyPair, 'ecdsaKeyPair');\r\n this.ecdsaKeyPair = null;\r\n }\r\n \r\n // Secure wipe of derived keys\r\n if (this.encryptionKey) {\r\n this._secureWipeMemory(this.encryptionKey, 'encryptionKey');\r\n this.encryptionKey = null;\r\n }\r\n \r\n if (this.macKey) {\r\n this._secureWipeMemory(this.macKey, 'macKey');\r\n this.macKey = null;\r\n }\r\n \r\n if (this.metadataKey) {\r\n this._secureWipeMemory(this.metadataKey, 'metadataKey');\r\n this.metadataKey = null;\r\n }\r\n \r\n if (this.nestedEncryptionKey) {\r\n this._secureWipeMemory(this.nestedEncryptionKey, 'nestedEncryptionKey');\r\n this.nestedEncryptionKey = null;\r\n }\r\n \r\n // Secure wipe of session data\r\n if (this.sessionSalt) {\r\n this._secureWipeMemory(this.sessionSalt, 'sessionSalt');\r\n this.sessionSalt = null;\r\n }\r\n \r\n if (this.sessionId) {\r\n this._secureWipeMemory(this.sessionId, 'sessionId');\r\n this.sessionId = null;\r\n }\r\n \r\n if (this.verificationCode) {\r\n this._secureWipeMemory(this.verificationCode, 'verificationCode');\r\n this.verificationCode = null;\r\n }\r\n \r\n if (this.peerPublicKey) {\r\n this._secureWipeMemory(this.peerPublicKey, 'peerPublicKey');\r\n this.peerPublicKey = null;\r\n }\r\n \r\n if (this.keyFingerprint) {\r\n this._secureWipeMemory(this.keyFingerprint, 'keyFingerprint');\r\n this.keyFingerprint = null;\r\n }\r\n \r\n if (this.connectionId) {\r\n this._secureWipeMemory(this.connectionId, 'connectionId');\r\n this.connectionId = null;\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Cryptographic materials securely cleaned up');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to cleanup cryptographic materials', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Force garbage collection if available\r\n */\r\n async _forceGarbageCollection() {\r\n try {\r\n // Use natural cleanup instead of forcing GC\r\n await this._performNaturalCleanup();\r\n this._secureLog('debug', '\uD83D\uDD12 Natural memory cleanup performed');\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to perform natural cleanup', {\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Perform periodic memory cleanup\r\n */\r\n async _performPeriodicMemoryCleanup() {\r\n try {\r\n this._secureMemoryManager.isCleaning = true;\r\n \r\n // Clean up any remaining sensitive data\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Clean up message queue if it's too large\r\n if (this.messageQueue && this.messageQueue.length > 100) {\r\n const excessMessages = this.messageQueue.splice(0, this.messageQueue.length - 50);\r\n excessMessages.forEach((message, index) => {\r\n this._secureWipeMemory(message, `periodicCleanup[${index}]`);\r\n });\r\n }\r\n \r\n // Clean up processed message IDs if too many\r\n if (this.processedMessageIds && this.processedMessageIds.size > 1000) {\r\n this.processedMessageIds.clear();\r\n }\r\n \r\n // Natural cleanup\r\n await this._forceGarbageCollection();\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Periodic memory cleanup completed');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error during periodic memory cleanup', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n } finally {\r\n this._secureMemoryManager.isCleaning = false;\r\n }\r\n }\r\n \r\n /**\r\n * Create secure error message without information disclosure\r\n */\r\n _createSecureErrorMessage(originalError, context = 'unknown') {\r\n try {\r\n // Categorize error for appropriate handling\r\n const category = this._categorizeError(originalError);\r\n \r\n // Generate safe error message based on category\r\n const safeMessage = this._getSafeErrorMessage(category, context);\r\n \r\n // Log detailed error internally for debugging\r\n this._secureLog('error', 'Internal error occurred', {\r\n category: category,\r\n context: context,\r\n errorType: originalError?.constructor?.name || 'Unknown',\r\n timestamp: Date.now()\r\n });\r\n \r\n // Track error frequency\r\n this._trackErrorFrequency(category);\r\n \r\n return safeMessage;\r\n \r\n } catch (error) {\r\n // Fallback to generic error if error handling fails\r\n this._secureLog('error', 'Error handling failed', {\r\n originalError: originalError?.message || 'Unknown',\r\n handlingError: error.message\r\n });\r\n return 'An unexpected error occurred';\r\n }\r\n }\r\n \r\n /**\r\n * Categorize error for appropriate handling\r\n */\r\n _categorizeError(error) {\r\n if (!error || !error.message) {\r\n return this._secureErrorHandler.errorCategories.UNKNOWN;\r\n }\r\n \r\n const message = error.message.toLowerCase();\r\n \r\n // Cryptographic errors\r\n if (message.includes('crypto') || \r\n message.includes('key') || \r\n message.includes('encrypt') || \r\n message.includes('decrypt') ||\r\n message.includes('sign') ||\r\n message.includes('verify') ||\r\n message.includes('ecdh') ||\r\n message.includes('ecdsa')) {\r\n return this._secureErrorHandler.errorCategories.CRYPTOGRAPHIC;\r\n }\r\n \r\n // Network errors\r\n if (message.includes('network') || \r\n message.includes('connection') || \r\n message.includes('timeout') ||\r\n message.includes('webrtc') ||\r\n message.includes('peer')) {\r\n return this._secureErrorHandler.errorCategories.NETWORK;\r\n }\r\n \r\n // Validation errors\r\n if (message.includes('invalid') || \r\n message.includes('validation') || \r\n message.includes('format') ||\r\n message.includes('type')) {\r\n return this._secureErrorHandler.errorCategories.VALIDATION;\r\n }\r\n \r\n // System errors\r\n if (message.includes('system') || \r\n message.includes('internal') || \r\n message.includes('memory') ||\r\n message.includes('resource')) {\r\n return this._secureErrorHandler.errorCategories.SYSTEM;\r\n }\r\n \r\n return this._secureErrorHandler.errorCategories.UNKNOWN;\r\n }\r\n \r\n /**\r\n * Get safe error message based on category\r\n */\r\n _getSafeErrorMessage(category, context) {\r\n const safeMessages = {\r\n [this._secureErrorHandler.errorCategories.CRYPTOGRAPHIC]: {\r\n 'key_generation': 'Security initialization failed',\r\n 'key_import': 'Security verification failed',\r\n 'key_derivation': 'Security setup failed',\r\n 'encryption': 'Message security failed',\r\n 'decryption': 'Message verification failed',\r\n 'signature': 'Authentication failed',\r\n 'default': 'Security operation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.NETWORK]: {\r\n 'connection': 'Connection failed',\r\n 'timeout': 'Connection timeout',\r\n 'peer': 'Peer connection failed',\r\n 'webrtc': 'Communication failed',\r\n 'default': 'Network operation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.VALIDATION]: {\r\n 'format': 'Invalid data format',\r\n 'type': 'Invalid data type',\r\n 'structure': 'Invalid data structure',\r\n 'default': 'Validation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.SYSTEM]: {\r\n 'memory': 'System resource error',\r\n 'resource': 'System resource unavailable',\r\n 'internal': 'Internal system error',\r\n 'default': 'System operation failed'\r\n },\r\n [this._secureErrorHandler.errorCategories.UNKNOWN]: {\r\n 'default': 'An unexpected error occurred'\r\n }\r\n };\r\n \r\n const categoryMessages = safeMessages[category] || safeMessages[this._secureErrorHandler.errorCategories.UNKNOWN];\r\n \r\n // Determine specific context for more precise message\r\n let specificContext = 'default';\r\n if (context.includes('key') || context.includes('crypto')) {\r\n specificContext = category === this._secureErrorHandler.errorCategories.CRYPTOGRAPHIC ? 'key_generation' : 'default';\r\n } else if (context.includes('connection') || context.includes('peer')) {\r\n specificContext = category === this._secureErrorHandler.errorCategories.NETWORK ? 'connection' : 'default';\r\n } else if (context.includes('validation') || context.includes('format')) {\r\n specificContext = category === this._secureErrorHandler.errorCategories.VALIDATION ? 'format' : 'default';\r\n }\r\n \r\n return categoryMessages[specificContext] || categoryMessages.default;\r\n }\r\n \r\n /**\r\n * Track error frequency for security monitoring\r\n */\r\n _trackErrorFrequency(category) {\r\n const now = Date.now();\r\n \r\n // Clean old error counts\r\n if (now - this._secureErrorHandler.lastErrorTime > 60000) { // 1 minute\r\n this._secureErrorHandler.errorCounts.clear();\r\n }\r\n \r\n // Increment error count\r\n const currentCount = this._secureErrorHandler.errorCounts.get(category) || 0;\r\n this._secureErrorHandler.errorCounts.set(category, currentCount + 1);\r\n this._secureErrorHandler.lastErrorTime = now;\r\n \r\n // Check if we're exceeding error threshold\r\n const totalErrors = Array.from(this._secureErrorHandler.errorCounts.values()).reduce((sum, count) => sum + count, 0);\r\n \r\n if (totalErrors > this._secureErrorHandler.errorThreshold) {\r\n this._secureErrorHandler.isInErrorMode = true;\r\n this._secureLog('warn', '\u26A0\uFE0F High error frequency detected - entering error mode', {\r\n totalErrors: totalErrors,\r\n threshold: this._secureErrorHandler.errorThreshold\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Throw secure error without information disclosure\r\n */\r\n _throwSecureError(originalError, context = 'unknown') {\r\n const secureMessage = this._createSecureErrorMessage(originalError, context);\r\n throw new Error(secureMessage);\r\n }\r\n \r\n /**\r\n * Get error handling statistics\r\n */\r\n _getErrorHandlingStats() {\r\n return {\r\n errorCounts: Object.fromEntries(this._secureErrorHandler.errorCounts),\r\n isInErrorMode: this._secureErrorHandler.isInErrorMode,\r\n lastErrorTime: this._secureErrorHandler.lastErrorTime,\r\n errorThreshold: this._secureErrorHandler.errorThreshold\r\n };\r\n }\r\n \r\n /**\r\n * Reset error handling system\r\n */\r\n _resetErrorHandlingSystem() {\r\n this._secureErrorHandler.errorCounts.clear();\r\n this._secureErrorHandler.isInErrorMode = false;\r\n this._secureErrorHandler.lastErrorTime = 0;\r\n \r\n this._secureLog('info', '\uD83D\uDD04 Error handling system reset');\r\n }\r\n \r\n /**\r\n * Get memory management statistics\r\n */\r\n _getMemoryManagementStats() {\r\n return {\r\n totalCleanups: this._secureMemoryManager.memoryStats.totalCleanups,\r\n failedCleanups: this._secureMemoryManager.memoryStats.failedCleanups,\r\n lastCleanup: this._secureMemoryManager.memoryStats.lastCleanup,\r\n isCleaning: this._secureMemoryManager.isCleaning,\r\n queueLength: this._secureMemoryManager.cleanupQueue.length\r\n };\r\n }\r\n \r\n /**\r\n * Validate API integrity and security\r\n */\r\n _validateAPIIntegrity() {\r\n try {\r\n // Check if API exists\r\n if (!window.secureBitChat) {\r\n this._secureLog('error', '\u274C Global API not found during integrity validation');\r\n return false;\r\n }\r\n \r\n // Validate required methods exist\r\n const requiredMethods = ['sendMessage', 'getConnectionStatus', 'getSecurityStatus', 'sendFile', 'disconnect'];\r\n const missingMethods = requiredMethods.filter(method => \r\n !window.secureBitChat[method] || typeof window.secureBitChat[method] !== 'function'\r\n );\r\n \r\n if (missingMethods.length > 0) {\r\n this._secureLog('error', '\u274C Global API integrity validation failed - missing methods', {\r\n missingMethods: missingMethods\r\n });\r\n return false;\r\n }\r\n \r\n // Test method binding integrity\r\n const testContext = { test: true };\r\n const boundMethods = requiredMethods.map(method => {\r\n try {\r\n return window.secureBitChat[method].bind(testContext);\r\n } catch (error) {\r\n return null;\r\n }\r\n });\r\n \r\n const unboundMethods = boundMethods.filter(method => method === null);\r\n if (unboundMethods.length > 0) {\r\n this._secureLog('error', '\u274C Global API integrity validation failed - method binding issues', {\r\n unboundMethods: unboundMethods.length\r\n });\r\n return false;\r\n }\r\n \r\n // Test API immutability\r\n try {\r\n const testProp = '_integrity_test_' + Date.now();\r\n Object.defineProperty(window.secureBitChat, testProp, {\r\n value: 'test',\r\n writable: true,\r\n configurable: true\r\n });\r\n \r\n this._secureLog('error', '\u274C Global API integrity validation failed - API is mutable');\r\n delete window.secureBitChat[testProp];\r\n return false;\r\n \r\n } catch (immutabilityError) {\r\n // This is expected - API should be immutable\r\n this._secureLog('debug', '\u2705 Global API immutability verified');\r\n }\r\n \r\n this._secureLog('info', '\u2705 Global API integrity validation passed');\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Global API integrity validation failed', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n _validateCryptographicSecurity() {\r\n // Check if basic security features are available\r\n const criticalFeatures = ['hasRateLimiting'];\r\n const missingCritical = criticalFeatures.filter(feature => !this.securityFeatures[feature]);\r\n \r\n if (missingCritical.length > 0) {\r\n this._secureLog('error', '\uD83D\uDEA8 CRITICAL: Missing critical rate limiting feature', {\r\n missing: missingCritical,\r\n currentFeatures: this.securityFeatures,\r\n action: 'Rate limiting will be forced enabled'\r\n });\r\n\r\n missingCritical.forEach(feature => {\r\n this.securityFeatures[feature] = true;\r\n this._secureLog('warn', `\u26A0\uFE0F Forced enable critical: ${feature} = true`);\r\n });\r\n }\r\n\r\n // Log current security state\r\n const availableFeatures = Object.keys(this.securityFeatures).filter(f => this.securityFeatures[f]);\r\n const encryptionFeatures = ['hasEncryption', 'hasECDH', 'hasECDSA'].filter(f => this.securityFeatures[f]);\r\n \r\n this._secureLog('info', '\u2705 Cryptographic security validation passed', {\r\n criticalFeatures: criticalFeatures.length,\r\n availableFeatures: availableFeatures.length,\r\n encryptionFeatures: encryptionFeatures.length,\r\n totalSecurityFeatures: availableFeatures.length,\r\n note: 'Encryption features will be enabled after key generation',\r\n currentState: {\r\n hasEncryption: this.securityFeatures.hasEncryption,\r\n hasECDH: this.securityFeatures.hasECDH,\r\n hasECDSA: this.securityFeatures.hasECDSA,\r\n hasRateLimiting: this.securityFeatures.hasRateLimiting\r\n }\r\n });\r\n \r\n return true;\r\n }\r\n\r\n _syncSecurityFeaturesWithTariff() {\r\n // All security features are enabled by default - no payment required\r\n this._secureLog('info', '\u2705 All security features enabled by default - no payment required');\r\n \r\n // Ensure all features are enabled\r\n const allFeatures = [\r\n 'hasEncryption', 'hasECDH', 'hasECDSA', 'hasMutualAuth',\r\n 'hasMetadataProtection', 'hasEnhancedReplayProtection',\r\n 'hasNonExtractableKeys', 'hasRateLimiting', 'hasEnhancedValidation', 'hasPFS',\r\n 'hasNestedEncryption', 'hasPacketPadding', 'hasPacketReordering',\r\n 'hasAntiFingerprinting', 'hasFakeTraffic', 'hasDecoyChannels', 'hasMessageChunking'\r\n ];\r\n \r\n allFeatures.forEach(feature => {\r\n this.securityFeatures[feature] = true;\r\n });\r\n \r\n this._secureLog('info', '\u2705 All security features enabled by default', {\r\n enabledFeatures: Object.keys(this.securityFeatures).filter(f => this.securityFeatures[f]).length,\r\n totalFeatures: Object.keys(this.securityFeatures).length\r\n });\r\n \r\n return;\r\n }\r\n \r\n /**\r\n * Emergency shutdown for critical issues\r\n */\r\n _emergencyShutdown(reason = 'Security breach') {\r\n this._secureLog('error', '\u274C EMERGENCY SHUTDOWN: ${reason}');\r\n \r\n try {\r\n // Clear critical data\r\n this.encryptionKey = null;\r\n this.macKey = null;\r\n this.metadataKey = null;\r\n this.verificationCode = null;\r\n this.keyFingerprint = null;\r\n this.connectionId = null;\r\n \r\n // Close connections\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Clear buffers\r\n this.messageQueue = [];\r\n this.processedMessageIds.clear();\r\n this.packetBuffer.clear();\r\n \r\n // Notify UI\r\n if (this.onStatusChange) {\r\n this.onStatusChange('security_breach');\r\n }\r\n \r\n this._secureLog('info', '\uD83D\uDD12 Emergency shutdown completed');\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error during emergency shutdown:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n _finalizeSecureInitialization() {\r\n this._startKeySecurityMonitoring();\r\n \r\n // Verify API integrity\r\n if (!this._verifyAPIIntegrity()) {\r\n this._secureLog('error', '\u274C Security initialization failed');\r\n return;\r\n }\r\n\r\n this._startSecurityMonitoring();\r\n \r\n // Start periodic log cleanup\r\n setInterval(() => {\r\n this._cleanupLogs();\r\n }, 300000);\r\n \r\n this._secureLog('info', '\u2705 Secure WebRTC Manager initialization completed');\r\n this._secureLog('info', '\uD83D\uDD12 Global exposure protection: Monitoring only, no automatic removal');\r\n }\r\n /**\r\n * Start security monitoring\r\n * @deprecated Use unified scheduler instead\r\n */\r\n _startSecurityMonitoring() {\r\n // All security monitoring moved to unified scheduler\r\n this._secureLog('info', '\uD83D\uDD27 Security monitoring moved to unified scheduler');\r\n }\r\n /**\r\n * Validates connection readiness for sending data\r\n * @param {boolean} throwError - whether to throw on not ready\r\n * @returns {boolean} true if connection is ready\r\n */\r\n _validateConnection(throwError = true) {\r\n const isDataChannelReady = this.dataChannel && this.dataChannel.readyState === 'open';\r\n const isConnectionVerified = this.isVerified;\r\n const isValid = isDataChannelReady && isConnectionVerified;\r\n \r\n if (!isValid && throwError) {\r\n if (!isDataChannelReady) {\r\n throw new Error('Data channel not ready');\r\n }\r\n if (!isConnectionVerified) {\r\n throw new Error('Connection not verified');\r\n }\r\n }\r\n \r\n return isValid;\r\n }\r\n\r\n /**\r\n * Hard gate for traffic blocking without verification\r\n * This method enforces that NO traffic (including system messages and file transfers)\r\n * can pass through without proper cryptographic verification\r\n */\r\n _enforceVerificationGate(operation = 'unknown', throwError = true) {\r\n if (!this.isVerified) {\r\n const errorMessage = `SECURITY VIOLATION: ${operation} blocked - connection not cryptographically verified`;\r\n this._secureLog('error', errorMessage, {\r\n operation: operation,\r\n isVerified: this.isVerified,\r\n hasKeys: !!(this.encryptionKey && this.macKey),\r\n timestamp: Date.now()\r\n });\r\n \r\n if (throwError) {\r\n throw new Error(errorMessage);\r\n }\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Safe method to set isVerified only after cryptographic verification\r\n * This is the ONLY method that should set isVerified = true\r\n */\r\n _setVerifiedStatus(verified, verificationMethod = 'unknown', verificationData = null) {\r\n if (verified) {\r\n // Validate that we have proper cryptographic verification\r\n if (!this.encryptionKey || !this.macKey) {\r\n throw new Error('Cannot set verified=true without encryption keys');\r\n }\r\n \r\n if (!verificationMethod || verificationMethod === 'unknown') {\r\n throw new Error('Cannot set verified=true without specifying verification method');\r\n }\r\n \r\n // Log the verification for audit trail\r\n this._secureLog('info', 'Connection verified through cryptographic verification', {\r\n verificationMethod: verificationMethod,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n keyFingerprint: this.keyFingerprint,\r\n timestamp: Date.now(),\r\n verificationData: verificationData ? 'provided' : 'none'\r\n });\r\n }\r\n \r\n this.isVerified = verified;\r\n \r\n if (verified) {\r\n this.onStatusChange('connected');\r\n } else {\r\n this.onStatusChange('disconnected');\r\n }\r\n }\r\n\r\n /**\r\n * Create AAD (Additional Authenticated Data) for file messages\r\n * This binds file messages to the current session and prevents replay attacks\r\n */\r\n _createFileMessageAAD(messageType, messageData = null) {\r\n // Verify that _createMessageAAD method is available\r\n if (typeof this._createMessageAAD !== 'function') {\r\n throw new Error('_createMessageAAD method is not available in _createFileMessageAAD. Manager may not be fully initialized.');\r\n }\r\n // Use the unified AAD creation method with file message flag\r\n return this._createMessageAAD(messageType, messageData, true);\r\n }\r\n\r\n /**\r\n * Validate AAD for file messages\r\n * This ensures file messages are bound to the correct session\r\n */\r\n _validateFileMessageAAD(aadString, expectedMessageType = null) {\r\n try {\r\n const aad = JSON.parse(aadString);\r\n \r\n // Validate session binding\r\n if (aad.sessionId !== (this.currentSession?.sessionId || 'unknown')) {\r\n throw new Error('AAD sessionId mismatch - possible replay attack');\r\n }\r\n \r\n if (aad.keyFingerprint !== (this.keyFingerprint || 'unknown')) {\r\n throw new Error('AAD keyFingerprint mismatch - possible key substitution attack');\r\n }\r\n \r\n // Validate message type if specified\r\n if (expectedMessageType && aad.messageType !== expectedMessageType) {\r\n throw new Error(`AAD messageType mismatch - expected ${expectedMessageType}, got ${aad.messageType}`);\r\n }\r\n \r\n // Validate timestamp (prevent very old messages)\r\n const now = Date.now();\r\n const messageAge = now - aad.timestamp;\r\n if (messageAge > 1800000) { // 30 minutes for better UX\r\n throw new Error('AAD timestamp too old - possible replay attack');\r\n }\r\n \r\n return aad;\r\n } catch (error) {\r\n this._secureLog('error', 'AAD validation failed', { error: error.message, aadString });\r\n throw new Error(`AAD validation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Extract DTLS fingerprint from SDP\r\n * This is essential for MITM protection\r\n */\r\n _extractDTLSFingerprintFromSDP(sdp) {\r\n try {\r\n if (!sdp || typeof sdp !== 'string') {\r\n throw new Error('Invalid SDP provided');\r\n }\r\n\r\n // Look for a=fingerprint lines in SDP with more flexible regex\r\n const fingerprintRegex = /a=fingerprint:([a-zA-Z0-9-]+)\\s+([A-Fa-f0-9:]+)/g;\r\n const fingerprints = [];\r\n let match;\r\n\r\n while ((match = fingerprintRegex.exec(sdp)) !== null) {\r\n fingerprints.push({\r\n algorithm: match[1].toLowerCase(),\r\n fingerprint: match[2].toLowerCase().replace(/:/g, '')\r\n });\r\n }\r\n\r\n if (fingerprints.length === 0) {\r\n // Try alternative fingerprint format\r\n const altFingerprintRegex = /fingerprint\\s*=\\s*([a-zA-Z0-9-]+)\\s+([A-Fa-f0-9:]+)/gi;\r\n while ((match = altFingerprintRegex.exec(sdp)) !== null) {\r\n fingerprints.push({\r\n algorithm: match[1].toLowerCase(),\r\n fingerprint: match[2].toLowerCase().replace(/:/g, '')\r\n });\r\n }\r\n }\r\n\r\n if (fingerprints.length === 0) {\r\n this._secureLog('warn', 'No DTLS fingerprints found in SDP - this may be normal for some WebRTC implementations', {\r\n sdpLength: sdp.length,\r\n sdpPreview: sdp.substring(0, 200) + '...'\r\n });\r\n throw new Error('No DTLS fingerprints found in SDP');\r\n }\r\n\r\n // Prefer SHA-256 fingerprints\r\n const sha256Fingerprint = fingerprints.find(fp => fp.algorithm === 'sha-256');\r\n if (sha256Fingerprint) {\r\n return sha256Fingerprint.fingerprint;\r\n }\r\n\r\n // Fallback to first available fingerprint\r\n return fingerprints[0].fingerprint;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to extract DTLS fingerprint from SDP', { \r\n error: error.message,\r\n sdpLength: sdp?.length || 0\r\n });\r\n throw new Error(`DTLS fingerprint extraction failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Validate DTLS fingerprint against expected value\r\n * This prevents MITM attacks by ensuring the remote peer has the expected certificate\r\n */\r\n async _validateDTLSFingerprint(receivedFingerprint, expectedFingerprint, context = 'unknown') {\r\n try {\r\n if (!receivedFingerprint || !expectedFingerprint) {\r\n throw new Error('Missing fingerprint for validation');\r\n }\r\n\r\n // Normalize fingerprints (remove colons, convert to lowercase)\r\n const normalizedReceived = receivedFingerprint.toLowerCase().replace(/:/g, '');\r\n const normalizedExpected = expectedFingerprint.toLowerCase().replace(/:/g, '');\r\n\r\n if (normalizedReceived !== normalizedExpected) {\r\n this._secureLog('error', 'DTLS fingerprint mismatch - possible MITM attack', {\r\n context: context,\r\n receivedHash: await this._createSafeLogHash(normalizedReceived, 'dtls_fingerprint'),\r\n expectedHash: await this._createSafeLogHash(normalizedExpected, 'dtls_fingerprint'),\r\n timestamp: Date.now()\r\n });\r\n \r\n throw new Error(`DTLS fingerprint mismatch - possible MITM attack in ${context}`);\r\n }\r\n\r\n this._secureLog('info', 'DTLS fingerprint validation successful', {\r\n context: context,\r\n fingerprintHash: await this._createSafeLogHash(normalizedReceived, 'dtls_fingerprint'),\r\n timestamp: Date.now()\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'DTLS fingerprint validation failed', { \r\n error: error.message, \r\n context: context \r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Compute SAS (Short Authentication String) for MITM protection\r\n * Uses HKDF with DTLS fingerprints to generate a stable 7-digit verification code\r\n * @param {ArrayBuffer|Uint8Array} keyMaterialRaw - Shared secret or key fingerprint data\r\n * @param {string} localFP - Local DTLS fingerprint\r\n * @param {string} remoteFP - Remote DTLS fingerprint\r\n * @returns {Promise} 7-digit SAS code\r\n */\r\n async _computeSAS(keyMaterialRaw, localFP, remoteFP) {\r\n try {\r\n \r\n if (!keyMaterialRaw || !localFP || !remoteFP) {\r\n const missing = [];\r\n if (!keyMaterialRaw) missing.push('keyMaterialRaw');\r\n if (!localFP) missing.push('localFP');\r\n if (!remoteFP) missing.push('remoteFP');\r\n throw new Error(`Missing required parameters for SAS computation: ${missing.join(', ')}`);\r\n }\r\n\r\n const enc = new TextEncoder();\r\n\r\n const salt = enc.encode(\r\n 'webrtc-sas|' + [localFP, remoteFP].sort().join('|')\r\n );\r\n\r\n let keyBuffer;\r\n if (keyMaterialRaw instanceof ArrayBuffer) {\r\n keyBuffer = keyMaterialRaw;\r\n } else if (keyMaterialRaw instanceof Uint8Array) {\r\n keyBuffer = keyMaterialRaw.buffer;\r\n } else if (typeof keyMaterialRaw === 'string') {\r\n // \u0415\u0441\u043B\u0438 \u044D\u0442\u043E \u0441\u0442\u0440\u043E\u043A\u0430 (\u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, keyFingerprint), \u0434\u0435\u043A\u043E\u0434\u0438\u0440\u0443\u0435\u043C \u0435\u0451\r\n // \u041F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u0435\u043C, \u0447\u0442\u043E \u044D\u0442\u043E hex \u0441\u0442\u0440\u043E\u043A\u0430\r\n const hexString = keyMaterialRaw.replace(/:/g, '').replace(/\\s/g, '');\r\n const bytes = new Uint8Array(hexString.length / 2);\r\n for (let i = 0; i < hexString.length; i += 2) {\r\n bytes[i / 2] = parseInt(hexString.substr(i, 2), 16);\r\n }\r\n keyBuffer = bytes.buffer;\r\n } else {\r\n throw new Error('Invalid keyMaterialRaw type');\r\n }\r\n\r\n // \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C HKDF(SHA-256) \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u0441\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u044B\u0435 64 \u0431\u0438\u0442\u0430 \u044D\u043D\u0442\u0440\u043E\u043F\u0438\u0438 \u0434\u043B\u044F \u043A\u043E\u0434\u0430\r\n const key = await crypto.subtle.importKey(\r\n 'raw',\r\n keyBuffer,\r\n 'HKDF',\r\n false,\r\n ['deriveBits']\r\n );\r\n\r\n const info = enc.encode('p2p-sas-v1');\r\n const bits = await crypto.subtle.deriveBits(\r\n { name: 'HKDF', hash: 'SHA-256', salt, info },\r\n key,\r\n 64 // 64 \u0431\u0438\u0442\u0430 \u0434\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u0434\u043B\u044F 6\u20137 \u0437\u043D\u0430\u043A\u043E\u0432\r\n );\r\n\r\n const dv = new DataView(bits);\r\n const n = (dv.getUint32(0) ^ dv.getUint32(4)) >>> 0;\r\n \r\n // Use rejection sampling to avoid bias in SAS code generation\r\n let sasValue;\r\n do {\r\n sasValue = crypto.getRandomValues(new Uint32Array(1))[0];\r\n } while (sasValue >= 4294967296 - (4294967296 % 10_000_000));\r\n \r\n const sasCode = String(sasValue % 10_000_000).padStart(7, '0'); \r\n\r\n\r\n this._secureLog('info', 'SAS code computed successfully', {\r\n localFP: localFP.substring(0, 16) + '...',\r\n remoteFP: remoteFP.substring(0, 16) + '...',\r\n sasLength: sasCode.length,\r\n timestamp: Date.now()\r\n });\r\n\r\n return sasCode;\r\n } catch (error) {\r\n this._secureLog('error', 'SAS computation failed', {\r\n error: error.message,\r\n keyMaterialType: typeof keyMaterialRaw,\r\n hasLocalFP: !!localFP,\r\n hasRemoteFP: !!remoteFP,\r\n timestamp: Date.now()\r\n });\r\n throw new Error(`SAS computation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * UTILITY: Decode hex keyFingerprint to Uint8Array for SAS computation\r\n * @param {string} hexString - Hex encoded keyFingerprint (e.g., \"aa:bb:cc:dd\")\r\n * @returns {Uint8Array} Decoded bytes\r\n */\r\n _decodeKeyFingerprint(hexString) {\r\n try {\r\n if (!hexString || typeof hexString !== 'string') {\r\n throw new Error('Invalid hex string provided');\r\n }\r\n\r\n // Use the utility from EnhancedSecureCryptoUtils\r\n return window.EnhancedSecureCryptoUtils.hexToUint8Array(hexString);\r\n } catch (error) {\r\n this._secureLog('error', 'Key fingerprint decoding failed', {\r\n error: error.message,\r\n inputType: typeof hexString,\r\n inputLength: hexString?.length || 0\r\n });\r\n throw new Error(`Key fingerprint decoding failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Emergency key wipe on fingerprint mismatch\r\n * This ensures no sensitive data remains if MITM is detected\r\n */\r\n _emergencyWipeOnFingerprintMismatch(reason = 'DTLS fingerprint mismatch') {\r\n try {\r\n this._secureLog('error', '\uD83D\uDEA8 EMERGENCY: Initiating security wipe due to fingerprint mismatch', {\r\n reason: reason,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Wipe all cryptographic materials\r\n this._secureWipeKeys();\r\n this._secureWipeMemory(this.encryptionKey, 'emergency_wipe');\r\n this._secureWipeMemory(this.macKey, 'emergency_wipe');\r\n this._secureWipeMemory(this.metadataKey, 'emergency_wipe');\r\n \r\n // Wipe ephemeral keys for PFS\r\n this._wipeEphemeralKeys();\r\n \r\n // Hard wipe old keys for PFS\r\n this._hardWipeOldKeys();\r\n\r\n // Reset verification status\r\n this.isVerified = null;\r\n this.verificationCode = null;\r\n this.keyFingerprint = null;\r\n this.connectionId = null;\r\n this.expectedDTLSFingerprint = null;\r\n\r\n // Disconnect immediately\r\n this.disconnect();\r\n\r\n // Notify UI about security breach\r\n this.deliverMessageToUI('\uD83D\uDEA8 SECURITY BREACH: Connection terminated due to fingerprint mismatch. Possible MITM attack detected!', 'system');\r\n\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to perform emergency wipe', { error: error.message });\r\n }\r\n }\r\n\r\n /**\r\n * Set expected DTLS fingerprint via out-of-band channel\r\n * This should be called after receiving the fingerprint through a secure channel\r\n * (e.g., QR code, voice call, in-person exchange, etc.)\r\n */\r\n setExpectedDTLSFingerprint(fingerprint, source = 'out_of_band') {\r\n try {\r\n if (!fingerprint || typeof fingerprint !== 'string') {\r\n throw new Error('Invalid fingerprint provided');\r\n }\r\n\r\n // Normalize fingerprint\r\n const normalizedFingerprint = fingerprint.toLowerCase().replace(/:/g, '');\r\n\r\n // Validate fingerprint format (should be hex string)\r\n if (!/^[a-f0-9]{40,64}$/.test(normalizedFingerprint)) {\r\n throw new Error('Invalid fingerprint format - must be hex string');\r\n }\r\n\r\n this.expectedDTLSFingerprint = normalizedFingerprint;\r\n\r\n this._secureLog('info', 'Expected DTLS fingerprint set via out-of-band channel', {\r\n source: source,\r\n fingerprint: normalizedFingerprint,\r\n timestamp: Date.now()\r\n });\r\n\r\n this.deliverMessageToUI(`\u2705 DTLS fingerprint set via ${source}. MITM protection enabled.`, 'system');\r\n\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to set expected DTLS fingerprint', { error: error.message });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current DTLS fingerprint for out-of-band verification\r\n * This should be shared through a secure channel (QR code, voice, etc.)\r\n */\r\n getCurrentDTLSFingerprint() {\r\n try {\r\n if (!this.expectedDTLSFingerprint) {\r\n throw new Error('No DTLS fingerprint available - connection not established');\r\n }\r\n\r\n return this.expectedDTLSFingerprint;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to get current DTLS fingerprint', { error: error.message });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * DEBUGGING: Temporarily disable strict DTLS validation\r\n * This should only be used for debugging connection issues\r\n */\r\n disableStrictDTLSValidation() {\r\n this.strictDTLSValidation = false;\r\n this._secureLog('warn', '\u26A0\uFE0F Strict DTLS validation disabled - security reduced', {\r\n timestamp: Date.now()\r\n });\r\n this.deliverMessageToUI('\u26A0\uFE0F DTLS validation disabled for debugging', 'system');\r\n }\r\n\r\n /**\r\n * SECURITY: Re-enable strict DTLS validation\r\n */\r\n enableStrictDTLSValidation() {\r\n this.strictDTLSValidation = true;\r\n this._secureLog('info', '\u2705 Strict DTLS validation re-enabled', {\r\n timestamp: Date.now()\r\n });\r\n this.deliverMessageToUI('\u2705 DTLS validation re-enabled', 'system');\r\n }\r\n\r\n /**\r\n * Generate ephemeral ECDH keys for Perfect Forward Secrecy\r\n * This ensures each session has unique, non-persistent keys\r\n */\r\n async _generateEphemeralECDHKeys() {\r\n try {\r\n this._secureLog('info', '\uD83D\uDD11 Generating ephemeral ECDH keys for PFS', {\r\n sessionStartTime: this.sessionStartTime,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Generate new ephemeral ECDH key pair\r\n const ephemeralKeyPair = await window.EnhancedSecureCryptoUtils.generateECDHKeyPair();\r\n \r\n if (!ephemeralKeyPair || !this._validateKeyPairConstantTime(ephemeralKeyPair)) {\r\n throw new Error('Ephemeral ECDH key pair validation failed');\r\n }\r\n\r\n // Store ephemeral keys with session binding\r\n const sessionId = this.currentSession?.sessionId || `session_${Date.now()}`;\r\n this.ephemeralKeyPairs.set(sessionId, {\r\n keyPair: ephemeralKeyPair,\r\n timestamp: Date.now(),\r\n sessionId: sessionId\r\n });\r\n\r\n this._secureLog('info', '\u2705 Ephemeral ECDH keys generated for PFS', {\r\n sessionIdHash: await this._createSafeLogHash(sessionId, 'session_id'),\r\n timestamp: Date.now()\r\n });\r\n\r\n return ephemeralKeyPair;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to generate ephemeral ECDH keys', { error: error.message });\r\n throw new Error(`Ephemeral key generation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Hard wipe old keys for real PFS\r\n * This prevents retrospective decryption attacks\r\n */\r\n async _hardWipeOldKeys() {\r\n try {\r\n this._secureLog('info', '\uD83E\uDDF9 Performing hard wipe of old keys for PFS', {\r\n oldKeysCount: this.oldKeys.size,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Hard wipe all old keys\r\n for (const [version, keySet] of this.oldKeys.entries()) {\r\n if (keySet.encryptionKey) {\r\n this._secureWipeMemory(keySet.encryptionKey, 'pfs_key_wipe');\r\n }\r\n if (keySet.macKey) {\r\n this._secureWipeMemory(keySet.macKey, 'pfs_key_wipe');\r\n }\r\n if (keySet.metadataKey) {\r\n this._secureWipeMemory(keySet.metadataKey, 'pfs_key_wipe');\r\n }\r\n \r\n // Clear references\r\n keySet.encryptionKey = null;\r\n keySet.macKey = null;\r\n keySet.metadataKey = null;\r\n keySet.keyFingerprint = null;\r\n }\r\n\r\n // Clear the oldKeys map completely\r\n this.oldKeys.clear();\r\n\r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n\r\n this._secureLog('info', '\u2705 Hard wipe of old keys completed for PFS', {\r\n timestamp: Date.now()\r\n });\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to perform hard wipe of old keys', { error: error.message });\r\n }\r\n }\r\n\r\n /**\r\n * Wipe ephemeral keys when session ends\r\n * This ensures session-specific keys are destroyed\r\n */\r\n async _wipeEphemeralKeys() {\r\n try {\r\n this._secureLog('info', '\uD83E\uDDF9 Wiping ephemeral keys for PFS', {\r\n ephemeralKeysCount: this.ephemeralKeyPairs.size,\r\n timestamp: Date.now()\r\n });\r\n\r\n // Wipe all ephemeral key pairs\r\n for (const [sessionId, keyData] of this.ephemeralKeyPairs.entries()) {\r\n if (keyData.keyPair?.privateKey) {\r\n this._secureWipeMemory(keyData.keyPair.privateKey, 'ephemeral_key_wipe');\r\n }\r\n if (keyData.keyPair?.publicKey) {\r\n this._secureWipeMemory(keyData.keyPair.publicKey, 'ephemeral_key_wipe');\r\n }\r\n \r\n // Clear references\r\n keyData.keyPair = null;\r\n keyData.timestamp = null;\r\n keyData.sessionId = null;\r\n }\r\n\r\n // Clear the ephemeral keys map\r\n this.ephemeralKeyPairs.clear();\r\n\r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n\r\n this._secureLog('info', '\u2705 Ephemeral keys wiped for PFS', {\r\n timestamp: Date.now()\r\n });\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to wipe ephemeral keys', { error: error.message });\r\n }\r\n }\r\n\r\n /**\r\n * Encrypt file messages with AAD\r\n * This ensures file messages are properly authenticated and bound to session\r\n */\r\n async _encryptFileMessage(messageData, aad) {\r\n try {\r\n if (!this.encryptionKey) {\r\n throw new Error('No encryption key available for file message');\r\n }\r\n\r\n // Convert message to string if it's an object\r\n const messageString = typeof messageData === 'string' ? messageData : JSON.stringify(messageData);\r\n \r\n // Encrypt with AAD using AES-GCM\r\n const encryptedData = await window.EnhancedSecureCryptoUtils.encryptDataWithAAD(\r\n messageString, \r\n this.encryptionKey, \r\n aad\r\n );\r\n \r\n // Create encrypted message wrapper\r\n const encryptedMessage = {\r\n type: 'encrypted_file_message',\r\n encryptedData: encryptedData,\r\n aad: aad,\r\n timestamp: Date.now(),\r\n keyFingerprint: this.keyFingerprint\r\n };\r\n \r\n return JSON.stringify(encryptedMessage);\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to encrypt file message', { error: error.message });\r\n throw new Error(`File message encryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Decrypt file messages with AAD validation\r\n * This ensures file messages are properly authenticated and bound to session\r\n */\r\n async _decryptFileMessage(encryptedMessageString) {\r\n try {\r\n const encryptedMessage = JSON.parse(encryptedMessageString);\r\n \r\n if (encryptedMessage.type !== 'encrypted_file_message') {\r\n throw new Error('Invalid encrypted file message type');\r\n }\r\n \r\n // Validate key fingerprint\r\n if (encryptedMessage.keyFingerprint !== this.keyFingerprint) {\r\n throw new Error('Key fingerprint mismatch in encrypted file message');\r\n }\r\n \r\n // Validate AAD with sequence number\r\n const aad = this._validateMessageAAD(encryptedMessage.aad, 'file_message');\r\n \r\n if (!this.encryptionKey) {\r\n throw new Error('No encryption key available for file message decryption');\r\n }\r\n \r\n // Decrypt with AAD validation\r\n const decryptedData = await window.EnhancedSecureCryptoUtils.decryptDataWithAAD(\r\n encryptedMessage.encryptedData,\r\n this.encryptionKey,\r\n encryptedMessage.aad\r\n );\r\n \r\n return {\r\n decryptedData: decryptedData,\r\n aad: aad\r\n };\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to decrypt file message', { error: error.message });\r\n throw new Error(`File message decryption failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Validates encryption keys readiness\r\n * @param {boolean} throwError - whether to throw on not ready\r\n * @returns {boolean} true if keys are ready\r\n */\r\n _validateEncryptionKeys(throwError = true) {\r\n const hasAllKeys = !!(this.encryptionKey && this.macKey && this.metadataKey);\r\n \r\n if (!hasAllKeys && throwError) {\r\n throw new Error('Encryption keys not initialized');\r\n }\r\n \r\n return hasAllKeys;\r\n }\r\n\r\n /**\r\n * Checks whether a message is a file-transfer message\r\n * @param {string|object} data - message payload\r\n * @returns {boolean} true if it's a file message\r\n */\r\n _isFileMessage(data) {\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return parsed.type && parsed.type.startsWith('file_');\r\n } catch {\r\n return false;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data.type) {\r\n return data.type.startsWith('file_');\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Checks whether a message is a system message\r\n * @param {string|object} data - message payload \r\n * @returns {boolean} true if it's a system message\r\n */\r\n _isSystemMessage(data) {\r\n const systemTypes = [\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_BOTH_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.PEER_DISCONNECT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.SECURITY_UPGRADE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_SIGNAL,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_READY\r\n ];\r\n\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return systemTypes.includes(parsed.type);\r\n } catch {\r\n return false;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data.type) {\r\n return systemTypes.includes(data.type);\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Checks whether a message is fake traffic\r\n * @param {any} data - message payload\r\n * @returns {boolean} true if it's a fake message\r\n */\r\n _isFakeMessage(data) {\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return parsed.type === EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE || \r\n parsed.isFakeTraffic === true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data !== null) {\r\n return data.type === EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE || \r\n data.isFakeTraffic === true;\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Safely executes an operation with error handling\r\n * @param {Function} operation - operation to execute\r\n * @param {string} errorMessage - error message to log\r\n * @param {any} fallback - default value on error\r\n * @returns {any} operation result or fallback\r\n */\r\n _withErrorHandling(operation, errorMessage, fallback = null) {\r\n try {\r\n return operation();\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C ${errorMessage}:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n return fallback;\r\n }\r\n }\r\n\r\n /**\r\n * Safely executes an async operation with error handling\r\n * @param {Function} operation - async operation\r\n * @param {string} errorMessage - error message to log\r\n * @param {any} fallback - default value on error\r\n * @returns {Promise} operation result or fallback\r\n */\r\n async _withAsyncErrorHandling(operation, errorMessage, fallback = null) {\r\n try {\r\n return await operation();\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C ${errorMessage}:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n return fallback;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Extracts message type from data\r\n * @param {string|object} data - message data\r\n * @returns {string|null} message type or null\r\n */\r\n _getMessageType(data) {\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n return parsed.type || null;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n \r\n if (typeof data === 'object' && data !== null) {\r\n return data.type || null;\r\n }\r\n \r\n return null;\r\n }\r\n\r\n /**\r\n * Resets notification flags for a new connection\r\n */\r\n _resetNotificationFlags() {\r\n this.lastSecurityLevelNotification = null;\r\n this.verificationNotificationSent = false;\r\n this.verificationInitiationSent = false;\r\n this.disconnectNotificationSent = false;\r\n this.reconnectionFailedNotificationSent = false;\r\n this.peerDisconnectNotificationSent = false;\r\n this.connectionClosedNotificationSent = false;\r\n this.fakeTrafficDisabledNotificationSent = false;\r\n this.advancedFeaturesDisabledNotificationSent = false;\r\n this.securityUpgradeNotificationSent = false;\r\n this.lastSecurityUpgradeStage = null;\r\n this.securityCalculationNotificationSent = false;\r\n this.lastSecurityCalculationLevel = null;\r\n }\r\n\r\n /**\r\n * Checks whether a message was filtered out\r\n * @param {any} result - processing result\r\n * @returns {boolean} true if filtered\r\n */\r\n _isFilteredMessage(result) {\r\n const filteredResults = Object.values(EnhancedSecureWebRTCManager.FILTERED_RESULTS);\r\n return filteredResults.includes(result);\r\n }\r\n /**\r\n * Enhanced log cleanup with security checks\r\n */\r\n _cleanupLogs() {\r\n // More aggressive cleanup to prevent data accumulation\r\n if (this._logCounts.size > 500) {\r\n this._logCounts.clear();\r\n this._secureLog('debug', '\uD83E\uDDF9 Log counts cleared due to size limit');\r\n }\r\n \r\n // Clean up old log entries to prevent memory leaks\r\n const now = Date.now();\r\n const maxAge = 300000; // 5 minutes\r\n \r\n // Check for suspicious log patterns\r\n let suspiciousCount = 0;\r\n for (const [key, count] of this._logCounts.entries()) {\r\n if (count > 10) {\r\n suspiciousCount++;\r\n }\r\n }\r\n \r\n // Emergency cleanup if too many suspicious patterns\r\n if (suspiciousCount > 20) {\r\n this._logCounts.clear();\r\n this._secureLog('warn', '\uD83D\uDEA8 Emergency log cleanup due to suspicious patterns');\r\n }\r\n \r\n // Reset security violation counter if system is stable\r\n if (this._logSecurityViolations > 0 && suspiciousCount < 5) {\r\n this._logSecurityViolations = Math.max(0, this._logSecurityViolations - 1);\r\n }\r\n \r\n // Clean up old IVs periodically\r\n if (!this._lastIVCleanupTime || Date.now() - this._lastIVCleanupTime > 300000) { // Every 5 minutes\r\n this._cleanupOldIVs();\r\n this._lastIVCleanupTime = Date.now();\r\n }\r\n \r\n // Periodic secure memory cleanup\r\n if (!this._secureMemoryManager.memoryStats.lastCleanup || \r\n Date.now() - this._secureMemoryManager.memoryStats.lastCleanup > 600000) { // Every 10 minutes\r\n // Schedule async cleanup without blocking\r\n this._performPeriodicMemoryCleanup().catch(error => {\r\n this._secureLog('error', 'Periodic cleanup failed', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n this._secureMemoryManager.memoryStats.lastCleanup = Date.now();\r\n }\r\n }\r\n /**\r\n * Secure logging stats with sensitive data protection\r\n */\r\n _getLoggingStats() {\r\n // Only return safe statistics\r\n const stats = {\r\n isProductionMode: this._isProductionMode,\r\n debugMode: this._debugMode,\r\n currentLogLevel: this._currentLogLevel,\r\n logCountsSize: this._logCounts.size,\r\n maxLogCount: this._maxLogCount,\r\n securityViolations: this._logSecurityViolations || 0,\r\n maxSecurityViolations: this._maxLogSecurityViolations || 3,\r\n systemStatus: this._currentLogLevel === -1 ? 'DISABLED' : 'ACTIVE'\r\n };\r\n \r\n // Sanitize any potentially sensitive data\r\n const sanitizedStats = {};\r\n for (const [key, value] of Object.entries(stats)) {\r\n if (typeof value === 'string' && this._containsSensitiveContent(value)) {\r\n sanitizedStats[key] = '[SENSITIVE_DATA_REDACTED]';\r\n } else {\r\n sanitizedStats[key] = value;\r\n }\r\n }\r\n \r\n return sanitizedStats;\r\n }\r\n /**\r\n * Enhanced emergency logging disable with cleanup\r\n */\r\n async _emergencyDisableLogging() {\r\n // Immediately disable all logging levels\r\n this._currentLogLevel = -1;\r\n \r\n // Clear all log data to prevent memory leaks\r\n this._logCounts.clear();\r\n \r\n // Clear any cached sensitive data\r\n if (this._logSecurityViolations) {\r\n this._logSecurityViolations = 0;\r\n }\r\n \r\n // Override _secureLog to a secure no-op\r\n this._secureLog = () => {\r\n // Only allow emergency console errors\r\n if (arguments[0] === 'error' && this._originalConsole?.error) {\r\n this._originalConsole.error('\uD83D\uDEA8 SECURITY: Logging system disabled - potential data exposure prevented');\r\n }\r\n };\r\n \r\n // Store original functions before overriding\r\n this._originalSanitizeString = this._sanitizeString;\r\n this._originalSanitizeLogData = this._sanitizeLogData;\r\n this._originalAuditLogMessage = this._auditLogMessage;\r\n this._originalContainsSensitiveContent = this._containsSensitiveContent;\r\n \r\n // Override all logging methods to prevent bypass\r\n this._sanitizeString = () => '[LOGGING_DISABLED]';\r\n this._sanitizeLogData = () => ({ error: 'LOGGING_DISABLED' });\r\n this._auditLogMessage = () => false;\r\n this._containsSensitiveContent = () => true; // Block everything\r\n \r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n \r\n // Notify about the emergency shutdown\r\n this._originalConsole?.error?.('\uD83D\uDEA8 CRITICAL: Secure logging system disabled due to potential data exposure');\r\n }\r\n\r\n /**\r\n * Reset logging system after emergency shutdown\r\n * Use this function to restore normal logging functionality\r\n */\r\n _resetLoggingSystem() {\r\n this._secureLog('info', '\uD83D\uDD27 Resetting logging system after emergency shutdown');\r\n \r\n // Restore original sanitize functions\r\n this._sanitizeString = this._originalSanitizeString || ((str) => str);\r\n this._sanitizeLogData = this._originalSanitizeLogData || ((data) => data);\r\n this._auditLogMessage = this._originalAuditLogMessage || (() => true);\r\n this._containsSensitiveContent = this._originalContainsSensitiveContent || (() => false);\r\n \r\n // Reset security violation counters\r\n this._logSecurityViolations = 0;\r\n \r\n this._secureLog('info', '\u2705 Logging system reset successfully');\r\n }\r\n /**\r\n * Enhanced audit function for log message security\r\n */\r\n _auditLogMessage(message, data) {\r\n if (!data || typeof data !== 'object') return true;\r\n \r\n // Convert to string and check for sensitive content\r\n const dataString = JSON.stringify(data);\r\n \r\n // Check message itself for sensitive content\r\n if (this._containsSensitiveContent(message)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.('\uD83D\uDEA8 SECURITY BREACH: Sensitive content detected in log message');\r\n return false;\r\n }\r\n \r\n // Check data string for sensitive content\r\n if (this._containsSensitiveContent(dataString)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.('\uD83D\uDEA8 SECURITY BREACH: Sensitive content detected in log data');\r\n return false;\r\n }\r\n \r\n // Enhanced dangerous pattern detection\r\n const dangerousPatterns = [\r\n 'secret', 'token', 'password', 'credential', 'auth',\r\n 'fingerprint', 'salt', 'signature', 'private_key', 'api_key', 'private',\r\n 'encryption', 'mac', 'metadata', 'session', 'jwt', 'bearer',\r\n 'key', 'hash', 'digest', 'nonce', 'iv', 'cipher'\r\n ];\r\n \r\n const dataStringLower = dataString.toLowerCase();\r\n \r\n for (const pattern of dangerousPatterns) {\r\n if (dataStringLower.includes(pattern) && !this._safeFieldsWhitelist.has(pattern)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 SECURITY BREACH: Dangerous pattern detected in log: ${pattern}`);\r\n return false;\r\n }\r\n }\r\n \r\n // Check for high entropy values in data\r\n for (const [key, value] of Object.entries(data)) {\r\n if (typeof value === 'string' && this._hasHighEntropy(value)) {\r\n this._emergencyDisableLogging();\r\n this._originalConsole?.error?.(`\uD83D\uDEA8 SECURITY BREACH: High entropy value detected in log field: ${key}`);\r\n return false;\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n\r\n initializeFileTransfer() {\r\n try {\r\n this._secureLog('info', '\uD83D\uDD27 Initializing Enhanced Secure File Transfer system...');\r\n\r\n if (this.fileTransferSystem) {\r\n this._secureLog('info', '\u2705 File transfer system already initialized');\r\n return;\r\n }\r\n \r\n // Step-by-step readiness check\r\n const channelReady = !!(this.dataChannel && this.dataChannel.readyState === 'open');\r\n if (!channelReady) {\r\n this._secureLog('warn', '\u26A0\uFE0F Data channel not open, deferring file transfer initialization');\r\n if (this.dataChannel) {\r\n const initHandler = () => {\r\n this._secureLog('info', '\uD83D\uDD04 DataChannel opened, initializing file transfer...');\r\n this.initializeFileTransfer();\r\n };\r\n this.dataChannel.addEventListener('open', initHandler, { once: true });\r\n }\r\n return;\r\n }\r\n\r\n if (!this.isVerified) {\r\n this._secureLog('warn', '\u26A0\uFE0F Connection not verified yet, deferring file transfer initialization');\r\n setTimeout(() => this.initializeFileTransfer(), 500);\r\n return;\r\n }\r\n \r\n // FIX: Clean up previous system if present\r\n if (this.fileTransferSystem) {\r\n this._secureLog('info', '\uD83E\uDDF9 Cleaning up existing file transfer system');\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n // Ensure encryption keys are present\r\n if (!this.encryptionKey || !this.macKey) {\r\n this._secureLog('warn', '\u26A0\uFE0F Encryption keys not ready, deferring file transfer initialization');\r\n setTimeout(() => this.initializeFileTransfer(), 1000);\r\n return;\r\n }\r\n \r\n // IMPORTANT: callback order: (onProgress, onComplete, onError, onFileReceived)\r\n const safeOnComplete = (summary) => {\r\n // Sender: finalize transfer, no Blob handling\r\n try {\r\n this._secureLog('info', '\uD83C\uDFC1 Sender transfer summary', { summary });\r\n // Optionally forward as progress/UI event\r\n if (this.onFileProgress) {\r\n this.onFileProgress({ type: 'complete', ...summary });\r\n }\r\n } catch (e) {\r\n this._secureLog('warn', '\u26A0\uFE0F onComplete handler failed:', { details: e.message });\r\n }\r\n };\r\n\r\n this.fileTransferSystem = new EnhancedSecureFileTransfer(\r\n this,\r\n this.onFileProgress || null,\r\n safeOnComplete,\r\n this.onFileError || null,\r\n this.onFileReceived || null\r\n );\r\n \r\n this._fileTransferActive = true;\r\n \r\n this._secureLog('info', '\u2705 Enhanced Secure File Transfer system initialized successfully');\r\n \r\n // Verify the system is ready\r\n const status = this.fileTransferSystem.getSystemStatus();\r\n this._secureLog('info', '\uD83D\uDD0D File transfer system status after init', { status });\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to initialize file transfer system', { errorType: error.constructor.name });\r\n this.fileTransferSystem = null;\r\n this._fileTransferActive = false;\r\n }\r\n }\r\n\r\n // ============================================\r\n // ENHANCED SECURITY INITIALIZATION\r\n // ============================================\r\n\r\n async initializeEnhancedSecurity() {\r\n try {\r\n // Generate nested encryption key\r\n await this.generateNestedEncryptionKey();\r\n \r\n // Initialize decoy channels\r\n if (this.decoyChannelConfig.enabled) {\r\n this.initializeDecoyChannels();\r\n }\r\n \r\n // Start fake traffic generation\r\n if (this.fakeTrafficConfig.enabled) {\r\n this.startFakeTrafficGeneration();\r\n }\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to initialize enhanced security', { errorType: error.constructor.name });\r\n }\r\n }\r\n \r\n // Helper function: unbiased integer in [min, max]\r\n getSafeRandomInt(min, max) {\r\n if (!Number.isInteger(min) || !Number.isInteger(max)) {\r\n throw new Error('getSafeRandomInt requires integer min and max');\r\n }\r\n if (min >= max) {\r\n throw new Error('min must be less than max');\r\n }\r\n \r\n const range = max - min + 1;\r\n const bitsNeeded = Math.ceil(Math.log2(range));\r\n const bytesNeeded = Math.ceil(bitsNeeded / 8);\r\n const mask = (1 << bitsNeeded) - 1;\r\n \r\n let randomValue;\r\n do {\r\n const randomBytes = crypto.getRandomValues(new Uint8Array(bytesNeeded));\r\n\r\n randomValue = 0;\r\n for (let i = 0; i < bytesNeeded; i++) {\r\n randomValue = (randomValue * 256) + randomBytes[i];\r\n }\r\n\r\n randomValue = randomValue & mask;\r\n \r\n } while (randomValue >= range); \r\n\r\n return min + randomValue;\r\n }\r\n\r\n getSafeRandomFloat(minFloat, maxFloat, steps = 1000) {\r\n if (typeof minFloat !== 'number' || typeof maxFloat !== 'number') {\r\n throw new Error('getSafeRandomFloat requires numeric min and max');\r\n }\r\n if (minFloat >= maxFloat) {\r\n throw new Error('minFloat must be less than maxFloat');\r\n }\r\n const randomIndex = this.getSafeRandomInt(0, steps);\r\n \r\n const step = (maxFloat - minFloat) / steps;\r\n\r\n return minFloat + (randomIndex * step);\r\n }\r\n\r\n generateFingerprintMask() {\r\n const mask = {\r\n timingOffset: this.getSafeRandomInt(0, 1500),\r\n sizeVariation: this.getSafeRandomFloat(0.75, 1.25, 1000),\r\n noisePattern: Array.from(crypto.getRandomValues(new Uint8Array(64))),\r\n headerVariations: [\r\n 'X-Client-Version', 'X-Session-ID', 'X-Request-ID', 'X-Timestamp', 'X-Signature',\r\n 'X-Secure', 'X-Encrypted', 'X-Protected', 'X-Safe', 'X-Anonymous', 'X-Private'\r\n ],\r\n noiseIntensity: this.getSafeRandomInt(50, 150),\r\n sizeMultiplier: this.getSafeRandomFloat(0.75, 1.25, 1000),\r\n timingVariation: this.getSafeRandomInt(100, 1100)\r\n };\r\n return mask;\r\n }\r\n\r\n // Security configuration - all features enabled by default\r\n configureSecurityForSession() {\r\n this._secureLog('info', '\uD83D\uDD27 Configuring security - all features enabled by default');\r\n \r\n // All security features are enabled by default - no payment required\r\n this.sessionConstraints = {};\r\n \r\n Object.keys(this.securityFeatures).forEach(feature => {\r\n this.sessionConstraints[feature] = true; // All features enabled\r\n });\r\n \r\n this.applySessionConstraints();\r\n \r\n this._secureLog('info', '\u2705 Security configured - all features enabled', { constraints: this.sessionConstraints });\r\n\r\n if (!this._validateCryptographicSecurity()) {\r\n this._secureLog('error', '\uD83D\uDEA8 CRITICAL: Cryptographic security validation failed after session configuration');\r\n\r\n if (this.onStatusChange) {\r\n this.onStatusChange('security_breach', {\r\n type: 'crypto_security_failure',\r\n message: 'Cryptographic security validation failed after session configuration'\r\n });\r\n }\r\n }\r\n \r\n this.notifySecurityLevel();\r\n \r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, EnhancedSecureWebRTCManager.TIMEOUTS.SECURITY_CALC_DELAY);\r\n }\r\n\r\n // Applying session constraints - all features enabled by default\r\n applySessionConstraints() {\r\n if (!this.sessionConstraints) return;\r\n\r\n // All features are enabled by default - no restrictions\r\n Object.keys(this.sessionConstraints).forEach(feature => {\r\n this.securityFeatures[feature] = true; // All features enabled\r\n \r\n // Enable linked configurations\r\n switch (feature) {\r\n case 'hasFakeTraffic':\r\n this.fakeTrafficConfig.enabled = true;\r\n if (this.isConnected()) {\r\n this.startFakeTrafficGeneration();\r\n }\r\n break;\r\n case 'hasDecoyChannels':\r\n this.decoyChannelConfig.enabled = true;\r\n if (this.isConnected()) {\r\n this.initializeDecoyChannels();\r\n }\r\n break;\r\n case 'hasPacketReordering':\r\n this.reorderingConfig.enabled = true;\r\n break;\r\n case 'hasAntiFingerprinting':\r\n this.antiFingerprintingConfig.enabled = true;\r\n break;\r\n case 'hasMessageChunking':\r\n this.chunkingConfig.enabled = true;\r\n break;\r\n }\r\n });\r\n \r\n this._secureLog('info', '\u2705 All security features enabled by default', {\r\n constraints: this.sessionConstraints,\r\n currentFeatures: this.securityFeatures\r\n });\r\n }\r\n deliverMessageToUI(message, type = 'received') {\r\n try {\r\n // Add debug logs\r\n this._secureLog('debug', '\uD83D\uDCE4 deliverMessageToUI called', {\r\n message: message,\r\n type: type,\r\n messageType: typeof message,\r\n hasOnMessage: !!this.onMessage\r\n });\r\n \r\n // Filter out file-transfer and system messages\r\n if (typeof message === 'object' && message.type) {\r\n const blockedTypes = [\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_START,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_CHUNK,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.CHUNK_CONFIRMATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_COMPLETE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_ERROR,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_BOTH_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.PEER_DISCONNECT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_SIGNAL,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_READY,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.SECURITY_UPGRADE\r\n ];\r\n if (blockedTypes.includes(message.type)) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83D\uDED1 Blocked system/file message from UI: ${message.type}`);\r\n }\r\n return; // do not show in chat\r\n }\r\n }\r\n\r\n // Additional check for string messages containing JSON\r\n if (typeof message === 'string' && message.trim().startsWith('{')) {\r\n try {\r\n const parsedMessage = JSON.parse(message);\r\n if (parsedMessage.type) {\r\n const blockedTypes = [\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_START,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_CHUNK,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.CHUNK_CONFIRMATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_COMPLETE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.FILE_TRANSFER_ERROR,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.HEARTBEAT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_RESPONSE,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.VERIFICATION_BOTH_CONFIRMED,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.PEER_DISCONNECT,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_SIGNAL,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.KEY_ROTATION_READY,\r\n EnhancedSecureWebRTCManager.MESSAGE_TYPES.SECURITY_UPGRADE\r\n ];\r\n if (blockedTypes.includes(parsedMessage.type)) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83D\uDED1 Blocked system/file message from UI (string): ${parsedMessage.type}`);\r\n }\r\n return; // do not show in chat\r\n }\r\n }\r\n } catch (parseError) {\r\n // Not JSON \u2014 fine for plain text messages\r\n }\r\n }\r\n\r\n if (this.onMessage) {\r\n this._secureLog('debug', '\uD83D\uDCE4 Calling this.onMessage callback', { message, type });\r\n this.onMessage(message, type);\r\n } else {\r\n this._secureLog('warn', '\u26A0\uFE0F this.onMessage callback is null or undefined');\r\n }\r\n } catch (err) {\r\n this._secureLog('error', '\u274C Failed to deliver message to UI:', { errorType: err?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n\r\n // Security Level Notification\r\n notifySecurityLevel() {\r\n // Avoid duplicate notifications\r\n if (this.lastSecurityLevelNotification === 'maximum') {\r\n return; // prevent duplication\r\n }\r\n \r\n this.lastSecurityLevelNotification = 'maximum';\r\n \r\n const message = '\uD83D\uDEE1\uFE0F Maximum Security Active - All features enabled';\r\n \r\n if (this.onMessage) {\r\n this.deliverMessageToUI(message, 'system');\r\n }\r\n\r\n // Showing details of active features\r\n if (this.onMessage) {\r\n const activeFeatures = Object.entries(this.securityFeatures)\r\n .filter(([key, value]) => value === true)\r\n .map(([key]) => key.replace('has', '').replace(/([A-Z])/g, ' $1').trim().toLowerCase())\r\n .slice(0, 5); \r\n\r\n this.deliverMessageToUI(`\uD83D\uDD27 Active: ${activeFeatures.join(', ')}...`, 'system');\r\n }\r\n }\r\n\r\n // Cleaning decoy channels\r\n cleanupDecoyChannels() {\r\n // Stopping decoy traffic\r\n for (const [channelName, timer] of this.decoyTimers.entries()) {\r\n clearTimeout(timer);\r\n }\r\n this.decoyTimers.clear();\r\n \r\n // Closing decoy channels\r\n for (const [channelName, channel] of this.decoyChannels.entries()) {\r\n if (channel.readyState === 'open') {\r\n channel.close();\r\n }\r\n }\r\n this.decoyChannels.clear();\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Decoy channels cleaned up');\r\n }\r\n\r\n // ============================================\r\n // 1. NESTED ENCRYPTION LAYER\r\n // ============================================\r\n\r\n async generateNestedEncryptionKey() {\r\n try {\r\n // Generate additional encryption key for nested encryption\r\n this.nestedEncryptionKey = await crypto.subtle.generateKey(\r\n { name: 'AES-GCM', length: 256 },\r\n false,\r\n ['encrypt', 'decrypt']\r\n );\r\n \r\n // Generate random IV for nested encryption\r\n // No need for base IV or counter - each encryption gets fresh random IV\r\n // This ensures maximum entropy and prevents IV reuse attacks\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to generate nested encryption key:', { errorType: error?.constructor?.name || 'Unknown' });\r\n throw error;\r\n }\r\n }\r\n\r\n async applyNestedEncryption(data) {\r\n if (!this.nestedEncryptionKey || !this.securityFeatures.hasNestedEncryption) {\r\n return data;\r\n }\r\n\r\n try {\r\n // Generate cryptographically secure IV with reuse prevention\r\n const uniqueIV = this._generateSecureIV(\r\n EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE, \r\n 'nestedEncryption'\r\n );\r\n \r\n // Encrypt data with nested layer\r\n const encrypted = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv: uniqueIV },\r\n this.nestedEncryptionKey,\r\n data\r\n );\r\n \r\n // Combine IV and encrypted data\r\n const result = new Uint8Array(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE + encrypted.byteLength);\r\n result.set(uniqueIV, 0);\r\n result.set(new Uint8Array(encrypted), EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE);\r\n \r\n this._secureLog('debug', '\u2705 Nested encryption applied with secure IV', {\r\n ivHash: await this._createSafeLogHash(uniqueIV, 'nestedEncryption'),\r\n ivSize: uniqueIV.length,\r\n dataSize: data.byteLength,\r\n encryptedSize: encrypted.byteLength\r\n });\r\n \r\n return result.buffer;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Nested encryption failed:', { \r\n errorType: error?.constructor?.name || 'Unknown',\r\n errorMessage: error?.message || 'Unknown error'\r\n });\r\n \r\n // If IV generation failed due to emergency mode, disable nested encryption\r\n if (error.message.includes('emergency mode')) {\r\n this.securityFeatures.hasNestedEncryption = false;\r\n this._secureLog('warn', '\u26A0\uFE0F Nested encryption disabled due to IV emergency mode');\r\n }\r\n \r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n async removeNestedEncryption(data) {\r\n if (!this.nestedEncryptionKey || !this.securityFeatures.hasNestedEncryption) {\r\n return data;\r\n }\r\n\r\n // Check that the data is actually encrypted with proper IV size\r\n if (!(data instanceof ArrayBuffer) || data.byteLength < EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE + 16) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Data not encrypted or too short for nested decryption (need IV + minimum encrypted data)');\r\n }\r\n return data;\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n const iv = dataArray.slice(0, EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE);\r\n const encryptedData = dataArray.slice(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE);\r\n \r\n // Check that there is data to decrypt\r\n if (encryptedData.length === 0) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD No encrypted data found');\r\n }\r\n return data;\r\n }\r\n \r\n // Decrypt nested layer\r\n const decrypted = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv: iv },\r\n this.nestedEncryptionKey,\r\n encryptedData\r\n );\r\n \r\n return decrypted;\r\n } catch (error) {\r\n // FIX: Better error handling\r\n if (error.name === 'OperationError') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Data not encrypted with nested encryption, skipping...');\r\n }\r\n } else {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Nested decryption failed:', { details: error.message });\r\n }\r\n }\r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n // ============================================\r\n // 2. PACKET PADDING\r\n // ============================================\r\n\r\n applyPacketPadding(data) {\r\n if (!this.securityFeatures.hasPacketPadding) {\r\n return data;\r\n }\r\n\r\n try {\r\n const originalSize = data.byteLength;\r\n let paddingSize;\r\n \r\n if (this.paddingConfig.useRandomPadding) {\r\n // Generate random padding size\r\n paddingSize = Math.floor(Math.random() * \r\n (this.paddingConfig.maxPadding - this.paddingConfig.minPadding + 1)) + \r\n this.paddingConfig.minPadding;\r\n } else {\r\n // Use fixed padding size\r\n paddingSize = this.paddingConfig.minPadding;\r\n }\r\n \r\n // Generate random padding data\r\n const padding = crypto.getRandomValues(new Uint8Array(paddingSize));\r\n \r\n // Create padded message\r\n const paddedData = new Uint8Array(originalSize + paddingSize + 4);\r\n \r\n // Add original size (4 bytes)\r\n const sizeView = new DataView(paddedData.buffer, 0, 4);\r\n sizeView.setUint32(0, originalSize, false);\r\n \r\n // Add original data\r\n paddedData.set(new Uint8Array(data), 4);\r\n \r\n // Add padding\r\n paddedData.set(padding, 4 + originalSize);\r\n \r\n return paddedData.buffer;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Packet padding failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n removePacketPadding(data) {\r\n if (!this.securityFeatures.hasPacketPadding) {\r\n return data;\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n \r\n // Check for minimum data length (4 bytes for size + minimum 1 byte of data)\r\n if (dataArray.length < 5) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Data too short for packet padding removal, skipping');\r\n }\r\n return data;\r\n }\r\n \r\n // Extract original size (first 4 bytes)\r\n const sizeView = new DataView(dataArray.buffer, 0, 4);\r\n const originalSize = sizeView.getUint32(0, false);\r\n \r\n // Checking the reasonableness of the size\r\n if (originalSize <= 0 || originalSize > dataArray.length - 4) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Invalid packet padding size, skipping removal');\r\n }\r\n return data;\r\n }\r\n \r\n // Extract original data\r\n const originalData = dataArray.slice(4, 4 + originalSize);\r\n \r\n return originalData.buffer;\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C Packet padding removal failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n return data; // Fallback to original data\r\n }\r\n }\r\n\r\n // ============================================\r\n // 3. FAKE TRAFFIC GENERATION\r\n // ============================================\r\n\r\n startFakeTrafficGeneration() {\r\n if (!this.fakeTrafficConfig.enabled || !this.isConnected()) {\r\n return;\r\n }\r\n\r\n // Prevent multiple fake traffic generators\r\n if (this.fakeTrafficTimer) {\r\n this._secureLog('warn', '\u26A0\uFE0F Fake traffic generation already running');\r\n return;\r\n }\r\n\r\n const sendFakeMessage = async () => {\r\n if (!this.isConnected()) {\r\n this.stopFakeTrafficGeneration();\r\n return;\r\n }\r\n\r\n try {\r\n const fakeMessage = this.generateFakeMessage();\r\n await this.sendFakeMessage(fakeMessage);\r\n \r\n // FIX: Increase intervals to reduce load\r\n const nextInterval = this.fakeTrafficConfig.randomDecoyIntervals ? \r\n this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minInterval, Math.min(this.fakeTrafficConfig.maxInterval, 60000)) : // Cap at 60 seconds\r\n this.fakeTrafficConfig.minInterval;\r\n \r\n // Minimum interval 15 seconds for stability\r\n const safeInterval = Math.max(nextInterval, EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MIN_INTERVAL);\r\n \r\n this.fakeTrafficTimer = setTimeout(sendFakeMessage, safeInterval);\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C Fake traffic generation failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n this.stopFakeTrafficGeneration();\r\n }\r\n };\r\n\r\n // Start fake traffic generation with longer initial delay\r\n // Use a reasonable range for initial delay (5-30 seconds)\r\n const minDelay = EnhancedSecureWebRTCManager.TIMEOUTS.DECOY_INITIAL_DELAY;\r\n const maxDelay = Math.min(this.fakeTrafficConfig.maxInterval, 30000); // Cap at 30 seconds\r\n const initialDelay = this.getUnbiasedRandomInRange(minDelay, maxDelay);\r\n this.fakeTrafficTimer = setTimeout(sendFakeMessage, initialDelay);\r\n }\r\n\r\n stopFakeTrafficGeneration() {\r\n if (this.fakeTrafficTimer) {\r\n clearTimeout(this.fakeTrafficTimer);\r\n this.fakeTrafficTimer = null;\r\n }\r\n }\r\n\r\n generateFakeMessage() {\r\n const patternIndex = this.getUnbiasedRandomInRange(0, this.fakeTrafficConfig.patterns.length - 1);\r\n const pattern = this.fakeTrafficConfig.patterns[patternIndex];\r\n \r\n const size = this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minSize, this.fakeTrafficConfig.maxSize);\r\n \r\n const fakeData = crypto.getRandomValues(new Uint8Array(size));\r\n \r\n return {\r\n type: EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE, \r\n pattern: pattern,\r\n data: Array.from(fakeData).map(b => b.toString(16).padStart(2, '0')).join(''),\r\n timestamp: Date.now(),\r\n size: size,\r\n isFakeTraffic: true, \r\n source: 'fake_traffic_generator',\r\n fakeId: crypto.getRandomValues(new Uint32Array(1))[0].toString(36) \r\n };\r\n }\r\n\r\n // ============================================\r\n // EMERGENCY SHUT-OFF OF ADVANCED FUNCTIONS\r\n // ============================================\r\n\r\n emergencyDisableAdvancedFeatures() {\r\n this._secureLog('error', '\uD83D\uDEA8 Emergency disabling advanced security features due to errors');\r\n \r\n // Disable problematic functions\r\n this.securityFeatures.hasNestedEncryption = false;\r\n this.securityFeatures.hasPacketReordering = false;\r\n this.securityFeatures.hasAntiFingerprinting = false;\r\n \r\n // Disable configurations\r\n this.reorderingConfig.enabled = false;\r\n this.antiFingerprintingConfig.enabled = false;\r\n \r\n // Clear the buffers\r\n this.packetBuffer.clear();\r\n \r\n // Stopping fake traffic\r\n this.emergencyDisableFakeTraffic();\r\n \r\n this._secureLog('info', '\u2705 Advanced features disabled, keeping basic encryption');\r\n \r\n // Check that advanced-features-disabled notification wasn't already sent\r\n if (!this.advancedFeaturesDisabledNotificationSent) {\r\n this.advancedFeaturesDisabledNotificationSent = true;\r\n if (this.onMessage) {\r\n this.deliverMessageToUI('\uD83D\uDEA8 Advanced security features temporarily disabled due to compatibility issues', 'system');\r\n }\r\n }\r\n }\r\n\r\n async sendFakeMessage(fakeMessage) {\r\n if (!this._validateConnection(false)) {\r\n return;\r\n }\r\n\r\n try {\r\n this._secureLog('debug', '\uD83C\uDFAD Sending fake message', {\r\n hasPattern: !!fakeMessage.pattern,\r\n sizeRange: fakeMessage.size > 100 ? 'large' : 'small'\r\n });\r\n \r\n const fakeData = JSON.stringify({\r\n ...fakeMessage,\r\n type: EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE, \r\n isFakeTraffic: true, \r\n timestamp: Date.now()\r\n });\r\n \r\n const fakeBuffer = new TextEncoder().encode(fakeData);\r\n const encryptedFake = await this.applySecurityLayers(fakeBuffer, true);\r\n this.dataChannel.send(encryptedFake);\r\n \r\n this._secureLog('debug', '\uD83C\uDFAD Fake message sent successfully', {\r\n pattern: fakeMessage.pattern\r\n });\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to send fake message', {\r\n error: error.message\r\n });\r\n }\r\n }\r\n\r\ncheckFakeTrafficStatus() {\r\n const status = {\r\n fakeTrafficEnabled: this.securityFeatures.hasFakeTraffic,\r\n fakeTrafficConfigEnabled: this.fakeTrafficConfig.enabled,\r\n timerActive: !!this.fakeTrafficTimer,\r\n patterns: this.fakeTrafficConfig.patterns,\r\n intervals: {\r\n min: this.fakeTrafficConfig.minInterval,\r\n max: this.fakeTrafficConfig.maxInterval\r\n }\r\n };\r\n \r\n if (this._debugMode) {\r\n this._secureLog('info', '\uD83C\uDFAD Fake Traffic Status', { status });\r\n }\r\n return status;\r\n }\r\nemergencyDisableFakeTraffic() {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\uD83D\uDEA8 Emergency disabling fake traffic');\r\n }\r\n \r\n this.securityFeatures.hasFakeTraffic = false;\r\n this.fakeTrafficConfig.enabled = false;\r\n this.stopFakeTrafficGeneration();\r\n \r\n if (this._debugMode) {\r\n this._secureLog('info', '\u2705 Fake traffic disabled');\r\n }\r\n \r\n // Check that fake-traffic-disabled notification wasn't already sent\r\n if (!this.fakeTrafficDisabledNotificationSent) {\r\n this.fakeTrafficDisabledNotificationSent = true;\r\n if (this.onMessage) {\r\n this.deliverMessageToUI('\uD83D\uDEA8 Fake traffic emergency disabled', 'system');\r\n }\r\n }\r\n }\r\n async _applySecurityLayersWithoutMutex(data, isFakeMessage = false) {\r\n try {\r\n let processedData = data;\r\n \r\n if (isFakeMessage) {\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n return processedData;\r\n }\r\n \r\n // Nested Encryption (if enabled)\r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey && processedData instanceof ArrayBuffer) {\r\n processedData = await this.applyNestedEncryption(processedData);\r\n }\r\n \r\n // Packet Reordering (if enabled)\r\n if (this.securityFeatures.hasPacketReordering && this.reorderingConfig?.enabled && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketReordering(processedData);\r\n }\r\n \r\n // Packet Padding (if enabled)\r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketPadding(processedData);\r\n }\r\n \r\n // Anti-Fingerprinting (if enabled)\r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyAntiFingerprinting(processedData);\r\n }\r\n \r\n // Final encryption (if keys are present)\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n \r\n return processedData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in applySecurityLayersWithoutMutex:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data; // Return original data on error\r\n }\r\n}\r\n // ============================================\r\n // 4. MESSAGE CHUNKING\r\n // ============================================\r\n\r\n async processChunkedMessage(chunkData) {\r\n try {\r\n if (!this.chunkingConfig.addChunkHeaders) {\r\n // No headers, treat as regular message\r\n return this.processMessage(chunkData);\r\n }\r\n\r\n const chunkArray = new Uint8Array(chunkData);\r\n if (chunkArray.length < 16) {\r\n // Too small to be a chunk with header\r\n return this.processMessage(chunkData);\r\n }\r\n\r\n // Extract chunk header\r\n const headerView = new DataView(chunkArray.buffer, 0, 16);\r\n const messageId = headerView.getUint32(0, false);\r\n const chunkIndex = headerView.getUint32(4, false);\r\n const totalChunks = headerView.getUint32(8, false);\r\n const chunkSize = headerView.getUint32(12, false);\r\n\r\n // Extract chunk data\r\n const chunk = chunkArray.slice(16, 16 + chunkSize);\r\n\r\n // Store chunk in buffer\r\n if (!this.chunkQueue[messageId]) {\r\n this.chunkQueue[messageId] = {\r\n chunks: new Array(totalChunks),\r\n received: 0,\r\n timestamp: Date.now()\r\n };\r\n }\r\n\r\n const messageBuffer = this.chunkQueue[messageId];\r\n messageBuffer.chunks[chunkIndex] = chunk;\r\n messageBuffer.received++;\r\n\r\n this._secureLog('debug', `\uD83D\uDCE6 Received chunk ${chunkIndex + 1}/${totalChunks} for message ${messageId}`);\r\n\r\n // Check if all chunks received\r\n if (messageBuffer.received === totalChunks) {\r\n // Combine all chunks\r\n const totalSize = messageBuffer.chunks.reduce((sum, chunk) => sum + chunk.length, 0);\r\n const combinedData = new Uint8Array(totalSize);\r\n \r\n let offset = 0;\r\n for (const chunk of messageBuffer.chunks) {\r\n combinedData.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n\r\n // Process complete message\r\n await this.processMessage(combinedData.buffer);\r\n \r\n // Clean up\r\n delete this.chunkQueue[messageId];\r\n \r\n this._secureLog('info', `\uD83D\uDCE6 Chunked message ${messageId} reassembled and processed`);\r\n }\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Chunked message processing failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n // ============================================\r\n // 5. DECOY CHANNELS\r\n // ============================================\r\n\r\n initializeDecoyChannels() {\r\n if (!this.decoyChannelConfig.enabled || !this.peerConnection) {\r\n return;\r\n }\r\n\r\n // Prevent multiple initializations\r\n if (this.decoyChannels.size > 0) {\r\n this._secureLog('warn', '\u26A0\uFE0F Decoy channels already initialized, skipping...');\r\n return;\r\n }\r\n\r\n try {\r\n const numDecoyChannels = Math.min(\r\n this.decoyChannelConfig.maxDecoyChannels,\r\n this.decoyChannelConfig.decoyChannelNames.length\r\n );\r\n\r\n for (let i = 0; i < numDecoyChannels; i++) {\r\n const channelName = this.decoyChannelConfig.decoyChannelNames[i];\r\n const decoyChannel = this.peerConnection.createDataChannel(channelName, {\r\n ordered: Math.random() > 0.5,\r\n maxRetransmits: Math.floor(Math.random() * 3)\r\n });\r\n\r\n this.setupDecoyChannel(decoyChannel, channelName);\r\n this.decoyChannels.set(channelName, decoyChannel);\r\n }\r\n\r\n if (this._debugMode) {\r\n this._secureLog('info', `\uD83C\uDFAD Initialized ${numDecoyChannels} decoy channels`);\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', '\u274C Failed to initialize decoy channels:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n }\r\n\r\n setupDecoyChannel(channel, channelName) {\r\n channel.onopen = () => {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Decoy channel \"${channelName}\" opened`);\r\n }\r\n this.startDecoyTraffic(channel, channelName);\r\n };\r\n\r\n channel.onmessage = (event) => {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Received decoy message on \"${channelName}\": ${event.data?.length || 'undefined'} bytes`);\r\n }\r\n };\r\n\r\n channel.onclose = () => {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Decoy channel \"${channelName}\" closed`);\r\n }\r\n this.stopDecoyTraffic(channelName);\r\n };\r\n\r\n channel.onerror = (error) => {\r\n if (this._debugMode) {\r\n this._secureLog('error', `\u274C Decoy channel \"${channelName}\" error`, { error: error.message });\r\n }\r\n };\r\n }\r\n\r\n startDecoyTraffic(channel, channelName) {\r\n const sendDecoyData = async () => {\r\n if (channel.readyState !== 'open') {\r\n return;\r\n }\r\n\r\n try {\r\n const decoyData = this.generateDecoyData(channelName);\r\n channel.send(decoyData);\r\n \r\n const interval = this.decoyChannelConfig.randomDecoyIntervals ?\r\n Math.random() * 15000 + 10000 : \r\n 20000; \r\n \r\n this.decoyTimers.set(channelName, setTimeout(() => sendDecoyData(), interval));\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('error', `\u274C Failed to send decoy data on \"${channelName}\"`, { error: error.message });\r\n }\r\n }\r\n };\r\n\r\n const initialDelay = Math.random() * 10000 + 5000; \r\n this.decoyTimers.set(channelName, setTimeout(() => sendDecoyData(), initialDelay));\r\n }\r\n\r\n stopDecoyTraffic(channelName) {\r\n const timer = this.decoyTimers.get(channelName);\r\n if (timer) {\r\n clearTimeout(timer);\r\n this.decoyTimers.delete(channelName);\r\n }\r\n }\r\n\r\n generateDecoyData(channelName) {\r\n const decoyTypes = {\r\n 'sync': () => JSON.stringify({\r\n type: 'sync',\r\n timestamp: Date.now(),\r\n sequence: Math.floor(Math.random() * 1000),\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(32)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'status': () => JSON.stringify({\r\n type: 'status',\r\n status: ['online', 'away', 'busy'][Math.floor(Math.random() * 3)],\r\n uptime: Math.floor(Math.random() * 3600),\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(16)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'heartbeat': () => JSON.stringify({\r\n type: 'heartbeat',\r\n timestamp: Date.now(),\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(24)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'metrics': () => JSON.stringify({\r\n type: 'metrics',\r\n cpu: Math.random() * 100,\r\n memory: Math.random() * 100,\r\n network: Math.random() * 1000,\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(20)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n }),\r\n 'debug': () => JSON.stringify({\r\n type: 'debug',\r\n level: ['info', 'warn', 'error'][Math.floor(Math.random() * 3)],\r\n message: 'Debug message',\r\n data: Array.from(crypto.getRandomValues(new Uint8Array(28)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('')\r\n })\r\n };\r\n\r\n return decoyTypes[channelName] ? decoyTypes[channelName]() : \r\n Array.from(crypto.getRandomValues(new Uint8Array(64)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n // ============================================\r\n // 6. PACKET REORDERING PROTECTION\r\n // ============================================\r\n\r\n addReorderingHeaders(data) {\r\n if (!this.reorderingConfig.enabled) {\r\n return data;\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n const headerSize = this.reorderingConfig.useTimestamps ? 12 : 8;\r\n const header = new ArrayBuffer(headerSize);\r\n const headerView = new DataView(header);\r\n\r\n // Add sequence number\r\n if (this.reorderingConfig.useSequenceNumbers) {\r\n headerView.setUint32(0, this.sequenceNumber++, false);\r\n }\r\n\r\n // Add timestamp\r\n if (this.reorderingConfig.useTimestamps) {\r\n headerView.setUint32(4, Date.now(), false);\r\n }\r\n\r\n // Add data size\r\n headerView.setUint32(this.reorderingConfig.useTimestamps ? 8 : 4, dataArray.length, false);\r\n\r\n // Combine header and data\r\n const result = new Uint8Array(headerSize + dataArray.length);\r\n result.set(new Uint8Array(header), 0);\r\n result.set(dataArray, headerSize);\r\n\r\n return result.buffer;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to add reordering headers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }\r\n\r\n async processReorderedPacket(data) {\r\n if (!this.reorderingConfig.enabled) {\r\n return this.processMessage(data);\r\n }\r\n\r\n try {\r\n const dataArray = new Uint8Array(data);\r\n const headerSize = this.reorderingConfig.useTimestamps ? 12 : 8;\r\n\r\n if (dataArray.length < headerSize) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Data too short for reordering headers, processing directly');\r\n }\r\n return this.processMessage(data);\r\n }\r\n\r\n const headerView = new DataView(dataArray.buffer, 0, headerSize);\r\n let sequence = 0;\r\n let timestamp = 0;\r\n let dataSize = 0;\r\n\r\n if (this.reorderingConfig.useSequenceNumbers) {\r\n sequence = headerView.getUint32(0, false);\r\n }\r\n\r\n if (this.reorderingConfig.useTimestamps) {\r\n timestamp = headerView.getUint32(4, false);\r\n }\r\n\r\n dataSize = headerView.getUint32(this.reorderingConfig.useTimestamps ? 8 : 4, false);\r\n\r\n if (dataSize > dataArray.length - headerSize || dataSize <= 0) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Invalid reordered packet data size, processing directly');\r\n }\r\n return this.processMessage(data);\r\n }\r\n\r\n const actualData = dataArray.slice(headerSize, headerSize + dataSize);\r\n\r\n try {\r\n const textData = new TextDecoder().decode(actualData);\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Reordered fake message: ${content.pattern || 'unknown'}`);\r\n }\r\n return; \r\n }\r\n } catch (e) {\r\n\r\n }\r\n\r\n this.packetBuffer.set(sequence, {\r\n data: actualData.buffer,\r\n timestamp: timestamp || Date.now()\r\n });\r\n\r\n await this.processOrderedPackets();\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to process reordered packet:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return this.processMessage(data);\r\n }\r\n}\r\n\r\n// ============================================\r\n// IMPROVED PROCESSORDEREDPACKETS with filtering\r\n// ============================================\r\n\r\nasync processOrderedPackets() {\r\n const now = Date.now();\r\n const timeout = this.reorderingConfig.reorderTimeout;\r\n\r\n while (true) {\r\n const nextSequence = this.lastProcessedSequence + 1;\r\n const packet = this.packetBuffer.get(nextSequence);\r\n\r\n if (!packet) {\r\n const oldestPacket = this.findOldestPacket();\r\n if (oldestPacket && (now - oldestPacket.timestamp) > timeout) {\r\n this._secureLog('warn', '\u26A0\uFE0F Packet ${oldestPacket.sequence} timed out, processing out of order');\r\n \r\n try {\r\n const textData = new TextDecoder().decode(oldestPacket.data);\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Timed out fake message: ${content.pattern || 'unknown'}`);\r\n this.packetBuffer.delete(oldestPacket.sequence);\r\n this.lastProcessedSequence = oldestPacket.sequence;\r\n continue; \r\n }\r\n } catch (e) {\r\n }\r\n \r\n await this.processMessage(oldestPacket.data);\r\n this.packetBuffer.delete(oldestPacket.sequence);\r\n this.lastProcessedSequence = oldestPacket.sequence;\r\n } else {\r\n break; \r\n }\r\n } else {\r\n try {\r\n const textData = new TextDecoder().decode(packet.data);\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Ordered fake message: ${content.pattern || 'unknown'}`);\r\n this.packetBuffer.delete(nextSequence);\r\n this.lastProcessedSequence = nextSequence;\r\n continue; \r\n }\r\n } catch (e) {\r\n }\r\n \r\n await this.processMessage(packet.data);\r\n this.packetBuffer.delete(nextSequence);\r\n this.lastProcessedSequence = nextSequence;\r\n }\r\n }\r\n\r\n this.cleanupOldPackets(now, timeout);\r\n}\r\n\r\n\r\n findOldestPacket() {\r\n let oldest = null;\r\n for (const [sequence, packet] of this.packetBuffer.entries()) {\r\n if (!oldest || packet.timestamp < oldest.timestamp) {\r\n oldest = { sequence, ...packet };\r\n }\r\n }\r\n return oldest;\r\n }\r\n\r\n cleanupOldPackets(now, timeout) {\r\n for (const [sequence, packet] of this.packetBuffer.entries()) {\r\n if ((now - packet.timestamp) > timeout) {\r\n this._secureLog('warn', '\u26A0\uFE0F \uD83D\uDDD1\uFE0F Removing timed out packet ${sequence}');\r\n this.packetBuffer.delete(sequence);\r\n }\r\n }\r\n }\r\n\r\n // ============================================\r\n // 7. ANTI-FINGERPRINTING\r\n // ============================================\r\n\r\n applyAntiFingerprinting(data) {\r\n if (!this.antiFingerprintingConfig.enabled) {\r\n return data;\r\n }\r\n\r\n try {\r\n let processedData = data;\r\n\r\n // Add random noise\r\n if (this.antiFingerprintingConfig.addNoise) {\r\n processedData = this.addNoise(processedData);\r\n }\r\n\r\n // Randomize sizes\r\n if (this.antiFingerprintingConfig.randomizeSizes) {\r\n processedData = this.randomizeSize(processedData);\r\n }\r\n\r\n // Mask patterns\r\n if (this.antiFingerprintingConfig.maskPatterns) {\r\n processedData = this.maskPatterns(processedData);\r\n }\r\n\r\n // Add random headers\r\n if (this.antiFingerprintingConfig.useRandomHeaders) {\r\n processedData = this.addRandomHeaders(processedData);\r\n }\r\n\r\n return processedData;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Anti-fingerprinting failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }\r\n\r\n addNoise(data) {\r\n const dataArray = new Uint8Array(data);\r\n const noiseSize = this.getUnbiasedRandomInRange(8, 40); // 8-40 bytes\r\n const noise = crypto.getRandomValues(new Uint8Array(noiseSize));\r\n \r\n const result = new Uint8Array(dataArray.length + noiseSize);\r\n result.set(dataArray, 0);\r\n result.set(noise, dataArray.length);\r\n \r\n return result.buffer;\r\n }\r\n\r\n randomizeSize(data) {\r\n const dataArray = new Uint8Array(data);\r\n const variation = this.fingerprintMask.sizeVariation;\r\n const targetSize = Math.floor(dataArray.length * variation);\r\n \r\n if (targetSize > dataArray.length) {\r\n // Add padding to increase size\r\n const padding = crypto.getRandomValues(new Uint8Array(targetSize - dataArray.length));\r\n const result = new Uint8Array(targetSize);\r\n result.set(dataArray, 0);\r\n result.set(padding, dataArray.length);\r\n return result.buffer;\r\n } else if (targetSize < dataArray.length) {\r\n // Truncate to decrease size\r\n return dataArray.slice(0, targetSize).buffer;\r\n }\r\n \r\n return data;\r\n }\r\n\r\n maskPatterns(data) {\r\n const dataArray = new Uint8Array(data);\r\n const result = new Uint8Array(dataArray.length);\r\n \r\n // Apply XOR with noise pattern\r\n for (let i = 0; i < dataArray.length; i++) {\r\n const noiseByte = this.fingerprintMask.noisePattern[i % this.fingerprintMask.noisePattern.length];\r\n result[i] = dataArray[i] ^ noiseByte;\r\n }\r\n \r\n return result.buffer;\r\n }\r\n\r\n addRandomHeaders(data) {\r\n const dataArray = new Uint8Array(data);\r\n const headerCount = this.getUnbiasedRandomInRange(1, 3); // 1-3 headers\r\n let totalHeaderSize = 0;\r\n \r\n // Calculate total header size\r\n for (let i = 0; i < headerCount; i++) {\r\n totalHeaderSize += 4 + this.getUnbiasedRandomInRange(0, 15) + 4; // size + data + checksum\r\n }\r\n \r\n const result = new Uint8Array(totalHeaderSize + dataArray.length);\r\n let offset = 0;\r\n \r\n // Add random headers\r\n for (let i = 0; i < headerCount; i++) {\r\n // Generate unbiased random index for header selection\r\n let headerIndex;\r\n do {\r\n headerIndex = crypto.getRandomValues(new Uint8Array(1))[0];\r\n } while (headerIndex >= 256 - (256 % this.fingerprintMask.headerVariations.length));\r\n \r\n const headerName = this.fingerprintMask.headerVariations[headerIndex % this.fingerprintMask.headerVariations.length];\r\n \r\n // Generate unbiased random size for header data (4-19 bytes)\r\n let headerSize;\r\n do {\r\n headerSize = crypto.getRandomValues(new Uint8Array(1))[0];\r\n } while (headerSize >= 256 - (256 % 16));\r\n \r\n const headerData = crypto.getRandomValues(new Uint8Array((headerSize % 16) + 4));\r\n \r\n // Header structure: [size:4][name:4][data:variable][checksum:4]\r\n const headerView = new DataView(result.buffer, offset);\r\n headerView.setUint32(0, headerData.length + 8, false); // Total header size\r\n headerView.setUint32(4, this.hashString(headerName), false); // Name hash\r\n \r\n result.set(headerData, offset + 8);\r\n \r\n // Add checksum\r\n const checksum = this.calculateChecksum(result.slice(offset, offset + 8 + headerData.length));\r\n const checksumView = new DataView(result.buffer, offset + 8 + headerData.length);\r\n checksumView.setUint32(0, checksum, false);\r\n \r\n offset += 8 + headerData.length + 4;\r\n }\r\n \r\n // Add original data\r\n result.set(dataArray, offset);\r\n \r\n return result.buffer;\r\n }\r\n\r\n hashString(str) {\r\n let hash = 0;\r\n for (let i = 0; i < str.length; i++) {\r\n const char = str.charCodeAt(i);\r\n hash = ((hash << 5) - hash) + char;\r\n hash = hash & hash;\r\n }\r\n return Math.abs(hash);\r\n }\r\n\r\n calculateChecksum(data) {\r\n let checksum = 0;\r\n for (let i = 0; i < data.length; i++) {\r\n checksum = (checksum + data[i]) & 0xFFFFFFFF;\r\n }\r\n return checksum;\r\n }\r\n\r\n // ============================================\r\n // ENHANCED MESSAGE SENDING AND RECEIVING\r\n // ============================================\r\n\r\n async removeSecurityLayers(data) {\r\n try {\r\n const status = this.getSecurityStatus();\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83D\uDD0D removeSecurityLayers (Stage ${status.stage})`, {\r\n dataType: typeof data,\r\n dataLength: data?.length || data?.byteLength || 0,\r\n activeFeatures: status.activeFeaturesCount\r\n });\r\n }\r\n\r\n if (!data) {\r\n this._secureLog('warn', '\u26A0\uFE0F Received empty data');\r\n return null;\r\n }\r\n\r\n let processedData = data;\r\n\r\n // IMPORTANT: Early check for fake messages\r\n if (typeof data === 'string') {\r\n try {\r\n const jsonData = JSON.parse(data);\r\n \r\n // PRIORITY ONE: Filtering out fake messages\r\n if (jsonData.type === 'fake') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', `\uD83C\uDFAD Fake message filtered out: ${jsonData.pattern} (size: ${jsonData.size})`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED'; \r\n }\r\n \r\n // System messages \u2014 do NOT return for re-processing\r\n if (jsonData.type && ['heartbeat', 'verification', 'verification_response', 'peer_disconnect', 'key_rotation_signal', 'key_rotation_ready', 'security_upgrade'].includes(jsonData.type)) {\r\n return 'SYSTEM_MESSAGE_FILTERED';\r\n }\r\n \r\n // File transfer messages \u2014 do NOT return for display\r\n if (jsonData.type && ['file_transfer_start', 'file_transfer_response', 'file_chunk', 'chunk_confirmation', 'file_transfer_complete', 'file_transfer_error'].includes(jsonData.type)) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCC1 File transfer message detected, blocking from chat', { type: jsonData.type });\r\n }\r\n return 'FILE_MESSAGE_FILTERED';\r\n }\r\n \r\n // Regular text messages - extract the actual message text\r\n if (jsonData.type === 'message') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, extracting text', { data: jsonData.data });\r\n }\r\n return jsonData.data; // Return the actual message text, not the JSON\r\n }\r\n \r\n // Enhanced messages\r\n if (jsonData.type === 'enhanced_message' && jsonData.data) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDD10 Enhanced message detected, decrypting...');\r\n }\r\n \r\n if (!this.encryptionKey || !this.macKey || !this.metadataKey) {\r\n this._secureLog('error', '\u274C Missing encryption keys');\r\n return null;\r\n }\r\n \r\n const decryptedResult = await window.EnhancedSecureCryptoUtils.decryptMessage(\r\n jsonData.data,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey\r\n );\r\n \r\n if (this._debugMode) {\r\n this._secureLog('debug', '\u2705 Enhanced message decrypted, extracting...');\r\n this._secureLog('debug', '\uD83D\uDD0D decryptedResult', {\r\n type: typeof decryptedResult,\r\n hasMessage: !!decryptedResult?.message,\r\n messageType: typeof decryptedResult?.message,\r\n messageLength: decryptedResult?.message?.length || 0,\r\n messageSample: decryptedResult?.message?.substring(0, 50) || 'no message'\r\n });\r\n }\r\n \r\n // CHECKING FOR FAKE MESSAGES AFTER DECRYPTION\r\n try {\r\n const decryptedContent = JSON.parse(decryptedResult.message);\r\n if (decryptedContent.type === 'fake' || decryptedContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Encrypted fake message: ${decryptedContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Decrypted content is not JSON, treating as plain text message');\r\n }\r\n }\r\n \r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCE4 Returning decrypted message', { message: decryptedResult.message?.substring(0, 50) });\r\n }\r\n return decryptedResult.message;\r\n }\r\n \r\n // Regular messages\r\n if (jsonData.type === 'message' && jsonData.data) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, extracting data');\r\n }\r\n return jsonData.data; // Return the actual message text\r\n }\r\n \r\n // If it's a regular message with type 'message', let it continue processing\r\n if (jsonData.type === 'message') {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, returning for display');\r\n }\r\n return data; // Return the original JSON string for processing\r\n }\r\n \r\n // If it's not a special type, return the original data for display\r\n if (!jsonData.type || (jsonData.type !== 'fake' && !['heartbeat', 'verification', 'verification_response', 'peer_disconnect', 'key_rotation_signal', 'key_rotation_ready', 'enhanced_message', 'security_upgrade', 'file_transfer_start', 'file_transfer_response', 'file_chunk', 'chunk_confirmation', 'file_transfer_complete', 'file_transfer_error'].includes(jsonData.type))) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular message detected, returning for display');\r\n }\r\n return data;\r\n }\r\n } catch (e) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDCC4 Not JSON, processing as raw data');\r\n }\r\n // If it's not JSON, it might be a plain text message - return as-is\r\n return data;\r\n }\r\n }\r\n\r\n // Standard Decryption\r\n if (this.encryptionKey && typeof processedData === 'string' && processedData.length > 50) {\r\n try {\r\n const base64Regex = /^[A-Za-z0-9+/=]+$/;\r\n if (base64Regex.test(processedData.trim())) {\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\uD83D\uDD13 Applying standard decryption...');\r\n }\r\n processedData = await window.EnhancedSecureCryptoUtils.decryptData(processedData, this.encryptionKey);\r\n if (this._debugMode) {\r\n this._secureLog('debug', '\u2705 Standard decryption successful');\r\n }\r\n \r\n // CHECKING FOR FAKE MESSAGES AFTER LEGACY DECRYPTION\r\n if (typeof processedData === 'string') {\r\n try {\r\n const legacyContent = JSON.parse(processedData);\r\n if (legacyContent.type === 'fake' || legacyContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Legacy fake message: ${legacyContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n \r\n }\r\n processedData = new TextEncoder().encode(processedData).buffer;\r\n }\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Standard decryption failed:', { details: error.message });\r\n }\r\n return data; \r\n }\r\n }\r\n\r\n if (this.securityFeatures.hasNestedEncryption && \r\n this.nestedEncryptionKey && \r\n processedData instanceof ArrayBuffer &&\r\n processedData.byteLength > 12) { \r\n \r\n try {\r\n processedData = await this.removeNestedEncryption(processedData);\r\n \r\n if (processedData instanceof ArrayBuffer) {\r\n try {\r\n const textData = new TextDecoder().decode(processedData);\r\n const nestedContent = JSON.parse(textData);\r\n if (nestedContent.type === 'fake' || nestedContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Nested fake message: ${nestedContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n \r\n }\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Nested decryption failed - skipping this layer:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n if (this.securityFeatures.hasPacketReordering && \r\n this.reorderingConfig.enabled && \r\n processedData instanceof ArrayBuffer) {\r\n try {\r\n const headerSize = this.reorderingConfig.useTimestamps ? 12 : 8;\r\n if (processedData.byteLength > headerSize) {\r\n return await this.processReorderedPacket(processedData);\r\n }\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Reordering processing failed - using direct processing:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n // Packet Padding Removal\r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removePacketPadding(processedData);\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Padding removal failed:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n // Anti-Fingerprinting Removal\r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removeAntiFingerprinting(processedData);\r\n } catch (error) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', '\u26A0\uFE0F Anti-fingerprinting removal failed:', { details: error.message });\r\n }\r\n }\r\n }\r\n\r\n // Final transformation\r\n if (processedData instanceof ArrayBuffer) {\r\n processedData = new TextDecoder().decode(processedData);\r\n }\r\n\r\n if (typeof processedData === 'string') {\r\n try {\r\n const finalContent = JSON.parse(processedData);\r\n if (finalContent.type === 'fake' || finalContent.isFakeTraffic === true) {\r\n if (this._debugMode) {\r\n this._secureLog('warn', `\uD83C\uDFAD BLOCKED: Final check fake message: ${finalContent.pattern || 'unknown'}`);\r\n }\r\n return 'FAKE_MESSAGE_FILTERED';\r\n }\r\n } catch (e) {\r\n }\r\n }\r\n\r\n return processedData;\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Critical error in removeSecurityLayers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n}\r\n\r\n removeAntiFingerprinting(data) {\r\n // This is a simplified version - in practice, you'd need to reverse all operations\r\n // For now, we'll just return the data as-is since the operations are mostly additive\r\n return data;\r\n }\r\n\r\n async applySecurityLayers(data, isFakeMessage = false) {\r\n try {\r\n let processedData = data;\r\n \r\n if (isFakeMessage) {\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n return processedData;\r\n }\r\n \r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey && processedData instanceof ArrayBuffer) {\r\n processedData = await this.applyNestedEncryption(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketReordering && this.reorderingConfig?.enabled && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketReordering(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketPadding(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyAntiFingerprinting(processedData);\r\n }\r\n \r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n \r\n return processedData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in applySecurityLayers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }\r\n\r\n async sendMessage(data) {\r\n // Comprehensive input validation\r\n const validation = this._validateInputData(data, 'sendMessage');\r\n if (!validation.isValid) {\r\n const errorMessage = `Input validation failed: ${validation.errors.join(', ')}`;\r\n this._secureLog('error', '\u274C Input validation failed in sendMessage', {\r\n errors: validation.errors,\r\n dataType: typeof data,\r\n dataLength: data?.length || data?.byteLength || 0\r\n });\r\n throw new Error(errorMessage);\r\n }\r\n\r\n // Rate limiting check\r\n if (!this._checkRateLimit('sendMessage')) {\r\n throw new Error('Rate limit exceeded for message sending');\r\n }\r\n\r\n // Enforce verification gate\r\n this._enforceVerificationGate('sendMessage');\r\n\r\n // Connection validation\r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n throw new Error('Data channel not ready');\r\n }\r\n\r\n try {\r\n this._secureLog('debug', 'sendMessage called', {\r\n hasDataChannel: !!this.dataChannel,\r\n dataChannelReady: this.dataChannel?.readyState === 'open',\r\n isInitiator: this.isInitiator,\r\n isVerified: this.isVerified,\r\n connectionReady: this.peerConnection?.connectionState === 'connected'\r\n });\r\n\r\n this._secureLog('debug', '\uD83D\uDD0D sendMessage DEBUG', {\r\n dataType: typeof validation.sanitizedData,\r\n isString: typeof validation.sanitizedData === 'string',\r\n isArrayBuffer: validation.sanitizedData instanceof ArrayBuffer,\r\n dataLength: validation.sanitizedData?.length || validation.sanitizedData?.byteLength || 0,\r\n });\r\n\r\n // CRITICAL SECURITY FIX: File messages MUST be encrypted\r\n // No more bypassing encryption for file_* messages\r\n if (typeof validation.sanitizedData === 'string') {\r\n try {\r\n const parsed = JSON.parse(validation.sanitizedData);\r\n \r\n if (parsed.type && parsed.type.startsWith('file_')) {\r\n this._secureLog('debug', '\uD83D\uDCC1 File message detected - applying full encryption with AAD', { type: parsed.type });\r\n \r\n // Create AAD for file message\r\n const aad = this._createFileMessageAAD(parsed.type, parsed.data);\r\n \r\n // Encrypt file message with AAD\r\n const encryptedData = await this._encryptFileMessage(validation.sanitizedData, aad);\r\n \r\n this.dataChannel.send(encryptedData);\r\n return true;\r\n }\r\n } catch (jsonError) {\r\n // Not JSON \u2014 continue normal handling\r\n }\r\n }\r\n\r\n // For regular text messages, send via secure path with AAD\r\n if (typeof validation.sanitizedData === 'string') {\r\n // Verify that _createMessageAAD method is available\r\n if (typeof this._createMessageAAD !== 'function') {\r\n throw new Error('_createMessageAAD method is not available. Manager may not be fully initialized.');\r\n }\r\n \r\n // Create AAD with sequence number for anti-replay protection\r\n const aad = this._createMessageAAD('message', { content: validation.sanitizedData });\r\n \r\n return await this.sendSecureMessage({ \r\n type: 'message', \r\n data: validation.sanitizedData, \r\n timestamp: Date.now(),\r\n aad: aad // Include AAD for sequence number validation\r\n });\r\n }\r\n\r\n // For binary data, apply security layers with a limited mutex\r\n this._secureLog('debug', '\uD83D\uDD10 Applying security layers to non-string data');\r\n const securedData = await this._applySecurityLayersWithLimitedMutex(validation.sanitizedData, false);\r\n this.dataChannel.send(securedData);\r\n \r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to send message', { \r\n error: error.message,\r\n errorType: error.constructor.name\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // FIX: New method applying security layers with limited mutex use\r\n async _applySecurityLayersWithLimitedMutex(data, isFakeMessage = false) {\r\n // Use mutex ONLY for cryptographic operations\r\n return this._withMutex('cryptoOperation', async (operationId) => {\r\n try {\r\n let processedData = data;\r\n \r\n if (isFakeMessage) {\r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n return processedData;\r\n }\r\n \r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey && processedData instanceof ArrayBuffer) {\r\n processedData = await this.applyNestedEncryption(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketReordering && this.reorderingConfig?.enabled && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketReordering(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyPacketPadding(processedData);\r\n }\r\n \r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n processedData = this.applyAntiFingerprinting(processedData);\r\n }\r\n \r\n if (this.encryptionKey && typeof processedData === 'string') {\r\n processedData = await window.EnhancedSecureCryptoUtils.encryptData(processedData, this.encryptionKey);\r\n }\r\n \r\n return processedData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in applySecurityLayers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return data;\r\n }\r\n }, 3000); // Short timeout for crypto operations\r\n}\r\n\r\n async sendSystemMessage(messageData) {\r\n // Block system messages without verification\r\n // Exception: Allow verification-related system messages\r\n const isVerificationMessage = messageData.type === 'verification_request' || \r\n messageData.type === 'verification_response' ||\r\n messageData.type === 'verification_required';\r\n \r\n if (!isVerificationMessage) {\r\n this._enforceVerificationGate('sendSystemMessage', false);\r\n }\r\n \r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n this._secureLog('warn', '\u26A0\uFE0F Cannot send system message - data channel not ready');\r\n return false;\r\n }\r\n\r\n try {\r\n const systemMessage = JSON.stringify({\r\n type: messageData.type,\r\n data: messageData,\r\n timestamp: Date.now()\r\n });\r\n\r\n this._secureLog('debug', '\uD83D\uDD27 Sending system message', { type: messageData.type });\r\n this.dataChannel.send(systemMessage);\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to send system message:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n\r\n // FIX 1: Simplified mutex system for message processing\r\nasync processMessage(data) {\r\n try {\r\n this._secureLog('debug', '\uFFFD\uFFFD Processing message', {\r\n dataType: typeof data,\r\n isArrayBuffer: data instanceof ArrayBuffer,\r\n hasData: !!(data?.length || data?.byteLength)\r\n });\r\n \r\n // CRITICAL: Early check for file messages WITHOUT mutex\r\n if (typeof data === 'string') {\r\n try {\r\n const parsed = JSON.parse(data);\r\n\r\n // ============================================\r\n // FILE MESSAGES \u2014 PRIORITY 1 (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n const fileMessageTypes = [\r\n 'file_transfer_start',\r\n 'file_transfer_response',\r\n 'file_chunk', \r\n 'chunk_confirmation',\r\n 'file_transfer_complete',\r\n 'file_transfer_error'\r\n ];\r\n\r\n // CRITICAL SECURITY FIX: Check for encrypted file messages first\r\n if (parsed.type === 'encrypted_file_message') {\r\n this._secureLog('debug', '\uD83D\uDCC1 Encrypted file message detected in processMessage');\r\n \r\n try {\r\n // Decrypt and validate file message\r\n const { decryptedData, aad } = await this._decryptFileMessage(data);\r\n \r\n // Parse decrypted data\r\n const decryptedParsed = JSON.parse(decryptedData);\r\n \r\n this._secureLog('debug', '\uD83D\uDCC1 File message decrypted successfully', { \r\n type: decryptedParsed.type,\r\n aadMessageType: aad.messageType \r\n });\r\n \r\n // Process decrypted file message\r\n if (this.fileTransferSystem && typeof this.fileTransferSystem.handleFileMessage === 'function') {\r\n await this.fileTransferSystem.handleFileMessage(decryptedParsed);\r\n return;\r\n }\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to decrypt file message', { error: error.message });\r\n return; // Drop invalid file message\r\n }\r\n }\r\n \r\n // Legacy unencrypted file messages - should not happen in secure mode\r\n if (parsed.type && fileMessageTypes.includes(parsed.type)) {\r\n this._secureLog('warn', '\u26A0\uFE0F Unencrypted file message detected - this should not happen in secure mode', { type: parsed.type });\r\n \r\n // Drop unencrypted file messages for security\r\n this._secureLog('error', '\u274C Dropping unencrypted file message for security', { type: parsed.type });\r\n return;\r\n }\r\n \r\n // ============================================\r\n // ENHANCED MESSAGES WITH AAD VALIDATION (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'enhanced_message') {\r\n this._secureLog('debug', '\uD83D\uDD10 Enhanced message detected in processMessage');\r\n \r\n try {\r\n // Decrypt enhanced message\r\n const decryptedData = await window.EnhancedSecureCryptoUtils.decryptMessage(\r\n parsed.data,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey\r\n );\r\n \r\n // Parse decrypted data\r\n const decryptedParsed = JSON.parse(decryptedData.data);\r\n \r\n // Validate AAD with sequence number\r\n if (decryptedData.metadata && decryptedData.metadata.sequenceNumber !== undefined) {\r\n if (!this._validateIncomingSequenceNumber(decryptedData.metadata.sequenceNumber, 'enhanced_message')) {\r\n this._secureLog('warn', '\u26A0\uFE0F Enhanced message sequence number validation failed - possible replay attack', {\r\n received: decryptedData.metadata.sequenceNumber,\r\n expected: this.expectedSequenceNumber\r\n });\r\n return; // Drop message with invalid sequence number\r\n }\r\n }\r\n \r\n // Process decrypted message\r\n if (decryptedParsed.type === 'message' && this.onMessage && decryptedParsed.data) {\r\n this.deliverMessageToUI(decryptedParsed.data, 'received');\r\n }\r\n \r\n return;\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to decrypt enhanced message', { error: error.message });\r\n return; // Drop invalid enhanced message\r\n }\r\n }\r\n \r\n // ============================================\r\n // REGULAR USER MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'message') {\r\n this._secureLog('debug', '\uD83D\uDCDD Regular user message detected in processMessage');\r\n if (this.onMessage && parsed.data) {\r\n this.deliverMessageToUI(parsed.data, 'received');\r\n }\r\n return;\r\n }\r\n \r\n // ============================================\r\n // SYSTEM MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type && ['heartbeat', 'verification', 'verification_response', 'verification_confirmed', 'verification_both_confirmed', 'peer_disconnect', 'security_upgrade'].includes(parsed.type)) {\r\n this.handleSystemMessage(parsed);\r\n return;\r\n }\r\n \r\n // ============================================\r\n // FAKE MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'fake') {\r\n this._secureLog('warn', '\uD83C\uDFAD Fake message blocked in processMessage', { pattern: parsed.pattern });\r\n return;\r\n }\r\n \r\n } catch (jsonError) {\r\n // Not JSON \u2014 treat as text WITHOUT mutex\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(data, 'received');\r\n }\r\n return;\r\n }\r\n }\r\n\r\n // ============================================\r\n // ENCRYPTED DATA PROCESSING (WITH MUTEX ONLY FOR CRYPTO)\r\n // ============================================\r\n \r\n // If here \u2014 apply security layers with limited mutex\r\n const originalData = await this._processEncryptedDataWithLimitedMutex(data);\r\n\r\n // Check processing result\r\n if (originalData === 'FAKE_MESSAGE_FILTERED' || \r\n originalData === 'FILE_MESSAGE_FILTERED' || \r\n originalData === 'SYSTEM_MESSAGE_FILTERED') {\r\n return;\r\n }\r\n \r\n if (!originalData) {\r\n this._secureLog('warn', '\u26A0\uFE0F No data returned from removeSecurityLayers');\r\n return;\r\n }\r\n\r\n // Handle result after removeSecurityLayers\r\n let messageText;\r\n \r\n if (typeof originalData === 'string') {\r\n try {\r\n const message = JSON.parse(originalData);\r\n \r\n // SECOND CHECK FOR FILE MESSAGES AFTER DECRYPTION\r\n if (message.type && fileMessageTypes.includes(message.type)) {\r\n this._secureLog('debug', '\uD83D\uDCC1 File message detected after decryption', { type: message.type });\r\n if (this.fileTransferSystem) {\r\n await this.fileTransferSystem.handleFileMessage(message);\r\n }\r\n return;\r\n }\r\n \r\n if (message.type && ['heartbeat', 'verification', 'verification_response', 'verification_confirmed', 'verification_both_confirmed', 'peer_disconnect', 'security_upgrade'].includes(message.type)) {\r\n this.handleSystemMessage(message);\r\n return;\r\n }\r\n \r\n if (message.type === 'fake') {\r\n this._secureLog('warn', `\uD83C\uDFAD Post-decryption fake message blocked: ${message.pattern}`);\r\n return;\r\n }\r\n \r\n // Regular messages\r\n if (message.type === 'message' && message.data) {\r\n messageText = message.data;\r\n } else {\r\n messageText = originalData;\r\n }\r\n } catch (e) {\r\n messageText = originalData;\r\n }\r\n } else if (originalData instanceof ArrayBuffer) {\r\n messageText = new TextDecoder().decode(originalData);\r\n } else if (originalData && typeof originalData === 'object' && originalData.message) {\r\n messageText = originalData.message;\r\n } else {\r\n this._secureLog('warn', '\u26A0\uFE0F Unexpected data type after processing:', { details: typeof originalData });\r\n return;\r\n }\r\n\r\n // Final check for fake and file messages\r\n if (messageText && messageText.trim().startsWith('{')) {\r\n try {\r\n const finalCheck = JSON.parse(messageText);\r\n if (finalCheck.type === 'fake') {\r\n this._secureLog('warn', `\uD83C\uDFAD Final fake message check blocked: ${finalCheck.pattern}`);\r\n return;\r\n }\r\n \r\n // Additional check for file and system messages\r\n const blockedTypes = [\r\n 'file_transfer_start', 'file_transfer_response', 'file_chunk', \r\n 'chunk_confirmation', 'file_transfer_complete', 'file_transfer_error',\r\n 'heartbeat', 'verification', 'verification_response', \r\n 'peer_disconnect', 'key_rotation_signal', 'key_rotation_ready', 'security_upgrade'\r\n ];\r\n \r\n if (finalCheck.type && blockedTypes.includes(finalCheck.type)) {\r\n this._secureLog('warn', `\uD83D\uDCC1 Final system/file message check blocked: ${finalCheck.type}`);\r\n return;\r\n }\r\n } catch (e) {\r\n // Not JSON \u2014 fine for plain text\r\n }\r\n }\r\n\r\n // Deliver message to the UI\r\n if (this.onMessage && messageText) {\r\n this._secureLog('debug', '\uD83D\uDCE4 Calling message handler with', { message: messageText.substring(0, 100) });\r\n this.deliverMessageToUI(messageText, 'received');\r\n }\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to process message:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n}\r\n\r\n // FIX: New method with limited mutex when processing encrypted data\r\n async _processEncryptedDataWithLimitedMutex(data) {\r\n // Use mutex ONLY for cryptographic operations\r\n return this._withMutex('cryptoOperation', async (operationId) => {\r\n this._secureLog('debug', '\uD83D\uDD10 Processing encrypted data with limited mutex', {\r\n operationId: operationId,\r\n dataType: typeof data\r\n });\r\n \r\n try {\r\n // Apply security layers\r\n const originalData = await this.removeSecurityLayers(data);\r\n return originalData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error processing encrypted data', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n return data; // Return original data on error\r\n }\r\n }, 2000); // Short timeout for crypto operations\r\n }\r\n\r\n notifySecurityUpdate() {\r\n try {\r\n this._secureLog('debug', '\uD83D\uDD12 Notifying about security level update', {\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n hasKeys: !!(this.encryptionKey && this.macKey && this.metadataKey),\r\n hasLastCalculation: !!this.lastSecurityCalculation\r\n });\r\n \r\n // Send an event about security level update\r\n document.dispatchEvent(new CustomEvent('security-level-updated', {\r\n detail: { \r\n timestamp: Date.now(), \r\n manager: 'webrtc',\r\n webrtcManager: this,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n hasKeys: !!(this.encryptionKey && this.macKey && this.metadataKey),\r\n lastCalculation: this.lastSecurityCalculation\r\n }\r\n }));\r\n \r\n // FIX: Force header refresh with correct manager\r\n setTimeout(() => {\r\n // Removed global callback - use event system instead\r\n // if (window.forceHeaderSecurityUpdate) {\r\n // window.forceHeaderSecurityUpdate(this);\r\n // }\r\n }, 100);\r\n \r\n // FIX: Direct update if there is a calculation\r\n if (this.lastSecurityCalculation) {\r\n document.dispatchEvent(new CustomEvent('real-security-calculated', {\r\n detail: {\r\n securityData: this.lastSecurityCalculation,\r\n webrtcManager: this,\r\n timestamp: Date.now()\r\n }\r\n }));\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error in notifySecurityUpdate', {\r\n error: error.message\r\n });\r\n }\r\n }\r\n\r\n handleSystemMessage(message) {\r\n this._secureLog('debug', '\uD83D\uDD27 Handling system message:', { type: message.type });\r\n \r\n switch (message.type) {\r\n case 'heartbeat':\r\n this.handleHeartbeat();\r\n break;\r\n case 'verification':\r\n this.handleVerificationRequest(message.data);\r\n break;\r\n case 'verification_response':\r\n this.handleVerificationResponse(message.data);\r\n break;\r\n case 'sas_code':\r\n this.handleSASCode(message.data);\r\n break;\r\n case 'verification_confirmed':\r\n this.handleVerificationConfirmed(message.data);\r\n break;\r\n case 'verification_both_confirmed':\r\n this.handleVerificationBothConfirmed(message.data);\r\n break;\r\n case 'peer_disconnect':\r\n this.handlePeerDisconnectNotification(message);\r\n break;\r\n case 'key_rotation_signal':\r\n this._secureLog('debug', '\uD83D\uDD04 Key rotation signal received (ignored for stability)');\r\n break;\r\n case 'key_rotation_ready':\r\n this._secureLog('debug', '\uD83D\uDD04 Key rotation ready signal received (ignored for stability)');\r\n break;\r\n case 'security_upgrade':\r\n this._secureLog('debug', '\uD83D\uDD12 Security upgrade notification received:', { type: message.type });\r\n // Security upgrade messages are handled internally, not displayed to user\r\n // to prevent duplicate system messages\r\n break;\r\n default:\r\n this._secureLog('debug', '\uD83D\uDD27 Unknown system message type:', { type: message.type });\r\n }\r\n }\r\n\r\n // ============================================\r\n // FUNCTION MANAGEMENT METHODS\r\n // ============================================\r\n\r\n // Method to enable Stage 2 functions\r\n enableStage2Security() {\r\n if (this.sessionConstraints?.hasPacketReordering) {\r\n this.securityFeatures.hasPacketReordering = true;\r\n this.reorderingConfig.enabled = true;\r\n }\r\n \r\n if (this.sessionConstraints?.hasAntiFingerprinting) {\r\n this.securityFeatures.hasAntiFingerprinting = true;\r\n this.antiFingerprintingConfig.enabled = true;\r\n // Enable full anti-fingerprinting features\r\n this.antiFingerprintingConfig.randomizeSizes = true;\r\n this.antiFingerprintingConfig.maskPatterns = true;\r\n this.antiFingerprintingConfig.useRandomHeaders = true;\r\n }\r\n \r\n this.notifySecurityUpgrade(2);\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, 500);\r\n }\r\n\r\n // Method to enable Stage 3 features (traffic obfuscation)\r\n enableStage3Security() {\r\n this._secureLog('info', '\uD83D\uDD12 Enabling Stage 3 features (traffic obfuscation)');\r\n \r\n if (this.sessionConstraints?.hasMessageChunking) {\r\n this.securityFeatures.hasMessageChunking = true;\r\n this.chunkingConfig.enabled = true;\r\n }\r\n \r\n if (this.sessionConstraints?.hasFakeTraffic) {\r\n this.securityFeatures.hasFakeTraffic = true;\r\n this.fakeTrafficConfig.enabled = true;\r\n this.startFakeTrafficGeneration();\r\n }\r\n \r\n this.notifySecurityUpgrade(3);\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, 500);\r\n }\r\n\r\n // Method for enabling Stage 4 functions (maximum safety)\r\n enableStage4Security() {\r\n this._secureLog('info', '\uD83D\uDD12 Enabling Stage 4 features (maximum safety)');\r\n \r\n if (this.sessionConstraints?.hasDecoyChannels && this.isConnected() && this.isVerified) {\r\n this.securityFeatures.hasDecoyChannels = true;\r\n this.decoyChannelConfig.enabled = true;\r\n \r\n try {\r\n this.initializeDecoyChannels();\r\n } catch (error) {\r\n this._secureLog('warn', '\u26A0\uFE0F Decoy channels initialization failed:', { details: error.message });\r\n this.securityFeatures.hasDecoyChannels = false;\r\n this.decoyChannelConfig.enabled = false;\r\n }\r\n }\r\n \r\n // Full anti-fingerprinting for maximum sessions\r\n if (this.sessionConstraints?.hasAntiFingerprinting) {\r\n this.antiFingerprintingConfig.randomizeSizes = true;\r\n this.antiFingerprintingConfig.maskPatterns = true;\r\n this.antiFingerprintingConfig.useRandomHeaders = false; \r\n }\r\n \r\n this.notifySecurityUpgrade(4);\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n }, 500);\r\n }\r\n\r\n forceSecurityUpdate() {\r\n setTimeout(() => {\r\n this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpdate();\r\n }, 100);\r\n }\r\n\r\n // Method for getting security status\r\n getSecurityStatus() {\r\n const activeFeatures = Object.entries(this.securityFeatures)\r\n .filter(([key, value]) => value === true)\r\n .map(([key]) => key);\r\n \r\n const stage = 4; // Maximum security stage\r\n \r\n return {\r\n stage: stage,\r\n securityLevel: 'maximum',\r\n activeFeatures: activeFeatures,\r\n totalFeatures: Object.keys(this.securityFeatures).length,\r\n activeFeaturesCount: activeFeatures.length,\r\n activeFeaturesNames: activeFeatures,\r\n sessionConstraints: this.sessionConstraints\r\n };\r\n }\r\n\r\n // Method to notify UI about security update\r\n notifySecurityUpgrade(stage) {\r\n const stageNames = {\r\n 1: 'Basic Enhanced',\r\n 2: 'Medium Security', \r\n 3: 'High Security',\r\n 4: 'Maximum Security'\r\n };\r\n \r\n const message = `\uD83D\uDD12 Security upgraded to Stage ${stage}: ${stageNames[stage]}`;\r\n \r\n // Avoid duplicate security-upgrade notifications\r\n if (!this.securityUpgradeNotificationSent || this.lastSecurityUpgradeStage !== stage) {\r\n this.securityUpgradeNotificationSent = true;\r\n this.lastSecurityUpgradeStage = stage;\r\n \r\n // Notify local UI via onMessage\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(message, 'system');\r\n }\r\n }\r\n\r\n // Send security upgrade notification to peer via WebRTC\r\n if (this.dataChannel && this.dataChannel.readyState === 'open') {\r\n try {\r\n const securityNotification = {\r\n type: 'security_upgrade',\r\n stage: stage,\r\n stageName: stageNames[stage],\r\n message: message,\r\n timestamp: Date.now()\r\n };\r\n \r\n this._secureLog('debug', '\uD83D\uDD12 Sending security upgrade notification to peer:', { type: securityNotification.type, stage: securityNotification.stage });\r\n this.dataChannel.send(JSON.stringify(securityNotification));\r\n } catch (error) {\r\n this._secureLog('warn', '\u26A0\uFE0F Failed to send security upgrade notification to peer:', { details: error.message });\r\n }\r\n }\r\n\r\n const status = this.getSecurityStatus();\r\n }\r\n\r\n async calculateAndReportSecurityLevel() {\r\n try {\r\n if (!window.EnhancedSecureCryptoUtils) {\r\n this._secureLog('warn', '\u26A0\uFE0F EnhancedSecureCryptoUtils not available for security calculation');\r\n return null;\r\n }\r\n\r\n if (!this.isConnected() || !this.isVerified || !this.encryptionKey || !this.macKey) {\r\n this._secureLog('debug', '\u26A0\uFE0F WebRTC not ready for security calculation', {\r\n connected: this.isConnected(),\r\n verified: this.isVerified,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey\r\n });\r\n return null;\r\n }\r\n\r\n this._secureLog('debug', '\uD83D\uDD0D Calculating real security level', {\r\n managerState: 'ready',\r\n hasAllKeys: !!(this.encryptionKey && this.macKey && this.metadataKey)\r\n });\r\n \r\n const securityData = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(this);\r\n \r\n this._secureLog('info', 'Real security level calculated', {\r\n hasSecurityLevel: !!securityData.level,\r\n scoreRange: securityData.score > 80 ? 'high' : securityData.score > 50 ? 'medium' : 'low',\r\n checksRatio: `${securityData.passedChecks}/${securityData.totalChecks}`,\r\n isRealCalculation: securityData.isRealData\r\n });\r\n\r\n this.lastSecurityCalculation = securityData;\r\n\r\n document.dispatchEvent(new CustomEvent('real-security-calculated', {\r\n detail: {\r\n securityData: securityData,\r\n webrtcManager: this,\r\n timestamp: Date.now(),\r\n source: 'calculateAndReportSecurityLevel'\r\n }\r\n }));\r\n\r\n if (securityData.isRealData && this.onMessage) {\r\n if (!this.securityCalculationNotificationSent || this.lastSecurityCalculationLevel !== securityData.level) {\r\n this.securityCalculationNotificationSent = true;\r\n this.lastSecurityCalculationLevel = securityData.level;\r\n \r\n const message = `Security Level: ${securityData.level} (${securityData.score}%) - ${securityData.passedChecks}/${securityData.totalChecks} checks passed`;\r\n this.deliverMessageToUI(message, 'system');\r\n }\r\n }\r\n \r\n return securityData;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to calculate real security level', {\r\n errorType: error.constructor.name\r\n });\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================\r\n // AUTOMATIC STEP-BY-STEP SWITCHING ON\r\n // ============================================\r\n\r\n // Method for automatic feature enablement with stability check\r\n async autoEnableSecurityFeatures() {\r\n this._secureLog('info', 'Starting graduated security activation - all features enabled');\r\n\r\n const checkStability = () => {\r\n const isStable = this.isConnected() && \r\n this.isVerified && \r\n this.connectionAttempts === 0 && \r\n this.messageQueue.length === 0 &&\r\n this.peerConnection?.connectionState === 'connected';\r\n return isStable;\r\n };\r\n \r\n await this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpgrade(1);\r\n \r\n // Enable all security stages progressively\r\n setTimeout(async () => {\r\n if (checkStability()) {\r\n this.enableStage2Security();\r\n await this.calculateAndReportSecurityLevel(); \r\n \r\n setTimeout(async () => {\r\n if (checkStability()) {\r\n this.enableStage3Security();\r\n await this.calculateAndReportSecurityLevel();\r\n \r\n setTimeout(async () => {\r\n if (checkStability()) {\r\n this.enableStage4Security();\r\n await this.calculateAndReportSecurityLevel();\r\n }\r\n }, 20000);\r\n }\r\n }, 15000);\r\n }\r\n }, 10000);\r\n }\r\n\r\n // ============================================\r\n // CONNECTION MANAGEMENT WITH ENHANCED SECURITY\r\n // ============================================\r\n\r\n async establishConnection() {\r\n try {\r\n // Initialize enhanced security features\r\n await this.initializeEnhancedSecurity();\r\n \r\n // Start fake traffic generation\r\n if (this.fakeTrafficConfig.enabled) {\r\n this.startFakeTrafficGeneration();\r\n }\r\n \r\n // Initialize decoy channels\r\n if (this.decoyChannelConfig.enabled) {\r\n this.initializeDecoyChannels();\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Failed to establish enhanced connection:', { errorType: error?.constructor?.name || 'Unknown' });\r\n // Do not close the connection on setup errors \u2014 just log and continue\r\n this.onStatusChange('disconnected');\r\n throw error;\r\n }\r\n }\r\n\r\n disconnect() {\r\n try {\r\n \r\n // Cleanup file transfer system\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n // Stop fake traffic generation\r\n this.stopFakeTrafficGeneration();\r\n \r\n // Stop decoy traffic\r\n for (const [channelName, timer] of this.decoyTimers.entries()) {\r\n clearTimeout(timer);\r\n }\r\n this.decoyTimers.clear();\r\n \r\n // Close decoy channels\r\n for (const [channelName, channel] of this.decoyChannels.entries()) {\r\n if (channel.readyState === 'open') {\r\n channel.close();\r\n }\r\n }\r\n this.decoyChannels.clear();\r\n \r\n // Clean up packet buffer\r\n this.packetBuffer.clear();\r\n \r\n // Clean up chunk queue\r\n this.chunkQueue = [];\r\n \r\n // Wipe ephemeral keys for PFS on disconnect\r\n this._wipeEphemeralKeys();\r\n \r\n // Hard wipe old keys for PFS\r\n this._hardWipeOldKeys();\r\n\r\n // Clear verification states\r\n this._clearVerificationStates();\r\n\r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error during enhanced disconnect:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n /**\r\n * Clear all verification states and data\r\n * Called when verification is rejected or connection is terminated\r\n */\r\n _clearVerificationStates() {\r\n try {\r\n \r\n // Clear verification states\r\n this.localVerificationConfirmed = false;\r\n this.remoteVerificationConfirmed = false;\r\n this.bothVerificationsConfirmed = false;\r\n this.isVerified = false;\r\n this.verificationCode = null;\r\n this.pendingSASCode = null;\r\n \r\n // Clear key fingerprint and connection data\r\n this.keyFingerprint = null;\r\n this.expectedDTLSFingerprint = null;\r\n this.connectionId = null;\r\n \r\n // Clear processed message IDs\r\n this.processedMessageIds.clear();\r\n \r\n // Reset notification flags\r\n this.verificationNotificationSent = false;\r\n this.verificationInitiationSent = false;\r\n \r\n } catch (error) {\r\n this._secureLog('error', '\u274C Error clearing verification states:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n // Start periodic cleanup for rate limiting and security\r\n startPeriodicCleanup() {\r\n // Cleanup moved to unified scheduler\r\n this._secureLog('info', '\uD83D\uDD27 Periodic cleanup moved to unified scheduler');\r\n }\r\n\r\n // Calculate current security level with real verification\r\n async calculateSecurityLevel() {\r\n return await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(this);\r\n }\r\n\r\n // PFS: Check if key rotation is needed\r\n shouldRotateKeys() {\r\n if (!this.isConnected() || !this.isVerified) {\r\n return false;\r\n }\r\n \r\n const now = Date.now();\r\n const timeSinceLastRotation = now - this.lastKeyRotation;\r\n \r\n // Rotate keys every 5 minutes or after 100 messages\r\n return timeSinceLastRotation > this.keyRotationInterval || \r\n this.messageCounter % 100 === 0;\r\n }\r\n\r\n // PFS: Rotate encryption keys for Perfect Forward Secrecy\r\n async rotateKeys() {\r\n return this._withMutex('keyOperation', async (operationId) => {\r\n this._secureLog('info', '\uD83D\uDD04 Starting key rotation with mutex', {\r\n operationId: operationId\r\n });\r\n \r\n // Validate state inside the critical section\r\n if (!this.isConnected() || !this.isVerified) {\r\n this._secureLog('warn', ' Key rotation aborted - connection not ready', {\r\n operationId: operationId,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified\r\n });\r\n return false;\r\n }\r\n \r\n // Ensure rotation is not already in progress\r\n if (this._keySystemState.isRotating) {\r\n this._secureLog('warn', ' Key rotation already in progress', {\r\n operationId: operationId\r\n });\r\n return false;\r\n }\r\n \r\n try {\r\n // Set rotation flag\r\n this._keySystemState.isRotating = true;\r\n this._keySystemState.lastOperation = 'rotation';\r\n this._keySystemState.lastOperationTime = Date.now();\r\n \r\n // Send rotation signal to peer\r\n const rotationSignal = {\r\n type: 'key_rotation_signal',\r\n newVersion: this.currentKeyVersion + 1,\r\n timestamp: Date.now(),\r\n operationId: operationId\r\n };\r\n \r\n if (this.dataChannel && this.dataChannel.readyState === 'open') {\r\n this.dataChannel.send(JSON.stringify(rotationSignal));\r\n } else {\r\n throw new Error('Data channel not ready for key rotation');\r\n }\r\n \r\n // Perform hard wipe of old keys for real PFS\r\n this._hardWipeOldKeys();\r\n \r\n // Wait for peer confirmation\r\n return new Promise((resolve) => {\r\n this.pendingRotation = {\r\n newVersion: this.currentKeyVersion + 1,\r\n operationId: operationId,\r\n resolve: resolve,\r\n timeout: setTimeout(() => {\r\n this._secureLog('error', ' Key rotation timeout', {\r\n operationId: operationId\r\n });\r\n this._keySystemState.isRotating = false;\r\n this.pendingRotation = null;\r\n resolve(false);\r\n }, 10000) // 10 seconds timeout\r\n };\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', ' Key rotation failed in critical section', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._keySystemState.isRotating = false;\r\n return false;\r\n }\r\n }, 10000); // 10 seconds timeout for the entire operation\r\n }\r\n\r\n // Real PFS - Clean up old keys with hard wipe\r\n cleanupOldKeys() {\r\n const now = Date.now();\r\n const maxKeyAge = EnhancedSecureWebRTCManager.LIMITS.MAX_KEY_AGE; // 15 minutes - keys older than this are deleted\r\n \r\n let wipedKeysCount = 0;\r\n \r\n for (const [version, keySet] of this.oldKeys.entries()) {\r\n if (now - keySet.timestamp > maxKeyAge) {\r\n // Hard wipe old keys before deletion\r\n if (keySet.encryptionKey) {\r\n this._secureWipeMemory(keySet.encryptionKey, 'pfs_cleanup_wipe');\r\n }\r\n if (keySet.macKey) {\r\n this._secureWipeMemory(keySet.macKey, 'pfs_cleanup_wipe');\r\n }\r\n if (keySet.metadataKey) {\r\n this._secureWipeMemory(keySet.metadataKey, 'pfs_cleanup_wipe');\r\n }\r\n \r\n // Clear references\r\n keySet.encryptionKey = null;\r\n keySet.macKey = null;\r\n keySet.metadataKey = null;\r\n keySet.keyFingerprint = null;\r\n \r\n this.oldKeys.delete(version);\r\n wipedKeysCount++;\r\n \r\n this._secureLog('info', '\uD83E\uDDF9 Old PFS keys hard wiped and cleaned up', {\r\n version: version,\r\n age: Math.round((now - keySet.timestamp) / 1000) + 's',\r\n timestamp: Date.now()\r\n });\r\n }\r\n }\r\n \r\n if (wipedKeysCount > 0) {\r\n this._secureLog('info', `PFS cleanup completed: ${wipedKeysCount} keys hard wiped`, {\r\n timestamp: Date.now()\r\n });\r\n }\r\n }\r\n\r\n // PFS: Get keys for specific version (for decryption)\r\n getKeysForVersion(version) {\r\n // First, we check the old keys (including version 0).\r\n const oldKeySet = this.oldKeys.get(version);\r\n if (oldKeySet && oldKeySet.encryptionKey && oldKeySet.macKey && oldKeySet.metadataKey) {\r\n return {\r\n encryptionKey: oldKeySet.encryptionKey,\r\n macKey: oldKeySet.macKey,\r\n metadataKey: oldKeySet.metadataKey\r\n };\r\n }\r\n \r\n // If this is the current version, return the current keys.\r\n if (version === this.currentKeyVersion) {\r\n if (this.encryptionKey && this.macKey && this.metadataKey) {\r\n return {\r\n encryptionKey: this.encryptionKey,\r\n macKey: this.macKey,\r\n metadataKey: this.metadataKey\r\n };\r\n }\r\n }\r\n \r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'No valid keys found for version', {\r\n requestedVersion: version,\r\n currentVersion: this.currentKeyVersion,\r\n availableVersions: Array.from(this.oldKeys.keys())\r\n });\r\n \r\n return null;\r\n }\r\n\r\n createPeerConnection() {\r\n const config = {\r\n iceServers: [\r\n { urls: 'stun:stun.l.google.com:19302' },\r\n { urls: 'stun:stun1.l.google.com:19302' },\r\n { urls: 'stun:stun2.l.google.com:19302' },\r\n { urls: 'stun:stun3.l.google.com:19302' },\r\n { urls: 'stun:stun4.l.google.com:19302' }\r\n ],\r\n iceCandidatePoolSize: 10,\r\n bundlePolicy: 'balanced'\r\n };\r\n\r\n this.peerConnection = new RTCPeerConnection(config);\r\n\r\n this.peerConnection.onconnectionstatechange = () => {\r\n const state = this.peerConnection.connectionState;\r\n \r\n if (state === 'connected' && !this.isVerified) {\r\n this.onStatusChange('verifying');\r\n } else if (state === 'connected' && this.isVerified) {\r\n this.onStatusChange('connected');\r\n } else if (state === 'disconnected' || state === 'closed') {\r\n // If this is an intentional disconnect, clear immediately.\r\n if (this.intentionalDisconnect) {\r\n this.onStatusChange('disconnected');\r\n setTimeout(() => this.disconnect(), 100);\r\n } else {\r\n this.onStatusChange('disconnected');\r\n // Clear verification states on unexpected disconnect\r\n this._clearVerificationStates();\r\n }\r\n } else if (state === 'failed') {\r\n // Do not auto-reconnect to avoid closing the session on errors\r\n this.onStatusChange('disconnected');\r\n\r\n } else {\r\n this.onStatusChange(state);\r\n }\r\n };\r\n\r\n this.peerConnection.ondatachannel = (event) => {\r\n \r\n // CRITICAL: Store the received data channel\r\n if (event.channel.label === 'securechat') {\r\n this.dataChannel = event.channel;\r\n this.setupDataChannel(event.channel);\r\n } else {\r\n // Handle additional channels (heartbeat, etc.)\r\n if (event.channel.label === 'heartbeat') {\r\n this.heartbeatChannel = event.channel;\r\n }\r\n }\r\n };\r\n }\r\n\r\n setupDataChannel(channel) {\r\n\r\n this.dataChannel = channel;\r\n\r\n this.dataChannel.onopen = async () => {\r\n // Configure backpressure for large transfers\r\n try {\r\n if (this.dataChannel && typeof this.dataChannel.bufferedAmountLowThreshold === 'number') {\r\n // 1 MB threshold for bufferedamountlow event\r\n this.dataChannel.bufferedAmountLowThreshold = 1024 * 1024;\r\n }\r\n } catch (e) {\r\n // ignore\r\n }\r\n \r\n try {\r\n await this.establishConnection();\r\n\r\n this.initializeFileTransfer();\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Error in establishConnection:', { errorType: error?.constructor?.name || 'Unknown' });\r\n // Continue despite errors\r\n }\r\n \r\n // CRITICAL: Send pending SAS code if available\r\n if (this.pendingSASCode && this.dataChannel && this.dataChannel.readyState === 'open') {\r\n try {\r\n const sasPayload = {\r\n type: 'sas_code',\r\n data: {\r\n code: this.pendingSASCode,\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS',\r\n securityLevel: 'MITM_PROTECTION_REQUIRED'\r\n }\r\n };\r\n this.dataChannel.send(JSON.stringify(sasPayload));\r\n this.pendingSASCode = null; // Clear after sending\r\n } catch (error) {\r\n }\r\n } else if (this.pendingSASCode) {\r\n }\r\n \r\n if (this.isVerified) {\r\n this.onStatusChange('connected');\r\n this.processMessageQueue();\r\n \r\n setTimeout(async () => {\r\n await this.calculateAndReportSecurityLevel();\r\n this.autoEnableSecurityFeatures();\r\n this.notifySecurityUpdate();\r\n }, 500);\r\n } else {\r\n this.onStatusChange('verifying');\r\n this.initiateVerification();\r\n }\r\n this.startHeartbeat();\r\n };\r\n\r\n this.dataChannel.onclose = () => {\r\n if (!this.intentionalDisconnect) {\r\n this.onStatusChange('disconnected');\r\n // Clear verification states on data channel close\r\n this._clearVerificationStates();\r\n \r\n if (!this.connectionClosedNotificationSent) {\r\n this.connectionClosedNotificationSent = true;\r\n this.deliverMessageToUI('\uD83D\uDD0C Enhanced secure connection closed. Check connection status.', 'system');\r\n }\r\n } else {\r\n this.onStatusChange('disconnected');\r\n // Clear verification states on intentional disconnect\r\n this._clearVerificationStates();\r\n \r\n if (!this.connectionClosedNotificationSent) {\r\n this.connectionClosedNotificationSent = true;\r\n this.deliverMessageToUI('\uD83D\uDD0C Enhanced secure connection closed', 'system');\r\n }\r\n }\r\n \r\n // Wipe ephemeral keys when session ends for PFS\r\n this._wipeEphemeralKeys();\r\n \r\n this.stopHeartbeat();\r\n this.isVerified = false;\r\n };\r\n\r\n // FIX 2: Remove mutex entirely from message processing path\r\n this.dataChannel.onmessage = async (event) => {\r\n try {\r\n\r\n // IMPORTANT: Process ALL messages WITHOUT mutex\r\n if (typeof event.data === 'string') {\r\n try {\r\n const parsed = JSON.parse(event.data);\r\n\r\n \r\n // ============================================\r\n // CRITICAL: FILE MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n const fileMessageTypes = [\r\n 'file_transfer_start',\r\n 'file_transfer_response', \r\n 'file_chunk',\r\n 'chunk_confirmation',\r\n 'file_transfer_complete',\r\n 'file_transfer_error'\r\n ];\r\n \r\n if (parsed.type && fileMessageTypes.includes(parsed.type)) {\r\n\r\n if (!this.fileTransferSystem) {\r\n try {\r\n if (this.isVerified && this.dataChannel && this.dataChannel.readyState === 'open') {\r\n this.initializeFileTransfer();\r\n\r\n let attempts = 0;\r\n const maxAttempts = 30;\r\n while (!this.fileTransferSystem && attempts < maxAttempts) {\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n attempts++;\r\n }\r\n }\r\n } catch (initError) {\r\n this._secureLog('error', 'Failed to initialize file transfer system for receiver:', { errorType: initError?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n\r\n if (this.fileTransferSystem) {\r\n await this.fileTransferSystem.handleFileMessage(parsed);\r\n return;\r\n }\r\n // Attempt lazy initialization on receiver side\r\n this._secureLog('warn', '\u26A0\uFE0F File transfer system not ready, attempting lazy init...');\r\n try {\r\n await this._ensureFileTransferReady();\r\n if (this.fileTransferSystem) {\r\n await this.fileTransferSystem.handleFileMessage(parsed);\r\n return;\r\n }\r\n } catch (e) {\r\n this._secureLog('error', 'Lazy init of file transfer failed:', { errorType: e?.message || e?.constructor?.name || 'Unknown' });\r\n }\r\n this._secureLog('error', 'No file transfer system available for:', { errorType: parsed.type?.constructor?.name || 'Unknown' });\r\n return; // IMPORTANT: Do not process further\r\n }\r\n \r\n // ============================================\r\n // SYSTEM MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type && ['heartbeat', 'verification', 'verification_response', 'verification_confirmed', 'verification_both_confirmed', 'sas_code', 'peer_disconnect', 'security_upgrade'].includes(parsed.type)) {\r\n this.handleSystemMessage(parsed);\r\n return;\r\n }\r\n \r\n // ============================================\r\n // REGULAR USER MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'message' && parsed.data) {\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(parsed.data, 'received');\r\n }\r\n return;\r\n }\r\n \r\n // ============================================\r\n // ENHANCED MESSAGES (WITHOUT MUTEX)\r\n // ============================================\r\n \r\n if (parsed.type === 'enhanced_message' && parsed.data) {\r\n await this._processEnhancedMessageWithoutMutex(parsed);\r\n return;\r\n }\r\n \r\n \r\n } catch (jsonError) {\r\n // Not JSON \u2014 treat as regular text message\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(event.data, 'received');\r\n }\r\n return;\r\n }\r\n } else if (event.data instanceof ArrayBuffer) {\r\n await this._processBinaryDataWithoutMutex(event.data);\r\n } else {\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to process message in onmessage:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n };\r\n }\r\n // FIX 4: New method for processing binary data WITHOUT mutex\r\n async _processBinaryDataWithoutMutex(data) {\r\n try {\r\n \r\n // Apply security layers WITHOUT mutex\r\n let processedData = data;\r\n \r\n // Nested Encryption Removal (if enabled)\r\n if (this.securityFeatures.hasNestedEncryption && \r\n this.nestedEncryptionKey && \r\n processedData instanceof ArrayBuffer &&\r\n processedData.byteLength > 12) {\r\n \r\n try {\r\n processedData = await this.removeNestedEncryption(processedData);\r\n } catch (error) {\r\n this._secureLog('warn', 'Nested decryption failed, continuing with original data');\r\n }\r\n }\r\n \r\n // Packet Padding Removal (if enabled)\r\n if (this.securityFeatures.hasPacketPadding && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removePacketPadding(processedData);\r\n } catch (error) {\r\n this._secureLog('warn', 'Packet padding removal failed, continuing with original data');\r\n }\r\n }\r\n \r\n // Anti-Fingerprinting Removal (if enabled)\r\n if (this.securityFeatures.hasAntiFingerprinting && processedData instanceof ArrayBuffer) {\r\n try {\r\n processedData = this.removeAntiFingerprinting(processedData);\r\n } catch (error) {\r\n this._secureLog('warn', 'Anti-fingerprinting removal failed, continuing with original data');\r\n }\r\n }\r\n \r\n // Convert to text\r\n if (processedData instanceof ArrayBuffer) {\r\n const textData = new TextDecoder().decode(processedData);\r\n \r\n // Check for fake messages\r\n try {\r\n const content = JSON.parse(textData);\r\n if (content.type === 'fake' || content.isFakeTraffic === true) {\r\n return;\r\n }\r\n } catch (e) {\r\n // Not JSON \u2014 fine for plain text\r\n }\r\n \r\n // Deliver message to user\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(textData, 'received');\r\n }\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Error processing binary data:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n // FIX 3: New method for processing enhanced messages WITHOUT mutex\r\n async _processEnhancedMessageWithoutMutex(parsedMessage) {\r\n try {\r\n \r\n if (!this.encryptionKey || !this.macKey || !this.metadataKey) {\r\n this._secureLog('error', 'Missing encryption keys for enhanced message');\r\n return;\r\n }\r\n \r\n const decryptedResult = await window.EnhancedSecureCryptoUtils.decryptMessage(\r\n parsedMessage.data,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey\r\n );\r\n \r\n if (decryptedResult && decryptedResult.message) {\r\n \r\n // Try parsing JSON and showing nested text if it's a chat message\r\n try {\r\n const decryptedContent = JSON.parse(decryptedResult.message);\r\n if (decryptedContent.type === 'fake' || decryptedContent.isFakeTraffic === true) {\r\n return;\r\n }\r\n if (decryptedContent && decryptedContent.type === 'message' && typeof decryptedContent.data === 'string') {\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(decryptedContent.data, 'received');\r\n }\r\n return;\r\n }\r\n } catch (e) {\r\n // Not JSON \u2014 fine for plain text\r\n }\r\n \r\n // Otherwise pass as-is\r\n if (this.onMessage) {\r\n this.deliverMessageToUI(decryptedResult.message, 'received');\r\n }\r\n } else {\r\n this._secureLog('warn', 'No message content in decrypted result');\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Error processing enhanced message:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n /**\r\n * Creates a unique ID for an operation\r\n */\r\n _generateOperationId() {\r\n return `op_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\r\n }\r\n\r\n /**\r\n * Atomic mutex acquisition with enhanced race condition protection\r\n */\r\n async _acquireMutex(mutexName, operationId, timeout = 5000) {\r\n // Build correct mutex property name\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Unknown mutex: ${mutexName}`, {\r\n mutexPropertyName: mutexPropertyName,\r\n availableMutexes: this._getAvailableMutexes(),\r\n operationId: operationId\r\n });\r\n throw new Error(`Unknown mutex: ${mutexName}. Available: ${this._getAvailableMutexes().join(', ')}`);\r\n }\r\n \r\n // Validate operation ID\r\n if (!operationId || typeof operationId !== 'string') {\r\n throw new Error('Invalid operation ID for mutex acquisition');\r\n }\r\n \r\n return new Promise((resolve, reject) => {\r\n // Atomic lock attempt with immediate state check\r\n const attemptLock = () => {\r\n // Check if mutex is already locked by this operation\r\n if (mutex.lockId === operationId) {\r\n this._secureLog('warn', `Mutex '${mutexName}' already locked by same operation`, {\r\n operationId: operationId\r\n });\r\n resolve();\r\n return;\r\n }\r\n \r\n // Atomic check and lock operation\r\n if (!mutex.locked) {\r\n // Set lock state atomically\r\n mutex.locked = true;\r\n mutex.lockId = operationId;\r\n mutex.lockTime = Date.now();\r\n \r\n this._secureLog('debug', `Mutex '${mutexName}' acquired atomically`, {\r\n operationId: operationId,\r\n lockTime: mutex.lockTime\r\n });\r\n \r\n // Set timeout for automatic release with enhanced validation\r\n mutex.lockTimeout = setTimeout(() => {\r\n // Enhanced timeout handling with state validation\r\n this._handleMutexTimeout(mutexName, operationId, timeout);\r\n }, timeout);\r\n \r\n resolve();\r\n } else {\r\n // Add to queue with timeout\r\n const queueItem = { \r\n resolve, \r\n reject, \r\n operationId,\r\n timestamp: Date.now(),\r\n timeout: setTimeout(() => {\r\n // Remove from queue on timeout\r\n const index = mutex.queue.findIndex(item => item.operationId === operationId);\r\n if (index !== -1) {\r\n mutex.queue.splice(index, 1);\r\n reject(new Error(`Mutex acquisition timeout for '${mutexName}'`));\r\n }\r\n }, timeout)\r\n };\r\n \r\n mutex.queue.push(queueItem);\r\n \r\n this._secureLog('debug', `Operation queued for mutex '${mutexName}'`, {\r\n operationId: operationId,\r\n queueLength: mutex.queue.length,\r\n currentLockId: mutex.lockId\r\n });\r\n }\r\n };\r\n \r\n // Execute lock attempt immediately\r\n attemptLock();\r\n });\r\n }\r\n\r\n /**\r\n * Enhanced mutex release with strict validation and error handling\r\n */\r\n _releaseMutex(mutexName, operationId) {\r\n // Validate input parameters\r\n if (!mutexName || typeof mutexName !== 'string') {\r\n throw new Error('Invalid mutex name provided for release');\r\n }\r\n \r\n if (!operationId || typeof operationId !== 'string') {\r\n throw new Error('Invalid operation ID provided for mutex release');\r\n }\r\n \r\n // Build correct mutex property name\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Unknown mutex for release: ${mutexName}`, {\r\n mutexPropertyName: mutexPropertyName,\r\n availableMutexes: this._getAvailableMutexes(),\r\n operationId: operationId\r\n });\r\n throw new Error(`Unknown mutex for release: ${mutexName}`);\r\n }\r\n \r\n // Strict validation of lock ownership\r\n if (mutex.lockId !== operationId) {\r\n this._secureLog('error', `CRITICAL: Invalid mutex release attempt - potential race condition`, {\r\n mutexName: mutexName,\r\n expectedLockId: mutex.lockId,\r\n providedOperationId: operationId,\r\n mutexState: {\r\n locked: mutex.locked,\r\n lockTime: mutex.lockTime,\r\n queueLength: mutex.queue.length\r\n }\r\n });\r\n \r\n // Throw error instead of silent failure\r\n throw new Error(`Invalid mutex release attempt for '${mutexName}': expected '${mutex.lockId}', got '${operationId}'`);\r\n }\r\n \r\n // Validate mutex is actually locked\r\n if (!mutex.locked) {\r\n this._secureLog('error', `CRITICAL: Attempting to release unlocked mutex`, {\r\n mutexName: mutexName,\r\n operationId: operationId,\r\n mutexState: {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n lockTime: mutex.lockTime\r\n }\r\n });\r\n throw new Error(`Attempting to release unlocked mutex: ${mutexName}`);\r\n }\r\n \r\n try {\r\n // Clear timeout first\r\n if (mutex.lockTimeout) {\r\n clearTimeout(mutex.lockTimeout);\r\n mutex.lockTimeout = null;\r\n }\r\n \r\n // Calculate lock duration for monitoring\r\n const lockDuration = mutex.lockTime ? Date.now() - mutex.lockTime : 0;\r\n \r\n // Atomic release with state validation\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTime = null;\r\n \r\n this._secureLog('debug', `Mutex released successfully: ${mutexName}`, {\r\n operationId: operationId,\r\n lockDuration: lockDuration,\r\n queueLength: mutex.queue.length\r\n });\r\n \r\n // Process next in queue with enhanced error handling\r\n this._processNextInQueue(mutexName);\r\n \r\n } catch (error) {\r\n // If queue processing fails, ensure mutex is still released\r\n this._secureLog('error', `Error during mutex release queue processing`, {\r\n mutexName: mutexName,\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Ensure mutex is released even if queue processing fails\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTime = null;\r\n mutex.lockTimeout = null;\r\n \r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Enhanced queue processing with comprehensive error handling\r\n */\r\n _processNextInQueue(mutexName) {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Mutex not found for queue processing: ${mutexName}`);\r\n return;\r\n }\r\n \r\n if (mutex.queue.length === 0) {\r\n return;\r\n }\r\n \r\n // Validate mutex state before processing queue\r\n if (mutex.locked) {\r\n this._secureLog('warn', `Mutex '${mutexName}' is still locked, skipping queue processing`, {\r\n lockId: mutex.lockId,\r\n queueLength: mutex.queue.length\r\n });\r\n return;\r\n }\r\n \r\n // Get next item from queue atomically with validation\r\n const nextItem = mutex.queue.shift();\r\n \r\n if (!nextItem) {\r\n this._secureLog('warn', `Empty queue item for mutex '${mutexName}'`);\r\n return;\r\n }\r\n \r\n // Validate queue item structure\r\n if (!nextItem.operationId || !nextItem.resolve || !nextItem.reject) {\r\n this._secureLog('error', `Invalid queue item structure for mutex '${mutexName}'`, {\r\n hasOperationId: !!nextItem.operationId,\r\n hasResolve: !!nextItem.resolve,\r\n hasReject: !!nextItem.reject\r\n });\r\n return;\r\n }\r\n \r\n try {\r\n // Clear timeout for this item\r\n if (nextItem.timeout) {\r\n clearTimeout(nextItem.timeout);\r\n }\r\n \r\n // Attempt to acquire lock for next item\r\n this._secureLog('debug', `Processing next operation in queue for mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n queueRemaining: mutex.queue.length,\r\n timestamp: Date.now()\r\n });\r\n \r\n // Retry lock acquisition for queued operation with enhanced error handling\r\n setTimeout(async () => {\r\n try {\r\n await this._acquireMutex(mutexName, nextItem.operationId, 5000);\r\n \r\n this._secureLog('debug', `Queued operation acquired mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n acquisitionTime: Date.now()\r\n });\r\n \r\n nextItem.resolve();\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Queued operation failed to acquire mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n timestamp: Date.now()\r\n });\r\n \r\n // Reject with detailed error information\r\n nextItem.reject(new Error(`Queue processing failed for '${mutexName}': ${error.message}`));\r\n \r\n // Continue processing queue even if one item fails\r\n setTimeout(() => {\r\n this._processNextInQueue(mutexName);\r\n }, 50);\r\n }\r\n }, 10); // Small delay to prevent immediate re-acquisition\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Critical error during queue processing for mutex '${mutexName}'`, {\r\n operationId: nextItem.operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Reject the operation and continue processing\r\n try {\r\n nextItem.reject(new Error(`Queue processing critical error: ${error.message}`));\r\n } catch (rejectError) {\r\n this._secureLog('error', `Failed to reject queue item`, {\r\n originalError: error.message,\r\n rejectError: rejectError.message\r\n });\r\n }\r\n \r\n // Continue processing remaining queue items\r\n setTimeout(() => {\r\n this._processNextInQueue(mutexName);\r\n }, 100);\r\n }\r\n }\r\n\r\n _getAvailableMutexes() {\r\n const mutexes = [];\r\n const propertyNames = Object.getOwnPropertyNames(this);\r\n \r\n for (const prop of propertyNames) {\r\n if (prop.endsWith('Mutex') && prop.startsWith('_')) {\r\n // Extract mutex name without prefix/suffix\r\n const mutexName = prop.slice(1, -5); // Remove '_' prefix and 'Mutex' suffix\r\n mutexes.push(mutexName);\r\n }\r\n }\r\n \r\n return mutexes;\r\n }\r\n\r\n /**\r\n * Enhanced mutex execution with atomic operations\r\n */\r\n async _withMutex(mutexName, operation, timeout = 5000) {\r\n const operationId = this._generateOperationId();\r\n \r\n // Validate mutex system before operation\r\n if (!this._validateMutexSystem()) {\r\n this._secureLog('error', 'Mutex system not properly initialized', {\r\n operationId: operationId,\r\n mutexName: mutexName\r\n });\r\n throw new Error('Mutex system not properly initialized. Call _initializeMutexSystem() first.');\r\n }\r\n \r\n // Get mutex reference with validation\r\n const mutex = this[`_${mutexName}Mutex`];\r\n if (!mutex) {\r\n throw new Error(`Mutex '${mutexName}' not found`);\r\n }\r\n \r\n let mutexAcquired = false;\r\n \r\n try {\r\n // Atomic mutex acquisition with timeout\r\n await this._acquireMutex(mutexName, operationId, timeout);\r\n mutexAcquired = true;\r\n \r\n // Increment operation counter atomically\r\n const counterKey = `${mutexName}Operations`;\r\n if (this._operationCounters && this._operationCounters[counterKey] !== undefined) {\r\n this._operationCounters[counterKey]++;\r\n }\r\n \r\n // Execute operation with enhanced error handling\r\n const result = await operation(operationId);\r\n \r\n // Validate result before returning\r\n if (result === undefined && operation.name !== 'cleanup') {\r\n this._secureLog('warn', 'Mutex operation returned undefined result', {\r\n operationId: operationId,\r\n mutexName: mutexName,\r\n operationName: operation.name\r\n });\r\n }\r\n \r\n return result;\r\n \r\n } catch (error) {\r\n // Enhanced error logging with context\r\n this._secureLog('error', 'Error in mutex operation', {\r\n operationId: operationId,\r\n mutexName: mutexName,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n mutexAcquired: mutexAcquired,\r\n mutexState: mutex ? {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n queueLength: mutex.queue.length\r\n } : 'null'\r\n });\r\n \r\n // If this is a key operation error, trigger emergency recovery\r\n if (mutexName === 'keyOperation') {\r\n this._handleKeyOperationError(error, operationId);\r\n }\r\n \r\n // Trigger emergency unlock for critical mutex errors\r\n if (error.message.includes('timeout') || error.message.includes('race condition')) {\r\n this._emergencyUnlockAllMutexes('errorHandler');\r\n }\r\n \r\n throw error;\r\n } finally {\r\n // Always release mutex in finally block with validation\r\n if (mutexAcquired) {\r\n try {\r\n await this._releaseMutex(mutexName, operationId);\r\n \r\n // Verify mutex was properly released\r\n if (mutex.locked && mutex.lockId === operationId) {\r\n this._secureLog('error', 'Mutex release verification failed', {\r\n operationId: operationId,\r\n mutexName: mutexName\r\n });\r\n // Force release as fallback\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n }\r\n \r\n } catch (releaseError) {\r\n this._secureLog('error', 'Error releasing mutex in finally block', {\r\n operationId: operationId,\r\n mutexName: mutexName,\r\n releaseErrorType: releaseError.constructor.name,\r\n releaseErrorMessage: releaseError.message\r\n });\r\n \r\n // Force release on error\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n }\r\n }\r\n }\r\n }\r\n\r\n _validateMutexSystem() {\r\n const requiredMutexes = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n \r\n for (const mutexName of requiredMutexes) {\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (!mutex || typeof mutex !== 'object') {\r\n this._secureLog('error', `Missing or invalid mutex: ${mutexName}`, {\r\n mutexPropertyName: mutexPropertyName,\r\n mutexType: typeof mutex\r\n });\r\n return false;\r\n }\r\n \r\n // Validate mutex structure\r\n const requiredProps = ['locked', 'queue', 'lockId', 'lockTimeout'];\r\n for (const prop of requiredProps) {\r\n if (!(prop in mutex)) {\r\n this._secureLog('error', `Mutex ${mutexName} missing property: ${prop}`);\r\n return false;\r\n }\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n\r\n /**\r\n * Enhanced emergency recovery of the mutex system\r\n */\r\n _emergencyRecoverMutexSystem() {\r\n this._secureLog('warn', 'Emergency mutex system recovery initiated');\r\n \r\n try {\r\n // Emergency unlock all mutexes first\r\n this._emergencyUnlockAllMutexes('emergencyRecovery');\r\n \r\n // Force re-initialize the system\r\n this._initializeMutexSystem();\r\n \r\n // Validate recovery success\r\n if (!this._validateMutexSystem()) {\r\n throw new Error('Mutex system validation failed after recovery');\r\n }\r\n \r\n this._secureLog('info', 'Mutex system recovered successfully with validation');\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to recover mutex system', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Last resort - force re-initialization\r\n try {\r\n this._initializeMutexSystem();\r\n this._secureLog('warn', 'Forced mutex system re-initialization completed');\r\n return true;\r\n } catch (reinitError) {\r\n this._secureLog('error', 'CRITICAL: Forced re-initialization also failed', {\r\n originalError: error.message,\r\n reinitError: reinitError.message\r\n });\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Atomic key generation with race condition protection\r\n */\r\n async _generateEncryptionKeys() {\r\n return this._withMutex('keyOperation', async (operationId) => {\r\n this._secureLog('info', 'Generating encryption keys with atomic mutex', {\r\n operationId: operationId\r\n });\r\n \r\n // Atomic state check and update using mutex lock\r\n const currentState = this._keySystemState;\r\n \r\n // Atomic check - if already initializing, wait or fail\r\n if (currentState.isInitializing) {\r\n this._secureLog('warn', 'Key generation already in progress, waiting for completion', {\r\n operationId: operationId,\r\n lastOperation: currentState.lastOperation,\r\n lastOperationTime: currentState.lastOperationTime\r\n });\r\n \r\n // Wait for existing operation to complete\r\n let waitAttempts = 0;\r\n const maxWaitAttempts = 50; // 5 seconds max wait\r\n \r\n while (currentState.isInitializing && waitAttempts < maxWaitAttempts) {\r\n await new Promise(resolve => setTimeout(resolve, 100));\r\n waitAttempts++;\r\n }\r\n \r\n if (currentState.isInitializing) {\r\n throw new Error('Key generation timeout - operation still in progress after 5 seconds');\r\n }\r\n }\r\n \r\n // Atomic state update within mutex protection\r\n try {\r\n // Set state atomically within mutex\r\n currentState.isInitializing = true;\r\n currentState.lastOperation = 'generation';\r\n currentState.lastOperationTime = Date.now();\r\n currentState.operationId = operationId;\r\n \r\n this._secureLog('debug', 'Atomic key generation state set', {\r\n operationId: operationId,\r\n timestamp: currentState.lastOperationTime\r\n });\r\n \r\n // Generate keys with individual error handling\r\n let ecdhKeyPair = null;\r\n let ecdsaKeyPair = null;\r\n \r\n // Generate ephemeral ECDH keys for PFS\r\n try {\r\n ecdhKeyPair = await this._generateEphemeralECDHKeys();\r\n \r\n // Validate ECDH keys immediately\r\n if (!ecdhKeyPair || !ecdhKeyPair.privateKey || !ecdhKeyPair.publicKey) {\r\n throw new Error('Ephemeral ECDH key pair validation failed');\r\n }\r\n \r\n // Constant-time validation for key types\r\n if (!this._validateKeyPairConstantTime(ecdhKeyPair)) {\r\n throw new Error('Ephemeral ECDH keys are not valid CryptoKey instances');\r\n }\r\n \r\n this._secureLog('debug', 'Ephemeral ECDH keys generated and validated for PFS', {\r\n operationId: operationId,\r\n privateKeyHash: await this._createSafeLogHash(ecdhKeyPair.privateKey, 'ecdh_private'),\r\n publicKeyHash: await this._createSafeLogHash(ecdhKeyPair.publicKey, 'ecdh_public'),\r\n privateKeyType: ecdhKeyPair.privateKey.algorithm?.name,\r\n publicKeyType: ecdhKeyPair.publicKey.algorithm?.name,\r\n isEphemeral: true\r\n });\r\n \r\n } catch (ecdhError) {\r\n this._secureLog('error', 'Ephemeral ECDH key generation failed', {\r\n operationId: operationId,\r\n errorType: ecdhError.constructor.name\r\n });\r\n this._throwSecureError(ecdhError, 'ephemeral_ecdh_key_generation');\r\n }\r\n \r\n // Generate ECDSA keys with retry mechanism\r\n try {\r\n ecdsaKeyPair = await window.EnhancedSecureCryptoUtils.generateECDSAKeyPair();\r\n \r\n // Validate ECDSA keys immediately\r\n if (!ecdsaKeyPair || !ecdsaKeyPair.privateKey || !ecdsaKeyPair.publicKey) {\r\n throw new Error('ECDSA key pair validation failed');\r\n }\r\n \r\n // Constant-time validation for key types\r\n if (!this._validateKeyPairConstantTime(ecdsaKeyPair)) {\r\n throw new Error('ECDSA keys are not valid CryptoKey instances');\r\n }\r\n \r\n this._secureLog('debug', 'ECDSA keys generated and validated', {\r\n operationId: operationId,\r\n privateKeyHash: await this._createSafeLogHash(ecdsaKeyPair.privateKey, 'ecdsa_private'),\r\n publicKeyHash: await this._createSafeLogHash(ecdsaKeyPair.publicKey, 'ecdsa_public'),\r\n privateKeyType: ecdsaKeyPair.privateKey.algorithm?.name,\r\n publicKeyType: ecdsaKeyPair.publicKey.algorithm?.name\r\n });\r\n \r\n } catch (ecdsaError) {\r\n this._secureLog('error', 'ECDSA key generation failed', {\r\n operationId: operationId,\r\n errorType: ecdsaError.constructor.name\r\n });\r\n this._throwSecureError(ecdsaError, 'ecdsa_key_generation');\r\n }\r\n \r\n // Final validation of both key pairs\r\n if (!ecdhKeyPair || !ecdsaKeyPair) {\r\n throw new Error('One or both key pairs failed to generate');\r\n }\r\n \r\n // Enable security features after successful key generation\r\n this._enableSecurityFeaturesAfterKeyGeneration(ecdhKeyPair, ecdsaKeyPair);\r\n \r\n this._secureLog('info', 'Encryption keys generated successfully with atomic protection', {\r\n operationId: operationId,\r\n hasECDHKeys: !!(ecdhKeyPair?.privateKey && ecdhKeyPair?.publicKey),\r\n hasECDSAKeys: !!(ecdsaKeyPair?.privateKey && ecdsaKeyPair?.publicKey),\r\n generationTime: Date.now() - currentState.lastOperationTime\r\n });\r\n \r\n return { ecdhKeyPair, ecdsaKeyPair };\r\n \r\n } catch (error) {\r\n // Ensure state is reset on any error\r\n this._secureLog('error', 'Key generation failed, resetting state', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n throw error;\r\n } finally {\r\n // Always reset state in finally block\r\n currentState.isInitializing = false;\r\n currentState.operationId = null;\r\n \r\n this._secureLog('debug', 'Key generation state reset', {\r\n operationId: operationId\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Enable security features after successful key generation\r\n */\r\n _enableSecurityFeaturesAfterKeyGeneration(ecdhKeyPair, ecdsaKeyPair) {\r\n try {\r\n // Enable encryption features based on available keys\r\n if (ecdhKeyPair && ecdhKeyPair.privateKey && ecdhKeyPair.publicKey) {\r\n this.securityFeatures.hasEncryption = true;\r\n this.securityFeatures.hasECDH = true;\r\n this._secureLog('info', 'ECDH encryption features enabled');\r\n }\r\n \r\n if (ecdsaKeyPair && ecdsaKeyPair.privateKey && ecdsaKeyPair.publicKey) {\r\n this.securityFeatures.hasECDSA = true;\r\n this._secureLog('info', 'ECDSA signature features enabled');\r\n }\r\n \r\n // Enable additional features that depend on encryption\r\n if (this.securityFeatures.hasEncryption) {\r\n this.securityFeatures.hasMetadataProtection = true;\r\n this.securityFeatures.hasEnhancedReplayProtection = true;\r\n this.securityFeatures.hasNonExtractableKeys = true;\r\n this._secureLog('info', 'Additional encryption-dependent features enabled');\r\n }\r\n \r\n // Enable PFS after ephemeral key generation\r\n if (ecdhKeyPair && this.ephemeralKeyPairs.size > 0) {\r\n this.securityFeatures.hasPFS = true;\r\n this._secureLog('info', 'Perfect Forward Secrecy enabled with ephemeral keys');\r\n }\r\n \r\n this._secureLog('info', 'Security features updated after key generation', {\r\n hasEncryption: this.securityFeatures.hasEncryption,\r\n hasECDH: this.securityFeatures.hasECDH,\r\n hasECDSA: this.securityFeatures.hasECDSA,\r\n hasMetadataProtection: this.securityFeatures.hasMetadataProtection,\r\n hasEnhancedReplayProtection: this.securityFeatures.hasEnhancedReplayProtection,\r\n hasNonExtractableKeys: this.securityFeatures.hasNonExtractableKeys,\r\n hasPFS: this.securityFeatures.hasPFS\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to enable security features after key generation', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Enhanced emergency mutex unlocking with authorization and validation\r\n */\r\n _emergencyUnlockAllMutexes(callerContext = 'unknown') {\r\n // Validate caller authorization\r\n const authorizedCallers = [\r\n 'keyOperation', 'cryptoOperation', 'connectionOperation',\r\n 'emergencyRecovery', 'systemShutdown', 'errorHandler'\r\n ];\r\n \r\n if (!authorizedCallers.includes(callerContext)) {\r\n this._secureLog('error', `UNAUTHORIZED emergency mutex unlock attempt`, {\r\n callerContext: callerContext,\r\n authorizedCallers: authorizedCallers,\r\n timestamp: Date.now()\r\n });\r\n throw new Error(`Unauthorized emergency mutex unlock attempt by: ${callerContext}`);\r\n }\r\n \r\n const mutexes = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n \r\n this._secureLog('error', 'EMERGENCY: Unlocking all mutexes with authorization and state cleanup', {\r\n callerContext: callerContext,\r\n timestamp: Date.now()\r\n });\r\n \r\n let unlockedCount = 0;\r\n let errorCount = 0;\r\n \r\n mutexes.forEach(mutexName => {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n if (mutex) {\r\n try {\r\n // Clear timeout first\r\n if (mutex.lockTimeout) {\r\n clearTimeout(mutex.lockTimeout);\r\n }\r\n \r\n // Log mutex state before emergency unlock\r\n const previousState = {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n lockTime: mutex.lockTime,\r\n queueLength: mutex.queue.length\r\n };\r\n \r\n // Reset mutex state atomically\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n mutex.lockTime = null;\r\n \r\n // Clear queue with proper error handling and logging\r\n let queueRejectCount = 0;\r\n mutex.queue.forEach(item => {\r\n try {\r\n if (item.reject && typeof item.reject === 'function') {\r\n item.reject(new Error(`Emergency mutex unlock for ${mutexName} by ${callerContext}`));\r\n queueRejectCount++;\r\n }\r\n } catch (rejectError) {\r\n this._secureLog('warn', `Failed to reject queue item during emergency unlock`, {\r\n mutexName: mutexName,\r\n errorType: rejectError.constructor.name\r\n });\r\n }\r\n });\r\n \r\n // Clear queue array\r\n mutex.queue = [];\r\n \r\n unlockedCount++;\r\n \r\n this._secureLog('debug', `Emergency unlocked mutex: ${mutexName}`, {\r\n previousState: previousState,\r\n queueRejectCount: queueRejectCount,\r\n callerContext: callerContext\r\n });\r\n \r\n } catch (error) {\r\n errorCount++;\r\n this._secureLog('error', `Error during emergency unlock of mutex: ${mutexName}`, {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n callerContext: callerContext\r\n });\r\n }\r\n }\r\n });\r\n \r\n // Reset key system state with validation\r\n if (this._keySystemState) {\r\n try {\r\n const previousKeyState = { ...this._keySystemState };\r\n \r\n this._keySystemState.isInitializing = false;\r\n this._keySystemState.isRotating = false;\r\n this._keySystemState.isDestroying = false;\r\n this._keySystemState.operationId = null;\r\n this._keySystemState.concurrentOperations = 0;\r\n \r\n this._secureLog('debug', `Emergency reset key system state`, {\r\n previousState: previousKeyState,\r\n callerContext: callerContext\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Error resetting key system state during emergency unlock`, {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n callerContext: callerContext\r\n });\r\n }\r\n }\r\n \r\n // Log emergency unlock summary\r\n this._secureLog('info', `Emergency mutex unlock completed`, {\r\n callerContext: callerContext,\r\n unlockedCount: unlockedCount,\r\n errorCount: errorCount,\r\n totalMutexes: mutexes.length,\r\n timestamp: Date.now()\r\n });\r\n \r\n // Trigger system validation after emergency unlock\r\n setTimeout(() => {\r\n this._validateMutexSystemAfterEmergencyUnlock();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Handle key operation errors with recovery mechanisms\r\n */\r\n _handleKeyOperationError(error, operationId) {\r\n this._secureLog('error', 'Key operation error detected, initiating recovery', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Reset key system state immediately\r\n if (this._keySystemState) {\r\n this._keySystemState.isInitializing = false;\r\n this._keySystemState.isRotating = false;\r\n this._keySystemState.isDestroying = false;\r\n this._keySystemState.operationId = null;\r\n }\r\n \r\n // Clear any partial key data\r\n this.ecdhKeyPair = null;\r\n this.ecdsaKeyPair = null;\r\n this.encryptionKey = null;\r\n this.macKey = null;\r\n this.metadataKey = null;\r\n \r\n // Trigger emergency recovery if needed\r\n if (error.message.includes('timeout') || error.message.includes('race condition')) {\r\n this._secureLog('warn', 'Race condition or timeout detected, triggering emergency recovery');\r\n this._emergencyRecoverMutexSystem();\r\n }\r\n }\r\n\r\n /**\r\n * Generate cryptographically secure IV with reuse prevention\r\n */\r\n _generateSecureIV(ivSize = 12, context = 'general') {\r\n // Check if we're in emergency mode\r\n if (this._ivTrackingSystem.emergencyMode) {\r\n this._secureLog('error', 'CRITICAL: IV generation blocked - emergency mode active due to IV reuse');\r\n throw new Error('IV generation blocked - emergency mode active');\r\n }\r\n \r\n let attempts = 0;\r\n const maxAttempts = 100; // Prevent infinite loops\r\n \r\n while (attempts < maxAttempts) {\r\n attempts++;\r\n \r\n // Generate fresh IV with crypto.getRandomValues\r\n const iv = crypto.getRandomValues(new Uint8Array(ivSize));\r\n \r\n // Convert IV to string for tracking\r\n const ivString = Array.from(iv).map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n // Check for IV reuse\r\n if (this._ivTrackingSystem.usedIVs.has(ivString)) {\r\n this._ivTrackingSystem.collisionCount++;\r\n this._secureLog('error', `CRITICAL: IV reuse detected!`, {\r\n context: context,\r\n attempt: attempts,\r\n collisionCount: this._ivTrackingSystem.collisionCount,\r\n ivString: ivString.substring(0, 16) + '...' // Log partial IV for debugging\r\n });\r\n \r\n // If too many collisions, trigger emergency mode\r\n if (this._ivTrackingSystem.collisionCount > 5) {\r\n this._ivTrackingSystem.emergencyMode = true;\r\n this._secureLog('error', 'CRITICAL: Emergency mode activated due to excessive IV reuse');\r\n throw new Error('Emergency mode: Excessive IV reuse detected');\r\n }\r\n \r\n continue; // Try again\r\n }\r\n \r\n // Validate IV entropy\r\n if (!this._validateIVEntropy(iv)) {\r\n this._ivTrackingSystem.entropyValidation.entropyFailures++;\r\n this._secureLog('warn', `Low entropy IV detected`, {\r\n context: context,\r\n attempt: attempts,\r\n entropyFailures: this._ivTrackingSystem.entropyValidation.entropyFailures\r\n });\r\n \r\n // If too many entropy failures, trigger emergency mode\r\n if (this._ivTrackingSystem.entropyValidation.entropyFailures > 10) {\r\n this._ivTrackingSystem.emergencyMode = true;\r\n this._secureLog('error', 'CRITICAL: Emergency mode activated due to low entropy IVs');\r\n throw new Error('Emergency mode: Low entropy IVs detected');\r\n }\r\n \r\n continue; // Try again\r\n }\r\n \r\n // Track IV usage\r\n this._ivTrackingSystem.usedIVs.add(ivString);\r\n this._ivTrackingSystem.ivHistory.set(ivString, {\r\n timestamp: Date.now(),\r\n context: context,\r\n attempt: attempts\r\n });\r\n \r\n // Track per-session IVs\r\n if (this.sessionId) {\r\n if (!this._ivTrackingSystem.sessionIVs.has(this.sessionId)) {\r\n this._ivTrackingSystem.sessionIVs.set(this.sessionId, new Set());\r\n }\r\n this._ivTrackingSystem.sessionIVs.get(this.sessionId).add(ivString);\r\n }\r\n \r\n // Validate RNG periodically\r\n this._validateRNGQuality();\r\n \r\n this._secureLog('debug', `Secure IV generated`, {\r\n context: context,\r\n attempt: attempts,\r\n ivSize: ivSize,\r\n totalIVs: this._ivTrackingSystem.usedIVs.size\r\n });\r\n \r\n return iv;\r\n }\r\n \r\n // If we can't generate a unique IV after max attempts\r\n this._secureLog('error', `Failed to generate unique IV after ${maxAttempts} attempts`, {\r\n context: context,\r\n totalIVs: this._ivTrackingSystem.usedIVs.size\r\n });\r\n throw new Error(`Failed to generate unique IV after ${maxAttempts} attempts`);\r\n }\r\n \r\n /**\r\n * Validate IV entropy to detect weak RNG\r\n */\r\n _validateIVEntropy(iv) {\r\n this._ivTrackingSystem.entropyValidation.entropyTests++;\r\n \r\n // Calculate byte distribution\r\n const byteCounts = new Array(256).fill(0);\r\n for (let i = 0; i < iv.length; i++) {\r\n byteCounts[iv[i]]++;\r\n }\r\n \r\n // Multi-dimensional entropy analysis\r\n const entropyResults = {\r\n shannon: 0,\r\n min: 0,\r\n collision: 0,\r\n compression: 0,\r\n quantum: 0\r\n };\r\n \r\n // 1. Shannon entropy calculation\r\n let shannonEntropy = 0;\r\n const totalBytes = iv.length;\r\n \r\n for (let i = 0; i < 256; i++) {\r\n if (byteCounts[i] > 0) {\r\n const probability = byteCounts[i] / totalBytes;\r\n shannonEntropy -= probability * Math.log2(probability);\r\n }\r\n }\r\n entropyResults.shannon = shannonEntropy;\r\n \r\n // 2. Min-entropy calculation (worst-case scenario)\r\n const maxCount = Math.max(...byteCounts);\r\n const maxProbability = maxCount / totalBytes;\r\n entropyResults.min = -Math.log2(maxProbability);\r\n \r\n // 3. Collision entropy calculation\r\n let collisionSum = 0;\r\n for (let i = 0; i < 256; i++) {\r\n if (byteCounts[i] > 0) {\r\n const probability = byteCounts[i] / totalBytes;\r\n collisionSum += probability * probability;\r\n }\r\n }\r\n entropyResults.collision = -Math.log2(collisionSum);\r\n \r\n // 4. Compression-based entropy estimation\r\n const ivString = Array.from(iv).map(b => String.fromCharCode(b)).join('');\r\n const compressedLength = this._estimateCompressedLength(ivString);\r\n entropyResults.compression = (1 - compressedLength / totalBytes) * 8;\r\n \r\n // 5. Quantum-resistant entropy analysis\r\n entropyResults.quantum = this._calculateQuantumResistantEntropy(iv);\r\n \r\n // Enhanced suspicious pattern detection\r\n const hasSuspiciousPatterns = this._detectAdvancedSuspiciousPatterns(iv);\r\n \r\n // Multi-criteria validation\r\n const minEntropyThreshold = this._ivTrackingSystem.entropyValidation.minEntropy;\r\n const isValid = (\r\n entropyResults.shannon >= minEntropyThreshold &&\r\n entropyResults.min >= minEntropyThreshold * 0.8 &&\r\n entropyResults.collision >= minEntropyThreshold * 0.9 &&\r\n entropyResults.compression >= minEntropyThreshold * 0.7 &&\r\n entropyResults.quantum >= minEntropyThreshold * 0.6 &&\r\n !hasSuspiciousPatterns\r\n );\r\n \r\n if (!isValid) {\r\n this._secureLog('warn', `Enhanced IV entropy validation failed`, {\r\n shannon: entropyResults.shannon.toFixed(2),\r\n min: entropyResults.min.toFixed(2),\r\n collision: entropyResults.collision.toFixed(2),\r\n compression: entropyResults.compression.toFixed(2),\r\n quantum: entropyResults.quantum.toFixed(2),\r\n minThreshold: minEntropyThreshold,\r\n hasSuspiciousPatterns: hasSuspiciousPatterns\r\n });\r\n }\r\n \r\n return isValid;\r\n }\r\n \r\n /**\r\n * Estimate compressed length for entropy calculation\r\n * @param {string} data - Data to estimate compression\r\n * @returns {number} Estimated compressed length\r\n */\r\n _estimateCompressedLength(data) {\r\n // Simple LZ77-like compression estimation\r\n let compressedLength = 0;\r\n let i = 0;\r\n \r\n while (i < data.length) {\r\n let matchLength = 0;\r\n let matchDistance = 0;\r\n \r\n // Look for repeated patterns\r\n for (let j = Math.max(0, i - 255); j < i; j++) {\r\n let k = 0;\r\n while (i + k < data.length && data[i + k] === data[j + k] && k < 255) {\r\n k++;\r\n }\r\n if (k > matchLength) {\r\n matchLength = k;\r\n matchDistance = i - j;\r\n }\r\n }\r\n \r\n if (matchLength >= 3) {\r\n compressedLength += 3; // Distance + length + literal\r\n i += matchLength;\r\n } else {\r\n compressedLength += 1;\r\n i += 1;\r\n }\r\n }\r\n \r\n return compressedLength;\r\n }\r\n\r\n /**\r\n * Calculate quantum-resistant entropy\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {number} Quantum-resistant entropy score\r\n */\r\n _calculateQuantumResistantEntropy(data) {\r\n // Quantum-resistant entropy analysis\r\n let quantumScore = 0;\r\n \r\n // 1. Check for quantum-vulnerable patterns\r\n const hasQuantumVulnerablePatterns = this._detectQuantumVulnerablePatterns(data);\r\n if (hasQuantumVulnerablePatterns) {\r\n quantumScore -= 2;\r\n }\r\n \r\n // 2. Analyze bit distribution\r\n const bitDistribution = this._analyzeBitDistribution(data);\r\n quantumScore += bitDistribution.score;\r\n \r\n // 3. Check for periodicity\r\n const periodicity = this._detectPeriodicity(data);\r\n quantumScore -= periodicity * 0.5;\r\n \r\n // 4. Normalize to 0-8 range\r\n return Math.max(0, Math.min(8, quantumScore));\r\n }\r\n\r\n /**\r\n * Detect quantum-vulnerable patterns\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {boolean} true if quantum-vulnerable patterns found\r\n */\r\n _detectQuantumVulnerablePatterns(data) {\r\n // Check for patterns vulnerable to quantum attacks\r\n const patterns = [\r\n [0, 0, 0, 0, 0, 0, 0, 0], // All zeros\r\n [255, 255, 255, 255, 255, 255, 255, 255], // All ones\r\n [0, 1, 0, 1, 0, 1, 0, 1], // Alternating\r\n [1, 0, 1, 0, 1, 0, 1, 0] // Alternating reverse\r\n ];\r\n \r\n for (const pattern of patterns) {\r\n for (let i = 0; i <= data.length - pattern.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < pattern.length; j++) {\r\n if (data[i + j] !== pattern[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return true;\r\n }\r\n }\r\n \r\n return false;\r\n }\r\n\r\n /**\r\n * Analyze bit distribution\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {Object} Bit distribution analysis\r\n */\r\n _analyzeBitDistribution(data) {\r\n let ones = 0;\r\n let totalBits = data.length * 8;\r\n \r\n for (const byte of data) {\r\n ones += (byte >>> 0).toString(2).split('1').length - 1;\r\n }\r\n \r\n const zeroRatio = (totalBits - ones) / totalBits;\r\n const oneRatio = ones / totalBits;\r\n \r\n // Ideal distribution is 50/50\r\n const deviation = Math.abs(0.5 - oneRatio);\r\n const score = Math.max(0, 8 - deviation * 16);\r\n \r\n return { score, zeroRatio, oneRatio, deviation };\r\n }\r\n\r\n /**\r\n * Detect periodicity in data\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {number} Periodicity score (0-1)\r\n */\r\n _detectPeriodicity(data) {\r\n if (data.length < 16) return 0;\r\n \r\n let maxPeriodicity = 0;\r\n \r\n // Check for periods from 2 to data.length/2\r\n for (let period = 2; period <= data.length / 2; period++) {\r\n let matches = 0;\r\n let totalChecks = 0;\r\n \r\n for (let i = 0; i < data.length - period; i++) {\r\n if (data[i] === data[i + period]) {\r\n matches++;\r\n }\r\n totalChecks++;\r\n }\r\n \r\n if (totalChecks > 0) {\r\n const periodicity = matches / totalChecks;\r\n maxPeriodicity = Math.max(maxPeriodicity, periodicity);\r\n }\r\n }\r\n \r\n return maxPeriodicity;\r\n }\r\n\r\n /**\r\n * Enhanced suspicious pattern detection\r\n * @param {Uint8Array} iv - IV to check\r\n * @returns {boolean} true if suspicious patterns found\r\n */\r\n _detectAdvancedSuspiciousPatterns(iv) {\r\n // Enhanced pattern detection with quantum-resistant analysis\r\n const patterns = [\r\n // Sequential patterns\r\n [0, 1, 2, 3, 4, 5, 6, 7],\r\n [255, 254, 253, 252, 251, 250, 249, 248],\r\n \r\n // Repeated patterns\r\n [0, 0, 0, 0, 0, 0, 0, 0],\r\n [255, 255, 255, 255, 255, 255, 255, 255],\r\n \r\n // Alternating patterns\r\n [0, 255, 0, 255, 0, 255, 0, 255],\r\n [255, 0, 255, 0, 255, 0, 255, 0]\r\n ];\r\n \r\n for (const pattern of patterns) {\r\n for (let i = 0; i <= iv.length - pattern.length; i++) {\r\n let match = true;\r\n for (let j = 0; j < pattern.length; j++) {\r\n if (iv[i + j] !== pattern[j]) {\r\n match = false;\r\n break;\r\n }\r\n }\r\n if (match) return true;\r\n }\r\n }\r\n \r\n // Check for low entropy regions\r\n const entropyMap = this._calculateLocalEntropy(iv);\r\n const lowEntropyRegions = entropyMap.filter(e => e < 3.0).length;\r\n \r\n return lowEntropyRegions > iv.length * 0.3; // More than 30% low entropy\r\n }\r\n\r\n /**\r\n * Calculate local entropy for pattern detection\r\n * @param {Uint8Array} data - Data to analyze\r\n * @returns {Array} Array of local entropy values\r\n */\r\n _calculateLocalEntropy(data) {\r\n const windowSize = 8;\r\n const entropyMap = [];\r\n \r\n for (let i = 0; i <= data.length - windowSize; i++) {\r\n const window = data.slice(i, i + windowSize);\r\n const charCount = {};\r\n \r\n for (const byte of window) {\r\n charCount[byte] = (charCount[byte] || 0) + 1;\r\n }\r\n \r\n let entropy = 0;\r\n for (const count of Object.values(charCount)) {\r\n const probability = count / windowSize;\r\n entropy -= probability * Math.log2(probability);\r\n }\r\n \r\n entropyMap.push(entropy);\r\n }\r\n \r\n return entropyMap;\r\n }\r\n\r\n /**\r\n * Detect suspicious patterns in IVs\r\n */\r\n _detectSuspiciousIVPatterns(iv) {\r\n // Check for all zeros or all ones\r\n const allZeros = iv.every(byte => byte === 0);\r\n const allOnes = iv.every(byte => byte === 255);\r\n \r\n if (allZeros || allOnes) {\r\n return true;\r\n }\r\n \r\n // Check for sequential patterns\r\n let sequentialCount = 0;\r\n for (let i = 1; i < iv.length; i++) {\r\n if (iv[i] === iv[i-1] + 1 || iv[i] === iv[i-1] - 1) {\r\n sequentialCount++;\r\n } else {\r\n sequentialCount = 0;\r\n }\r\n \r\n if (sequentialCount >= 3) {\r\n return true; // Suspicious sequential pattern\r\n }\r\n }\r\n \r\n // Check for repeated patterns\r\n for (let patternLength = 2; patternLength <= Math.floor(iv.length / 2); patternLength++) {\r\n for (let start = 0; start <= iv.length - patternLength * 2; start++) {\r\n const pattern1 = iv.slice(start, start + patternLength);\r\n const pattern2 = iv.slice(start + patternLength, start + patternLength * 2);\r\n \r\n if (pattern1.every((byte, index) => byte === pattern2[index])) {\r\n return true; // Repeated pattern detected\r\n }\r\n }\r\n }\r\n \r\n return false;\r\n }\r\n \r\n /**\r\n * Clean up old IVs with strict limits\r\n */\r\n async _cleanupOldIVs() {\r\n const now = Date.now();\r\n const maxAge = 1800000; // Reduced to 30 minutes for better security\r\n let cleanedCount = 0;\r\n const cleanupBatch = [];\r\n \r\n // Aggressive cleanup with quantum-resistant patterns\r\n // Enforce maximum IV history size with batch processing\r\n if (this._ivTrackingSystem.ivHistory.size > this._ivTrackingSystem.maxIVHistorySize) {\r\n const ivArray = Array.from(this._ivTrackingSystem.ivHistory.entries());\r\n const toRemove = ivArray.slice(0, ivArray.length - this._ivTrackingSystem.maxIVHistorySize);\r\n \r\n for (const [ivString] of toRemove) {\r\n cleanupBatch.push(ivString);\r\n cleanedCount++;\r\n \r\n // Process in batches to prevent memory spikes\r\n if (cleanupBatch.length >= 100) {\r\n this._processCleanupBatch(cleanupBatch);\r\n cleanupBatch.length = 0;\r\n }\r\n }\r\n }\r\n \r\n // Clean up old IVs from history by age with enhanced security\r\n for (const [ivString, metadata] of this._ivTrackingSystem.ivHistory.entries()) {\r\n if (now - metadata.timestamp > maxAge) {\r\n cleanupBatch.push(ivString);\r\n cleanedCount++;\r\n \r\n // Process in batches to prevent memory spikes\r\n if (cleanupBatch.length >= 100) {\r\n this._processCleanupBatch(cleanupBatch);\r\n cleanupBatch.length = 0;\r\n }\r\n }\r\n }\r\n \r\n // Process remaining batch\r\n if (cleanupBatch.length > 0) {\r\n this._processCleanupBatch(cleanupBatch);\r\n }\r\n \r\n // Enhanced session IV cleanup with entropy preservation\r\n for (const [sessionId, sessionIVs] of this._ivTrackingSystem.sessionIVs.entries()) {\r\n if (sessionIVs.size > this._ivTrackingSystem.maxSessionIVs) {\r\n const ivArray = Array.from(sessionIVs);\r\n const toRemove = ivArray.slice(0, ivArray.length - this._ivTrackingSystem.maxSessionIVs);\r\n \r\n for (const ivString of toRemove) {\r\n sessionIVs.delete(ivString);\r\n this._ivTrackingSystem.usedIVs.delete(ivString);\r\n this._ivTrackingSystem.ivHistory.delete(ivString);\r\n cleanedCount++;\r\n }\r\n }\r\n }\r\n \r\n // Schedule natural cleanup if significant cleanup occurred\r\n if (cleanedCount > 50) {\r\n await this._performNaturalCleanup();\r\n }\r\n \r\n if (cleanedCount > 0) {\r\n this._secureLog('debug', `Enhanced cleanup: ${cleanedCount} old IVs removed`, {\r\n cleanedCount: cleanedCount,\r\n remainingIVs: this._ivTrackingSystem.usedIVs.size,\r\n remainingHistory: this._ivTrackingSystem.ivHistory.size,\r\n memoryPressure: this._calculateMemoryPressure()\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Process cleanup batch with constant-time operations\r\n * @param {Array} batch - Batch of items to clean up\r\n */\r\n _processCleanupBatch(batch) {\r\n // Constant-time batch processing\r\n for (const item of batch) {\r\n this._ivTrackingSystem.usedIVs.delete(item);\r\n this._ivTrackingSystem.ivHistory.delete(item);\r\n }\r\n }\r\n\r\n /**\r\n * Calculate memory pressure for adaptive cleanup\r\n * @returns {number} Memory pressure score (0-100)\r\n */\r\n _calculateMemoryPressure() {\r\n const totalIVs = this._ivTrackingSystem.usedIVs.size;\r\n const maxAllowed = this._resourceLimits.maxIVHistory;\r\n \r\n return Math.min(100, Math.floor((totalIVs / maxAllowed) * 100));\r\n }\r\n\r\n /**\r\n * Get IV tracking system statistics\r\n */\r\n _getIVTrackingStats() {\r\n return {\r\n totalIVs: this._ivTrackingSystem.usedIVs.size,\r\n collisionCount: this._ivTrackingSystem.collisionCount,\r\n entropyTests: this._ivTrackingSystem.entropyValidation.entropyTests,\r\n entropyFailures: this._ivTrackingSystem.entropyValidation.entropyFailures,\r\n rngTests: this._ivTrackingSystem.rngValidation.testsPerformed,\r\n weakRngDetected: this._ivTrackingSystem.rngValidation.weakRngDetected,\r\n emergencyMode: this._ivTrackingSystem.emergencyMode,\r\n sessionCount: this._ivTrackingSystem.sessionIVs.size,\r\n lastCleanup: this._lastIVCleanupTime || 0\r\n };\r\n }\r\n \r\n /**\r\n * Reset IV tracking system (for testing or emergency recovery)\r\n */\r\n _resetIVTrackingSystem() {\r\n this._secureLog('warn', 'Resetting IV tracking system');\r\n \r\n this._ivTrackingSystem.usedIVs.clear();\r\n this._ivTrackingSystem.ivHistory.clear();\r\n this._ivTrackingSystem.sessionIVs.clear();\r\n this._ivTrackingSystem.collisionCount = 0;\r\n this._ivTrackingSystem.entropyValidation.entropyTests = 0;\r\n this._ivTrackingSystem.entropyValidation.entropyFailures = 0;\r\n this._ivTrackingSystem.rngValidation.testsPerformed = 0;\r\n this._ivTrackingSystem.rngValidation.weakRngDetected = false;\r\n this._ivTrackingSystem.emergencyMode = false;\r\n \r\n this._secureLog('info', 'IV tracking system reset completed');\r\n }\r\n \r\n /**\r\n * Validate RNG quality\r\n */\r\n _validateRNGQuality() {\r\n const now = Date.now();\r\n \r\n // Validate RNG every 1000 IV generations\r\n if (this._ivTrackingSystem.rngValidation.testsPerformed % 1000 === 0) {\r\n try {\r\n // Generate test IVs and validate\r\n const testIVs = [];\r\n for (let i = 0; i < 100; i++) {\r\n testIVs.push(crypto.getRandomValues(new Uint8Array(12)));\r\n }\r\n \r\n // Check for duplicates in test set\r\n const testIVStrings = testIVs.map(iv => Array.from(iv).map(b => b.toString(16).padStart(2, '0')).join(''));\r\n const uniqueTestIVs = new Set(testIVStrings);\r\n \r\n if (uniqueTestIVs.size < 95) { // Allow some tolerance\r\n this._ivTrackingSystem.rngValidation.weakRngDetected = true;\r\n this._secureLog('error', 'CRITICAL: Weak RNG detected in validation test', {\r\n uniqueIVs: uniqueTestIVs.size,\r\n totalTests: testIVs.length\r\n });\r\n }\r\n \r\n this._ivTrackingSystem.rngValidation.lastValidation = now;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'RNG validation failed', {\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }\r\n \r\n this._ivTrackingSystem.rngValidation.testsPerformed++;\r\n }\r\n \r\n /**\r\n * Handle mutex timeout with enhanced state validation\r\n */\r\n _handleMutexTimeout(mutexName, operationId, timeout) {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n \r\n if (!mutex) {\r\n this._secureLog('error', `Mutex '${mutexName}' not found during timeout handling`);\r\n return;\r\n }\r\n \r\n // Validate timeout conditions\r\n if (mutex.lockId !== operationId) {\r\n this._secureLog('warn', `Timeout for different operation ID on mutex '${mutexName}'`, {\r\n expectedOperationId: operationId,\r\n actualLockId: mutex.lockId,\r\n locked: mutex.locked\r\n });\r\n return;\r\n }\r\n \r\n if (!mutex.locked) {\r\n this._secureLog('warn', `Timeout for already unlocked mutex '${mutexName}'`, {\r\n operationId: operationId\r\n });\r\n return;\r\n }\r\n \r\n try {\r\n // Calculate lock duration for monitoring\r\n const lockDuration = mutex.lockTime ? Date.now() - mutex.lockTime : 0;\r\n \r\n this._secureLog('warn', `Mutex '${mutexName}' auto-released due to timeout`, {\r\n operationId: operationId,\r\n lockDuration: lockDuration,\r\n timeout: timeout,\r\n queueLength: mutex.queue.length\r\n });\r\n \r\n // Atomic release with state validation\r\n mutex.locked = false;\r\n mutex.lockId = null;\r\n mutex.lockTimeout = null;\r\n mutex.lockTime = null;\r\n \r\n // Process next in queue with error handling\r\n setTimeout(() => {\r\n try {\r\n this._processNextInQueue(mutexName);\r\n } catch (queueError) {\r\n this._secureLog('error', `Error processing queue after timeout for mutex '${mutexName}'`, {\r\n errorType: queueError.constructor.name,\r\n errorMessage: queueError.message\r\n });\r\n }\r\n }, 10);\r\n \r\n } catch (error) {\r\n this._secureLog('error', `Critical error during mutex timeout handling for '${mutexName}'`, {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n \r\n // Force emergency unlock if timeout handling fails\r\n try {\r\n this._emergencyUnlockAllMutexes('timeoutHandler');\r\n } catch (emergencyError) {\r\n this._secureLog('error', `Emergency unlock failed during timeout handling`, {\r\n originalError: error.message,\r\n emergencyError: emergencyError.message\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validate mutex system after emergency unlock\r\n */\r\n _validateMutexSystemAfterEmergencyUnlock() {\r\n const mutexes = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n let validationErrors = 0;\r\n \r\n this._secureLog('info', 'Validating mutex system after emergency unlock');\r\n \r\n mutexes.forEach(mutexName => {\r\n const mutex = this[`_${mutexName}Mutex`];\r\n \r\n if (!mutex) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' not found after emergency unlock`);\r\n return;\r\n }\r\n \r\n // Validate mutex state consistency\r\n if (mutex.locked) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still locked after emergency unlock`, {\r\n lockId: mutex.lockId,\r\n lockTime: mutex.lockTime\r\n });\r\n }\r\n \r\n if (mutex.lockId !== null) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still has lock ID after emergency unlock`, {\r\n lockId: mutex.lockId\r\n });\r\n }\r\n \r\n if (mutex.lockTimeout !== null) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still has timeout after emergency unlock`);\r\n }\r\n \r\n if (mutex.queue.length > 0) {\r\n validationErrors++;\r\n this._secureLog('error', `Mutex '${mutexName}' still has queue items after emergency unlock`, {\r\n queueLength: mutex.queue.length\r\n });\r\n }\r\n });\r\n \r\n // Validate key system state\r\n if (this._keySystemState) {\r\n if (this._keySystemState.isInitializing || \r\n this._keySystemState.isRotating || \r\n this._keySystemState.isDestroying) {\r\n validationErrors++;\r\n this._secureLog('error', `Key system state not properly reset after emergency unlock`, {\r\n isInitializing: this._keySystemState.isInitializing,\r\n isRotating: this._keySystemState.isRotating,\r\n isDestroying: this._keySystemState.isDestroying\r\n });\r\n }\r\n }\r\n \r\n if (validationErrors === 0) {\r\n this._secureLog('info', 'Mutex system validation passed after emergency unlock');\r\n } else {\r\n this._secureLog('error', `Mutex system validation failed after emergency unlock`, {\r\n validationErrors: validationErrors\r\n });\r\n \r\n // Force re-initialization if validation fails\r\n setTimeout(() => {\r\n this._emergencyRecoverMutexSystem();\r\n }, 1000);\r\n }\r\n }\r\n /**\r\n * NEW: Diagnostics of the mutex system state\r\n */\r\n _getMutexSystemDiagnostics() {\r\n const diagnostics = {\r\n timestamp: Date.now(),\r\n systemValid: this._validateMutexSystem(),\r\n mutexes: {},\r\n counters: { ...this._operationCounters },\r\n keySystemState: { ...this._keySystemState }\r\n };\r\n \r\n const mutexNames = ['keyOperation', 'cryptoOperation', 'connectionOperation'];\r\n \r\n mutexNames.forEach(mutexName => {\r\n const mutexPropertyName = `_${mutexName}Mutex`;\r\n const mutex = this[mutexPropertyName];\r\n \r\n if (mutex) {\r\n diagnostics.mutexes[mutexName] = {\r\n locked: mutex.locked,\r\n lockId: mutex.lockId,\r\n queueLength: mutex.queue.length,\r\n hasTimeout: !!mutex.lockTimeout\r\n };\r\n } else {\r\n diagnostics.mutexes[mutexName] = { error: 'not_found' };\r\n }\r\n });\r\n \r\n return diagnostics;\r\n }\r\n\r\n /**\r\n * FULLY FIXED createSecureOffer()\r\n * With race-condition protection and improved security\r\n */\r\n async createSecureOffer() {\r\n return this._withMutex('connectionOperation', async (operationId) => {\r\n this._secureLog('info', 'Creating secure offer with mutex', {\r\n operationId: operationId,\r\n connectionAttempts: this.connectionAttempts,\r\n currentState: this.peerConnection?.connectionState || 'none'\r\n });\r\n \r\n try {\r\n // ============================================\r\n // PHASE 1: INITIALIZATION AND VALIDATION\r\n // ============================================\r\n \r\n // Reset notification flags for a new connection\r\n this._resetNotificationFlags();\r\n \r\n // Rate limiting check\r\n if (!this._checkRateLimit()) {\r\n throw new Error('Connection rate limit exceeded. Please wait before trying again.');\r\n }\r\n \r\n // Reset attempt counters\r\n this.connectionAttempts = 0;\r\n \r\n // Generate session salt (64 bytes for v4.0)\r\n this.sessionSalt = window.EnhancedSecureCryptoUtils.generateSalt();\r\n \r\n this._secureLog('debug', 'Session salt generated', {\r\n operationId: operationId,\r\n saltLength: this.sessionSalt.length,\r\n isValidSalt: Array.isArray(this.sessionSalt) && this.sessionSalt.length === 64\r\n });\r\n \r\n // ============================================\r\n // PHASE 2: SECURE KEY GENERATION\r\n // ============================================\r\n \r\n // Secure key generation via mutex\r\n const keyPairs = await this._generateEncryptionKeys();\r\n this.ecdhKeyPair = keyPairs.ecdhKeyPair;\r\n this.ecdsaKeyPair = keyPairs.ecdsaKeyPair;\r\n \r\n // Validate generated keys\r\n if (!this.ecdhKeyPair?.privateKey || !this.ecdhKeyPair?.publicKey) {\r\n throw new Error('Failed to generate valid ECDH key pair');\r\n }\r\n \r\n if (!this.ecdsaKeyPair?.privateKey || !this.ecdsaKeyPair?.publicKey) {\r\n throw new Error('Failed to generate valid ECDSA key pair');\r\n }\r\n \r\n // ============================================\r\n // PHASE 3: MITM PROTECTION AND FINGERPRINTING\r\n // ============================================\r\n \r\n // MITM Protection: Compute unique key fingerprints\r\n const ecdhFingerprint = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(\r\n await crypto.subtle.exportKey('spki', this.ecdhKeyPair.publicKey)\r\n );\r\n const ecdsaFingerprint = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(\r\n await crypto.subtle.exportKey('spki', this.ecdsaKeyPair.publicKey)\r\n );\r\n \r\n // Validate fingerprints\r\n if (!ecdhFingerprint || !ecdsaFingerprint) {\r\n throw new Error('Failed to generate key fingerprints');\r\n }\r\n \r\n this._secureLog('info', 'Generated unique key pairs for MITM protection', {\r\n operationId: operationId,\r\n hasECDHFingerprint: !!ecdhFingerprint,\r\n hasECDSAFingerprint: !!ecdsaFingerprint,\r\n fingerprintLength: ecdhFingerprint.length,\r\n timestamp: Date.now()\r\n });\r\n \r\n // ============================================\r\n // PHASE 4: EXPORT SIGNED KEYS\r\n // ============================================\r\n \r\n // Export keys with digital signatures\r\n const ecdhPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdhKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDH'\r\n );\r\n \r\n const ecdsaPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdsaKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDSA'\r\n );\r\n\r\n \r\n if (!ecdhPublicKeyData || typeof ecdhPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDH key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdhPublicKeyData.keyData || !ecdhPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdhPublicKeyData.keyData,\r\n hasSignature: !!ecdhPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export incomplete - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData || typeof ecdsaPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData.keyData || !ecdsaPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdsaPublicKeyData.keyData,\r\n hasSignature: !!ecdsaPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export incomplete - hard abort required');\r\n }\r\n \r\n // ============================================\r\n // PHASE 5: UPDATE SECURITY FEATURES\r\n // ============================================\r\n \r\n // Atomic update of security features\r\n this._updateSecurityFeatures({\r\n hasEncryption: true,\r\n hasECDH: true,\r\n hasECDSA: true,\r\n hasMutualAuth: true,\r\n hasMetadataProtection: true,\r\n hasEnhancedReplayProtection: true,\r\n hasNonExtractableKeys: true,\r\n hasRateLimiting: true,\r\n hasEnhancedValidation: true,\r\n hasPFS: true\r\n });\r\n \r\n // ============================================\r\n // PHASE 6: INITIALIZE PEER CONNECTION\r\n // ============================================\r\n \r\n this.isInitiator = true;\r\n this.onStatusChange('connecting');\r\n \r\n // Create peer connection\r\n this.createPeerConnection();\r\n \r\n // Create main data channel\r\n this.dataChannel = this.peerConnection.createDataChannel('securechat', {\r\n ordered: true\r\n });\r\n \r\n // Setup data channel\r\n this.setupDataChannel(this.dataChannel);\r\n \r\n this._secureLog('debug', 'Data channel created', {\r\n operationId: operationId,\r\n channelLabel: this.dataChannel.label,\r\n channelOrdered: this.dataChannel.ordered\r\n });\r\n \r\n // ============================================\r\n // PHASE 7: CREATE SDP OFFER\r\n // ============================================\r\n \r\n\r\n const offer = await this.peerConnection.createOffer({\r\n offerToReceiveAudio: false,\r\n offerToReceiveVideo: false\r\n });\r\n \r\n await this.peerConnection.setLocalDescription(offer);\r\n\r\n try {\r\n const ourFingerprint = this._extractDTLSFingerprintFromSDP(offer.sdp);\r\n this.expectedDTLSFingerprint = ourFingerprint;\r\n \r\n this._secureLog('info', 'Generated DTLS fingerprint for out-of-band verification', {\r\n fingerprint: ourFingerprint,\r\n context: 'offer_creation'\r\n });\r\n \r\n // Notify UI that fingerprint is ready for out-of-band verification\r\n this.deliverMessageToUI(`DTLS fingerprint ready for verification: ${ourFingerprint}`, 'system');\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to extract DTLS fingerprint from offer', { error: error.message });\r\n // Continue without fingerprint validation (fallback mode)\r\n }\r\n \r\n // Await ICE gathering\r\n await this.waitForIceGathering();\r\n \r\n this._secureLog('debug', 'ICE gathering completed', {\r\n operationId: operationId,\r\n iceGatheringState: this.peerConnection.iceGatheringState,\r\n connectionState: this.peerConnection.connectionState\r\n });\r\n \r\n // ============================================\r\n // PHASE 8: GENERATE SAS FOR OUT-OF-BAND VERIFICATION\r\n // ============================================\r\n\r\n this.verificationCode = window.EnhancedSecureCryptoUtils.generateVerificationCode();\r\n \r\n // Validate verification code\r\n if (!this.verificationCode || this.verificationCode.length < EnhancedSecureWebRTCManager.SIZES.VERIFICATION_CODE_MIN_LENGTH) {\r\n throw new Error('Failed to generate valid verification code');\r\n }\r\n \r\n // ============================================\r\n // PHASE 9: MUTUAL AUTHENTICATION CHALLENGE\r\n // ============================================\r\n \r\n // Generate challenge for mutual authentication\r\n const authChallenge = window.EnhancedSecureCryptoUtils.generateMutualAuthChallenge();\r\n \r\n if (!authChallenge) {\r\n throw new Error('Failed to generate mutual authentication challenge');\r\n }\r\n \r\n // ============================================\r\n // PHASE 10: SESSION ID FOR MITM PROTECTION\r\n // ============================================\r\n \r\n // MITM Protection: Generate session-specific ID\r\n this.sessionId = Array.from(crypto.getRandomValues(new Uint8Array(EnhancedSecureWebRTCManager.SIZES.SESSION_ID_LENGTH)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n // Validate session ID\r\n if (!this.sessionId || this.sessionId.length !== (EnhancedSecureWebRTCManager.SIZES.SESSION_ID_LENGTH * 2)) {\r\n throw new Error('Failed to generate valid session ID');\r\n }\r\n \r\n // Generate connection ID for AAD\r\n this.connectionId = Array.from(crypto.getRandomValues(new Uint8Array(8)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n \r\n // ============================================\r\n // PHASE 11: SECURITY LEVEL CALCULATION\r\n // ============================================\r\n \r\n // All security features are enabled by default\r\n const securityLevel = {\r\n level: 'MAXIMUM',\r\n score: 100,\r\n color: 'green',\r\n details: 'All security features enabled by default',\r\n passedChecks: 10,\r\n totalChecks: 10,\r\n isRealData: true\r\n };\r\n \r\n // ============================================\r\n // PHASE 12: CREATE OFFER PACKAGE\r\n // ============================================\r\n \r\n const currentTimestamp = Date.now();\r\n \r\n // Create compact offer package for smaller QR codes\r\n const offerPackage = {\r\n // Core information (minimal)\r\n t: 'offer', // type\r\n s: this.peerConnection.localDescription.sdp, // sdp\r\n v: '4.0', // version\r\n ts: currentTimestamp, // timestamp\r\n \r\n // Cryptographic keys (essential)\r\n e: ecdhPublicKeyData, // ecdhPublicKey\r\n d: ecdsaPublicKeyData, // ecdsaPublicKey\r\n \r\n // Session data (essential)\r\n sl: this.sessionSalt, // salt\r\n si: this.sessionId, // sessionId\r\n ci: this.connectionId, // connectionId\r\n \r\n // Authentication (essential)\r\n vc: this.verificationCode, // verificationCode\r\n ac: authChallenge, // authChallenge\r\n \r\n // Security metadata (simplified)\r\n slv: 'MAX', // securityLevel\r\n \r\n // Key fingerprints (shortened)\r\n kf: {\r\n e: ecdhFingerprint.substring(0, 12), // ecdh (12 chars)\r\n d: ecdsaFingerprint.substring(0, 12) // ecdsa (12 chars)\r\n }\r\n };\r\n \r\n // ============================================\r\n // PHASE 13: VALIDATE OFFER PACKAGE\r\n // ============================================\r\n\r\n try {\r\n const validationResult = this.validateEnhancedOfferData(offerPackage);\r\n\r\n } catch (validationError) {\r\n throw new Error(`Offer package validation error: ${validationError.message}`);\r\n }\r\n \r\n // ============================================\r\n // PHASE 14: LOGGING AND EVENTS\r\n // ============================================\r\n \r\n this._secureLog('info', 'Enhanced secure offer created successfully', {\r\n operationId: operationId,\r\n version: offerPackage.version,\r\n hasECDSA: true,\r\n hasMutualAuth: true,\r\n hasSessionId: !!offerPackage.sessionId,\r\n securityLevel: securityLevel.level,\r\n timestamp: currentTimestamp,\r\n capabilitiesCount: 10 // All capabilities enabled by default\r\n });\r\n \r\n // Dispatch event about new connection\r\n document.dispatchEvent(new CustomEvent('new-connection', {\r\n detail: { \r\n type: 'offer',\r\n timestamp: currentTimestamp,\r\n securityLevel: securityLevel.level,\r\n operationId: operationId\r\n }\r\n }));\r\n\r\n return offerPackage;\r\n \r\n } catch (error) {\r\n // ============================================\r\n // ERROR HANDLING\r\n // ============================================\r\n \r\n this._secureLog('error', 'Enhanced secure offer creation failed in critical section', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n phase: this._determineErrorPhase(error),\r\n connectionAttempts: this.connectionAttempts\r\n });\r\n \r\n // Cleanup state on error\r\n this._cleanupFailedOfferCreation();\r\n \r\n // Update status\r\n this.onStatusChange('disconnected');\r\n \r\n // Re-throw for upper-level handling\r\n throw error;\r\n }\r\n }, 15000); // 15 seconds timeout for the entire offer creation\r\n }\r\n\r\n /**\r\n * HELPER: Determine the phase where the error occurred\r\n */\r\n _determineErrorPhase(error) {\r\n const message = error.message.toLowerCase();\r\n \r\n if (message.includes('rate limit')) return 'rate_limiting';\r\n if (message.includes('key pair') || message.includes('generate')) return 'key_generation';\r\n if (message.includes('fingerprint')) return 'fingerprinting';\r\n if (message.includes('export') || message.includes('signature')) return 'key_export';\r\n if (message.includes('peer connection')) return 'webrtc_setup';\r\n if (message.includes('offer') || message.includes('sdp')) return 'sdp_creation';\r\n if (message.includes('verification')) return 'verification_setup';\r\n if (message.includes('session')) return 'session_setup';\r\n if (message.includes('validation')) return 'package_validation';\r\n \r\n return 'unknown';\r\n }\r\n\r\n /**\r\n * Secure cleanup state after failed offer creation\r\n */\r\n _cleanupFailedOfferCreation() {\r\n try {\r\n // Secure wipe of cryptographic materials\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Close peer connection if it was created\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Clear data channel\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n \r\n // Reset flags\r\n this.isInitiator = false;\r\n this.isVerified = false;\r\n \r\n // Reset security features to baseline\r\n this._updateSecurityFeatures({\r\n hasEncryption: false,\r\n hasECDH: false,\r\n hasECDSA: false,\r\n hasMutualAuth: false,\r\n hasMetadataProtection: false,\r\n hasEnhancedReplayProtection: false,\r\n hasNonExtractableKeys: false,\r\n hasEnhancedValidation: false,\r\n hasPFS: false\r\n });\r\n \r\n // Schedule natural cleanup\r\n this._forceGarbageCollection().catch(error => {\r\n this._secureLog('error', 'Cleanup failed during offer cleanup', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n \r\n this._secureLog('debug', 'Failed offer creation cleanup completed with secure memory wipe');\r\n \r\n } catch (cleanupError) {\r\n this._secureLog('error', 'Error during offer creation cleanup', {\r\n errorType: cleanupError.constructor.name,\r\n errorMessage: cleanupError.message\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * HELPER: Atomic update of security features (if not added yet)\r\n */\r\n _updateSecurityFeatures(updates) {\r\n const oldFeatures = { ...this.securityFeatures };\r\n \r\n try {\r\n Object.assign(this.securityFeatures, updates);\r\n \r\n this._secureLog('debug', 'Security features updated', {\r\n updatedCount: Object.keys(updates).length,\r\n totalFeatures: Object.keys(this.securityFeatures).length\r\n });\r\n \r\n } catch (error) {\r\n // Roll back on error\r\n this.securityFeatures = oldFeatures;\r\n this._secureLog('error', 'Security features update failed, rolled back', {\r\n errorType: error.constructor.name\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * FULLY FIXED METHOD createSecureAnswer()\r\n * With race-condition protection and enhanced security\r\n */\r\n async createSecureAnswer(offerData) {\r\n return this._withMutex('connectionOperation', async (operationId) => {\r\n this._secureLog('info', 'Creating secure answer with mutex', {\r\n operationId: operationId,\r\n hasOfferData: !!offerData,\r\n offerType: offerData?.type,\r\n offerVersion: offerData?.version,\r\n offerTimestamp: offerData?.timestamp\r\n });\r\n \r\n try {\r\n // ============================================\r\n // PHASE 1: PRE-VALIDATION OF OFFER\r\n // ============================================\r\n \r\n // Reset notification flags for a new connection\r\n this._resetNotificationFlags();\r\n \r\n this._secureLog('debug', 'Starting enhanced offer validation', {\r\n operationId: operationId,\r\n hasOfferData: !!offerData,\r\n offerType: offerData?.type,\r\n hasECDHKey: !!offerData?.ecdhPublicKey,\r\n hasECDSAKey: !!offerData?.ecdsaPublicKey,\r\n hasSalt: !!offerData?.salt\r\n });\r\n \r\n // Strict input validation\r\n if (!this.validateEnhancedOfferData(offerData)) {\r\n throw new Error('Invalid connection data format - failed enhanced validation');\r\n }\r\n \r\n // Rate limiting check\r\n if (!window.EnhancedSecureCryptoUtils.rateLimiter.checkConnectionRate(this.rateLimiterId)) {\r\n throw new Error('Connection rate limit exceeded. Please wait before trying again.');\r\n }\r\n \r\n // ============================================\r\n // PHASE 2: SECURITY AND ANTI-REPLAY PROTECTION\r\n // ============================================\r\n \r\n // MITM Protection: Validate offer data structure (support both formats)\r\n const timestamp = offerData.ts || offerData.timestamp;\r\n const version = offerData.v || offerData.version;\r\n if (!timestamp || !version) {\r\n throw new Error('Missing required security fields in offer data \u2013 possible MITM attack');\r\n }\r\n \r\n // Replay attack protection (extended to 30 minutes for better UX)\r\n const offerAge = Date.now() - timestamp;\r\n const MAX_OFFER_AGE = 1800000; // 30 minutes for better user experience\r\n \r\n if (offerAge > MAX_OFFER_AGE) {\r\n this._secureLog('error', 'Offer data is too old - possible replay attack', {\r\n operationId: operationId,\r\n offerAge: Math.round(offerAge / 1000),\r\n maxAllowedAge: Math.round(MAX_OFFER_AGE / 1000),\r\n timestamp: offerData.timestamp\r\n });\r\n \r\n // Notify the main code about the replay attack\r\n if (this.onAnswerError) {\r\n this.onAnswerError('replay_attack', 'Offer data is too old \u2013 possible replay attack');\r\n }\r\n \r\n throw new Error('Offer data is too old \u2013 possible replay attack');\r\n }\r\n \r\n // Protocol version compatibility check (support both formats)\r\n const protocolVersion = version; // Use the version we already extracted\r\n if (protocolVersion !== '4.0') {\r\n this._secureLog('warn', 'Protocol version mismatch detected', {\r\n operationId: operationId,\r\n expectedVersion: '4.0',\r\n receivedVersion: protocolVersion\r\n });\r\n \r\n // For backward compatibility with v3.0, a fallback can be added\r\n if (protocolVersion !== '3.0') {\r\n throw new Error(`Unsupported protocol version: ${protocolVersion}`);\r\n }\r\n }\r\n \r\n // ============================================\r\n // PHASE 3: EXTRACT AND VALIDATE SESSION SALT\r\n // ============================================\r\n \r\n // Set session salt from offer (support both formats)\r\n this.sessionSalt = offerData.sl || offerData.salt;\r\n \r\n // Validate session salt\r\n if (!Array.isArray(this.sessionSalt)) {\r\n throw new Error('Invalid session salt format - must be array');\r\n }\r\n \r\n const expectedSaltLength = protocolVersion === '4.0' ? 64 : 32;\r\n if (this.sessionSalt.length !== expectedSaltLength) {\r\n throw new Error(`Invalid session salt length: expected ${expectedSaltLength}, got ${this.sessionSalt.length}`);\r\n }\r\n \r\n // MITM Protection: Check salt integrity\r\n const saltFingerprint = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(this.sessionSalt);\r\n \r\n this._secureLog('info', 'Session salt validated successfully', {\r\n operationId: operationId,\r\n saltLength: this.sessionSalt.length,\r\n saltFingerprint: saltFingerprint.substring(0, 8)\r\n });\r\n \r\n // ============================================\r\n // PHASE 4: SECURE GENERATION OF OUR KEYS\r\n // ============================================\r\n \r\n // Secure generation of our keys via mutex\r\n const keyPairs = await this._generateEncryptionKeys();\r\n this.ecdhKeyPair = keyPairs.ecdhKeyPair;\r\n this.ecdsaKeyPair = keyPairs.ecdsaKeyPair;\r\n \r\n // Additional validation of generated keys\r\n if (!(this.ecdhKeyPair?.privateKey instanceof CryptoKey)) {\r\n this._secureLog('error', 'Local ECDH private key is not a CryptoKey', {\r\n operationId: operationId,\r\n hasKeyPair: !!this.ecdhKeyPair,\r\n privateKeyType: typeof this.ecdhKeyPair?.privateKey,\r\n privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name\r\n });\r\n throw new Error('Local ECDH private key is not a valid CryptoKey');\r\n }\r\n \r\n // ============================================\r\n // PHASE 5: IMPORT AND VERIFY PEER KEYS\r\n // ============================================\r\n \r\n // Import peer ECDSA public key for signature verification (support both formats)\r\n let peerECDSAPublicKey;\r\n \r\n try {\r\n const ecdsaKey = offerData.d || offerData.ecdsaPublicKey;\r\n peerECDSAPublicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n new Uint8Array(ecdsaKey.keyData),\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-384'\r\n },\r\n false,\r\n ['verify']\r\n );\r\n } catch (error) {\r\n this._throwSecureError(error, 'ecdsa_key_import');\r\n }\r\n \r\n // ============================================\r\n // PHASE 6: IMPORT AND VERIFY ECDH KEY\r\n // ============================================\r\n \r\n // Import and verify ECDH public key using verified ECDSA key (support both formats)\r\n let peerECDHPublicKey;\r\n \r\n try {\r\n const ecdhKey = offerData.e || offerData.ecdhPublicKey;\r\n peerECDHPublicKey = await window.EnhancedSecureCryptoUtils.importSignedPublicKey(\r\n ecdhKey,\r\n peerECDSAPublicKey,\r\n 'ECDH'\r\n );\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to import signed ECDH public key', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._throwSecureError(error, 'ecdh_key_import');\r\n }\r\n \r\n // Final validation of ECDH key\r\n if (!(peerECDHPublicKey instanceof CryptoKey)) {\r\n this._secureLog('error', 'Peer ECDH public key is not a CryptoKey', {\r\n operationId: operationId,\r\n publicKeyType: typeof peerECDHPublicKey,\r\n publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name\r\n });\r\n throw new Error('Peer ECDH public key is not a valid CryptoKey');\r\n }\r\n \r\n // Save peer key for PFS rotation\r\n this.peerPublicKey = peerECDHPublicKey;\r\n \r\n // ============================================\r\n // PHASE 7: DERIVE SHARED ENCRYPTION KEYS\r\n // ============================================\r\n \r\n // Derive shared keys with metadata protection\r\n let derivedKeys;\r\n \r\n try {\r\n this._secureLog('debug', 'About to call deriveSharedKeys', {\r\n operationId: operationId,\r\n privateKeyType: typeof this.ecdhKeyPair.privateKey,\r\n publicKeyType: typeof peerECDHPublicKey,\r\n saltLength: this.sessionSalt?.length,\r\n privateKeyAlgorithm: this.ecdhKeyPair.privateKey?.algorithm?.name,\r\n publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name\r\n });\r\n \r\n derivedKeys = await window.EnhancedSecureCryptoUtils.deriveSharedKeys(\r\n this.ecdhKeyPair.privateKey,\r\n peerECDHPublicKey,\r\n this.sessionSalt\r\n );\r\n \r\n this._secureLog('debug', 'deriveSharedKeys completed successfully', {\r\n operationId: operationId,\r\n hasMessageKey: !!derivedKeys.messageKey,\r\n hasMacKey: !!derivedKeys.macKey,\r\n hasPfsKey: !!derivedKeys.pfsKey,\r\n hasMetadataKey: !!derivedKeys.metadataKey,\r\n hasFingerprint: !!derivedKeys.fingerprint\r\n });\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to derive shared keys', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n errorStack: error.stack,\r\n privateKeyType: typeof this.ecdhKeyPair.privateKey,\r\n publicKeyType: typeof peerECDHPublicKey,\r\n saltLength: this.sessionSalt?.length,\r\n privateKeyAlgorithm: this.ecdhKeyPair.privateKey?.algorithm?.name,\r\n publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name\r\n });\r\n this._throwSecureError(error, 'key_derivation');\r\n }\r\n \r\n // Securely set keys via helper\r\n await this._setEncryptionKeys(\r\n derivedKeys.messageKey,\r\n derivedKeys.macKey,\r\n derivedKeys.metadataKey,\r\n derivedKeys.fingerprint\r\n );\r\n \r\n // Additional validation of installed keys\r\n if (!(this.encryptionKey instanceof CryptoKey) || \r\n !(this.macKey instanceof CryptoKey) || \r\n !(this.metadataKey instanceof CryptoKey)) {\r\n \r\n this._secureLog('error', 'Invalid key types after derivation', {\r\n operationId: operationId,\r\n encryptionKeyType: typeof this.encryptionKey,\r\n macKeyType: typeof this.macKey,\r\n metadataKeyType: typeof this.metadataKey\r\n });\r\n throw new Error('Invalid key types after derivation');\r\n }\r\n \r\n // Set verification code from offer\r\n this.verificationCode = offerData.verificationCode;\r\n \r\n this._secureLog('info', 'Encryption keys derived and set successfully', {\r\n operationId: operationId,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n hasMetadataKey: !!this.metadataKey,\r\n hasKeyFingerprint: !!this.keyFingerprint,\r\n mitmProtection: 'enabled',\r\n signatureVerified: true\r\n });\r\n \r\n // ============================================\r\n // PHASE 8: UPDATE SECURITY FEATURES\r\n // ============================================\r\n \r\n // Atomic update of security features\r\n this._updateSecurityFeatures({\r\n hasEncryption: true,\r\n hasECDH: true,\r\n hasECDSA: true,\r\n hasMutualAuth: true,\r\n hasMetadataProtection: true,\r\n hasEnhancedReplayProtection: true,\r\n hasNonExtractableKeys: true,\r\n hasRateLimiting: true,\r\n hasEnhancedValidation: true,\r\n hasPFS: true\r\n });\r\n \r\n // PFS: Initialize key version tracking\r\n this.currentKeyVersion = 0;\r\n this.lastKeyRotation = Date.now();\r\n this.keyVersions.set(0, {\r\n salt: this.sessionSalt,\r\n timestamp: this.lastKeyRotation,\r\n messageCount: 0\r\n });\r\n \r\n // ============================================\r\n // PHASE 9: CREATE AUTHENTICATION PROOF\r\n // ============================================\r\n \r\n // Create proof for mutual authentication\r\n let authProof;\r\n \r\n if (offerData.authChallenge) {\r\n try {\r\n authProof = await window.EnhancedSecureCryptoUtils.createAuthProof(\r\n offerData.authChallenge,\r\n this.ecdsaKeyPair.privateKey,\r\n this.ecdsaKeyPair.publicKey\r\n );\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to create authentication proof', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n this._throwSecureError(error, 'authentication_proof_creation');\r\n }\r\n } else {\r\n this._secureLog('warn', 'No auth challenge in offer - mutual auth disabled', {\r\n operationId: operationId\r\n });\r\n }\r\n \r\n // ============================================\r\n // PHASE 10: INITIALIZE WEBRTC\r\n // ============================================\r\n \r\n this.isInitiator = false;\r\n this.onStatusChange('connecting');\r\n \r\n this.onKeyExchange(this.keyFingerprint);\r\n \r\n // Create peer connection first\r\n this.createPeerConnection();\r\n \r\n // Validate DTLS fingerprint before setting remote description\r\n if (this.strictDTLSValidation) {\r\n try {\r\n const receivedFingerprint = this._extractDTLSFingerprintFromSDP(offerData.sdp);\r\n \r\n if (this.expectedDTLSFingerprint) {\r\n await this._validateDTLSFingerprint(receivedFingerprint, this.expectedDTLSFingerprint, 'offer_validation');\r\n } else {\r\n // Store fingerprint for future validation (first connection)\r\n this.expectedDTLSFingerprint = receivedFingerprint;\r\n this._secureLog('info', 'Stored DTLS fingerprint for future validation', {\r\n fingerprint: receivedFingerprint,\r\n context: 'first_connection'\r\n });\r\n }\r\n } catch (error) {\r\n this._secureLog('warn', 'DTLS fingerprint validation failed - continuing in fallback mode', { \r\n error: error.message,\r\n context: 'offer_validation'\r\n });\r\n // Continue without strict fingerprint validation for first connection\r\n // This allows the connection to proceed while maintaining security awareness\r\n }\r\n } else {\r\n this._secureLog('info', 'DTLS fingerprint validation disabled - proceeding without validation');\r\n }\r\n\r\n // Set remote description from offer\r\n try {\r\n this._secureLog('debug', 'Setting remote description from offer', {\r\n operationId: operationId,\r\n sdpLength: offerData.sdp?.length || 0\r\n });\r\n \r\n await this.peerConnection.setRemoteDescription(new RTCSessionDescription({\r\n type: 'offer',\r\n sdp: offerData.s || offerData.sdp\r\n }));\r\n \r\n this._secureLog('debug', 'Remote description set successfully', {\r\n operationId: operationId,\r\n signalingState: this.peerConnection.signalingState\r\n });\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to set remote description', { \r\n error: error.message,\r\n operationId: operationId\r\n });\r\n this._throwSecureError(error, 'webrtc_remote_description');\r\n }\r\n \r\n this._secureLog('debug', 'Remote description set successfully', {\r\n operationId: operationId,\r\n connectionState: this.peerConnection.connectionState,\r\n signalingState: this.peerConnection.signalingState\r\n });\r\n \r\n // ============================================\r\n // PHASE 11: CREATE SDP ANSWER\r\n // ============================================\r\n \r\n // Create WebRTC answer\r\n let answer;\r\n \r\n try {\r\n answer = await this.peerConnection.createAnswer({\r\n offerToReceiveAudio: false,\r\n offerToReceiveVideo: false\r\n });\r\n } catch (error) {\r\n this._throwSecureError(error, 'webrtc_create_answer');\r\n }\r\n \r\n // Set local description\r\n try {\r\n await this.peerConnection.setLocalDescription(answer);\r\n } catch (error) {\r\n this._throwSecureError(error, 'webrtc_local_description');\r\n }\r\n \r\n // Extract and store our DTLS fingerprint for out-of-band verification\r\n try {\r\n const ourFingerprint = this._extractDTLSFingerprintFromSDP(answer.sdp);\r\n this.expectedDTLSFingerprint = ourFingerprint;\r\n \r\n this._secureLog('info', 'Generated DTLS fingerprint for out-of-band verification', {\r\n fingerprint: ourFingerprint,\r\n context: 'answer_creation'\r\n });\r\n \r\n // Notify UI that fingerprint is ready for out-of-band verification\r\n this.deliverMessageToUI(`DTLS fingerprint ready for verification: ${ourFingerprint}`, 'system');\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to extract DTLS fingerprint from answer', { error: error.message });\r\n // Continue without fingerprint validation (fallback mode)\r\n }\r\n \r\n \r\n // Await ICE gathering\r\n await this.waitForIceGathering();\r\n \r\n this._secureLog('debug', 'ICE gathering completed for answer', {\r\n operationId: operationId,\r\n iceGatheringState: this.peerConnection.iceGatheringState,\r\n connectionState: this.peerConnection.connectionState\r\n });\r\n \r\n // ============================================\r\n // PHASE 12: EXPORT OUR KEYS\r\n // ============================================\r\n \r\n // Export our keys with signatures\r\n const ecdhPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdhKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDH'\r\n );\r\n \r\n const ecdsaPublicKeyData = await window.EnhancedSecureCryptoUtils.exportPublicKeyWithSignature(\r\n this.ecdsaKeyPair.publicKey,\r\n this.ecdsaKeyPair.privateKey,\r\n 'ECDSA'\r\n );\r\n \r\n if (!ecdhPublicKeyData || typeof ecdhPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDH key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdhPublicKeyData.keyData || !ecdhPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdhPublicKeyData.keyData,\r\n hasSignature: !!ecdhPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key export incomplete - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData || typeof ecdsaPublicKeyData !== 'object') {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export failed - invalid object structure', { operationId });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export validation failed - hard abort required');\r\n }\r\n \r\n if (!ecdsaPublicKeyData.keyData || !ecdsaPublicKeyData.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key export incomplete - missing keyData or signature', { \r\n operationId,\r\n hasKeyData: !!ecdsaPublicKeyData.keyData,\r\n hasSignature: !!ecdsaPublicKeyData.signature \r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key export incomplete - hard abort required');\r\n }\r\n \r\n // ============================================\r\n // PHASE 13: SECURITY LEVEL CALCULATION\r\n // ============================================\r\n \r\n // All security features are enabled by default\r\n const securityLevel = {\r\n level: 'MAXIMUM',\r\n score: 100,\r\n color: 'green',\r\n details: 'All security features enabled by default',\r\n passedChecks: 10,\r\n totalChecks: 10,\r\n isRealData: true\r\n };\r\n \r\n // ============================================\r\n // PHASE 14: CREATE ANSWER PACKAGE\r\n // ============================================\r\n \r\n const currentTimestamp = Date.now();\r\n \r\n // Create compact answer package for smaller QR codes\r\n const answerPackage = {\r\n // Core information (minimal)\r\n t: 'answer', // type\r\n s: this.peerConnection.localDescription.sdp, // sdp\r\n v: '4.0', // version\r\n ts: currentTimestamp, // timestamp\r\n \r\n // Cryptographic keys (essential)\r\n e: ecdhPublicKeyData, // ecdhPublicKey\r\n d: ecdsaPublicKeyData, // ecdsaPublicKey\r\n \r\n // Authentication (essential)\r\n ap: authProof, // authProof\r\n \r\n // Security metadata (simplified)\r\n slv: 'MAX', // securityLevel\r\n \r\n // Session confirmation (simplified)\r\n sc: {\r\n sf: saltFingerprint.substring(0, 12), // saltFingerprint (12 chars)\r\n kd: true, // keyDerivationSuccess\r\n ma: true // mutualAuthEnabled\r\n }\r\n };\r\n \r\n // ============================================\r\n // PHASE 15: VALIDATION AND LOGGING\r\n // ============================================\r\n \r\n // Final validation of the answer package (support both formats)\r\n const hasSDP = answerPackage.s || answerPackage.sdp;\r\n const hasECDH = answerPackage.e || answerPackage.ecdhPublicKey;\r\n const hasECDSA = answerPackage.d || answerPackage.ecdsaPublicKey;\r\n \r\n if (!hasSDP || !hasECDH || !hasECDSA) {\r\n throw new Error('Generated answer package is incomplete');\r\n }\r\n \r\n this._secureLog('info', 'Enhanced secure answer created successfully', {\r\n operationId: operationId,\r\n version: answerPackage.version,\r\n hasECDSA: true,\r\n hasMutualAuth: !!authProof,\r\n hasSessionConfirmation: !!answerPackage.sessionConfirmation,\r\n securityLevel: securityLevel.level,\r\n timestamp: currentTimestamp,\r\n processingTime: currentTimestamp - offerData.timestamp\r\n });\r\n \r\n // Dispatch event about new connection\r\n document.dispatchEvent(new CustomEvent('new-connection', {\r\n detail: { \r\n type: 'answer',\r\n timestamp: currentTimestamp,\r\n securityLevel: securityLevel.level,\r\n operationId: operationId\r\n }\r\n }));\r\n \r\n // ============================================\r\n // PHASE 16: SCHEDULE SECURITY CALCULATIONS\r\n // ============================================\r\n \r\n // Plan security calculation after connection\r\n setTimeout(async () => {\r\n try {\r\n const realSecurityData = await this.calculateAndReportSecurityLevel();\r\n if (realSecurityData) {\r\n this.notifySecurityUpdate();\r\n this._secureLog('info', 'Post-connection security level calculated', {\r\n operationId: operationId,\r\n level: realSecurityData.level\r\n });\r\n }\r\n } catch (error) {\r\n this._secureLog('error', 'Error calculating post-connection security', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n }\r\n }, 1000);\r\n \r\n // Retry if the first calculation fails\r\n setTimeout(async () => {\r\n if (!this.lastSecurityCalculation || this.lastSecurityCalculation.score < 50) {\r\n this._secureLog('info', 'Retrying security calculation', {\r\n operationId: operationId\r\n });\r\n await this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpdate();\r\n }\r\n }, 3000);\r\n \r\n // Final security update\r\n this.notifySecurityUpdate();\r\n \r\n // ============================================\r\n // PHASE 17: RETURN RESULT\r\n // ============================================\r\n \r\n return answerPackage;\r\n \r\n } catch (error) {\r\n // ============================================\r\n // ERROR HANDLING\r\n // ============================================\r\n \r\n this._secureLog('error', 'Enhanced secure answer creation failed in critical section', {\r\n operationId: operationId,\r\n errorType: error.constructor.name,\r\n errorMessage: error.message,\r\n phase: this._determineAnswerErrorPhase(error),\r\n offerAge: offerData?.timestamp ? Date.now() - offerData.timestamp : 'unknown'\r\n });\r\n \r\n // Cleanup state on error\r\n this._cleanupFailedAnswerCreation();\r\n \r\n // Update status\r\n this.onStatusChange('disconnected');\r\n \r\n // Special handling of security errors\r\n if (this.onAnswerError) {\r\n if (error.message.includes('too old') || error.message.includes('replay')) {\r\n this.onAnswerError('replay_attack', error.message);\r\n } else if (error.message.includes('MITM') || error.message.includes('signature')) {\r\n this.onAnswerError('security_violation', error.message);\r\n } else if (error.message.includes('validation') || error.message.includes('format')) {\r\n this.onAnswerError('invalid_format', error.message);\r\n } else {\r\n this.onAnswerError('general_error', error.message);\r\n }\r\n }\r\n \r\n // Re-throw for upper-level handling\r\n throw error;\r\n }\r\n }, 20000); // 20 seconds timeout for the entire answer creation (longer than offer)\r\n }\r\n\r\n /**\r\n * HELPER: Determine error phase for answer\r\n */\r\n _determineAnswerErrorPhase(error) {\r\n const message = error.message.toLowerCase();\r\n \r\n if (message.includes('validation') || message.includes('format')) return 'offer_validation';\r\n if (message.includes('rate limit')) return 'rate_limiting';\r\n if (message.includes('replay') || message.includes('too old')) return 'replay_protection';\r\n if (message.includes('salt')) return 'salt_validation';\r\n if (message.includes('key pair') || message.includes('generate')) return 'key_generation';\r\n if (message.includes('import') || message.includes('ecdsa') || message.includes('ecdh')) return 'key_import';\r\n if (message.includes('signature') || message.includes('mitm')) return 'signature_verification';\r\n if (message.includes('derive') || message.includes('shared')) return 'key_derivation';\r\n if (message.includes('auth') || message.includes('proof')) return 'authentication';\r\n if (message.includes('remote description') || message.includes('local description')) return 'webrtc_setup';\r\n if (message.includes('answer') || message.includes('sdp')) return 'sdp_creation';\r\n if (message.includes('export')) return 'key_export';\r\n if (message.includes('security level')) return 'security_calculation';\r\n \r\n return 'unknown';\r\n }\r\n\r\n /**\r\n * HELPER: Cleanup state after failed answer creation\r\n */\r\n /**\r\n * Secure cleanup state after failed answer creation\r\n */\r\n _cleanupFailedAnswerCreation() {\r\n try {\r\n // Secure wipe of cryptographic materials\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Secure wipe of PFS key versions\r\n this.currentKeyVersion = 0;\r\n this.keyVersions.clear();\r\n this.oldKeys.clear();\r\n \r\n // Close peer connection if created\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Clear data channel\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n \r\n // Reset flags and counters\r\n this.isInitiator = false;\r\n this.isVerified = false;\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.messageCounter = 0;\r\n this.processedMessageIds.clear();\r\n this.replayWindow.clear(); // Clear replay window\r\n \r\n // Reset security features to baseline\r\n this._updateSecurityFeatures({\r\n hasEncryption: false,\r\n hasECDH: false,\r\n hasECDSA: false,\r\n hasMutualAuth: false,\r\n hasMetadataProtection: false,\r\n hasEnhancedReplayProtection: false,\r\n hasNonExtractableKeys: false,\r\n hasEnhancedValidation: false,\r\n hasPFS: false\r\n });\r\n \r\n // Schedule natural cleanup\r\n this._forceGarbageCollection().catch(error => {\r\n this._secureLog('error', 'Cleanup failed during answer cleanup', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n \r\n this._secureLog('debug', 'Failed answer creation cleanup completed with secure memory wipe');\r\n \r\n } catch (cleanupError) {\r\n this._secureLog('error', 'Error during answer creation cleanup', {\r\n errorType: cleanupError.constructor.name,\r\n errorMessage: cleanupError.message\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * HELPER: Securely set encryption keys (if not set yet)\r\n */\r\n async _setEncryptionKeys(encryptionKey, macKey, metadataKey, keyFingerprint) {\r\n return this._withMutex('keyOperation', async (operationId) => {\r\n this._secureLog('info', 'Setting encryption keys with mutex', {\r\n operationId: operationId\r\n });\r\n \r\n // Validate all keys before setting\r\n if (!(encryptionKey instanceof CryptoKey) ||\r\n !(macKey instanceof CryptoKey) ||\r\n !(metadataKey instanceof CryptoKey)) {\r\n throw new Error('Invalid key types provided');\r\n }\r\n \r\n if (!keyFingerprint || typeof keyFingerprint !== 'string') {\r\n throw new Error('Invalid key fingerprint provided');\r\n }\r\n \r\n // Atomically set all keys\r\n const oldKeys = {\r\n encryptionKey: this.encryptionKey,\r\n macKey: this.macKey,\r\n metadataKey: this.metadataKey,\r\n keyFingerprint: this.keyFingerprint\r\n };\r\n \r\n try {\r\n this.encryptionKey = encryptionKey;\r\n this.macKey = macKey;\r\n this.metadataKey = metadataKey;\r\n this.keyFingerprint = keyFingerprint;\r\n \r\n // Reset counters\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.messageCounter = 0;\r\n this.processedMessageIds.clear();\r\n this.replayWindow.clear(); // Clear replay window\r\n \r\n this._secureLog('info', 'Encryption keys set successfully', {\r\n operationId: operationId,\r\n hasAllKeys: !!(this.encryptionKey && this.macKey && this.metadataKey),\r\n hasFingerprint: !!this.keyFingerprint\r\n });\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n // Roll back on error\r\n this.encryptionKey = oldKeys.encryptionKey;\r\n this.macKey = oldKeys.macKey;\r\n this.metadataKey = oldKeys.metadataKey;\r\n this.keyFingerprint = oldKeys.keyFingerprint;\r\n \r\n this._secureLog('error', 'Key setting failed, rolled back', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n \r\n throw error;\r\n }\r\n });\r\n }\r\n\r\n async handleSecureAnswer(answerData) {\r\n try {\r\n \r\n if (!answerData || typeof answerData !== 'object' || Array.isArray(answerData)) {\r\n this._secureLog('error', 'CRITICAL: Invalid answer data structure', { \r\n hasAnswerData: !!answerData,\r\n answerDataType: typeof answerData,\r\n isArray: Array.isArray(answerData)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Answer data must be a non-null object');\r\n }\r\n \r\n // Support both compact and legacy answer formats\r\n const isCompactAnswer = answerData.t === 'answer' && answerData.s;\r\n const isLegacyAnswer = answerData.type === 'enhanced_secure_answer' && answerData.sdp;\r\n \r\n if (!isCompactAnswer && !isLegacyAnswer) {\r\n this._secureLog('error', 'CRITICAL: Invalid answer format', { \r\n type: answerData.type || answerData.t,\r\n hasSdp: !!(answerData.sdp || answerData.s)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid answer format - hard abort required');\r\n }\r\n\r\n // CRITICAL: Strict validation of ECDH public key structure\r\n // Support both full and compact key names\r\n const ecdhKey = answerData.ecdhPublicKey || answerData.e;\r\n const ecdsaKey = answerData.ecdsaPublicKey || answerData.d;\r\n \r\n if (!ecdhKey || typeof ecdhKey !== 'object' || Array.isArray(ecdhKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDH public key structure in answer', { \r\n hasEcdhKey: !!ecdhKey,\r\n ecdhKeyType: typeof ecdhKey,\r\n isArray: Array.isArray(ecdhKey),\r\n availableKeys: Object.keys(answerData)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Missing or invalid ECDH public key structure');\r\n }\r\n \r\n if (!ecdhKey.keyData || !ecdhKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key missing keyData or signature in answer', { \r\n hasKeyData: !!ecdhKey.keyData,\r\n hasSignature: !!ecdhKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key missing keyData or signature');\r\n }\r\n\r\n // CRITICAL: Strict validation of ECDSA public key structure\r\n if (!ecdsaKey || typeof ecdsaKey !== 'object' || Array.isArray(ecdsaKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDSA public key structure in answer', { \r\n hasEcdsaKey: !!ecdsaKey,\r\n ecdsaKeyType: typeof ecdsaKey,\r\n isArray: Array.isArray(ecdsaKey)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Missing or invalid ECDSA public key structure');\r\n }\r\n \r\n if (!ecdsaKey.keyData || !ecdsaKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key missing keyData or signature in answer', { \r\n hasKeyData: !!ecdsaKey.keyData,\r\n hasSignature: !!ecdsaKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key missing keyData or signature');\r\n }\r\n\r\n // Additional MITM protection: Validate answer data structure\r\n // Support both compact and legacy formats\r\n const timestamp = answerData.ts || answerData.timestamp;\r\n const version = answerData.v || answerData.version;\r\n \r\n if (!timestamp || !version) {\r\n throw new Error('Missing required fields in response data \u2013 possible MITM attack');\r\n }\r\n\r\n // MITM Protection: Verify session ID if present (for enhanced security)\r\n if (answerData.sessionId && this.sessionId && answerData.sessionId !== this.sessionId) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Session ID mismatch detected - possible MITM attack', {\r\n expectedSessionIdHash: await this._createSafeLogHash(this.sessionId, 'session_id'),\r\n receivedSessionIdHash: await this._createSafeLogHash(answerData.sessionId, 'session_id')\r\n });\r\n throw new Error('Session ID mismatch \u2013 possible MITM attack');\r\n }\r\n\r\n // Check for replay attacks (reject answers older than 1 hour)\r\n const answerAge = Date.now() - answerData.timestamp;\r\n if (answerAge > 3600000) { // 1 hour in milliseconds\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Answer data is too old - possible replay attack', {\r\n answerAge: answerAge,\r\n timestamp: answerData.timestamp\r\n });\r\n \r\n // Notify the main code about the replay attack error\r\n if (this.onAnswerError) {\r\n this.onAnswerError('replay_attack', 'Response data is too old \u2013 possible replay attack');\r\n }\r\n \r\n throw new Error('Response data is too old \u2013 possible replay attack');\r\n }\r\n\r\n // Check protocol version compatibility\r\n if (answerData.version !== '4.0') {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('warn', 'Incompatible protocol version in answer', {\r\n expectedVersion: '4.0',\r\n receivedVersion: answerData.version\r\n });\r\n }\r\n\r\n // Import ECDSA public key for verification (self-signed)\r\n const peerECDSAPublicKey = await crypto.subtle.importKey(\r\n 'spki',\r\n new Uint8Array(ecdsaKey.keyData),\r\n {\r\n name: 'ECDSA',\r\n namedCurve: 'P-384'\r\n },\r\n false,\r\n ['verify']\r\n );\r\n\r\n\r\n // Now import and verify the ECDH public key using the verified ECDSA key\r\n const peerPublicKey = await window.EnhancedSecureCryptoUtils.importPublicKeyFromSignedPackage(\r\n ecdhKey,\r\n peerECDSAPublicKey\r\n );\r\n \r\n // Additional MITM protection: Verify session salt integrity\r\n if (!this.sessionSalt || this.sessionSalt.length !== 64) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Invalid session salt detected - possible session hijacking', {\r\n saltLength: this.sessionSalt ? this.sessionSalt.length : 0\r\n });\r\n throw new Error('Invalid session salt \u2013 possible session hijacking attempt');\r\n }\r\n\r\n // Verify that the session salt hasn't been tampered with\r\n const expectedSaltHash = await window.EnhancedSecureCryptoUtils.calculateKeyFingerprint(this.sessionSalt);\r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Session salt integrity verified', {\r\n saltFingerprint: expectedSaltHash.substring(0, 8)\r\n });\r\n\r\n // Additional validation: Ensure all keys are CryptoKey instances before derivation\r\n if (!(this.ecdhKeyPair?.privateKey instanceof CryptoKey)) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Local ECDH private key is not a CryptoKey in handleSecureAnswer', {\r\n hasKeyPair: !!this.ecdhKeyPair,\r\n privateKeyType: typeof this.ecdhKeyPair?.privateKey,\r\n privateKeyAlgorithm: this.ecdhKeyPair?.privateKey?.algorithm?.name\r\n });\r\n throw new Error('Local ECDH private key is not a CryptoKey');\r\n }\r\n \r\n if (!(peerPublicKey instanceof CryptoKey)) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Peer ECDH public key is not a CryptoKey in handleSecureAnswer', {\r\n publicKeyType: typeof peerPublicKey,\r\n publicKeyAlgorithm: peerPublicKey?.algorithm?.name\r\n });\r\n throw new Error('Peer ECDH public key is not a CryptoKey');\r\n }\r\n\r\n // Store peer's public key for PFS key rotation\r\n this.peerPublicKey = peerPublicKey;\r\n \r\n // Initialize connection ID if not already set\r\n if (!this.connectionId) {\r\n this.connectionId = Array.from(crypto.getRandomValues(new Uint8Array(8)))\r\n .map(b => b.toString(16).padStart(2, '0')).join('');\r\n }\r\n\r\n \r\n const derivedKeys = await window.EnhancedSecureCryptoUtils.deriveSharedKeys(\r\n this.ecdhKeyPair.privateKey,\r\n peerPublicKey,\r\n this.sessionSalt\r\n );\r\n \r\n this.encryptionKey = derivedKeys.messageKey;\r\n this.macKey = derivedKeys.macKey;\r\n this.metadataKey = derivedKeys.metadataKey;\r\n this.keyFingerprint = derivedKeys.fingerprint;\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.messageCounter = 0;\r\n this.processedMessageIds.clear();\r\n this.replayWindow.clear(); // Clear replay window\r\n // Validate that all keys are properly set\r\n if (!(this.encryptionKey instanceof CryptoKey) || \r\n !(this.macKey instanceof CryptoKey) || \r\n !(this.metadataKey instanceof CryptoKey)) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Invalid key types after derivation in handleSecureAnswer', {\r\n encryptionKeyType: typeof this.encryptionKey,\r\n macKeyType: typeof this.macKey,\r\n metadataKeyType: typeof this.metadataKey,\r\n encryptionKeyAlgorithm: this.encryptionKey?.algorithm?.name,\r\n macKeyAlgorithm: this.macKey?.algorithm?.name,\r\n metadataKeyAlgorithm: this.metadataKey?.algorithm?.name\r\n });\r\n throw new Error('Invalid key types after export');\r\n }\r\n \r\n this._secureLog('info', 'Encryption keys set in handleSecureAnswer', {\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n hasMetadataKey: !!this.metadataKey,\r\n hasKeyFingerprint: !!this.keyFingerprint,\r\n mitmProtection: 'enabled',\r\n signatureVerified: true\r\n });\r\n \r\n // Update security features for initiator after successful key exchange\r\n this.securityFeatures.hasMutualAuth = true;\r\n this.securityFeatures.hasMetadataProtection = true;\r\n this.securityFeatures.hasEnhancedReplayProtection = true;\r\n this.securityFeatures.hasPFS = true;\r\n \r\n // PFS: Initialize key version tracking\r\n this.currentKeyVersion = 0;\r\n this.lastKeyRotation = Date.now();\r\n this.keyVersions.set(0, {\r\n salt: this.sessionSalt,\r\n timestamp: this.lastKeyRotation,\r\n messageCount: 0\r\n });\r\n \r\n this.onKeyExchange(this.keyFingerprint);\r\n\r\n // Compute SAS for MITM protection (Offer side - Answer handler)\r\n try {\r\n const remoteFP = this._extractDTLSFingerprintFromSDP(answerData.sdp || answerData.s); \r\n const localFP = this.expectedDTLSFingerprint; \r\n const keyBytes = this._decodeKeyFingerprint(this.keyFingerprint); \r\n\r\n this.verificationCode = await this._computeSAS(keyBytes, localFP, remoteFP);\r\n this.onStatusChange?.('verifying'); \r\n this.onVerificationRequired(this.verificationCode);\r\n \r\n // CRITICAL: Store SAS code to send when data channel opens\r\n this.pendingSASCode = this.verificationCode;\r\n \r\n this._secureLog('info', 'SAS verification code generated for MITM protection (Offer side)', {\r\n sasCode: this.verificationCode,\r\n localFP: localFP.substring(0, 16) + '...',\r\n remoteFP: remoteFP.substring(0, 16) + '...',\r\n timestamp: Date.now()\r\n });\r\n } catch (sasError) {\r\n this._secureLog('error', 'SAS computation failed in handleSecureAnswer (Offer side)', {\r\n errorType: sasError?.constructor?.name || 'Unknown'\r\n });\r\n this._secureLog('error', 'SAS computation failed in handleSecureAnswer (Offer side)', {\r\n error: sasError.message,\r\n stack: sasError.stack,\r\n timestamp: Date.now()\r\n });\r\n }\r\n\r\n // Validate DTLS fingerprint before setting remote description\r\n if (this.strictDTLSValidation) {\r\n try {\r\n const receivedFingerprint = this._extractDTLSFingerprintFromSDP(answerData.sdp || answerData.s);\r\n \r\n if (this.expectedDTLSFingerprint) {\r\n await this._validateDTLSFingerprint(receivedFingerprint, this.expectedDTLSFingerprint, 'answer_validation');\r\n } else {\r\n // Store fingerprint for future validation (first connection)\r\n this.expectedDTLSFingerprint = receivedFingerprint;\r\n this._secureLog('info', 'Stored DTLS fingerprint for future validation', {\r\n fingerprint: receivedFingerprint,\r\n context: 'first_connection'\r\n });\r\n }\r\n } catch (error) {\r\n this._secureLog('warn', 'DTLS fingerprint validation failed - continuing in fallback mode', { \r\n error: error.message,\r\n context: 'answer_validation'\r\n });\r\n\r\n }\r\n } else {\r\n this._secureLog('info', 'DTLS fingerprint validation disabled - proceeding without validation');\r\n }\r\n\r\n // Support both full and compact SDP field names\r\n const sdpData = answerData.sdp || answerData.s;\r\n \r\n this._secureLog('debug', 'Setting remote description from answer', {\r\n sdpLength: sdpData?.length || 0,\r\n usingCompactSDP: !answerData.sdp && !!answerData.s\r\n });\r\n \r\n await this.peerConnection.setRemoteDescription({\r\n type: 'answer',\r\n sdp: sdpData\r\n });\r\n \r\n this._secureLog('debug', 'Remote description set successfully from answer', {\r\n signalingState: this.peerConnection.signalingState\r\n });\r\n\r\n setTimeout(async () => {\r\n try {\r\n const securityData = await this.calculateAndReportSecurityLevel();\r\n if (securityData) {\r\n this.notifySecurityUpdate();\r\n }\r\n } catch (error) {\r\n this._secureLog('error', 'Error calculating security after connection:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }, 1000);\r\n setTimeout(async () => {\r\n if (!this.lastSecurityCalculation || this.lastSecurityCalculation.score < 50) {\r\n await this.calculateAndReportSecurityLevel();\r\n this.notifySecurityUpdate();\r\n }\r\n }, 3000);\r\n this.notifySecurityUpdate();\r\n } catch (error) {\r\n this._secureLog('error', 'Enhanced secure answer handling failed', {\r\n errorType: error.constructor.name\r\n });\r\n this.onStatusChange('failed');\r\n\r\n if (this.onAnswerError) {\r\n if (error.message.includes('too old') || error.message.includes('\u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0441\u0442\u0430\u0440\u044B\u0435')) {\r\n this.onAnswerError('replay_attack', error.message);\r\n } else if (error.message.includes('MITM') || error.message.includes('signature') || error.message.includes('\u043F\u043E\u0434\u043F\u0438\u0441\u044C')) {\r\n this.onAnswerError('security_violation', error.message);\r\n } else {\r\n this.onAnswerError('general_error', error.message);\r\n }\r\n }\r\n \r\n throw error;\r\n }\r\n }\r\n\r\n\r\n initiateVerification() {\r\n \r\n if (this.isInitiator) {\r\n // Ensure verification initiation notice wasn't already sent\r\n if (!this.verificationInitiationSent) {\r\n this.verificationInitiationSent = true;\r\n this.deliverMessageToUI('CRITICAL: Compare verification code with peer out-of-band (voice/video/in-person) to prevent MITM attack!', 'system');\r\n this.deliverMessageToUI(`Your verification code: ${this.verificationCode}`, 'system');\r\n this.deliverMessageToUI('Ask peer to confirm this exact code before allowing traffic!', 'system');\r\n }\r\n } else {\r\n\r\n this.deliverMessageToUI('Waiting for verification code from peer...', 'system');\r\n }\r\n }\r\n\r\n confirmVerification() {\r\n \r\n try {\r\n \r\n // Mark local verification as confirmed\r\n this.localVerificationConfirmed = true;\r\n \r\n // Send confirmation to peer\r\n const confirmationPayload = {\r\n type: 'verification_confirmed',\r\n data: {\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS',\r\n securityLevel: 'MITM_PROTECTION_REQUIRED'\r\n }\r\n };\r\n\r\n this.dataChannel.send(JSON.stringify(confirmationPayload));\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Check if both parties have confirmed\r\n this._checkBothVerificationsConfirmed();\r\n \r\n // Notify UI about local confirmation\r\n this.deliverMessageToUI('You confirmed the verification code. Waiting for peer confirmation...', 'system');\r\n \r\n this.processMessageQueue();\r\n } catch (error) {\r\n this._secureLog('error', 'SAS verification failed:', { errorType: error?.constructor?.name || 'Unknown' });\r\n this.deliverMessageToUI('SAS verification failed', 'system');\r\n }\r\n }\r\n\r\n _checkBothVerificationsConfirmed() {\r\n // Check if both parties have confirmed verification\r\n if (this.localVerificationConfirmed && this.remoteVerificationConfirmed && !this.bothVerificationsConfirmed) {\r\n this.bothVerificationsConfirmed = true;\r\n \r\n // Notify both parties that verification is complete\r\n const bothConfirmedPayload = {\r\n type: 'verification_both_confirmed',\r\n data: {\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS',\r\n securityLevel: 'MITM_PROTECTION_COMPLETE'\r\n }\r\n };\r\n\r\n this.dataChannel.send(JSON.stringify(bothConfirmedPayload));\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Set verified status and open chat after 2 second delay\r\n this.deliverMessageToUI('Both parties confirmed! Opening secure chat in 2 seconds...', 'system');\r\n \r\n setTimeout(() => {\r\n this._setVerifiedStatus(true, 'MUTUAL_SAS_CONFIRMED', { \r\n code: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n this._enforceVerificationGate('mutual_confirmed', false);\r\n this.onStatusChange?.('verified');\r\n }, 2000);\r\n }\r\n }\r\n\r\n handleVerificationConfirmed(data) {\r\n this.remoteVerificationConfirmed = true;\r\n \r\n // Notify UI about peer confirmation\r\n this.deliverMessageToUI('Peer confirmed the verification code. Waiting for your confirmation...', 'system');\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Check if both parties have confirmed\r\n this._checkBothVerificationsConfirmed();\r\n }\r\n\r\n handleVerificationBothConfirmed(data) {\r\n // Handle notification that both parties have confirmed\r\n this.bothVerificationsConfirmed = true;\r\n \r\n // Notify UI about state change\r\n if (this.onVerificationStateChange) {\r\n this.onVerificationStateChange({\r\n localConfirmed: this.localVerificationConfirmed,\r\n remoteConfirmed: this.remoteVerificationConfirmed,\r\n bothConfirmed: this.bothVerificationsConfirmed\r\n });\r\n }\r\n \r\n // Set verified status and open chat after 2 second delay\r\n this.deliverMessageToUI('Both parties confirmed! Opening secure chat in 2 seconds...', 'system');\r\n \r\n setTimeout(() => {\r\n this._setVerifiedStatus(true, 'MUTUAL_SAS_CONFIRMED', { \r\n code: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n this._enforceVerificationGate('mutual_confirmed', false);\r\n this.onStatusChange?.('verified');\r\n }, 2000);\r\n }\r\n\r\n handleVerificationRequest(data) {\r\n\r\n \r\n if (data.code === this.verificationCode) {\r\n const responsePayload = {\r\n type: 'verification_response',\r\n data: {\r\n ok: true,\r\n timestamp: Date.now(),\r\n verificationMethod: 'SAS', // Indicate SAS was used\r\n securityLevel: 'MITM_PROTECTED'\r\n }\r\n };\r\n this.dataChannel.send(JSON.stringify(responsePayload));\r\n \r\n // Ensure verification success notice wasn't already sent\r\n if (!this.verificationNotificationSent) {\r\n this.verificationNotificationSent = true;\r\n this.deliverMessageToUI('SAS verification successful! MITM protection confirmed. Channel is now secure!', 'system');\r\n }\r\n \r\n this.processMessageQueue();\r\n } else {\r\n // SAS verification failed - possible MITM attack\r\n const responsePayload = {\r\n type: 'verification_response',\r\n data: {\r\n ok: false,\r\n timestamp: Date.now(),\r\n reason: 'code_mismatch'\r\n }\r\n };\r\n this.dataChannel.send(JSON.stringify(responsePayload));\r\n \r\n this._secureLog('error', 'SAS verification failed - possible MITM attack', {\r\n receivedCode: data.code,\r\n expectedCode: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n \r\n this.deliverMessageToUI('SAS verification failed! Possible MITM attack detected. Connection aborted for safety!', 'system');\r\n this.disconnect();\r\n }\r\n }\r\n\r\n handleSASCode(data) {\r\n\r\n \r\n this.verificationCode = data.code;\r\n this.onStatusChange?.('verifying'); \r\n this.onVerificationRequired(this.verificationCode);\r\n \r\n this._secureLog('info', 'SAS code received from Offer side', {\r\n sasCode: this.verificationCode,\r\n timestamp: Date.now()\r\n });\r\n }\r\n\r\n handleVerificationResponse(data) {\r\n \r\n if (data.ok === true) {\r\n \r\n // Log successful mutual SAS verification\r\n this._secureLog('info', 'Mutual SAS verification completed - MITM protection active', {\r\n verificationMethod: data.verificationMethod || 'SAS',\r\n securityLevel: data.securityLevel || 'MITM_PROTECTED',\r\n timestamp: Date.now()\r\n });\r\n \r\n // Ensure verification success notice wasn't already sent\r\n if (!this.verificationNotificationSent) {\r\n this.verificationNotificationSent = true;\r\n this.deliverMessageToUI(' Mutual SAS verification complete! MITM protection active. Channel is now secure!', 'system');\r\n }\r\n \r\n this.processMessageQueue();\r\n } else {\r\n // Peer verification failed - connection not secure\r\n this._secureLog('error', 'Peer SAS verification failed - connection not secure', {\r\n responseData: data,\r\n timestamp: Date.now()\r\n });\r\n \r\n this.deliverMessageToUI('Peer verification failed! Connection not secure!', 'system');\r\n this.disconnect();\r\n }\r\n }\r\n\r\n validateOfferData(offerData) {\r\n return offerData &&\r\n offerData.type === 'enhanced_secure_offer' &&\r\n offerData.sdp &&\r\n offerData.publicKey &&\r\n offerData.salt &&\r\n offerData.verificationCode &&\r\n Array.isArray(offerData.publicKey) &&\r\n Array.isArray(offerData.salt) &&\r\n offerData.salt.length === 32;\r\n }\r\n\r\n validateEnhancedOfferData(offerData) {\r\n try {\r\n // CRITICAL: Strict type checking to prevent syntax errors\r\n if (!offerData || typeof offerData !== 'object' || Array.isArray(offerData)) {\r\n this._secureLog('error', 'CRITICAL: Invalid offer data structure', { \r\n hasOfferData: !!offerData,\r\n offerDataType: typeof offerData,\r\n isArray: Array.isArray(offerData)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Offer data must be a non-null object');\r\n }\r\n\r\n // Basic required fields will be validated after format detection\r\n\r\n // Check if this is v4.0 compact format or legacy format\r\n const isV4CompactFormat = offerData.v === '4.0' && offerData.e && offerData.d;\r\n const isV4Format = offerData.version === '4.0' && offerData.ecdhPublicKey && offerData.ecdsaPublicKey;\r\n \r\n // Validate offer type (support compact, legacy v3.0 and v4.0 formats)\r\n const isValidType = isV4CompactFormat ? \r\n ['offer'].includes(offerData.t) :\r\n ['enhanced_secure_offer', 'secure_offer'].includes(offerData.type);\r\n \r\n if (!isValidType) {\r\n throw new Error('Invalid offer type');\r\n }\r\n \r\n if (isV4CompactFormat) {\r\n // v4.0 compact format validation\r\n const compactRequiredFields = [\r\n 'e', 'd', 'sl', 'vc', 'si', 'ci', 'ac', 'slv'\r\n ];\r\n \r\n for (const field of compactRequiredFields) {\r\n if (!offerData[field]) {\r\n throw new Error(`Missing required v4.0 compact field: ${field}`);\r\n }\r\n }\r\n \r\n // Validate key structures\r\n if (!offerData.e || typeof offerData.e !== 'object' || Array.isArray(offerData.e)) {\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDH public key structure');\r\n }\r\n \r\n if (!offerData.d || typeof offerData.d !== 'object' || Array.isArray(offerData.d)) {\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDSA public key structure');\r\n }\r\n \r\n // Validate salt length\r\n if (!Array.isArray(offerData.sl) || offerData.sl.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes for v4.0');\r\n }\r\n \r\n // Validate verification code format\r\n if (typeof offerData.vc !== 'string' || offerData.vc.length < 6) {\r\n throw new Error('Invalid verification code format');\r\n }\r\n \r\n // Validate security level\r\n if (!['MAX', 'HIGH', 'MED', 'LOW'].includes(offerData.slv)) {\r\n throw new Error('Invalid security level');\r\n }\r\n \r\n // Validate timestamp (not older than 1 hour)\r\n const offerAge = Date.now() - offerData.ts;\r\n if (offerAge > 3600000) {\r\n throw new Error('Offer is too old (older than 1 hour)');\r\n }\r\n \r\n this._secureLog('info', 'v4.0 compact offer validation passed', {\r\n version: offerData.v,\r\n hasECDH: !!offerData.e,\r\n hasECDSA: !!offerData.d,\r\n hasSalt: !!offerData.sl,\r\n hasVerificationCode: !!offerData.vc,\r\n securityLevel: offerData.slv,\r\n offerAge: Math.round(offerAge / 1000) + 's'\r\n });\r\n } else if (isV4Format) {\r\n // v4.0 enhanced validation\r\n const v4RequiredFields = [\r\n 'ecdhPublicKey', 'ecdsaPublicKey', 'salt', 'verificationCode',\r\n 'authChallenge', 'timestamp', 'version', 'securityLevel'\r\n ];\r\n\r\n for (const field of v4RequiredFields) {\r\n if (!offerData[field]) {\r\n throw new Error(`Missing v4.0 field: ${field}`);\r\n }\r\n }\r\n\r\n // Validate salt (must be 64 bytes for v4.0)\r\n if (!Array.isArray(offerData.salt) || offerData.salt.length !== 64) {\r\n throw new Error('Salt must be exactly 64 bytes for v4.0');\r\n }\r\n\r\n // Validate timestamp (not older than 1 hour)\r\n const offerAge = Date.now() - offerData.timestamp;\r\n if (offerAge > 3600000) {\r\n throw new Error('Offer is too old (older than 1 hour)');\r\n }\r\n\r\n // CRITICAL: Strict validation of key structures to prevent syntax errors\r\n if (!offerData.ecdhPublicKey || typeof offerData.ecdhPublicKey !== 'object' || Array.isArray(offerData.ecdhPublicKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDH public key structure', { \r\n hasEcdhKey: !!offerData.ecdhPublicKey,\r\n ecdhKeyType: typeof offerData.ecdhPublicKey,\r\n isArray: Array.isArray(offerData.ecdhPublicKey)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDH public key structure - hard abort required');\r\n }\r\n\r\n if (!offerData.ecdsaPublicKey || typeof offerData.ecdsaPublicKey !== 'object' || Array.isArray(offerData.ecdsaPublicKey)) {\r\n this._secureLog('error', 'CRITICAL: Invalid ECDSA public key structure', { \r\n hasEcdsaKey: !!offerData.ecdsaPublicKey,\r\n ecdsaKeyType: typeof offerData.ecdsaPublicKey,\r\n isArray: Array.isArray(offerData.ecdsaPublicKey)\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: Invalid ECDSA public key structure - hard abort required');\r\n }\r\n\r\n // CRITICAL: Validate key internal structure to prevent syntax errors\r\n if (!offerData.ecdhPublicKey.keyData || !offerData.ecdhPublicKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDH key missing keyData or signature', { \r\n hasKeyData: !!offerData.ecdhPublicKey.keyData,\r\n hasSignature: !!offerData.ecdhPublicKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDH key missing keyData or signature');\r\n }\r\n\r\n if (!offerData.ecdsaPublicKey.keyData || !offerData.ecdsaPublicKey.signature) {\r\n this._secureLog('error', 'CRITICAL: ECDSA key missing keyData or signature', { \r\n hasKeyData: !!offerData.ecdsaPublicKey.keyData,\r\n hasSignature: !!offerData.ecdsaPublicKey.signature\r\n });\r\n throw new Error('CRITICAL SECURITY FAILURE: ECDSA key missing keyData or signature');\r\n }\r\n\r\n if (typeof offerData.verificationCode !== 'string' || offerData.verificationCode.length < 6) {\r\n throw new Error('Invalid SAS verification code format - MITM protection required');\r\n }\r\n\r\n this._secureLog('info', 'v4.0 offer validation passed', {\r\n version: offerData.version,\r\n hasSecurityLevel: !!offerData.securityLevel?.level,\r\n offerAge: Math.round(offerAge / 1000) + 's'\r\n });\r\n } else {\r\n // v3.0 backward compatibility validation\r\n // NOTE: v3.0 has limited security - SAS verification is still critical\r\n const v3RequiredFields = ['publicKey', 'salt', 'verificationCode'];\r\n for (const field of v3RequiredFields) {\r\n if (!offerData[field]) {\r\n throw new Error(`Missing v3.0 field: ${field}`);\r\n }\r\n }\r\n\r\n // Validate salt (32 bytes for v3.0)\r\n if (!Array.isArray(offerData.salt) || offerData.salt.length !== 32) {\r\n throw new Error('Salt must be exactly 32 bytes for v3.0');\r\n }\r\n\r\n // Validate public key\r\n if (!Array.isArray(offerData.publicKey)) {\r\n throw new Error('Invalid public key format for v3.0');\r\n }\r\n\r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'v3.0 offer validation passed (backward compatibility)', {\r\n version: 'v3.0',\r\n legacy: true\r\n });\r\n }\r\n\r\n // Validate SDP structure (basic check for all versions)\r\n const sdp = isV4CompactFormat ? offerData.s : offerData.sdp;\r\n if (typeof sdp !== 'string' || !sdp.includes('v=0')) {\r\n throw new Error('Invalid SDP structure');\r\n }\r\n\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'CRITICAL: Security validation failed - hard abort required', {\r\n error: error.message,\r\n errorType: error.constructor.name,\r\n timestamp: Date.now()\r\n });\r\n\r\n throw new Error(`CRITICAL SECURITY VALIDATION FAILURE: ${error.message}`);\r\n }\r\n }\r\n\r\n async sendSecureMessage(message) {\r\n // Comprehensive input validation\r\n const validation = this._validateInputData(message, 'sendSecureMessage');\r\n if (!validation.isValid) {\r\n const errorMessage = `Input validation failed: ${validation.errors.join(', ')}`;\r\n this._secureLog('error', 'Input validation failed in sendSecureMessage', {\r\n errors: validation.errors,\r\n messageType: typeof message\r\n });\r\n throw new Error(errorMessage);\r\n }\r\n\r\n // Rate limiting check\r\n if (!this._checkRateLimit('sendSecureMessage')) {\r\n throw new Error('Rate limit exceeded for secure message sending');\r\n }\r\n\r\n // Enforce verification gate\r\n this._enforceVerificationGate('sendSecureMessage');\r\n\r\n // Quick readiness check WITHOUT mutex\r\n if (!this.isConnected()) {\r\n if (validation.sanitizedData && typeof validation.sanitizedData === 'object' && validation.sanitizedData.type && validation.sanitizedData.type.startsWith('file_')) {\r\n throw new Error('Connection not ready for file transfer. Please ensure the connection is established and verified.');\r\n }\r\n this.messageQueue.push(validation.sanitizedData);\r\n throw new Error('Connection not ready. Message queued for sending.');\r\n }\r\n \r\n // Use mutex ONLY for cryptographic operations\r\n return this._withMutex('cryptoOperation', async (operationId) => {\r\n // Re-check inside critical section\r\n if (!this.isConnected() || !this.isVerified) {\r\n throw new Error('Connection lost during message preparation');\r\n }\r\n \r\n // Note: master key session is managed by SecureMasterKeyManager\r\n // Do not gate here on _isUnlocked to avoid false blocking\r\n // Session timers are handled inside the master key manager on key access\r\n \r\n // Validate keys inside critical section\r\n if (!this.encryptionKey || !this.macKey || !this.metadataKey) {\r\n throw new Error('Encryption keys not initialized');\r\n }\r\n \r\n // Additional rate limiting check\r\n if (!window.EnhancedSecureCryptoUtils.rateLimiter.checkMessageRate(this.rateLimiterId)) {\r\n throw new Error('Message rate limit exceeded (60 messages per minute)');\r\n }\r\n \r\n try {\r\n // Accept strings and objects; stringify objects\r\n const textToSend = typeof validation.sanitizedData === 'string' ? validation.sanitizedData : JSON.stringify(validation.sanitizedData);\r\n const sanitizedMessage = window.EnhancedSecureCryptoUtils.sanitizeMessage(textToSend);\r\n const messageId = `msg_${Date.now()}_${this.messageCounter++}`;\r\n \r\n // Create AAD with sequence number for anti-replay protection\r\n if (typeof this._createMessageAAD !== 'function') {\r\n throw new Error('_createMessageAAD method is not available in sendSecureMessage. Manager may not be fully initialized.');\r\n }\r\n const aad = message.aad || this._createMessageAAD('enhanced_message', { content: sanitizedMessage });\r\n \r\n // Use enhanced encryption with AAD and sequence number\r\n const encryptedData = await window.EnhancedSecureCryptoUtils.encryptMessage(\r\n sanitizedMessage,\r\n this.encryptionKey,\r\n this.macKey,\r\n this.metadataKey,\r\n messageId,\r\n JSON.parse(aad).sequenceNumber // Use sequence number from AAD\r\n );\r\n \r\n const payload = {\r\n type: 'enhanced_message',\r\n data: encryptedData,\r\n keyVersion: this.currentKeyVersion,\r\n version: '4.0'\r\n };\r\n \r\n this.dataChannel.send(JSON.stringify(payload));\r\n // Locally display only plain strings to avoid UI duplication\r\n if (typeof validation.sanitizedData === 'string') {\r\n this.deliverMessageToUI(validation.sanitizedData, 'sent');\r\n }\r\n \r\n this._secureLog('debug', 'Secure message sent successfully', {\r\n operationId: operationId,\r\n messageLength: sanitizedMessage.length,\r\n keyVersion: this.currentKeyVersion\r\n });\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Secure message sending failed', {\r\n operationId: operationId,\r\n errorType: error.constructor.name\r\n });\r\n \r\n // Improved user-facing error messages (English)\r\n if (error.message.includes('Session expired')) {\r\n throw new Error('Session expired. Please enter your password to unlock.');\r\n } else if (error.message.includes('Encryption keys not initialized')) {\r\n throw new Error('Session expired due to inactivity. Please reconnect to the chat.');\r\n } else if (error.message.includes('Connection lost')) {\r\n throw new Error('Connection lost. Please check your Internet connection.');\r\n } else if (error.message.includes('Rate limit exceeded')) {\r\n throw new Error('Message rate limit exceeded. Please wait before sending another message.');\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }, 2000); // Reduced timeout for crypto operations\r\n }\r\n\r\n processMessageQueue() {\r\n while (this.messageQueue.length > 0 && this.isConnected() && this.isVerified) {\r\n const message = this.messageQueue.shift();\r\n this.sendSecureMessage(message).catch(console.error);\r\n }\r\n }\r\n\r\n startHeartbeat() {\r\n // Heartbeat moved to unified scheduler with connection validation\r\n this._secureLog('info', 'Heartbeat moved to unified scheduler');\r\n \r\n // Store heartbeat configuration for scheduler\r\n this._heartbeatConfig = {\r\n enabled: true,\r\n interval: EnhancedSecureWebRTCManager.TIMEOUTS.HEARTBEAT_INTERVAL,\r\n lastHeartbeat: 0\r\n };\r\n }\r\n\r\n stopHeartbeat() {\r\n // Heartbeat stopped via unified scheduler\r\n if (this._heartbeatConfig) {\r\n this._heartbeatConfig.enabled = false;\r\n }\r\n }\r\n\r\n /**\r\n * Stop all active timers and cleanup scheduler\r\n */\r\n _stopAllTimers() {\r\n this._secureLog('info', 'Stopping all timers and cleanup scheduler');\r\n \r\n // Stop maintenance scheduler\r\n if (this._maintenanceScheduler) {\r\n clearInterval(this._maintenanceScheduler);\r\n this._maintenanceScheduler = null;\r\n }\r\n \r\n // Stop heartbeat\r\n if (this._heartbeatConfig) {\r\n this._heartbeatConfig.enabled = false;\r\n }\r\n \r\n // Clear all timer references\r\n if (this._activeTimers) {\r\n this._activeTimers.forEach(timer => {\r\n if (timer) clearInterval(timer);\r\n });\r\n this._activeTimers.clear();\r\n }\r\n \r\n this._secureLog('info', 'All timers stopped successfully');\r\n }\r\n\r\n\r\n waitForIceGathering() {\r\n return new Promise((resolve) => {\r\n if (this.peerConnection.iceGatheringState === 'complete') {\r\n resolve();\r\n return;\r\n }\r\n\r\n const checkState = () => {\r\n if (this.peerConnection && this.peerConnection.iceGatheringState === 'complete') {\r\n this.peerConnection.removeEventListener('icegatheringstatechange', checkState);\r\n resolve();\r\n }\r\n };\r\n \r\n this.peerConnection.addEventListener('icegatheringstatechange', checkState);\r\n \r\n setTimeout(() => {\r\n if (this.peerConnection) {\r\n this.peerConnection.removeEventListener('icegatheringstatechange', checkState);\r\n }\r\n resolve();\r\n }, EnhancedSecureWebRTCManager.TIMEOUTS.ICE_GATHERING_TIMEOUT);\r\n });\r\n }\r\n\r\n retryConnection() {\r\n this._secureLog('info', 'Retrying connection', {\r\n attempt: this.connectionAttempts,\r\n maxAttempts: this.maxConnectionAttempts\r\n });\r\n this.onStatusChange('retrying');\r\n }\r\n\r\n isConnected() {\r\n const hasDataChannel = !!this.dataChannel;\r\n const dataChannelState = this.dataChannel?.readyState;\r\n const isDataChannelOpen = dataChannelState === 'open';\r\n const isVerified = this.isVerified;\r\n const connectionState = this.peerConnection?.connectionState;\r\n \r\n return this.dataChannel && this.dataChannel.readyState === 'open' && this.isVerified;\r\n }\r\n\r\n getConnectionInfo() {\r\n return {\r\n fingerprint: this.keyFingerprint,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n connectionState: this.peerConnection?.connectionState,\r\n iceConnectionState: this.peerConnection?.iceConnectionState,\r\n verificationCode: this.verificationCode\r\n };\r\n }\r\n\r\n disconnect() {\r\n // Stop all timers first\r\n this._stopAllTimers();\r\n \r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n }\r\n this.intentionalDisconnect = true;\r\n \r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Starting intentional disconnect');\r\n\r\n this.sendDisconnectNotification();\r\n\r\n setTimeout(() => {\r\n this.sendDisconnectNotification(); \r\n }, 100);\r\n\r\n document.dispatchEvent(new CustomEvent('peer-disconnect', {\r\n detail: { \r\n reason: 'user_disconnect',\r\n timestamp: Date.now()\r\n }\r\n }));\r\n }\r\n \r\n handleUnexpectedDisconnect() {\r\n this.sendDisconnectNotification();\r\n this.isVerified = false;\r\n \r\n // Ensure disconnect notification wasn't already sent\r\n if (!this.disconnectNotificationSent) {\r\n this.disconnectNotificationSent = true;\r\n this.deliverMessageToUI('\uD83D\uDD0C Connection lost. Attempting to reconnect...', 'system');\r\n }\r\n \r\n // Cleanup file transfer system on unexpected disconnect\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n document.dispatchEvent(new CustomEvent('peer-disconnect', {\r\n detail: { \r\n reason: 'connection_lost',\r\n timestamp: Date.now()\r\n }\r\n }));\r\n\r\n }\r\n \r\n sendDisconnectNotification() {\r\n try {\r\n if (this.dataChannel && this.dataChannel.readyState === 'open') {\r\n const notification = {\r\n type: 'peer_disconnect',\r\n timestamp: Date.now(),\r\n reason: this.intentionalDisconnect ? 'user_disconnect' : 'connection_lost'\r\n };\r\n\r\n for (let i = 0; i < 3; i++) {\r\n try {\r\n this.dataChannel.send(JSON.stringify(notification));\r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Disconnect notification sent', {\r\n reason: notification.reason,\r\n attempt: i + 1\r\n });\r\n break;\r\n } catch (sendError) {\r\n if (i === 2) { \r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Failed to send disconnect notification', {\r\n error: sendError.message\r\n });\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n window.EnhancedSecureCryptoUtils.secureLog.log('error', 'Could not send disconnect notification', {\r\n error: error.message\r\n });\r\n }\r\n }\r\n \r\n attemptReconnection() {\r\n // Ensure reconnection-failed notification wasn't already sent\r\n if (!this.reconnectionFailedNotificationSent) {\r\n this.reconnectionFailedNotificationSent = true;\r\n this.deliverMessageToUI('Unable to reconnect. A new connection is required.', 'system');\r\n }\r\n\r\n }\r\n \r\n handlePeerDisconnectNotification(data) {\r\n const reason = data.reason || 'unknown';\r\n const reasonText = reason === 'user_disconnect' ? 'manually disconnected.' : 'connection lost.';\r\n \r\n // Ensure peer-disconnect notification wasn't already sent\r\n if (!this.peerDisconnectNotificationSent) {\r\n this.peerDisconnectNotificationSent = true;\r\n this.deliverMessageToUI(`Peer ${reasonText}`, 'system');\r\n }\r\n \r\n this.onStatusChange('peer_disconnected');\r\n \r\n this.intentionalDisconnect = false;\r\n this.isVerified = false;\r\n this.stopHeartbeat();\r\n \r\n this.onKeyExchange(''); \r\n this.onVerificationRequired(''); \r\n\r\n document.dispatchEvent(new CustomEvent('peer-disconnect', {\r\n detail: { \r\n reason: reason,\r\n timestamp: Date.now()\r\n }\r\n }));\r\n\r\n setTimeout(() => {\r\n this.disconnect();\r\n }, 2000);\r\n \r\n window.EnhancedSecureCryptoUtils.secureLog.log('info', 'Peer disconnect notification processed', {\r\n reason: reason\r\n });\r\n }\r\n \r\n /**\r\n * Secure disconnect with complete memory cleanup\r\n */\r\n disconnect() {\r\n this.stopHeartbeat();\r\n this.isVerified = false;\r\n this.processedMessageIds.clear();\r\n this.messageCounter = 0;\r\n \r\n // Secure cleanup of cryptographic materials\r\n this._secureCleanupCryptographicMaterials();\r\n \r\n // Secure wipe of PFS key versions\r\n this.keyVersions.clear();\r\n this.oldKeys.clear();\r\n this.currentKeyVersion = 0;\r\n this.lastKeyRotation = Date.now();\r\n \r\n // Reset message counters\r\n this.sequenceNumber = 0;\r\n this.expectedSequenceNumber = 0;\r\n this.replayWindow.clear(); // Clear replay window\r\n \r\n // Reset security features\r\n this.securityFeatures = {\r\n hasEncryption: true,\r\n hasECDH: true,\r\n hasECDSA: true, \r\n hasMutualAuth: true, \r\n hasMetadataProtection: true, \r\n hasEnhancedReplayProtection: true, \r\n hasNonExtractableKeys: true, \r\n hasRateLimiting: true, \r\n hasEnhancedValidation: true, \r\n hasPFS: true \r\n };\r\n \r\n // Close connections\r\n if (this.dataChannel) {\r\n this.dataChannel.close();\r\n this.dataChannel = null;\r\n }\r\n if (this.peerConnection) {\r\n this.peerConnection.close();\r\n this.peerConnection = null;\r\n }\r\n \r\n // Secure wipe of message queue\r\n if (this.messageQueue && this.messageQueue.length > 0) {\r\n this.messageQueue.forEach((message, index) => {\r\n this._secureWipeMemory(message, `messageQueue[${index}]`);\r\n });\r\n this.messageQueue = [];\r\n }\r\n \r\n // Schedule natural cleanup\r\n this._forceGarbageCollection().catch(error => {\r\n this._secureLog('error', 'Cleanup failed during disconnect', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n });\r\n \r\n document.dispatchEvent(new CustomEvent('connection-cleaned', {\r\n detail: { \r\n timestamp: Date.now(),\r\n reason: this.intentionalDisconnect ? 'user_cleanup' : 'automatic_cleanup'\r\n }\r\n }));\r\n\r\n // Notify UI about complete cleanup\r\n this.onStatusChange('disconnected');\r\n this.onKeyExchange('');\r\n this.onVerificationRequired('');\r\n \r\n this._secureLog('info', 'Connection securely cleaned up with complete memory wipe');\r\n \r\n // Reset the intentional disconnect flag\r\n this.intentionalDisconnect = false;\r\n }\r\n // Public method to send files\r\n async sendFile(file) {\r\n // Enforce verification gate for file transfers\r\n this._enforceVerificationGate('sendFile');\r\n \r\n if (!this.isConnected()) {\r\n throw new Error('Connection not ready for file transfer. Please ensure the connection is established.');\r\n }\r\n\r\n if (!this.fileTransferSystem) {\r\n this.initializeFileTransfer();\r\n \r\n // Allow time for initialization\r\n await new Promise(resolve => setTimeout(resolve, 500));\r\n \r\n if (!this.fileTransferSystem) {\r\n throw new Error('File transfer system could not be initialized. Please try reconnecting.');\r\n }\r\n }\r\n\r\n // Verify key readiness\r\n if (!this.encryptionKey || !this.macKey) {\r\n throw new Error('Encryption keys not ready. Please wait for connection to be fully established.');\r\n }\r\n\r\n\r\n try {\r\n const fileId = await this.fileTransferSystem.sendFile(file);\r\n return fileId;\r\n } catch (error) {\r\n this._secureLog('error', 'File transfer error:', { errorType: error?.constructor?.name || 'Unknown' });\r\n \r\n // Re-throw with a clearer message\r\n if (error.message.includes('Connection not ready')) {\r\n throw new Error('Connection not ready for file transfer. Check connection status.');\r\n } else if (error.message.includes('Encryption keys not initialized')) {\r\n throw new Error('Session expired due to inactivity. Please reconnect to the chat.');\r\n } else if (error.message.includes('Transfer timeout')) {\r\n throw new Error('File transfer timeout. Check connection and try again.');\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n // Get active file transfers\r\n getFileTransfers() {\r\n if (!this.fileTransferSystem) {\r\n return { sending: [], receiving: [] };\r\n }\r\n \r\n try {\r\n // Check available methods in file transfer system\r\n let sending = [];\r\n let receiving = [];\r\n \r\n if (typeof this.fileTransferSystem.getActiveTransfers === 'function') {\r\n sending = this.fileTransferSystem.getActiveTransfers();\r\n } else {\r\n this._secureLog('warn', 'getActiveTransfers method not available in file transfer system');\r\n }\r\n \r\n if (typeof this.fileTransferSystem.getReceivingTransfers === 'function') {\r\n receiving = this.fileTransferSystem.getReceivingTransfers();\r\n } else {\r\n this._secureLog('warn', 'getReceivingTransfers method not available in file transfer system');\r\n }\r\n \r\n return {\r\n sending: sending || [],\r\n receiving: receiving || []\r\n };\r\n } catch (error) {\r\n this._secureLog('error', 'Error getting file transfers:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return { sending: [], receiving: [] };\r\n }\r\n }\r\n\r\n // Get file transfer system status\r\n getFileTransferStatus() {\r\n if (!this.fileTransferSystem) {\r\n return {\r\n initialized: false,\r\n status: 'not_initialized',\r\n message: 'File transfer system not initialized'\r\n };\r\n }\r\n \r\n const activeTransfers = this.fileTransferSystem.getActiveTransfers();\r\n const receivingTransfers = this.fileTransferSystem.getReceivingTransfers();\r\n \r\n return {\r\n initialized: true,\r\n status: 'ready',\r\n activeTransfers: activeTransfers.length,\r\n receivingTransfers: receivingTransfers.length,\r\n totalTransfers: activeTransfers.length + receivingTransfers.length\r\n };\r\n }\r\n\r\n // Cancel file transfer\r\n cancelFileTransfer(fileId) {\r\n if (!this.fileTransferSystem) return false;\r\n return this.fileTransferSystem.cancelTransfer(fileId);\r\n }\r\n\r\n // Force cleanup of file transfer system\r\n cleanupFileTransferSystem() {\r\n if (this.fileTransferSystem) {\r\n this._secureLog('info', '\uD83E\uDDF9 Force cleaning up file transfer system');\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n // Reinitialize file transfer system\r\n reinitializeFileTransfer() {\r\n try {\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n }\r\n this.initializeFileTransfer();\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to reinitialize file transfer system:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n\r\n // Set file transfer callbacks\r\n setFileTransferCallbacks(onProgress, onReceived, onError) {\r\n this.onFileProgress = onProgress;\r\n this.onFileReceived = onReceived;\r\n this.onFileError = onError;\r\n \r\n // Reinitialize file transfer system if it exists to update callbacks\r\n if (this.fileTransferSystem) {\r\n this.initializeFileTransfer();\r\n }\r\n }\r\n\r\n // ============================================\r\n // SESSION ACTIVATION HANDLING\r\n // ============================================\r\n\r\n async handleSessionActivation(sessionData) {\r\n try {\r\n \r\n // Update session state\r\n this.currentSession = sessionData;\r\n \r\n // FIX: More lenient checks for activation\r\n const hasKeys = !!(this.encryptionKey && this.macKey);\r\n const hasSession = !!(sessionData.sessionId);\r\n \r\n // Force connection status if there is an active session\r\n if (hasSession) {\r\n this.onStatusChange('connected');\r\n\r\n }\r\n\r\n setTimeout(() => {\r\n try {\r\n this.initializeFileTransfer();\r\n } catch (error) {\r\n this._secureLog('warn', 'File transfer initialization failed during session activation:', { details: error.message });\r\n }\r\n }, 1000);\r\n \r\n \r\n if (this.fileTransferSystem && this.isConnected()) {\r\n \r\n if (typeof this.fileTransferSystem.onSessionUpdate === 'function') {\r\n this.fileTransferSystem.onSessionUpdate({\r\n keyFingerprint: this.keyFingerprint,\r\n sessionSalt: this.sessionSalt,\r\n hasMacKey: !!this.macKey\r\n });\r\n }\r\n }\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to handle session activation:', { errorType: error?.constructor?.name || 'Unknown' });\r\n }\r\n }\r\n // Method to check readiness of file transfers\r\ncheckFileTransferReadiness() {\r\n const status = {\r\n hasFileTransferSystem: !!this.fileTransferSystem,\r\n hasDataChannel: !!this.dataChannel,\r\n dataChannelState: this.dataChannel?.readyState,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n ready: false\r\n };\r\n \r\n status.ready = status.hasFileTransferSystem && \r\n status.hasDataChannel && \r\n status.dataChannelState === 'open' && \r\n status.isConnected && \r\n status.isVerified;\r\n return status;\r\n }\r\n\r\n // Method to force re-initialize file transfer system\r\n forceReinitializeFileTransfer() {\r\n try {\r\n \r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n \r\n // Small delay before reinitialization\r\n setTimeout(() => {\r\n this.initializeFileTransfer();\r\n }, 500);\r\n \r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to force reinitialize file transfer:', { errorType: error?.constructor?.name || 'Unknown' });\r\n return false;\r\n }\r\n }\r\n\r\n // Method to get diagnostic information\r\n getFileTransferDiagnostics() {\r\n const diagnostics = {\r\n timestamp: new Date().toISOString(),\r\n webrtcManager: {\r\n hasDataChannel: !!this.dataChannel,\r\n dataChannelState: this.dataChannel?.readyState,\r\n isConnected: this.isConnected(),\r\n isVerified: this.isVerified,\r\n isInitiator: this.isInitiator,\r\n hasEncryptionKey: !!this.encryptionKey,\r\n hasMacKey: !!this.macKey,\r\n hasMetadataKey: !!this.metadataKey,\r\n hasKeyFingerprint: !!this.keyFingerprint,\r\n hasSessionSalt: !!this.sessionSalt\r\n },\r\n fileTransferSystem: null,\r\n globalState: {\r\n fileTransferActive: this._fileTransferActive || false,\r\n hasFileTransferSystem: !!this.fileTransferSystem,\r\n fileTransferSystemType: this.fileTransferSystem ? 'EnhancedSecureFileTransfer' : 'none'\r\n }\r\n };\r\n \r\n if (this.fileTransferSystem) {\r\n try {\r\n diagnostics.fileTransferSystem = this.fileTransferSystem.getSystemStatus();\r\n } catch (error) {\r\n diagnostics.fileTransferSystem = { error: error.message };\r\n }\r\n }\r\n \r\n return diagnostics;\r\n }\r\n\r\n getSupportedFileTypes() {\r\n if (!this.fileTransferSystem) {\r\n return { error: 'File transfer system not initialized' };\r\n }\r\n \r\n try {\r\n return this.fileTransferSystem.getSupportedFileTypes();\r\n } catch (error) {\r\n return { error: error.message };\r\n }\r\n }\r\n\r\n validateFile(file) {\r\n if (!this.fileTransferSystem) {\r\n return { \r\n isValid: false, \r\n errors: ['File transfer system not initialized'],\r\n fileType: null,\r\n fileSize: file?.size || 0,\r\n formattedSize: '0 B'\r\n };\r\n }\r\n \r\n try {\r\n return this.fileTransferSystem.validateFile(file);\r\n } catch (error) {\r\n return { \r\n isValid: false, \r\n errors: [error.message],\r\n fileType: null,\r\n fileSize: file?.size || 0,\r\n formattedSize: '0 B'\r\n };\r\n }\r\n }\r\n\r\n getFileTypeInfo() {\r\n if (!this.fileTransferSystem) {\r\n return { error: 'File transfer system not initialized' };\r\n }\r\n \r\n try {\r\n return this.fileTransferSystem.getFileTypeInfo();\r\n } catch (error) {\r\n return { error: error.message };\r\n }\r\n }\r\n\r\n async forceInitializeFileTransfer(options = {}) {\r\n const abortController = new AbortController();\r\n const { signal = abortController.signal, timeout = 6000 } = options;\r\n\r\n if (signal && signal !== abortController.signal) {\r\n signal.addEventListener('abort', () => abortController.abort());\r\n }\r\n try {\r\n if (!this.isVerified) {\r\n throw new Error('Connection not verified');\r\n }\r\n \r\n if (!this.dataChannel || this.dataChannel.readyState !== 'open') {\r\n throw new Error('Data channel not open');\r\n }\r\n \r\n if (!this.encryptionKey || !this.macKey) {\r\n throw new Error('Encryption keys not ready');\r\n }\r\n\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n }\r\n\r\n this.initializeFileTransfer();\r\n\r\n let attempts = 0;\r\n const maxAttempts = 50;\r\n const checkInterval = 100; \r\n const maxWaitTime = maxAttempts * checkInterval; \r\n\r\n const initializationPromise = new Promise((resolve, reject) => {\r\n const checkInitialization = () => {\r\n if (abortController.signal.aborted) {\r\n reject(new Error('Operation cancelled'));\r\n return;\r\n }\r\n \r\n if (this.fileTransferSystem) {\r\n resolve(true);\r\n return;\r\n }\r\n \r\n if (attempts >= maxAttempts) {\r\n reject(new Error(`Initialization timeout after ${maxWaitTime}ms`));\r\n return;\r\n }\r\n \r\n attempts++;\r\n setTimeout(checkInitialization, checkInterval);\r\n };\r\n \r\n checkInitialization();\r\n });\r\n\r\n await Promise.race([\r\n initializationPromise,\r\n new Promise((_, reject) => \r\n setTimeout(() => reject(new Error(`Global timeout after ${timeout}ms`)), timeout)\r\n )\r\n ]);\r\n \r\n if (this.fileTransferSystem) {\r\n return true;\r\n } else {\r\n throw new Error('Force initialization timeout');\r\n }\r\n \r\n } catch (error) {\r\n if (error.name === 'AbortError' || error.message.includes('cancelled')) {\r\n this._secureLog('info', 'File transfer initialization cancelled by user');\r\n return { cancelled: true };\r\n }\r\n \r\n this._secureLog('error', 'Force file transfer initialization failed:', { \r\n errorType: error?.constructor?.name || 'Unknown',\r\n message: error.message,\r\n attempts: attempts\r\n });\r\n return { error: error.message, attempts: attempts };\r\n }\r\n }\r\n\r\n cancelFileTransferInitialization() {\r\n try {\r\n if (this.fileTransferSystem) {\r\n this.fileTransferSystem.cleanup();\r\n this.fileTransferSystem = null;\r\n this._fileTransferActive = false;\r\n this._secureLog('info', 'File transfer initialization cancelled');\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to cancel file transfer initialization:', { \r\n errorType: error?.constructor?.name || 'Unknown' \r\n });\r\n return false;\r\n }\r\n }\r\n \r\n getFileTransferSystemStatus() {\r\n if (!this.fileTransferSystem) {\r\n return { available: false, status: 'not_initialized' };\r\n }\r\n \r\n try {\r\n const status = this.fileTransferSystem.getSystemStatus();\r\n return {\r\n available: true,\r\n status: status.status || 'unknown',\r\n activeTransfers: status.activeTransfers || 0,\r\n receivingTransfers: status.receivingTransfers || 0,\r\n systemType: 'EnhancedSecureFileTransfer'\r\n };\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to get file transfer system status:', { \r\n errorType: error?.constructor?.name || 'Unknown' \r\n });\r\n return { available: false, status: 'error', error: error.message };\r\n }\r\n }\r\n\r\n _validateNestedEncryptionSecurity() {\r\n if (this.securityFeatures.hasNestedEncryption && this.nestedEncryptionKey) {\r\n // Test secure IV generation with reuse prevention\r\n try {\r\n const testIV1 = this._generateSecureIV(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE, 'securityTest1');\r\n const testIV2 = this._generateSecureIV(EnhancedSecureWebRTCManager.SIZES.NESTED_ENCRYPTION_IV_SIZE, 'securityTest2');\r\n \r\n // Verify IVs are different and properly tracked\r\n if (testIV1.every((byte, index) => byte === testIV2[index])) {\r\n this._secureLog('error', 'CRITICAL: Nested encryption security validation failed - IVs are identical!');\r\n return false;\r\n }\r\n \r\n // Verify IV tracking system is working\r\n const stats = this._getIVTrackingStats();\r\n if (stats.totalIVs < 2) {\r\n this._secureLog('error', 'CRITICAL: IV tracking system not working properly');\r\n return false;\r\n }\r\n \r\n this._secureLog('info', 'Nested encryption security validation passed - secure IV generation working');\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'CRITICAL: Nested encryption security validation failed:', {\r\n errorType: error.constructor.name,\r\n errorMessage: error.message\r\n });\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n}\r\n\r\nclass SecureKeyStorage {\r\n constructor(masterKeyManager = null) {\r\n // Use WeakMap for automatic garbage collection of unused keys\r\n this._keyStore = new WeakMap();\r\n this._keyMetadata = new Map(); // Metadata doesn't need WeakMap\r\n this._keyReferences = new Map(); // Strong references for active keys\r\n \r\n // Use secure master key manager instead of global key\r\n this._masterKeyManager = masterKeyManager || new SecureMasterKeyManager();\r\n \r\n // Initialize persistent storage for extractable keys\r\n this._persistentStorage = new SecurePersistentKeyStorage(this._masterKeyManager);\r\n \r\n // Setup master key manager callbacks\r\n this._setupMasterKeyCallbacks();\r\n\r\n setTimeout(() => {\r\n if (!this.validateStorageIntegrity()) {\r\n this._secureLog('error', 'CRITICAL: Key storage integrity check failed');\r\n }\r\n }, 100);\r\n \r\n }\r\n\r\n /**\r\n * Setup callbacks for master key manager\r\n */\r\n _setupMasterKeyCallbacks() {\r\n // Set default password callback (can be overridden)\r\n this._masterKeyManager.setPasswordRequiredCallback((isRetry, callback) => {\r\n // Default implementation - should be overridden by application\r\n const password = prompt(isRetry ? \r\n 'Incorrect password. Please enter your master password:' : \r\n 'Please enter your master password to unlock secure storage:'\r\n );\r\n callback(password);\r\n });\r\n \r\n this._masterKeyManager.setSessionExpiredCallback((reason) => {\r\n console.warn(`Master key session expired: ${reason}`);\r\n // Application should handle this event\r\n });\r\n \r\n this._masterKeyManager.setUnlockedCallback(() => {\r\n console.log('Master key unlocked successfully');\r\n });\r\n }\r\n \r\n /**\r\n * Set custom password callback\r\n */\r\n setPasswordCallback(callback) {\r\n this._masterKeyManager.setPasswordRequiredCallback(callback);\r\n }\r\n \r\n /**\r\n * Set custom session expired callback\r\n */\r\n setSessionExpiredCallback(callback) {\r\n this._masterKeyManager.setSessionExpiredCallback(callback);\r\n }\r\n \r\n /**\r\n * Get master key (with automatic unlock if needed)\r\n */\r\n async _getMasterKey() {\r\n if (!this._masterKeyManager.isUnlocked()) {\r\n await this._masterKeyManager.unlock();\r\n }\r\n return this._masterKeyManager.getMasterKey();\r\n }\r\n\r\n async storeKey(keyId, cryptoKey, metadata = {}) {\r\n if (!(cryptoKey instanceof CryptoKey)) {\r\n throw new Error('Only CryptoKey objects can be stored');\r\n }\r\n\r\n try {\r\n // For non-extractable keys, store only in-memory reference\r\n if (!cryptoKey.extractable) {\r\n this._keyReferences.set(keyId, cryptoKey);\r\n this._keyMetadata.set(keyId, {\r\n ...metadata,\r\n created: Date.now(),\r\n lastAccessed: Date.now(),\r\n extractable: false,\r\n persistent: false,\r\n encrypted: false\r\n });\r\n return true;\r\n }\r\n\r\n // For extractable keys, use persistent storage with encryption\r\n await this._persistentStorage.storeExtractableKey(keyId, cryptoKey, metadata);\r\n \r\n // Also store in memory for immediate access\r\n this._keyReferences.set(keyId, cryptoKey);\r\n this._keyMetadata.set(keyId, {\r\n ...metadata,\r\n created: Date.now(),\r\n lastAccessed: Date.now(),\r\n extractable: true,\r\n persistent: true,\r\n encrypted: true\r\n });\r\n\r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to store key securely', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n async retrieveKey(keyId) {\r\n try {\r\n // Check if key is in memory first\r\n if (this._keyReferences.has(keyId)) {\r\n const metadata = this._keyMetadata.get(keyId);\r\n if (metadata) {\r\n metadata.lastAccessed = Date.now();\r\n }\r\n return this._keyReferences.get(keyId);\r\n }\r\n \r\n // Try to restore from persistent storage\r\n const restoredKey = await this._persistentStorage.retrieveKey(keyId);\r\n if (restoredKey) {\r\n // Update memory cache\r\n this._keyReferences.set(keyId, restoredKey);\r\n \r\n // Update or create metadata\r\n const existingMetadata = this._keyMetadata.get(keyId);\r\n this._keyMetadata.set(keyId, {\r\n ...existingMetadata,\r\n lastAccessed: Date.now(),\r\n restoredFromPersistent: true\r\n });\r\n \r\n return restoredKey;\r\n }\r\n \r\n return null;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to retrieve key', {\r\n keyIdHash: await this._createSafeLogHash(keyId, 'key_id'),\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return null;\r\n }\r\n }\r\n\r\n async _encryptKeyData(keyData) {\r\n const dataToEncrypt = typeof keyData === 'object' \r\n ? JSON.stringify(keyData) \r\n : keyData;\r\n \r\n const encoder = new TextEncoder();\r\n const data = encoder.encode(dataToEncrypt);\r\n \r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n \r\n const masterKey = await this._getMasterKey();\r\n const encryptedData = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n data\r\n );\r\n\r\n // Return IV + encrypted data\r\n const result = new Uint8Array(iv.length + encryptedData.byteLength);\r\n result.set(iv, 0);\r\n result.set(new Uint8Array(encryptedData), iv.length);\r\n \r\n return result;\r\n }\r\n\r\n async _decryptKeyData(encryptedData) {\r\n const iv = encryptedData.slice(0, 12);\r\n const data = encryptedData.slice(12);\r\n \r\n const masterKey = await this._getMasterKey();\r\n const decryptedData = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n data\r\n );\r\n\r\n const decoder = new TextDecoder();\r\n const jsonString = decoder.decode(decryptedData);\r\n \r\n try {\r\n return JSON.parse(jsonString);\r\n } catch {\r\n return decryptedData;\r\n }\r\n }\r\n\r\n async secureWipe(keyId) {\r\n const cryptoKey = this._keyReferences.get(keyId);\r\n \r\n if (cryptoKey) {\r\n // Remove from WeakMap (will be GC'd)\r\n this._keyStore.delete(cryptoKey);\r\n // Remove strong reference\r\n this._keyReferences.delete(keyId);\r\n // Remove metadata\r\n this._keyMetadata.delete(keyId);\r\n }\r\n\r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n }\r\n\r\n async secureWipeAll() {\r\n // Clear persistent storage\r\n try {\r\n await this._persistentStorage.clearAll();\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to clear persistent storage', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n }\r\n \r\n // Clear all references\r\n this._keyReferences.clear();\r\n this._keyMetadata.clear();\r\n \r\n // WeakMap entries will be garbage collected\r\n this._keyStore = new WeakMap();\r\n \r\n // Schedule natural cleanup\r\n await this._performNaturalCleanup();\r\n }\r\n\r\n // Validate storage integrity\r\n validateStorageIntegrity() {\r\n const violations = [];\r\n \r\n for (const [keyId, metadata] of this._keyMetadata.entries()) {\r\n // Check: extractable keys must be encrypted\r\n if (metadata.extractable === true && metadata.encrypted !== true) {\r\n violations.push({\r\n keyId,\r\n type: 'EXTRACTABLE_KEY_NOT_ENCRYPTED',\r\n metadata\r\n });\r\n }\r\n \r\n // Check: non-extractable keys should not be encrypted\r\n if (metadata.extractable === false && metadata.encrypted === true) {\r\n violations.push({\r\n keyId,\r\n type: 'NON_EXTRACTABLE_KEY_ENCRYPTED',\r\n metadata\r\n });\r\n }\r\n }\r\n \r\n if (violations.length > 0) {\r\n this._secureLog('error', 'Storage integrity violations detected', {\r\n violationCount: violations.length\r\n });\r\n return false;\r\n }\r\n \r\n return true;\r\n }\r\n\r\n async getStorageStats() {\r\n const persistentStats = await this._persistentStorage.getStorageStats();\r\n \r\n return {\r\n totalKeys: this._keyReferences.size,\r\n memoryKeys: this._keyReferences.size,\r\n persistentKeys: persistentStats.persistentKeys,\r\n metadata: Array.from(this._keyMetadata.entries()).map(([id, meta]) => ({\r\n id,\r\n created: meta.created,\r\n lastAccessed: meta.lastAccessed,\r\n age: Date.now() - meta.created,\r\n persistent: meta.persistent || false\r\n })),\r\n persistent: persistentStats\r\n };\r\n }\r\n \r\n /**\r\n * List all stored keys (memory + persistent)\r\n */\r\n async listAllKeys() {\r\n try {\r\n const memoryKeys = Array.from(this._keyMetadata.entries()).map(([keyId, metadata]) => ({\r\n keyId,\r\n ...metadata,\r\n location: 'memory'\r\n }));\r\n \r\n const persistentKeys = await this._persistentStorage.listStoredKeys();\r\n const persistentKeysFormatted = persistentKeys.map(key => ({\r\n ...key,\r\n location: 'persistent'\r\n }));\r\n \r\n return {\r\n memoryKeys,\r\n persistentKeys: persistentKeysFormatted,\r\n totalCount: memoryKeys.length + persistentKeysFormatted.length\r\n };\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to list keys', {\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return {\r\n memoryKeys: [],\r\n persistentKeys: [],\r\n totalCount: 0,\r\n error: error.message\r\n };\r\n }\r\n }\r\n \r\n /**\r\n * Delete key from both memory and persistent storage\r\n */\r\n async deleteKey(keyId) {\r\n try {\r\n // Remove from memory\r\n this._keyReferences.delete(keyId);\r\n this._keyMetadata.delete(keyId);\r\n \r\n // Remove from persistent storage\r\n await this._persistentStorage.deleteKey(keyId);\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n this._secureLog('error', 'Failed to delete key', {\r\n keyIdHash: await this._createSafeLogHash(keyId, 'key_id'),\r\n errorType: error?.constructor?.name || 'Unknown'\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n // Method _generateNextSequenceNumber moved to constructor area for early availability\r\n\r\n /**\r\n * Validate incoming message sequence number\r\n * This prevents replay attacks and ensures message ordering\r\n */\r\n _validateIncomingSequenceNumber(receivedSeq, context = 'unknown') {\r\n try {\r\n if (!this.replayProtectionEnabled) {\r\n return true; // Skip validation if disabled\r\n }\r\n\r\n // Check if sequence number is within acceptable range\r\n if (receivedSeq < this.expectedSequenceNumber - this.replayWindowSize) {\r\n this._secureLog('warn', 'Sequence number too old - possible replay attack', {\r\n received: receivedSeq,\r\n expected: this.expectedSequenceNumber,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n\r\n // Check if sequence number is too far ahead (DoS protection)\r\n if (receivedSeq > this.expectedSequenceNumber + this.maxSequenceGap) {\r\n this._secureLog('warn', 'Sequence number gap too large - possible DoS attack', {\r\n received: receivedSeq,\r\n expected: this.expectedSequenceNumber,\r\n gap: receivedSeq - this.expectedSequenceNumber,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n\r\n // Check if sequence number is already in replay window\r\n if (this.replayWindow.has(receivedSeq)) {\r\n this._secureLog('warn', 'Duplicate sequence number detected - replay attack', {\r\n received: receivedSeq,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n\r\n // Add to replay window\r\n this.replayWindow.add(receivedSeq);\r\n \r\n // Maintain sliding window size\r\n if (this.replayWindow.size > this.replayWindowSize) {\r\n const oldestSeq = Math.min(...this.replayWindow);\r\n this.replayWindow.delete(oldestSeq);\r\n }\r\n\r\n // Update expected sequence number if this is the next expected\r\n if (receivedSeq === this.expectedSequenceNumber) {\r\n this.expectedSequenceNumber++;\r\n \r\n // Clean up replay window entries that are no longer needed\r\n while (this.replayWindow.has(this.expectedSequenceNumber - this.replayWindowSize - 1)) {\r\n this.replayWindow.delete(this.expectedSequenceNumber - this.replayWindowSize - 1);\r\n }\r\n }\r\n\r\n this._secureLog('debug', 'Sequence number validation successful', {\r\n received: receivedSeq,\r\n expected: this.expectedSequenceNumber,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Sequence number validation failed', {\r\n error: error.message,\r\n context: context,\r\n timestamp: Date.now()\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n // Method _createMessageAAD moved to constructor area for early availability\r\n\r\n /**\r\n * Validate message AAD with sequence number\r\n * This ensures message integrity and prevents replay attacks\r\n */\r\n _validateMessageAAD(aadString, expectedMessageType = null) {\r\n try {\r\n const aad = JSON.parse(aadString);\r\n \r\n // Validate session binding\r\n if (aad.sessionId !== (this.currentSession?.sessionId || 'unknown')) {\r\n throw new Error('AAD sessionId mismatch - possible replay attack');\r\n }\r\n \r\n if (aad.keyFingerprint !== (this.keyFingerprint || 'unknown')) {\r\n throw new Error('AAD keyFingerprint mismatch - possible key substitution attack');\r\n }\r\n \r\n // Validate sequence number\r\n if (!this._validateIncomingSequenceNumber(aad.sequenceNumber, aad.messageType)) {\r\n throw new Error('Sequence number validation failed - possible replay or DoS attack');\r\n }\r\n \r\n // Validate message type if specified\r\n if (expectedMessageType && aad.messageType !== expectedMessageType) {\r\n throw new Error(`AAD messageType mismatch - expected ${expectedMessageType}, got ${aad.messageType}`);\r\n }\r\n \r\n return aad;\r\n } catch (error) {\r\n this._secureLog('error', 'AAD validation failed', { error: error.message, aadString });\r\n throw new Error(`AAD validation failed: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Get anti-replay protection status\r\n * This shows the current state of replay protection\r\n */\r\n getAntiReplayStatus() {\r\n const status = {\r\n replayProtectionEnabled: this.replayProtectionEnabled,\r\n replayWindowSize: this.replayWindowSize,\r\n currentReplayWindowSize: this.replayWindow.size,\r\n sequenceNumber: this.sequenceNumber,\r\n expectedSequenceNumber: this.expectedSequenceNumber,\r\n maxSequenceGap: this.maxSequenceGap,\r\n replayWindowEntries: Array.from(this.replayWindow).sort((a, b) => a - b)\r\n };\r\n\r\n this._secureLog('info', 'Anti-replay status retrieved', status);\r\n return status;\r\n }\r\n\r\n /**\r\n * Configure anti-replay protection\r\n * This allows fine-tuning of replay protection parameters\r\n */\r\n configureAntiReplayProtection(config) {\r\n try {\r\n if (config.windowSize !== undefined) {\r\n if (config.windowSize < 16 || config.windowSize > 1024) {\r\n throw new Error('Replay window size must be between 16 and 1024');\r\n }\r\n this.replayWindowSize = config.windowSize;\r\n }\r\n\r\n if (config.maxGap !== undefined) {\r\n if (config.maxGap < 10 || config.maxGap > 1000) {\r\n throw new Error('Max sequence gap must be between 10 and 1000');\r\n }\r\n this.maxSequenceGap = config.maxGap;\r\n }\r\n\r\n if (config.enabled !== undefined) {\r\n this.replayProtectionEnabled = config.enabled;\r\n }\r\n\r\n this._secureLog('info', 'Anti-replay protection configured', config);\r\n return true;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to configure anti-replay protection', { error: error.message });\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get real security level with actual cryptographic tests\r\n * This provides real-time verification of security features\r\n */\r\n async getRealSecurityLevel() {\r\n try {\r\n const securityData = {\r\n // Basic security features\r\n ecdhKeyExchange: !!this.ecdhKeyPair,\r\n ecdsaSignatures: !!this.ecdsaKeyPair,\r\n aesEncryption: !!this.encryptionKey,\r\n messageIntegrity: !!this.hmacKey,\r\n \r\n // Advanced security features - using the exact property names expected by EnhancedSecureCryptoUtils\r\n replayProtection: this.replayProtectionEnabled,\r\n dtlsFingerprint: !!this.expectedDTLSFingerprint,\r\n sasCode: !!this.verificationCode,\r\n metadataProtection: true, // Always enabled\r\n trafficObfuscation: true, // Always enabled\r\n perfectForwardSecrecy: true, // Always enabled\r\n \r\n // Rate limiting\r\n rateLimiter: true, // Always enabled\r\n \r\n // Additional info\r\n connectionId: this.connectionId,\r\n keyFingerprint: this.keyFingerprint,\r\n currentSecurityLevel: 'maximum',\r\n timestamp: Date.now()\r\n };\r\n\r\n \r\n this._secureLog('info', 'Real security level calculated', securityData);\r\n return securityData;\r\n } catch (error) {\r\n this._secureLog('error', 'Failed to calculate real security level', { error: error.message });\r\n throw error;\r\n }\r\n }\r\n\r\n\r\n}\r\n\r\n/**\r\n * Secure IndexedDB Wrapper for Encrypted Key Storage\r\n * Provides secure persistent storage with encryption\r\n */\r\nclass SecureIndexedDBWrapper {\r\n constructor(dbName = 'SecureKeyStorage', version = 1) {\r\n this.dbName = dbName;\r\n this.version = version;\r\n this.db = null;\r\n \r\n // Store names\r\n this.KEYS_STORE = 'encrypted_keys';\r\n this.METADATA_STORE = 'key_metadata';\r\n this.SALT_STORE = 'master_salt';\r\n }\r\n \r\n /**\r\n * Initialize IndexedDB connection\r\n */\r\n async initialize() {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, this.version);\r\n \r\n request.onerror = () => {\r\n reject(new Error(`Failed to open IndexedDB: ${request.error}`));\r\n };\r\n \r\n request.onsuccess = () => {\r\n this.db = request.result;\r\n resolve();\r\n };\r\n \r\n request.onupgradeneeded = (event) => {\r\n const db = event.target.result;\r\n \r\n // Create encrypted keys store\r\n if (!db.objectStoreNames.contains(this.KEYS_STORE)) {\r\n const keysStore = db.createObjectStore(this.KEYS_STORE, { keyPath: 'keyId' });\r\n keysStore.createIndex('timestamp', 'timestamp', { unique: false });\r\n keysStore.createIndex('algorithm', 'algorithm', { unique: false });\r\n }\r\n \r\n // Create metadata store\r\n if (!db.objectStoreNames.contains(this.METADATA_STORE)) {\r\n const metadataStore = db.createObjectStore(this.METADATA_STORE, { keyPath: 'keyId' });\r\n metadataStore.createIndex('created', 'created', { unique: false });\r\n metadataStore.createIndex('lastAccessed', 'lastAccessed', { unique: false });\r\n }\r\n \r\n // Create salt store\r\n if (!db.objectStoreNames.contains(this.SALT_STORE)) {\r\n db.createObjectStore(this.SALT_STORE, { keyPath: 'id' });\r\n }\r\n };\r\n });\r\n }\r\n \r\n /**\r\n * Store encrypted key data\r\n */\r\n async storeEncryptedKey(keyId, encryptedData, iv, algorithm, usages, type, metadata = {}) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE, this.METADATA_STORE], 'readwrite');\r\n \r\n const keyRecord = {\r\n keyId: keyId,\r\n encryptedData: Array.from(new Uint8Array(encryptedData)), // Convert to array for storage\r\n iv: Array.from(new Uint8Array(iv)),\r\n algorithm: algorithm,\r\n usages: usages,\r\n type: type,\r\n timestamp: Date.now()\r\n };\r\n \r\n const metadataRecord = {\r\n keyId: keyId,\r\n ...metadata,\r\n created: Date.now(),\r\n lastAccessed: Date.now(),\r\n extractable: true,\r\n persistent: true\r\n };\r\n \r\n return new Promise((resolve, reject) => {\r\n const keysRequest = transaction.objectStore(this.KEYS_STORE).put(keyRecord);\r\n const metadataRequest = transaction.objectStore(this.METADATA_STORE).put(metadataRecord);\r\n \r\n transaction.oncomplete = () => resolve();\r\n transaction.onerror = () => reject(new Error(`Failed to store key: ${transaction.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Retrieve encrypted key data\r\n */\r\n async getEncryptedKey(keyId) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE], 'readonly');\r\n const store = transaction.objectStore(this.KEYS_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.get(keyId);\r\n \r\n request.onsuccess = () => {\r\n const result = request.result;\r\n if (result) {\r\n // Convert arrays back to Uint8Array\r\n result.encryptedData = new Uint8Array(result.encryptedData);\r\n result.iv = new Uint8Array(result.iv);\r\n }\r\n resolve(result);\r\n };\r\n \r\n request.onerror = () => reject(new Error(`Failed to retrieve key: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Update key metadata (e.g., last accessed time)\r\n */\r\n async updateKeyMetadata(keyId, updates) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.METADATA_STORE], 'readwrite');\r\n const store = transaction.objectStore(this.METADATA_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const getRequest = store.get(keyId);\r\n \r\n getRequest.onsuccess = () => {\r\n const metadata = getRequest.result;\r\n if (metadata) {\r\n Object.assign(metadata, updates);\r\n const putRequest = store.put(metadata);\r\n \r\n putRequest.onsuccess = () => resolve();\r\n putRequest.onerror = () => reject(new Error(`Failed to update metadata: ${putRequest.error}`));\r\n } else {\r\n reject(new Error(`Key metadata not found: ${keyId}`));\r\n }\r\n };\r\n \r\n getRequest.onerror = () => reject(new Error(`Failed to get metadata: ${getRequest.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Delete key and its metadata\r\n */\r\n async deleteKey(keyId) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE, this.METADATA_STORE], 'readwrite');\r\n \r\n return new Promise((resolve, reject) => {\r\n const keysRequest = transaction.objectStore(this.KEYS_STORE).delete(keyId);\r\n const metadataRequest = transaction.objectStore(this.METADATA_STORE).delete(keyId);\r\n \r\n transaction.oncomplete = () => resolve();\r\n transaction.onerror = () => reject(new Error(`Failed to delete key: ${transaction.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * List all stored keys\r\n */\r\n async listKeys() {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.METADATA_STORE], 'readonly');\r\n const store = transaction.objectStore(this.METADATA_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.getAll();\r\n \r\n request.onsuccess = () => resolve(request.result);\r\n request.onerror = () => reject(new Error(`Failed to list keys: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Store master key salt\r\n */\r\n async storeMasterSalt(salt) {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.SALT_STORE], 'readwrite');\r\n const store = transaction.objectStore(this.SALT_STORE);\r\n \r\n const saltRecord = {\r\n id: 'master_salt',\r\n salt: Array.from(new Uint8Array(salt)),\r\n created: Date.now()\r\n };\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.put(saltRecord);\r\n \r\n request.onsuccess = () => resolve();\r\n request.onerror = () => reject(new Error(`Failed to store salt: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Retrieve master key salt\r\n */\r\n async getMasterSalt() {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.SALT_STORE], 'readonly');\r\n const store = transaction.objectStore(this.SALT_STORE);\r\n \r\n return new Promise((resolve, reject) => {\r\n const request = store.get('master_salt');\r\n \r\n request.onsuccess = () => {\r\n const result = request.result;\r\n if (result) {\r\n resolve(new Uint8Array(result.salt));\r\n } else {\r\n resolve(null);\r\n }\r\n };\r\n \r\n request.onerror = () => reject(new Error(`Failed to retrieve salt: ${request.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Clear all data (for security wipe)\r\n */\r\n async clearAll() {\r\n if (!this.db) {\r\n throw new Error('Database not initialized');\r\n }\r\n \r\n const transaction = this.db.transaction([this.KEYS_STORE, this.METADATA_STORE, this.SALT_STORE], 'readwrite');\r\n \r\n return new Promise((resolve, reject) => {\r\n const keysRequest = transaction.objectStore(this.KEYS_STORE).clear();\r\n const metadataRequest = transaction.objectStore(this.METADATA_STORE).clear();\r\n const saltRequest = transaction.objectStore(this.SALT_STORE).clear();\r\n \r\n transaction.oncomplete = () => resolve();\r\n transaction.onerror = () => reject(new Error(`Failed to clear database: ${transaction.error}`));\r\n });\r\n }\r\n \r\n /**\r\n * Close database connection\r\n */\r\n close() {\r\n if (this.db) {\r\n this.db.close();\r\n this.db = null;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Secure Persistent Key Storage with Key Wrapping\r\n * Implements secure storage of extractable keys using AES-GCM encryption\r\n */\r\nclass SecurePersistentKeyStorage {\r\n constructor(masterKeyManager, indexedDBWrapper = null) {\r\n this._masterKeyManager = masterKeyManager;\r\n this._indexedDB = indexedDBWrapper || new SecureIndexedDBWrapper();\r\n this._dbInitialized = false;\r\n \r\n // In-memory cache for restored keys (WeakMap for automatic cleanup)\r\n this._keyCache = new WeakMap();\r\n this._keyReferences = new Map(); // Strong references for active keys\r\n }\r\n \r\n /**\r\n * Initialize IndexedDB if not already done\r\n */\r\n async _ensureDBInitialized() {\r\n if (!this._dbInitialized) {\r\n await this._indexedDB.initialize();\r\n this._dbInitialized = true;\r\n }\r\n }\r\n \r\n /**\r\n * Store extractable key with encryption\r\n */\r\n async storeExtractableKey(keyId, cryptoKey, metadata = {}) {\r\n if (!(cryptoKey instanceof CryptoKey)) {\r\n throw new Error('Only CryptoKey objects can be stored');\r\n }\r\n \r\n if (!cryptoKey.extractable) {\r\n throw new Error('Key must be extractable for persistent storage');\r\n }\r\n \r\n try {\r\n await this._ensureDBInitialized();\r\n \r\n // Export key to JWK\r\n const jwkData = await crypto.subtle.exportKey('jwk', cryptoKey);\r\n \r\n // Get master key for encryption\r\n const masterKey = this._masterKeyManager.getMasterKey();\r\n \r\n // Encrypt JWK data\r\n const { encryptedData, iv } = await this._encryptKeyData(jwkData, masterKey);\r\n \r\n // Store encrypted data in IndexedDB\r\n await this._indexedDB.storeEncryptedKey(\r\n keyId,\r\n encryptedData,\r\n iv,\r\n cryptoKey.algorithm,\r\n cryptoKey.usages,\r\n cryptoKey.type,\r\n metadata\r\n );\r\n \r\n // Store non-extractable reference in memory cache\r\n const nonExtractableKey = await this._importAsNonExtractable(jwkData, cryptoKey.algorithm, cryptoKey.usages);\r\n this._keyReferences.set(keyId, nonExtractableKey);\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to store extractable key: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Retrieve and restore key from persistent storage\r\n */\r\n async retrieveKey(keyId) {\r\n try {\r\n // Check if key is already in memory cache\r\n if (this._keyReferences.has(keyId)) {\r\n return this._keyReferences.get(keyId);\r\n }\r\n \r\n await this._ensureDBInitialized();\r\n \r\n // Get encrypted key data from IndexedDB\r\n const keyRecord = await this._indexedDB.getEncryptedKey(keyId);\r\n if (!keyRecord) {\r\n return null;\r\n }\r\n \r\n // Get master key for decryption\r\n const masterKey = this._masterKeyManager.getMasterKey();\r\n \r\n // Decrypt JWK data\r\n const jwkData = await this._decryptKeyData(keyRecord.encryptedData, keyRecord.iv, masterKey);\r\n \r\n // Import as non-extractable key\r\n const restoredKey = await this._importAsNonExtractable(jwkData, keyRecord.algorithm, keyRecord.usages);\r\n \r\n // Cache in memory\r\n this._keyReferences.set(keyId, restoredKey);\r\n \r\n // Update last accessed time\r\n await this._indexedDB.updateKeyMetadata(keyId, { lastAccessed: Date.now() });\r\n \r\n return restoredKey;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to retrieve key: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Delete key from persistent storage\r\n */\r\n async deleteKey(keyId) {\r\n try {\r\n await this._ensureDBInitialized();\r\n \r\n // Remove from IndexedDB\r\n await this._indexedDB.deleteKey(keyId);\r\n \r\n // Remove from memory cache\r\n this._keyReferences.delete(keyId);\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to delete key: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * List all stored keys\r\n */\r\n async listStoredKeys() {\r\n try {\r\n await this._ensureDBInitialized();\r\n return await this._indexedDB.listKeys();\r\n } catch (error) {\r\n throw new Error(`Failed to list keys: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Clear all persistent storage\r\n */\r\n async clearAll() {\r\n try {\r\n await this._ensureDBInitialized();\r\n \r\n // Clear IndexedDB\r\n await this._indexedDB.clearAll();\r\n \r\n // Clear memory cache\r\n this._keyReferences.clear();\r\n \r\n return true;\r\n \r\n } catch (error) {\r\n throw new Error(`Failed to clear storage: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Encrypt key data using master key\r\n */\r\n async _encryptKeyData(jwkData, masterKey) {\r\n // Convert JWK to JSON string and then to bytes\r\n const jsonString = JSON.stringify(jwkData);\r\n const data = new TextEncoder().encode(jsonString);\r\n \r\n // Generate random IV\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n \r\n // Encrypt with AES-GCM\r\n const encryptedData = await crypto.subtle.encrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n data\r\n );\r\n \r\n return {\r\n encryptedData: new Uint8Array(encryptedData),\r\n iv: iv\r\n };\r\n }\r\n \r\n /**\r\n * Decrypt key data using master key\r\n */\r\n async _decryptKeyData(encryptedData, iv, masterKey) {\r\n // Decrypt with AES-GCM\r\n const decryptedData = await crypto.subtle.decrypt(\r\n { name: 'AES-GCM', iv },\r\n masterKey,\r\n encryptedData\r\n );\r\n \r\n // Convert back to JWK\r\n const jsonString = new TextDecoder().decode(decryptedData);\r\n return JSON.parse(jsonString);\r\n }\r\n \r\n /**\r\n * Import JWK as non-extractable key\r\n */\r\n async _importAsNonExtractable(jwkData, algorithm, usages) {\r\n return await crypto.subtle.importKey(\r\n 'jwk',\r\n jwkData,\r\n algorithm,\r\n false, // non-extractable for security\r\n usages\r\n );\r\n }\r\n \r\n /**\r\n * Get storage statistics\r\n */\r\n async getStorageStats() {\r\n try {\r\n await this._ensureDBInitialized();\r\n const keys = await this._indexedDB.listKeys();\r\n \r\n return {\r\n totalKeys: keys.length,\r\n memoryKeys: this._keyReferences.size,\r\n persistentKeys: keys.length,\r\n lastAccessed: keys.reduce((latest, key) => \r\n Math.max(latest, key.lastAccessed || 0), 0)\r\n };\r\n \r\n } catch (error) {\r\n return {\r\n totalKeys: 0,\r\n memoryKeys: this._keyReferences.size,\r\n persistentKeys: 0,\r\n lastAccessed: 0,\r\n error: error.message\r\n };\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Secure Master Key Manager with Password-Based Derivation\r\n * Implements PBKDF2-based key derivation and session management\r\n */\r\nclass SecureMasterKeyManager {\r\n constructor(indexedDBWrapper = null) {\r\n // Session state\r\n this._masterKey = null;\r\n this._isUnlocked = false;\r\n this._sessionTimeout = null;\r\n this._lastActivity = null;\r\n \r\n // Configuration\r\n this._sessionTimeoutMs = 60 * 60 * 1000; // 60 minutes (\u0443\u0432\u0435\u043B\u0438\u0447\u0435\u043D\u043E \u0441 15 \u043C\u0438\u043D\u0443\u0442)\r\n this._inactivityTimeoutMs = 30 * 60 * 1000; // 30 minutes (\u0443\u0432\u0435\u043B\u0438\u0447\u0435\u043D\u043E \u0441 5 \u043C\u0438\u043D\u0443\u0442)\r\n \r\n // PBKDF2 parameters\r\n this._pbkdf2Iterations = 100000; // 100k iterations\r\n this._saltSize = 32; // 256 bits\r\n \r\n // IndexedDB wrapper for persistent salt storage\r\n this._indexedDB = indexedDBWrapper || new SecureIndexedDBWrapper();\r\n this._dbInitialized = false;\r\n \r\n // Event handlers\r\n this._onPasswordRequired = null;\r\n this._onSessionExpired = null;\r\n this._onUnlocked = null;\r\n \r\n // Setup event listeners (disabled for better UX - no auto-disconnect)\r\n // this._setupEventListeners();\r\n }\r\n \r\n /**\r\n * Set callback for password requests\r\n */\r\n setPasswordRequiredCallback(callback) {\r\n this._onPasswordRequired = callback;\r\n }\r\n \r\n /**\r\n * Set callback for session expiration\r\n */\r\n setSessionExpiredCallback(callback) {\r\n this._onSessionExpired = callback;\r\n }\r\n \r\n /**\r\n * Set callback for successful unlock\r\n */\r\n setUnlockedCallback(callback) {\r\n this._onUnlocked = callback;\r\n }\r\n \r\n /**\r\n * Setup event listeners for session management\r\n */\r\n _setupEventListeners() {\r\n // Handle page visibility changes\r\n if (typeof document !== 'undefined') {\r\n document.addEventListener('visibilitychange', () => {\r\n if (document.hidden) {\r\n this._handleFocusOut();\r\n } else {\r\n this._handleFocusIn();\r\n }\r\n });\r\n \r\n // Handle window focus/blur\r\n window.addEventListener('blur', () => this._handleFocusOut());\r\n window.addEventListener('focus', () => this._handleFocusIn());\r\n \r\n // Handle user activity\r\n ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'].forEach(event => {\r\n document.addEventListener(event, () => this._updateActivity(), { passive: true });\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Handle focus out - start inactivity timer\r\n */\r\n _handleFocusOut() {\r\n if (this._isUnlocked) {\r\n // Start shorter timeout when window loses focus\r\n this._startInactivityTimer(this._inactivityTimeoutMs);\r\n }\r\n }\r\n \r\n /**\r\n * Handle focus in - reset timers\r\n */\r\n _handleFocusIn() {\r\n if (this._isUnlocked) {\r\n this._resetSessionTimer();\r\n }\r\n }\r\n \r\n /**\r\n * Update last activity timestamp\r\n */\r\n _updateActivity() {\r\n this._lastActivity = Date.now();\r\n if (this._isUnlocked) {\r\n this._resetSessionTimer();\r\n }\r\n }\r\n \r\n /**\r\n * Start session timer\r\n */\r\n _startSessionTimer() {\r\n this._clearTimers();\r\n this._sessionTimeout = setTimeout(() => {\r\n this._expireSession('timeout');\r\n }, this._sessionTimeoutMs);\r\n }\r\n \r\n /**\r\n * Start inactivity timer\r\n */\r\n _startInactivityTimer(timeout) {\r\n this._clearTimers();\r\n this._sessionTimeout = setTimeout(() => {\r\n this._expireSession('inactivity');\r\n }, timeout);\r\n }\r\n \r\n /**\r\n * Reset session timer\r\n */\r\n _resetSessionTimer() {\r\n if (this._isUnlocked) {\r\n this._startSessionTimer();\r\n }\r\n }\r\n \r\n /**\r\n * Clear all timers\r\n */\r\n _clearTimers() {\r\n if (this._sessionTimeout) {\r\n clearTimeout(this._sessionTimeout);\r\n this._sessionTimeout = null;\r\n }\r\n }\r\n \r\n /**\r\n * Expire the current session\r\n */\r\n _expireSession(reason = 'unknown') {\r\n if (this._isUnlocked) {\r\n this._secureWipeMasterKey();\r\n this._isUnlocked = false;\r\n \r\n if (this._onSessionExpired) {\r\n this._onSessionExpired(reason);\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Initialize IndexedDB if not already done\r\n */\r\n async _ensureDBInitialized() {\r\n if (!this._dbInitialized) {\r\n await this._indexedDB.initialize();\r\n this._dbInitialized = true;\r\n }\r\n }\r\n \r\n /**\r\n * Generate salt for PBKDF2\r\n */\r\n _generateSalt() {\r\n return crypto.getRandomValues(new Uint8Array(this._saltSize));\r\n }\r\n \r\n /**\r\n * Get or create persistent salt\r\n */\r\n async _getOrCreateSalt() {\r\n await this._ensureDBInitialized();\r\n \r\n // Try to get existing salt\r\n let salt = await this._indexedDB.getMasterSalt();\r\n \r\n if (!salt) {\r\n // Generate new salt and store it\r\n salt = this._generateSalt();\r\n await this._indexedDB.storeMasterSalt(salt);\r\n }\r\n \r\n return salt;\r\n }\r\n \r\n /**\r\n * Derive master key from password using PBKDF2\r\n */\r\n async _deriveKeyFromPassword(password, salt) {\r\n try {\r\n // Import password as key material\r\n const passwordKey = await crypto.subtle.importKey(\r\n 'raw',\r\n new TextEncoder().encode(password),\r\n 'PBKDF2',\r\n false,\r\n ['deriveKey']\r\n );\r\n \r\n // Derive AES-GCM key using PBKDF2\r\n const derivedKey = await crypto.subtle.deriveKey(\r\n {\r\n name: 'PBKDF2',\r\n salt: salt,\r\n iterations: this._pbkdf2Iterations,\r\n hash: 'SHA-256'\r\n },\r\n passwordKey,\r\n {\r\n name: 'AES-GCM',\r\n length: 256\r\n },\r\n false, // non-extractable for security\r\n ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']\r\n );\r\n \r\n return derivedKey;\r\n } catch (error) {\r\n throw new Error(`Key derivation failed: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * Request password from user\r\n */\r\n async _requestPassword(isRetry = false) {\r\n if (!this._onPasswordRequired) {\r\n throw new Error('Password callback not set');\r\n }\r\n \r\n return new Promise((resolve, reject) => {\r\n this._onPasswordRequired(isRetry, (password) => {\r\n if (password) {\r\n resolve(password);\r\n } else {\r\n reject(new Error('Password not provided'));\r\n }\r\n });\r\n });\r\n }\r\n \r\n /**\r\n * Unlock the master key with password\r\n */\r\n async unlock(password = null) {\r\n try {\r\n // Request password if not provided\r\n if (!password) {\r\n password = await this._requestPassword(false);\r\n }\r\n \r\n // Get or create persistent salt\r\n const salt = await this._getOrCreateSalt();\r\n \r\n // Derive master key\r\n this._masterKey = await this._deriveKeyFromPassword(password, salt);\r\n \r\n // Mark as unlocked\r\n this._isUnlocked = true;\r\n this._lastActivity = Date.now();\r\n \r\n // Start session timer\r\n this._startSessionTimer();\r\n \r\n // Securely wipe password from memory\r\n password = null;\r\n \r\n if (this._onUnlocked) {\r\n this._onUnlocked();\r\n }\r\n \r\n return { success: true };\r\n \r\n } catch (error) {\r\n // Securely wipe password on error\r\n password = null;\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Lock the master key\r\n */\r\n lock() {\r\n this._expireSession('manual');\r\n }\r\n \r\n /**\r\n * Get master key (only if unlocked)\r\n */\r\n getMasterKey() {\r\n if (!this._isUnlocked || !this._masterKey) {\r\n throw new Error('Master key is locked');\r\n }\r\n \r\n this._updateActivity();\r\n return this._masterKey;\r\n }\r\n \r\n /**\r\n * Check if master key is unlocked\r\n */\r\n isUnlocked() {\r\n return this._isUnlocked && this._masterKey !== null;\r\n }\r\n \r\n /**\r\n * Get session status\r\n */\r\n getSessionStatus() {\r\n return {\r\n isUnlocked: this._isUnlocked,\r\n lastActivity: this._lastActivity,\r\n sessionTimeoutMs: this._sessionTimeoutMs,\r\n inactivityTimeoutMs: this._inactivityTimeoutMs\r\n };\r\n }\r\n \r\n /**\r\n * Securely wipe master key from memory\r\n */\r\n _secureWipeMasterKey() {\r\n if (this._masterKey) {\r\n // CryptoKey objects are automatically garbage collected\r\n // but we clear the reference immediately\r\n this._masterKey = null;\r\n }\r\n this._clearTimers();\r\n }\r\n \r\n /**\r\n * Cleanup on destruction\r\n */\r\n destroy() {\r\n this._secureWipeMasterKey();\r\n this._isUnlocked = false;\r\n \r\n // Remove event listeners\r\n if (typeof document !== 'undefined') {\r\n document.removeEventListener('visibilitychange', this._handleFocusOut);\r\n window.removeEventListener('blur', this._handleFocusOut);\r\n window.removeEventListener('focus', this._handleFocusIn);\r\n }\r\n }\r\n}\r\n\r\nexport { \r\n EnhancedSecureWebRTCManager, \r\n SecureMasterKeyManager, \r\n SecureIndexedDBWrapper, \r\n SecurePersistentKeyStorage \r\n};", "import { EnhancedSecureCryptoUtils } from '../crypto/EnhancedSecureCryptoUtils.js';\r\nimport { EnhancedSecureWebRTCManager } from '../network/EnhancedSecureWebRTCManager.js';\r\nimport { EnhancedSecureFileTransfer } from '../transfer/EnhancedSecureFileTransfer.js';\r\nimport { NotificationIntegration } from '../notifications/NotificationIntegration.js';\r\n\r\n// Import UI components (side-effect: they attach themselves to window.*)\r\nimport '../components/ui/Header.jsx';\r\nimport '../components/ui/DownloadApps.jsx';\r\nimport '../components/ui/UniqueFeatureSlider.jsx';\r\nimport '../components/ui/SecurityFeatures.jsx';\r\nimport '../components/ui/Testimonials.jsx';\r\nimport '../components/ui/ComparisonTable.jsx';\r\nimport '../components/ui/Roadmap.jsx';\r\nimport '../components/ui/FileTransfer.jsx';\r\n\r\n// Expose to global for legacy usage inside app code\r\nwindow.EnhancedSecureCryptoUtils = EnhancedSecureCryptoUtils;\r\nwindow.EnhancedSecureWebRTCManager = EnhancedSecureWebRTCManager;\r\nwindow.EnhancedSecureFileTransfer = EnhancedSecureFileTransfer;\r\nwindow.NotificationIntegration = NotificationIntegration;\r\n\r\n// Mount application once DOM and modules are ready\r\nconst start = () => {\r\n if (typeof window.initializeApp === 'function') {\r\n window.initializeApp();\r\n } else if (window.DEBUG_MODE) {\r\n console.error('initializeApp is not defined on window');\r\n }\r\n};\r\n\r\nif (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', start);\r\n} else {\r\n start();\r\n}\r\n", "const EnhancedMinimalHeader = ({ \n status, \n fingerprint, \n verificationCode, \n onDisconnect, \n isConnected, \n securityLevel, \n webrtcManager \n}) => {\n const [realSecurityLevel, setRealSecurityLevel] = React.useState(null);\n const [lastSecurityUpdate, setLastSecurityUpdate] = React.useState(0);\n // Added local session state to remove references errors after session timer removal\n const [hasActiveSession, setHasActiveSession] = React.useState(false);\n const [currentTimeLeft, setCurrentTimeLeft] = React.useState(0);\n const [sessionType, setSessionType] = React.useState('unknown');\n\n // ============================================\n // FIXED SECURITY UPDATE LOGIC\n // ============================================\n \n React.useEffect(() => {\n let isUpdating = false; \n let lastUpdateAttempt = 0; \n \n const updateRealSecurityStatus = async () => {\n const now = Date.now();\n if (now - lastUpdateAttempt < 10000) { \n return;\n }\n\n if (isUpdating) {\n return;\n }\n \n isUpdating = true;\n lastUpdateAttempt = now;\n \n try {\n if (!webrtcManager || !isConnected) {\n return;\n }\n \n const activeWebrtcManager = webrtcManager;\n \n let realSecurityData = null;\n \n if (typeof activeWebrtcManager.getRealSecurityLevel === 'function') {\n realSecurityData = await activeWebrtcManager.getRealSecurityLevel();\n } else if (typeof activeWebrtcManager.calculateAndReportSecurityLevel === 'function') {\n realSecurityData = await activeWebrtcManager.calculateAndReportSecurityLevel();\n } else {\n realSecurityData = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(activeWebrtcManager);\n }\n \n if (realSecurityData && realSecurityData.isRealData !== false) {\n const currentScore = realSecurityLevel?.score || 0;\n const newScore = realSecurityData.score || 0;\n\n if (currentScore !== newScore || !realSecurityLevel) {\n setRealSecurityLevel(realSecurityData);\n setLastSecurityUpdate(now);\n\n } else if (window.DEBUG_MODE) {\n }\n } else {\n console.warn(' Security calculation returned invalid data');\n }\n \n } catch (error) {\n console.error(' Error in real security calculation:', error);\n } finally {\n isUpdating = false;\n }\n };\n\n if (isConnected) {\n updateRealSecurityStatus();\n \n if (!realSecurityLevel || realSecurityLevel.score < 50) {\n const retryInterval = setInterval(() => {\n if (!realSecurityLevel || realSecurityLevel.score < 50) {\n updateRealSecurityStatus();\n } else {\n clearInterval(retryInterval);\n }\n }, 5000); \n \n setTimeout(() => clearInterval(retryInterval), 30000);\n }\n }\n\n const interval = setInterval(updateRealSecurityStatus, 30000);\n \n return () => clearInterval(interval);\n }, [webrtcManager, isConnected]);\n\n // ============================================\n // FIXED EVENT HANDLERS\n // ============================================\n\n React.useEffect(() => {\n const handleSecurityUpdate = (event) => {\n\n setTimeout(() => {\n setLastSecurityUpdate(0);\n }, 100);\n };\n\n const handleRealSecurityCalculated = (event) => {\n \n if (event.detail && event.detail.securityData) {\n setRealSecurityLevel(event.detail.securityData);\n setLastSecurityUpdate(Date.now());\n }\n };\n\n document.addEventListener('security-level-updated', handleSecurityUpdate);\n document.addEventListener('real-security-calculated', handleRealSecurityCalculated);\n \n window.forceHeaderSecurityUpdate = (webrtcManager) => {\n \n if (webrtcManager && window.EnhancedSecureCryptoUtils) {\n window.EnhancedSecureCryptoUtils.calculateSecurityLevel(webrtcManager)\n .then(securityData => {\n if (securityData && securityData.isRealData !== false) {\n setRealSecurityLevel(securityData);\n setLastSecurityUpdate(Date.now());\n console.log('\u2705 Header security level force-updated');\n }\n })\n .catch(error => {\n console.error('\u274C Force update failed:', error);\n });\n } else {\n setLastSecurityUpdate(0); \n }\n };\n\n return () => {\n document.removeEventListener('security-level-updated', handleSecurityUpdate);\n document.removeEventListener('real-security-calculated', handleRealSecurityCalculated);\n };\n }, []);\n\n // ============================================\n // REST of the component logic\n // ============================================\n\n React.useEffect(() => {\n // All security features are enabled by default - no session management needed\n setHasActiveSession(true);\n setCurrentTimeLeft(0);\n setSessionType('premium'); // All features enabled\n }, []);\n\n React.useEffect(() => {\n // All security features are enabled by default\n setHasActiveSession(true);\n setCurrentTimeLeft(0);\n setSessionType('premium'); // All features enabled\n }, []);\n\n React.useEffect(() => {\n const handleForceUpdate = (event) => {\n // All security features are enabled by default\n setHasActiveSession(true);\n setCurrentTimeLeft(0);\n setSessionType('premium'); // All features enabled\n };\n\n // Connection cleanup handler (use existing event from module)\n const handleConnectionCleaned = () => {\n if (window.DEBUG_MODE) {\n console.log('\uD83E\uDDF9 Connection cleaned - clearing security data in header');\n }\n\n setRealSecurityLevel(null);\n setLastSecurityUpdate(0);\n\n setHasActiveSession(false);\n setCurrentTimeLeft(0);\n setSessionType('unknown');\n };\n\n const handlePeerDisconnect = () => {\n if (window.DEBUG_MODE) {\n console.log('\uD83D\uDC4B Peer disconnect detected - clearing security data in header');\n }\n\n setRealSecurityLevel(null);\n setLastSecurityUpdate(0);\n };\n\n const handleDisconnected = () => {\n\n setRealSecurityLevel(null);\n setLastSecurityUpdate(0);\n setHasActiveSession(false);\n setCurrentTimeLeft(0);\n setSessionType('unknown');\n };\n\n document.addEventListener('force-header-update', handleForceUpdate);\n document.addEventListener('peer-disconnect', handlePeerDisconnect);\n document.addEventListener('connection-cleaned', handleConnectionCleaned);\n document.addEventListener('disconnected', handleDisconnected);\n \n return () => {\n document.removeEventListener('force-header-update', handleForceUpdate);\n document.removeEventListener('peer-disconnect', handlePeerDisconnect);\n document.removeEventListener('connection-cleaned', handleConnectionCleaned);\n document.removeEventListener('disconnected', handleDisconnected);\n };\n }, []);\n\n // ============================================\n // SECURITY INDICATOR CLICK HANDLER\n // ============================================\n\n const handleSecurityClick = async (event) => {\n // Check if it's a right-click or Ctrl+click to disconnect\n if (event && (event.button === 2 || event.ctrlKey || event.metaKey)) {\n if (onDisconnect && typeof onDisconnect === 'function') {\n onDisconnect();\n return;\n }\n }\n\n // Prevent default behavior\n event.preventDefault();\n event.stopPropagation();\n\n\n // Run real security tests if webrtcManager is available\n let realTestResults = null;\n if (webrtcManager && window.EnhancedSecureCryptoUtils) {\n try {\n realTestResults = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(webrtcManager);\n console.log('\u2705 Real security tests completed:', realTestResults);\n } catch (error) {\n console.error('\u274C Real security tests failed:', error);\n }\n } else {\n console.log('\u26A0\uFE0F Cannot run security tests:', {\n webrtcManager: !!webrtcManager,\n cryptoUtils: !!window.EnhancedSecureCryptoUtils\n });\n }\n\n // If no real test results and no existing security level, show progress message\n if (!realTestResults && !realSecurityLevel) {\n alert('Security verification in progress...\\nPlease wait for real-time cryptographic verification to complete.');\n return;\n }\n\n // Use real test results if available, otherwise fall back to current data\n let securityData = realTestResults || realSecurityLevel;\n\n // If still no security data, create a basic fallback\n if (!securityData) {\n securityData = {\n level: 'UNKNOWN',\n score: 0,\n color: 'gray',\n verificationResults: {},\n timestamp: Date.now(),\n details: 'Security verification not available',\n isRealData: false,\n passedChecks: 0,\n totalChecks: 0\n };\n console.log('Using fallback security data:', securityData);\n }\n\n // Detailed information about the REAL security check\n let message = `REAL-TIME SECURITY VERIFICATION\\n\\n`;\n message += `Security Level: ${securityData.level} (${securityData.score}%)\\n`;\n message += `Verification Time: ${new Date(securityData.timestamp).toLocaleTimeString()}\\n`;\n message += `Data Source: ${securityData.isRealData ? 'Real Cryptographic Tests' : 'Simulated Data'}\\n\\n`;\n \n if (securityData.verificationResults) {\n message += 'DETAILED CRYPTOGRAPHIC TESTS:\\n';\n message += '=' + '='.repeat(40) + '\\n';\n \n const passedTests = Object.entries(securityData.verificationResults).filter(([key, result]) => result.passed);\n const failedTests = Object.entries(securityData.verificationResults).filter(([key, result]) => !result.passed);\n \n if (passedTests.length > 0) {\n message += 'PASSED TESTS:\\n';\n passedTests.forEach(([key, result]) => {\n const testName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());\n message += ` ${testName}: ${result.details || 'Test passed'}\\n`;\n });\n message += '\\n';\n }\n \n if (failedTests.length > 0) {\n message += 'FAILED/UNAVAILABLE TESTS:\\n';\n failedTests.forEach(([key, result]) => {\n const testName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());\n message += ` ${testName}: ${result.details || 'Test failed or unavailable'}\\n`;\n });\n message += '\\n';\n }\n \n message += `SUMMARY:\\n`;\n message += `Passed: ${securityData.passedChecks}/${securityData.totalChecks} tests\\n`;\n message += `Score: ${securityData.score}/${securityData.maxPossibleScore || 100} points\\n\\n`;\n }\n \n // Real security features status\n message += `SECURITY FEATURES STATUS:\\n`;\n message += '=' + '='.repeat(40) + '\\n';\n \n if (securityData.verificationResults) {\n const features = {\n 'ECDSA Digital Signatures': securityData.verificationResults.verifyECDSASignatures?.passed || false,\n 'ECDH Key Exchange': securityData.verificationResults.verifyECDHKeyExchange?.passed || false,\n 'AES-GCM Encryption': securityData.verificationResults.verifyEncryption?.passed || false,\n 'Message Integrity (HMAC)': securityData.verificationResults.verifyMessageIntegrity?.passed || false,\n 'Perfect Forward Secrecy': securityData.verificationResults.verifyPerfectForwardSecrecy?.passed || false,\n 'Replay Protection': securityData.verificationResults.verifyReplayProtection?.passed || false,\n 'DTLS Fingerprint': securityData.verificationResults.verifyDTLSFingerprint?.passed || false,\n 'SAS Verification': securityData.verificationResults.verifySASVerification?.passed || false,\n 'Metadata Protection': securityData.verificationResults.verifyMetadataProtection?.passed || false,\n 'Traffic Obfuscation': securityData.verificationResults.verifyTrafficObfuscation?.passed || false\n };\n \n Object.entries(features).forEach(([feature, isEnabled]) => {\n message += `${isEnabled ? '\u2705' : '\u274C'} ${feature}\\n`;\n });\n } else {\n // Fallback if no verification results\n message += `\u2705 ECDSA Digital Signatures\\n`;\n message += `\u2705 ECDH Key Exchange\\n`;\n message += `\u2705 AES-GCM Encryption\\n`;\n message += `\u2705 Message Integrity (HMAC)\\n`;\n message += `\u2705 Perfect Forward Secrecy\\n`;\n message += `\u2705 Replay Protection\\n`;\n message += `\u2705 DTLS Fingerprint\\n`;\n message += `\u2705 SAS Verification\\n`;\n message += `\u2705 Metadata Protection\\n`;\n message += `\u2705 Traffic Obfuscation\\n`;\n }\n \n message += `\\n${securityData.details || 'Real cryptographic verification completed'}`;\n \n if (securityData.isRealData) {\n message += '\\n\\n\u2705 This is REAL-TIME verification using actual cryptographic functions.';\n } else {\n message += '\\n\\n\u26A0\uFE0F Warning: This data may be simulated. Connection may not be fully established.';\n }\n \n // Show in a more user-friendly way\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0,0,0,0.8);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n font-family: monospace;\n `;\n \n const content = document.createElement('div');\n content.style.cssText = `\n background: #1a1a1a;\n color: #fff;\n padding: 20px;\n border-radius: 8px;\n max-width: 80%;\n max-height: 80%;\n overflow-y: auto;\n white-space: pre-line;\n border: 1px solid #333;\n `;\n \n content.textContent = message;\n modal.appendChild(content);\n \n // Close on click outside\n modal.addEventListener('click', (e) => {\n if (e.target === modal) {\n document.body.removeChild(modal);\n }\n });\n \n // Close on Escape key\n const handleKeyDown = (e) => {\n if (e.key === 'Escape') {\n document.body.removeChild(modal);\n document.removeEventListener('keydown', handleKeyDown);\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n \n document.body.appendChild(modal);\n };\n\n // ============================================\n // DISPLAY UTILITIES\n // ============================================\n\n const getStatusConfig = () => {\n switch (status) {\n case 'connected':\n return {\n text: 'Connected',\n className: 'status-connected',\n badgeClass: 'bg-green-500/10 text-green-400 border-green-500/20'\n };\n case 'verifying':\n return {\n text: 'Verifying...',\n className: 'status-verifying',\n badgeClass: 'bg-purple-500/10 text-purple-400 border-purple-500/20'\n };\n case 'connecting':\n return {\n text: 'Connecting...',\n className: 'status-connecting',\n badgeClass: 'bg-blue-500/10 text-blue-400 border-blue-500/20'\n };\n case 'retrying':\n return {\n text: 'Retrying...',\n className: 'status-connecting',\n badgeClass: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20'\n };\n case 'failed':\n return {\n text: 'Error',\n className: 'status-failed',\n badgeClass: 'bg-red-500/10 text-red-400 border-red-500/20'\n };\n case 'reconnecting':\n return {\n text: 'Reconnecting...',\n className: 'status-connecting',\n badgeClass: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20'\n };\n case 'peer_disconnected':\n return {\n text: 'Peer disconnected',\n className: 'status-failed',\n badgeClass: 'bg-orange-500/10 text-orange-400 border-orange-500/20'\n };\n default:\n return {\n text: 'Not connected',\n className: 'status-disconnected',\n badgeClass: 'bg-gray-500/10 text-gray-400 border-gray-500/20'\n };\n }\n };\n\n const config = getStatusConfig();\n const displaySecurityLevel = isConnected ? (realSecurityLevel || securityLevel) : null;\n \n\n // ============================================\n // DATA RELIABILITY INDICATOR\n // ============================================\n\n const getSecurityIndicatorDetails = () => {\n if (!displaySecurityLevel) {\n return {\n tooltip: 'Security verification in progress...',\n isVerified: false,\n dataSource: 'loading'\n };\n }\n \n const isRealData = displaySecurityLevel.isRealData !== false;\n const baseTooltip = `${displaySecurityLevel.level} (${displaySecurityLevel.score}%)`;\n \n if (isRealData) {\n return {\n tooltip: `${baseTooltip} - Real-time verification \u2705\\nRight-click or Ctrl+click to disconnect`,\n isVerified: true,\n dataSource: 'real'\n };\n } else {\n return {\n tooltip: `${baseTooltip} - Estimated (connection establishing...)\\nRight-click or Ctrl+click to disconnect`,\n isVerified: false,\n dataSource: 'estimated'\n };\n }\n };\n\n const securityDetails = getSecurityIndicatorDetails();\n\n // ============================================\n // ADDING global methods for debugging\n // ============================================\n\n React.useEffect(() => {\n window.debugHeaderSecurity = () => {\n console.log('\uD83D\uDD0D Header Security Debug:', {\n realSecurityLevel,\n lastSecurityUpdate,\n isConnected,\n webrtcManagerProp: !!webrtcManager,\n windowWebrtcManager: !!window.webrtcManager,\n cryptoUtils: !!window.EnhancedSecureCryptoUtils,\n displaySecurityLevel: displaySecurityLevel,\n securityDetails: securityDetails\n });\n };\n \n return () => {\n delete window.debugHeaderSecurity;\n };\n }, [realSecurityLevel, lastSecurityUpdate, isConnected, webrtcManager, displaySecurityLevel, securityDetails]);\n\n // ============================================\n // RENDER\n // ============================================\n\n return React.createElement('header', {\n className: 'header-minimal sticky top-0 z-50'\n }, [\n React.createElement('div', {\n key: 'container',\n className: 'max-w-7xl mx-auto px-4 sm:px-6 lg:px-8'\n }, [\n React.createElement('div', {\n key: 'content',\n className: 'flex items-center justify-between h-16'\n }, [\n // Logo and Title\n React.createElement('div', {\n key: 'logo-section',\n className: 'flex items-center space-x-2 sm:space-x-3'\n }, [\n React.createElement('div', {\n key: 'logo',\n className: 'icon-container w-8 h-8 sm:w-10 sm:h-10'\n }, [\n React.createElement('i', {\n className: 'fas fa-shield-halved accent-orange text-sm sm:text-base'\n })\n ]),\n React.createElement('div', {\n key: 'title-section'\n }, [\n React.createElement('h1', {\n key: 'title',\n className: 'text-lg sm:text-xl font-semibold text-primary'\n }, 'SecureBit.chat'),\n React.createElement('p', {\n key: 'subtitle',\n className: 'text-xs sm:text-sm text-muted hidden sm:block'\n }, 'End-to-end freedom v4.4.99')\n ])\n ]),\n\n // Status and Controls - Responsive\n React.createElement('div', {\n key: 'status-section',\n className: 'flex items-center space-x-2 sm:space-x-3'\n }, [\n\n displaySecurityLevel && React.createElement('div', {\n key: 'security-level',\n className: 'hidden md:flex items-center space-x-2 cursor-pointer hover:opacity-80 transition-opacity duration-200',\n onClick: handleSecurityClick,\n onContextMenu: (e) => {\n e.preventDefault();\n if (onDisconnect && typeof onDisconnect === 'function') {\n onDisconnect();\n }\n },\n title: securityDetails.tooltip\n }, [\n React.createElement('div', {\n key: 'security-icon',\n className: `w-6 h-6 rounded-full flex items-center justify-center relative ${\n displaySecurityLevel.color === 'green' ? 'bg-green-500/20' :\n displaySecurityLevel.color === 'orange' ? 'bg-orange-500/20' :\n displaySecurityLevel.color === 'yellow' ? 'bg-yellow-500/20' : 'bg-red-500/20'\n } ${securityDetails.isVerified ? '' : 'animate-pulse'}`\n }, [\n React.createElement('i', {\n className: `fas fa-shield-alt text-xs ${\n displaySecurityLevel.color === 'green' ? 'text-green-400' :\n displaySecurityLevel.color === 'orange' ? 'text-orange-400' :\n displaySecurityLevel.color === 'yellow' ? 'text-yellow-400' : 'text-red-400'\n }`\n })\n ]),\n React.createElement('div', {\n key: 'security-info',\n className: 'flex flex-col'\n }, [\n React.createElement('div', {\n key: 'security-level-text',\n className: 'text-xs font-medium text-primary flex items-center space-x-1'\n }, [\n React.createElement('span', {}, `${displaySecurityLevel.level} (${displaySecurityLevel.score}%)`)\n ]),\n React.createElement('div', {\n key: 'security-details',\n className: 'text-xs text-muted mt-1 hidden lg:block'\n }, securityDetails.dataSource === 'real' ? \n `${displaySecurityLevel.passedChecks || 0}/${displaySecurityLevel.totalChecks || 0} tests` :\n (displaySecurityLevel.details || `Stage ${displaySecurityLevel.stage || 1}`)\n ),\n React.createElement('div', {\n key: 'security-progress',\n className: 'w-16 h-1 bg-gray-600 rounded-full overflow-hidden'\n }, [\n React.createElement('div', {\n key: 'progress-bar',\n className: `h-full transition-all duration-500 ${\n displaySecurityLevel.color === 'green' ? 'bg-green-400' :\n displaySecurityLevel.color === 'orange' ? 'bg-orange-400' :\n displaySecurityLevel.color === 'yellow' ? 'bg-yellow-400' : 'bg-red-400'\n }`,\n style: { width: `${displaySecurityLevel.score}%` }\n })\n ])\n ])\n ]),\n\n // Mobile Security Indicator\n displaySecurityLevel && React.createElement('div', {\n key: 'mobile-security',\n className: 'md:hidden flex items-center'\n }, [\n React.createElement('div', {\n key: 'mobile-security-icon',\n className: `w-8 h-8 rounded-full flex items-center justify-center cursor-pointer hover:opacity-80 transition-opacity duration-200 relative ${\n displaySecurityLevel.color === 'green' ? 'bg-green-500/20' :\n displaySecurityLevel.color === 'orange' ? 'bg-orange-500/20' :\n displaySecurityLevel.color === 'yellow' ? 'bg-yellow-500/20' : 'bg-red-500/20'\n } ${securityDetails.isVerified ? '' : 'animate-pulse'}`,\n title: securityDetails.tooltip,\n onClick: handleSecurityClick,\n onContextMenu: (e) => {\n e.preventDefault();\n if (onDisconnect && typeof onDisconnect === 'function') {\n onDisconnect();\n }\n }\n }, [\n React.createElement('i', {\n className: `fas fa-shield-alt text-sm ${\n displaySecurityLevel.color === 'green' ? 'text-green-400' :\n displaySecurityLevel.color === 'orange' ? 'text-orange-400' :\n displaySecurityLevel.color === 'yellow' ? 'text-yellow-400' : 'text-red-400'\n }`\n })\n ])\n ]),\n\n // Status Badge\n React.createElement('div', {\n key: 'status-badge',\n className: `px-2 sm:px-3 py-1.5 rounded-lg border ${config.badgeClass} flex items-center space-x-1 sm:space-x-2`\n }, [\n React.createElement('span', {\n key: 'status-dot',\n className: `status-dot ${config.className}`\n }),\n React.createElement('span', {\n key: 'status-text',\n className: 'text-xs sm:text-sm font-medium'\n }, config.text),\n ]),\n\n // Disconnect Button\n isConnected && React.createElement('button', {\n key: 'disconnect-btn',\n onClick: onDisconnect,\n className: 'p-1.5 sm:px-3 sm:py-1.5 bg-red-500/10 hover:bg-red-500/20 text-red-400 border border-red-500/20 rounded-lg transition-all duration-200 text-sm'\n }, [\n React.createElement('i', {\n className: 'fas fa-power-off sm:mr-2'\n }),\n React.createElement('span', {\n className: 'hidden sm:inline'\n }, 'Disconnect')\n ])\n ])\n ])\n ])\n ]);\n};\n\nwindow.EnhancedMinimalHeader = EnhancedMinimalHeader;\n", "const DownloadApps = () => {\r\n const apps = [\r\n { id: 'web', name: 'Web App', subtitle: 'Browser Version', icon: 'fas fa-globe', platform: 'Web', isActive: true, url: 'https://securebit.chat/', color: 'green' },\r\n { id: 'windows', name: 'Windows', subtitle: 'Desktop App', icon: 'fab fa-windows', platform: 'Desktop', isActive: false, url: 'https://securebit.chat/download/windows/SecureBit%20Chat%20Setup%204.1.222.exe', color: 'blue' },\r\n { id: 'macos', name: 'macOS', subtitle: 'Desktop App', icon: 'fab fa-safari', platform: 'Desktop', isActive: false, url: '#', color: 'gray' },\r\n { id: 'linux', name: 'Linux', subtitle: 'Desktop App', icon: 'fab fa-linux', platform: 'Desktop', isActive: false, url: '#', color: 'orange' },\r\n { id: 'ios', name: 'iOS', subtitle: 'iPhone & iPad', icon: 'fab fa-apple', platform: 'Mobile', isActive: false, url: 'https://apps.apple.com/app/securebit-chat/', color: 'white' },\r\n { id: 'android', name: 'Android', subtitle: 'Google Play', icon: 'fab fa-android', platform: 'Mobile', isActive: false, url: 'https://play.google.com/store/apps/details?id=com.securebit.chat', color: 'green' },\r\n { id: 'chrome', name: 'Chrome', subtitle: 'Browser Extension', icon: 'fab fa-chrome', platform: 'Browser', isActive: false, url: '#', color: 'yellow' },\r\n { id: 'edge', name: 'Edge', subtitle: 'Browser Extension', icon: 'fab fa-edge', platform: 'Browser', isActive: false, url: '#', color: 'blue' },\r\n { id: 'opera', name: 'Opera', subtitle: 'Browser Extension', icon: 'fab fa-opera', platform: 'Browser', isActive: false, url: '#', color: 'red' },\r\n { id: 'firefox', name: 'Firefox', subtitle: 'Browser Extension', icon: 'fab fa-firefox-browser', platform: 'Browser', isActive: false, url: '#', color: 'orange' },\r\n ];\r\n\r\n const handleDownload = (app) => {\r\n if (app.isActive) window.open(app.url, '_blank');\r\n };\r\n\r\n const desktopApps = apps.filter(a => a.platform === 'Desktop' || a.platform === 'Web');\r\n const mobileApps = apps.filter(a => a.platform === 'Mobile');\r\n const browserApps = apps.filter(a => a.platform === 'Browser');\r\n\r\n const cardSize = \"w-28 h-28\";\r\n\r\n const colorClasses = {\r\n green: 'text-green-500',\r\n blue: 'text-blue-500',\r\n gray: 'text-gray-500',\r\n orange: 'text-orange-500',\r\n red: 'text-red-500',\r\n white: 'text-white',\r\n yellow: 'text-yellow-400',\r\n };\r\n\r\n const renderAppCard = (app) => (\r\n React.createElement('div', {\r\n key: app.id,\r\n className: `group relative ${cardSize} rounded-2xl overflow-hidden card-minimal cursor-pointer`\r\n }, [\r\n React.createElement('i', {\r\n key: 'bg-icon',\r\n className: `${app.icon} absolute text-[3rem] ${app.isActive ? colorClasses[app.color] : 'text-white/10'} top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none transition-all duration-500 group-hover:scale-105`\r\n }),\r\n React.createElement('div', {\r\n key: 'overlay',\r\n className: \"absolute inset-0 bg-black/30 backdrop-blur-md flex flex-col items-center justify-center text-center opacity-0 transition-opacity duration-300 group-hover:opacity-100\"\r\n }, [\r\n React.createElement('h4', { key: 'name', className: `text-sm font-semibold text-primary mb-1` }, app.name),\r\n React.createElement('p', { key: 'subtitle', className: `text-xs text-secondary mb-2` }, app.subtitle),\r\n app.isActive ?\r\n React.createElement('button', {\r\n key: 'btn',\r\n onClick: () => handleDownload(app),\r\n className: `px-2 py-1 rounded-xl bg-emerald-500 text-black font-medium hover:bg-emerald-600 transition-colors text-xs`\r\n }, app.id === \"web\" ? \"Launch\" : \"Download\")\r\n :\r\n React.createElement('span', { key: 'coming', className: \"text-gray-400 font-medium text-xs\" }, \"Coming Soon\")\r\n ])\r\n ])\r\n );\r\n\r\n return React.createElement('div', { className: \"mt-20 px-6\" }, [\r\n // Header\r\n React.createElement('div', { key: 'header', className: \"text-center max-w-3xl mx-auto mb-12\" }, [\r\n React.createElement('h3', { key: 'title', className: \"text-3xl font-bold text-primary mb-3\" }, 'Download SecureBit.chat'),\r\n React.createElement('p', { key: 'subtitle', className: \"text-secondary text-lg mb-5\" }, 'Stay secure on every device. Choose your platform and start chatting privately.')\r\n ]),\r\n\r\n // Desktop Apps\r\n React.createElement('div', { key: 'desktop-row', className: \"hidden sm:flex justify-center flex-wrap gap-6 mb-6\" },\r\n desktopApps.map(renderAppCard)\r\n ),\r\n\r\n // Mobile Apps\r\n React.createElement('div', { key: 'mobile-row', className: \"flex justify-center gap-6 mb-6\" },\r\n mobileApps.map(renderAppCard)\r\n ),\r\n\r\n // Browser Extensions\r\n React.createElement('div', { key: 'browser-row', className: \"flex justify-center gap-6\" },\r\n browserApps.map(renderAppCard)\r\n )\r\n ]);\r\n};\r\n\r\nwindow.DownloadApps = DownloadApps;\r\n", "// Enhanced Modern Slider Component with Loading Protection\r\nconst UniqueFeatureSlider = () => {\r\n const trackRef = React.useRef(null);\r\n const wrapRef = React.useRef(null);\r\n const [current, setCurrent] = React.useState(0);\r\n const [isReady, setIsReady] = React.useState(false);\r\n\r\n const slides = [\r\n {\r\n icon: \"\uD83D\uDEE1\uFE0F\",\r\n bgImage: \"linear-gradient(135deg, rgb(255 107 53 / 6%) 0%, rgb(255 140 66 / 45%) 100%)\",\r\n thumbIcon: \"\uD83D\uDD12\",\r\n title: \"18-Layer Military Security\",\r\n description: \"Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA + Complete ASN.1 Validation.\"\r\n },\r\n {\r\n icon: \"\uD83C\uDF10\",\r\n bgImage: \"linear-gradient(135deg, rgb(147 51 234 / 6%) 0%, rgb(168 85 247 / 45%) 100%)\",\r\n thumbIcon: \"\uD83D\uDD17\",\r\n title: \"Pure P2P WebRTC\",\r\n description: \"Direct peer-to-peer connections without any servers. Complete decentralization with zero infrastructure.\"\r\n },\r\n {\r\n icon: \"\uD83D\uDD04\",\r\n bgImage: \"linear-gradient(135deg, rgb(16 185 129 / 6%) 0%, rgb(52 211 153 / 45%) 100%)\",\r\n thumbIcon: \"\u26A1\",\r\n title: \"Perfect Forward Secrecy\",\r\n description: \"Automatic key rotation every 5 minutes. Non-extractable keys with hardware protection.\"\r\n },\r\n {\r\n icon: \"\uD83C\uDFAD\",\r\n bgImage: \"linear-gradient(135deg, rgb(6 182 212 / 6%) 0%, rgb(34 211 238 / 45%) 100%)\",\r\n thumbIcon: \"\uD83C\uDF2B\uFE0F\",\r\n title: \"Traffic Obfuscation\",\r\n description: \"Fake traffic generation and pattern masking make communication indistinguishable from noise.\"\r\n },\r\n {\r\n icon: \"\uD83D\uDC41\uFE0F\",\r\n bgImage: \"linear-gradient(135deg, rgb(37 99 235 / 6%) 0%, rgb(59 130 246 / 45%) 100%)\",\r\n thumbIcon: \"\uD83D\uDEAB\",\r\n title: \"Zero Data Collection\",\r\n description: \"No registration, no servers, no logs. Complete anonymity with instant channels.\"\r\n }\r\n ];\r\n\r\n // \u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430\r\n React.useEffect(() => {\r\n const timer = setTimeout(() => {\r\n setIsReady(true);\r\n }, 100);\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n const isMobile = () => window.matchMedia(\"(max-width:767px)\").matches;\r\n\r\n const center = React.useCallback((i) => {\r\n if (!trackRef.current || !wrapRef.current) return;\r\n const card = trackRef.current.children[i];\r\n if (!card) return;\r\n\r\n const axis = isMobile() ? \"top\" : \"left\";\r\n const size = isMobile() ? \"clientHeight\" : \"clientWidth\";\r\n const start = isMobile() ? card.offsetTop : card.offsetLeft;\r\n \r\n wrapRef.current.scrollTo({\r\n [axis]: start - (wrapRef.current[size] / 2 - card[size] / 2),\r\n behavior: \"smooth\"\r\n });\r\n }, []);\r\n\r\n const activate = React.useCallback((i, scroll = false) => {\r\n if (i === current) return;\r\n setCurrent(i);\r\n if (scroll) {\r\n setTimeout(() => center(i), 50);\r\n }\r\n }, [current, center]);\r\n\r\n const go = (step) => {\r\n const newIndex = Math.min(Math.max(current + step, 0), slides.length - 1);\r\n activate(newIndex, true);\r\n };\r\n\r\n React.useEffect(() => {\r\n const handleKeydown = (e) => {\r\n if ([\"ArrowRight\", \"ArrowDown\"].includes(e.key)) go(1);\r\n if ([\"ArrowLeft\", \"ArrowUp\"].includes(e.key)) go(-1);\r\n };\r\n\r\n window.addEventListener(\"keydown\", handleKeydown, { passive: true });\r\n return () => window.removeEventListener(\"keydown\", handleKeydown);\r\n }, [current]);\r\n\r\n React.useEffect(() => {\r\n if (isReady) {\r\n center(current);\r\n }\r\n }, [current, center, isReady]);\r\n // Render loading state if not ready\r\n if (!isReady) {\r\n return React.createElement('section', { \r\n style: { \r\n background: 'transparent',\r\n minHeight: '400px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n } \r\n }, \r\n React.createElement('div', { \r\n style: { \r\n opacity: 0.5,\r\n fontSize: '14px',\r\n color: '#fff'\r\n }\r\n }, 'Loading...')\r\n );\r\n }\r\n\r\n return React.createElement('section', { style: { background: 'transparent' } }, [\r\n // Header\r\n React.createElement('div', { \r\n key: 'head',\r\n className: 'head'\r\n }, [\r\n React.createElement('h2', { \r\n key: 'title', \r\n className: 'text-2xl sm:text-3xl font-bold text-white mb-4 leading-snug' \r\n }, 'Why SecureBit.chat is unique'),\r\n React.createElement('div', { \r\n key: 'controls',\r\n className: 'controls'\r\n }, [\r\n React.createElement('button', {\r\n key: 'prev',\r\n id: 'prev-slider',\r\n className: 'nav-btn',\r\n 'aria-label': 'Prev',\r\n disabled: current === 0,\r\n onClick: () => go(-1)\r\n }, '\u2039'),\r\n React.createElement('button', {\r\n key: 'next',\r\n id: 'next-slider',\r\n className: 'nav-btn',\r\n 'aria-label': 'Next',\r\n disabled: current === slides.length - 1,\r\n onClick: () => go(1)\r\n }, '\u203A')\r\n ])\r\n ]),\r\n\r\n // Slider\r\n React.createElement('div', {\r\n key: 'slider',\r\n className: 'slider',\r\n ref: wrapRef\r\n },\r\n React.createElement('div', {\r\n className: 'track',\r\n ref: trackRef\r\n }, slides.map((slide, index) =>\r\n React.createElement('article', {\r\n key: index,\r\n className: 'project-card',\r\n ...(index === current ? { active: '' } : {}),\r\n onMouseEnter: () => {\r\n if (window.matchMedia(\"(hover:hover)\").matches) {\r\n activate(index, true);\r\n }\r\n },\r\n onClick: () => activate(index, true)\r\n }, [\r\n // Background\r\n React.createElement('div', {\r\n key: 'bg',\r\n className: 'project-card__bg',\r\n style: {\r\n background: slide.bgImage,\r\n backgroundSize: 'cover',\r\n backgroundPosition: 'center'\r\n }\r\n }),\r\n\r\n // Content\r\n React.createElement('div', {\r\n key: 'content',\r\n className: 'project-card__content'\r\n }, [\r\n // Text container\r\n React.createElement('div', { key: 'text' }, [\r\n React.createElement('h3', {\r\n key: 'title',\r\n className: 'project-card__title'\r\n }, slide.title),\r\n React.createElement('p', {\r\n key: 'desc',\r\n className: 'project-card__desc'\r\n }, slide.description)\r\n ])\r\n ])\r\n ])\r\n ))\r\n ),\r\n ]);\r\n};\r\n\r\n// Export for use in your app\r\nwindow.UniqueFeatureSlider = UniqueFeatureSlider;", "const SecurityFeatures = () => {\r\n const features = [\r\n { id: 'feature1', color: '#00ff88', icon: 'fas fa-key accent-green', title: 'ECDH P-384 Key Exchange', desc: 'Military-grade elliptic curve key exchange' },\r\n { id: 'feature2', color: '#a78bfa', icon: 'fas fa-user-shield accent-purple', title: 'MITM Protection', desc: 'Out-of-band verification against attacks' },\r\n { id: 'feature3', color: '#ff8800', icon: 'fas fa-lock accent-orange', title: 'AES-GCM 256 Encryption', desc: 'Authenticated encryption standard' },\r\n { id: 'feature4', color: '#00ffff', icon: 'fas fa-sync-alt accent-cyan', title: 'Perfect Forward Secrecy', desc: 'Automatic key rotation every 5 minutes' },\r\n { id: 'feature5', color: '#0088ff', icon: 'fas fa-signature accent-blue', title: 'ECDSA P-384 Signatures', desc: 'Digital signatures for message integrity' },\r\n { id: 'feature6', color: '#f87171', icon: 'fas fa-shield-alt accent-red', title: 'SAS Security', desc: 'Revolutionary key exchange & MITM protection' }\r\n ];\r\n\r\n React.useEffect(() => {\r\n const cards = document.querySelectorAll(\".card\");\r\n const radius = 200; \r\n\r\n const handleMove = (e) => {\r\n cards.forEach((card) => {\r\n const rect = card.getBoundingClientRect();\r\n const cx = rect.left + rect.width / 2;\r\n const cy = rect.top + rect.height / 2;\r\n\r\n const dx = e.clientX - cx;\r\n const dy = e.clientY - cy;\r\n const dist = Math.sqrt(dx * dx + dy * dy);\r\n\r\n if (dist < radius) {\r\n const x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n card.style.setProperty(\"--x\", `${x}px`);\r\n card.style.setProperty(\"--y\", `${y}px`);\r\n card.classList.add(\"active-glow\");\r\n } else {\r\n card.classList.remove(\"active-glow\");\r\n }\r\n });\r\n };\r\n\r\n window.addEventListener(\"mousemove\", handleMove);\r\n return () => window.removeEventListener(\"mousemove\", handleMove);\r\n }, []);\r\n\r\n const renderFeature = (f) =>\r\n React.createElement('div', {\r\n key: f.id,\r\n className: \"card p-3 sm:p-4 text-center\",\r\n style: { \"--color\": f.color }\r\n }, [\r\n React.createElement('div', { key: 'icon', className: \"w-10 h-10 sm:w-12 sm:h-12 flex items-center justify-center mx-auto mb-2 sm:mb-3 relative z-10\" }, [\r\n React.createElement('i', { className: f.icon })\r\n ]),\r\n React.createElement('h4', { key: 'title', className: \"text-xs sm:text-sm font-medium text-primary mb-1 relative z-10\" }, f.title),\r\n React.createElement('p', { key: 'desc', className: \"text-xs text-muted leading-tight relative z-10\" }, f.desc)\r\n ]);\r\n\r\n return React.createElement('div', {\r\n className: \"grid grid-cols-2 md:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4 max-w-6xl mx-auto mt-8\"\r\n }, features.map(renderFeature));\r\n};\r\n\r\nwindow.SecurityFeatures = SecurityFeatures;\r\n", "const Testimonials = () => {\r\n const testimonials = [\r\n { id: \"t1\", rating: 5.0, text: \"The interface feels modern and smooth. It saves me at least 2 hours every day when managing design tasks.\"},\r\n { id: \"t2\", rating: 5.0, text: \"Finally, a solution that blends speed with simplicity. My team adopted it within a week without training.\"},\r\n { id: \"t3\", rating: 5.0, text: \"I can track progress in real time and get a clear overview of our workflow. It feels empowering.\"},\r\n { id: \"t4\", rating: 5.0, text: \"Our pipeline visibility improved dramatically. I no longer need to manually track updates.\"},\r\n { id: \"t5\", rating: 5.0, text: \"The security-first approach gives me peace of mind. We handle sensitive data with confidence now.\"},\r\n { id: \"t6\", rating: 5.0, text: \"User feedback cycles are now twice as fast. It helps us test and ship features quickly.\"}\r\n ];\r\n\r\n React.useEffect(() => {\r\n const colUp = document.querySelector(\".col-up\");\r\n const colDown = document.querySelector(\".col-down\");\r\n const wrapper = document.querySelector(\".testimonials-wrapper\");\r\n\r\n if (!colUp || !colDown || !wrapper) return;\r\n\r\n let paused = false;\r\n const speed = 0.5;\r\n let animationId;\r\n\r\n const cloneCards = (container) => {\r\n const cards = Array.from(container.children);\r\n cards.forEach(card => {\r\n const clone = card.cloneNode(true);\r\n container.appendChild(clone);\r\n });\r\n };\r\n\r\n cloneCards(colUp);\r\n cloneCards(colDown);\r\n\r\n const getHalfHeight = (el) => {\r\n const children = Array.from(el.children);\r\n const halfCount = children.length / 2;\r\n let height = 0;\r\n for (let i = 0; i < halfCount; i++) {\r\n height += children[i].offsetHeight;\r\n if (i < halfCount - 1) height += 24; \r\n }\r\n return height;\r\n };\r\n\r\n let y1 = 0;\r\n const maxScroll1 = getHalfHeight(colUp);\r\n const maxScroll2 = getHalfHeight(colDown);\r\n let y2 = -maxScroll2; \r\n\r\n function animate() {\r\n if (!paused) {\r\n y1 -= speed;\r\n y2 += speed;\r\n\r\n if (Math.abs(y1) >= maxScroll1) {\r\n y1 = 0;\r\n }\r\n \r\n if (y2 >= 0) {\r\n y2 = -maxScroll2;\r\n }\r\n\r\n colUp.style.transform = `translateY(${y1}px)`;\r\n colDown.style.transform = `translateY(${y2}px)`;\r\n }\r\n animationId = requestAnimationFrame(animate);\r\n }\r\n\r\n animate();\r\n\r\n const handleMouseEnter = () => { paused = true; };\r\n const handleMouseLeave = () => { paused = false; };\r\n\r\n wrapper.addEventListener(\"mouseenter\", handleMouseEnter);\r\n wrapper.addEventListener(\"mouseleave\", handleMouseLeave);\r\n\r\n return () => {\r\n cancelAnimationFrame(animationId);\r\n wrapper.removeEventListener(\"mouseenter\", handleMouseEnter);\r\n wrapper.removeEventListener(\"mouseleave\", handleMouseLeave);\r\n };\r\n }, []);\r\n\r\n const renderCard = (t, index) => (\r\n
\r\n
\r\n {\"\u2605\".repeat(Math.floor(t.rating))}\r\n {t.rating.toFixed(1)}\r\n
\r\n

{t.text}

\r\n
\r\n );\r\n\r\n return (\r\n
\r\n
\r\n
\r\n

Testimonials

\r\n

\r\n What our users are saying\r\n

\r\n

\r\n We continuously listen to our community and improve every day.\r\n

\r\n
\r\n\r\n
\r\n
\r\n
\r\n\r\n
\r\n {testimonials.map((t, i) => renderCard(t, i))}\r\n
\r\n\r\n
\r\n {testimonials.map((t, i) => renderCard(t, i))}\r\n
\r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nwindow.Testimonials = Testimonials;\r\n", "\r\n \r\n \r\n const ComparisonTable = () => {\r\n const [selectedFeature, setSelectedFeature] = React.useState(null);\r\n\r\n const messengers = [\r\n {\r\n name: \"SecureBit.chat\",\r\n logo:
\r\n \r\n
,\r\n type: \"P2P WebRTC\",\r\n version: \"Latest\",\r\n color: \"orange\",\r\n },\r\n {\r\n name: \"Signal\",\r\n logo: (\r\n \r\n \r\n \r\n \r\n ),\r\n type: \"Centralized\",\r\n version: \"Latest\",\r\n color: \"blue\",\r\n },\r\n {\r\n name: \"Threema\",\r\n logo: (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n ),\r\n type: \"Centralized\",\r\n version: \"Latest\",\r\n color: \"green\",\r\n },\r\n {\r\n name: \"Session\",\r\n logo: (\r\n \r\n \r\n \r\n \r\n ),\r\n type: \"Onion Network\",\r\n version: \"Latest\",\r\n color: \"cyan\",\r\n },\r\n ];\r\n\r\n const features = [\r\n {\r\n name: \"Security Architecture\",\r\n lockbit: { status: \"trophy\", detail: \"18-layer military-grade defense system with complete ASN.1 validation\" },\r\n signal: { status: \"check\", detail: \"Signal Protocol with double ratchet\" },\r\n threema: { status: \"check\", detail: \"Standard security implementation\" },\r\n session: { status: \"check\", detail: \"Modified Signal Protocol + Onion routing\" },\r\n },\r\n {\r\n name: \"Cryptography\",\r\n lockbit: { status: \"trophy\", detail: \"ECDH P-384 + AES-GCM 256 + ECDSA P-384\" },\r\n signal: { status: \"check\", detail: \"Signal Protocol + Double Ratchet\" },\r\n threema: { status: \"check\", detail: \"NaCl + XSalsa20 + Poly1305\" },\r\n session: { status: \"check\", detail: \"Modified Signal Protocol\" },\r\n },\r\n {\r\n name: \"Perfect Forward Secrecy\",\r\n lockbit: { status: \"trophy\", detail: \"Auto rotation every 5 minutes or 100 messages\" },\r\n signal: { status: \"check\", detail: \"Double Ratchet algorithm\" },\r\n threema: { status: \"warning\", detail: \"Partial (group chats)\" },\r\n session: { status: \"check\", detail: \"Session Ratchet algorithm\" },\r\n },\r\n {\r\n name: \"Architecture\",\r\n lockbit: { status: \"trophy\", detail: \"Pure P2P WebRTC without servers\" },\r\n signal: { status: \"times\", detail: \"Centralized Signal servers\" },\r\n threema: { status: \"times\", detail: \"Threema servers in Switzerland\" },\r\n session: { status: \"warning\", detail: \"Onion routing via network nodes\" },\r\n },\r\n {\r\n name: \"Registration Anonymity\",\r\n lockbit: { status: \"trophy\", detail: \"No registration required, instant anonymous channels\" },\r\n signal: { status: \"times\", detail: \"Phone number required\" },\r\n threema: { status: \"check\", detail: \"ID generated locally\" },\r\n session: { status: \"check\", detail: \"Random session ID\" },\r\n },\r\n {\r\n name: \"Metadata Protection\",\r\n lockbit: { status: \"trophy\", detail: \"Full metadata encryption + traffic obfuscation\" },\r\n signal: { status: \"warning\", detail: \"Sealed Sender (partial)\" },\r\n threema: { status: \"warning\", detail: \"Minimal metadata\" },\r\n session: { status: \"check\", detail: \"Onion routing hides metadata\" },\r\n },\r\n {\r\n name: \"Traffic Obfuscation\",\r\n lockbit: { status: \"trophy\", detail: \"Fake traffic + pattern masking + packet padding\" },\r\n signal: { status: \"times\", detail: \"No traffic obfuscation\" },\r\n threema: { status: \"times\", detail: \"No traffic obfuscation\" },\r\n session: { status: \"check\", detail: \"Onion routing provides obfuscation\" },\r\n },\r\n {\r\n name: \"Open Source\",\r\n lockbit: { status: \"trophy\", detail: \"100% open + auditable + MIT license\" },\r\n signal: { status: \"check\", detail: \"Fully open\" },\r\n threema: { status: \"warning\", detail: \"Only clients open\" },\r\n session: { status: \"check\", detail: \"Fully open\" },\r\n },\r\n {\r\n name: \"MITM Protection\",\r\n lockbit: { status: \"trophy\", detail: \"Out-of-band verification + mutual auth + ECDSA\" },\r\n signal: { status: \"check\", detail: \"Safety numbers verification\" },\r\n threema: { status: \"check\", detail: \"QR code scanning\" },\r\n session: { status: \"warning\", detail: \"Basic key verification\" },\r\n },\r\n {\r\n name: \"Censorship Resistance\",\r\n lockbit: { status: \"trophy\", detail: \"Impossible to block P2P + no servers to target\" },\r\n signal: { status: \"warning\", detail: \"Blocked in authoritarian countries\" },\r\n threema: { status: \"warning\", detail: \"May be blocked\" },\r\n session: { status: \"check\", detail: \"Onion routing bypasses blocks\" },\r\n },\r\n {\r\n name: \"Data Storage\",\r\n lockbit: { status: \"trophy\", detail: \"Zero data storage - only in browser memory\" },\r\n signal: { status: \"warning\", detail: \"Local database storage\" },\r\n threema: { status: \"warning\", detail: \"Local + optional backup\" },\r\n session: { status: \"warning\", detail: \"Local database storage\" },\r\n },\r\n {\r\n name: \"Key Security\",\r\n lockbit: { status: \"trophy\", detail: \"Non-extractable keys + hardware protection\" },\r\n signal: { status: \"check\", detail: \"Secure key storage\" },\r\n threema: { status: \"check\", detail: \"Local key storage\" },\r\n session: { status: \"check\", detail: \"Secure key storage\" },\r\n },\r\n {\r\n name: \"Post-Quantum Roadmap\",\r\n lockbit: { status: \"check\", detail: \"Planned v5.0 - CRYSTALS-Kyber/Dilithium\" },\r\n signal: { status: \"warning\", detail: \"PQXDH in development\" },\r\n threema: { status: \"times\", detail: \"Not announced\" },\r\n session: { status: \"times\", detail: \"Not announced\" },\r\n },\r\n ];\r\n\r\n const getStatusIcon = (status) => {\r\n const statusMap = {\r\n \"trophy\": { icon: \"fa-trophy\", color: \"accent-orange\" },\r\n \"check\": { icon: \"fa-check\", color: \"text-green-300\" },\r\n \"warning\": { icon: \"fa-exclamation-triangle\", color: \"text-yellow-300\" },\r\n \"times\": { icon: \"fa-times\", color: \"text-red-300\" },\r\n };\r\n return statusMap[status] || { icon: \"fa-question\", color: \"text-gray-400\" };\r\n };\r\n\r\n const toggleFeatureDetail = (index) => {\r\n setSelectedFeature(selectedFeature === index ? null : index);\r\n };\r\n\r\n return (\r\n
\r\n {/* Title */}\r\n
\r\n

\r\n Enhanced Security Edition Comparison\r\n

\r\n

\r\n Enhanced Security Edition vs leading secure messengers\r\n

\r\n
\r\n\r\n {/* Table container */}\r\n
\r\n {/* Mobile Alert */}\r\n
\r\n

\r\n \r\n Rotate your device horizontally for better viewing\r\n

\r\n
\r\n\r\n {/* Table */}\r\n
\r\n \r\n {/* Table Header */}\r\n \r\n \r\n \r\n Security Criterion\r\n \r\n {messengers.map((messenger, index) => (\r\n \r\n
\r\n
{messenger.logo}
\r\n
\r\n {messenger.name}\r\n
\r\n
{messenger.type}
\r\n
{messenger.version}
\r\n
\r\n \r\n ))}\r\n \r\n \r\n\r\n {/* Table body */}\r\n \r\n {features.map((feature, featureIndex) => (\r\n \r\n toggleFeatureDetail(featureIndex)}\r\n >\r\n \r\n
\r\n {feature.name}\r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n {/* Details */}\r\n {selectedFeature === featureIndex && (\r\n \r\n Technical Details:\r\n \r\n
\r\n {feature.lockbit.detail}\r\n
\r\n \r\n \r\n
\r\n {feature.signal.detail}\r\n
\r\n \r\n \r\n
\r\n {feature.threema.detail}\r\n
\r\n \r\n \r\n
\r\n {feature.session.detail}\r\n
\r\n \r\n \r\n )}\r\n
\r\n ))}\r\n \r\n \r\n
\r\n\r\n {/* Legend */}\r\n
\r\n
\r\n \r\n Category Leader\r\n
\r\n\r\n
\r\n \r\n Excellent\r\n
\r\n
\r\n \r\n Partial/Limited\r\n
\r\n
\r\n \r\n Not Available\r\n
\r\n
\r\n
\r\n
\r\n );\r\n };\r\n window.ComparisonTable = ComparisonTable;", "function Roadmap() {\r\n const [selectedPhase, setSelectedPhase] = React.useState(null);\r\n const phases = [\r\n {\r\n version: \"v1.0\",\r\n title: \"Start of Development\",\r\n status: \"done\",\r\n date: \"Early 2025\",\r\n description: \"Idea, prototype, and infrastructure setup\",\r\n features: [\r\n \"Concept and requirements formation\",\r\n \"Stack selection: WebRTC, P2P, cryptography\",\r\n \"First messaging prototypes\",\r\n \"Repository creation and CI\",\r\n \"Basic encryption architecture\",\r\n \"UX/UI design\"\r\n ]\r\n },\r\n {\r\n version: \"v1.5\",\r\n title: \"Alpha Release\",\r\n status: \"done\",\r\n date: \"Spring 2025\",\r\n description: \"First public alpha: basic chat and key exchange\",\r\n features: [\r\n \"Basic P2P messaging via WebRTC\",\r\n \"Simple E2E encryption (demo scheme)\",\r\n \"Stable signaling and reconnection\",\r\n \"Minimal UX for testing\",\r\n \"Feedback collection from early testers\"\r\n ]\r\n },\r\n {\r\n version: \"v2.0\",\r\n title: \"Security Hardened\",\r\n status: \"done\",\r\n date: \"Summer 2025\",\r\n description: \"Security strengthening and stable branch release\",\r\n features: [\r\n \"ECDH/ECDSA implementation in production\",\r\n \"Perfect Forward Secrecy and key rotation\",\r\n \"Improved authentication checks\",\r\n \"File encryption and large payload transfers\",\r\n \"Audit of basic cryptoprocesses\"\r\n ]\r\n },\r\n {\r\n version: \"v3.0\",\r\n title: \"Scaling & Stability\",\r\n status: \"done\",\r\n date: \"Fall 2025\",\r\n description: \"Network scaling and stability improvements\",\r\n features: [\r\n \"Optimization of P2P connections and NAT traversal\",\r\n \"Reconnection mechanisms and message queues\",\r\n \"Reduced battery consumption on mobile\",\r\n \"Support for multi-device synchronization\",\r\n \"Monitoring and logging tools for developers\"\r\n ]\r\n },\r\n {\r\n version: \"v3.5\",\r\n title: \"Privacy-first Release\",\r\n status: \"done\",\r\n date: \"Winter 2025\",\r\n description: \"Focus on privacy: minimizing metadata\",\r\n features: [\r\n \"Metadata protection and fingerprint reduction\",\r\n \"Experiments with onion routing and DHT\",\r\n \"Options for anonymous connections\",\r\n \"Preparation for open code audit\",\r\n \"Improved user verification processes\"\r\n ]\r\n },\r\n \r\n // current and future phases\r\n {\r\n version: \"v4.4.99\",\r\n title: \"Enhanced Security Edition\",\r\n status: \"current\",\r\n date: \"Now\",\r\n description: \"Current version with ECDH + DTLS + SAS security, 18-layer military-grade cryptography and complete ASN.1 validation\",\r\n features: [\r\n \"ECDH + DTLS + SAS triple-layer security\",\r\n \"ECDH P-384 + AES-GCM 256-bit encryption\",\r\n \"DTLS fingerprint verification\",\r\n \"SAS (Short Authentication String) verification\",\r\n \"Perfect Forward Secrecy with key rotation\",\r\n \"Enhanced MITM attack prevention\",\r\n \"Complete ASN.1 DER validation\",\r\n \"OID and EC point verification\",\r\n \"SPKI structure validation\",\r\n \"P2P WebRTC architecture\",\r\n \"Metadata protection\",\r\n \"100% open source code\"\r\n ]\r\n },\r\n {\r\n version: \"v4.5\",\r\n title: \"Mobile & Desktop Edition\",\r\n status: \"development\",\r\n date: \"Q2 2025\",\r\n description: \"Native apps for all platforms\",\r\n features: [\r\n \"PWA app for mobile\",\r\n \"Electron app for desktop\",\r\n \"Real-time notifications\",\r\n \"Automatic reconnection\",\r\n \"Battery optimization\",\r\n \"Cross-device synchronization\",\r\n \"Improved UX/UI\",\r\n \"Support for files up to 100MB\"\r\n ]\r\n },\r\n {\r\n version: \"v5.0\",\r\n title: \"Quantum-Resistant Edition\",\r\n status: \"planned\",\r\n date: \"Q4 2025\",\r\n description: \"Protection against quantum computers\",\r\n features: [\r\n \"Post-quantum cryptography CRYSTALS-Kyber\",\r\n \"SPHINCS+ digital signatures\",\r\n \"Hybrid scheme: classic + PQ\",\r\n \"Quantum-safe key exchange\",\r\n \"Updated hashing algorithms\",\r\n \"Migration of existing sessions\",\r\n \"Compatibility with v4.x\",\r\n \"Quantum-resistant protocols\"\r\n ]\r\n },\r\n {\r\n version: \"v5.5\",\r\n title: \"Group Communications\",\r\n status: \"planned\",\r\n date: \"Q2 2026\",\r\n description: \"Group chats with preserved privacy\",\r\n features: [\r\n \"P2P group connections up to 8 participants\",\r\n \"Mesh networking for groups\",\r\n \"Signal Double Ratchet for groups\",\r\n \"Anonymous groups without metadata\",\r\n \"Ephemeral groups (disappear after session)\",\r\n \"Cryptographic group administration\",\r\n \"Group member auditing\"\r\n ]\r\n },\r\n {\r\n version: \"v6.0\",\r\n title: \"Decentralized Network\",\r\n status: \"research\",\r\n date: \"2027\",\r\n description: \"Fully decentralized network\",\r\n features: [\r\n \"LockBit node mesh network\",\r\n \"DHT for peer discovery\",\r\n \"Built-in onion routing\",\r\n \"Tokenomics and node incentives\",\r\n \"Governance via DAO\",\r\n \"Interoperability with other networks\",\r\n \"Cross-platform compatibility\",\r\n \"Self-healing network\"\r\n ]\r\n },\r\n {\r\n version: \"v7.0\",\r\n title: \"AI Privacy Assistant\",\r\n status: \"research\",\r\n date: \"2028+\",\r\n description: \"AI for privacy and security\",\r\n features: [\r\n \"Local AI threat analysis\",\r\n \"Automatic MITM detection\",\r\n \"Adaptive cryptography\",\r\n \"Personalized security recommendations\",\r\n \"Zero-knowledge machine learning\",\r\n \"Private AI assistant\",\r\n \"Predictive security\",\r\n \"Autonomous attack protection\"\r\n ]\r\n }\r\n ];\r\n \r\n \r\n const getStatusConfig = (status) => {\r\n switch (status) {\r\n case 'current':\r\n return {\r\n color: 'green',\r\n bgClass: 'bg-green-500/10 border-green-500/20',\r\n textClass: 'text-green-400',\r\n icon: 'fas fa-check-circle',\r\n label: 'Current Version'\r\n };\r\n case 'development':\r\n return {\r\n color: 'orange',\r\n bgClass: 'bg-orange-500/10 border-orange-500/20',\r\n textClass: 'text-orange-400',\r\n icon: 'fas fa-code',\r\n label: 'In Development'\r\n };\r\n case 'planned':\r\n return {\r\n color: 'blue',\r\n bgClass: 'bg-blue-500/10 border-blue-500/20',\r\n textClass: 'text-blue-400',\r\n icon: 'fas fa-calendar-alt',\r\n label: 'Planned'\r\n };\r\n case 'research':\r\n return {\r\n color: 'purple',\r\n bgClass: 'bg-purple-500/10 border-purple-500/20',\r\n textClass: 'text-purple-400',\r\n icon: 'fas fa-flask',\r\n label: 'Research'\r\n };\r\n case 'done':\r\n return {\r\n color: 'gray',\r\n bgClass: 'bg-gray-500/10 border-gray-500/20',\r\n textClass: 'text-gray-300',\r\n icon: 'fas fa-flag-checkered',\r\n label: 'Released'\r\n };\r\n default:\r\n return {\r\n color: 'gray',\r\n bgClass: 'bg-gray-500/10 border-gray-500/20',\r\n textClass: 'text-gray-400',\r\n icon: 'fas fa-question',\r\n label: 'Unknown'\r\n };\r\n }\r\n };\r\n \r\n \r\n const togglePhaseDetail = (index) => {\r\n setSelectedPhase(selectedPhase === index ? null : index);\r\n };\r\n return (\r\n
\r\n
\r\n

\r\n Development Roadmap\r\n

\r\n

\r\n Evolution of SecureBit.chat : from initial development to quantum-resistant decentralized network with complete ASN.1 validation\r\n

\r\n
\r\n \r\n
\r\n
\r\n {/* The line has been removed */}\r\n \r\n
\r\n {phases.map((phase, index) => {\r\n const statusConfig = getStatusConfig(phase.status);\r\n const isExpanded = selectedPhase === index;\r\n \r\n return (\r\n
\r\n {/* The dots are visible only on sm and larger screens */}\r\n \r\n togglePhaseDetail(index)}\r\n key={`phase-button-${index}`}\r\n className={`card-minimal rounded-xl p-4 text-left w-full transition-all duration-300 ${\r\n isExpanded\r\n ? \"ring-2 ring-\" + statusConfig.color + \"-500/30\"\r\n : \"\"\r\n }`}\r\n >\r\n \r\n \r\n \r\n \r\n {phase.version}\r\n \r\n
\r\n \r\n
\r\n \r\n {phase.title}\r\n \r\n \r\n {phase.description}\r\n

\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n {statusConfig.label}\r\n \r\n
\r\n \r\n
{phase.date}
\r\n \r\n
\r\n
\r\n \r\n {isExpanded && (\r\n \r\n \r\n \r\n Key features:\r\n \r\n \r\n \r\n {phase.features.map((feature, featureIndex) => (\r\n \r\n \r\n \r\n {feature}\r\n \r\n \r\n ))}\r\n \r\n \r\n )}\r\n \r\n \r\n );\r\n })}\r\n \r\n \r\n \r\n \r\n
\r\n \r\n \r\n Join the future of privacy\r\n \r\n

\r\n SecureBit.chat grows thanks to the community. Your ideas and feedback help shape the future of secure communication with complete ASN.1 validation.\r\n

\r\n \r\n \r\n \r\n \r\n GitHub Repository\r\n \r\n \r\n \r\n \r\n Feedback\r\n \r\n
\r\n \r\n \r\n \r\n );\r\n };\r\n window.Roadmap = Roadmap;", "// File Transfer Component for Chat Interface - Fixed Version\r\nconst FileTransferComponent = ({ webrtcManager, isConnected }) => {\r\n const [dragOver, setDragOver] = React.useState(false);\r\n const [transfers, setTransfers] = React.useState({ sending: [], receiving: [] });\r\n const [readyFiles, setReadyFiles] = React.useState([]); // \u0444\u0430\u0439\u043B\u044B, \u0433\u043E\u0442\u043E\u0432\u044B\u0435 \u043A \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044E\r\n const fileInputRef = React.useRef(null);\r\n\r\n // Update transfers periodically\r\n React.useEffect(() => {\r\n if (!isConnected || !webrtcManager) return;\r\n\r\n const updateTransfers = () => {\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n };\r\n\r\n const interval = setInterval(updateTransfers, 500);\r\n return () => clearInterval(interval);\r\n }, [isConnected, webrtcManager]);\r\n\r\n // Setup file transfer callbacks - \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u041D\u0415 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u043F\u0440\u043E\u043C\u0435\u0436\u0443\u0442\u043E\u0447\u043D\u044B\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0432 \u0447\u0430\u0442\r\n React.useEffect(() => {\r\n if (!webrtcManager) return;\r\n\r\n webrtcManager.setFileTransferCallbacks(\r\n // Progress callback - \u0422\u041E\u041B\u042C\u041A\u041E \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u043C UI, \u041D\u0415 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u0432 \u0447\u0430\u0442\r\n (progress) => {\r\n // \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u043C \u0442\u043E\u043B\u044C\u043A\u043E \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0435 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n \r\n // \u041D\u0415 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0432 \u0447\u0430\u0442!\r\n },\r\n \r\n // File received callback - \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u043C \u043A\u043D\u043E\u043F\u043A\u0443 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F \u0432 UI\r\n (fileData) => {\r\n // \u0414\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u043C \u0432 \u0441\u043F\u0438\u0441\u043E\u043A \u0433\u043E\u0442\u043E\u0432\u044B\u0445 \u043A \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044E\r\n setReadyFiles(prev => {\r\n // \u0438\u0437\u0431\u0435\u0433\u0430\u0435\u043C \u0434\u0443\u0431\u043B\u0435\u0439 \u043F\u043E fileId\r\n if (prev.some(f => f.fileId === fileData.fileId)) return prev;\r\n return [...prev, {\r\n fileId: fileData.fileId,\r\n fileName: fileData.fileName,\r\n fileSize: fileData.fileSize,\r\n mimeType: fileData.mimeType,\r\n getBlob: fileData.getBlob,\r\n getObjectURL: fileData.getObjectURL,\r\n revokeObjectURL: fileData.revokeObjectURL\r\n }];\r\n });\r\n\r\n // \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u043C \u0441\u043F\u0438\u0441\u043E\u043A \u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u0447\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n },\r\n \r\n // Error callback\r\n (error) => {\r\n const currentTransfers = webrtcManager.getFileTransfers();\r\n setTransfers(currentTransfers);\r\n \r\n // \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u041D\u0415 \u0434\u0443\u0431\u043B\u0438\u0440\u0443\u0435\u043C \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043E\u0431 \u043E\u0448\u0438\u0431\u043A\u0430\u0445\r\n // \u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F \u043E\u0431 \u043E\u0448\u0438\u0431\u043A\u0430\u0445 \u0443\u0436\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F \u0432 WebRTC \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u0435\r\n }\r\n );\r\n }, [webrtcManager]);\r\n\r\n const handleFileSelect = async (files) => {\r\n if (!isConnected || !webrtcManager) {\r\n alert('\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E. \u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435.');\r\n return;\r\n }\r\n\r\n // \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\r\n if (!webrtcManager.isConnected() || !webrtcManager.isVerified) {\r\n alert('\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432\u043E \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0444\u0430\u0439\u043B\u043E\u0432. \u0414\u043E\u0436\u0434\u0438\u0442\u0435\u0441\u044C \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F.');\r\n return;\r\n }\r\n\r\n for (const file of files) {\r\n try {\r\n // \u041A\u0420\u0418\u0422\u0418\u0427\u0415\u0421\u041A\u041E\u0415 \u0418\u0421\u041F\u0420\u0410\u0412\u041B\u0415\u041D\u0418\u0415: \u0412\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u044F \u0444\u0430\u0439\u043B\u0430 \u043F\u0435\u0440\u0435\u0434 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u043E\u0439\r\n const validation = webrtcManager.validateFile(file);\r\n if (!validation.isValid) {\r\n const errorMessage = validation.errors.join('. ');\r\n alert(`\u0424\u0430\u0439\u043B ${file.name} \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D: ${errorMessage}`);\r\n continue;\r\n }\r\n\r\n await webrtcManager.sendFile(file);\r\n } catch (error) {\r\n // \u0411\u043E\u043B\u0435\u0435 \u043C\u044F\u0433\u043A\u0430\u044F \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u043E\u0448\u0438\u0431\u043E\u043A - \u043D\u0435 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0435\u043C \u0441\u0435\u0441\u0441\u0438\u044E\r\n \r\n // \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044E \u043E\u0448\u0438\u0431\u043A\u0443, \u043D\u043E \u043D\u0435 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0435\u043C \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435\r\n if (error.message.includes('Connection not ready')) {\r\n alert(`\u0424\u0430\u0439\u043B ${file.name} \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D \u0441\u0435\u0439\u0447\u0430\u0441. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0438 \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0441\u043D\u043E\u0432\u0430.`);\r\n } else if (error.message.includes('File too large') || error.message.includes('exceeds maximum')) {\r\n alert(`\u0424\u0430\u0439\u043B ${file.name} \u0441\u043B\u0438\u0448\u043A\u043E\u043C \u0431\u043E\u043B\u044C\u0448\u043E\u0439: ${error.message}`);\r\n } else if (error.message.includes('Maximum concurrent transfers')) {\r\n alert(`\u0414\u043E\u0441\u0442\u0438\u0433\u043D\u0443\u0442 \u043B\u0438\u043C\u0438\u0442 \u043E\u0434\u043D\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u0447. \u0414\u043E\u0436\u0434\u0438\u0442\u0435\u0441\u044C \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0443\u0449\u0438\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u0447.`);\r\n } else if (error.message.includes('File type not allowed')) {\r\n alert(`\u0422\u0438\u043F \u0444\u0430\u0439\u043B\u0430 ${file.name} \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F: ${error.message}`);\r\n } else {\r\n alert(`\u041E\u0448\u0438\u0431\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438 \u0444\u0430\u0439\u043B\u0430 ${file.name}: ${error.message}`);\r\n }\r\n }\r\n }\r\n };\r\n\r\n const handleDrop = (e) => {\r\n e.preventDefault();\r\n setDragOver(false);\r\n \r\n const files = Array.from(e.dataTransfer.files);\r\n handleFileSelect(files);\r\n };\r\n\r\n const handleDragOver = (e) => {\r\n e.preventDefault();\r\n setDragOver(true);\r\n };\r\n\r\n const handleDragLeave = (e) => {\r\n e.preventDefault();\r\n setDragOver(false);\r\n };\r\n\r\n const handleFileInputChange = (e) => {\r\n const files = Array.from(e.target.files);\r\n handleFileSelect(files);\r\n e.target.value = ''; // Reset input\r\n };\r\n\r\n const formatFileSize = (bytes) => {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\r\n };\r\n\r\n const getStatusIcon = (status) => {\r\n switch (status) {\r\n case 'metadata_sent':\r\n case 'preparing':\r\n return 'fas fa-cog fa-spin';\r\n case 'transmitting':\r\n case 'receiving':\r\n return 'fas fa-exchange-alt fa-pulse';\r\n case 'assembling':\r\n return 'fas fa-puzzle-piece fa-pulse';\r\n case 'completed':\r\n return 'fas fa-check text-green-400';\r\n case 'failed':\r\n return 'fas fa-times text-red-400';\r\n default:\r\n return 'fas fa-circle';\r\n }\r\n };\r\n\r\n const getStatusText = (status) => {\r\n switch (status) {\r\n case 'metadata_sent':\r\n return '\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043A\u0430...';\r\n case 'transmitting':\r\n return '\u041E\u0442\u043F\u0440\u0430\u0432\u043A\u0430...';\r\n case 'receiving':\r\n return '\u041F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435...';\r\n case 'assembling':\r\n return '\u0421\u0431\u043E\u0440\u043A\u0430 \u0444\u0430\u0439\u043B\u0430...';\r\n case 'completed':\r\n return '\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043E';\r\n case 'failed':\r\n return '\u041E\u0448\u0438\u0431\u043A\u0430';\r\n default:\r\n return status;\r\n }\r\n };\r\n\r\n if (!isConnected) {\r\n return React.createElement('div', {\r\n className: \"p-4 text-center text-muted\"\r\n }, '\u041F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043B\u043E\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u043E\u043C \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0438');\r\n }\r\n\r\n // \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u043C \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\r\n const isConnectionReady = webrtcManager && webrtcManager.isConnected() && webrtcManager.isVerified;\r\n \r\n if (!isConnectionReady) {\r\n return React.createElement('div', {\r\n className: \"p-4 text-center text-yellow-600\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-exclamation-triangle mr-2'\r\n }),\r\n '\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0443\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u0435\u0442\u0441\u044F... \u041F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043B\u043E\u0432 \u0431\u0443\u0434\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043F\u043E\u0441\u043B\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438.'\r\n ]);\r\n }\r\n\r\n return React.createElement('div', {\r\n className: \"file-transfer-component\"\r\n }, [\r\n // File Drop Zone\r\n React.createElement('div', {\r\n key: 'drop-zone',\r\n className: `file-drop-zone ${dragOver ? 'drag-over' : ''}`,\r\n onDrop: handleDrop,\r\n onDragOver: handleDragOver,\r\n onDragLeave: handleDragLeave,\r\n onClick: () => fileInputRef.current?.click()\r\n }, [\r\n React.createElement('div', {\r\n key: 'drop-content',\r\n className: \"drop-content\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-cloud-upload-alt text-2xl mb-2 text-blue-400'\r\n }),\r\n React.createElement('p', {\r\n key: 'text',\r\n className: \"text-primary font-medium\"\r\n }, 'Drag files here or click to select'),\r\n React.createElement('p', {\r\n key: 'subtext',\r\n className: \"text-muted text-sm\"\r\n }, 'Maximum size: 100 MB per file')\r\n ])\r\n ]),\r\n\r\n // Hidden file input\r\n React.createElement('input', {\r\n key: 'file-input',\r\n ref: fileInputRef,\r\n type: 'file',\r\n multiple: true,\r\n className: 'hidden',\r\n onChange: handleFileInputChange\r\n }),\r\n\r\n // Active Transfers\r\n (transfers.sending.length > 0 || transfers.receiving.length > 0) && React.createElement('div', {\r\n key: 'transfers',\r\n className: \"active-transfers mt-4\"\r\n }, [\r\n React.createElement('h4', {\r\n key: 'title',\r\n className: \"text-primary font-medium mb-3 flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-exchange-alt mr-2'\r\n }),\r\n '\u041F\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043B\u043E\u0432'\r\n ]),\r\n\r\n // Sending files\r\n ...transfers.sending.map(transfer => \r\n React.createElement('div', {\r\n key: `send-${transfer.fileId}`,\r\n className: \"transfer-item bg-blue-500/10 border border-blue-500/20 rounded-lg p-3 mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'header',\r\n className: \"flex items-center justify-between mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'info',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-upload text-blue-400 mr-2'\r\n }),\r\n React.createElement('span', {\r\n key: 'name',\r\n className: \"text-primary font-medium text-sm\"\r\n }, transfer.fileName),\r\n React.createElement('span', {\r\n key: 'size',\r\n className: \"text-muted text-xs ml-2\"\r\n }, formatFileSize(transfer.fileSize))\r\n ]),\r\n React.createElement('button', {\r\n key: 'cancel',\r\n onClick: () => webrtcManager.cancelFileTransfer(transfer.fileId),\r\n className: \"text-red-400 hover:text-red-300 text-xs\"\r\n }, [\r\n React.createElement('i', {\r\n className: 'fas fa-times'\r\n })\r\n ])\r\n ]),\r\n React.createElement('div', {\r\n key: 'progress',\r\n className: \"progress-bar\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'fill',\r\n className: \"progress-fill bg-blue-400\",\r\n style: { width: `${transfer.progress}%` }\r\n }),\r\n React.createElement('div', {\r\n key: 'text',\r\n className: \"progress-text text-xs flex items-center justify-between\"\r\n }, [\r\n React.createElement('span', {\r\n key: 'status',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: `${getStatusIcon(transfer.status)} mr-1`\r\n }),\r\n getStatusText(transfer.status)\r\n ]),\r\n React.createElement('span', {\r\n key: 'percent'\r\n }, `${transfer.progress.toFixed(1)}%`)\r\n ])\r\n ])\r\n ])\r\n ),\r\n\r\n // Receiving files\r\n ...transfers.receiving.map(transfer => \r\n React.createElement('div', {\r\n key: `recv-${transfer.fileId}`,\r\n className: \"transfer-item bg-green-500/10 border border-green-500/20 rounded-lg p-3 mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'header',\r\n className: \"flex items-center justify-between mb-2\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'info',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: 'fas fa-download text-green-400 mr-2'\r\n }),\r\n React.createElement('span', {\r\n key: 'name',\r\n className: \"text-primary font-medium text-sm\"\r\n }, transfer.fileName),\r\n React.createElement('span', {\r\n key: 'size',\r\n className: \"text-muted text-xs ml-2\"\r\n }, formatFileSize(transfer.fileSize))\r\n ]),\r\n React.createElement('div', { key: 'actions', className: 'flex items-center space-x-2' }, [\r\n (() => {\r\n const rf = readyFiles.find(f => f.fileId === transfer.fileId);\r\n if (!rf || transfer.status !== 'completed') return null;\r\n return React.createElement('button', {\r\n key: 'download',\r\n className: 'text-green-400 hover:text-green-300 text-xs flex items-center',\r\n onClick: async () => {\r\n try {\r\n const url = await rf.getObjectURL();\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = rf.fileName || 'file';\r\n a.click();\r\n rf.revokeObjectURL(url);\r\n } catch (e) {\r\n alert('Failed to start download: ' + e.message);\r\n }\r\n }\r\n }, [\r\n React.createElement('i', { key: 'i', className: 'fas fa-download mr-1' }),\r\n 'Download'\r\n ]);\r\n })(),\r\n React.createElement('button', {\r\n key: 'cancel',\r\n onClick: () => webrtcManager.cancelFileTransfer(transfer.fileId),\r\n className: \"text-red-400 hover:text-red-300 text-xs\"\r\n }, [\r\n React.createElement('i', {\r\n className: 'fas fa-times'\r\n })\r\n ])\r\n ])\r\n ]),\r\n React.createElement('div', {\r\n key: 'progress',\r\n className: \"progress-bar\"\r\n }, [\r\n React.createElement('div', {\r\n key: 'fill',\r\n className: \"progress-fill bg-green-400\",\r\n style: { width: `${transfer.progress}%` }\r\n }),\r\n React.createElement('div', {\r\n key: 'text',\r\n className: \"progress-text text-xs flex items-center justify-between\"\r\n }, [\r\n React.createElement('span', {\r\n key: 'status',\r\n className: \"flex items-center\"\r\n }, [\r\n React.createElement('i', {\r\n key: 'icon',\r\n className: `${getStatusIcon(transfer.status)} mr-1`\r\n }),\r\n getStatusText(transfer.status)\r\n ]),\r\n React.createElement('span', {\r\n key: 'percent'\r\n }, `${transfer.progress.toFixed(1)}%`)\r\n ])\r\n ])\r\n ])\r\n )\r\n ])\r\n ]);\r\n};\r\n\r\n// Export\r\nwindow.FileTransferComponent = FileTransferComponent;"], + "mappings": "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", "names": ["NotificationIntegration", "fileMessageTypes", "attempts", "start", "error", "attempts", "chunk", "fileMessageTypes", "window", "start", "webrtcManager", "start"] } diff --git a/doc/CRYPTOGRAPHY.md b/doc/CRYPTOGRAPHY.md index 480494d..be80881 100644 --- a/doc/CRYPTOGRAPHY.md +++ b/doc/CRYPTOGRAPHY.md @@ -1143,9 +1143,9 @@ await mutexManager._withMutex('connectionOperation', async () => { ## 🔗 Key Derivation -### HKDF Implementation +### HKDF Implementation (RFC 5869 Compliant) -#### **Enhanced Key Derivation** +#### **Enhanced Key Derivation with Proper Separation** ```javascript async function deriveSharedKeys(privateKey, publicKey, salt) { // Validate inputs @@ -1159,43 +1159,132 @@ async function deriveSharedKeys(privateKey, publicKey, salt) { const saltBytes = new Uint8Array(salt); const encoder = new TextEncoder(); - // Enhanced context info - const contextInfo = encoder.encode('SecureBit.chat v4.0 Enhanced Security Edition'); - - // Derive master shared secret - const sharedSecret = await crypto.subtle.deriveKey( + // Step 1: Derive raw ECDH shared secret using pure ECDH + const rawKeyMaterial = await crypto.subtle.deriveKey( { name: 'ECDH', public: publicKey }, privateKey, { - name: 'HKDF', - hash: 'SHA-384', - salt: saltBytes, - info: contextInfo + name: 'AES-GCM', + length: 256 }, - false, // Non-extractable + true, // Extractable for HKDF processing + ['encrypt', 'decrypt'] + ); + + // Export the raw key material + const rawKeyData = await crypto.subtle.exportKey('raw', rawKeyMaterial); + + // Import as HKDF key material for further derivation + const rawSharedSecret = await crypto.subtle.importKey( + 'raw', + rawKeyData, + { + name: 'HKDF', + hash: 'SHA-256' + }, + false, ['deriveKey'] ); - // Derive specific keys - const keys = await Promise.all([ - deriveSpecificKey(sharedSecret, saltBytes, 'message-encryption-v4', 'AES-GCM', 256), - deriveSpecificKey(sharedSecret, saltBytes, 'message-authentication-v4', 'HMAC', 384), - deriveSpecificKey(sharedSecret, saltBytes, 'metadata-protection-v4', 'AES-GCM', 256), - deriveSpecificKey(sharedSecret, saltBytes, 'fingerprint-generation-v4', 'AES-GCM', 256, true) - ]); + // Step 2: Derive specific keys using HKDF with unique info parameters + // Each key uses unique info parameter for proper separation - const [encryptionKey, macKey, metadataKey, fingerprintKey] = keys; + // Derive message encryption key (messageKey) + const messageKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('message-encryption-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + false, // Non-extractable for enhanced security + ['encrypt', 'decrypt'] + ); - // Generate key fingerprint + // Derive MAC key for message authentication + const macKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('message-authentication-v4') + }, + rawSharedSecret, + { + name: 'HMAC', + hash: 'SHA-256' + }, + false, // Non-extractable + ['sign', 'verify'] + ); + + // Derive Perfect Forward Secrecy key (pfsKey) + const pfsKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('perfect-forward-secrecy-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + false, // Non-extractable + ['encrypt', 'decrypt'] + ); + + // Derive separate metadata encryption key + const metadataKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('metadata-protection-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + false, // Non-extractable + ['encrypt', 'decrypt'] + ); + + // Generate temporary extractable key for fingerprint calculation + const fingerprintKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('fingerprint-generation-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + true, // Extractable only for fingerprint + ['encrypt', 'decrypt'] + ); + + // Generate key fingerprint for verification const fingerprintKeyData = await crypto.subtle.exportKey('raw', fingerprintKey); const fingerprint = await generateKeyFingerprint(Array.from(new Uint8Array(fingerprintKeyData))); return { - encryptionKey, + messageKey, macKey, + pfsKey, metadataKey, fingerprint, timestamp: Date.now(), @@ -1204,31 +1293,13 @@ async function deriveSharedKeys(privateKey, publicKey, salt) { } ``` -#### **Specific Key Derivation** -```javascript -async function deriveSpecificKey(masterKey, salt, info, algorithm, keySize, extractable = false) { - const encoder = new TextEncoder(); - - const derivedKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-384', - salt: salt, - info: encoder.encode(info) - }, - masterKey, - algorithm === 'AES-GCM' ? - { name: 'AES-GCM', length: keySize } : - { name: 'HMAC', hash: `SHA-${keySize}` }, - extractable, - algorithm === 'AES-GCM' ? - ['encrypt', 'decrypt'] : - ['sign', 'verify'] - ); - - return derivedKey; -} -``` +#### **HKDF Security Properties** +- **RFC 5869 Compliance:** Full adherence to HMAC-based Extract-and-Expand Key Derivation Function standard +- **Proper Key Separation:** Each derived key uses unique `info` parameter to prevent key reuse +- **Salt Security:** 64-byte cryptographically secure salt for each derivation +- **Non-Extractable Keys:** All operational keys are hardware-protected and non-exportable +- **Forward Secrecy:** Independent key derivation for each session prevents key compromise propagation +- **Algorithm Consistency:** SHA-256 hash function for optimal compatibility and performance ### Key Fingerprinting diff --git a/doc/SECURITY-ARCHITECTURE.md b/doc/SECURITY-ARCHITECTURE.md index a16bcf7..202b1dc 100644 --- a/doc/SECURITY-ARCHITECTURE.md +++ b/doc/SECURITY-ARCHITECTURE.md @@ -27,12 +27,13 @@ SecureBit.chat implements a revolutionary **18-layer security architecture** wit ## 🏗️ Security Architecture Overview -### 18-Layer Defense System +### 19-Layer Defense System ``` ┌─────────────────────────────────────────────────────────────┐ │ APPLICATION LAYER │ ├─────────────────────────────────────────────────────────────┤ +│ Layer 19: HKDF Key Derivation (RFC 5869 Compliant) │ │ Layer 18: EC Point Validation (Format & Structure) │ │ Layer 17: OID Validation (Algorithm & Curve Verification) │ │ Layer 16: ASN.1 Validation (Complete Key Structure) │ @@ -75,7 +76,7 @@ SecureBit.chat implements a revolutionary **18-layer security architecture** wit | 3 | 1-9 | High | + Timing attacks | | 4 | 1-12 | High Enhanced | + Advanced persistent threats | | 5 | 1-15 | Military-Grade | + Race conditions, Key exposure | -| 6 | 1-18 | Maximum | + DTLS race conditions, Memory safety, Key structure validation | +| 6 | 1-19 | Maximum | + DTLS race conditions, Memory safety, Key structure validation, HKDF compliance | --- @@ -166,6 +167,55 @@ const validateOID = (parsed) => { }; ``` +### Layer 19: HKDF Key Derivation (RFC 5869 Compliant) +**Purpose:** RFC 5869 compliant key derivation with proper key separation and cryptographic security + +**Technical Specifications:** +- **Standard:** RFC 5869 HMAC-based Extract-and-Expand Key Derivation Function +- **Hash Function:** SHA-256 for optimal compatibility and performance +- **Salt Security:** 64-byte cryptographically secure salt for each derivation +- **Key Separation:** Unique `info` parameters for each derived key type +- **Non-Extractable Keys:** Hardware-protected keys for enhanced security + +**Implementation:** +```javascript +// HKDF key derivation with proper separation +const deriveSharedKeys = async (privateKey, publicKey, salt) => { + // Step 1: Pure ECDH derivation + const rawKeyMaterial = await crypto.subtle.deriveKey( + { name: 'ECDH', public: publicKey }, + privateKey, + { name: 'AES-GCM', length: 256 }, + true, // Extractable for HKDF processing + ['encrypt', 'decrypt'] + ); + + // Export and import for HKDF + const rawKeyData = await crypto.subtle.exportKey('raw', rawKeyMaterial); + const rawSharedSecret = await crypto.subtle.importKey( + 'raw', rawKeyData, + { name: 'HKDF', hash: 'SHA-256' }, + false, ['deriveKey'] + ); + + // Step 2: Derive specific keys with unique info parameters + const messageKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('message-encryption-v4') + }, + rawSharedSecret, + { name: 'AES-GCM', length: 256 }, + false, ['encrypt', 'decrypt'] + ); + + // Additional keys derived with unique info parameters... + return { messageKey, macKey, pfsKey, metadataKey, fingerprint }; +}; +``` + ### Layer 18: EC Point Validation (Format & Structure Verification) **Purpose:** Verification of elliptic curve point format and structure @@ -403,12 +453,13 @@ webrtcManager.checkFakeTrafficStatus() | Metric | Target | Current | Status | |--------|---------|---------|---------| -| Active Security Layers | 12 | 12 | ✅ | +| Active Security Layers | 19 | 19 | ✅ | | Encryption Strength | 256-bit | 256-bit | ✅ | | Key Exchange Security | P-384 | P-384 | ✅ | | Forward Secrecy | Complete | Complete | ✅ | | Traffic Obfuscation | Maximum | Maximum | ✅ | | Attack Surface | Minimal | Minimal | ✅ | +| HKDF Compliance | RFC 5869 | RFC 5869 | ✅ | --- diff --git a/manifest.json b/manifest.json index 9c54fcf..f65cb99 100644 --- a/manifest.json +++ b/manifest.json @@ -1,5 +1,5 @@ { - "name": "SecureBit.chat v4.4.18 - ECDH + DTLS + SAS", + "name": "SecureBit.chat v4.4.99 - ECDH + DTLS + SAS", "short_name": "SecureBit", "description": "P2P messenger with ECDH + DTLS + SAS security, military-grade cryptography and Lightning Network payments", "start_url": "./", diff --git a/src/app.jsx b/src/app.jsx index 126e7d0..2c5deff 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -1924,7 +1924,7 @@ } } - handleMessage(' SecureBit.chat Enhanced Security Edition v4.4.18 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.', 'system'); + handleMessage(' SecureBit.chat Enhanced Security Edition v4.4.99 - ECDH + DTLS + SAS initialized. Ready to establish a secure connection with ECDH key exchange, DTLS fingerprint verification, and SAS authentication to prevent MITM attacks.', 'system'); const handleBeforeUnload = (event) => { if (event.type === 'beforeunload' && !isTabSwitching) { diff --git a/src/components/ui/Header.jsx b/src/components/ui/Header.jsx index 4db0b73..d667b02 100644 --- a/src/components/ui/Header.jsx +++ b/src/components/ui/Header.jsx @@ -557,7 +557,7 @@ const EnhancedMinimalHeader = ({ React.createElement('p', { key: 'subtitle', className: 'text-xs sm:text-sm text-muted hidden sm:block' - }, 'End-to-end freedom v4.4.18') + }, 'End-to-end freedom v4.4.99') ]) ]), diff --git a/src/components/ui/Roadmap.jsx b/src/components/ui/Roadmap.jsx index 74c6c19..9eeebba 100644 --- a/src/components/ui/Roadmap.jsx +++ b/src/components/ui/Roadmap.jsx @@ -75,7 +75,7 @@ function Roadmap() { // current and future phases { - version: "v4.4.18", + version: "v4.4.99", title: "Enhanced Security Edition", status: "current", date: "Now", diff --git a/src/crypto/EnhancedSecureCryptoUtils.js b/src/crypto/EnhancedSecureCryptoUtils.js index 17a6574..5114c28 100644 --- a/src/crypto/EnhancedSecureCryptoUtils.js +++ b/src/crypto/EnhancedSecureCryptoUtils.js @@ -977,11 +977,18 @@ class EnhancedSecureCryptoUtils { if (level === 'error') { // В production показываем только код ошибки без деталей console.error(`❌ [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]`); + // Временно показываем детали для отладки + if (context && Object.keys(context).length > 0) { + console.error('Error details:', context); + } } else if (level === 'warn') { // В production показываем только предупреждение без контекста console.warn(`⚠️ [SecureChat] ${message}`); + } else if (level === 'info' || level === 'debug') { + // Временно показываем info/debug логи для отладки + console.log(`[SecureChat] ${message}`, context); } else { - // В production не показываем info/debug логи + // В production не показываем другие логи return; } } else { @@ -1914,6 +1921,16 @@ class EnhancedSecureCryptoUtils { // Enhanced key derivation with metadata protection and 64-byte salt static async deriveSharedKeys(privateKey, publicKey, salt) { try { + EnhancedSecureCryptoUtils.secureLog.log('info', 'Starting key derivation', { + privateKeyType: typeof privateKey, + publicKeyType: typeof publicKey, + saltLength: salt?.length, + privateKeyAlgorithm: privateKey?.algorithm?.name, + publicKeyAlgorithm: publicKey?.algorithm?.name, + privateKeyUsages: privateKey?.usages, + publicKeyUsages: publicKey?.usages + }); + // Validate input parameters are CryptoKey instances if (!(privateKey instanceof CryptoKey)) { EnhancedSecureCryptoUtils.secureLog.log('error', 'Private key is not a CryptoKey', { @@ -1928,7 +1945,7 @@ class EnhancedSecureCryptoUtils { publicKeyType: typeof publicKey, publicKeyAlgorithm: publicKey?.algorithm?.name }); - throw new Error('The private key is not a valid CryptoKey.'); + throw new Error('The public key is not a valid CryptoKey.'); } // Validate salt size (should be 64 bytes for enhanced security) @@ -1939,209 +1956,156 @@ class EnhancedSecureCryptoUtils { const saltBytes = new Uint8Array(salt); const encoder = new TextEncoder(); - // Enhanced context info with version and additional entropy - const contextInfo = encoder.encode('SecureBit.chat v4.0 Enhanced Security Edition'); - - // Derive master shared secret with enhanced parameters - // Try SHA-384 first, fallback to SHA-256 - let sharedSecret; + // Step 1: Derive raw ECDH shared secret using pure ECDH + let rawSharedSecret; try { - sharedSecret = await crypto.subtle.deriveKey( - { - name: 'ECDH', - public: publicKey - }, - privateKey, - { - name: 'HKDF', - hash: 'SHA-384', - salt: saltBytes, - info: contextInfo - }, - false, // Non-extractable - ['deriveKey'] - ); - } catch (sha384Error) { - EnhancedSecureCryptoUtils.secureLog.log('warn', 'SHA-384 key derivation failed, trying SHA-256', { - error: sha384Error.message, - privateKeyType: typeof privateKey, - publicKeyType: typeof publicKey, - privateKeyAlgorithm: privateKey?.algorithm?.name, - publicKeyAlgorithm: publicKey?.algorithm?.name - }); + EnhancedSecureCryptoUtils.secureLog.log('info', 'Step 1: Starting ECDH derivation'); - sharedSecret = await crypto.subtle.deriveKey( + // Use pure ECDH to derive raw key material + const rawKeyMaterial = await crypto.subtle.deriveKey( { name: 'ECDH', public: publicKey }, privateKey, - { - name: 'HKDF', - hash: 'SHA-256', - salt: saltBytes, - info: contextInfo - }, - false, // Non-extractable - ['deriveKey'] - ); - } - - // Derive message encryption key with fallback - let encryptionKey; - try { - encryptionKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-384', - salt: saltBytes, - info: encoder.encode('message-encryption-v4') - }, - sharedSecret, { name: 'AES-GCM', length: 256 }, - false, // Non-extractable for enhanced security + true, // Extractable ['encrypt', 'decrypt'] ); - } catch (sha384Error) { - encryptionKey = await crypto.subtle.deriveKey( + + // Export the raw key material + const rawKeyData = await crypto.subtle.exportKey('raw', rawKeyMaterial); + + // Import as HKDF key material for further derivation + rawSharedSecret = await crypto.subtle.importKey( + 'raw', + rawKeyData, { name: 'HKDF', - hash: 'SHA-256', - salt: saltBytes, - info: encoder.encode('message-encryption-v4') - }, - sharedSecret, - { - name: 'AES-GCM', - length: 256 - }, - false, // Non-extractable for enhanced security - ['encrypt', 'decrypt'] - ); - } - - // Derive MAC key for message authentication with fallback - let macKey; - try { - macKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-384', - salt: saltBytes, - info: encoder.encode('message-authentication-v4') - }, - sharedSecret, - { - name: 'HMAC', - hash: 'SHA-384' - }, - false, // Non-extractable - ['sign', 'verify'] - ); - } catch (sha384Error) { - macKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-256', - salt: saltBytes, - info: encoder.encode('message-authentication-v4') - }, - sharedSecret, - { - name: 'HMAC', hash: 'SHA-256' }, - false, // Non-extractable - ['sign', 'verify'] + false, + ['deriveKey'] ); + + EnhancedSecureCryptoUtils.secureLog.log('info', 'Step 1: ECDH derivation successful'); + } catch (error) { + EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDH derivation failed', { + error: error.message + }); + throw error; } + + // Step 2: Use HKDF to derive specific keys directly + EnhancedSecureCryptoUtils.secureLog.log('info', 'Step 2: Starting HKDF key derivation'); - // Derive separate metadata encryption key with fallback + // Step 3: Derive specific keys using HKDF with unique info parameters + // Each key uses unique info parameter for proper separation + + // Derive message encryption key (messageKey) + let messageKey; + messageKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('message-encryption-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + false, // Non-extractable for enhanced security + ['encrypt', 'decrypt'] + ); + + // Derive MAC key for message authentication + let macKey; + macKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('message-authentication-v4') + }, + rawSharedSecret, + { + name: 'HMAC', + hash: 'SHA-256' + }, + false, // Non-extractable + ['sign', 'verify'] + ); + + // Derive Perfect Forward Secrecy key (pfsKey) + let pfsKey; + pfsKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('perfect-forward-secrecy-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + false, // Non-extractable + ['encrypt', 'decrypt'] + ); + + // Derive separate metadata encryption key let metadataKey; - try { - metadataKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-384', - salt: saltBytes, - info: encoder.encode('metadata-protection-v4') - }, - sharedSecret, - { - name: 'AES-GCM', - length: 256 - }, - false, // Non-extractable - ['encrypt', 'decrypt'] - ); - } catch (sha384Error) { - metadataKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-256', - salt: saltBytes, - info: encoder.encode('metadata-protection-v4') - }, - sharedSecret, - { - name: 'AES-GCM', - length: 256 - }, - false, // Non-extractable - ['encrypt', 'decrypt'] - ); - } + metadataKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('metadata-protection-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + false, // Non-extractable + ['encrypt', 'decrypt'] + ); - // Generate temporary extractable key for fingerprint calculation with fallback + // Generate temporary extractable key for fingerprint calculation let fingerprintKey; - try { - fingerprintKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-384', - salt: saltBytes, - info: encoder.encode('fingerprint-generation-v4') - }, - sharedSecret, - { - name: 'AES-GCM', - length: 256 - }, - true, // Extractable only for fingerprint - ['encrypt', 'decrypt'] - ); - } catch (sha384Error) { - fingerprintKey = await crypto.subtle.deriveKey( - { - name: 'HKDF', - hash: 'SHA-256', - salt: saltBytes, - info: encoder.encode('fingerprint-generation-v4') - }, - sharedSecret, - { - name: 'AES-GCM', - length: 256 - }, - true, // Extractable only for fingerprint - ['encrypt', 'decrypt'] - ); - } + fingerprintKey = await crypto.subtle.deriveKey( + { + name: 'HKDF', + hash: 'SHA-256', + salt: saltBytes, + info: encoder.encode('fingerprint-generation-v4') + }, + rawSharedSecret, + { + name: 'AES-GCM', + length: 256 + }, + true, // Extractable only for fingerprint + ['encrypt', 'decrypt'] + ); // Generate key fingerprint for verification const fingerprintKeyData = await crypto.subtle.exportKey('raw', fingerprintKey); const fingerprint = await EnhancedSecureCryptoUtils.generateKeyFingerprint(Array.from(new Uint8Array(fingerprintKeyData))); // Validate that all derived keys are CryptoKey instances - if (!(encryptionKey instanceof CryptoKey)) { - EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived encryption key is not a CryptoKey', { - encryptionKeyType: typeof encryptionKey, - encryptionKeyAlgorithm: encryptionKey?.algorithm?.name + if (!(messageKey instanceof CryptoKey)) { + EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived message key is not a CryptoKey', { + messageKeyType: typeof messageKey, + messageKeyAlgorithm: messageKey?.algorithm?.name }); - throw new Error('The derived encryption key is not a valid CryptoKey.'); + throw new Error('The derived message key is not a valid CryptoKey.'); } if (!(macKey instanceof CryptoKey)) { @@ -2152,6 +2116,14 @@ class EnhancedSecureCryptoUtils { throw new Error('The derived MAC key is not a valid CryptoKey.'); } + if (!(pfsKey instanceof CryptoKey)) { + EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived PFS key is not a CryptoKey', { + pfsKeyType: typeof pfsKey, + pfsKeyAlgorithm: pfsKey?.algorithm?.name + }); + throw new Error('The derived PFS key is not a valid CryptoKey.'); + } + if (!(metadataKey instanceof CryptoKey)) { EnhancedSecureCryptoUtils.secureLog.log('error', 'Derived metadata key is not a CryptoKey', { metadataKeyType: typeof metadataKey, @@ -2160,24 +2132,37 @@ class EnhancedSecureCryptoUtils { throw new Error('The derived metadata key is not a valid CryptoKey.'); } - EnhancedSecureCryptoUtils.secureLog.log('info', 'Enhanced shared keys derived successfully', { + EnhancedSecureCryptoUtils.secureLog.log('info', 'Enhanced shared keys derived successfully with proper HKDF separation', { saltSize: salt.length, + hasMessageKey: true, + hasMacKey: true, + hasPfsKey: true, hasMetadataKey: true, nonExtractable: true, version: '4.0', - allKeysValid: true + allKeysValid: true, + hkdfProperlyImplemented: true }); return { - encryptionKey, + messageKey, // Renamed from encryptionKey for clarity macKey, + pfsKey, // Added Perfect Forward Secrecy key metadataKey, fingerprint, timestamp: Date.now(), version: '4.0' }; } catch (error) { - EnhancedSecureCryptoUtils.secureLog.log('error', 'Enhanced key derivation failed', { error: error.message }); + EnhancedSecureCryptoUtils.secureLog.log('error', 'Enhanced key derivation failed', { + error: error.message, + errorStack: error.stack, + privateKeyType: typeof privateKey, + publicKeyType: typeof publicKey, + saltLength: salt?.length, + privateKeyAlgorithm: privateKey?.algorithm?.name, + publicKeyAlgorithm: publicKey?.algorithm?.name + }); throw new Error(`Failed to create shared encryption keys: ${error.message}`); } } diff --git a/src/network/EnhancedSecureWebRTCManager.js b/src/network/EnhancedSecureWebRTCManager.js index 0b22f34..ea29fd3 100644 --- a/src/network/EnhancedSecureWebRTCManager.js +++ b/src/network/EnhancedSecureWebRTCManager.js @@ -101,7 +101,7 @@ class EnhancedSecureWebRTCManager { }; // Static debug flag instead of this._debugMode - static DEBUG_MODE = false; // Set to true during development, false in production + static DEBUG_MODE = true; // Set to true during development, false in production constructor(onMessage, onStatusChange, onKeyExchange, onVerificationRequired, onAnswerError = null, onVerificationStateChange = null, config = {}) { @@ -9766,22 +9766,47 @@ async processMessage(data) { let derivedKeys; try { + this._secureLog('debug', 'About to call deriveSharedKeys', { + operationId: operationId, + privateKeyType: typeof this.ecdhKeyPair.privateKey, + publicKeyType: typeof peerECDHPublicKey, + saltLength: this.sessionSalt?.length, + privateKeyAlgorithm: this.ecdhKeyPair.privateKey?.algorithm?.name, + publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name + }); + derivedKeys = await window.EnhancedSecureCryptoUtils.deriveSharedKeys( this.ecdhKeyPair.privateKey, peerECDHPublicKey, this.sessionSalt ); + + this._secureLog('debug', 'deriveSharedKeys completed successfully', { + operationId: operationId, + hasMessageKey: !!derivedKeys.messageKey, + hasMacKey: !!derivedKeys.macKey, + hasPfsKey: !!derivedKeys.pfsKey, + hasMetadataKey: !!derivedKeys.metadataKey, + hasFingerprint: !!derivedKeys.fingerprint + }); } catch (error) { this._secureLog('error', 'Failed to derive shared keys', { operationId: operationId, - errorType: error.constructor.name + errorType: error.constructor.name, + errorMessage: error.message, + errorStack: error.stack, + privateKeyType: typeof this.ecdhKeyPair.privateKey, + publicKeyType: typeof peerECDHPublicKey, + saltLength: this.sessionSalt?.length, + privateKeyAlgorithm: this.ecdhKeyPair.privateKey?.algorithm?.name, + publicKeyAlgorithm: peerECDHPublicKey?.algorithm?.name }); this._throwSecureError(error, 'key_derivation'); } // Securely set keys via helper await this._setEncryptionKeys( - derivedKeys.encryptionKey, + derivedKeys.messageKey, derivedKeys.macKey, derivedKeys.metadataKey, derivedKeys.fingerprint @@ -10524,7 +10549,7 @@ async processMessage(data) { this.sessionSalt ); - this.encryptionKey = derivedKeys.encryptionKey; + this.encryptionKey = derivedKeys.messageKey; this.macKey = derivedKeys.macKey; this.metadataKey = derivedKeys.metadataKey; this.keyFingerprint = derivedKeys.fingerprint; diff --git a/sw.js b/sw.js index 76ac780..b308e0a 100644 --- a/sw.js +++ b/sw.js @@ -1,9 +1,9 @@ // SecureBit.chat Service Worker -// Conservative PWA Edition v4.4.18 - Minimal Caching Strategy +// Conservative PWA Edition v4.4.99 - Minimal Caching Strategy -const CACHE_NAME = 'securebit-pwa-v4.4.18'; -const STATIC_CACHE = 'securebit-pwa-static-v4.4.18'; -const DYNAMIC_CACHE = 'securebit-pwa-dynamic-v4.4.18'; +const CACHE_NAME = 'securebit-pwa-v4.4.99'; +const STATIC_CACHE = 'securebit-pwa-static-v4.4.99'; +const DYNAMIC_CACHE = 'securebit-pwa-dynamic-v4.4.99'; // Essential files for PWA offline functionality const STATIC_ASSETS = [