From e748508a328025548b81ad4386fdace1826f7a78 Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Thu, 27 Sep 2018 17:35:39 -0700 Subject: [PATCH] Handle U2F-registered security keys. --- .../authenticator_assertion_response.rb | 7 ++++++- lib/webauthn/authenticator_response.rb | 20 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/webauthn/authenticator_assertion_response.rb b/lib/webauthn/authenticator_assertion_response.rb index 41edcedf..68d61bca 100644 --- a/lib/webauthn/authenticator_assertion_response.rb +++ b/lib/webauthn/authenticator_assertion_response.rb @@ -18,6 +18,12 @@ def valid?(original_challenge, original_origin, allowed_credentials:) valid_signature?(credential_public_key(allowed_credentials)) end + def valid_u2f_registered?(original_challenge, original_rp_id, allowed_credentials:) + super(original_challenge, original_rp_id) && + valid_credential?(allowed_credentials) && + valid_signature?(credential_public_key(allowed_credentials)) + end + private attr_reader :credential_id, :authenticator_data_bytes, :signature @@ -38,7 +44,6 @@ def valid_signature?(public_key_bytes) def valid_credential?(allowed_credentials) allowed_credential_ids = allowed_credentials.map { |credential| credential[:id] } - allowed_credential_ids.include?(credential_id) end diff --git a/lib/webauthn/authenticator_response.rb b/lib/webauthn/authenticator_response.rb index bd036fc9..c896346b 100644 --- a/lib/webauthn/authenticator_response.rb +++ b/lib/webauthn/authenticator_response.rb @@ -10,7 +10,15 @@ def valid?(original_challenge, original_origin) valid_type? && valid_challenge?(original_challenge) && valid_origin?(original_origin) && - valid_rp_id?(original_origin) && + authenticator_data.valid? && + authenticator_data.user_present? + end + + def valid_u2f_registered?(original_challenge, original_rp_id) + valid_type? && + valid_challenge?(original_challenge) && + valid_origin_u2f_registered?(original_rp_id) && + valid_rp_id_u2f_registered?(original_rp_id) && authenticator_data.valid? && authenticator_data.user_present? end @@ -37,8 +45,16 @@ def valid_origin?(original_origin) def valid_rp_id?(original_origin) domain = URI.parse(original_origin).host + OpenSSL::Digest::SHA256.digest(original_origin) == authenticator_data.rp_id_hash + end + + # TODO: Not needed? + def valid_origin_u2f_registered?(original_rp_id) + URI.parse(client_data.origin).host == URI.parse(original_rp_id).host + end - OpenSSL::Digest::SHA256.digest(domain) == authenticator_data.rp_id_hash + def valid_rp_id_u2f_registered?(original_rp_id) + OpenSSL::Digest::SHA256.digest(original_rp_id) == authenticator_data.rp_id_hash end def type