You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-12-04 05:02:41 +03:00
Remove crypto shims (#4292)
* Inline subtlecrypto shim The presence of this thing just makes code more confusing. * Remove pre-node-20 webcrypto hack Until node 20.0, the webcrypto API lived at `crypto.webCrypto`. It's now available at the same place as in web -- `globalThis.crypto`. See: https://nodejs.org/docs/latest-v20.x/api/webcrypto.html#web-crypto-api * oidc auth test: Clean up mocking THe previous reset code wasn't really resetting the right thing. Let's just re-init `window.crypto` on each test. * Remove `crypto` shim This isn't very useful any more.
This commit is contained in:
committed by
GitHub
parent
957329b218
commit
712ba617de
@@ -26,7 +26,6 @@ import { getRandomValues } from "node:crypto";
|
|||||||
import { TextEncoder } from "node:util";
|
import { TextEncoder } from "node:util";
|
||||||
|
|
||||||
import { Method } from "../../../src";
|
import { Method } from "../../../src";
|
||||||
import * as crypto from "../../../src/crypto/crypto";
|
|
||||||
import { logger } from "../../../src/logger";
|
import { logger } from "../../../src/logger";
|
||||||
import {
|
import {
|
||||||
completeAuthorizationCodeGrant,
|
completeAuthorizationCodeGrant,
|
||||||
@@ -39,11 +38,6 @@ import { makeDelegatedAuthConfig, mockOpenIdConfiguration } from "../../test-uti
|
|||||||
|
|
||||||
jest.mock("jwt-decode");
|
jest.mock("jwt-decode");
|
||||||
|
|
||||||
const webCrypto = new Crypto();
|
|
||||||
|
|
||||||
// save for resetting mocks
|
|
||||||
const realSubtleCrypto = crypto.subtleCrypto;
|
|
||||||
|
|
||||||
describe("oidc authorization", () => {
|
describe("oidc authorization", () => {
|
||||||
const delegatedAuthConfig = makeDelegatedAuthConfig();
|
const delegatedAuthConfig = makeDelegatedAuthConfig();
|
||||||
const authorizationEndpoint = delegatedAuthConfig.authorizationEndpoint;
|
const authorizationEndpoint = delegatedAuthConfig.authorizationEndpoint;
|
||||||
@@ -62,7 +56,11 @@ describe("oidc authorization", () => {
|
|||||||
delegatedAuthConfig.metadata.issuer + ".well-known/openid-configuration",
|
delegatedAuthConfig.metadata.issuer + ".well-known/openid-configuration",
|
||||||
mockOpenIdConfiguration(),
|
mockOpenIdConfiguration(),
|
||||||
);
|
);
|
||||||
|
global.TextEncoder = TextEncoder;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const webCrypto = new Crypto();
|
||||||
Object.defineProperty(window, "crypto", {
|
Object.defineProperty(window, "crypto", {
|
||||||
value: {
|
value: {
|
||||||
getRandomValues,
|
getRandomValues,
|
||||||
@@ -70,12 +68,6 @@ describe("oidc authorization", () => {
|
|||||||
subtle: webCrypto.subtle,
|
subtle: webCrypto.subtle,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
global.TextEncoder = TextEncoder;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
// @ts-ignore reset any ugly mocking we did
|
|
||||||
crypto.subtleCrypto = realSubtleCrypto;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should generate authorization params", () => {
|
it("should generate authorization params", () => {
|
||||||
@@ -99,7 +91,7 @@ describe("oidc authorization", () => {
|
|||||||
it("should generate url with correct parameters", async () => {
|
it("should generate url with correct parameters", async () => {
|
||||||
// test the no crypto case here
|
// test the no crypto case here
|
||||||
// @ts-ignore mocking
|
// @ts-ignore mocking
|
||||||
crypto.subtleCrypto = undefined;
|
globalThis.crypto.subtle = undefined;
|
||||||
|
|
||||||
const authorizationParams = generateAuthorizationParams({ redirectUri: baseUrl });
|
const authorizationParams = generateAuthorizationParams({ redirectUri: baseUrl });
|
||||||
const authUrl = new URL(
|
const authUrl = new URL(
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { decodeBase64, encodeBase64 } from "../base64";
|
import { decodeBase64, encodeBase64 } from "../base64";
|
||||||
import { subtleCrypto, crypto } from "./crypto";
|
|
||||||
|
|
||||||
// salt for HKDF, with 8 bytes of zeros
|
// salt for HKDF, with 8 bytes of zeros
|
||||||
const zeroSalt = new Uint8Array(8);
|
const zeroSalt = new Uint8Array(8);
|
||||||
@@ -49,7 +48,7 @@ export async function encryptAES(
|
|||||||
iv = decodeBase64(ivStr);
|
iv = decodeBase64(ivStr);
|
||||||
} else {
|
} else {
|
||||||
iv = new Uint8Array(16);
|
iv = new Uint8Array(16);
|
||||||
crypto.getRandomValues(iv);
|
globalThis.crypto.getRandomValues(iv);
|
||||||
|
|
||||||
// clear bit 63 of the IV to stop us hitting the 64-bit counter boundary
|
// clear bit 63 of the IV to stop us hitting the 64-bit counter boundary
|
||||||
// (which would mean we wouldn't be able to decrypt on Android). The loss
|
// (which would mean we wouldn't be able to decrypt on Android). The loss
|
||||||
@@ -60,7 +59,7 @@ export async function encryptAES(
|
|||||||
const [aesKey, hmacKey] = await deriveKeys(key, name);
|
const [aesKey, hmacKey] = await deriveKeys(key, name);
|
||||||
const encodedData = new TextEncoder().encode(data);
|
const encodedData = new TextEncoder().encode(data);
|
||||||
|
|
||||||
const ciphertext = await subtleCrypto.encrypt(
|
const ciphertext = await globalThis.crypto.subtle.encrypt(
|
||||||
{
|
{
|
||||||
name: "AES-CTR",
|
name: "AES-CTR",
|
||||||
counter: iv,
|
counter: iv,
|
||||||
@@ -70,7 +69,7 @@ export async function encryptAES(
|
|||||||
encodedData,
|
encodedData,
|
||||||
);
|
);
|
||||||
|
|
||||||
const hmac = await subtleCrypto.sign({ name: "HMAC" }, hmacKey, ciphertext);
|
const hmac = await globalThis.crypto.subtle.sign({ name: "HMAC" }, hmacKey, ciphertext);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
iv: encodeBase64(iv),
|
iv: encodeBase64(iv),
|
||||||
@@ -91,11 +90,11 @@ export async function decryptAES(data: IEncryptedPayload, key: Uint8Array, name:
|
|||||||
|
|
||||||
const ciphertext = decodeBase64(data.ciphertext);
|
const ciphertext = decodeBase64(data.ciphertext);
|
||||||
|
|
||||||
if (!(await subtleCrypto.verify({ name: "HMAC" }, hmacKey, decodeBase64(data.mac), ciphertext))) {
|
if (!(await globalThis.crypto.subtle.verify({ name: "HMAC" }, hmacKey, decodeBase64(data.mac), ciphertext))) {
|
||||||
throw new Error(`Error decrypting secret ${name}: bad MAC`);
|
throw new Error(`Error decrypting secret ${name}: bad MAC`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const plaintext = await subtleCrypto.decrypt(
|
const plaintext = await globalThis.crypto.subtle.decrypt(
|
||||||
{
|
{
|
||||||
name: "AES-CTR",
|
name: "AES-CTR",
|
||||||
counter: decodeBase64(data.iv),
|
counter: decodeBase64(data.iv),
|
||||||
@@ -109,8 +108,8 @@ export async function decryptAES(data: IEncryptedPayload, key: Uint8Array, name:
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deriveKeys(key: Uint8Array, name: string): Promise<[CryptoKey, CryptoKey]> {
|
async function deriveKeys(key: Uint8Array, name: string): Promise<[CryptoKey, CryptoKey]> {
|
||||||
const hkdfkey = await subtleCrypto.importKey("raw", key, { name: "HKDF" }, false, ["deriveBits"]);
|
const hkdfkey = await globalThis.crypto.subtle.importKey("raw", key, { name: "HKDF" }, false, ["deriveBits"]);
|
||||||
const keybits = await subtleCrypto.deriveBits(
|
const keybits = await globalThis.crypto.subtle.deriveBits(
|
||||||
{
|
{
|
||||||
name: "HKDF",
|
name: "HKDF",
|
||||||
salt: zeroSalt,
|
salt: zeroSalt,
|
||||||
@@ -126,9 +125,12 @@ async function deriveKeys(key: Uint8Array, name: string): Promise<[CryptoKey, Cr
|
|||||||
const aesKey = keybits.slice(0, 32);
|
const aesKey = keybits.slice(0, 32);
|
||||||
const hmacKey = keybits.slice(32);
|
const hmacKey = keybits.slice(32);
|
||||||
|
|
||||||
const aesProm = subtleCrypto.importKey("raw", aesKey, { name: "AES-CTR" }, false, ["encrypt", "decrypt"]);
|
const aesProm = globalThis.crypto.subtle.importKey("raw", aesKey, { name: "AES-CTR" }, false, [
|
||||||
|
"encrypt",
|
||||||
|
"decrypt",
|
||||||
|
]);
|
||||||
|
|
||||||
const hmacProm = subtleCrypto.importKey(
|
const hmacProm = globalThis.crypto.subtle.importKey(
|
||||||
"raw",
|
"raw",
|
||||||
hmacKey,
|
hmacKey,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import {
|
|||||||
} from "./keybackup";
|
} from "./keybackup";
|
||||||
import { UnstableValue } from "../NamespacedValue";
|
import { UnstableValue } from "../NamespacedValue";
|
||||||
import { CryptoEvent } from "./index";
|
import { CryptoEvent } from "./index";
|
||||||
import { crypto } from "./crypto";
|
|
||||||
import { ClientPrefix, HTTPError, MatrixError, Method } from "../http-api";
|
import { ClientPrefix, HTTPError, MatrixError, Method } from "../http-api";
|
||||||
import { BackupTrustInfo } from "../crypto-api/keybackup";
|
import { BackupTrustInfo } from "../crypto-api/keybackup";
|
||||||
import { BackupDecryptor } from "../common-crypto/CryptoBackend";
|
import { BackupDecryptor } from "../common-crypto/CryptoBackend";
|
||||||
@@ -764,7 +763,7 @@ export class Curve25519 implements BackupAlgorithm {
|
|||||||
|
|
||||||
function randomBytes(size: number): Uint8Array {
|
function randomBytes(size: number): Uint8Array {
|
||||||
const buf = new Uint8Array(size);
|
const buf = new Uint8Array(size);
|
||||||
crypto.getRandomValues(buf);
|
globalThis.crypto.getRandomValues(buf);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,25 +14,5 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { logger } from "../logger";
|
/** @deprecated this is a no-op and should no longer be called. */
|
||||||
|
export function setCrypto(_crypto: Crypto): void {}
|
||||||
export let crypto = globalThis.crypto;
|
|
||||||
export let subtleCrypto = crypto?.subtle ?? crypto?.webkitSubtle; // TODO: Stop using webkitSubtle fallback
|
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
||||||
if (!crypto) {
|
|
||||||
try {
|
|
||||||
crypto = require("crypto").webcrypto;
|
|
||||||
} catch (e) {
|
|
||||||
logger.error("Failed to load webcrypto", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!subtleCrypto) {
|
|
||||||
subtleCrypto = crypto?.subtle;
|
|
||||||
}
|
|
||||||
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
||||||
|
|
||||||
export function setCrypto(_crypto: Crypto): void {
|
|
||||||
crypto = _crypto;
|
|
||||||
subtleCrypto = _crypto.subtle ?? _crypto.webkitSubtle;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { randomString } from "../randomstring";
|
import { randomString } from "../randomstring";
|
||||||
import { subtleCrypto } from "./crypto";
|
|
||||||
|
|
||||||
const DEFAULT_ITERATIONS = 500000;
|
const DEFAULT_ITERATIONS = 500000;
|
||||||
|
|
||||||
@@ -62,15 +61,19 @@ export async function deriveKey(
|
|||||||
iterations: number,
|
iterations: number,
|
||||||
numBits = DEFAULT_BITSIZE,
|
numBits = DEFAULT_BITSIZE,
|
||||||
): Promise<Uint8Array> {
|
): Promise<Uint8Array> {
|
||||||
if (!subtleCrypto || !TextEncoder) {
|
if (!globalThis.crypto.subtle || !TextEncoder) {
|
||||||
throw new Error("Password-based backup is not available on this platform");
|
throw new Error("Password-based backup is not available on this platform");
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = await subtleCrypto.importKey("raw", new TextEncoder().encode(password), { name: "PBKDF2" }, false, [
|
const key = await globalThis.crypto.subtle.importKey(
|
||||||
"deriveBits",
|
"raw",
|
||||||
]);
|
new TextEncoder().encode(password),
|
||||||
|
{ name: "PBKDF2" },
|
||||||
|
false,
|
||||||
|
["deriveBits"],
|
||||||
|
);
|
||||||
|
|
||||||
const keybits = await subtleCrypto.deriveBits(
|
const keybits = await globalThis.crypto.subtle.deriveBits(
|
||||||
{
|
{
|
||||||
name: "PBKDF2",
|
name: "PBKDF2",
|
||||||
salt: new TextEncoder().encode(salt),
|
salt: new TextEncoder().encode(salt),
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ limitations under the License.
|
|||||||
* QR code key verification.
|
* QR code key verification.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { crypto } from "../crypto";
|
|
||||||
import { VerificationBase as Base } from "./Base";
|
import { VerificationBase as Base } from "./Base";
|
||||||
import { newKeyMismatchError, newUserCancelledError } from "./Error";
|
import { newKeyMismatchError, newUserCancelledError } from "./Error";
|
||||||
import { decodeBase64, encodeUnpaddedBase64 } from "../../base64";
|
import { decodeBase64, encodeUnpaddedBase64 } from "../../base64";
|
||||||
@@ -202,7 +201,7 @@ export class QRCodeData {
|
|||||||
|
|
||||||
private static generateSharedSecret(): string {
|
private static generateSharedSecret(): string {
|
||||||
const secretBytes = new Uint8Array(11);
|
const secretBytes = new Uint8Array(11);
|
||||||
crypto.getRandomValues(secretBytes);
|
globalThis.crypto.getRandomValues(secretBytes);
|
||||||
return encodeUnpaddedBase64(secretBytes);
|
return encodeUnpaddedBase64(secretBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,17 +16,16 @@ limitations under the License.
|
|||||||
|
|
||||||
import { IdTokenClaims, Log, OidcClient, SigninResponse, SigninState, WebStorageStateStore } from "oidc-client-ts";
|
import { IdTokenClaims, Log, OidcClient, SigninResponse, SigninState, WebStorageStateStore } from "oidc-client-ts";
|
||||||
|
|
||||||
import { subtleCrypto } from "../crypto/crypto";
|
|
||||||
import { logger } from "../logger";
|
import { logger } from "../logger";
|
||||||
import { randomString } from "../randomstring";
|
import { randomString } from "../randomstring";
|
||||||
import { OidcError } from "./error";
|
import { OidcError } from "./error";
|
||||||
import {
|
import {
|
||||||
validateIdToken,
|
|
||||||
ValidatedIssuerMetadata,
|
|
||||||
validateStoredUserState,
|
|
||||||
UserState,
|
|
||||||
BearerTokenResponse,
|
BearerTokenResponse,
|
||||||
|
UserState,
|
||||||
validateBearerTokenResponse,
|
validateBearerTokenResponse,
|
||||||
|
ValidatedIssuerMetadata,
|
||||||
|
validateIdToken,
|
||||||
|
validateStoredUserState,
|
||||||
} from "./validate";
|
} from "./validate";
|
||||||
|
|
||||||
// reexport for backwards compatibility
|
// reexport for backwards compatibility
|
||||||
@@ -57,14 +56,14 @@ export const generateScope = (deviceId?: string): string => {
|
|||||||
|
|
||||||
// https://www.rfc-editor.org/rfc/rfc7636
|
// https://www.rfc-editor.org/rfc/rfc7636
|
||||||
const generateCodeChallenge = async (codeVerifier: string): Promise<string> => {
|
const generateCodeChallenge = async (codeVerifier: string): Promise<string> => {
|
||||||
if (!subtleCrypto) {
|
if (!globalThis.crypto.subtle) {
|
||||||
// @TODO(kerrya) should this be allowed? configurable?
|
// @TODO(kerrya) should this be allowed? configurable?
|
||||||
logger.warn("A secure context is required to generate code challenge. Using plain text code challenge");
|
logger.warn("A secure context is required to generate code challenge. Using plain text code challenge");
|
||||||
return codeVerifier;
|
return codeVerifier;
|
||||||
}
|
}
|
||||||
const utf8 = new TextEncoder().encode(codeVerifier);
|
const utf8 = new TextEncoder().encode(codeVerifier);
|
||||||
|
|
||||||
const digest = await subtleCrypto.digest("SHA-256", utf8);
|
const digest = await globalThis.crypto.subtle.digest("SHA-256", utf8);
|
||||||
|
|
||||||
return btoa(String.fromCharCode(...new Uint8Array(digest)))
|
return btoa(String.fromCharCode(...new Uint8Array(digest)))
|
||||||
.replace(/=/g, "")
|
.replace(/=/g, "")
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { encodeUnpaddedBase64Url } from "./base64";
|
import { encodeUnpaddedBase64Url } from "./base64";
|
||||||
import { crypto } from "./crypto/crypto";
|
|
||||||
|
|
||||||
const LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
|
const LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
|
||||||
const UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
@@ -24,7 +23,7 @@ const DIGITS = "0123456789";
|
|||||||
|
|
||||||
export function secureRandomBase64Url(len: number): string {
|
export function secureRandomBase64Url(len: number): string {
|
||||||
const key = new Uint8Array(len);
|
const key = new Uint8Array(len);
|
||||||
crypto.getRandomValues(key);
|
globalThis.crypto.getRandomValues(key);
|
||||||
|
|
||||||
return encodeUnpaddedBase64Url(key);
|
return encodeUnpaddedBase64Url(key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,15 @@ limitations under the License.
|
|||||||
import { SAS } from "@matrix-org/olm";
|
import { SAS } from "@matrix-org/olm";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
RendezvousError,
|
|
||||||
RendezvousCode,
|
|
||||||
RendezvousIntent,
|
|
||||||
RendezvousChannel,
|
|
||||||
RendezvousTransportDetails,
|
|
||||||
RendezvousTransport,
|
|
||||||
LegacyRendezvousFailureReason as RendezvousFailureReason,
|
LegacyRendezvousFailureReason as RendezvousFailureReason,
|
||||||
|
RendezvousChannel,
|
||||||
|
RendezvousCode,
|
||||||
|
RendezvousError,
|
||||||
|
RendezvousIntent,
|
||||||
|
RendezvousTransport,
|
||||||
|
RendezvousTransportDetails,
|
||||||
} from "..";
|
} from "..";
|
||||||
import { encodeUnpaddedBase64, decodeBase64 } from "../../base64";
|
import { decodeBase64, encodeUnpaddedBase64 } from "../../base64";
|
||||||
import { crypto, subtleCrypto } from "../../crypto/crypto";
|
|
||||||
import { generateDecimalSas } from "../../crypto/verification/SASDecimal";
|
import { generateDecimalSas } from "../../crypto/verification/SASDecimal";
|
||||||
import { UnstableValue } from "../../NamespacedValue";
|
import { UnstableValue } from "../../NamespacedValue";
|
||||||
|
|
||||||
@@ -56,11 +55,11 @@ export interface EncryptedPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function importKey(key: Uint8Array): Promise<CryptoKey> {
|
async function importKey(key: Uint8Array): Promise<CryptoKey> {
|
||||||
if (!subtleCrypto) {
|
if (!globalThis.crypto.subtle) {
|
||||||
throw new Error("Web Crypto is not available");
|
throw new Error("Web Crypto is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
const imported = subtleCrypto.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
const imported = globalThis.crypto.subtle.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
||||||
|
|
||||||
return imported;
|
return imported;
|
||||||
}
|
}
|
||||||
@@ -164,16 +163,16 @@ export class MSC3903ECDHv2RendezvousChannel<T> implements RendezvousChannel<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async encrypt(data: T): Promise<MSC3903ECDHPayload> {
|
private async encrypt(data: T): Promise<MSC3903ECDHPayload> {
|
||||||
if (!subtleCrypto) {
|
if (!globalThis.crypto.subtle) {
|
||||||
throw new Error("Web Crypto is not available");
|
throw new Error("Web Crypto is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
const iv = new Uint8Array(32);
|
const iv = new Uint8Array(32);
|
||||||
crypto.getRandomValues(iv);
|
globalThis.crypto.getRandomValues(iv);
|
||||||
|
|
||||||
const encodedData = new TextEncoder().encode(JSON.stringify(data));
|
const encodedData = new TextEncoder().encode(JSON.stringify(data));
|
||||||
|
|
||||||
const ciphertext = await subtleCrypto.encrypt(
|
const ciphertext = await globalThis.crypto.subtle.encrypt(
|
||||||
{
|
{
|
||||||
name: "AES-GCM",
|
name: "AES-GCM",
|
||||||
iv,
|
iv,
|
||||||
@@ -208,11 +207,11 @@ export class MSC3903ECDHv2RendezvousChannel<T> implements RendezvousChannel<T> {
|
|||||||
|
|
||||||
const ciphertextBytes = decodeBase64(ciphertext);
|
const ciphertextBytes = decodeBase64(ciphertext);
|
||||||
|
|
||||||
if (!subtleCrypto) {
|
if (!globalThis.crypto.subtle) {
|
||||||
throw new Error("Web Crypto is not available");
|
throw new Error("Web Crypto is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
const plaintext = await subtleCrypto.decrypt(
|
const plaintext = await globalThis.crypto.subtle.decrypt(
|
||||||
{
|
{
|
||||||
name: "AES-GCM",
|
name: "AES-GCM",
|
||||||
iv: decodeBase64(iv),
|
iv: decodeBase64(iv),
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import { encodeUri } from "../utils";
|
|||||||
import { IHttpOpts, MatrixError, MatrixHttpApi, Method } from "../http-api";
|
import { IHttpOpts, MatrixError, MatrixHttpApi, Method } from "../http-api";
|
||||||
import { IToDeviceEvent } from "../sync-accumulator";
|
import { IToDeviceEvent } from "../sync-accumulator";
|
||||||
import { ServerSideSecretStorage } from "../secret-storage";
|
import { ServerSideSecretStorage } from "../secret-storage";
|
||||||
import { crypto } from "../crypto/crypto";
|
|
||||||
import { decodeBase64, encodeUnpaddedBase64 } from "../base64";
|
import { decodeBase64, encodeUnpaddedBase64 } from "../base64";
|
||||||
import { Logger } from "../logger";
|
import { Logger } from "../logger";
|
||||||
|
|
||||||
@@ -155,7 +154,7 @@ export class DehydratedDeviceManager {
|
|||||||
*/
|
*/
|
||||||
public async resetKey(): Promise<void> {
|
public async resetKey(): Promise<void> {
|
||||||
const key = new Uint8Array(32);
|
const key = new Uint8Array(32);
|
||||||
crypto.getRandomValues(key);
|
globalThis.crypto.getRandomValues(key);
|
||||||
await this.secretStorage.store(SECRET_STORAGE_NAME, encodeUnpaddedBase64(key));
|
await this.secretStorage.store(SECRET_STORAGE_NAME, encodeUnpaddedBase64(key));
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ import { CrossSigningIdentity } from "./CrossSigningIdentity";
|
|||||||
import { secretStorageCanAccessSecrets, secretStorageContainsCrossSigningKeys } from "./secret-storage";
|
import { secretStorageCanAccessSecrets, secretStorageContainsCrossSigningKeys } from "./secret-storage";
|
||||||
import { keyFromPassphrase } from "../crypto/key_passphrase";
|
import { keyFromPassphrase } from "../crypto/key_passphrase";
|
||||||
import { encodeRecoveryKey } from "../crypto/recoverykey";
|
import { encodeRecoveryKey } from "../crypto/recoverykey";
|
||||||
import { crypto } from "../crypto/crypto";
|
|
||||||
import { isVerificationEvent, RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification";
|
import { isVerificationEvent, RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification";
|
||||||
import { EventType, MsgType } from "../@types/event";
|
import { EventType, MsgType } from "../@types/event";
|
||||||
import { CryptoEvent } from "../crypto";
|
import { CryptoEvent } from "../crypto";
|
||||||
@@ -891,7 +890,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
} else {
|
} else {
|
||||||
// Using the navigator crypto API to generate the private key
|
// Using the navigator crypto API to generate the private key
|
||||||
const key = new Uint8Array(32);
|
const key = new Uint8Array(32);
|
||||||
crypto.getRandomValues(key);
|
globalThis.crypto.getRandomValues(key);
|
||||||
return {
|
return {
|
||||||
privateKey: key,
|
privateKey: key,
|
||||||
encodedPrivateKey: encodeRecoveryKey(key),
|
encodedPrivateKey: encodeRecoveryKey(key),
|
||||||
|
|||||||
Reference in New Issue
Block a user