Skip to content

Commit

Permalink
Implement PublicKeyCredentialHint for WebAuthn L3 (#524)
Browse files Browse the repository at this point in the history
* Implement PublicKeyCredentialHint for WebAuthn L3.

* Set `Hints` to `null` when empty array is passed.

* Format XML comment

* Ignore when writing null

* remove link

* Needs to be list, order matters

* Correct backwards compatibility options for PublicKeyCredentialHint

* Add support for `hints` during authentication.

* Correct

---------

Co-authored-by: Anders Åberg <anders@andersaberg.com>
  • Loading branch information
jonashendrickx and abergs authored Jul 15, 2024
1 parent b1157a5 commit df37692
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Src/Fido2.Models/AssertionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public class AssertionOptions : Fido2ResponseBase
[JsonPropertyName("userVerification")]
public UserVerificationRequirement? UserVerification { get; set; }

/// <summary>
/// This OPTIONAL member contains zero or more elements from <see cref="PublicKeyCredentialHint"/> to guide the user agent in interacting with the user. Note that the elements have type DOMString despite being taken from that enumeration.
/// </summary>
[JsonPropertyName("hints")]
public IReadOnlyList<PublicKeyCredentialHint> Hints { get; set; } = Array.Empty<PublicKeyCredentialHint>();

/// <summary>
/// This OPTIONAL member contains additional parameters requesting additional processing by the client and authenticator.
/// For example, if transaction confirmation is sought from the user, then the prompt string might be included as an extension.
Expand Down
38 changes: 38 additions & 0 deletions Src/Fido2.Models/CredentialCreateOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,44 @@ public sealed class CredentialCreateOptions : Fido2ResponseBase
[JsonPropertyName("authenticatorSelection")]
public AuthenticatorSelection AuthenticatorSelection { get; set; }

private IReadOnlyList<PublicKeyCredentialHint> _hints = Array.Empty<PublicKeyCredentialHint>();

/// <summary>
/// Guides the user agent in interacting with the user. This OPTIONAL member contains zero or more elements from <see cref="PublicKeyCredentialHint" />.
/// </summary>
/// <remarks>
/// When <see cref="Hints"/> is set, <see cref="AuthenticatorSelection.AuthenticatorAttachment" /> will be set to one of the values in the table below:
/// <list type="table">
/// <item><term><see cref="PublicKeyCredentialHint.SecurityKey"/></term><description><see cref="AuthenticatorAttachment.CrossPlatform"/></description></item>
/// <item><term><see cref="PublicKeyCredentialHint.ClientDevice"/></term><description><see cref="AuthenticatorAttachment.Platform"/></description></item>
/// <item><term><see cref="PublicKeyCredentialHint.Hybrid"/></term><description><see cref="AuthenticatorAttachment.CrossPlatform"/></description></item>
/// </list>
/// </remarks>
[JsonPropertyName("hints")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public IReadOnlyList<PublicKeyCredentialHint> Hints
{
get
{
return _hints;
}
set
{
if (value.Any())
{
AuthenticatorSelection ??= new AuthenticatorSelection();
AuthenticatorSelection.AuthenticatorAttachment = value[0] switch
{
PublicKeyCredentialHint.SecurityKey or PublicKeyCredentialHint.Hybrid => AuthenticatorAttachment
.CrossPlatform,
PublicKeyCredentialHint.ClientDevice => AuthenticatorAttachment.Platform,
_ => AuthenticatorSelection.AuthenticatorAttachment
};
}
_hints = value;
}
}

/// <summary>
/// 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.
/// </summary>
Expand Down
30 changes: 30 additions & 0 deletions Src/Fido2.Models/Objects/PublicKeyCredentialHint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace Fido2NetLib.Objects;

/// <summary>
/// WebAuthn Relying Parties may use this enumeration to communicate hints to the user-agent about how a request may be best completed. These hints are not requirements, and do not bind the user-agent, but may guide it in providing the best experience by using contextual information that the Relying Party has about the request. Hints are provided in order of decreasing preference so, if two hints are contradictory, the first one controls. Hints may also overlap: if a more-specific hint is defined a Relying Party may still wish to send less specific ones for user-agents that may not recognise the more specific one. In this case the most specific hint should be sent before the less-specific ones.
/// Hints MAY contradict information contained in credential transports and authenticatorAttachment. When this occurs, the hints take precedence. (Note that transports values are not provided when using discoverable credentials, leaving hints as the only avenue for expressing some aspects of such a request.)
/// </summary>
[JsonConverter(typeof(FidoEnumConverter<PublicKeyCredentialHint>))]
public enum PublicKeyCredentialHint
{
/// <summary>
/// Indicates that the Relying Party believes that users will satisfy this request with a physical security key. For example, an enterprise Relying Party may set this hint if they have issued security keys to their employees and will only accept those authenticators for registration and authentication.
/// </summary>
[EnumMember(Value = "security-key")]
SecurityKey,

/// <summary>
/// Indicates that the Relying Party believes that users will satisfy this request with a platform authenticator attached to the client device.
/// </summary>
[EnumMember(Value = "client-device")]
ClientDevice,

/// <summary>
/// Indicates that the Relying Party believes that users will satisfy this request with general-purpose authenticators such as smartphones. For example, a consumer Relying Party may believe that only a small fraction of their customers possesses dedicated security keys. This option also implies that the local platform authenticator should not be promoted in the UI.
/// </summary>
[EnumMember(Value = "hybrid")]
Hybrid,
}

0 comments on commit df37692

Please sign in to comment.