7211.js.map (27975B)
1 {"version":3,"file":"bundles/9cacd6575f4c8ee1aedb/7211.js","mappings":"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","sources":["webpack://element-web/./src/async-components/views/dialogs/security/ImportE2eKeysDialog.tsx","webpack://element-web/./src/utils/MegolmExportEncryption.ts"],"sourcesContent":["/*\nCopyright 2024 New Vector Ltd.\nCopyright 2022 The Matrix.org Foundation C.I.C.\nCopyright 2017 Vector Creations Ltd\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport React, { createRef } from \"react\";\nimport { type MatrixClient } from \"matrix-js-sdk/src/matrix\";\nimport { logger } from \"matrix-js-sdk/src/logger\";\n\nimport * as MegolmExportEncryption from \"../../../../utils/MegolmExportEncryption\";\nimport { _t } from \"../../../../languageHandler\";\nimport BaseDialog from \"../../../../components/views/dialogs/BaseDialog\";\nimport Field from \"../../../../components/views/elements/Field\";\n\nfunction readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n if (e.target?.result) {\n resolve(e.target.result as ArrayBuffer);\n } else {\n reject(new Error(\"Failed to read file due to unknown error\"));\n }\n };\n reader.onerror = reject;\n\n reader.readAsArrayBuffer(file);\n });\n}\n\nenum Phase {\n Edit = \"edit\",\n Importing = \"importing\",\n}\n\ninterface IProps {\n matrixClient: MatrixClient;\n onFinished(imported?: boolean): void;\n}\n\ninterface IState {\n enableSubmit: boolean;\n phase: Phase;\n errStr: string | null;\n passphrase: string;\n}\n\nexport default class ImportE2eKeysDialog extends React.Component<IProps, IState> {\n private unmounted = false;\n private file = createRef<HTMLInputElement>();\n\n public constructor(props: IProps) {\n super(props);\n\n this.state = {\n enableSubmit: false,\n phase: Phase.Edit,\n errStr: null,\n passphrase: \"\",\n };\n }\n\n public componentDidMount(): void {\n this.unmounted = false;\n }\n\n public componentWillUnmount(): void {\n this.unmounted = true;\n }\n\n private onFormChange = (): void => {\n const files = this.file.current?.files;\n this.setState({\n enableSubmit: this.state.passphrase !== \"\" && !!files?.length,\n });\n };\n\n private onPassphraseChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {\n this.setState({ passphrase: ev.target.value }, this.onFormChange); // update general form state too\n };\n\n private onFormSubmit = (ev: React.FormEvent): boolean => {\n ev.preventDefault();\n // noinspection JSIgnoredPromiseFromCall\n const file = this.file.current?.files?.[0];\n if (file) {\n this.startImport(file, this.state.passphrase);\n }\n return false;\n };\n\n private startImport(file: File, passphrase: string): Promise<void> {\n this.setState({\n errStr: null,\n phase: Phase.Importing,\n });\n\n return readFileAsArrayBuffer(file)\n .then((arrayBuffer) => {\n return MegolmExportEncryption.decryptMegolmKeyFile(arrayBuffer, passphrase);\n })\n .then((keys) => {\n return this.props.matrixClient.getCrypto()!.importRoomKeysAsJson(keys);\n })\n .then(() => {\n // TODO: it would probably be nice to give some feedback about what we've imported here.\n this.props.onFinished(true);\n })\n .catch((e) => {\n logger.error(\"Error importing e2e keys:\", e);\n if (this.unmounted) {\n return;\n }\n const msg = e.friendlyText || _t(\"error|unknown\");\n this.setState({\n errStr: msg,\n phase: Phase.Edit,\n });\n });\n }\n\n private onCancelClick = (ev: React.MouseEvent): boolean => {\n ev.preventDefault();\n this.props.onFinished(false);\n return false;\n };\n\n public render(): React.ReactNode {\n const disableForm = this.state.phase !== Phase.Edit;\n\n return (\n <BaseDialog\n className=\"mx_importE2eKeysDialog\"\n onFinished={this.props.onFinished}\n title={_t(\"settings|key_export_import|import_title\")}\n >\n <form onSubmit={this.onFormSubmit}>\n <div className=\"mx_Dialog_content\">\n <p>{_t(\"settings|key_export_import|import_description_1\")}</p>\n <p>{_t(\"settings|key_export_import|import_description_2\")}</p>\n <div className=\"error\">{this.state.errStr}</div>\n <div className=\"mx_E2eKeysDialog_inputTable\">\n <div className=\"mx_E2eKeysDialog_inputRow\">\n <div className=\"mx_E2eKeysDialog_inputLabel\">\n <label htmlFor=\"importFile\">\n {_t(\"settings|key_export_import|file_to_import\")}\n </label>\n </div>\n <div className=\"mx_E2eKeysDialog_inputCell\">\n <input\n ref={this.file}\n id=\"importFile\"\n type=\"file\"\n autoFocus={true}\n onChange={this.onFormChange}\n disabled={disableForm}\n />\n </div>\n </div>\n <div className=\"mx_E2eKeysDialog_inputRow\">\n <Field\n label={_t(\"settings|key_export_import|enter_passphrase\")}\n value={this.state.passphrase}\n onChange={this.onPassphraseChange}\n size={64}\n type=\"password\"\n disabled={disableForm}\n />\n </div>\n </div>\n </div>\n <div className=\"mx_Dialog_buttons\">\n <input\n className=\"mx_Dialog_primary\"\n type=\"submit\"\n value={_t(\"action|import\")}\n disabled={!this.state.enableSubmit || disableForm}\n />\n <button onClick={this.onCancelClick} disabled={disableForm}>\n {_t(\"action|cancel\")}\n </button>\n </div>\n </form>\n </BaseDialog>\n );\n }\n}\n","/*\nCopyright 2024 New Vector Ltd.\nCopyright 2020 The Matrix.org Foundation C.I.C.\nCopyright 2017 Vector Creations Ltd\n\nSPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial\nPlease see LICENSE files in the repository root for full details.\n*/\n\nimport { logger } from \"matrix-js-sdk/src/logger\";\n\nimport { _t } from \"../languageHandler\";\nimport SdkConfig from \"../SdkConfig\";\n\nconst subtleCrypto = window.crypto.subtle;\n\n/**\n * Make an Error object which has a friendlyText property which is already\n * translated and suitable for showing to the user.\n *\n * @param {string} message message for the exception\n * @param {string} friendlyText\n * @returns {{message: string, friendlyText: string}}\n */\nfunction friendlyError(message: string, friendlyText: string): { message: string; friendlyText: string } {\n return { message, friendlyText };\n}\n\nfunction cryptoFailMsg(): string {\n return _t(\"encryption|export_unsupported\");\n}\n\n/**\n * Decrypt a megolm key file\n *\n * @param {ArrayBuffer} data file to decrypt\n * @param {String} password\n * @return {Promise<String>} promise for decrypted output\n *\n *\n */\nexport async function decryptMegolmKeyFile(data: ArrayBuffer, password: string): Promise<string> {\n const body = unpackMegolmKeyFile(data);\n const brand = SdkConfig.get().brand;\n\n // check we have a version byte\n if (body.length < 1) {\n throw friendlyError(\"Invalid file: too short\", _t(\"encryption|import_invalid_keyfile\", { brand }));\n }\n\n const version = body[0];\n if (version !== 1) {\n throw friendlyError(\"Unsupported version\", _t(\"encryption|import_invalid_keyfile\", { brand }));\n }\n\n const ciphertextLength = body.length - (1 + 16 + 16 + 4 + 32);\n if (ciphertextLength < 0) {\n throw friendlyError(\"Invalid file: too short\", _t(\"encryption|import_invalid_keyfile\", { brand }));\n }\n\n const salt = body.subarray(1, 1 + 16);\n const iv = body.subarray(17, 17 + 16);\n const iterations = (body[33] << 24) | (body[34] << 16) | (body[35] << 8) | body[36];\n const ciphertext = body.subarray(37, 37 + ciphertextLength);\n const hmac = body.subarray(-32);\n\n const [aesKey, hmacKey] = await deriveKeys(salt, iterations, password);\n const toVerify = body.subarray(0, -32);\n\n let isValid;\n try {\n isValid = await subtleCrypto.verify({ name: \"HMAC\" }, hmacKey, hmac, toVerify);\n } catch (e) {\n throw friendlyError(\"subtleCrypto.verify failed: \" + e, cryptoFailMsg());\n }\n if (!isValid) {\n throw friendlyError(\"hmac mismatch\", _t(\"encryption|import_invalid_passphrase\"));\n }\n\n let plaintext;\n try {\n plaintext = await subtleCrypto.decrypt(\n {\n name: \"AES-CTR\",\n counter: iv,\n length: 64,\n },\n aesKey,\n ciphertext,\n );\n } catch (e) {\n throw friendlyError(\"subtleCrypto.decrypt failed: \" + e, cryptoFailMsg());\n }\n\n return new TextDecoder().decode(new Uint8Array(plaintext));\n}\n\n/**\n * Encrypt a megolm key file\n *\n * @param {String} data\n * @param {String} password\n * @param {Object=} options\n * @param {Number=} options.kdf_rounds Number of iterations to perform of the\n * key-derivation function.\n * @return {Promise<ArrayBuffer>} promise for encrypted output\n */\nexport async function encryptMegolmKeyFile(\n data: string,\n password: string,\n options?: { kdf_rounds?: number }, // eslint-disable-line camelcase\n): Promise<ArrayBuffer> {\n options = options || {};\n const kdfRounds = options.kdf_rounds || 500000;\n\n const salt = new Uint8Array(16);\n window.crypto.getRandomValues(salt);\n\n const iv = new Uint8Array(16);\n window.crypto.getRandomValues(iv);\n\n // clear bit 63 of the IV to stop us hitting the 64-bit counter boundary\n // (which would mean we wouldn't be able to decrypt on Android). The loss\n // of a single bit of iv is a price we have to pay.\n iv[8] &= 0x7f;\n\n const [aesKey, hmacKey] = await deriveKeys(salt, kdfRounds, password);\n const encodedData = new TextEncoder().encode(data);\n\n let ciphertext;\n try {\n ciphertext = await subtleCrypto.encrypt(\n {\n name: \"AES-CTR\",\n counter: iv,\n length: 64,\n },\n aesKey,\n encodedData,\n );\n } catch (e) {\n throw friendlyError(\"subtleCrypto.encrypt failed: \" + e, cryptoFailMsg());\n }\n\n const cipherArray = new Uint8Array(ciphertext);\n const bodyLength = 1 + salt.length + iv.length + 4 + cipherArray.length + 32;\n const resultBuffer = new Uint8Array(bodyLength);\n let idx = 0;\n resultBuffer[idx++] = 1; // version\n resultBuffer.set(salt, idx);\n idx += salt.length;\n resultBuffer.set(iv, idx);\n idx += iv.length;\n resultBuffer[idx++] = kdfRounds >> 24;\n resultBuffer[idx++] = (kdfRounds >> 16) & 0xff;\n resultBuffer[idx++] = (kdfRounds >> 8) & 0xff;\n resultBuffer[idx++] = kdfRounds & 0xff;\n resultBuffer.set(cipherArray, idx);\n idx += cipherArray.length;\n\n const toSign = resultBuffer.subarray(0, idx);\n\n let hmac;\n try {\n hmac = await subtleCrypto.sign({ name: \"HMAC\" }, hmacKey, toSign);\n } catch (e) {\n throw friendlyError(\"subtleCrypto.sign failed: \" + e, cryptoFailMsg());\n }\n\n const hmacArray = new Uint8Array(hmac);\n resultBuffer.set(hmacArray, idx);\n return packMegolmKeyFile(resultBuffer);\n}\n\n/**\n * Derive the AES and HMAC-SHA-256 keys for the file\n *\n * @param {Unit8Array} salt salt for pbkdf\n * @param {Number} iterations number of pbkdf iterations\n * @param {String} password password\n * @return {Promise<[CryptoKey, CryptoKey]>} promise for [aes key, hmac key]\n */\nasync function deriveKeys(\n salt: Uint8Array<ArrayBuffer>,\n iterations: number,\n password: string,\n): Promise<[CryptoKey, CryptoKey]> {\n const start = new Date();\n\n let key;\n try {\n key = await subtleCrypto.importKey(\"raw\", new TextEncoder().encode(password), { name: \"PBKDF2\" }, false, [\n \"deriveBits\",\n ]);\n } catch (e) {\n throw friendlyError(\"subtleCrypto.importKey failed: \" + e, cryptoFailMsg());\n }\n\n let keybits;\n try {\n keybits = await subtleCrypto.deriveBits(\n {\n name: \"PBKDF2\",\n salt: salt,\n iterations: iterations,\n hash: \"SHA-512\",\n },\n key,\n 512,\n );\n } catch (e) {\n throw friendlyError(\"subtleCrypto.deriveBits failed: \" + e, cryptoFailMsg());\n }\n\n const now = new Date();\n logger.log(\"E2e import/export: deriveKeys took \" + (now.getTime() - start.getTime()) + \"ms\");\n\n const aesKey = keybits.slice(0, 32);\n const hmacKey = keybits.slice(32);\n\n const aesProm = subtleCrypto\n .importKey(\"raw\", aesKey, { name: \"AES-CTR\" }, false, [\"encrypt\", \"decrypt\"])\n .catch((e) => {\n throw friendlyError(\"subtleCrypto.importKey failed for AES key: \" + e, cryptoFailMsg());\n });\n\n const hmacProm = subtleCrypto\n .importKey(\n \"raw\",\n hmacKey,\n {\n name: \"HMAC\",\n hash: { name: \"SHA-256\" },\n },\n false,\n [\"sign\", \"verify\"],\n )\n .catch((e) => {\n throw friendlyError(\"subtleCrypto.importKey failed for HMAC key: \" + e, cryptoFailMsg());\n });\n\n return Promise.all([aesProm, hmacProm]);\n}\n\nconst HEADER_LINE = \"-----BEGIN MEGOLM SESSION DATA-----\";\nconst TRAILER_LINE = \"-----END MEGOLM SESSION DATA-----\";\n\n/**\n * Unbase64 an ascii-armoured megolm key file\n *\n * Strips the header and trailer lines, and unbase64s the content\n *\n * @param {ArrayBuffer} data input file\n * @return {Uint8Array} unbase64ed content\n */\nfunction unpackMegolmKeyFile(data: ArrayBuffer): Uint8Array<ArrayBuffer> {\n // parse the file as a great big String. This should be safe, because there\n // should be no non-ASCII characters, and it means that we can do string\n // comparisons to find the header and footer, and feed it into window.atob.\n const fileStr = new TextDecoder().decode(new Uint8Array(data));\n\n // look for the start line\n let lineStart = 0;\n // eslint-disable-next-line no-constant-condition\n while (1) {\n const lineEnd = fileStr.indexOf(\"\\n\", lineStart);\n if (lineEnd < 0) {\n throw new Error(\"Header line not found\");\n }\n const line = fileStr.slice(lineStart, lineEnd).trim();\n\n // start the next line after the newline\n lineStart = lineEnd + 1;\n\n if (line === HEADER_LINE) {\n break;\n }\n }\n\n const dataStart = lineStart;\n\n // look for the end line\n // eslint-disable-next-line no-constant-condition\n while (1) {\n const lineEnd = fileStr.indexOf(\"\\n\", lineStart);\n const line = fileStr.slice(lineStart, lineEnd < 0 ? undefined : lineEnd).trim();\n if (line === TRAILER_LINE) {\n break;\n }\n\n if (lineEnd < 0) {\n throw new Error(\"Trailer line not found\");\n }\n\n // start the next line after the newline\n lineStart = lineEnd + 1;\n }\n\n const dataEnd = lineStart;\n return decodeBase64(fileStr.slice(dataStart, dataEnd));\n}\n\n/**\n * ascii-armour a megolm key file\n *\n * base64s the content, and adds header and trailer lines\n *\n * @param {Uint8Array} data raw data\n * @return {ArrayBuffer} formatted file\n */\nfunction packMegolmKeyFile(data: Uint8Array): ArrayBuffer {\n // we split into lines before base64ing, because encodeBase64 doesn't deal\n // terribly well with large arrays.\n const LINE_LENGTH = (72 * 4) / 3;\n const nLines = Math.ceil(data.length / LINE_LENGTH);\n const lines = new Array(nLines + 3);\n lines[0] = HEADER_LINE;\n let o = 0;\n let i;\n for (i = 1; i <= nLines; i++) {\n lines[i] = encodeBase64(data.subarray(o, o + LINE_LENGTH));\n o += LINE_LENGTH;\n }\n lines[i++] = TRAILER_LINE;\n lines[i] = \"\";\n return new TextEncoder().encode(lines.join(\"\\n\")).buffer;\n}\n\n/**\n * Encode a typed array of uint8 as base64.\n * @param {Uint8Array} uint8Array The data to encode.\n * @return {string} The base64.\n */\nfunction encodeBase64(uint8Array: Uint8Array): string {\n // Misinterpt the Uint8Array as Latin-1.\n // window.btoa expects a unicode string with codepoints in the range 0-255.\n const latin1String = String.fromCharCode.apply(null, Array.from(uint8Array));\n // Use the builtin base64 encoder.\n return window.btoa(latin1String);\n}\n\n/**\n * Decode a base64 string to a typed array of uint8.\n * @param {string} base64 The base64 to decode.\n * @return {Uint8Array} The decoded data.\n */\nfunction decodeBase64(base64: string): Uint8Array<ArrayBuffer> {\n // window.atob returns a unicode string with codepoints in the range 0-255.\n const latin1String = window.atob(base64);\n // Encode the string as a Uint8Array\n const uint8Array = new Uint8Array(latin1String.length);\n for (let i = 0; i < latin1String.length; i++) {\n uint8Array[i] = latin1String.charCodeAt(i);\n }\n return uint8Array;\n}\n"],"names":["Phase","ImportE2eKeysDialog","React","constructor","props","super","_defineProperty","createRef","_this$file$current","files","this","file","current","setState","enableSubmit","state","passphrase","length","ev","target","value","onFormChange","_this$file$current2","preventDefault","startImport","onFinished","phase","Edit","errStr","componentDidMount","unmounted","componentWillUnmount","Importing","Promise","resolve","reject","reader","FileReader","onload","e","_e$target","result","Error","onerror","readAsArrayBuffer","readFileAsArrayBuffer","then","arrayBuffer","MegolmExportEncryption","keys","matrixClient","getCrypto","importRoomKeysAsJson","catch","logger","error","msg","friendlyText","_t","render","disableForm","BaseDialog","className","title","onSubmit","onFormSubmit","htmlFor","ref","id","type","autoFocus","onChange","disabled","Field","label","onPassphraseChange","size","onClick","onCancelClick","subtleCrypto","window","crypto","subtle","friendlyError","message","cryptoFailMsg","async","decryptMegolmKeyFile","data","password","body","fileStr","TextDecoder","decode","Uint8Array","lineStart","lineEnd","indexOf","line","slice","trim","HEADER_LINE","dataStart","undefined","TRAILER_LINE","dataEnd","base64","latin1String","atob","uint8Array","i","charCodeAt","decodeBase64","unpackMegolmKeyFile","brand","SdkConfig","get","ciphertextLength","salt","subarray","iv","iterations","ciphertext","hmac","aesKey","hmacKey","deriveKeys","toVerify","isValid","plaintext","verify","name","decrypt","counter","encryptMegolmKeyFile","options","kdfRounds","kdf_rounds","getRandomValues","encodedData","TextEncoder","encode","encrypt","cipherArray","bodyLength","resultBuffer","idx","set","toSign","sign","hmacArray","LINE_LENGTH","nLines","Math","ceil","lines","Array","o","encodeBase64","join","buffer","packMegolmKeyFile","start","Date","key","keybits","importKey","deriveBits","hash","now","log","getTime","aesProm","hmacProm","all","String","fromCharCode","apply","from","btoa"],"sourceRoot":""}