Skip to content
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
13 changes: 10 additions & 3 deletions lib/auth/webauthncli/fido2.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func fido2Login(

// Does the device have a suitable credential?
const pin = ""
actualRPID, err := discoverRPID(dev, pin, rpID, appID, allowedCreds)
actualRPID, err := discoverRPID(dev, info, pin, rpID, appID, allowedCreds)
if err != nil {
log.Debugf("FIDO2: Device %v: filtered due to lack of allowed credential", info.path)
return false, nil
Expand Down Expand Up @@ -237,7 +237,7 @@ func fido2Login(
}, actualUser, nil
}

func discoverRPID(dev FIDODevice, pin, rpID, appID string, allowedCreds [][]byte) (string, error) {
func discoverRPID(dev FIDODevice, info *deviceInfo, pin, rpID, appID string, allowedCreds [][]byte) (string, error) {
// The actual hash is not necessary here.
const cdh = "00000000000000000000000000000000"

Expand All @@ -248,8 +248,15 @@ func discoverRPID(dev FIDODevice, pin, rpID, appID string, allowedCreds [][]byte
if id == "" {
continue
}
if _, err := dev.Assertion(id, []byte(cdh), allowedCreds, pin, opts); err == nil {
switch _, err := dev.Assertion(id, []byte(cdh), allowedCreds, pin, opts); {
// Yubikey4 returns ErrUserPresenceRequired if the credential exists,
// despite the UP=false opts above.
case err == nil, errors.Is(err, libfido2.ErrUserPresenceRequired):
return id, nil
case errors.Is(err, libfido2.ErrNoCredentials):
// Device not registered for RPID=id, keep trying.
default:
log.WithError(err).Debugf("FIDO2: Device %v: attempt RPID = %v", info.path, id)
}
}
return "", libfido2.ErrNoCredentials
Expand Down
5 changes: 5 additions & 0 deletions lib/auth/webauthncli/fido2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,11 @@ func (f *fakeFIDO2Device) Assertion(

// "base" credential. Only add an assertion if explicitly requested.
if _, ok := credIDs[string(f.key.KeyHandle)]; ok {
// Simulate Yubikey4 and require UP, even if UP==false is set.
if f.u2fOnly && opts.UP == libfido2.False {
return nil, libfido2.ErrUserPresenceRequired
}

assertions = append(assertions, &libfido2.Assertion{
AuthDataCBOR: assertionAuthDataCBOR,
Sig: assertionSig,
Expand Down