mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-16831] TS Strict crypto function service (#12737)
* strict types in crypto function services * Improve aesDecrypt types
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { DecryptParameters } from "@bitwarden/common/platform/models/domain/decrypt-parameters";
|
||||
import { EcbDecryptParameters } from "@bitwarden/common/platform/models/domain/decrypt-parameters";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
|
||||
import { NodeCryptoFunctionService } from "./node-crypto-function.service";
|
||||
@@ -193,8 +193,8 @@ describe("NodeCrypto Function Service", () => {
|
||||
const iv = Utils.fromBufferToB64(makeStaticByteArray(16));
|
||||
const symKey = new SymmetricCryptoKey(makeStaticByteArray(32));
|
||||
const data = "ByUF8vhyX4ddU9gcooznwA==";
|
||||
const params = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params, "cbc");
|
||||
const parameters = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey);
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast({ mode: "cbc", parameters });
|
||||
expect(decValue).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
@@ -202,10 +202,11 @@ describe("NodeCrypto Function Service", () => {
|
||||
describe("aesDecryptFast ECB mode", () => {
|
||||
it("should successfully decrypt data", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const params = new DecryptParameters<Uint8Array>();
|
||||
params.encKey = makeStaticByteArray(32);
|
||||
params.data = Utils.fromB64ToArray("z5q2XSxYCdQFdI+qK2yLlw==");
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params, "ecb");
|
||||
const parameters: EcbDecryptParameters<Uint8Array> = {
|
||||
encKey: makeStaticByteArray(32),
|
||||
data: Utils.fromB64ToArray("z5q2XSxYCdQFdI+qK2yLlw=="),
|
||||
};
|
||||
const decValue = await nodeCryptoFunctionService.aesDecryptFast({ mode: "ecb", parameters });
|
||||
expect(decValue).toBe("EncryptMe!");
|
||||
});
|
||||
});
|
||||
@@ -219,6 +220,15 @@ describe("NodeCrypto Function Service", () => {
|
||||
const decValue = await nodeCryptoFunctionService.aesDecrypt(data, iv, key, "cbc");
|
||||
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
|
||||
});
|
||||
|
||||
it("throws if IV is not provided", async () => {
|
||||
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const key = makeStaticByteArray(32);
|
||||
const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA==");
|
||||
await expect(
|
||||
async () => await nodeCryptoFunctionService.aesDecrypt(data, null, key, "cbc"),
|
||||
).rejects.toThrow("Invalid initialization vector");
|
||||
});
|
||||
});
|
||||
|
||||
describe("aesDecrypt ECB mode", () => {
|
||||
@@ -454,7 +464,7 @@ function testHmac(algorithm: "sha1" | "sha256" | "sha512", mac: string, fast = f
|
||||
const cryptoFunctionService = new NodeCryptoFunctionService();
|
||||
const value = Utils.fromUtf8ToArray("SignMe!!");
|
||||
const key = Utils.fromUtf8ToArray("secretkey");
|
||||
let computedMac: ArrayBuffer = null;
|
||||
let computedMac: ArrayBuffer;
|
||||
if (fast) {
|
||||
computedMac = await cryptoFunctionService.hmacFast(value, key, algorithm);
|
||||
} else {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import * as crypto from "crypto";
|
||||
|
||||
import * as forge from "node-forge";
|
||||
|
||||
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { DecryptParameters } from "@bitwarden/common/platform/models/domain/decrypt-parameters";
|
||||
import {
|
||||
CbcDecryptParameters,
|
||||
EcbDecryptParameters,
|
||||
} from "@bitwarden/common/platform/models/domain/decrypt-parameters";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { CsprngArray } from "@bitwarden/common/types/csprng";
|
||||
|
||||
@@ -168,10 +169,10 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
|
||||
aesDecryptFastParameters(
|
||||
data: string,
|
||||
iv: string,
|
||||
mac: string,
|
||||
mac: string | null,
|
||||
key: SymmetricCryptoKey,
|
||||
): DecryptParameters<Uint8Array> {
|
||||
const p = new DecryptParameters<Uint8Array>();
|
||||
): CbcDecryptParameters<Uint8Array> {
|
||||
const p = {} as CbcDecryptParameters<Uint8Array>;
|
||||
p.encKey = key.encKey;
|
||||
p.data = Utils.fromB64ToArray(data);
|
||||
p.iv = Utils.fromB64ToArray(iv);
|
||||
@@ -191,22 +192,25 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
|
||||
return p;
|
||||
}
|
||||
|
||||
async aesDecryptFast(
|
||||
parameters: DecryptParameters<Uint8Array>,
|
||||
mode: "cbc" | "ecb",
|
||||
): Promise<string> {
|
||||
const decBuf = await this.aesDecrypt(parameters.data, parameters.iv, parameters.encKey, mode);
|
||||
async aesDecryptFast({
|
||||
mode,
|
||||
parameters,
|
||||
}:
|
||||
| { mode: "cbc"; parameters: CbcDecryptParameters<Uint8Array> }
|
||||
| { mode: "ecb"; parameters: EcbDecryptParameters<Uint8Array> }): Promise<string> {
|
||||
const iv = mode === "cbc" ? parameters.iv : null;
|
||||
const decBuf = await this.aesDecrypt(parameters.data, iv, parameters.encKey, mode);
|
||||
return Utils.fromBufferToUtf8(decBuf);
|
||||
}
|
||||
|
||||
aesDecrypt(
|
||||
data: Uint8Array,
|
||||
iv: Uint8Array,
|
||||
iv: Uint8Array | null,
|
||||
key: Uint8Array,
|
||||
mode: "cbc" | "ecb",
|
||||
): Promise<Uint8Array> {
|
||||
const nodeData = this.toNodeBuffer(data);
|
||||
const nodeIv = mode === "ecb" ? null : this.toNodeBuffer(iv);
|
||||
const nodeIv = this.toNodeBufferOrNull(iv);
|
||||
const nodeKey = this.toNodeBuffer(key);
|
||||
const decipher = crypto.createDecipheriv(this.toNodeCryptoAesMode(mode), nodeKey, nodeIv);
|
||||
const decBuf = Buffer.concat([decipher.update(nodeData), decipher.final()]);
|
||||
@@ -311,6 +315,13 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
|
||||
return Buffer.from(value);
|
||||
}
|
||||
|
||||
private toNodeBufferOrNull(value: Uint8Array | null): Buffer | null {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return this.toNodeBuffer(value);
|
||||
}
|
||||
|
||||
private toUint8Buffer(value: Buffer | string | Uint8Array): Uint8Array {
|
||||
let buf: Uint8Array;
|
||||
if (typeof value === "string") {
|
||||
|
||||
Reference in New Issue
Block a user