Skip to content

Commit

Permalink
feat: add resident key protocol option (#13)
Browse files Browse the repository at this point in the history
Adds the residentKey protocol option which is part of Webauthn Level 2.
  • Loading branch information
james-d-elliott committed Mar 1, 2022
1 parent a71ef84 commit 5ad54f8
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 5 deletions.
21 changes: 18 additions & 3 deletions protocol/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type AttestedCredentialData struct {
CredentialPublicKey []byte `json:"public_key"`
}

// AuthenticatorAttachment https://www.w3.org/TR/webauthn/#platform-attachment
// AuthenticatorAttachment https://www.w3.org/TR/webauthn/#dom-authenticatorselectioncriteria-authenticatorattachment
type AuthenticatorAttachment string

const (
Expand All @@ -65,6 +65,21 @@ const (
CrossPlatform AuthenticatorAttachment = "cross-platform"
)

// ResidentKeyRequirement https://www.w3.org/TR/webauthn/#dom-authenticatorselectioncriteria-residentkey
type ResidentKeyRequirement string

const (
// ResidentKeyRequirementDiscouraged indicates to the client we do not want a discoverable credential. This is the default.
ResidentKeyRequirementDiscouraged ResidentKeyRequirement = "discouraged"

// ResidentKeyRequirementPreferred indicates to the client we would prefer a discoverable credential.
ResidentKeyRequirementPreferred ResidentKeyRequirement = "preferred"

// ResidentKeyRequirementRequired indicates to the client we require a discoverable credential and that it should
// fail if the credential does not support this feature.
ResidentKeyRequirementRequired ResidentKeyRequirement = "required"
)

// Authenticators may implement various transports for communicating with clients. This enumeration defines
// hints as to how clients might communicate with a particular authenticator in order to obtain an assertion
// for a specific credential. Note that these hints represent the WebAuthn Relying Party's best belief as to
Expand Down Expand Up @@ -237,8 +252,8 @@ func ResidentKeyRequired() *bool {
return &required
}

// ResidentKeyUnrequired - Do not require that the private key be resident to the client device.
func ResidentKeyUnrequired() *bool {
// ResidentKeyNotRequired - Do not require that the private key be resident to the client device.
func ResidentKeyNotRequired() *bool {
required := false
return &required
}
Expand Down
5 changes: 5 additions & 0 deletions protocol/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ type AuthenticatorSelection struct {
// credentials. If the parameter is set to true, the authenticator MUST create a client-side-resident
// public key credential source when creating a public key credential.
RequireResidentKey *bool `json:"requireResidentKey,omitempty"`

// ResidentKey this member describes the Relying Party's requirements regarding resident
// credentials per Webauthn Level 2.
ResidentKey ResidentKeyRequirement `json:"residentKey,omitempty"`

// UserVerification This member describes the Relying Party's requirements regarding user verification for
// the create() operation. Eligible authenticators are filtered to only those capable of satisfying this
// requirement.
Expand Down
4 changes: 2 additions & 2 deletions webauthn/authenticator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ func TestSelectAuthenticator(t *testing.T) {
{"Generate Correct Authenticator Selection",
args{
att: "platform",
rrk: p.ResidentKeyUnrequired(),
rrk: p.ResidentKeyNotRequired(),
uv: "preferred",
},
p.AuthenticatorSelection{
AuthenticatorAttachment: p.Platform,
RequireResidentKey: p.ResidentKeyUnrequired(),
RequireResidentKey: p.ResidentKeyNotRequired(),
UserVerification: p.VerificationPreferred,
},
},
Expand Down
13 changes: 13 additions & 0 deletions webauthn/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ func WithAppIdExcludeExtension(appid string) RegistrationOption {
}
}

// WithResidentKeyRequirement sets both the resident key and require resident key protocol options. When
func WithResidentKeyRequirement(requirement protocol.ResidentKeyRequirement) RegistrationOption {
return func(cco *protocol.PublicKeyCredentialCreationOptions) {
cco.AuthenticatorSelection.ResidentKey = requirement
switch requirement {
case protocol.ResidentKeyRequirementRequired:
cco.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyRequired()
default:
cco.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyNotRequired()
}
}
}

// Take the response from the authenticator and client and verify the credential against the user's credentials and
// session data.
func (webauthn *WebAuthn) FinishRegistration(user User, session SessionData, response *http.Request) (*Credential, error) {
Expand Down

0 comments on commit 5ad54f8

Please sign in to comment.