Add a purpose to challanges
This commit is contained in:
@@ -28,14 +28,19 @@ class ActionPack::Passkey::ChallengesController < ActionController::Base
|
||||
private
|
||||
def create_passkey_challenge
|
||||
ActionPack::WebAuthn::PublicKeyCredential::Options.new(
|
||||
challenge_expiration: challenge_expiration
|
||||
challenge_expiration: challenge_expiration,
|
||||
challenge_purpose: challenge_purpose
|
||||
).challenge
|
||||
end
|
||||
|
||||
def challenge_purpose
|
||||
params[:purpose] == "registration" ? "registration" : "authentication"
|
||||
end
|
||||
|
||||
def challenge_expiration
|
||||
config = Rails.configuration.action_pack.web_authn
|
||||
|
||||
if params[:purpose] == "registration"
|
||||
if challenge_purpose == "registration"
|
||||
config.creation_challenge_expiration
|
||||
else
|
||||
config.request_challenge_expiration
|
||||
|
||||
@@ -47,6 +47,10 @@ class ActionPack::WebAuthn::Authenticator::AssertionResponse < ActionPack::WebAu
|
||||
end
|
||||
|
||||
private
|
||||
def challenge_purpose
|
||||
"authentication"
|
||||
end
|
||||
|
||||
def client_data_type_must_be_get
|
||||
unless client_data["type"] == "webauthn.get"
|
||||
errors.add(:base, "Client data type is not webauthn.get")
|
||||
|
||||
@@ -49,6 +49,10 @@ class ActionPack::WebAuthn::Authenticator::AttestationResponse < ActionPack::Web
|
||||
end
|
||||
|
||||
private
|
||||
def challenge_purpose
|
||||
"registration"
|
||||
end
|
||||
|
||||
def client_data_type_must_be_create
|
||||
unless client_data["type"] == "webauthn.create"
|
||||
errors.add(:base, "Client data type is not webauthn.create")
|
||||
|
||||
@@ -85,13 +85,17 @@ class ActionPack::WebAuthn::Authenticator::Response
|
||||
|
||||
signed_message = Base64.urlsafe_decode64(client_data["challenge"])
|
||||
|
||||
unless ActionPack::WebAuthn.challenge_verifier.verified(signed_message)
|
||||
unless ActionPack::WebAuthn.challenge_verifier.verified(signed_message, purpose: challenge_purpose)
|
||||
errors.add(:base, "Challenge has expired")
|
||||
end
|
||||
rescue ArgumentError
|
||||
errors.add(:base, "Challenge is invalid")
|
||||
end
|
||||
|
||||
def challenge_purpose
|
||||
nil
|
||||
end
|
||||
|
||||
def origin_must_match
|
||||
if origin.blank?
|
||||
errors.add(:base, "Origin missing")
|
||||
|
||||
@@ -53,6 +53,7 @@ class ActionPack::WebAuthn::PublicKeyCredential::CreationOptions < ActionPack::W
|
||||
attribute :exclude_credentials, default: -> { [] }
|
||||
attribute :attestation, default: :none
|
||||
attribute :challenge_expiration, default: -> { Rails.configuration.action_pack.web_authn.creation_challenge_expiration }
|
||||
attribute :challenge_purpose, default: "registration"
|
||||
|
||||
validates :id, :name, :display_name, presence: true
|
||||
validates :resident_key, inclusion: { in: RESIDENT_KEY_OPTIONS }
|
||||
|
||||
@@ -36,6 +36,7 @@ class ActionPack::WebAuthn::PublicKeyCredential::Options
|
||||
attribute :user_verification, default: :preferred
|
||||
attribute :relying_party, default: -> { ActionPack::WebAuthn.relying_party }
|
||||
attribute :challenge_expiration
|
||||
attribute :challenge_purpose
|
||||
|
||||
validates :user_verification, inclusion: { in: USER_VERIFICATION_OPTIONS }
|
||||
|
||||
@@ -70,7 +71,8 @@ class ActionPack::WebAuthn::PublicKeyCredential::Options
|
||||
@challenge ||= Base64.urlsafe_encode64(
|
||||
ActionPack::WebAuthn.challenge_verifier.generate(
|
||||
Base64.strict_encode64(SecureRandom.random_bytes(CHALLENGE_LENGTH)),
|
||||
expires_in: challenge_expiration
|
||||
expires_in: challenge_expiration,
|
||||
purpose: challenge_purpose
|
||||
),
|
||||
padding: false
|
||||
)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
class ActionPack::WebAuthn::PublicKeyCredential::RequestOptions < ActionPack::WebAuthn::PublicKeyCredential::Options
|
||||
attribute :credentials, default: -> { [] }
|
||||
attribute :challenge_expiration, default: -> { Rails.configuration.action_pack.web_authn.request_challenge_expiration }
|
||||
attribute :challenge_purpose, default: "authentication"
|
||||
|
||||
def initialize(attributes = {})
|
||||
super
|
||||
|
||||
Reference in New Issue
Block a user