# frozen_string_literal: true require 'webauthn/challenge_generator' require 'webauthn/security_key_base_validation_service' require 'webauthn/security_key_registration_service' require 'webauthn/security_key_authentication_service' module Webauthn ACCEPTABLE_REGISTRATION_TYPE = "webauthn.create" ACCEPTABLE_AUTHENTICATION_TYPE = "webauthn.get" # -7 - ES256 # -257 - RS256 (Windows Hello supported alg.) SUPPORTED_ALGORITHMS = COSE::Algorithm.registered_algorithm_ids.freeze VALID_ATTESTATION_FORMATS = ['none', 'packed', 'fido-u2f'].freeze class SecurityKeyError < StandardError; end class InvalidOriginError < SecurityKeyError; end class InvalidRelyingPartyIdError < SecurityKeyError; end class UserVerificationError < SecurityKeyError; end class ChallengeMismatchError < SecurityKeyError; end class InvalidTypeError < SecurityKeyError; end class UnsupportedPublicKeyAlgorithmError < SecurityKeyError; end class UnsupportedAttestationFormatError < SecurityKeyError; end class CredentialIdInUseError < SecurityKeyError; end class MalformedAttestationError < SecurityKeyError; end class NotFoundError < SecurityKeyError; end class OwnershipError < SecurityKeyError; end class PublicKeyError < SecurityKeyError; end class UnknownCOSEAlgorithmError < SecurityKeyError; end ## # Usage: # # These methods should be used in controllers where we # are challenging the user that has a security key, and # they must respond with a valid webauthn response and # credentials. def self.stage_challenge(user, secure_session) ::Webauthn::ChallengeGenerator.generate.commit_to_session(secure_session, user) end def self.allowed_credentials(user, secure_session) return {} if !user.security_keys_enabled? credential_ids = user.second_factor_security_key_credential_ids { allowed_credential_ids: credential_ids, challenge: secure_session[ Webauthn::ChallengeGenerator::ChallengeSession.session_challenge_key(user) ] } end def self.rp_id(user, secure_session) secure_session[Webauthn::ChallengeGenerator::ChallengeSession.session_rp_id_key(user)] end def self.rp_name(user, secure_session) secure_session[Webauthn::ChallengeGenerator::ChallengeSession.session_rp_name_key(user)] end def self.challenge(user, secure_session) secure_session[Webauthn::ChallengeGenerator::ChallengeSession.session_challenge_key(user)] end end