mirror of
https://github.com/bitwarden/browser
synced 2026-01-31 00:33:33 +00:00
tmp
This commit is contained in:
@@ -213,9 +213,7 @@ export class AuthRequestService implements AuthRequestServiceAbstraction {
|
||||
);
|
||||
|
||||
const masterKey = new SymmetricCryptoKey(decryptedMasterKeyArrayBuffer) as MasterKey;
|
||||
const masterKeyHash = Utils.fromBufferToUtf8(
|
||||
decryptedMasterKeyHashArrayBuffer.buffer as ArrayBuffer,
|
||||
);
|
||||
const masterKeyHash = Utils.fromBufferToUtf8(decryptedMasterKeyHashArrayBuffer);
|
||||
|
||||
return {
|
||||
masterKey,
|
||||
|
||||
@@ -7,11 +7,11 @@ export abstract class WebAuthnLoginPrfKeyServiceAbstraction {
|
||||
/**
|
||||
* Get the salt used to generate the PRF-output used when logging in with WebAuthn.
|
||||
*/
|
||||
abstract getLoginWithPrfSalt(): Promise<ArrayBuffer>;
|
||||
abstract getLoginWithPrfSalt(): Promise<Uint8Array>;
|
||||
|
||||
/**
|
||||
* Create a symmetric key from the PRF-output by stretching it.
|
||||
* This should be used as `UpstreamKey` with `RotateableKeySet`.
|
||||
*/
|
||||
abstract createSymmetricKeyFromPrf(prf: ArrayBuffer): Promise<PrfKey>;
|
||||
abstract createSymmetricKeyFromPrf(prf: Uint8Array): Promise<PrfKey>;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export class AdminAuthRequestStorable {
|
||||
toJSON() {
|
||||
return {
|
||||
id: this.id,
|
||||
privateKey: Utils.fromBufferToByteString(this.privateKey.buffer as ArrayBuffer),
|
||||
privateKey: Utils.fromBufferToByteString(this.privateKey),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@ export class WebAuthnLoginAssertionResponseRequest extends WebAuthnLoginResponse
|
||||
}
|
||||
|
||||
this.response = {
|
||||
authenticatorData: Utils.fromBufferToUrlB64(credential.response.authenticatorData),
|
||||
signature: Utils.fromBufferToUrlB64(credential.response.signature),
|
||||
clientDataJSON: Utils.fromBufferToUrlB64(credential.response.clientDataJSON),
|
||||
userHandle: Utils.fromBufferToUrlB64(credential.response.userHandle),
|
||||
authenticatorData: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.authenticatorData)),
|
||||
signature: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.signature)),
|
||||
clientDataJSON: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.clientDataJSON)),
|
||||
userHandle: Utils.fromBufferToUrlB64(new Uint8Array(credential.response.userHandle)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ export abstract class WebAuthnLoginResponseRequest {
|
||||
|
||||
constructor(credential: PublicKeyCredential) {
|
||||
this.id = credential.id;
|
||||
this.rawId = Utils.fromBufferToUrlB64(credential.rawId);
|
||||
this.rawId = Utils.fromBufferToUrlB64(new Uint8Array(credential.rawId));
|
||||
this.type = credential.type;
|
||||
|
||||
// WARNING: do not add PRF information here by mapping
|
||||
|
||||
@@ -19,7 +19,7 @@ export class AssertionOptionsResponse
|
||||
...c,
|
||||
id: Utils.fromUrlB64ToArray(c.id).buffer,
|
||||
}));
|
||||
this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge"));
|
||||
this.challenge = Utils.fromUrlB64ToArray(this.getResponseProperty("challenge")).buffer as ArrayBuffer;
|
||||
this.extensions = this.getResponseProperty("extensions");
|
||||
this.rpId = this.getResponseProperty("rpId");
|
||||
this.timeout = this.getResponseProperty("timeout");
|
||||
|
||||
@@ -8,12 +8,12 @@ const LoginWithPrfSalt = "passwordless-login";
|
||||
export class WebAuthnLoginPrfKeyService implements WebAuthnLoginPrfKeyServiceAbstraction {
|
||||
constructor(private cryptoFunctionService: CryptoFunctionService) {}
|
||||
|
||||
async getLoginWithPrfSalt(): Promise<ArrayBuffer> {
|
||||
return await this.cryptoFunctionService.hash(LoginWithPrfSalt, "sha256");
|
||||
async getLoginWithPrfSalt(): Promise<Uint8Array> {
|
||||
return (await this.cryptoFunctionService.hash(LoginWithPrfSalt, "sha256"));
|
||||
}
|
||||
|
||||
async createSymmetricKeyFromPrf(prf: ArrayBuffer): Promise<PrfKey> {
|
||||
return (await this.stretchKey(new Uint8Array(prf))) as PrfKey;
|
||||
async createSymmetricKeyFromPrf(prf: Uint8Array): Promise<PrfKey> {
|
||||
return (await this.stretchKey(prf)) as PrfKey;
|
||||
}
|
||||
|
||||
// TODO: use keyGenerationService.stretchKey
|
||||
|
||||
@@ -39,7 +39,7 @@ describe("WebAuthnLoginService", () => {
|
||||
// We must do this to make the mocked classes available for all the
|
||||
// assertCredential(...) tests.
|
||||
global.PublicKeyCredential = MockPublicKeyCredential as any;
|
||||
global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse;
|
||||
global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse as any;
|
||||
|
||||
// Save the original navigator
|
||||
originalNavigator = global.window.navigator;
|
||||
@@ -143,7 +143,7 @@ describe("WebAuthnLoginService", () => {
|
||||
publicKeyCredential.getClientExtensionResults().prf?.results?.first;
|
||||
const prfKey = new SymmetricCryptoKey(new Uint8Array(prfResult)) as PrfKey;
|
||||
|
||||
webAuthnLoginPrfKeyService.getLoginWithPrfSalt.mockResolvedValue(saltArrayBuffer);
|
||||
webAuthnLoginPrfKeyService.getLoginWithPrfSalt.mockResolvedValue(new Uint8Array(saltArrayBuffer));
|
||||
webAuthnLoginPrfKeyService.createSymmetricKeyFromPrf.mockResolvedValue(prfKey);
|
||||
|
||||
// Mock implementations
|
||||
@@ -271,23 +271,23 @@ function randomBytes(length: number): Uint8Array {
|
||||
// so we need to mock them and assign them to the global object to make them available
|
||||
// for the tests
|
||||
class MockAuthenticatorAssertionResponse implements AuthenticatorAssertionResponse {
|
||||
clientDataJSON: ArrayBuffer = randomBytes(32).buffer;
|
||||
authenticatorData: ArrayBuffer = randomBytes(196).buffer;
|
||||
signature: ArrayBuffer = randomBytes(72).buffer;
|
||||
userHandle: ArrayBuffer = randomBytes(16).buffer;
|
||||
clientDataJSON: ArrayBuffer = randomBytes(32).buffer as ArrayBuffer;
|
||||
authenticatorData: ArrayBuffer = randomBytes(196).buffer as ArrayBuffer;
|
||||
signature: ArrayBuffer = randomBytes(72).buffer as ArrayBuffer;
|
||||
userHandle: ArrayBuffer = randomBytes(16).buffer as ArrayBuffer;
|
||||
|
||||
clientDataJSONB64Str = Utils.fromBufferToUrlB64(this.clientDataJSON);
|
||||
authenticatorDataB64Str = Utils.fromBufferToUrlB64(this.authenticatorData);
|
||||
signatureB64Str = Utils.fromBufferToUrlB64(this.signature);
|
||||
userHandleB64Str = Utils.fromBufferToUrlB64(this.userHandle);
|
||||
clientDataJSONB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.clientDataJSON));
|
||||
authenticatorDataB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.authenticatorData));
|
||||
signatureB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.signature));
|
||||
userHandleB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.userHandle));
|
||||
}
|
||||
|
||||
class MockPublicKeyCredential implements PublicKeyCredential {
|
||||
authenticatorAttachment = "cross-platform";
|
||||
id = "mockCredentialId";
|
||||
type = "public-key";
|
||||
rawId: ArrayBuffer = randomBytes(32).buffer;
|
||||
rawIdB64Str = Utils.fromBufferToUrlB64(this.rawId);
|
||||
rawId: ArrayBuffer = randomBytes(32).buffer as ArrayBuffer;
|
||||
rawIdB64Str = Utils.fromBufferToUrlB64(new Uint8Array(this.rawId));
|
||||
|
||||
response: MockAuthenticatorAssertionResponse = new MockAuthenticatorAssertionResponse();
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export class DefaultKeyGenerationService implements KeyGenerationService {
|
||||
): Promise<{ salt: string; material: CsprngArray; derivedKey: SymmetricCryptoKey }> {
|
||||
if (salt == null) {
|
||||
const bytes = await this.cryptoFunctionService.randomBytes(32);
|
||||
salt = Utils.fromBufferToUtf8(bytes.buffer as ArrayBuffer);
|
||||
salt = Utils.fromBufferToUtf8(bytes);
|
||||
}
|
||||
const material = await this.cryptoFunctionService.aesGenerateKey(bitLength);
|
||||
const key = await this.cryptoFunctionService.hkdf(material, salt, purpose, 64, "sha256");
|
||||
|
||||
@@ -40,14 +40,14 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||
|
||||
const pbkdf2Params: Pbkdf2Params = {
|
||||
name: "PBKDF2",
|
||||
salt: saltBuf,
|
||||
salt: saltBuf as BufferSource,
|
||||
iterations: iterations,
|
||||
hash: { name: this.toWebCryptoAlgorithm(algorithm) },
|
||||
};
|
||||
|
||||
const impKey = await this.subtle.importKey(
|
||||
"raw",
|
||||
passwordBuf,
|
||||
passwordBuf as BufferSource,
|
||||
{ name: "PBKDF2" } as any,
|
||||
false,
|
||||
["deriveBits"],
|
||||
@@ -68,12 +68,12 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||
|
||||
const hkdfParams: HkdfParams = {
|
||||
name: "HKDF",
|
||||
salt: saltBuf,
|
||||
info: infoBuf,
|
||||
salt: saltBuf as BufferSource,
|
||||
info: infoBuf as BufferSource,
|
||||
hash: { name: this.toWebCryptoAlgorithm(algorithm) },
|
||||
};
|
||||
|
||||
const impKey = await this.subtle.importKey("raw", ikm, { name: "HKDF" } as any, false, [
|
||||
const impKey = await this.subtle.importKey("raw", ikm as BufferSource, { name: "HKDF" } as any, false, [
|
||||
"deriveBits",
|
||||
]);
|
||||
const buffer = await this.subtle.deriveBits(hkdfParams as any, impKey, outputByteSize * 8);
|
||||
@@ -130,7 +130,7 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||
const valueBuf = this.toBuf(value);
|
||||
const buffer = await this.subtle.digest(
|
||||
{ name: this.toWebCryptoAlgorithm(algorithm) },
|
||||
valueBuf,
|
||||
valueBuf as BufferSource,
|
||||
);
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
@@ -145,8 +145,14 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||
hash: { name: this.toWebCryptoAlgorithm(algorithm) },
|
||||
};
|
||||
|
||||
const impKey = await this.subtle.importKey("raw", key, signingAlgorithm, false, ["sign"]);
|
||||
const buffer = await this.subtle.sign(signingAlgorithm, impKey, value);
|
||||
const impKey = await this.subtle.importKey(
|
||||
"raw",
|
||||
key as BufferSource,
|
||||
signingAlgorithm,
|
||||
false,
|
||||
["sign"],
|
||||
);
|
||||
const buffer = await this.subtle.sign(signingAlgorithm, impKey, value as BufferSource);
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
|
||||
@@ -194,15 +200,15 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||
return {
|
||||
iv: forge.util.decode64(iv),
|
||||
data: forge.util.decode64(data),
|
||||
encKey: forge.util.createBuffer(innerKey.encryptionKey).getBytes(),
|
||||
encKey: forge.util.createBuffer(innerKey.encryptionKey.buffer as ArrayBuffer).getBytes(),
|
||||
} as CbcDecryptParameters<string>;
|
||||
} else if (innerKey.type === EncryptionType.AesCbc256_HmacSha256_B64) {
|
||||
const macData = forge.util.decode64(iv) + forge.util.decode64(data);
|
||||
return {
|
||||
iv: forge.util.decode64(iv),
|
||||
data: forge.util.decode64(data),
|
||||
encKey: forge.util.createBuffer(innerKey.encryptionKey).getBytes(),
|
||||
macKey: forge.util.createBuffer(innerKey.authenticationKey).getBytes(),
|
||||
encKey: forge.util.createBuffer(innerKey.encryptionKey.buffer as ArrayBuffer).getBytes(),
|
||||
macKey: forge.util.createBuffer(innerKey.authenticationKey.buffer as ArrayBuffer).getBytes(),
|
||||
mac: forge.util.decode64(mac!),
|
||||
macData,
|
||||
} as CbcDecryptParameters<string>;
|
||||
@@ -248,15 +254,23 @@ export class WebCryptoFunctionService implements CryptoFunctionService {
|
||||
const result = await this.aesDecryptFast({ mode: "ecb", parameters });
|
||||
return Utils.fromByteStringToArray(result);
|
||||
}
|
||||
const impKey = await this.subtle.importKey("raw", key, { name: "AES-CBC" } as any, false, [
|
||||
"decrypt",
|
||||
]);
|
||||
const impKey = await this.subtle.importKey(
|
||||
"raw",
|
||||
key as BufferSource,
|
||||
{ name: "AES-CBC" } as any,
|
||||
false,
|
||||
["decrypt"],
|
||||
);
|
||||
|
||||
// CBC
|
||||
if (iv == null) {
|
||||
throw new Error("IV is required for CBC mode.");
|
||||
}
|
||||
const buffer = await this.subtle.decrypt({ name: "AES-CBC", iv: iv }, impKey, data);
|
||||
const buffer = await this.subtle.decrypt(
|
||||
{ name: "AES-CBC", iv: iv as BufferSource },
|
||||
impKey,
|
||||
data as BufferSource,
|
||||
);
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ describe("Utils Service", () => {
|
||||
"should correctly round trip convert from base64 to ArrayBuffer and back",
|
||||
() => {
|
||||
// Convert known base64 string to ArrayBuffer
|
||||
const bufferFromB64 = Utils.fromB64ToArray(b64HelloWorldString).buffer;
|
||||
const bufferFromB64 = Utils.fromB64ToArray(b64HelloWorldString).buffer as ArrayBuffer;
|
||||
|
||||
// Convert the ArrayBuffer back to a base64 string
|
||||
const roundTrippedB64String = Utils.fromBufferToB64(bufferFromB64);
|
||||
@@ -487,13 +487,13 @@ describe("Utils Service", () => {
|
||||
}
|
||||
|
||||
runInBothEnvironments("should convert an ArrayBuffer to a hex string", () => {
|
||||
const buffer = new Uint8Array([0, 1, 10, 16, 255]).buffer;
|
||||
const buffer = new Uint8Array([0, 1, 10, 16, 255]);
|
||||
const hexString = Utils.fromBufferToHex(buffer);
|
||||
expect(hexString).toBe("00010a10ff");
|
||||
});
|
||||
|
||||
runInBothEnvironments("should handle an empty buffer", () => {
|
||||
const buffer = new ArrayBuffer(0);
|
||||
const buffer = new Uint8Array(0);
|
||||
const hexString = Utils.fromBufferToHex(buffer);
|
||||
expect(hexString).toBe("");
|
||||
});
|
||||
@@ -501,7 +501,7 @@ describe("Utils Service", () => {
|
||||
runInBothEnvironments(
|
||||
"should correctly convert a large buffer containing a repeating sequence of all 256 unique byte values to hex",
|
||||
() => {
|
||||
const largeBuffer = new Uint8Array(1024).map((_, index) => index % 256).buffer;
|
||||
const largeBuffer = new Uint8Array(1024).map((_, index) => index % 256);
|
||||
const hexString = Utils.fromBufferToHex(largeBuffer);
|
||||
const expectedHexString = createSequentialHexByteString(256).repeat(4);
|
||||
expect(hexString).toBe(expectedHexString);
|
||||
@@ -509,7 +509,7 @@ describe("Utils Service", () => {
|
||||
);
|
||||
|
||||
runInBothEnvironments("should correctly convert a buffer with a single byte to hex", () => {
|
||||
const singleByteBuffer = new Uint8Array([0xab]).buffer;
|
||||
const singleByteBuffer = new Uint8Array([0xab]);
|
||||
const hexString = Utils.fromBufferToHex(singleByteBuffer);
|
||||
expect(hexString).toBe("ab");
|
||||
});
|
||||
@@ -517,7 +517,7 @@ describe("Utils Service", () => {
|
||||
runInBothEnvironments(
|
||||
"should correctly convert a buffer with an odd number of bytes to hex",
|
||||
() => {
|
||||
const oddByteBuffer = new Uint8Array([0x01, 0x23, 0x45, 0x67, 0x89]).buffer;
|
||||
const oddByteBuffer = new Uint8Array([0x01, 0x23, 0x45, 0x67, 0x89]);
|
||||
const hexString = Utils.fromBufferToHex(oddByteBuffer);
|
||||
expect(hexString).toBe("0123456789");
|
||||
},
|
||||
@@ -527,7 +527,7 @@ describe("Utils Service", () => {
|
||||
describe("hexStringToArrayBuffer(...)", () => {
|
||||
test("should convert a hex string to an ArrayBuffer correctly", () => {
|
||||
const hexString = "ff0a1b"; // Arbitrary hex string
|
||||
const expectedResult = new Uint8Array([255, 10, 27]).buffer;
|
||||
const expectedResult = new Uint8Array([255, 10, 27]).buffer as ArrayBuffer;
|
||||
const result = Utils.hexStringToArrayBuffer(hexString);
|
||||
expect(new Uint8Array(result)).toEqual(new Uint8Array(expectedResult));
|
||||
});
|
||||
@@ -541,7 +541,7 @@ describe("Utils Service", () => {
|
||||
|
||||
test("should convert a hex string representing zero to an ArrayBuffer correctly", () => {
|
||||
const hexString = "00";
|
||||
const expectedResult = new Uint8Array([0]).buffer;
|
||||
const expectedResult = new Uint8Array([0]).buffer as ArrayBuffer;
|
||||
const result = Utils.hexStringToArrayBuffer(hexString);
|
||||
expect(new Uint8Array(result)).toEqual(new Uint8Array(expectedResult));
|
||||
});
|
||||
@@ -556,7 +556,7 @@ describe("Utils Service", () => {
|
||||
test("should convert a long hex string to an ArrayBuffer correctly", () => {
|
||||
const hexString = "0102030405060708090a0b0c0d0e0f";
|
||||
const expectedResult = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
|
||||
.buffer;
|
||||
.buffer as ArrayBuffer;
|
||||
const result = Utils.hexStringToArrayBuffer(hexString);
|
||||
expect(new Uint8Array(result)).toEqual(new Uint8Array(expectedResult));
|
||||
});
|
||||
@@ -566,10 +566,10 @@ describe("Utils Service", () => {
|
||||
runInBothEnvironments(
|
||||
"should allow round-trip conversion from ArrayBuffer to hex and back",
|
||||
() => {
|
||||
const originalBuffer = new Uint8Array([10, 20, 30, 40, 255]).buffer; // arbitrary buffer
|
||||
const originalBuffer = new Uint8Array([10, 20, 30, 40, 255]); // arbitrary buffer
|
||||
const hexString = Utils.fromBufferToHex(originalBuffer);
|
||||
const roundTripBuffer = Utils.hexStringToArrayBuffer(hexString);
|
||||
expect(new Uint8Array(roundTripBuffer)).toEqual(new Uint8Array(originalBuffer));
|
||||
expect(new Uint8Array(roundTripBuffer)).toEqual(originalBuffer);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -578,7 +578,7 @@ describe("Utils Service", () => {
|
||||
() => {
|
||||
const hexString = "0a141e28ff"; // arbitrary hex string
|
||||
const bufferFromHex = Utils.hexStringToArrayBuffer(hexString);
|
||||
const roundTripHexString = Utils.fromBufferToHex(bufferFromHex);
|
||||
const roundTripHexString = Utils.fromBufferToHex(new Uint8Array(bufferFromHex));
|
||||
expect(roundTripHexString).toBe(hexString);
|
||||
},
|
||||
);
|
||||
@@ -761,13 +761,13 @@ describe("Utils Service", () => {
|
||||
});
|
||||
|
||||
runInBothEnvironments("should convert an ArrayBuffer to a utf8 string", () => {
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray).buffer;
|
||||
const buffer = new Uint8Array(asciiHelloWorldArray);
|
||||
const str = Utils.fromBufferToUtf8(buffer);
|
||||
expect(str).toBe(asciiHelloWorld);
|
||||
});
|
||||
|
||||
runInBothEnvironments("should handle an empty buffer", () => {
|
||||
const buffer = new ArrayBuffer(0);
|
||||
const buffer = new Uint8Array(0);
|
||||
const str = Utils.fromBufferToUtf8(buffer);
|
||||
expect(str).toBe("");
|
||||
});
|
||||
@@ -798,7 +798,7 @@ describe("Utils Service", () => {
|
||||
];
|
||||
|
||||
cases.forEach((c) => {
|
||||
const buffer = new Uint8Array(c.input).buffer;
|
||||
const buffer = new Uint8Array(c.input);
|
||||
const str = Utils.fromBufferToUtf8(buffer);
|
||||
// Match the expected output
|
||||
expect(str).toBe(c.output);
|
||||
|
||||
@@ -205,7 +205,7 @@ export class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
static fromBufferToUrlB64(buffer: ArrayBuffer): string {
|
||||
static fromBufferToUrlB64(buffer: Uint8Array): string {
|
||||
return Utils.fromB64toUrlB64(Utils.fromBufferToB64(buffer));
|
||||
}
|
||||
|
||||
@@ -213,16 +213,16 @@ export class Utils {
|
||||
return b64Str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
||||
}
|
||||
|
||||
static fromBufferToUtf8(buffer: ArrayBuffer): string {
|
||||
static fromBufferToUtf8(buffer: Uint8Array): string {
|
||||
return BufferLib.from(buffer).toString("utf8");
|
||||
}
|
||||
|
||||
static fromBufferToByteString(buffer: ArrayBuffer): string {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(buffer));
|
||||
static fromBufferToByteString(buffer: Uint8Array): string {
|
||||
return String.fromCharCode.apply(null, buffer);
|
||||
}
|
||||
|
||||
// ref: https://stackoverflow.com/a/40031979/1090359
|
||||
static fromBufferToHex(buffer: ArrayBuffer): string {
|
||||
static fromBufferToHex(buffer: Uint8Array): string {
|
||||
if (Utils.isNode) {
|
||||
return Buffer.from(buffer).toString("hex");
|
||||
} else {
|
||||
|
||||
@@ -28,7 +28,10 @@ const mockUser1 = "testUser1" as UserId;
|
||||
|
||||
const createSub = (key: string) => {
|
||||
return {
|
||||
options: { applicationServerKey: Utils.fromUrlB64ToArray(key), userVisibleOnly: true },
|
||||
options: {
|
||||
applicationServerKey: Utils.fromUrlB64ToArray(key).buffer as ArrayBuffer,
|
||||
userVisibleOnly: true,
|
||||
},
|
||||
endpoint: `web.push.endpoint/?${Utils.newGuid()}`,
|
||||
expirationTime: 5,
|
||||
getKey: () => null,
|
||||
|
||||
@@ -173,7 +173,7 @@ class MyWebPushConnector implements WebPushConnector {
|
||||
// REASON: `Utils.fromBufferToUrlB64` handles null by returning null back to it.
|
||||
// its annotation should be updated and then this assertion can be removed.
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
|
||||
existingSubscription.options?.applicationServerKey!,
|
||||
new Uint8Array(existingSubscription.options?.applicationServerKey!)
|
||||
);
|
||||
|
||||
if (subscriptionKey !== key) {
|
||||
|
||||
@@ -9,7 +9,7 @@ describe("credential-id-utils", () => {
|
||||
new Uint8Array([
|
||||
0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07,
|
||||
0xe7,
|
||||
]).buffer,
|
||||
]).buffer as ArrayBuffer,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ describe("credential-id-utils", () => {
|
||||
new Uint8Array([
|
||||
0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07,
|
||||
0xe7,
|
||||
]).buffer,
|
||||
]).buffer as ArrayBuffer,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -39,8 +39,8 @@ describe("credential-id-utils", () => {
|
||||
|
||||
describe("compareCredentialIds", () => {
|
||||
it("returns true when the two credential IDs are equal", () => {
|
||||
const a = new Uint8Array([0x01, 0x02, 0x03]);
|
||||
const b = new Uint8Array([0x01, 0x02, 0x03]);
|
||||
const a = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer;
|
||||
const b = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer;
|
||||
|
||||
const result = compareCredentialIds(a, b);
|
||||
|
||||
@@ -48,8 +48,8 @@ describe("credential-id-utils", () => {
|
||||
});
|
||||
|
||||
it("returns false when the two credential IDs are not equal", () => {
|
||||
const a = new Uint8Array([0x01, 0x02, 0x03]);
|
||||
const b = new Uint8Array([0x01, 0x02, 0x04]);
|
||||
const a = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer;
|
||||
const b = new Uint8Array([0x01, 0x02, 0x04]).buffer as ArrayBuffer;
|
||||
|
||||
const result = compareCredentialIds(a, b);
|
||||
|
||||
@@ -57,8 +57,8 @@ describe("credential-id-utils", () => {
|
||||
});
|
||||
|
||||
it("returns false when the two credential IDs have different lengths", () => {
|
||||
const a = new Uint8Array([0x01, 0x02, 0x03]);
|
||||
const b = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
|
||||
const a = new Uint8Array([0x01, 0x02, 0x03]).buffer as ArrayBuffer;
|
||||
const b = new Uint8Array([0x01, 0x02, 0x03, 0x04]).buffer as ArrayBuffer;
|
||||
|
||||
const result = compareCredentialIds(a, b);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export function parseCredentialId(encodedCredentialId: string): ArrayBuffer {
|
||||
return Fido2Utils.stringToBuffer(encodedCredentialId.slice(4));
|
||||
}
|
||||
|
||||
return guidToRawFormat(encodedCredentialId).buffer;
|
||||
return guidToRawFormat(encodedCredentialId).buffer as ArrayBuffer;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
],
|
||||
excludeCredentialDescriptorList: params.excludeCredentialDescriptorList ?? [
|
||||
{
|
||||
id: randomBytes(16),
|
||||
id: randomBytes(16).buffer as ArrayBuffer,
|
||||
transports: ["internal"],
|
||||
type: "public-key",
|
||||
},
|
||||
|
||||
@@ -348,12 +348,12 @@ export class Fido2AuthenticatorService<
|
||||
});
|
||||
|
||||
return {
|
||||
authenticatorData,
|
||||
authenticatorData: authenticatorData.buffer as ArrayBuffer,
|
||||
selectedCredential: {
|
||||
id: parseCredentialId(selectedCredentialId),
|
||||
userHandle: Fido2Utils.stringToBuffer(selectedFido2Credential.userHandle),
|
||||
},
|
||||
signature,
|
||||
signature: signature.buffer as ArrayBuffer,
|
||||
};
|
||||
} catch (error) {
|
||||
this.logService?.error(
|
||||
@@ -537,7 +537,10 @@ async function generateAuthData(params: AuthDataParams) {
|
||||
const authData: Array<number> = [];
|
||||
|
||||
const rpIdHash = new Uint8Array(
|
||||
await crypto.subtle.digest({ name: "SHA-256" }, Utils.fromByteStringToArray(params.rpId)),
|
||||
await crypto.subtle.digest(
|
||||
{ name: "SHA-256" },
|
||||
Utils.fromByteStringToArray(params.rpId) as BufferSource,
|
||||
),
|
||||
);
|
||||
authData.push(...rpIdHash);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export async function getCredentialsForAutofill(
|
||||
|
||||
// Credentials are stored as a GUID or b64 string with `b64.` prepended,
|
||||
// but we need to return them as a URL-safe base64 string
|
||||
const credId = Utils.fromBufferToUrlB64(parseCredentialId(credential.credentialId));
|
||||
const credId = Utils.fromBufferToUrlB64(new Uint8Array(parseCredentialId(credential.credentialId)));
|
||||
|
||||
return {
|
||||
cipherId: cipher.id,
|
||||
|
||||
@@ -572,7 +572,7 @@ describe("FidoAuthenticatorService", () => {
|
||||
const allowedCredentialIds = [
|
||||
Fido2Utils.bufferToString(guidToRawFormat(Utils.newGuid())),
|
||||
Fido2Utils.bufferToString(guidToRawFormat(Utils.newGuid())),
|
||||
Fido2Utils.bufferToString(Utils.fromByteStringToArray("not-a-guid")),
|
||||
Fido2Utils.bufferToString(Utils.fromByteStringToArray("not-a-guid") as BufferSource),
|
||||
];
|
||||
const params = createParams({
|
||||
userVerification: "required",
|
||||
@@ -700,11 +700,11 @@ describe("FidoAuthenticatorService", () => {
|
||||
function createAuthenticatorAssertResult(): Fido2AuthenticatorGetAssertionResult {
|
||||
return {
|
||||
selectedCredential: {
|
||||
id: randomBytes(32),
|
||||
userHandle: randomBytes(32),
|
||||
id: randomBytes(32).buffer as ArrayBuffer,
|
||||
userHandle: randomBytes(32).buffer as ArrayBuffer,
|
||||
},
|
||||
authenticatorData: randomBytes(64),
|
||||
signature: randomBytes(64),
|
||||
authenticatorData: randomBytes(64).buffer as ArrayBuffer,
|
||||
signature: randomBytes(64).buffer as ArrayBuffer,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -181,7 +181,7 @@ export class Fido2ClientService<
|
||||
};
|
||||
const clientDataJSON = JSON.stringify(collectedClientData);
|
||||
const clientDataJSONBytes = Utils.fromByteStringToArray(clientDataJSON);
|
||||
const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes);
|
||||
const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes.buffer as ArrayBuffer);
|
||||
const makeCredentialParams = mapToMakeCredentialParams({
|
||||
params,
|
||||
credTypesAndPubKeyAlgs,
|
||||
@@ -248,7 +248,7 @@ export class Fido2ClientService<
|
||||
credentialId: Fido2Utils.bufferToString(makeCredentialResult.credentialId),
|
||||
attestationObject: Fido2Utils.bufferToString(makeCredentialResult.attestationObject),
|
||||
authData: Fido2Utils.bufferToString(makeCredentialResult.authData),
|
||||
clientDataJSON: Fido2Utils.bufferToString(clientDataJSONBytes),
|
||||
clientDataJSON: Fido2Utils.bufferToString(new Uint8Array(clientDataJSONBytes)),
|
||||
publicKey: Fido2Utils.bufferToString(makeCredentialResult.publicKey),
|
||||
publicKeyAlgorithm: makeCredentialResult.publicKeyAlgorithm,
|
||||
transports: ["internal", "hybrid"],
|
||||
@@ -308,7 +308,7 @@ export class Fido2ClientService<
|
||||
);
|
||||
}
|
||||
|
||||
const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes);
|
||||
const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes.buffer as ArrayBuffer);
|
||||
const getAssertionParams = mapToGetAssertionParams({ params, clientDataHash });
|
||||
|
||||
if (abortController.signal.aborted) {
|
||||
@@ -402,7 +402,7 @@ export class Fido2ClientService<
|
||||
];
|
||||
assumeUserPresence = true;
|
||||
|
||||
const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes);
|
||||
const clientDataHash = await crypto.subtle.digest({ name: "SHA-256" }, clientDataJSONBytes.buffer as ArrayBuffer);
|
||||
const getAssertionParams = mapToGetAssertionParams({
|
||||
params,
|
||||
clientDataHash,
|
||||
@@ -429,8 +429,8 @@ export class Fido2ClientService<
|
||||
): AssertCredentialResult {
|
||||
return {
|
||||
authenticatorData: Fido2Utils.bufferToString(getAssertionResult.authenticatorData),
|
||||
clientDataJSON: Fido2Utils.bufferToString(clientDataJSONBytes),
|
||||
credentialId: Fido2Utils.bufferToString(getAssertionResult.selectedCredential.id),
|
||||
clientDataJSON: Fido2Utils.bufferToString(new Uint8Array(clientDataJSONBytes)),
|
||||
credentialId: Fido2Utils.bufferToString(new Uint8Array(getAssertionResult.selectedCredential.id)),
|
||||
userHandle:
|
||||
getAssertionResult.selectedCredential.userHandle !== undefined
|
||||
? Fido2Utils.bufferToString(getAssertionResult.selectedCredential.userHandle)
|
||||
|
||||
@@ -43,14 +43,14 @@ export class Fido2Utils {
|
||||
}
|
||||
|
||||
static bufferToString(bufferSource: BufferSource): string {
|
||||
return Fido2Utils.fromBufferToB64(Fido2Utils.bufferSourceToUint8Array(bufferSource))
|
||||
return Fido2Utils.fromBufferToB64(Fido2Utils.bufferSourceToUint8Array(bufferSource).buffer as ArrayBuffer)
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=/g, "");
|
||||
}
|
||||
|
||||
static stringToBuffer(str: string): ArrayBuffer {
|
||||
return Fido2Utils.fromB64ToArray(Fido2Utils.fromUrlB64ToB64(str)).buffer;
|
||||
return Fido2Utils.fromB64ToArray(Fido2Utils.fromUrlB64ToB64(str)).buffer as ArrayBuffer;
|
||||
}
|
||||
|
||||
static bufferSourceToUint8Array(bufferSource: BufferSource): Uint8Array {
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("guid-utils", () => {
|
||||
it.each(workingExamples)(
|
||||
"returns UUID in standard format when given a valid UUID array buffer",
|
||||
(expected, input) => {
|
||||
const result = guidToStandardFormat(input);
|
||||
const result = guidToStandardFormat(input.buffer as ArrayBuffer);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@ export class AzureFileUploadService {
|
||||
});
|
||||
|
||||
const request = new Request(url, {
|
||||
body: data.buffer,
|
||||
body: data.buffer.buffer as ArrayBuffer,
|
||||
cache: "no-store",
|
||||
method: "PUT",
|
||||
headers: headers,
|
||||
|
||||
@@ -10,7 +10,7 @@ export class BitwardenFileUploadService {
|
||||
const fd = new FormData();
|
||||
|
||||
if (Utils.isBrowser) {
|
||||
const blob = new Blob([encryptedFileData.buffer], { type: "application/octet-stream" });
|
||||
const blob = new Blob([encryptedFileData.buffer.buffer as ArrayBuffer], { type: "application/octet-stream" });
|
||||
fd.append("data", blob, encryptedFileName);
|
||||
} else if (Utils.isNode) {
|
||||
fd.append(
|
||||
|
||||
@@ -20,17 +20,3 @@ describe("Ever had user key", () => {
|
||||
expect(result).toEqual(everHadUserKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Encrypted private key", () => {
|
||||
const sut = USER_ENCRYPTED_PRIVATE_KEY;
|
||||
|
||||
it("should deserialize encrypted private key", () => {
|
||||
const encryptedPrivateKey = makeEncString().encryptedString;
|
||||
|
||||
const result = sut.deserializer(
|
||||
JSON.parse(JSON.stringify(encryptedPrivateKey as unknown)) as unknown as EncryptedString,
|
||||
);
|
||||
|
||||
expect(result).toEqual(encryptedPrivateKey);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import * as zxcvbn from "zxcvbn";
|
||||
import zxcvbn from "zxcvbn";
|
||||
|
||||
import { PasswordStrengthServiceAbstraction } from "./password-strength.service.abstraction";
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ export abstract class CipherService implements UserKeyRotationDataProvider<Ciphe
|
||||
abstract saveAttachmentRawWithServer(
|
||||
cipher: Cipher,
|
||||
filename: string,
|
||||
data: ArrayBuffer,
|
||||
data: Uint8Array,
|
||||
userId: UserId,
|
||||
admin?: boolean,
|
||||
): Promise<Cipher>;
|
||||
|
||||
@@ -1803,7 +1803,7 @@ export class CipherService implements CipherServiceAbstraction {
|
||||
|
||||
const fd = new FormData();
|
||||
try {
|
||||
const blob = new Blob([encData.buffer], { type: "application/octet-stream" });
|
||||
const blob = new Blob([encData.buffer.buffer as ArrayBuffer], { type: "application/octet-stream" });
|
||||
fd.append("key", dataEncKey[1].encryptedString);
|
||||
fd.append("data", blob, encFileName.encryptedString);
|
||||
fd.append("lastKnownRevisionDate", lastKnownRevisionDate.toISOString());
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build": "npm run clean && tsc",
|
||||
"build": "npm run clean && tsgo",
|
||||
"build:watch": "npm run clean && tsc -watch",
|
||||
"test": "jest"
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"build": "npm run clean && tsc",
|
||||
"build": "npm run clean && tsgo",
|
||||
"build:watch": "npm run clean && tsc -watch",
|
||||
"test": "jest"
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"declaration": false,
|
||||
"outDir": "dist",
|
||||
"baseUrl": ".",
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"*": ["../../*"],
|
||||
"@bitwarden/admin-console/common": ["./libs/admin-console/src/common"],
|
||||
"@bitwarden/angular/*": ["./libs/angular/src/*"],
|
||||
"@bitwarden/assets": ["./libs/assets/src/index.ts"],
|
||||
|
||||
Reference in New Issue
Block a user