webauthncli

package
v0.0.0-...-5c79d48 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2024 License: AGPL-3.0 Imports: 34 Imported by: 0

Documentation

Overview

Package webauthncli provides the client-side implementation for WebAuthn.

There are two separate implementations contained within the package:

* A U2F (aka CTAP1), pure Go implementation, backed by flynn/u2f * A FIDO2 (aka CTAP1/CTAP2) implementation, backed by Yubico's libfido2

High-level API methods prefer the FIDO2 implementation, falling back to U2F if the binary isn't compiled with libfido2 support. Note that passwordless requires CTAP2.

The FIDO2 implementation is protected by the `libfido2` build tag. In order to build FIDO2-enabled code, in addition to setting the build tag (eg, `go build -tags=libfido2 ./tool/tsh` or `go test -tags=libfido2 ./lib/auth/webauthncli`), you must first have libfido2 installed in your system.

To install libfido2 [follow its installation instructions]( https://github.com/Yubico/libfido2#installation). See gravitational/go-libfido2(https://github.com/gravitational/go-libfido2#why-fork) for additional build options.

Refer to [buildbox](https://github.com/gravitational/teleport/blob/master/build.assets/Dockerfile#L10) for the library versions used by release binaries.

Index

Constants

This section is empty.

Variables

View Source
var DevicePollInterval = 200 * time.Millisecond

DevicePollInterval is the interval between polling attempts on Webauthn or U2F devices. Used by otherwise tight loops such as RunOnU2FDevices and related methods, like Login.

View Source
var ErrAlreadyRegistered = errors.New("already registered")

ErrAlreadyRegistered may be used by RunOnU2FDevices callbacks to signify that a certain authenticator is already registered, and thus should be removed from the loop.

View Source
var ErrUsingNonRegisteredDevice = errors.New("You are using a security key that is not registered with Teleport. Try a different security key.")

ErrUsingNonRegisteredDevice is returned from Login when the user attempts to authenticate with a non-registered security key. The error message is meant to be displayed to end-users, thus it breaks the usual Go error conventions (capitalized sentences, punctuation).

View Source
var FIDO2PollInterval = 200 * time.Millisecond

FIDO2PollInterval is the poll interval used to check for new FIDO2 devices.

Functions

func FIDO2Login

func FIDO2Login(
	ctx context.Context,
	origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error)

FIDO2Login implements Login for CTAP1 and CTAP2 devices. It must be called with a context with timeout, otherwise it can run indefinitely. The informed user is used to disambiguate credentials in case of passwordless logins. It returns an MFAAuthenticateResponse and the credential user, if a resident credential is used. Most callers should call Login directly, as it is correctly guarded by IsFIDO2Available.

func FIDO2Register

func FIDO2Register(
	ctx context.Context,
	origin string, cc *wantypes.CredentialCreation, prompt RegisterPrompt,
) (*proto.MFARegisterResponse, error)

FIDO2Register implements Register for CTAP1 and CTAP2 devices. It must be called with a context with timeout, otherwise it can run indefinitely. Most callers should call Register directly, as it is correctly guarded by IsFIDO2Available.

func HasPlatformSupport

func HasPlatformSupport() bool

HasPlatformSupport returns true if the platform supports client-side WebAuthn-compatible logins.

func IsFIDO2Available

func IsFIDO2Available() bool

IsFIDO2Available returns true if FIDO2 is implemented either via native libfido2 library or Windows WebAuthn API.

func Login

func Login(
	ctx context.Context,
	origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error)

Login performs client-side, U2F-compatible, Webauthn login. This method blocks until either device authentication is successful or the context is canceled. Calling Login without a deadline or cancel condition may cause it to block forever. The informed user is used to disambiguate credentials in case of passwordless logins. It returns an MFAAuthenticateResponse and the credential user, if a resident credential is used. The caller is expected to react to LoginPrompt in order to prompt the user at appropriate times. Login may choose different flows depending on the type of authentication and connected devices.

func Register

Register performs client-side, U2F-compatible, Webauthn registration. This method blocks until either device authentication is successful or the context is canceled. Calling Register without a deadline or cancel condition may cause it block forever. The caller is expected to react to RegisterPrompt in order to prompt the user at appropriate times. Register may choose different flows depending on the type of authentication and connected devices.

func RunOnU2FDevices

func RunOnU2FDevices(ctx context.Context, runCredentials ...func(Token) error) error

RunOnU2FDevices polls for new U2F/CTAP1 devices and invokes the callbacks against them in regular intervals, running until either one callback succeeds or the context is canceled. Typically, each callback represents a {credential,rpid} pair to check against the device. Calling this method using a context without a cancel or deadline means it will execute until successful (which may be never). Most callers should prefer higher-abstraction functions such as Login.

func ToTouchIDCredentialPicker

func ToTouchIDCredentialPicker(p credentialPicker) touchid.CredentialPicker

ToTouchIDCredentialPicker adapts a wancli credential picker, such as LoginPrompt or DefaultPrompt, to a touchid.CredentialPicker

func U2FLogin

U2FLogin implements Login for U2F/CTAP1 devices. The implementation is backed exclusively by Go code, making it useful in scenarios where libfido2 is unavailable.

func U2FRegister

U2FRegister implements Register for U2F/CTAP1 devices. The implementation is backed exclusively by Go code, making it useful in scenarios where libfido2 is unavailable.

Types

type AuthenticatorAttachment

type AuthenticatorAttachment int

AuthenticatorAttachment allows callers to choose a specific attachment.

const (
	AttachmentAuto AuthenticatorAttachment = iota
	AttachmentCrossPlatform
	AttachmentPlatform
)

func (AuthenticatorAttachment) String

func (a AuthenticatorAttachment) String() string

type CollectedClientData

type CollectedClientData struct {
	Type      string `json:"type"`
	Challenge string `json:"challenge"`
	Origin    string `json:"origin"`
}

CollectedClientData is part of the data signed by authenticators (after marshaled to JSON, hashed and appended to authData). https://www.w3.org/TR/webauthn-2/#dictionary-client-data

type CredentialInfo

type CredentialInfo struct {
	ID   []byte
	User UserInfo
}

CredentialInfo holds information about a WebAuthn credential, typically a resident public key credential.

type DefaultPrompt

type DefaultPrompt struct {
	PINMessage                            string
	FirstTouchMessage, SecondTouchMessage string
	AcknowledgeTouchMessage               string
	PromptCredentialMessage               string
	// contains filtered or unexported fields
}

DefaultPrompt is a default implementation for LoginPrompt and RegistrationPrompt.

func NewDefaultPrompt

func NewDefaultPrompt(ctx context.Context, out io.Writer) *DefaultPrompt

NewDefaultPrompt creates a new default prompt. Default messages are suitable for login / authorization. Messages may be customized by setting the appropriate fields.

func (*DefaultPrompt) PromptCredential

func (p *DefaultPrompt) PromptCredential(creds []*CredentialInfo) (*CredentialInfo, error)

PromptCredential prompts the user to choose a credential, in case multiple credentials are available.

func (*DefaultPrompt) PromptPIN

func (p *DefaultPrompt) PromptPIN() (string, error)

PromptPIN prompts the user for a PIN.

func (*DefaultPrompt) PromptTouch

func (p *DefaultPrompt) PromptTouch() (TouchAcknowledger, error)

PromptTouch prompts the user for a security key touch, using different messages for first and second prompts. Error is always nil.

type FIDO2DiagResult

type FIDO2DiagResult struct {
	Available                           bool
	RegisterSuccessful, LoginSuccessful bool
}

func FIDO2Diag

func FIDO2Diag(ctx context.Context, promptOut io.Writer) (*FIDO2DiagResult, error)

FIDO2Diag runs a few diagnostic commands and returns the result. User interaction is required.

type LoginOpts

type LoginOpts struct {
	// User is the desired credential username for login.
	// If empty, Login may either choose a credential or prompt the user for input
	// (via LoginPrompt).
	User string
	// AuthenticatorAttachment specifies the desired authenticator attachment.
	AuthenticatorAttachment AuthenticatorAttachment
}

LoginOpts groups non-mandatory options for Login.

type LoginPrompt

type LoginPrompt interface {
	// PromptPIN prompts the user for their PIN.
	PromptPIN() (string, error)
	// PromptTouch prompts the user for a security key touch.
	// In certain situations multiple touches may be required (PIN-protected
	// devices, passwordless flows, etc).
	// Returns a TouchAcknowledger which should be called to signal to the user
	// that the touch was successfully detected.
	// Returns an error if the prompt fails to be sent to the user.
	PromptTouch() (TouchAcknowledger, error)
	// PromptCredential prompts the user to choose a credential, in case multiple
	// credentials are available.
	// Callers are free to modify the slice, such as by sorting the credentials,
	// but must return one of the pointers contained within.
	PromptCredential(creds []*CredentialInfo) (*CredentialInfo, error)
}

LoginPrompt is the user interface for FIDO2Login.

Prompts can have remote implementations, thus all methods may error.

type RegisterPrompt

type RegisterPrompt interface {
	// PromptPIN prompts the user for their PIN.
	PromptPIN() (string, error)
	// PromptTouch prompts the user for a security key touch.
	// In certain situations multiple touches may be required (PIN-protected
	// devices, passwordless flows, etc).
	// Returns a TouchAcknowledger which should be called to signal to the user
	// that the touch was successfully detected.
	// Returns an error if the prompt fails to be sent to the user.
	PromptTouch() (TouchAcknowledger, error)
}

RegisterPrompt is the user interface for FIDO2Register.

Prompts can have remote implementations, thus all methods may error.

type Token

type Token interface {
	CheckAuthenticate(req u2ftoken.AuthenticateRequest) error
	Authenticate(req u2ftoken.AuthenticateRequest) (*u2ftoken.AuthenticateResponse, error)
	Register(req u2ftoken.RegisterRequest) ([]byte, error)
}

Token represents the actions possible using an U2F/CTAP1 token.

type TouchAcknowledger

type TouchAcknowledger func() error

TouchAcknowledger is a function type which should be called to signal to the user that a security key touch was successfully detected. May return an error if the acknowledgement fails to be sent to the user.

type UserInfo

type UserInfo struct {
	// UserHandle is the WebAuthn user handle (also referred as user ID).
	UserHandle []byte
	Name       string
}

UserInfo holds information about a credential owner.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL