Skip to content

Commit

Permalink
Auth/pm 8882/Add TDE Logging (#9673)
Browse files Browse the repository at this point in the history
* Added logging behind feature flag.

* Added default for new flag.

* Additional logging changes.

* Consolidated log messages.

* Removed unneccessary log.

* Fixed test error.

* Fixed linting.

* Fixed constructor on test.

* Updated to remove flag

* Moved service.

* Added logging to redirect guard.

(cherry picked from commit fe1c432)
  • Loading branch information
trmartin4 committed Jun 17, 2024
1 parent f61521d commit 5e80ead
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
8 changes: 8 additions & 0 deletions libs/angular/src/auth/guards/redirect.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";

export interface RedirectRoutes {
loggedIn: string;
Expand All @@ -32,6 +33,7 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
const authService = inject(AuthService);
const cryptoService = inject(CryptoService);
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
const logService = inject(LogService);
const router = inject(Router);

const authStatus = await authService.getAuthStatus();
Expand All @@ -49,6 +51,12 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);
if (authStatus === AuthenticationStatus.Locked && tdeEnabled && !everHadUserKey) {
logService.info(
"Sending user to TDE decryption options. AuthStatus is %s. TDE support is %s. Ever had user key is %s.",
AuthenticationStatus[authStatus],
tdeEnabled,
everHadUserKey,
);
return router.createUrlTree([routes.notDecrypted], { queryParams: route.queryParams });
}

Expand Down
16 changes: 16 additions & 0 deletions libs/angular/src/auth/guards/tde-decryption-required.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";

/**
* Only allow access to this route if the vault is locked and has never been decrypted.
Expand All @@ -23,15 +24,30 @@ export function tdeDecryptionRequiredGuard(): CanActivateFn {
const authService = inject(AuthService);
const cryptoService = inject(CryptoService);
const deviceTrustService = inject(DeviceTrustServiceAbstraction);
const logService = inject(LogService);
const router = inject(Router);

const authStatus = await authService.getAuthStatus();
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$);

// We need to determine if we should bypass the decryption options and send the user to the vault.
// The ONLY time that we want to send a user to the decryption options is when:
// 1. The user's auth status is Locked, AND
// 2. TDE is enabled, AND
// 3. The user has never had a user key in state since last logout.
// The inverse of this is when we should send the user to the vault.
if (authStatus !== AuthenticationStatus.Locked || !tdeEnabled || everHadUserKey) {
return router.createUrlTree(["/"]);
}

logService.info(
"Sending user to TDE decryption options. AuthStatus is %s. TDE support is %s. Ever had user key is %s.",
AuthenticationStatus[authStatus],
tdeEnabled,
everHadUserKey,
);

return true;
};
}
30 changes: 28 additions & 2 deletions libs/auth/src/common/login-strategies/sso-login.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ export class SsoLoginStrategy extends LoginStrategy {

data.userEnteredEmail = credentials.email;

const deviceRequest = await this.buildDeviceRequest();

this.logService.info("Logging in with appId %s.", deviceRequest.identifier);

data.tokenRequest = new SsoTokenRequest(
credentials.code,
credentials.codeVerifier,
credentials.redirectUrl,
await this.buildTwoFactor(credentials.twoFactor, credentials.email),
await this.buildDeviceRequest(),
deviceRequest,
);

this.cache.next(data);
Expand Down Expand Up @@ -195,12 +199,18 @@ export class SsoLoginStrategy extends LoginStrategy {

// Note: TDE and key connector are mutually exclusive
if (userDecryptionOptions?.trustedDeviceOption) {
this.logService.info("Attempting to set user key with approved admin auth request.");

// Try to use the user key from an approved admin request if it exists.
// Using it will clear it from state and future requests will use the device key.
await this.trySetUserKeyWithApprovedAdminRequestIfExists(userId);

const hasUserKey = await this.cryptoService.hasUserKey(userId);

// Only try to set user key with device key if admin approval request was not successful
// Only try to set user key with device key if admin approval request was not successful.
if (!hasUserKey) {
this.logService.info("Attempting to set user key with device key.");

await this.trySetUserKeyWithDeviceKey(tokenResponse, userId);
}
} else if (
Expand Down Expand Up @@ -275,11 +285,27 @@ export class SsoLoginStrategy extends LoginStrategy {
): Promise<void> {
const trustedDeviceOption = tokenResponse.userDecryptionOptions?.trustedDeviceOption;

if (!trustedDeviceOption) {
this.logService.error("Unable to set user key due to missing trustedDeviceOption.");
return;
}

const deviceKey = await this.deviceTrustService.getDeviceKey(userId);
const encDevicePrivateKey = trustedDeviceOption?.encryptedPrivateKey;
const encUserKey = trustedDeviceOption?.encryptedUserKey;

if (!deviceKey || !encDevicePrivateKey || !encUserKey) {
if (!deviceKey) {
await this.logService.warning("Unable to set user key due to missing device key.");
}
if (!encDevicePrivateKey) {
await this.logService.warning(
"Unable to set user key due to missing encrypted device private key.",
);
}
if (!encUserKey) {
await this.logService.warning("Unable to set user key due to missing encrypted user key.");
}
return;
}

Expand Down

0 comments on commit 5e80ead

Please sign in to comment.