Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add resident key protocol option #13

Merged
merged 1 commit into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat: add resident key protocol option
Adds the residentKey protocol option which is part of Webauthn Level 2.
  • Loading branch information
james-d-elliott committed Mar 1, 2022
commit d973582f1ae9432913b96511a858ca46618fd1e2
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