webauthn

package module
v0.0.0-...-5003f9b Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2024 License: MIT Imports: 18 Imported by: 1

README

go-webauthn

This library helps implement WebAuthn Relying Party functionality in Go.

[!WARNING] While it does not fully comply with the WebAuthn Level 3 specification at present, it can implement authentication using Passkeys.

Examples

See the example directory for examples on how to use this library.

Credential Registration

Initiation phase

var (
    rpConfig = &webauthn.RPConfig{
    		ID:      "localhost",
    		Name:    "localhost",
    		Origins: []string{"http://localhost:8080"},
    	}
)

// Save the session and return the options as a response
options, webauthnSession, err := webauthn.CreateRegistrationCeremonyOptions(rpConfig, *webauthnUser)

Verification phase

var registrationResponse webauthn.RegistrationResponseJSON
if err := json.NewDecoder(r.Body).Decode(&registrationResponse); err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
	return
}

// Save the credential associated with the user.
// See WebAuthn Level 3 for data that RP should save: https://www.w3.org/TR/webauthn-3/#reg-ceremony-store-credential-record
// Also, it should be verified that credential.ID is not associated with other users.
credential, err := webauthn.VerifyRegistrationCelemonyResponse(rpConfig, *session, registrationResponse, nil)
Authentication

Initiation phase

// Save the session and return the options as a response
options, session, err := webauthn.CreateAuthenticationOptions(rpConfig, sessionID)

Verification phase

var authenticationResponse webauthn.AuthenticationResponseJSON
if err := json.NewDecoder(r.Body).Decode(&authenticationResponse); err != nil {
	http.Error(w, err.Error(), http.StatusBadRequest)
	return
}

param := webauthn.VerifyDiscoverableCredentialAuthenticationParam{
	RPConfig:           rpConfig,
	Challenge:          session.Challenge,
	AllowedCredentials: session.AllowedCredentials,
	UserVerification:   session.UserVerification,
}

webauthnUser, credentialRecord, err := webauthn.VerifyDiscoverableCredentialAuthenticationResponse(
	param,
	discoverUserPasskey,
	authenticationResponse,
	nil,
)

user := ToYourUserModel(webauthnUser)
user.UpdatePasskey(credentialRecord)

// en: discoverUserPasskey is a function that RP should implement to get the passkey associated with the user from your database using credentialRawID and userHandle as keys.
func discoverUserPasskey(credentialRawID []byte, userHandle string) (*webauthn.WebAuthnUser, *webauthn.CredentialRecord, error) {}

Modify registration and authentication options

You can modify registration and authentication options using webauthn.WithUserVerification and webauthn.WithAttestaion.

webauthn.CreateRegistrationCeremonyOptions(
    rpConfig,
    *webauthnUser,
    webauthn.WithAttestationPreference(webauthn.AttestationConveyancePreferenceIndirect)
)

Status

This library's releases are not stable. Therefore, breaking changes may be made without warning.

Support Attestation Statement Format

Attestation Statement Format Supported
none Yes
packed Yes
apple No
android-key No
android-safetynet No
tpm No
fido-u2f No

Client Extensions

Client Extensions are not yet supported.

Documentation

Index

Constants

View Source
const (
	AuthenticatorDataMinSize = 37
)
View Source
const PublicKeyCredentialTypePublicKey = "public-key"

https://www.w3.org/TR/webauthn-3/#enum-credentialType

Variables

This section is empty.

Functions

func CreateAuthenticationOptions

func CreateAuthenticationOptions(rpConfig RPConfig, sessionID []byte, opts ...AuthenticationCeremonyOption) (*PublicKeyCredentialRequestOptions, *Session, error)

func DenyWhenClonedAuthenticator

func DenyWhenClonedAuthenticator(requestSignCount uint32, currentSignCount uint32) (bool, error)

func GenerateChallenge

func GenerateChallenge() (challenge []byte, err error)

func IsValidChallenge

func IsValidChallenge(challenge []byte) bool

func SecureCompare

func SecureCompare(given string, actual string) bool

func SecureCompareByte

func SecureCompareByte(given []byte, actual []byte) bool

func SignatureAlgorithm

func SignatureAlgorithm(coseAlg COSEAlgorithmIdentifier) x509.SignatureAlgorithm

Types

type AndroidKeyAttestationStatementVerifier

type AndroidKeyAttestationStatementVerifier struct{}

func (*AndroidKeyAttestationStatementVerifier) Verify

func (a *AndroidKeyAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type AndroidSafetyNetAttestationStatementVerifier

type AndroidSafetyNetAttestationStatementVerifier struct{}

func (*AndroidSafetyNetAttestationStatementVerifier) Verify

func (a *AndroidSafetyNetAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type AppleAttestationStatementVerifier

type AppleAttestationStatementVerifier struct{}

func (*AppleAttestationStatementVerifier) Verify

func (a *AppleAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type AttestationConveyancePreference

type AttestationConveyancePreference string
const (
	AttestationConveyancePreferenceNone       AttestationConveyancePreference = "none"
	AttestationConveyancePreferenceDirect     AttestationConveyancePreference = "direct"
	AttestationConveyancePreferenceIndirect   AttestationConveyancePreference = "indirect"
	AttestationConveyancePreferenceEnterprise AttestationConveyancePreference = "enterprise"
)

func (AttestationConveyancePreference) IsValid

func (AttestationConveyancePreference) String

type AttestationFormat

type AttestationFormat string

https://www.iana.org/assignments/webauthn/webauthn.xhtml

const (
	// https://www.iana.org/assignments/webauthn/webauthn.xhtml
	// 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 platform authenticators on versions "N", and later, may provide this proprietary "hardware attestation" statement.
	AttestationFormatAndroidKey AttestationFormat = "android-key"

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

	// AttestationFormatFIDOUniversalSecondFactor is used with FIDO U2F authenticators
	AttestationFormatFIDOUniversalSecondFactor AttestationFormat = "fido-u2f"

	// AttestationFormatApple is used with Apple devices' platform authenticators
	AttestationFormatApple AttestationFormat = "apple"

	// AttestationFormatNone 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"
)

type AttestationObject

type AttestationObject struct {
	AuthData     []byte         `cbor:"authData"`
	Format       string         `cbor:"fmt"`
	AttStatement map[string]any `cbor:"attStmt"`
}

type AttestationStatementVerifier

type AttestationStatementVerifier interface {
	// https://www.w3.org/TR/webauthn-3/#sctn-attestation-formats
	Verify() (attestationType string, x509Certs []string, err error)
}

func DetermineAttestaionStatement

func DetermineAttestaionStatement(format string, attStmt map[string]any, authData, hash []byte) (AttestationStatementVerifier, error)

type AttestedCredentialData

type AttestedCredentialData struct {
	AAGUID              []byte `json:"aaguid"`
	CredentialIDLength  uint16 `json:"credential_id_length"`
	CredentialID        []byte `json:"credential_id"`
	CredentialPublicKey []byte `json:"public_key"`
}

https://www.w3.org/TR/webauthn-3/#sctn-attested-credential-data

func (*AttestedCredentialData) DecodeCredentialPublicKey

func (a *AttestedCredentialData) DecodeCredentialPublicKey() (*coseKey, error)

func (*AttestedCredentialData) VerifyCredentialID

func (a *AttestedCredentialData) VerifyCredentialID() error

func (*AttestedCredentialData) VerifyPublicKeyAlgParams

func (a *AttestedCredentialData) VerifyPublicKeyAlgParams(publicKeyCredParams []PublicKeyCredentialParameters) error

type AuthenticationCelemonyVerifier

type AuthenticationCelemonyVerifier interface {
	IsAuthenticationCeremony() bool
	VerifyChallenge(challenge []byte) (bool, error)
	VerifyOrigin(rpOrigins, rpSubFrameOrigins []string) (bool, error)
	VerifyRPID(rpID string) bool
	VerifyUserPresent() bool
	VerifyUserVerified(userVerificationOption UserVerification) bool
	VerifyFlags() (bool, error)
	VerifySignature() (bool, error)
	VerifySignCount() (bool, error)
	VerifyAttestaionObject() (bool, error)

	GetUser() WebAuthnUser
	GetUserCredential() CredentialRecord
	GetAuthenticatorAssertionResponse() AuthenticatorAssertionResponse
	GetClientData() CollectedClientData
}

func NewAuthenticationCelemonyVerifier

func NewAuthenticationCelemonyVerifier(
	responseJSON AuthenticationResponseJSON,
	allowedCredentials []PublicKeyCredentialDescriptor,
	discoveryUserHandler DiscoveryUserHandler,
	opts ...AuthenticatorAssertionResponseVerifierOption,
) (AuthenticationCelemonyVerifier, error)

type AuthenticationCelemonyVerifierFunc

type AuthenticationCelemonyVerifierFunc func(
	responseJSON AuthenticationResponseJSON,
	allowedCredentials []PublicKeyCredentialDescriptor,
	discoveryUserHandler DiscoveryUserHandler,
	opts ...AuthenticatorAssertionResponseVerifierOption,
) (AuthenticationCelemonyVerifier, error)

type AuthenticationCeremonyOption

type AuthenticationCeremonyOption func(*PublicKeyCredentialRequestOptions)

func WithUserVerification

func WithUserVerification(userVerification UserVerification) AuthenticationCeremonyOption

type AuthenticationExtensionsClientInputs

type AuthenticationExtensionsClientInputs struct{}

type AuthenticationExtensionsClientOutputs

type AuthenticationExtensionsClientOutputs struct{}

type AuthenticationExtensionsClientOutputsJSON

type AuthenticationExtensionsClientOutputsJSON struct{}

type AuthenticationResponse

type AuthenticationResponse struct {
	PublicKeyCredential

	Response AuthenticatorAssertionResponse
}

type AuthenticationResponseJSON

type AuthenticationResponseJSON struct {
	PublicKeyCredentialJSON

	Response AuthenticatorAssertionResponseJSON `json:"response"`
}

func (AuthenticationResponseJSON) Parse

type AuthenticatorAssertionResponse

type AuthenticatorAssertionResponse struct {
	AuthenticatorResponse

	AuthenticatorData *AuthenticatorData `json:"authenticatorData"`
	Signature         []byte             `json:"signature"`
	UserHandle        string             `json:"userHandle"`
	AttestationObject *AttestationObject `json:"attestationObject"`
	// contains filtered or unexported fields
}

type AuthenticatorAssertionResponseJSON

type AuthenticatorAssertionResponseJSON struct {
	AuthenticatorResponseJSON

	AuthenticatorData string  `json:"authenticatorData"`
	Signature         string  `json:"signature"`
	UserHandle        string  `json:"userHandle"`
	AttestationObject *string `json:"attestationObject"`
}

https://www.w3.org/TR/webauthn-3/#authenticatorassertionresponse

func (AuthenticatorAssertionResponseJSON) Parse

type AuthenticatorAssertionResponseVerifierOption

type AuthenticatorAssertionResponseVerifierOption func(*authenticationCelemonyVerifier)

type AuthenticatorAttestationResponse

type AuthenticatorAttestationResponse struct {
	AuthenticatorResponse

	AttestationObject AttestationObject
	// contains filtered or unexported fields
}

type AuthenticatorAttestationResponseJSON

type AuthenticatorAttestationResponseJSON struct {
	ClientDataJSON     string   `json:"clientDataJSON"`
	AuthenticatorData  string   `json:"authenticatorData"`
	Transports         []string `json:"transports"`
	PublicKey          string   `json:"publicKey"`
	PublicKeyAlgorithm int64    `json:"publicKeyAlgorithm"`
	AttestationObject  string   `json:"attestationObject"`
}

https://www.w3.org/TR/webauthn-3/#dictdef-authenticatorattestationresponsejson

func (AuthenticatorAttestationResponseJSON) Parse

type AuthenticatorData

type AuthenticatorData struct {
	RPIDHash               []byte                 `json:"rpid"`
	Flags                  AuthenticatorFlags     `json:"flags"`
	SignCount              uint32                 `json:"sign_count"`
	AttestedCredentialData AttestedCredentialData `json:"att_data"`
	Extensions             []byte                 `json:"ext_data"`
}

https://www.w3.org/TR/webauthn-3/#sctn-authenticator-data

func (*AuthenticatorData) Unmarshal

func (a *AuthenticatorData) Unmarshal(data []byte) error

type AuthenticatorFlags

type AuthenticatorFlags byte

https://www.w3.org/TR/webauthn-3/#authdata-flags

const (
	// https://www.w3.org/TR/webauthn-3/#authdata-flags
	FlagUserPresent AuthenticatorFlags = 1 << iota
	FlagRFU1
	FlagUserVerified
	FlagBackupEligible
	FlagBackupState
	FlagRFU2
	FlagAttestedCredentialData
	FlagHasExtensions
)

func (AuthenticatorFlags) HasAttestedCredentialData

func (a AuthenticatorFlags) HasAttestedCredentialData() bool

func (AuthenticatorFlags) HasBackupEligible

func (a AuthenticatorFlags) HasBackupEligible() bool

func (AuthenticatorFlags) HasBackupState

func (a AuthenticatorFlags) HasBackupState() bool

func (AuthenticatorFlags) HasExtensions

func (a AuthenticatorFlags) HasExtensions() bool

func (AuthenticatorFlags) HasUserPresent

func (a AuthenticatorFlags) HasUserPresent() bool

func (AuthenticatorFlags) HasUserVerified

func (a AuthenticatorFlags) HasUserVerified() bool

type AuthenticatorResponse

type AuthenticatorResponse struct {
	ClientDataJSON []byte `json:"clientDataJSON"`
	// contains filtered or unexported fields
}

func (AuthenticatorResponse) GetParsedClientDataJSON

func (a AuthenticatorResponse) GetParsedClientDataJSON() CollectedClientData

type AuthenticatorResponseJSON

type AuthenticatorResponseJSON struct {
	ClientDataJSON string `json:"clientDataJSON"`
}

func (AuthenticatorResponseJSON) Unmarshal

type AuthenticatorSelectionCriteria

type AuthenticatorSelectionCriteria struct {
	AuthenticatorAttachment string           `json:"authenticatorAttachment,omitempty"`
	ResidentKey             string           `json:"residentKey,omitempty"`
	RequireResidentKey      bool             `json:"requireResidentKey,omitempty"`
	UserVerification        UserVerification `json:"userVerification,omitempty"`
}

type AuthenticatorTransport

type AuthenticatorTransport string
const (
	AuthenticatorTransportUSB      AuthenticatorTransport = "usb"
	AuthenticatorTransportNFC      AuthenticatorTransport = "nfc"
	AuthenticatorTransportBLE      AuthenticatorTransport = "ble"
	AuthenticatorTransportHybrid   AuthenticatorTransport = "hybrid"
	AuthenticatorTransportInternal AuthenticatorTransport = "internal"
)

type Base64URLEncodedByte

type Base64URLEncodedByte []byte

func (Base64URLEncodedByte) Decode

func (b Base64URLEncodedByte) Decode() ([]byte, error)

func (Base64URLEncodedByte) String

func (b Base64URLEncodedByte) String() string

type COSEAlgorithmIdentifier

type COSEAlgorithmIdentifier int

https://www.w3.org/TR/webauthn-3/#sctn-alg-identifier

const (
	// AlgRS256 is RSASSA-PKCS1-v1_5 using SHA-256
	AlgRS256 COSEAlgorithmIdentifier = -257
	// AlgHSS_LMS is HSS/LMS hash-based digital signature
	AlgHSS_LMS COSEAlgorithmIdentifier = -46
	// AlgSHAKE256 is SHAKE-256 512-bit Hash Value
	AlgSHAKE256 COSEAlgorithmIdentifier = -45
	// AlgSHA512 is SHA-2 512-bit Hash
	AlgSHA512 COSEAlgorithmIdentifier = -44
	// AlgSHA384 is SHA-2 384-bit Hash
	AlgSHA384 COSEAlgorithmIdentifier = -43
	// AlgRSAESOAEP_SHA512 is RSAES-OAEP w/ SHA-512
	AlgRSAESOAEP_SHA512 COSEAlgorithmIdentifier = -42
	// AlgRSAESOAEP_SHA256 is RSAES-OAEP w/ SHA-256
	AlgRSAESOAEP_SHA256 COSEAlgorithmIdentifier = -41
	// AlgRSAESOAEP_RFC8017_Default_Parameters is RSAES-OAEP w/ SHA-1
	AlgRSAESOAEP_RFC8017_Default_Parameters COSEAlgorithmIdentifier = -40
	// AlgPS512 is RSASSA-PSS w/ SHA-512
	AlgPS512 COSEAlgorithmIdentifier = -39
	// AlgPS384 is RSASSA-PSS w/ SHA-384
	AlgPS384 COSEAlgorithmIdentifier = -38
	// AlgPS256 is RSASSA-PSS w/ SHA-256
	AlgPS256 COSEAlgorithmIdentifier = -37
	// AlgES512 is ECDSA w/ SHA-512
	AlgES512 COSEAlgorithmIdentifier = -36
	// AlgES384 is ECDSA w/ SHA-384
	AlgES384 COSEAlgorithmIdentifier = -35
	// AlgECDH_SS_A256KW is ECDH SS w/ Concat KDF and AES Key Wrap w/ 256-bit key
	AlgECDH_SS_A256KW COSEAlgorithmIdentifier = -34
	// AlgECDH_SS_A192KW is ECDH SS w/ Concat KDF and AES Key Wrap w/ 192-bit key
	AlgECDH_SS_A192KW COSEAlgorithmIdentifier = -33
	// AlgECDH_SS_A128KW is ECDH SS w/ Concat KDF and AES Key Wrap w/ 128-bit key
	AlgECDH_SS_A128KW COSEAlgorithmIdentifier = -32
	// AlgECDH_ES_A256KW is ECDH ES w/ Concat KDF and AES Key Wrap w/ 256-bit key
	AlgECDH_ES_A256KW COSEAlgorithmIdentifier = -31
	// AlgECDH_ES_A192KW is ECDH ES w/ Concat KDF and AES Key Wrap w/ 192-bit key
	AlgECDH_ES_A192KW COSEAlgorithmIdentifier = -30
	// AlgECDH_ES_A128KW is ECDH ES w/ Concat KDF and AES Key Wrap w/ 128-bit key
	AlgECDH_ES_A128KW COSEAlgorithmIdentifier = -29
	// AlgECDH_SS_HKDF_512 is ECDH SS w/ HKDF - generate key directly
	AlgECDH_SS_HKDF_512 COSEAlgorithmIdentifier = -28
	// AlgECDH_SS_HKDF_256 is ECDH SS w/ HKDF - generate key directly
	AlgECDH_SS_HKDF_256 COSEAlgorithmIdentifier = -27
	// AlgECDH_ES_HKDF_512 is ECDH ES w/ HKDF - generate key directly
	AlgECDH_ES_HKDF_512 COSEAlgorithmIdentifier = -26
	// AlgECDH_ES_HKDF_256 is ECDH ES w/ HKDF - generate key directly
	AlgECDH_ES_HKDF_256 COSEAlgorithmIdentifier = -25
	// AlgSHAKE128 is SHAKE-128 256-bit Hash Value
	AlgSHAKE128 COSEAlgorithmIdentifier = -18
	// AlgSHA_512_256 is SHA-2 512-bit Hash truncated to 256-bits
	AlgSHA_512_256 COSEAlgorithmIdentifier = -17
	// AlgSHA_256 is SHA-2 256-bit Hash
	AlgSHA_256 COSEAlgorithmIdentifier = -16
	// Algdirect_HKDF_AES_256 is Shared secret w/ AES-MAC 256-bit key
	Algdirect_HKDF_AES_256 COSEAlgorithmIdentifier = -13
	// Algdirect_HKDF_AES_128 is Shared secret w/ AES-MAC 128-bit key
	Algdirect_HKDF_AES_128 COSEAlgorithmIdentifier = -12
	// Algdirect_HKDF_SHA_512 is Shared secret w/ HKDF and SHA-512
	Algdirect_HKDF_SHA_512 COSEAlgorithmIdentifier = -11
	// Algdirect_HKDF_SHA_256 is Shared secret w/ HKDF and SHA-256
	Algdirect_HKDF_SHA_256 COSEAlgorithmIdentifier = -10
	// AlgEdDSA is EdDSA
	AlgEdDSA COSEAlgorithmIdentifier = -8
	// AlgES256 is ECDSA w/ SHA-256
	AlgES256 COSEAlgorithmIdentifier = -7
	// Algdirect is Direct use of CEK
	Algdirect COSEAlgorithmIdentifier = -6
	// AlgA256KW is AES Key Wrap w/ 256-bit key
	AlgA256KW COSEAlgorithmIdentifier = -5
	// AlgA192KW is AES Key Wrap w/ 192-bit key
	AlgA192KW COSEAlgorithmIdentifier = -4
	// AlgA128KW is AES Key Wrap w/ 128-bit key
	AlgA128KW COSEAlgorithmIdentifier = -3
	// AlgA128GCM is AES-GCM mode w/ 128-bit key, 128-bit tag
	AlgA128GCM COSEAlgorithmIdentifier = 1
	// AlgA192GCM is AES-GCM mode w/ 192-bit key, 128-bit tag
	AlgA192GCM COSEAlgorithmIdentifier = 2
	// AlgA256GCM is AES-GCM mode w/ 256-bit key, 128-bit tag
	AlgA256GCM COSEAlgorithmIdentifier = 3
	// AlgHMAC_256_64 is HMAC w/ SHA-256 truncated to 64 bits
	AlgHMAC_256_64 COSEAlgorithmIdentifier = 4
	// AlgHMAC_256_256 is HMAC w/ SHA-256
	AlgHMAC_256_256 COSEAlgorithmIdentifier = 5
	// AlgHMAC_384_384 is HMAC w/ SHA-384
	AlgHMAC_384_384 COSEAlgorithmIdentifier = 6
	// AlgHMAC_512_512 is HMAC w/ SHA-512
	AlgHMAC_512_512 COSEAlgorithmIdentifier = 7
	// AlgAES_CCM_16_64_128 is AES-CCM mode 128-bit key, 64-bit tag, 13-byte nonce
	AlgAES_CCM_16_64_128 COSEAlgorithmIdentifier = 10
	// AlgAES_CCM_16_64_256 is AES-CCM mode 256-bit key, 64-bit tag, 13-byte nonce
	AlgAES_CCM_16_64_256 COSEAlgorithmIdentifier = 11
	// AlgAES_CCM_64_64_128 is AES-CCM mode 128-bit key, 64-bit tag, 7-byte nonce
	AlgAES_CCM_64_64_128 COSEAlgorithmIdentifier = 12
	// AlgAES_CCM_64_64_256 is AES-CCM mode 256-bit key, 64-bit tag, 7-byte nonce
	AlgAES_CCM_64_64_256 COSEAlgorithmIdentifier = 13
	// AlgAES_MAC_128_64 is AES-MAC 128-bit key, 64-bit tag
	AlgAES_MAC_128_64 COSEAlgorithmIdentifier = 14
	// AlgAES_MAC_256_64 is AES-MAC 256-bit key, 64-bit tag
	AlgAES_MAC_256_64 COSEAlgorithmIdentifier = 15
	// AlgChaCha20_Poly1305 is ChaCha20/Poly1305 w/ 256-bit key, 128-bit tag
	AlgChaCha20_Poly1305 COSEAlgorithmIdentifier = 24
	// AlgAES_MAC_128_128 is AES-MAC 128-bit key, 128-bit tag
	AlgAES_MAC_128_128 COSEAlgorithmIdentifier = 25
	// AlgAES_MAC_256_128 is AES-MAC 256-bit key, 128-bit tag
	AlgAES_MAC_256_128 COSEAlgorithmIdentifier = 26
	// AlgAES_CCM_16_128_128 is AES-CCM mode 128-bit key, 128-bit tag, 13-byte nonce
	AlgAES_CCM_16_128_128 COSEAlgorithmIdentifier = 30
	// AlgAES_CCM_16_128_256 is AES-CCM mode 256-bit key, 128-bit tag, 13-byte nonce
	AlgAES_CCM_16_128_256 COSEAlgorithmIdentifier = 31
	// AlgAES_CCM_64_128_128 is AES-CCM mode 128-bit key, 128-bit tag, 7-byte nonce
	AlgAES_CCM_64_128_128 COSEAlgorithmIdentifier = 32
	// AlgAES_CCM_64_128_256 is AES-CCM mode 256-bit key, 128-bit tag, 7-byte nonce
	AlgAES_CCM_64_128_256 COSEAlgorithmIdentifier = 33
)

https://www.iana.org/assignments/cose/cose.xhtml#algorithms

type COSEKeyType

type COSEKeyType int
const (
	COSEKeyTypeReserved COSEKeyType = iota
	COSEKeyTypeOKP
	COSEKeyTypeEC2
	COSEKeyTypeRSA
	COSEKeyTypeSymmetric
	COSEKeyTypeHSS_LMS
	COSEKeyTypeWalnutDSA
)

https://www.iana.org/assignments/cose/cose.xhtml#key-type

type CollectedClientData

type CollectedClientData struct {
	Type        string `json:"type"`
	Challenge   string `json:"challenge"`
	Origin      string `json:"origin"`
	TopOrigin   string `json:"topOrigin,omitempty"`
	CrossOrigin bool   `json:"crossOrigin,omitempty"`
}

CollectedClientData represents the contextual bindings of both the WebAuthn Relying Party and the client. https://www.w3.org/TR/webauthn-3/#dictionary-client-data

func (*CollectedClientData) IsAuthenticationCeremony

func (c *CollectedClientData) IsAuthenticationCeremony() bool

func (*CollectedClientData) IsRegistrationCelemoney

func (c *CollectedClientData) IsRegistrationCelemoney() bool

func (*CollectedClientData) IsValidOrigin

func (c *CollectedClientData) IsValidOrigin(rpOrigins []string, rpSubFrameOrigins []string) (bool, error)

func (*CollectedClientData) VerifyChallenge

func (c *CollectedClientData) VerifyChallenge(expectChallenge []byte) (bool, error)

type CredentialRecord

type CredentialRecord struct {
	// Recommended
	Type           string
	ID             []byte
	PublicKey      []byte
	SignCount      uint32
	Transports     []string
	UvInitialized  bool
	BackupEligible bool
	BackupState    bool
	// Optional
	AttestationObject         []byte
	AttestationClientDataJSON []byte
}

https://www.w3.org/TR/webauthn-3/#credential-record

func VerifyRegistrationCelemonyResponse

func VerifyRegistrationCelemonyResponse(
	rpConfig RPConfig, session Session, registrationResponse RegistrationResponseJSON, verifierFunc RegistrationCelemonyVerifierFunc,
) (*CredentialRecord, error)

func (*CredentialRecord) GetPublicKey

func (r *CredentialRecord) GetPublicKey() (PublicKeyData, error)

The credential public key encoded in COSE_Key format, using the CTAP2 canonical CBOR encoding form.

func (*CredentialRecord) UpdateState

func (c *CredentialRecord) UpdateState(authenticatorAssertionResponse *AuthenticatorAssertionResponse)

type DiscoveryUserHandler

type DiscoveryUserHandler func(credentialRawID []byte, userHandle string) (*WebAuthnUser, *CredentialRecord, error)

type EC2PublicKeyData

type EC2PublicKeyData struct {
	PublicKeyDataBase

	Curve       int64  `cbor:"-1,keyasint" json:"crv"`
	XCoordinate []byte `cbor:"-2,keyasint" json:"x"`
	YCoordinate []byte `cbor:"-3,keyasint" json:"y"`
}

EC2PublicKeyData represents an Elliptic Curve public key https://datatracker.ietf.org/doc/html/rfc8152#section-8.1 https://datatracker.ietf.org/doc/html/rfc8392#appendix-A.2.3

func (*EC2PublicKeyData) GetAlgorithm

func (p *EC2PublicKeyData) GetAlgorithm() int64

func (*EC2PublicKeyData) GetKeyType

func (p *EC2PublicKeyData) GetKeyType() int64

func (*EC2PublicKeyData) Verify

func (p *EC2PublicKeyData) Verify(data []byte, signature []byte) (bool, error)

type EllipticCurveKey

type EllipticCurveKey int
const (
	EC2P256 EllipticCurveKey
	EC2P384
	EC2P521
	OctetKeyPairX25519
	OctetKeyPairX448
	OctetKeyPairEd25519
	OctetKeyPairEd448
)

https://datatracker.ietf.org/doc/html/rfc8152#section-13.1

type FIDOUniversalSecondFactorAttestationStatementVerifier

type FIDOUniversalSecondFactorAttestationStatementVerifier struct{}

func (*FIDOUniversalSecondFactorAttestationStatementVerifier) Verify

func (f *FIDOUniversalSecondFactorAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type NoneAttestationStatementVerifier

type NoneAttestationStatementVerifier struct{}

https://www.w3.org/TR/webauthn-3/#sctn-none-attestation

func (*NoneAttestationStatementVerifier) Verify

func (n *NoneAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type OKPPublicKeyData

type OKPPublicKeyData struct {
	PublicKeyDataBase

	Curve       int64  `cbor:"-1,keyasint" json:"crv"`
	XCoordinate []byte `cbor:"-2,keyasint" json:"x"`
}

https://datatracker.ietf.org/doc/html/rfc8152#section-13.2

func (*OKPPublicKeyData) GetAlgorithm

func (p *OKPPublicKeyData) GetAlgorithm() int64

func (*OKPPublicKeyData) GetKeyType

func (p *OKPPublicKeyData) GetKeyType() int64

func (*OKPPublicKeyData) Verify

func (p *OKPPublicKeyData) Verify(data []byte, signature []byte) (bool, error)

type PackedAttestationStatementVerifier

type PackedAttestationStatementVerifier struct {
	AttStmt        map[string]any
	AuthData       []byte
	ClientDataHash []byte
}

https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation

func (*PackedAttestationStatementVerifier) Verify

func (p *PackedAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type PublicKeyCredential

type PublicKeyCredential struct {
	ID                      []byte
	RawID                   []byte
	AuthenticatorAttachment string
	ClientExtensionResults  AuthenticationExtensionsClientOutputsJSON
	Type                    string
}

type PublicKeyCredentialCreationOptions

type PublicKeyCredentialCreationOptions struct {
	RP   PublicKeyCredentialRpEntity   `json:"rp"`
	User PublicKeyCredentialUserEntity `json:"user"`

	Challenge        Base64URLEncodedByte            `json:"challenge"`
	PubKeyCredParams []PublicKeyCredentialParameters `json:"pubKeyCredParams,omitempty"`

	Timeout                int64                                `json:"timeout,omitempty"`
	ExcludeCredentials     []PublicKeyCredentialDescriptor      `json:"excludeCredentials,omitempty"`
	AuthenticatorSelection AuthenticatorSelectionCriteria       `json:"authenticatorSelection,omitempty"`
	Hints                  []string                             `json:"hints,omitempty"`
	Attestation            AttestationConveyancePreference      `json:"attestation,omitempty"`
	AttestationFormats     []string                             `json:"attestationFormats,omitempty"`
	Extensions             AuthenticationExtensionsClientInputs `json:"extensions,omitempty"`
}

type PublicKeyCredentialDescriptor

type PublicKeyCredentialDescriptor struct {
	Type       string   `json:"type"`
	ID         []byte   `json:"id"`
	Transports []string `json:"transports,omitempty"`
}

type PublicKeyCredentialEntity

type PublicKeyCredentialEntity struct {
	Name string `json:"name"`
}

type PublicKeyCredentialJSON

type PublicKeyCredentialJSON struct {
	ID                      string                                    `json:"id"`
	RawID                   string                                    `json:"rawId"`
	AuthenticatorAttachment string                                    `json:"authenticatorAttachment"`
	ClientExtensionResults  AuthenticationExtensionsClientOutputsJSON `json:"clientExtensionResults"`
	Type                    string                                    `json:"type"`
}

func (PublicKeyCredentialJSON) Parse

type PublicKeyCredentialParameters

type PublicKeyCredentialParameters struct {
	Type string                  `json:"type"`
	Alg  COSEAlgorithmIdentifier `json:"alg"`
}

type PublicKeyCredentialRequestOptions

type PublicKeyCredentialRequestOptions struct {
	Challenge Base64URLEncodedByte `json:"challenge"`
	Timeout   int64                `json:"timeout,omitempty"`

	RPID               string                               `json:"rpId"`
	AlloedCredentials  []PublicKeyCredentialDescriptor      `json:"allowCredentials,omitempty"`
	UserVerification   UserVerification                     `json:"userVerification,omitempty"`
	Hints              []string                             `json:"hints,omitempty"`
	Attestation        AttestationConveyancePreference      `json:"attestation,omitempty" default:"none"`
	AttestationFormats []string                             `json:"attestationFormats,omitempty"`
	Extensions         AuthenticationExtensionsClientInputs `json:"extensions,omitempty"`
}

https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialrequestoptions

func (PublicKeyCredentialRequestOptions) IsValid

type PublicKeyCredentialRpEntity

type PublicKeyCredentialRpEntity struct {
	PublicKeyCredentialEntity

	ID string `json:"id"`
}

type PublicKeyCredentialUserEntity

type PublicKeyCredentialUserEntity struct {
	ID          []byte `json:"id"`
	Name        string `json:"name"`
	DisplayName string `json:"displayName"`
}

type PublicKeyData

type PublicKeyData interface {
	Verify(data []byte, signature []byte) (bool, error)
	GetKeyType() int64
	GetAlgorithm() int64
}

func ParsePublicKey

func ParsePublicKey(publicKey []byte) (PublicKeyData, error)

type PublicKeyDataBase

type PublicKeyDataBase struct {
	// https://datatracker.ietf.org/doc/html/rfc8152#section-13
	KeyType   int64 `cbor:"1,keyasint" json:"kty"` // required
	Algorithm int64 `cbor:"3,keyasint" json:"alg"` // required
}

publicKeyData represents a COSE_Key object https://datatracker.ietf.org/doc/html/rfc8152#section-13

type RPConfig

type RPConfig struct {
	ID              string
	Name            string
	Origins         []string
	SubFrameOrigins []string
}

type RegistrationCelemonyVerifier

type RegistrationCelemonyVerifier interface {
	VerifyChallenge(challenge []byte) (bool, error)
	VerifyOrigin(rpOrigins, rpSubFrameOrigins []string) (bool, error)
	VerifyRPID(rpID string) (bool, error)
	VerifyAuthenticatorDataFlags(userVerification UserVerification) (bool, error)
	VerifyPublicKeyAlgParams(params []PublicKeyCredentialParameters) (bool, error)
	VerifyAttestationStatement() (bool, error)

	AuthenticatorData() AuthenticatorData
	Response() AuthenticatorAttestationResponse
	ClientDataJSON() CollectedClientData
	AttestationObject() AttestationObject
}

func NewRegistrationCelemonyVerifier

func NewRegistrationCelemonyVerifier(registrationResponse RegistrationResponseJSON) (RegistrationCelemonyVerifier, error)

type RegistrationCelemonyVerifierFunc

type RegistrationCelemonyVerifierFunc func(registrationResponse RegistrationResponseJSON) (RegistrationCelemonyVerifier, error)

type RegistrationCeremonyOption

type RegistrationCeremonyOption func(*PublicKeyCredentialCreationOptions)

func WithAuthenticatorSelection

func WithAuthenticatorSelection(authenticatorSelectionCriteria AuthenticatorSelectionCriteria) RegistrationCeremonyOption

type RegistrationResponse

type RegistrationResponse struct {
	ID                      string
	RawID                   string
	Response                AuthenticatorAttestationResponse
	ClientDataJSON          CollectedClientData
	AttestationObject       AttestationObject
	AuthenticatorData       AuthenticatorData
	AuthenticatorAttachment string
	ClientExtensionResults  AuthenticationExtensionsClientOutputsJSON
	Type                    string
	RawResponse             RegistrationResponseJSON
}

type RegistrationResponseJSON

type RegistrationResponseJSON struct {
	ID                      string                                    `json:"id"`
	RawID                   string                                    `json:"rawId"`
	Response                AuthenticatorAttestationResponseJSON      `json:"response"`
	AuthenticatorAttachment string                                    `json:"authenticatorAttachment"`
	ClientExtensionResults  AuthenticationExtensionsClientOutputsJSON `json:"clientExtensionResults"`
	Type                    string                                    `json:"type"`
}

func (RegistrationResponseJSON) Parse

type RelyingParty

type RelyingParty struct {
	RPConfig *RPConfig
}

func NewRelyingParty

func NewRelyingParty(rp *RPConfig) *RelyingParty

type Session

type Session struct {
	// ID is a unique identifier for the session.
	ID []byte
	// Challenge is a non-guessable value to prevent reply attacks.
	// MUST be randomly generated by Relying Parties in an environment they trust (e.g., on the server-side),
	// and the returned challenge value in the client’s response MUST match what was generated.
	// In order to prevent replay attacks, the challenges MUST contain enough entropy to
	// make guessing them infeasible. Challenges SHOULD therefore be at least 16 bytes long.
	Challenge []byte
	// RPID is the Relying Party identifier.
	RPID string
	// UserVerification is the user verification requirement.
	// valid values are "required", "preferred", "discouraged"
	UserVerification UserVerification

	// AllowedCredentials is an OPTIONAL member,
	// used by the client to find qualified authenticators for this authentication ceremony.
	// If the user account is identified during authentication,
	// the credentials of the user account should be listed for this member.
	// more details: https://www.w3.org/TR/webauthn-3/#dom-publickeycredentialrequestoptions-allowcredentials
	AllowedCredentials []PublicKeyCredentialDescriptor
}

func NewWebAuthnSession

func NewWebAuthnSession(id, challenge []byte, rpid string, userVerification UserVerification, allowedCredentials []PublicKeyCredentialDescriptor) (*Session, error)

type SignCountVerifier

type SignCountVerifier func(requestSignCount uint32, currentSignCount uint32) (bool, error)

type TPMAttestationStatementVerifier

type TPMAttestationStatementVerifier struct{}

func (*TPMAttestationStatementVerifier) Verify

func (t *TPMAttestationStatementVerifier) Verify() (attestationType string, x509Certs []string, err error)

type UserVerification

type UserVerification string
const (
	UserVerificationRequired    UserVerification = "required"
	UserVerificationPreferred   UserVerification = "preferred"
	UserVerificationDiscouraged UserVerification = "discouraged"
)

func (UserVerification) IsDiscouraged

func (uv UserVerification) IsDiscouraged() bool

func (UserVerification) IsPreferred

func (uv UserVerification) IsPreferred() bool

func (UserVerification) IsRequired

func (uv UserVerification) IsRequired() bool

func (UserVerification) IsValid

func (uv UserVerification) IsValid() bool

func (UserVerification) String

func (uv UserVerification) String() string

type VerifyDiscoverableCredentialAuthenticationParam

type VerifyDiscoverableCredentialAuthenticationParam struct {
	RPConfig           RPConfig
	Challenge          []byte
	AllowedCredentials []PublicKeyCredentialDescriptor
	UserVerification   UserVerification
}

type WebAuthnUser

type WebAuthnUser struct {
	ID          []byte
	Name        string
	DisplayName string
	Credentials []CredentialRecord
}

Directories

Path Synopsis
example
simple Module

Jump to

Keyboard shortcuts

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