From 27897e9384e7a184f183e0c322212f181e0473f4 Mon Sep 17 00:00:00 2001 From: Nicolas Temciuc Date: Tue, 4 Feb 2025 21:01:56 -0300 Subject: [PATCH] feat!: remove `token binding` support --- lib/webauthn/authenticator_response.rb | 6 ---- lib/webauthn/client_data.rb | 14 -------- lib/webauthn/fake_client.rb | 14 ++------ .../authenticator_assertion_response_spec.rb | 36 ------------------- ...authenticator_attestation_response_spec.rb | 30 ---------------- 5 files changed, 3 insertions(+), 97 deletions(-) diff --git a/lib/webauthn/authenticator_response.rb b/lib/webauthn/authenticator_response.rb index 1151b5e5..527a3aa8 100644 --- a/lib/webauthn/authenticator_response.rb +++ b/lib/webauthn/authenticator_response.rb @@ -13,7 +13,6 @@ class AuthenticatorDataVerificationError < VerificationError; end class ChallengeVerificationError < VerificationError; end class OriginVerificationError < VerificationError; end class RpIdVerificationError < VerificationError; end - class TokenBindingVerificationError < VerificationError; end class TypeVerificationError < VerificationError; end class UserPresenceVerificationError < VerificationError; end class UserVerifiedVerificationError < VerificationError; end @@ -29,7 +28,6 @@ def verify(expected_challenge, expected_origin = nil, user_presence: nil, user_v rp_id ||= relying_party.id verify_item(:type) - verify_item(:token_binding) verify_item(:challenge, expected_challenge) verify_item(:origin, expected_origin) verify_item(:authenticator_data) @@ -75,10 +73,6 @@ def valid_type? client_data.type == type end - def valid_token_binding? - client_data.valid_token_binding_format? - end - def valid_challenge?(expected_challenge) OpenSSL.secure_compare(client_data.challenge, expected_challenge) end diff --git a/lib/webauthn/client_data.rb b/lib/webauthn/client_data.rb index 0d31c964..29038e71 100644 --- a/lib/webauthn/client_data.rb +++ b/lib/webauthn/client_data.rb @@ -9,8 +9,6 @@ module WebAuthn class ClientDataMissingError < Error; end class ClientData - VALID_TOKEN_BINDING_STATUSES = ["present", "supported", "not-supported"].freeze - def initialize(client_data_json) @client_data_json = client_data_json end @@ -27,18 +25,6 @@ def origin data["origin"] end - def token_binding - data["tokenBinding"] - end - - def valid_token_binding_format? - if token_binding - token_binding.is_a?(Hash) && VALID_TOKEN_BINDING_STATUSES.include?(token_binding["status"]) - else - true - end - end - def hash OpenSSL::Digest::SHA256.digest(client_data_json) end diff --git a/lib/webauthn/fake_client.rb b/lib/webauthn/fake_client.rb index 98ae0d45..e679c93b 100644 --- a/lib/webauthn/fake_client.rb +++ b/lib/webauthn/fake_client.rb @@ -10,16 +10,14 @@ module WebAuthn class FakeClient TYPES = { create: "webauthn.create", get: "webauthn.get" }.freeze - attr_reader :origin, :token_binding, :encoding + attr_reader :origin, :encoding def initialize( origin = fake_origin, - token_binding: nil, authenticator: WebAuthn::FakeAuthenticator.new, encoding: WebAuthn.configuration.encoding ) @origin = origin - @token_binding = token_binding @authenticator = authenticator @encoding = encoding end @@ -127,17 +125,11 @@ def get(challenge: fake_challenge, attr_reader :authenticator def data_json_for(method, challenge) - data = { + { type: type_for(method), challenge: internal_encoder.encode(challenge), origin: origin - } - - if token_binding - data[:tokenBinding] = token_binding - end - - data.to_json + }.to_json end def encoder diff --git a/spec/webauthn/authenticator_assertion_response_spec.rb b/spec/webauthn/authenticator_assertion_response_spec.rb index b0d3f95d..3a1ee80a 100644 --- a/spec/webauthn/authenticator_assertion_response_spec.rb +++ b/spec/webauthn/authenticator_assertion_response_spec.rb @@ -367,42 +367,6 @@ end end - describe "tokenBinding validation" do - let(:client) { WebAuthn::FakeClient.new(actual_origin, token_binding: token_binding, encoding: false) } - - context "it has stuff" do - let(:token_binding) { { status: "supported" } } - - it "verifies" do - expect( - assertion_response.verify(original_challenge, public_key: credential_public_key, sign_count: 0) - ).to be_truthy - end - - it "is valid" do - expect( - assertion_response.valid?(original_challenge, public_key: credential_public_key, sign_count: 0) - ).to be_truthy - end - end - - context "has an invalid format" do - let(:token_binding) { "invalid token binding format" } - - it "doesn't verify" do - expect { - assertion_response.verify(original_challenge, public_key: credential_public_key, sign_count: 0) - }.to raise_exception(WebAuthn::TokenBindingVerificationError) - end - - it "isn't valid" do - expect( - assertion_response.valid?(original_challenge, public_key: credential_public_key, sign_count: 0) - ).to be_falsy - end - end - end - describe "rp_id validation" do before do WebAuthn.configuration.rp_id = "different-rp_id" diff --git a/spec/webauthn/authenticator_attestation_response_spec.rb b/spec/webauthn/authenticator_attestation_response_spec.rb index eda785d9..30511172 100644 --- a/spec/webauthn/authenticator_attestation_response_spec.rb +++ b/spec/webauthn/authenticator_attestation_response_spec.rb @@ -479,36 +479,6 @@ end end - describe "tokenBinding validation" do - let(:client) { WebAuthn::FakeClient.new(origin, token_binding: token_binding, encoding: false) } - - context "it has stuff" do - let(:token_binding) { { status: "supported" } } - - it "verifies" do - expect(attestation_response.verify(original_challenge, origin)).to be_truthy - end - - it "is valid" do - expect(attestation_response.valid?(original_challenge, origin)).to be_truthy - end - end - - context "has an invalid format" do - let(:token_binding) { "invalid token binding format" } - - it "doesn't verify" do - expect { - attestation_response.verify(original_challenge, origin) - }.to raise_exception(WebAuthn::TokenBindingVerificationError) - end - - it "isn't valid" do - expect(attestation_response.valid?(original_challenge, origin)).to be_falsy - end - end - end - describe "user presence" do context "when UP is not set" do let(:public_key_credential) { client.create(challenge: original_challenge, user_present: false) }