|
331 | 331 |
|
332 | 332 | RSA.publicKeyBits = 2048; // number of bits in RSA public key, which must be at least 2048
|
333 | 333 | RSA.publicKeySize = RSA.publicKeyBits / 8; // number of bytes for RSA-OAEP encrypted data size
|
334 |
| - RSA.publicKeyBase64 = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxd5OKVoLgirReke8SqdEkels5xwpJ8j9qZlyMjbFScCC9DNcbFCuOFHrpPBtauCXprygbT2WGnahU/NZGF467A1NNoi2NBxbYqhKRZ+6mHKIHEmNM+ANAOssgoFsj2bynz6G6DjN2pEBVL9mXxeogvNnn3N0EJtnrKwqRtyMay4CxrilT+v46Or99mlkJP/2UcJqoTax8FVovVb4tL69Cu6Vkn3I2ATUu3gA1evUJgNrtLdQTnpi3AK4h9zW3TuF0yAexSvb5mCmlZ92tHvvNuRUS5pevRAyDWawv9j2vZmLwBk5MSBBmqg0NNAnuSz4iKJBEV6JVPTQdxrmAFZ6YQIDAQAB'; |
335 |
| - ECDSA.publicKeyBase64 = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpEObqiXsmmo11EXm8PSCaZlugTs8PlDKzc9Nm46c3ERW8lDG+6XJ1nG0KaOJmB5vj3v/BOiM41QWHcfkRQgDnA=='; |
| 334 | + RSA.publicKeyBase64 = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv6dGbIUSD3kQWmvBYXnaUszgJI1e8AbVcerOHOI3nSrgi3n2v/JBnuPwRlsffyRxEEZZYWh7aRMUhujTQON8xjxblhS42/veIIr9s30sOnn/u7+/+I9XdvZOZtAw0+UPhWLgmV6LRvQW/55Bq6p+FTcNpw/b3dYSKOUqz0zIXTlNEl6RTxmq5qyKGMN4MU5r1vU/199ShGnfF5EtAQL/Hr6q/M+bwINy0IW/31VFbIJyLYASJyuj28gkz3szjr9GQ8W3MOXetD/bQhYP8YPiwmf4W6EfaI5GSMaymn2Wrl68X0I1p5P5ZY4zJwh7Q1hIB1UT5l9SPE+Nrvp8Fc43ZQIDAQAB'; |
| 335 | + ECDSA.publicKeyBase64 = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7gUfFZDR97WPYG3rLeciBX389l4C/UflJKJ4ZUjzMkIOGWXYH1TWPGUnyW9/3bNjfHnvxRQXMvOJ/Jsxqjk3Mg=='; |
336 | 336 | ECDSA.signatureLength = SHA256.hashBytes * 2;
|
337 | 337 | ECDHE.publicKeyLength = 1 + SHA256.hashBytes * 2;
|
338 | 338 |
|
|
1710 | 1710 | const getBrowserHash = async function getBrowserHash() {
|
1711 | 1711 | //await Promise.all(promises);
|
1712 | 1712 | //traverseDone = true;
|
1713 |
| - const browserHashJSON = JSON.stringify(browserHashObject, null, 0); |
| 1713 | + let browserHashJSON = JSON.stringify(browserHashObject, null, 0); |
1714 | 1714 | //console.log(JSON.stringify(browserHashObject, null, 2));
|
| 1715 | + browserHashObject = null; |
1715 | 1716 | const browserHashUtf8 = new TextEncoder('utf-8').encode(browserHashJSON);
|
| 1717 | + browserHashJSON = null; |
1716 | 1718 | const browserHash = await crypto.subtle.digest(SHA256.hashName, browserHashUtf8);
|
| 1719 | + browserHashUtf8.fill(0); |
1717 | 1720 | return browserHash;
|
1718 | 1721 | }
|
1719 | 1722 |
|
|
1725 | 1728 | ));
|
1726 | 1729 | const userAgentUtf8 = new TextEncoder('utf-8').encode(navigator.userAgent);
|
1727 | 1730 | const userAgentHash = await crypto.subtle.digest(SHA256.hashName, userAgentUtf8);
|
| 1731 | + userAgentUtf8.fill(0); |
1728 | 1732 | const browserHash = await getBrowserHash();
|
1729 | 1733 | const scriptsUtf8 = new TextEncoder('utf-8').encode(scripts.join('\0'));
|
1730 | 1734 | const scriptsHash = await crypto.subtle.digest(SHA256.hashName, scriptsUtf8);
|
| 1735 | + scriptsUtf8.fill(0); |
1731 | 1736 | outerHTML = document.querySelector('html').outerHTML;
|
1732 | 1737 | //console.log('outerHTML', outerHTML);
|
1733 | 1738 | const htmlUtf8 = new TextEncoder('utf-8').encode(outerHTML);
|
1734 | 1739 | const htmlHash = await crypto.subtle.digest(SHA256.hashName, htmlUtf8);
|
| 1740 | + htmlUtf8.fill(0); |
1735 | 1741 |
|
1736 | 1742 | CurrentSession.ClientIntegrity = {
|
1737 | 1743 | userAgentHash: userAgentHash,
|
|
1749 | 1755 |
|
1750 | 1756 | Connect.encryptedHeader =
|
1751 | 1757 | await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, RSA.serverPublicKey, decryptedHeader);
|
| 1758 | + decryptedHeader.fill(0); |
1752 | 1759 |
|
1753 | 1760 | const decryptedBody = HKDF.concat(
|
1754 | 1761 | NextSession.clientRandom,
|
|
1775 | 1782 | );
|
1776 | 1783 | Connect.encryptedBody =
|
1777 | 1784 | await crypto.subtle.encrypt(aesAlg, aesKey, decryptedBody);
|
| 1785 | + decryptedBody.fill(0); |
1778 | 1786 |
|
1779 | 1787 | Connect.encrypted = HKDF.concat(
|
1780 | 1788 | Connect.type,
|
|
2038 | 2046 | CurrentSession.ClientIntegrity.htmlHash,
|
2039 | 2047 | ));
|
2040 | 2048 |
|
| 2049 | + // Discard ClientIntegrity |
| 2050 | + [ 'userAgentHash', 'browserHash', 'scriptsHash', 'htmlHash' ].forEach((name) => { |
| 2051 | + new Uint8Array(CurrentSession.ClientIntegrity[name]).fill(0); |
| 2052 | + delete CurrentSession.ClientIntegrity[name]; |
| 2053 | + }); |
| 2054 | + delete CurrentSession.ClientIntegrity; |
| 2055 | + |
2041 | 2056 | // Derive Pseudo-PSK for initial key derivation
|
2042 | 2057 | CurrentSession.PSK =
|
2043 | 2058 | await HKDF.Expand_Label(CurrentSession.connect_early_secret, 'connect', '', SHA256.hashBytes); // pseudo-PSK
|
|
2057 | 2072 | false,
|
2058 | 2073 | ['sign']
|
2059 | 2074 | );
|
| 2075 | + // Discard connect_salt |
| 2076 | + new Uint8Array(CurrentSession.connect_salt).fill(0); |
| 2077 | + delete CurrentSession.connect_salt; |
2060 | 2078 |
|
2061 | 2079 | if (!await sendConnectRequest(Connect, Accept, CurrentSession, NextSession)) {
|
2062 | 2080 | throw new Error('doConnect: sendConnectRequest failed');
|
|
0 commit comments