From cc4c70d2cfb14738299de41fbf1a72b2eb40000e Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 11:34:38 -0700 Subject: [PATCH 01/14] Validate the JSON data in load Check to make sure that the loaded JSON actually contains data in the keys we are going to use before we use them, to avoid runtime exceptions on Nil. --- lib/u2f/register_response.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/u2f/register_response.rb b/lib/u2f/register_response.rb index da6fec9..2303694 100644 --- a/lib/u2f/register_response.rb +++ b/lib/u2f/register_response.rb @@ -20,6 +20,10 @@ def self.load_from_json(json) raise RegistrationError, code: data['errorCode'] end + if data['clientData'].blank? || data['registrationData'].blank? + raise RegistrationError, code: 2 + end + instance = new instance.client_data_json = ::U2F.urlsafe_decode64(data['clientData']) From 02e716273fb9a74bab9daf80f39263ce5f54024d Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 12:52:39 -0700 Subject: [PATCH 02/14] Raise error on bad response data When trying to sign response make sue the data is correct and raise a known error rather than a method missing error on bad data. --- lib/u2f/sign_response.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/u2f/sign_response.rb b/lib/u2f/sign_response.rb index c6425ec..e53fef9 100644 --- a/lib/u2f/sign_response.rb +++ b/lib/u2f/sign_response.rb @@ -4,6 +4,10 @@ class SignResponse def self.load_from_json(json) data = ::JSON.parse(json) + if data['clientData'].blank? || data['keyHandle'].blank? || data['signatureData'].blank? + raise Error, 'Missing required data' + end + instance = new instance.client_data_json = ::U2F.urlsafe_decode64(data['clientData']) From a8ad97aae1864e5ea8cb6138dbe2b23406084cb4 Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 12:54:53 -0700 Subject: [PATCH 03/14] Bad request constant --- lib/u2f/register_response.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/u2f/register_response.rb b/lib/u2f/register_response.rb index 2303694..bdc4b99 100644 --- a/lib/u2f/register_response.rb +++ b/lib/u2f/register_response.rb @@ -11,6 +11,7 @@ class RegisterResponse KEY_HANDLE_LENGTH_LENGTH = 1 KEY_HANDLE_LENGTH_OFFSET = PUBLIC_KEY_OFFSET + PUBLIC_KEY_LENGTH KEY_HANDLE_OFFSET = KEY_HANDLE_LENGTH_OFFSET + KEY_HANDLE_LENGTH_LENGTH + BAD_REQUEST = 2 def self.load_from_json(json) # TODO: validate @@ -21,7 +22,7 @@ def self.load_from_json(json) end if data['clientData'].blank? || data['registrationData'].blank? - raise RegistrationError, code: 2 + raise RegistrationError, code: BAD_REQUEST end instance = new From 9a880908d7e328dbd860b9b3a55069eab4ca9190 Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 12:59:36 -0700 Subject: [PATCH 04/14] Add test for invalid JSON error --- spec/lib/register_response_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/lib/register_response_spec.rb b/spec/lib/register_response_spec.rb index d8dad83..5c89cca 100644 --- a/spec/lib/register_response_spec.rb +++ b/spec/lib/register_response_spec.rb @@ -28,6 +28,17 @@ end end + context 'with invalid response' do + let(:registration_data_json) { '{}' } + t 'raises RegistrationError with code' do + expect { + register_response + }.to raise_error(U2F::RegistrationError) do |error| + expect(error.code).to eq(2) + end + end + end + context 'with unpadded response' do let(:registration_data_json) { registration_data_json_without_padding } it 'does not raise "invalid base64" exception' do From bc645085a4b2167847264e8a45c8b17fc04fc8cc Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 13:05:13 -0700 Subject: [PATCH 05/14] Add test for handling invalid response data --- spec/lib/sign_response_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/lib/sign_response_spec.rb b/spec/lib/sign_response_spec.rb index f804d37..9d38735 100644 --- a/spec/lib/sign_response_spec.rb +++ b/spec/lib/sign_response_spec.rb @@ -8,6 +8,17 @@ let(:sign_response) { U2F::SignResponse.load_from_json json_response } let(:public_key_pem) { U2F::U2F.public_key_pem(device.origin_public_key_raw) } + context 'with invalid response' do + let(:json_response) { '{}' } + it 'raises error' do + expect { + sign_response + }.to raise_error(U2F::Error) do |error| + expect(error.message).to eq('Missing required data') + end + end + end + describe '#counter' do subject { sign_response.counter } it { is_expected.to be device.counter } From 77fee61b3dc283d803d810ecea8e836c1ea04b2d Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 13:08:56 -0700 Subject: [PATCH 06/14] Fix typo --- spec/lib/register_response_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/register_response_spec.rb b/spec/lib/register_response_spec.rb index 5c89cca..ad65e66 100644 --- a/spec/lib/register_response_spec.rb +++ b/spec/lib/register_response_spec.rb @@ -30,7 +30,7 @@ context 'with invalid response' do let(:registration_data_json) { '{}' } - t 'raises RegistrationError with code' do + it 'raises RegistrationError with code' do expect { register_response }.to raise_error(U2F::RegistrationError) do |error| From 6abd5cd6a40201e0de7032bdcc6db0e98d353a5a Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 13:16:11 -0700 Subject: [PATCH 07/14] Use nil instead of blank --- lib/u2f/sign_response.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/u2f/sign_response.rb b/lib/u2f/sign_response.rb index e53fef9..ffd8e9f 100644 --- a/lib/u2f/sign_response.rb +++ b/lib/u2f/sign_response.rb @@ -4,7 +4,7 @@ class SignResponse def self.load_from_json(json) data = ::JSON.parse(json) - if data['clientData'].blank? || data['keyHandle'].blank? || data['signatureData'].blank? + if data['clientData'].nil? || data['keyHandle'].nil? || data['signatureData'].nil? raise Error, 'Missing required data' end From 8928ba2cf4d0cbdd6e38dcc2aa3e1da0c77a134c Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Thu, 29 Jun 2017 13:17:21 -0700 Subject: [PATCH 08/14] Use key instead of blank --- lib/u2f/register_response.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/u2f/register_response.rb b/lib/u2f/register_response.rb index bdc4b99..9167d24 100644 --- a/lib/u2f/register_response.rb +++ b/lib/u2f/register_response.rb @@ -21,7 +21,7 @@ def self.load_from_json(json) raise RegistrationError, code: data['errorCode'] end - if data['clientData'].blank? || data['registrationData'].blank? + if !data.key?('clientData') || !data.key?('registrationData') raise RegistrationError, code: BAD_REQUEST end From 3fcaadfa5f593b8537ed3570dadcc5d6a3c2dfbd Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Mon, 24 Jul 2017 15:34:38 -0700 Subject: [PATCH 09/14] Change .nil? checks to .key? --- lib/u2f/sign_response.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/u2f/sign_response.rb b/lib/u2f/sign_response.rb index ffd8e9f..1e7d2e7 100644 --- a/lib/u2f/sign_response.rb +++ b/lib/u2f/sign_response.rb @@ -4,7 +4,7 @@ class SignResponse def self.load_from_json(json) data = ::JSON.parse(json) - if data['clientData'].nil? || data['keyHandle'].nil? || data['signatureData'].nil? + if data.key?('clientData') || data.key?('keyHandle') || data.key?('signatureData') raise Error, 'Missing required data' end From c8121f69f6048e4019e876cc3da0f7b95ad42d14 Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Mon, 24 Jul 2017 15:36:10 -0700 Subject: [PATCH 10/14] Change error from bad data code to invalid json message --- lib/u2f/register_response.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/u2f/register_response.rb b/lib/u2f/register_response.rb index 9167d24..ca1ede2 100644 --- a/lib/u2f/register_response.rb +++ b/lib/u2f/register_response.rb @@ -11,7 +11,6 @@ class RegisterResponse KEY_HANDLE_LENGTH_LENGTH = 1 KEY_HANDLE_LENGTH_OFFSET = PUBLIC_KEY_OFFSET + PUBLIC_KEY_LENGTH KEY_HANDLE_OFFSET = KEY_HANDLE_LENGTH_OFFSET + KEY_HANDLE_LENGTH_LENGTH - BAD_REQUEST = 2 def self.load_from_json(json) # TODO: validate @@ -22,7 +21,7 @@ def self.load_from_json(json) end if !data.key?('clientData') || !data.key?('registrationData') - raise RegistrationError, code: BAD_REQUEST + raise RegistrationError, message: 'Invalid JSON' end instance = new From bd14277cbe4cb6108ec26269747c5ddf99244291 Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Mon, 24 Jul 2017 15:36:36 -0700 Subject: [PATCH 11/14] oops --- lib/u2f/register_response.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/u2f/register_response.rb b/lib/u2f/register_response.rb index ca1ede2..e2bc61a 100644 --- a/lib/u2f/register_response.rb +++ b/lib/u2f/register_response.rb @@ -21,7 +21,7 @@ def self.load_from_json(json) end if !data.key?('clientData') || !data.key?('registrationData') - raise RegistrationError, message: 'Invalid JSON' + raise RegistrationError, 'Invalid JSON' end instance = new From 82a2076ec6cf804219c90f38e385f5202d8404ea Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Mon, 24 Jul 2017 15:37:42 -0700 Subject: [PATCH 12/14] Fix test --- spec/lib/register_response_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/register_response_spec.rb b/spec/lib/register_response_spec.rb index ad65e66..4249d70 100644 --- a/spec/lib/register_response_spec.rb +++ b/spec/lib/register_response_spec.rb @@ -34,7 +34,7 @@ expect { register_response }.to raise_error(U2F::RegistrationError) do |error| - expect(error.code).to eq(2) + expect(error.message).to eq('Invalid JSON') end end end From 9b90bb19354064e556402c69a5af7038fafd98b2 Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Tue, 25 Jul 2017 11:44:42 -0700 Subject: [PATCH 13/14] Fix error --- lib/u2f/register_response.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/u2f/register_response.rb b/lib/u2f/register_response.rb index e2bc61a..cf706c9 100644 --- a/lib/u2f/register_response.rb +++ b/lib/u2f/register_response.rb @@ -21,9 +21,9 @@ def self.load_from_json(json) end if !data.key?('clientData') || !data.key?('registrationData') - raise RegistrationError, 'Invalid JSON' + raise RegistrationError, message: 'Invalid JSON' end - + instance = new instance.client_data_json = ::U2F.urlsafe_decode64(data['clientData']) From beeb1402e492ef3dc64962d1a1ee4f69067e821e Mon Sep 17 00:00:00 2001 From: Ashley Martens Date: Tue, 25 Jul 2017 11:49:07 -0700 Subject: [PATCH 14/14] Fix sign response --- lib/u2f/sign_response.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/u2f/sign_response.rb b/lib/u2f/sign_response.rb index 1e7d2e7..5da2791 100644 --- a/lib/u2f/sign_response.rb +++ b/lib/u2f/sign_response.rb @@ -4,10 +4,11 @@ class SignResponse def self.load_from_json(json) data = ::JSON.parse(json) - if data.key?('clientData') || data.key?('keyHandle') || data.key?('signatureData') + if !data.key?('clientData') || !data.key?('keyHandle') || + !data.key?('signatureData') raise Error, 'Missing required data' end - + instance = new instance.client_data_json = ::U2F.urlsafe_decode64(data['clientData'])