diff --git a/src/Core/Abstractions/IFido2ClientService.cs b/src/Core/Abstractions/IFido2ClientService.cs new file mode 100644 index 000000000..a690faacf --- /dev/null +++ b/src/Core/Abstractions/IFido2ClientService.cs @@ -0,0 +1,35 @@ +using Bit.Core.Utilities.Fido2; + +namespace Bit.Core.Abstractions +{ + /// + /// 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. + /// + public interface IFido2ClientService + { + /// + /// 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 + /// + /// The parameters for the credential creation operation + /// The new credential + Task CreateCredentialAsync(Fido2ClientCreateCredentialParams createCredentialParams); + + /// + /// 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 + /// + /// The parameters for the credential assertion operation + /// The asserted credential + Task AssertCredentialAsync(Fido2ClientAssertCredentialParams assertCredentialParams); + } +} diff --git a/src/Core/Services/Fido2AuthenticatorService.cs b/src/Core/Services/Fido2AuthenticatorService.cs index ef0b4e5cb..e82dd5825 100644 --- a/src/Core/Services/Fido2AuthenticatorService.cs +++ b/src/Core/Services/Fido2AuthenticatorService.cs @@ -128,6 +128,7 @@ namespace Bit.Core.Services string selectedCipherId; bool userVerified; bool userPresence; + // TODO: We might want reconsider allowing user presence to be optional if (assertionParams.AllowCredentialDescriptorList?.Length == 1 && assertionParams.RequireUserPresence == false) { selectedCipherId = cipherOptions[0].Id; diff --git a/src/Core/Services/Fido2ClientService.cs b/src/Core/Services/Fido2ClientService.cs new file mode 100644 index 000000000..025b28412 --- /dev/null +++ b/src/Core/Services/Fido2ClientService.cs @@ -0,0 +1,12 @@ +using Bit.Core.Abstractions; +using Bit.Core.Utilities.Fido2; + +namespace Bit.Core.Services +{ + public class Fido2ClientService : IFido2ClientService + { + public Task CreateCredentialAsync(Fido2ClientCreateCredentialParams createCredentialParams) => throw new NotImplementedException(); + + public Task AssertCredentialAsync(Fido2ClientAssertCredentialParams assertCredentialParams) => throw new NotImplementedException(); + } +} diff --git a/src/Core/Utilities/Fido2/AuthenticatorSelectionCriteria.cs b/src/Core/Utilities/Fido2/AuthenticatorSelectionCriteria.cs new file mode 100644 index 000000000..d988eb07e --- /dev/null +++ b/src/Core/Utilities/Fido2/AuthenticatorSelectionCriteria.cs @@ -0,0 +1,18 @@ +namespace Bit.Core.Utilities.Fido2 +{ + #nullable enable + /// + /// The Relying Party's requirements of the authenticator used in the creation of the credential. + /// + public class AuthenticatorSelectionCriteria + { + public bool? RequireResidentKey { get; set; } + public string? ResidentKey { get; set; } + public string UserVerification { get; set; } = "preferred"; + + /// + /// This member is intended for use by Relying Parties that wish to select the appropriate authenticators to participate in the create() operation. + /// + // public AuthenticatorAttachment? AuthenticatorAttachment { get; set; } // not used + } +} diff --git a/src/Core/Utilities/Fido2/Fido2ClientAssertCredentialParams.cs b/src/Core/Utilities/Fido2/Fido2ClientAssertCredentialParams.cs new file mode 100644 index 000000000..f479467d5 --- /dev/null +++ b/src/Core/Utilities/Fido2/Fido2ClientAssertCredentialParams.cs @@ -0,0 +1,51 @@ +namespace Bit.Core.Utilities.Fido2 +{ + #nullable enable + + /// + /// Parameters for asserting a credential. + /// + /// This class is an extended version of the WebAuthn struct: + /// https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialrequestoptions + /// + public class Fido2ClientAssertCredentialParams + { + /// + /// S challenge that the selected authenticator signs, along with other data, when producing an authentication + /// assertion. + /// + public required byte[] Challenge { get; set; } + + /// + /// The relying party identifier claimed by the caller. If omitted, its value will be the CredentialsContainer + /// object's relevant settings object's origin's effective domain. + /// + public string RpId { get; set; } + + /// + /// The Relying Party's origin (e.g., "https://example.com"). + /// + public string Origin { get; set; } + + /// + /// A list of PublicKeyCredentialDescriptor objects representing public key credentials acceptable to the caller, + /// in descending order of the caller’s preference (the first item in the list is the most preferred credential, + /// and so on down the list). + /// + public PublicKeyCredentialDescriptor[] AllowCredentials { get; set; } = []; + + /// + /// The Relying Party's requirements regarding user verification for the get() operation. + /// + public string UserVerification { get; set; } = "preferred"; + + /// + /// This 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. + /// + /// + /// This is not currently supported. + /// + public int? Timeout { get; set; } + } +} diff --git a/src/Core/Utilities/Fido2/Fido2ClientAssertCredentialResult.cs b/src/Core/Utilities/Fido2/Fido2ClientAssertCredentialResult.cs new file mode 100644 index 000000000..31bc9468c --- /dev/null +++ b/src/Core/Utilities/Fido2/Fido2ClientAssertCredentialResult.cs @@ -0,0 +1,20 @@ +namespace Bit.Core.Utilities.Fido2 +{ + /// + /// The result of asserting a credential. + /// + /// See: https://www.w3.org/TR/webauthn-2/#publickeycredential + /// + public class Fido2ClientAssertCredentialResult + { + /// + /// Base64url encoding of the credential identifer. + /// + public required string Id { get; set; } + + /// + /// The credential identifier. + /// + public required byte[] RawId { get; set; } + } +} diff --git a/src/Core/Utilities/Fido2/Fido2ClientAuthenticatorAssertionResponse.cs b/src/Core/Utilities/Fido2/Fido2ClientAuthenticatorAssertionResponse.cs new file mode 100644 index 000000000..ad343f1dc --- /dev/null +++ b/src/Core/Utilities/Fido2/Fido2ClientAuthenticatorAssertionResponse.cs @@ -0,0 +1,35 @@ +namespace Bit.Core.Utilities.Fido2 +{ + /// + /// This class represents an authenticator's response to a client's request for generation of a + /// new authentication assertion given the WebAuthn Relying Party's challenge. + /// This response contains a cryptographic signature proving possession of the credential private key, + /// and optionally evidence of user consent to a specific transaction. + /// + /// See: https://www.w3.org/TR/webauthn-2/#iface-authenticatorassertionresponse + /// + public class Fido2ClientAuthenticatorAssertionResponse + { + /// + /// The JSON-compatible serialization of client data passed to the authenticator by the client + /// in order to generate this assertion. The exact JSON serialization MUST be preserved, as the + /// hash of the serialized client data has been computed over it. + /// + public required byte[] ClientDataJSON { get; set; } + + /// + /// The authenticator data returned by the authenticator. + /// + public required byte[] AuthenticatorData { get; set; } + + /// + /// Raw signature returned from the authenticator. + /// + public required byte[] Signature { get; set; } + + /// + /// The user handle returned from the authenticator, or null if the authenticator did not return a user handle. + /// + public byte[] UserHandle { get; set; } = null; + } +} diff --git a/src/Core/Utilities/Fido2/Fido2ClientCreateCredentialParams.cs b/src/Core/Utilities/Fido2/Fido2ClientCreateCredentialParams.cs new file mode 100644 index 000000000..49668ef38 --- /dev/null +++ b/src/Core/Utilities/Fido2/Fido2ClientCreateCredentialParams.cs @@ -0,0 +1,75 @@ +namespace Bit.Core.Utilities.Fido2 +{ + #nullable enable + + /// + /// Parameters for creating a new credential. + /// + public class Fido2ClientCreateCredentialParams + { + /// + /// The Relaying Parties origin, see: https://html.spec.whatwg.org/multipage/browsers.html#concept-origin + /// + public required string Origin { get; set; } + + /// + /// 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. + /// + public bool SameOriginWithAncestors { get; set; } + + /// + /// The Relying Party's preference for attestation conveyance + /// + public string? Attestation { get; set; } = "none"; + + /// + /// The Relying Party's requirements of the authenticator used in the creation of the credential. + /// + public AuthenticatorSelectionCriteria? AuthenticatorSelection { get; set; } + + /// + /// Challenge intended to be used for generating the newly created credential's attestation object. + /// + public required byte[] Challenge { get; set; } // base64url 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. + /// + public List? ExcludeCredentials { get; set; } + + /// + /// This member contains additional parameters requesting additional processing by the client and authenticator. + /// Not currently supported. + /// + public object? Extensions { get; set; } + + /// + /// 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. + /// + public required List PubKeyCredParams { get; set; } + + /// + /// Data about the Relying Party responsible for the request. + /// + public required PublicKeyCredentialRpEntity Rp { get; set; } + + /// + /// Data about the user account for which the Relying Party is requesting attestation. + /// + public required PublicKeyCredentialUserEntity User { get; set; } + + /// + /// 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. + /// + /// + /// This is not currently supported. + /// + public int? Timeout { get; set; } + } +} diff --git a/src/Core/Utilities/Fido2/Fido2ClientCreateCredentialResult.cs b/src/Core/Utilities/Fido2/Fido2ClientCreateCredentialResult.cs new file mode 100644 index 000000000..21cd90357 --- /dev/null +++ b/src/Core/Utilities/Fido2/Fido2ClientCreateCredentialResult.cs @@ -0,0 +1,19 @@ +namespace Bit.Core.Utilities.Fido2 +{ + /// + /// The result of creating a new credential. + /// + /// This class is an extended version of the WebAuthn struct: + /// https://www.w3.org/TR/webauthn-3/#credentialcreationdata-attestationobjectresult + /// + public class Fido2ClientCreateCredentialResult + { + public byte[] CredentialId { get; set; } + public byte[] ClientDataJSON { get; set; } + public byte[] AttestationObject { get; set; } + public byte[] AuthData { get; set; } + public byte[] PublicKey { get; set; } + public int PublicKeyAlgorithm { get; set; } + public string[] Transports { get; set; } + } +} diff --git a/src/Core/Utilities/Fido2/PublicKeyCredentialParameters.cs b/src/Core/Utilities/Fido2/PublicKeyCredentialParameters.cs new file mode 100644 index 000000000..af3e00d23 --- /dev/null +++ b/src/Core/Utilities/Fido2/PublicKeyCredentialParameters.cs @@ -0,0 +1,15 @@ +namespace Bit.Core.Utilities.Fido2 +{ + /// + /// A description of a key type and algorithm. + /// + public class PublicKeyCredentialParameters + { + public string Type { get; set; } + + /// + /// Cose algorithm identifier, e.g. -7 for ES256. + /// + public int Alg { get; set; } + } +}