Skip to content

Commit

Permalink
feat: support hints and attestation formats
Browse files Browse the repository at this point in the history
This adds support to the hints and attestation format options, both of which are new elements from Level 3 which are effectively optional. This allows users who wish to leverage this option to do so with no negative effects for those who do not.
  • Loading branch information
james-d-elliott committed Feb 8, 2024
1 parent fbca431 commit 1b8248d
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 16 deletions.
90 changes: 76 additions & 14 deletions protocol/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,33 @@ type CredentialAssertion struct {
// In order to create a Credential via create(), the caller specifies a few parameters in a
// PublicKeyCredentialCreationOptions object.
//
// TODO: There is one field missing from this for WebAuthn Level 3. A string slice named 'attestationFormats'.
//
// Specification: §5.4. Options for Credential Creation (https://www.w3.org/TR/webauthn/#dictionary-makecredentialoptions)
type PublicKeyCredentialCreationOptions struct {
RelyingParty RelyingPartyEntity `json:"rp"`
User UserEntity `json:"user"`
Challenge URLEncodedBase64 `json:"challenge"`
Parameters []CredentialParameter `json:"pubKeyCredParams,omitempty"`
Timeout int `json:"timeout,omitempty"`
CredentialExcludeList []CredentialDescriptor `json:"excludeCredentials,omitempty"`
AuthenticatorSelection AuthenticatorSelection `json:"authenticatorSelection,omitempty"`
Attestation ConveyancePreference `json:"attestation,omitempty"`
Extensions AuthenticationExtensions `json:"extensions,omitempty"`
RelyingParty RelyingPartyEntity `json:"rp"`
User UserEntity `json:"user"`
Challenge URLEncodedBase64 `json:"challenge"`
Parameters []CredentialParameter `json:"pubKeyCredParams,omitempty"`
Timeout int `json:"timeout,omitempty"`
CredentialExcludeList []CredentialDescriptor `json:"excludeCredentials,omitempty"`
AuthenticatorSelection AuthenticatorSelection `json:"authenticatorSelection,omitempty"`
Hints []PublicKeyCredentialHint `json:"hints,omitempty"`
Attestation ConveyancePreference `json:"attestation,omitempty"`
AttestationFormats []AttestationFormat `json:"attestationFormats,omitempty"`
Extensions AuthenticationExtensions `json:"extensions,omitempty"`
}

// The PublicKeyCredentialRequestOptions dictionary supplies get() with the data it needs to generate an assertion.
// Its challenge member MUST be present, while its other members are OPTIONAL.
//
// TODO: There are two fields missing from this for WebAuthn Level 3. A string type named 'attestation', and a string
// slice named 'attestationFormats'.
//
// Specification: §5.5. Options for Assertion Generation (https://www.w3.org/TR/webauthn/#dictionary-assertion-options)
type PublicKeyCredentialRequestOptions struct {
Challenge URLEncodedBase64 `json:"challenge"`
Timeout int `json:"timeout,omitempty"`
RelyingPartyID string `json:"rpId,omitempty"`
AllowedCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"`
UserVerification UserVerificationRequirement `json:"userVerification,omitempty"`
Attestation ConveyancePreference `json:"attestation,omitempty"`
AttestationFormats []AttestationFormat `json:"attestationFormats,omitempty"`
Extensions AuthenticationExtensions `json:"extensions,omitempty"`
}

Expand Down Expand Up @@ -126,6 +125,69 @@ type AuthenticatorSelection struct {
UserVerification UserVerificationRequirement `json:"userVerification,omitempty"`
}

// PublicKeyCredentialHint is a type representing the enum PublicKeyCredentialHints from
// https://www.w3.org/TR/webauthn-3/#enum-hints.
type PublicKeyCredentialHint string

const (
// PublicKeyCredentialHintSecurityKey is a PublicKeyCredentialHint that 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.
//
// For compatibility with older user agents, when this hint is used in PublicKeyCredentialCreationOptions, the
// authenticatorAttachment SHOULD be set to cross-platform.
PublicKeyCredentialHintSecurityKey PublicKeyCredentialHint = "security-key"

// PublicKeyCredentialHintClientDevice is a PublicKeyCredentialHint that indicates that the Relying Party believes
// that users will satisfy this request with a platform authenticator attached to the client device.
//
// For compatibility with older user agents, when this hint is used in PublicKeyCredentialCreationOptions, the
// authenticatorAttachment SHOULD be set to platform.
PublicKeyCredentialHintClientDevice PublicKeyCredentialHint = "client-device"

// PublicKeyCredentialHintHybrid is a PublicKeyCredentialHint that 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.
//
// For compatibility with older user agents, when this hint is used in PublicKeyCredentialCreationOptions, the
// authenticatorAttachment SHOULD be set to cross-platform.
PublicKeyCredentialHintHybrid PublicKeyCredentialHint = "hybrid"
)

type AttestationFormat string

const (
// AttestationFormatPacked is the "packed" attestation statement format is a WebAuthn-optimized format for
// attestation. It uses a very compact but still extensible encoding method. This format is implementable by
//authenticators with limited resources (e.g., secure elements).
AttestationFormatPacked AttestationFormat = "packed"

// AttestationFormatTPM is the TPM attestation statement format returns an attestation statement in the same format
// as the packed attestation statement format, although the rawData and signature fields are computed differently.
AttestationFormatTPM AttestationFormat = "tpm"

// AttestationFormatAndroidKey is the attestation statement format for platform authenticators on versions "N", and
// later, which may provide this proprietary "hardware attestation" statement.
AttestationFormatAndroidKey AttestationFormat = "android-key"

// AttestationFormatAndroidSafetyNet is the attestation statement format that Android-based platform authenticators
// MAY produce an attestation statement based on the Android SafetyNet API.
AttestationFormatAndroidSafetyNet AttestationFormat = "android-safetynet"

// AttestationFormatFIDOU2F is the attestation statement format that is used with FIDO U2F authenticators.
AttestationFormatFIDOU2F AttestationFormat = "fido-u2f"

// AttestationFormatApple is the attestation statement format that is used with Apple devices' platform
// authenticators.
AttestationFormatApple AttestationFormat = "apple"

// AttestationFormatNone is the attestation statement format that is used to replace any authenticator-provided
// attestation statement when a WebAuthn Relying Party indicates it does not wish to receive attestation information.
AttestationFormatNone AttestationFormat = "none"
)

// ConveyancePreference is the type representing the AttestationConveyancePreference IDL.
//
// WebAuthn Relying Parties may use AttestationConveyancePreference to specify their preference regarding attestation
Expand Down
16 changes: 16 additions & 0 deletions webauthn/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,22 @@ func WithUserVerification(userVerification protocol.UserVerificationRequirement)
}
}

// WithLoginConveyancePreference adjusts the non-default parameters regarding whether the authenticator should attest to the
// credential.
func WithLoginConveyancePreference(preference protocol.ConveyancePreference) LoginOption {
return func(cco *protocol.PublicKeyCredentialRequestOptions) {
cco.Attestation = preference
}
}

// WithLoginAttestationFormats adjusts the preferred attestation formats for this credential request in most to least
// preferable. Advisory only.
func WithLoginAttestationFormats(formats ...protocol.AttestationFormat) LoginOption {
return func(cco *protocol.PublicKeyCredentialRequestOptions) {
cco.AttestationFormats = formats
}
}

// WithAssertionExtensions adjusts the requested extensions.
func WithAssertionExtensions(extensions protocol.AuthenticationExtensions) LoginOption {
return func(cco *protocol.PublicKeyCredentialRequestOptions) {
Expand Down
26 changes: 24 additions & 2 deletions webauthn/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,43 @@ func WithAuthenticatorSelection(authenticatorSelection protocol.AuthenticatorSel
}
}

func WithHints(hints ...protocol.PublicKeyCredentialHint) RegistrationOption {
return func(cco *protocol.PublicKeyCredentialCreationOptions) {
cco.Hints = hints
}
}

// WithExclusions adjusts the non-default parameters regarding credentials to exclude from registration.
func WithExclusions(excludeList []protocol.CredentialDescriptor) RegistrationOption {
return func(cco *protocol.PublicKeyCredentialCreationOptions) {
cco.CredentialExcludeList = excludeList
}
}

// WithConveyancePreference adjusts the non-default parameters regarding whether the authenticator should attest to the
// credential.
// WithConveyancePreference is a direct alias for WithRegistrationConveyancePreference.
//
// Deprecated: Use WithRegistrationConveyancePreference in favor of WithConveyancePreference as this function will be
// likely be removed in a future release.
func WithConveyancePreference(preference protocol.ConveyancePreference) RegistrationOption {
return WithRegistrationConveyancePreference(preference)
}

// WithRegistrationConveyancePreference adjusts the non-default parameters regarding whether the authenticator should attest to the
// credential.
func WithRegistrationConveyancePreference(preference protocol.ConveyancePreference) RegistrationOption {
return func(cco *protocol.PublicKeyCredentialCreationOptions) {
cco.Attestation = preference
}
}

// WithRegistrationAttestationFormats adjusts the preferred attestation formats for this credential creation in most to
// least preferable. Advisory only.
func WithRegistrationAttestationFormats(formats ...protocol.AttestationFormat) RegistrationOption {
return func(cco *protocol.PublicKeyCredentialCreationOptions) {
cco.AttestationFormats = formats
}
}

// WithExtensions adjusts the extension parameter in the registration options.
func WithExtensions(extension protocol.AuthenticationExtensions) RegistrationOption {
return func(cco *protocol.PublicKeyCredentialCreationOptions) {
Expand Down

0 comments on commit 1b8248d

Please sign in to comment.