mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 16:53:34 +00:00
[PM-6400] Move core FIDO2 code from vault to platform ownership (#8044)
* [PM-6400] Move core FIDO2 code from vault to platform ownership - lib/common/vault/abstractions/fido2 -> lib/common/platform/abstractions/fido2 - lib/common/vault/services/fido2 -> lib/common/platform/services/fido2 * [PM-6400] fix: wrong imports
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* This class represents an abstraction of the WebAuthn Authenticator model as described by W3C:
|
||||
* https://www.w3.org/TR/webauthn-3/#sctn-authenticator-model
|
||||
*
|
||||
* The authenticator provides key management and cryptographic signatures.
|
||||
*/
|
||||
export abstract class Fido2AuthenticatorService {
|
||||
/**
|
||||
* Create and save a new credential as described in:
|
||||
* https://www.w3.org/TR/webauthn-3/#sctn-op-make-cred
|
||||
*
|
||||
* @param params Parameters for creating a new credential
|
||||
* @param abortController An AbortController that can be used to abort the operation.
|
||||
* @returns A promise that resolves with the new credential and an attestation signature.
|
||||
**/
|
||||
makeCredential: (
|
||||
params: Fido2AuthenticatorMakeCredentialsParams,
|
||||
tab: chrome.tabs.Tab,
|
||||
abortController?: AbortController,
|
||||
) => Promise<Fido2AuthenticatorMakeCredentialResult>;
|
||||
|
||||
/**
|
||||
* Generate an assertion using an existing credential as describe in:
|
||||
* https://www.w3.org/TR/webauthn-3/#sctn-op-get-assertion
|
||||
*
|
||||
* @param params Parameters for generating an assertion
|
||||
* @param abortController An AbortController that can be used to abort the operation.
|
||||
* @returns A promise that resolves with the asserted credential and an assertion signature.
|
||||
*/
|
||||
getAssertion: (
|
||||
params: Fido2AuthenticatorGetAssertionParams,
|
||||
tab: chrome.tabs.Tab,
|
||||
abortController?: AbortController,
|
||||
) => Promise<Fido2AuthenticatorGetAssertionResult>;
|
||||
}
|
||||
|
||||
export enum Fido2AlgorithmIdentifier {
|
||||
ES256 = -7,
|
||||
RS256 = -257,
|
||||
}
|
||||
|
||||
export enum Fido2AuthenticatorErrorCode {
|
||||
Unknown = "UnknownError",
|
||||
NotSupported = "NotSupportedError",
|
||||
InvalidState = "InvalidStateError",
|
||||
NotAllowed = "NotAllowedError",
|
||||
Constraint = "ConstraintError",
|
||||
}
|
||||
|
||||
export class Fido2AuthenticatorError extends Error {
|
||||
constructor(readonly errorCode: Fido2AuthenticatorErrorCode) {
|
||||
super(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
export interface PublicKeyCredentialDescriptor {
|
||||
id: BufferSource;
|
||||
transports?: ("ble" | "hybrid" | "internal" | "nfc" | "usb")[];
|
||||
type: "public-key";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for {@link Fido2AuthenticatorService.makeCredential}
|
||||
*
|
||||
* This interface represents the input parameters described in
|
||||
* https://www.w3.org/TR/webauthn-3/#sctn-op-make-cred
|
||||
*/
|
||||
export interface Fido2AuthenticatorMakeCredentialsParams {
|
||||
/** The hash of the serialized client data, provided by the client. */
|
||||
hash: BufferSource;
|
||||
/** The Relying Party's PublicKeyCredentialRpEntity. */
|
||||
rpEntity: {
|
||||
name: string;
|
||||
id?: string;
|
||||
};
|
||||
/** The user account’s PublicKeyCredentialUserEntity, containing the user handle given by the Relying Party. */
|
||||
userEntity: {
|
||||
id: BufferSource;
|
||||
name?: string;
|
||||
displayName?: string;
|
||||
icon?: string;
|
||||
};
|
||||
/** A sequence of pairs of PublicKeyCredentialType and public key algorithms (COSEAlgorithmIdentifier) requested by the Relying Party. This sequence is ordered from most preferred to least preferred. The authenticator makes a best-effort to create the most preferred credential that it can. */
|
||||
credTypesAndPubKeyAlgs: {
|
||||
alg: number;
|
||||
type: "public-key"; // not used
|
||||
}[];
|
||||
/** An OPTIONAL list of PublicKeyCredentialDescriptor objects provided by the Relying Party with the intention that, if any of these are known to the authenticator, it SHOULD NOT create a new credential. excludeCredentialDescriptorList contains a list of known credentials. */
|
||||
excludeCredentialDescriptorList?: PublicKeyCredentialDescriptor[];
|
||||
/** A map from extension identifiers to their authenticator extension inputs, created by the client based on the extensions requested by the Relying Party, if any. */
|
||||
extensions?: {
|
||||
appid?: string;
|
||||
appidExclude?: string;
|
||||
credProps?: boolean;
|
||||
uvm?: boolean;
|
||||
};
|
||||
/** A Boolean value that indicates that individually-identifying attestation MAY be returned by the authenticator. */
|
||||
enterpriseAttestationPossible?: boolean; // Ignored by bitwarden at the moment
|
||||
/** The effective resident key requirement for credential creation, a Boolean value determined by the client. Resident is synonymous with discoverable. */
|
||||
requireResidentKey: boolean;
|
||||
requireUserVerification: boolean;
|
||||
/** Forwarded to user interface */
|
||||
fallbackSupported: boolean;
|
||||
/** The constant Boolean value true. It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may wish to make a test of user presence optional although WebAuthn does not. */
|
||||
// requireUserPresence: true; // Always required
|
||||
}
|
||||
|
||||
export interface Fido2AuthenticatorMakeCredentialResult {
|
||||
credentialId: BufferSource;
|
||||
attestationObject: BufferSource;
|
||||
authData: BufferSource;
|
||||
publicKey: BufferSource;
|
||||
publicKeyAlgorithm: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for {@link Fido2AuthenticatorService.getAssertion}
|
||||
|
||||
* This interface represents the input parameters described in
|
||||
* https://www.w3.org/TR/webauthn-3/#sctn-op-get-assertion
|
||||
*/
|
||||
export interface Fido2AuthenticatorGetAssertionParams {
|
||||
/** The caller’s RP ID, as determined by the user agent and the client. */
|
||||
rpId: string;
|
||||
/** The hash of the serialized client data, provided by the client. */
|
||||
hash: BufferSource;
|
||||
allowCredentialDescriptorList: PublicKeyCredentialDescriptor[];
|
||||
/** The effective user verification requirement for assertion, a Boolean value provided by the client. */
|
||||
requireUserVerification: boolean;
|
||||
/** The constant Boolean value true. It is included here as a pseudo-parameter to simplify applying this abstract authenticator model to implementations that may wish to make a test of user presence optional although WebAuthn does not. */
|
||||
// requireUserPresence: boolean; // Always required
|
||||
extensions: unknown;
|
||||
/** Forwarded to user interface */
|
||||
fallbackSupported: boolean;
|
||||
}
|
||||
|
||||
export interface Fido2AuthenticatorGetAssertionResult {
|
||||
selectedCredential: {
|
||||
id: Uint8Array;
|
||||
userHandle?: Uint8Array;
|
||||
};
|
||||
authenticatorData: Uint8Array;
|
||||
signature: Uint8Array;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
export const UserRequestedFallbackAbortReason = "UserRequestedFallback";
|
||||
|
||||
export type UserVerification = "discouraged" | "preferred" | "required";
|
||||
|
||||
/**
|
||||
* This class represents an abstraction of the WebAuthn Client as described by W3C:
|
||||
* https://www.w3.org/TR/webauthn-3/#webauthn-client
|
||||
*
|
||||
* The WebAuthn Client is an intermediary entity typically implemented in the user agent
|
||||
* (in whole, or in part). Conceptually, it underlies the Web Authentication API and embodies
|
||||
* the implementation of the Web Authentication API's operations.
|
||||
*
|
||||
* It is responsible for both marshalling the inputs for the underlying authenticator operations,
|
||||
* and for returning the results of the latter operations to the Web Authentication API's callers.
|
||||
*/
|
||||
export abstract class Fido2ClientService {
|
||||
isFido2FeatureEnabled: (hostname: string, origin: string) => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Allows WebAuthn Relying Party scripts to request the creation of a new public key credential source.
|
||||
* For more information please see: https://www.w3.org/TR/webauthn-3/#sctn-createCredential
|
||||
*
|
||||
* @param params The parameters for the credential creation operation.
|
||||
* @param abortController An AbortController that can be used to abort the operation.
|
||||
* @returns A promise that resolves with the new credential.
|
||||
*/
|
||||
createCredential: (
|
||||
params: CreateCredentialParams,
|
||||
tab: chrome.tabs.Tab,
|
||||
abortController?: AbortController,
|
||||
) => Promise<CreateCredentialResult>;
|
||||
|
||||
/**
|
||||
* Allows WebAuthn Relying Party scripts to discover and use an existing public key credential, with the user’s consent.
|
||||
* Relying Party script can optionally specify some criteria to indicate what credential sources are acceptable to it.
|
||||
* For more information please see: https://www.w3.org/TR/webauthn-3/#sctn-getAssertion
|
||||
*
|
||||
* @param params The parameters for the credential assertion operation.
|
||||
* @param abortController An AbortController that can be used to abort the operation.
|
||||
* @returns A promise that resolves with the asserted credential.
|
||||
*/
|
||||
assertCredential: (
|
||||
params: AssertCredentialParams,
|
||||
tab: chrome.tabs.Tab,
|
||||
abortController?: AbortController,
|
||||
) => Promise<AssertCredentialResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for creating a new credential.
|
||||
*/
|
||||
export interface CreateCredentialParams {
|
||||
/** The Relaying Parties origin, see: https://html.spec.whatwg.org/multipage/browsers.html#concept-origin */
|
||||
origin: string;
|
||||
/**
|
||||
* A value which is true if and only if the caller’s environment settings object is same-origin with its ancestors.
|
||||
* It is false if caller is cross-origin.
|
||||
* */
|
||||
sameOriginWithAncestors: boolean;
|
||||
/** The Relying Party's preference for attestation conveyance */
|
||||
attestation?: "direct" | "enterprise" | "indirect" | "none";
|
||||
/** The Relying Party's requirements of the authenticator used in the creation of the credential. */
|
||||
authenticatorSelection?: {
|
||||
// authenticatorAttachment?: AuthenticatorAttachment; // not used
|
||||
requireResidentKey?: boolean;
|
||||
residentKey?: "discouraged" | "preferred" | "required";
|
||||
userVerification?: UserVerification;
|
||||
};
|
||||
/** Challenge intended to be used for generating the newly created credential's attestation object. */
|
||||
challenge: string; // b64 encoded
|
||||
/**
|
||||
* This member is intended for use by Relying Parties that wish to limit the creation of multiple credentials for
|
||||
* the same account on a single authenticator. The client is requested to return an error if the new credential would
|
||||
* be created on an authenticator that also contains one of the credentials enumerated in this parameter.
|
||||
* */
|
||||
excludeCredentials?: {
|
||||
id: string; // b64 encoded
|
||||
transports?: ("ble" | "hybrid" | "internal" | "nfc" | "usb")[];
|
||||
type: "public-key";
|
||||
}[];
|
||||
/**
|
||||
* This member contains additional parameters requesting additional processing by the client and authenticator.
|
||||
**/
|
||||
extensions?: {
|
||||
appid?: string; // Not supported
|
||||
appidExclude?: string; // Not supported
|
||||
uvm?: boolean; // Not supported
|
||||
credProps?: boolean;
|
||||
};
|
||||
/**
|
||||
* This member contains information about the desired properties of the credential to be created.
|
||||
* The sequence is ordered from most preferred to least preferred.
|
||||
* The client makes a best-effort to create the most preferred credential that it can.
|
||||
*/
|
||||
pubKeyCredParams: PublicKeyCredentialParam[];
|
||||
/** Data about the Relying Party responsible for the request. */
|
||||
rp: {
|
||||
id?: string;
|
||||
name: string;
|
||||
};
|
||||
/** Data about the user account for which the Relying Party is requesting attestation. */
|
||||
user: {
|
||||
id: string; // b64 encoded
|
||||
displayName: string;
|
||||
name: string;
|
||||
};
|
||||
/** Forwarded to user interface */
|
||||
fallbackSupported: boolean;
|
||||
/**
|
||||
* This member specifies a time, in milliseconds, that the caller is willing to wait for the call to complete.
|
||||
* This is treated as a hint, and MAY be overridden by the client.
|
||||
**/
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of creating a new credential.
|
||||
*/
|
||||
export interface CreateCredentialResult {
|
||||
credentialId: string;
|
||||
clientDataJSON: string;
|
||||
attestationObject: string;
|
||||
authData: string;
|
||||
publicKey: string;
|
||||
publicKeyAlgorithm: number;
|
||||
transports: string[];
|
||||
extensions: {
|
||||
credProps?: {
|
||||
rk: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for asserting a credential.
|
||||
*/
|
||||
export interface AssertCredentialParams {
|
||||
allowedCredentialIds: string[];
|
||||
rpId: string;
|
||||
origin: string;
|
||||
challenge: string;
|
||||
userVerification?: UserVerification;
|
||||
timeout: number;
|
||||
sameOriginWithAncestors: boolean;
|
||||
fallbackSupported: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of asserting a credential.
|
||||
*/
|
||||
export interface AssertCredentialResult {
|
||||
credentialId: string;
|
||||
clientDataJSON: string;
|
||||
authenticatorData: string;
|
||||
signature: string;
|
||||
userHandle: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A description of a key type and algorithm.
|
||||
*
|
||||
* @example {
|
||||
* alg: -7, // ES256
|
||||
* type: "public-key"
|
||||
* }
|
||||
*/
|
||||
export interface PublicKeyCredentialParam {
|
||||
alg: number;
|
||||
type: "public-key";
|
||||
}
|
||||
|
||||
/**
|
||||
* Error thrown when the user requests a fallback to the browser's built-in WebAuthn implementation.
|
||||
*/
|
||||
export class FallbackRequestedError extends Error {
|
||||
readonly fallbackRequested = true;
|
||||
constructor() {
|
||||
super("FallbackRequested");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Parameters used to ask the user to confirm the creation of a new credential.
|
||||
*/
|
||||
export interface NewCredentialParams {
|
||||
/**
|
||||
* The name of the credential.
|
||||
*/
|
||||
credentialName: string;
|
||||
|
||||
/**
|
||||
* The name of the user.
|
||||
*/
|
||||
userName: string;
|
||||
|
||||
/**
|
||||
* Whether or not the user must be verified before completing the operation.
|
||||
*/
|
||||
userVerification: boolean;
|
||||
/**
|
||||
* The relying party ID is usually the URL
|
||||
*/
|
||||
rpId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters used to ask the user to pick a credential from a list of existing credentials.
|
||||
*/
|
||||
export interface PickCredentialParams {
|
||||
/**
|
||||
* The IDs of the credentials that the user can pick from.
|
||||
*/
|
||||
cipherIds: string[];
|
||||
|
||||
/**
|
||||
* Whether or not the user must be verified before completing the operation.
|
||||
*/
|
||||
userVerification: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* This service is used to provide a user interface with which the user can control FIDO2 operations.
|
||||
* It acts as a way to remote control the user interface from the background script.
|
||||
*
|
||||
* The service is session based and is intended to be used by the FIDO2 authenticator to open a window,
|
||||
* and then use this window to ask the user for input and/or display messages to the user.
|
||||
*/
|
||||
export abstract class Fido2UserInterfaceService {
|
||||
/**
|
||||
* Creates a new session.
|
||||
* Note: This will not necessarily open a window until it is needed to request something from the user.
|
||||
*
|
||||
* @param fallbackSupported Whether or not the browser natively supports WebAuthn.
|
||||
* @param abortController An abort controller that can be used to cancel/close the session.
|
||||
*/
|
||||
newSession: (
|
||||
fallbackSupported: boolean,
|
||||
tab: chrome.tabs.Tab,
|
||||
abortController?: AbortController,
|
||||
) => Promise<Fido2UserInterfaceSession>;
|
||||
}
|
||||
|
||||
export abstract class Fido2UserInterfaceSession {
|
||||
/**
|
||||
* Ask the user to pick a credential from a list of existing credentials.
|
||||
*
|
||||
* @param params The parameters to use when asking the user to pick a credential.
|
||||
* @param abortController An abort controller that can be used to cancel/close the session.
|
||||
* @returns The ID of the cipher that contains the credentials the user picked.
|
||||
*/
|
||||
pickCredential: (
|
||||
params: PickCredentialParams,
|
||||
) => Promise<{ cipherId: string; userVerified: boolean }>;
|
||||
|
||||
/**
|
||||
* Ask the user to confirm the creation of a new credential.
|
||||
*
|
||||
* @param params The parameters to use when asking the user to confirm the creation of a new credential.
|
||||
* @param abortController An abort controller that can be used to cancel/close the session.
|
||||
* @returns The ID of the cipher where the new credential should be saved.
|
||||
*/
|
||||
confirmNewCredential: (
|
||||
params: NewCredentialParams,
|
||||
) => Promise<{ cipherId: string; userVerified: boolean }>;
|
||||
|
||||
/**
|
||||
* Make sure that the vault is unlocked.
|
||||
* This will open a window and ask the user to login or unlock the vault if necessary.
|
||||
*/
|
||||
ensureUnlockedVault: () => Promise<void>;
|
||||
|
||||
/**
|
||||
* Inform the user that the operation was cancelled because their vault contains excluded credentials.
|
||||
*
|
||||
* @param existingCipherIds The IDs of the excluded credentials.
|
||||
*/
|
||||
informExcludedCredential: (existingCipherIds: string[]) => Promise<void>;
|
||||
|
||||
/**
|
||||
* Inform the user that the operation was cancelled because their vault does not contain any useable credentials.
|
||||
*/
|
||||
informCredentialNotFound: (abortController?: AbortController) => Promise<void>;
|
||||
|
||||
/**
|
||||
* Close the session, including any windows that may be open.
|
||||
*/
|
||||
close: () => void;
|
||||
}
|
||||
Reference in New Issue
Block a user