mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-21 16:18:28 +01:00
Add logging for decryption failures (#11683)
* Add logging to decryption routines * Fix case of uknown encryption type * Remove enum to string mapping
This commit is contained in:
parent
9b471e6633
commit
b3b311e164
@ -8,6 +8,14 @@ export enum EncryptionType {
|
||||
Rsa2048_OaepSha1_HmacSha256_B64 = 6,
|
||||
}
|
||||
|
||||
export function encryptionTypeToString(encryptionType: EncryptionType): string {
|
||||
if (encryptionType in EncryptionType) {
|
||||
return EncryptionType[encryptionType];
|
||||
} else {
|
||||
return "Unknown encryption type " + encryptionType;
|
||||
}
|
||||
}
|
||||
|
||||
/** The expected number of parts to a serialized EncString of the given encryption type.
|
||||
* For example, an EncString of type AesCbc256_B64 will have 2 parts, and an EncString of type
|
||||
* AesCbc128_HmacSha256_B64 will have 3 parts.
|
||||
|
@ -2,7 +2,7 @@ import { Utils } from "../../../platform/misc/utils";
|
||||
import { CryptoFunctionService } from "../../abstractions/crypto-function.service";
|
||||
import { EncryptService } from "../../abstractions/encrypt.service";
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { EncryptionType } from "../../enums";
|
||||
import { EncryptionType, encryptionTypeToString as encryptionTypeName } from "../../enums";
|
||||
import { Decryptable } from "../../interfaces/decryptable.interface";
|
||||
import { Encrypted } from "../../interfaces/encrypted";
|
||||
import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface";
|
||||
@ -70,13 +70,24 @@ export class EncryptServiceImplementation implements EncryptService {
|
||||
|
||||
key = this.resolveLegacyKey(key, encString);
|
||||
|
||||
// DO NOT REMOVE OR MOVE. This prevents downgrade to mac-less CBC, which would compromise integrity and confidentiality.
|
||||
if (key.macKey != null && encString?.mac == null) {
|
||||
this.logService.error("MAC required but not provided.");
|
||||
this.logService.error(
|
||||
"[Encrypt service] Key has mac key but payload is missing mac bytes. Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encString.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (key.encType !== encString.encryptionType) {
|
||||
this.logService.error("Key encryption type does not match payload encryption type.");
|
||||
this.logService.error(
|
||||
"[Encrypt service] Key encryption type does not match payload encryption type. Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encString.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -94,7 +105,12 @@ export class EncryptServiceImplementation implements EncryptService {
|
||||
);
|
||||
const macsEqual = await this.cryptoFunctionService.compareFast(fastParams.mac, computedMac);
|
||||
if (!macsEqual) {
|
||||
this.logMacFailed("MAC comparison failed. Key or payload has changed.");
|
||||
this.logMacFailed(
|
||||
"[Encrypt service] MAC comparison failed. Key or payload has changed. Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encString.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -113,13 +129,24 @@ export class EncryptServiceImplementation implements EncryptService {
|
||||
|
||||
key = this.resolveLegacyKey(key, encThing);
|
||||
|
||||
// DO NOT REMOVE OR MOVE. This prevents downgrade to mac-less CBC, which would compromise integrity and confidentiality.
|
||||
if (key.macKey != null && encThing.macBytes == null) {
|
||||
this.logService.error("MAC required but not provided.");
|
||||
this.logService.error(
|
||||
"[Encrypt service] Key has mac key but payload is missing mac bytes. Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encThing.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (key.encType !== encThing.encryptionType) {
|
||||
this.logService.error("Key encryption type does not match payload encryption type.");
|
||||
this.logService.error(
|
||||
"[Encrypt service] Key encryption type does not match payload encryption type. Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encThing.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -129,13 +156,25 @@ export class EncryptServiceImplementation implements EncryptService {
|
||||
macData.set(new Uint8Array(encThing.dataBytes), encThing.ivBytes.byteLength);
|
||||
const computedMac = await this.cryptoFunctionService.hmac(macData, key.macKey, "sha256");
|
||||
if (computedMac === null) {
|
||||
this.logMacFailed("Failed to compute MAC.");
|
||||
this.logMacFailed(
|
||||
"[Encrypt service] Failed to compute MAC." +
|
||||
" Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encThing.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const macsMatch = await this.cryptoFunctionService.compare(encThing.macBytes, computedMac);
|
||||
if (!macsMatch) {
|
||||
this.logMacFailed("MAC comparison failed. Key or payload has changed.");
|
||||
this.logMacFailed(
|
||||
"[Encrypt service] MAC comparison failed. Key or payload has changed." +
|
||||
" Key type " +
|
||||
encryptionTypeName(key.encType) +
|
||||
" Payload type " +
|
||||
encryptionTypeName(encThing.encryptionType),
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -164,7 +203,7 @@ export class EncryptServiceImplementation implements EncryptService {
|
||||
|
||||
async rsaDecrypt(data: EncString, privateKey: Uint8Array): Promise<Uint8Array> {
|
||||
if (data == null) {
|
||||
throw new Error("No data provided for decryption.");
|
||||
throw new Error("[Encrypt service] rsaDecrypt: No data provided for decryption.");
|
||||
}
|
||||
|
||||
let algorithm: "sha1" | "sha256";
|
||||
@ -182,7 +221,7 @@ export class EncryptServiceImplementation implements EncryptService {
|
||||
}
|
||||
|
||||
if (privateKey == null) {
|
||||
throw new Error("No private key provided for decryption.");
|
||||
throw new Error("[Encrypt service] rsaDecrypt: No private key provided for decryption.");
|
||||
}
|
||||
|
||||
return this.cryptoFunctionService.rsaDecrypt(data.dataBytes, privateKey, algorithm);
|
||||
|
Loading…
Reference in New Issue
Block a user