1
0
mirror of https://github.com/bitwarden/directory-connector synced 2026-01-07 19:13:31 +00:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Jared McCannon
b813d14d85 updating package-lock 2026-01-06 10:08:39 -06:00
Jared McCannon
233d72b4d1 corrected tests to pull the new type 2026-01-06 10:06:10 -06:00
Jared McCannon
7508af725b fixed build errors 2026-01-06 09:36:17 -06:00
renovate[bot]
eef12c65fe [deps]: Update typescript to v5.9.3 2025-12-31 16:02:10 +00:00
9 changed files with 395 additions and 316 deletions

View File

@@ -15,13 +15,13 @@ describe("SymmetricCryptoKey", () => {
describe("guesses encKey from key length", () => {
it("AesCbc256_B64", () => {
const key = makeStaticByteArray(32);
const cryptoKey = new SymmetricCryptoKey(key);
const cryptoKey = new SymmetricCryptoKey(key.buffer as ArrayBuffer);
expect(cryptoKey).toEqual({
encKey: key,
encKey: key.buffer,
encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
encType: 0,
key: key,
key: key.buffer,
keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
macKey: null,
});
@@ -29,38 +29,38 @@ describe("SymmetricCryptoKey", () => {
it("AesCbc128_HmacSha256_B64", () => {
const key = makeStaticByteArray(32);
const cryptoKey = new SymmetricCryptoKey(key, EncryptionType.AesCbc128_HmacSha256_B64);
const cryptoKey = new SymmetricCryptoKey(key.buffer as ArrayBuffer, EncryptionType.AesCbc128_HmacSha256_B64);
expect(cryptoKey).toEqual({
encKey: key.slice(0, 16),
encKey: key.buffer.slice(0, 16),
encKeyB64: "AAECAwQFBgcICQoLDA0ODw==",
encType: 1,
key: key,
key: key.buffer,
keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
macKey: key.slice(16, 32),
macKey: key.buffer.slice(16, 32),
macKeyB64: "EBESExQVFhcYGRobHB0eHw==",
});
});
it("AesCbc256_HmacSha256_B64", () => {
const key = makeStaticByteArray(64);
const cryptoKey = new SymmetricCryptoKey(key);
const cryptoKey = new SymmetricCryptoKey(key.buffer as ArrayBuffer);
expect(cryptoKey).toEqual({
encKey: key.slice(0, 32),
encKey: key.buffer.slice(0, 32),
encKeyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
encType: 2,
key: key,
key: key.buffer,
keyB64:
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==",
macKey: key.slice(32, 64),
macKey: key.buffer.slice(32, 64),
macKeyB64: "ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8=",
});
});
it("unknown length", () => {
const t = () => {
new SymmetricCryptoKey(makeStaticByteArray(30));
new SymmetricCryptoKey(makeStaticByteArray(30).buffer as ArrayBuffer);
};
expect(t).toThrowError("Unable to determine encType.");

View File

@@ -29,6 +29,6 @@ export class NodeUtils {
// https://stackoverflow.com/a/31394257
static bufferToArrayBuffer(buf: Buffer): ArrayBuffer {
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) as ArrayBuffer;
}
}

View File

@@ -164,7 +164,7 @@ export class Utils {
}
static fromUtf8ToUrlB64(utfStr: string): string {
return Utils.fromBufferToUrlB64(Utils.fromUtf8ToArray(utfStr));
return Utils.fromBufferToUrlB64(Utils.fromUtf8ToArray(utfStr).buffer as ArrayBuffer);
}
static fromB64ToUtf8(b64Str: string): string {

View File

@@ -42,9 +42,9 @@ export class ChallengeResponse extends BaseResponse implements PublicKeyCredenti
super(response);
this.attestation = this.getResponseProperty("attestation");
this.authenticatorSelection = this.getResponseProperty("authenticatorSelection");
this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge"));
this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge")) as Uint8Array<ArrayBuffer>;
this.excludeCredentials = this.getResponseProperty("excludeCredentials").map((c: any) => {
c.id = Utils.fromUrlB64ToArray(c.id).buffer;
c.id = Utils.fromUrlB64ToArray(c.id).buffer as ArrayBuffer;
return c;
});
this.extensions = this.getResponseProperty("extensions");

View File

@@ -109,7 +109,7 @@ export class CryptoService implements CryptoServiceAbstraction {
): Promise<SymmetricCryptoKey> {
const key = await this.retrieveKeyFromStorage(keySuffix, userId);
if (key != null) {
const symmetricKey = new SymmetricCryptoKey(Utils.fromB64ToArray(key).buffer);
const symmetricKey = new SymmetricCryptoKey(Utils.fromB64ToArray(key).buffer as ArrayBuffer);
if (!(await this.validateKey(symmetricKey))) {
this.logService.warning("Wrong key, throwing away stored key");
@@ -512,7 +512,7 @@ export class CryptoService implements CryptoServiceAbstraction {
let plainBuf: ArrayBuffer;
if (typeof plainValue === "string") {
plainBuf = Utils.fromUtf8ToArray(plainValue).buffer;
plainBuf = Utils.fromUtf8ToArray(plainValue).buffer as ArrayBuffer;
} else {
plainBuf = plainValue;
}
@@ -539,7 +539,7 @@ export class CryptoService implements CryptoServiceAbstraction {
}
encBytes.set(new Uint8Array(encValue.data), 1 + encValue.iv.byteLength + macLen);
return new EncArrayBuffer(encBytes.buffer);
return new EncArrayBuffer(encBytes.buffer as ArrayBuffer);
}
async rsaEncrypt(data: ArrayBuffer, publicKey?: ArrayBuffer): Promise<EncString> {
@@ -585,7 +585,7 @@ export class CryptoService implements CryptoServiceAbstraction {
throw new Error("encPieces unavailable.");
}
const data = Utils.fromB64ToArray(encPieces[0]).buffer;
const data = Utils.fromB64ToArray(encPieces[0]).buffer as ArrayBuffer;
const privateKey = privateKeyValue ?? (await this.getPrivateKey());
if (privateKey == null) {
throw new Error("No private key.");
@@ -608,9 +608,9 @@ export class CryptoService implements CryptoServiceAbstraction {
}
async decryptToBytes(encString: EncString, key?: SymmetricCryptoKey): Promise<ArrayBuffer> {
const iv = Utils.fromB64ToArray(encString.iv).buffer;
const data = Utils.fromB64ToArray(encString.data).buffer;
const mac = encString.mac ? Utils.fromB64ToArray(encString.mac).buffer : null;
const iv = Utils.fromB64ToArray(encString.iv).buffer as ArrayBuffer;
const data = Utils.fromB64ToArray(encString.data).buffer as ArrayBuffer;
const mac = encString.mac ? Utils.fromB64ToArray(encString.mac).buffer as ArrayBuffer : null;
const decipher = await this.aesDecryptToBytes(encString.encryptionType, data, iv, mac, key);
if (decipher == null) {
return null;
@@ -667,9 +667,9 @@ export class CryptoService implements CryptoServiceAbstraction {
return await this.aesDecryptToBytes(
encType,
ctBytes.buffer,
ivBytes.buffer,
macBytes != null ? macBytes.buffer : null,
ctBytes.buffer as ArrayBuffer,
ivBytes.buffer as ArrayBuffer,
macBytes != null ? macBytes.buffer as ArrayBuffer : null,
key,
);
}
@@ -766,7 +766,7 @@ export class CryptoService implements CryptoServiceAbstraction {
const macData = new Uint8Array(obj.iv.byteLength + obj.data.byteLength);
macData.set(new Uint8Array(obj.iv), 0);
macData.set(new Uint8Array(obj.data), obj.iv.byteLength);
obj.mac = await this.cryptoFunctionService.hmac(macData.buffer, obj.key.macKey, "sha256");
obj.mac = await this.cryptoFunctionService.hmac(macData.buffer as ArrayBuffer, obj.key.macKey, "sha256");
}
return obj;
@@ -832,7 +832,7 @@ export class CryptoService implements CryptoServiceAbstraction {
macData.set(new Uint8Array(iv), 0);
macData.set(new Uint8Array(data), iv.byteLength);
const computedMac = await this.cryptoFunctionService.hmac(
macData.buffer,
macData.buffer as ArrayBuffer,
theKey.macKey,
"sha256",
);
@@ -889,7 +889,7 @@ export class CryptoService implements CryptoServiceAbstraction {
const macKey = await this.cryptoFunctionService.hkdfExpand(key.key, "mac", 32, "sha256");
newKey.set(new Uint8Array(encKey));
newKey.set(new Uint8Array(macKey), 32);
return new SymmetricCryptoKey(newKey.buffer);
return new SymmetricCryptoKey(newKey.buffer as ArrayBuffer);
}
private async hashPhrase(hash: ArrayBuffer, minimumEntropy = 64) {

View File

@@ -94,7 +94,7 @@ describe("NodeCrypto Function Service", () => {
it("should fail with prk too small", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const f = cryptoFunctionService.hkdfExpand(
Utils.fromB64ToArray(prk16Byte),
Utils.fromB64ToArray(prk16Byte).buffer as ArrayBuffer,
"info",
32,
"sha256",
@@ -105,7 +105,7 @@ describe("NodeCrypto Function Service", () => {
it("should fail with outputByteSize is too large", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const f = cryptoFunctionService.hkdfExpand(
Utils.fromB64ToArray(prk32Byte),
Utils.fromB64ToArray(prk32Byte).buffer as ArrayBuffer,
"info",
8161,
"sha256",
@@ -170,9 +170,9 @@ describe("NodeCrypto Function Service", () => {
const key = makeStaticByteArray(32);
const data = Utils.fromUtf8ToArray("EncryptMe!");
const encValue = await nodeCryptoFunctionService.aesEncrypt(
data.buffer,
iv.buffer,
key.buffer,
data.buffer as ArrayBuffer,
iv.buffer as ArrayBuffer,
key.buffer as ArrayBuffer,
);
expect(Utils.fromBufferToB64(encValue)).toBe("ByUF8vhyX4ddU9gcooznwA==");
});
@@ -184,11 +184,11 @@ describe("NodeCrypto Function Service", () => {
const value = "EncryptMe!";
const data = Utils.fromUtf8ToArray(value);
const encValue = await nodeCryptoFunctionService.aesEncrypt(
data.buffer,
iv.buffer,
key.buffer,
data.buffer as ArrayBuffer,
iv.buffer as ArrayBuffer,
key.buffer as ArrayBuffer,
);
const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv.buffer, key.buffer);
const decValue = await nodeCryptoFunctionService.aesDecrypt(encValue, iv.buffer as ArrayBuffer, key.buffer as ArrayBuffer);
expect(Utils.fromBufferToUtf8(decValue)).toBe(value);
});
});
@@ -196,8 +196,8 @@ describe("NodeCrypto Function Service", () => {
describe("aesDecryptFast", () => {
it("should successfully decrypt data", async () => {
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
const iv = Utils.fromBufferToB64(makeStaticByteArray(16).buffer);
const symKey = new SymmetricCryptoKey(makeStaticByteArray(32).buffer);
const iv = Utils.fromBufferToB64(makeStaticByteArray(16).buffer as ArrayBuffer);
const symKey = new SymmetricCryptoKey(makeStaticByteArray(32).buffer as ArrayBuffer);
const data = "ByUF8vhyX4ddU9gcooznwA==";
const params = nodeCryptoFunctionService.aesDecryptFastParameters(data, iv, null, symKey);
const decValue = await nodeCryptoFunctionService.aesDecryptFast(params);
@@ -212,9 +212,9 @@ describe("NodeCrypto Function Service", () => {
const key = makeStaticByteArray(32);
const data = Utils.fromB64ToArray("ByUF8vhyX4ddU9gcooznwA==");
const decValue = await nodeCryptoFunctionService.aesDecrypt(
data.buffer,
iv.buffer,
key.buffer,
data.buffer as ArrayBuffer,
iv.buffer as ArrayBuffer,
key.buffer as ArrayBuffer,
);
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
});
@@ -228,11 +228,11 @@ describe("NodeCrypto Function Service", () => {
const value = "EncryptMe!";
const data = Utils.fromUtf8ToArray(value);
const encValue = await nodeCryptoFunctionService.rsaEncrypt(
data.buffer,
pubKey.buffer,
data.buffer as ArrayBuffer,
pubKey.buffer as ArrayBuffer,
"sha1",
);
const decValue = await nodeCryptoFunctionService.rsaDecrypt(encValue, privKey.buffer, "sha1");
const decValue = await nodeCryptoFunctionService.rsaDecrypt(encValue, privKey.buffer as ArrayBuffer, "sha1");
expect(Utils.fromBufferToUtf8(decValue)).toBe(value);
});
});
@@ -248,8 +248,8 @@ describe("NodeCrypto Function Service", () => {
"/5jcercUtK2o+XrzNrL4UQ7yLZcFz6Bfwb/j6ICYvqd/YJwXNE6dwlL57OfwJyCdw2rRYf0/qI00t9u8Iitw==",
);
const decValue = await nodeCryptoFunctionService.rsaDecrypt(
data.buffer,
privKey.buffer,
data.buffer as ArrayBuffer,
privKey.buffer as ArrayBuffer,
"sha1",
);
expect(Utils.fromBufferToUtf8(decValue)).toBe("EncryptMe!");
@@ -260,7 +260,7 @@ describe("NodeCrypto Function Service", () => {
it("should successfully extract key", async () => {
const nodeCryptoFunctionService = new NodeCryptoFunctionService();
const privKey = Utils.fromB64ToArray(RsaPrivateKey);
const publicKey = await nodeCryptoFunctionService.rsaExtractPublicKey(privKey.buffer);
const publicKey = await nodeCryptoFunctionService.rsaExtractPublicKey(privKey.buffer as ArrayBuffer);
expect(Utils.fromBufferToB64(publicKey)).toBe(RsaPublicKey);
});
});
@@ -326,8 +326,8 @@ function testPbkdf2(
it("should create valid " + algorithm + " key from array buffer input", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const key = await cryptoFunctionService.pbkdf2(
Utils.fromUtf8ToArray(regularPassword).buffer,
Utils.fromUtf8ToArray(regularEmail).buffer,
Utils.fromUtf8ToArray(regularPassword).buffer as ArrayBuffer,
Utils.fromUtf8ToArray(regularEmail).buffer as ArrayBuffer,
algorithm,
5000,
);
@@ -341,7 +341,7 @@ function testHkdf(
utf8Key: string,
unicodeKey: string,
) {
const ikm = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ==");
const ikm = Utils.fromB64ToArray("criAmKtfzxanbgea5/kelQ==").buffer as ArrayBuffer;
const regularSalt = "salt";
const utf8Salt = "üser_salt";
@@ -373,8 +373,8 @@ function testHkdf(
const cryptoFunctionService = new NodeCryptoFunctionService();
const key = await cryptoFunctionService.hkdf(
ikm,
Utils.fromUtf8ToArray(regularSalt).buffer,
Utils.fromUtf8ToArray(regularInfo).buffer,
Utils.fromUtf8ToArray(regularSalt).buffer as ArrayBuffer,
Utils.fromUtf8ToArray(regularInfo).buffer as ArrayBuffer,
32,
algorithm,
);
@@ -393,7 +393,7 @@ function testHkdfExpand(
it("should create valid " + algorithm + " " + outputByteSize + " byte okm", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const okm = await cryptoFunctionService.hkdfExpand(
Utils.fromB64ToArray(b64prk),
Utils.fromB64ToArray(b64prk).buffer as ArrayBuffer,
info,
outputByteSize,
algorithm,
@@ -433,7 +433,7 @@ function testHash(
it("should create valid " + algorithm + " hash from array buffer input", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const hash = await cryptoFunctionService.hash(
Utils.fromUtf8ToArray(regularValue).buffer,
Utils.fromUtf8ToArray(regularValue).buffer as ArrayBuffer,
algorithm,
);
expect(Utils.fromBufferToHex(hash)).toBe(regularHash);
@@ -443,8 +443,8 @@ function testHash(
function testHmac(algorithm: "sha1" | "sha256" | "sha512", mac: string, fast = false) {
it("should create valid " + algorithm + " hmac", async () => {
const cryptoFunctionService = new NodeCryptoFunctionService();
const value = Utils.fromUtf8ToArray("SignMe!!").buffer;
const key = Utils.fromUtf8ToArray("secretkey").buffer;
const value = Utils.fromUtf8ToArray("SignMe!!").buffer as ArrayBuffer;
const key = Utils.fromUtf8ToArray("secretkey").buffer as ArrayBuffer;
let computedMac: ArrayBuffer = null;
if (fast) {
computedMac = await cryptoFunctionService.hmacFast(value, key, algorithm);
@@ -462,8 +462,8 @@ function testCompare(fast = false) {
a[0] = 1;
a[1] = 2;
const equal = fast
? await cryptoFunctionService.compareFast(a.buffer, a.buffer)
: await cryptoFunctionService.compare(a.buffer, a.buffer);
? await cryptoFunctionService.compareFast(a.buffer as ArrayBuffer, a.buffer as ArrayBuffer)
: await cryptoFunctionService.compare(a.buffer as ArrayBuffer, a.buffer as ArrayBuffer);
expect(equal).toBe(true);
});
@@ -476,8 +476,8 @@ function testCompare(fast = false) {
b[0] = 3;
b[1] = 4;
const equal = fast
? await cryptoFunctionService.compareFast(a.buffer, b.buffer)
: await cryptoFunctionService.compare(a.buffer, b.buffer);
? await cryptoFunctionService.compareFast(a.buffer as ArrayBuffer, b.buffer as ArrayBuffer)
: await cryptoFunctionService.compare(a.buffer as ArrayBuffer, b.buffer as ArrayBuffer);
expect(equal).toBe(false);
});
@@ -489,8 +489,8 @@ function testCompare(fast = false) {
const b = new Uint8Array(2);
b[0] = 3;
const equal = fast
? await cryptoFunctionService.compareFast(a.buffer, b.buffer)
: await cryptoFunctionService.compare(a.buffer, b.buffer);
? await cryptoFunctionService.compareFast(a.buffer as ArrayBuffer, b.buffer as ArrayBuffer)
: await cryptoFunctionService.compare(a.buffer as ArrayBuffer, b.buffer as ArrayBuffer);
expect(equal).toBe(false);
});
}

View File

@@ -67,14 +67,14 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
t.set(previousT);
t.set(infoArr, previousT.length);
t.set([i + 1], t.length - 1);
previousT = new Uint8Array(await this.hmac(t.buffer, prk, algorithm));
previousT = new Uint8Array(await this.hmac(t.buffer as ArrayBuffer, prk, algorithm));
okm.set(previousT, runningOkmLength);
runningOkmLength += previousT.length;
if (runningOkmLength >= outputByteSize) {
break;
}
}
return okm.slice(0, outputByteSize).buffer;
return okm.slice(0, outputByteSize).buffer as ArrayBuffer;
}
hash(
@@ -147,19 +147,19 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
): DecryptParameters<ArrayBuffer> {
const p = new DecryptParameters<ArrayBuffer>();
p.encKey = key.encKey;
p.data = Utils.fromB64ToArray(data).buffer;
p.iv = Utils.fromB64ToArray(iv).buffer;
p.data = Utils.fromB64ToArray(data).buffer as ArrayBuffer;
p.iv = Utils.fromB64ToArray(iv).buffer as ArrayBuffer;
const macData = new Uint8Array(p.iv.byteLength + p.data.byteLength);
macData.set(new Uint8Array(p.iv), 0);
macData.set(new Uint8Array(p.data), p.iv.byteLength);
p.macData = macData.buffer;
p.macData = macData.buffer as ArrayBuffer;
if (key.macKey != null) {
p.macKey = key.macKey;
}
if (mac != null) {
p.mac = Utils.fromB64ToArray(mac).buffer;
p.mac = Utils.fromB64ToArray(mac).buffer as ArrayBuffer;
}
return p;
@@ -215,7 +215,7 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
const publicKeyAsn1 = forge.pki.publicKeyToAsn1(forgePublicKey);
const publicKeyByteString = forge.asn1.toDer(publicKeyAsn1).data;
const publicKeyArray = Utils.fromByteStringToArray(publicKeyByteString);
return Promise.resolve(publicKeyArray.buffer);
return Promise.resolve(publicKeyArray.buffer as ArrayBuffer);
}
async rsaGenerateKeyPair(length: 1024 | 2048 | 4096): Promise<[ArrayBuffer, ArrayBuffer]> {
@@ -241,7 +241,7 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
const privateKeyByteString = forge.asn1.toDer(privateKeyPkcs8).getBytes();
const privateKey = Utils.fromByteStringToArray(privateKeyByteString);
resolve([publicKey.buffer, privateKey.buffer]);
resolve([publicKey.buffer as ArrayBuffer, privateKey.buffer as ArrayBuffer]);
},
);
});
@@ -276,9 +276,9 @@ export class NodeCryptoFunctionService implements CryptoFunctionService {
private toArrayBuffer(value: Buffer | string | ArrayBuffer): ArrayBuffer {
let buf: ArrayBuffer;
if (typeof value === "string") {
buf = Utils.fromUtf8ToArray(value).buffer;
buf = Utils.fromUtf8ToArray(value).buffer as ArrayBuffer;
} else {
buf = new Uint8Array(value).buffer;
buf = new Uint8Array(value).buffer as ArrayBuffer;
}
return buf;
}

561
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -135,7 +135,7 @@
"ts-loader": "9.5.2",
"tsconfig-paths-webpack-plugin": "4.2.0",
"type-fest": "5.3.0",
"typescript": "5.8.3",
"typescript": "5.9.3",
"webpack": "5.103.0",
"webpack-cli": "6.0.1",
"webpack-merge": "6.0.1",