017bcc9ce1
- Fix indentation - Split awkward initializer into separate methods - Rename credentials to passkeys - Simplify authenticator registry loading - Flatten nested errors under ActionPack::WebAuthn - Set passkey current params only requests that use it - Inline anemic methods - Replace custom validation with ActiveModel::Validation - Rename identity to holder in Passkey - Rename credentials to passkeys in JS - Extract framework library out of controllers - Pass params hashes down to ActionPack - Attempt to simplify public interface - Push data decoding down to the classes representing the data - Introduce has_passkeys - Add CBOR bigint support - Rename ActionPack::WebAuthn::Passkey to ActionPack::Passkey - Add create_passkey_button helper - Rename public-key to creation-options - Add sign_in_with_passkey_button helper - Dispatch events for the whole Passkey lifecycle - Add ED25519 support - Prevent crash on missing meta tag - Validate resident key options - Don't clobber existing ActionPack config options - Validate cryptographic params - Move CurrentWebAuthnRequest into ActionPack::Passkey - Use ActiveModel::Attributes for Options objects - Implement expiring challanges - Add lifecycle events - Extract param helpers into Request - Add passkey_creation_options and passkey_request_options helpers - Add create_passkey_challenge to make it easier to override the create method if needed - Prefix all view helpers with passkey_ - Auto-include ActionPack::Passkey::Holder - Make the passkey challange url configurable - Add a reminder about Passkeys to the magic link email
74 lines
2.4 KiB
Ruby
74 lines
2.4 KiB
Ruby
# = Action Pack WebAuthn Attestation
|
|
#
|
|
# Decodes and represents the attestation object returned by an authenticator
|
|
# during registration. The attestation object is CBOR-encoded and contains
|
|
# the authenticator data along with an optional attestation statement.
|
|
#
|
|
# == Usage
|
|
#
|
|
# attestation = ActionPack::WebAuthn::Authenticator::Attestation.decode(
|
|
# attestation_object_bytes
|
|
# )
|
|
#
|
|
# attestation.credential_id # => "abc123..."
|
|
# attestation.public_key # => OpenSSL::PKey::EC
|
|
# attestation.sign_count # => 0
|
|
#
|
|
# == Attributes
|
|
#
|
|
# [+authenticator_data+]
|
|
# The parsed Data containing credential information.
|
|
#
|
|
# [+format+]
|
|
# The attestation statement format (e.g., "none", "packed", "fido-u2f").
|
|
#
|
|
# [+attestation_statement+]
|
|
# The attestation statement, which may contain a signature from the
|
|
# authenticator manufacturer. Empty for "none" format.
|
|
#
|
|
# == Delegated Methods
|
|
#
|
|
# The following methods are delegated to +authenticator_data+:
|
|
#
|
|
# * +credential_id+ - Base64URL-encoded credential identifier
|
|
# * +public_key+ - OpenSSL public key object
|
|
# * +public_key_bytes+ - Raw COSE key bytes
|
|
# * +sign_count+ - Signature counter for replay detection
|
|
#
|
|
class ActionPack::WebAuthn::Authenticator::Attestation
|
|
attr_reader :authenticator_data, :format, :attestation_statement
|
|
|
|
delegate :credential_id, :public_key, :public_key_bytes, :sign_count, :aaguid, :backed_up?, to: :authenticator_data
|
|
|
|
# Wraps raw attestation data into an Attestation instance. Accepts an
|
|
# existing Attestation object (returned as-is), a Base64URL-encoded string,
|
|
# or raw binary.
|
|
def self.wrap(data)
|
|
if data.is_a?(self)
|
|
data
|
|
else
|
|
data = Base64.urlsafe_decode64(data) unless data.encoding == Encoding::BINARY
|
|
decode(data)
|
|
end
|
|
rescue ArgumentError
|
|
raise ActionPack::WebAuthn::InvalidResponseError, "Invalid base64 encoding in attestation object"
|
|
end
|
|
|
|
# Decodes a CBOR-encoded attestation object into an Attestation instance.
|
|
def self.decode(bytes)
|
|
cbor = ActionPack::WebAuthn::CborDecoder.decode(bytes)
|
|
|
|
new(
|
|
authenticator_data: ActionPack::WebAuthn::Authenticator::Data.decode(cbor["authData"]),
|
|
format: cbor["fmt"],
|
|
attestation_statement: cbor["attStmt"]
|
|
)
|
|
end
|
|
|
|
def initialize(authenticator_data:, format:, attestation_statement:)
|
|
@authenticator_data = authenticator_data
|
|
@format = format
|
|
@attestation_statement = attestation_statement
|
|
end
|
|
end
|