Documentation
¶
Overview ¶
Package webauthn is a pure-Go (CGO=0), MRI-faithful reimplementation of the Ruby webauthn gem — the WebAuthn / passkeys relying-party library.
It mirrors the gem's surface: a RelyingParty (the gem's WebAuthn::RelyingParty / WebAuthn::Configuration) builds ceremony options with RelyingParty.OptionsForCreate and RelyingParty.OptionsForGet, and verifies client responses via RelyingParty.FromCreate / RegistrationCredential.Verify (registration) and RelyingParty.FromGet / AuthenticationCredential.Verify (authentication). Failures surface as the Error tree that mirrors WebAuthn::Error and its subclasses (ChallengeVerificationError, OriginVerificationError, SignatureVerificationError, SignCountVerificationError, AttestationStatementVerificationError, …).
The heavy lifting — CBOR decoding, COSE key parsing, attestation-format verification (packed, fido-u2f, none, tpm, android-key, apple, …) and signature checks — is delegated to the pure-Go github.com/go-webauthn/webauthn library; this package supplies the gem-shaped orchestration and error mapping on top. All verification is endianness- and timezone-independent and builds with CGO disabled on every supported 64-bit target, including the big-endian s390x.
Index ¶
- Constants
- Variables
- type AuthenticationCredential
- type AuthenticatorAssertionResponse
- type AuthenticatorAttestationResponse
- type CreateOptions
- type Error
- type GetOptions
- type PublicKey
- type RegistrationCredential
- func (c *RegistrationCredential) AttestationFormat() string
- func (c *RegistrationCredential) AttestationType() string
- func (c *RegistrationCredential) ID() []byte
- func (c *RegistrationCredential) PublicKey() *PublicKey
- func (c *RegistrationCredential) Response() *AuthenticatorAttestationResponse
- func (c *RegistrationCredential) SignCount() uint32
- func (c *RegistrationCredential) Verify(expectedChallenge []byte, opts ...VerifyOption) error
- type RelyingParty
- func (rp *RelyingParty) FromCreate(clientResponse []byte) (*RegistrationCredential, error)
- func (rp *RelyingParty) FromGet(clientResponse []byte) (*AuthenticationCredential, error)
- func (rp *RelyingParty) OptionsForCreate(opts CreateOptions) (*protocol.PublicKeyCredentialCreationOptions, error)
- func (rp *RelyingParty) OptionsForGet(opts GetOptions) (*protocol.PublicKeyCredentialRequestOptions, error)
- type User
- type VerifyOption
Constants ¶
const DefaultChallengeLength = 32
DefaultChallengeLength is the number of random bytes used for a ceremony challenge when the caller does not supply one, matching the webauthn gem's default (WebAuthn.configuration.encoding aside, 32 bytes of entropy).
Variables ¶
var ( // ErrWebAuthn is the root of the tree, corresponding to WebAuthn::Error. // Every other sentinel reports true for errors.Is against a value produced // from the same class only; use the specific sentinels to discriminate. ErrWebAuthn = &Error{class: "Error", msg: "webauthn error"} // ChallengeVerificationError is raised when the challenge echoed back in the // client data does not match the challenge the relying party issued. ChallengeVerificationError = &Error{class: "ChallengeVerificationError", msg: "challenge verification failed"} // OriginVerificationError is raised when the client data origin does not // match the relying party origin. OriginVerificationError = &Error{class: "OriginVerificationError", msg: "origin verification failed"} // TypeVerificationError is raised when the client data type is not the value // expected for the ceremony (webauthn.create or webauthn.get). TypeVerificationError = &Error{class: "TypeVerificationError", msg: "type verification failed"} // RpIdVerificationError is raised when the RP ID hash in the authenticator // data does not match the SHA-256 of the relying party ID. RpIdVerificationError = &Error{class: "RpIdVerificationError", msg: "RP ID hash verification failed"} // UserPresenceVerificationError is raised when the user-present flag is not // set in the authenticator data. UserPresenceVerificationError = &Error{class: "UserPresenceVerificationError", msg: "user presence verification failed"} // UserVerificationError is raised when user verification was required but the // user-verified flag is not set in the authenticator data. UserVerificationError = &Error{class: "UserVerificationError", msg: "user verification failed"} // SignatureVerificationError is raised when the assertion signature does not // verify against the stored credential public key. SignatureVerificationError = &Error{class: "SignatureVerificationError", msg: "signature verification failed"} // SignCountVerificationError is raised when the authenticator sign count did // not increase relative to the stored value (a possible cloned credential). SignCountVerificationError = &Error{class: "SignCountVerificationError", msg: "sign count verification failed"} // AttestationStatementVerificationError is raised when the attestation // statement in a registration response fails verification. AttestationStatementVerificationError = &Error{class: "AttestationStatementVerificationError", msg: "attestation statement verification failed"} // AuthenticatorDataVerificationError is raised when the authenticator data is // malformed or too short to be parsed. AuthenticatorDataVerificationError = &Error{class: "AuthenticatorDataVerificationError", msg: "authenticator data verification failed"} // ClientDataMissingError is raised when the client response could not be // parsed into a well-formed credential. ClientDataMissingError = &Error{class: "ClientDataMissingError", msg: "client data missing or malformed"} )
The exported sentinels mirror WebAuthn::Error and its subclasses. Wrap them with fmt.Errorf("%w", …) checks via errors.Is(err, ChallengeVerificationError) and friends.
Functions ¶
This section is empty.
Types ¶
type AuthenticationCredential ¶
type AuthenticationCredential struct {
// contains filtered or unexported fields
}
AuthenticationCredential mirrors the object returned by WebAuthn::Credential.from_get. Call Verify with the stored credential public key and sign count to validate the assertion.
func (*AuthenticationCredential) ID ¶
func (c *AuthenticationCredential) ID() []byte
ID returns the raw credential ID from the assertion.
func (*AuthenticationCredential) Response ¶
func (c *AuthenticationCredential) Response() *AuthenticatorAssertionResponse
Response returns the decoded assertion response.
func (*AuthenticationCredential) SignCount ¶
func (c *AuthenticationCredential) SignCount() uint32
SignCount returns the sign count reported by the authenticator in the verified assertion. Persist it as the new stored sign count.
func (*AuthenticationCredential) Verify ¶
func (c *AuthenticationCredential) Verify(expectedChallenge, publicKey []byte, storedSignCount uint32, opts ...VerifyOption) error
Verify mirrors AuthenticatorAssertionResponse#verify(expected_challenge, public_key:, sign_count:). It checks the client data type, challenge, origin, RP ID hash and user flags, verifies the assertion signature against the stored COSE public key, and enforces the sign-count regression rule. storedSignCount is the sign count persisted at registration (or the previous assertion).
type AuthenticatorAssertionResponse ¶
type AuthenticatorAssertionResponse struct {
// contains filtered or unexported fields
}
AuthenticatorAssertionResponse mirrors WebAuthn::AuthenticatorAssertionResponse: the authenticator's answer to an authentication ceremony (authenticatorData, signature and clientDataJSON), already decoded.
func (*AuthenticatorAssertionResponse) AuthenticatorData ¶
func (r *AuthenticatorAssertionResponse) AuthenticatorData() []byte
AuthenticatorData returns the raw authenticatorData bytes.
func (*AuthenticatorAssertionResponse) ClientDataJSON ¶
func (r *AuthenticatorAssertionResponse) ClientDataJSON() []byte
ClientDataJSON returns the raw clientDataJSON bytes.
func (*AuthenticatorAssertionResponse) Signature ¶
func (r *AuthenticatorAssertionResponse) Signature() []byte
Signature returns the raw assertion signature bytes.
type AuthenticatorAttestationResponse ¶
type AuthenticatorAttestationResponse struct {
// contains filtered or unexported fields
}
AuthenticatorAttestationResponse mirrors WebAuthn::AuthenticatorAttestationResponse: the authenticator's answer to a registration ceremony (attestationObject and clientDataJSON), already decoded.
func (*AuthenticatorAttestationResponse) AttestationObject ¶
func (r *AuthenticatorAttestationResponse) AttestationObject() []byte
AttestationObject returns the raw CBOR attestationObject bytes.
func (*AuthenticatorAttestationResponse) ClientDataJSON ¶
func (r *AuthenticatorAttestationResponse) ClientDataJSON() []byte
ClientDataJSON returns the raw clientDataJSON bytes.
type CreateOptions ¶
type CreateOptions struct {
// User is the account the credential is being created for.
User User
// Exclude is the list of existing credential IDs to place in
// excludeCredentials so the authenticator refuses to re-register.
Exclude [][]byte
// AuthenticatorSelection constrains the authenticators the client may use.
AuthenticatorSelection *protocol.AuthenticatorSelection
// UserVerification sets authenticatorSelection.userVerification when
// AuthenticatorSelection is nil.
UserVerification protocol.UserVerificationRequirement
// Attestation is the attestation conveyance preference (none, indirect,
// direct, enterprise).
Attestation protocol.ConveyancePreference
// Challenge, when non-empty, is used verbatim instead of a fresh random
// challenge. Supply it to make a ceremony deterministic.
Challenge []byte
}
CreateOptions are the inputs to OptionsForCreate, mirroring the keyword arguments of WebAuthn::Credential.options_for_create.
type Error ¶
type Error struct {
// contains filtered or unexported fields
}
Error is the common type for every error raised by this package. It mirrors the exception tree of Ruby's webauthn gem, where every error descends from WebAuthn::Error. The Class method returns the Ruby class name of the corresponding exception (for example "ChallengeVerificationError"), and errors.Is matches an error against one of the exported sentinels regardless of any wrapped cause or contextual message.
type GetOptions ¶
type GetOptions struct {
// Allow is the list of credential IDs to place in allowCredentials.
Allow [][]byte
// UserVerification sets the userVerification requirement.
UserVerification protocol.UserVerificationRequirement
// Challenge, when non-empty, is used verbatim instead of a fresh random
// challenge.
Challenge []byte
}
GetOptions are the inputs to OptionsForGet, mirroring the keyword arguments of WebAuthn::Credential.options_for_get.
type PublicKey ¶
type PublicKey struct {
// contains filtered or unexported fields
}
PublicKey mirrors WebAuthn::PublicKey: a thin wrapper over a COSE_Key encoded credential public key. It exposes the raw COSE bytes (what a relying party stores next to a credential) and can verify a signature over arbitrary data, delegating the COSE/CBOR decoding and the EC2/RSA/OKP signature checks to go-webauthn's webauthncose package.
func NewPublicKey ¶
NewPublicKey decodes a COSE_Key encoded credential public key. It returns an error wrapping UnsupportedKey semantics when the bytes are not a valid COSE key of a supported type.
type RegistrationCredential ¶
type RegistrationCredential struct {
// contains filtered or unexported fields
}
RegistrationCredential mirrors the object returned by WebAuthn::Credential.from_create. Call Verify to validate the attestation against the relying party; afterwards the credential ID, public key and sign count are available.
func (*RegistrationCredential) AttestationFormat ¶
func (c *RegistrationCredential) AttestationFormat() string
AttestationFormat returns the attestation statement format (e.g. "none", "packed", "fido-u2f").
func (*RegistrationCredential) AttestationType ¶
func (c *RegistrationCredential) AttestationType() string
AttestationType returns the attestation trust type reported by the verifier (e.g. "none", "basic_full", "basic_surrogate").
func (*RegistrationCredential) ID ¶
func (c *RegistrationCredential) ID() []byte
ID returns the raw credential ID. It is only populated after a successful Verify.
func (*RegistrationCredential) PublicKey ¶
func (c *RegistrationCredential) PublicKey() *PublicKey
PublicKey returns the credential's COSE public key wrapper. It is only populated after a successful Verify.
func (*RegistrationCredential) Response ¶
func (c *RegistrationCredential) Response() *AuthenticatorAttestationResponse
Response returns the decoded attestation response.
func (*RegistrationCredential) SignCount ¶
func (c *RegistrationCredential) SignCount() uint32
SignCount returns the initial authenticator sign count.
func (*RegistrationCredential) Verify ¶
func (c *RegistrationCredential) Verify(expectedChallenge []byte, opts ...VerifyOption) error
Verify mirrors AuthenticatorAttestationResponse#verify(expected_challenge). It checks, in order, the client data type, the challenge, the origin, the RP ID hash and the user-presence/verification flags, then delegates attestation statement verification (packed / fido-u2f / none / …) to go-webauthn. On success the credential ID, public key and sign count are populated.
type RelyingParty ¶
type RelyingParty struct {
// Origin is the fully-qualified origin the browser reports, e.g.
// "https://example.com".
Origin string
// Name is the human-palatable relying party name shown to the user.
Name string
// ID is the RP ID, an effective domain such as "example.com".
ID string
// Algorithms is the ordered list of acceptable COSE algorithm names offered
// in pubKeyCredParams. When empty the gem defaults ES256, PS256 and RS256
// are used.
Algorithms []string
// Timeout, when non-zero, is echoed into the ceremony options in
// milliseconds.
Timeout int
}
RelyingParty mirrors WebAuthn::RelyingParty / WebAuthn::Configuration. It carries the identity of the relying party (origin, name and RP ID) plus the list of acceptable COSE algorithms, and is the entry point for building ceremony options and verifying client responses.
Construct one with NewRelyingParty:
rp := webauthn.NewRelyingParty("https://example.com", "Example", "example.com")
func NewRelyingParty ¶
func NewRelyingParty(origin, name, id string) *RelyingParty
NewRelyingParty builds a RelyingParty with the default algorithm set.
func (*RelyingParty) FromCreate ¶
func (rp *RelyingParty) FromCreate(clientResponse []byte) (*RegistrationCredential, error)
FromCreate mirrors WebAuthn::Credential.from_create: it parses the JSON client response produced by navigator.credentials.create() into a RegistrationCredential bound to this relying party. It does not yet verify the attestation; call Verify for that.
func (*RelyingParty) FromGet ¶
func (rp *RelyingParty) FromGet(clientResponse []byte) (*AuthenticationCredential, error)
FromGet mirrors WebAuthn::Credential.from_get: it parses the JSON client response produced by navigator.credentials.get() into an AuthenticationCredential bound to this relying party.
func (*RelyingParty) OptionsForCreate ¶
func (rp *RelyingParty) OptionsForCreate(opts CreateOptions) (*protocol.PublicKeyCredentialCreationOptions, error)
OptionsForCreate mirrors WebAuthn::Credential.options_for_create: it returns a PublicKeyCredentialCreationOptions carrying the challenge, relying party, user and pubKeyCredParams that the browser passes to navigator.credentials.create(). The returned challenge is the value to store and later hand to RegistrationCredential.Verify.
func (*RelyingParty) OptionsForGet ¶
func (rp *RelyingParty) OptionsForGet(opts GetOptions) (*protocol.PublicKeyCredentialRequestOptions, error)
OptionsForGet mirrors WebAuthn::Credential.options_for_get: it returns a PublicKeyCredentialRequestOptions carrying the challenge, RP ID and allowCredentials for navigator.credentials.get().
type User ¶
User mirrors the user account passed to WebAuthn::Credential.options_for_create (a PublicKeyCredentialUserEntity). ID is the opaque user handle.
type VerifyOption ¶
type VerifyOption func(*verifyConfig)
VerifyOption tunes a call to RegistrationCredential.Verify or AuthenticationCredential.Verify, mirroring the optional keyword arguments of the webauthn gem's #verify methods.
func RequireUserVerification ¶
func RequireUserVerification() VerifyOption
RequireUserVerification asserts that the authenticator set the user-verified (UV) flag, mirroring passing user_verification: true to the gem.