web_authn 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ba07fe60ce73457f0f61ddc7c53dbf2b07886d93
4
- data.tar.gz: a9d76ab96805dd91c619551c09e0701a2a7b0795
2
+ SHA256:
3
+ metadata.gz: f684ad0ab8c4f516d4bb9023db18476bb76daa8a262576867b21debbb746ad19
4
+ data.tar.gz: 64f0b2c7251de13671401dca713f8c7b2c09a08874bce8cf66b83f2de7d5e6a6
5
5
  SHA512:
6
- metadata.gz: 4550a5b91a35c2c5e302b58072b2a063b203370a8128d03cc851d7866e8f6bee92eab6d86dda0a41dcc366b47f9c86bfc9a0eef1e6f4a7df24bba18bbf61e32f
7
- data.tar.gz: 5aa59a73d18cfd24b6bd86431676c4c570ee6e5ff0e7af5c83fc70767a134ec87a577d1a7ebe0aab187dd92d9e467987b0e0adb085fe244aa57be6d4ac6f9849
6
+ metadata.gz: 426f5241570eb0030fb0a189930b53b5fb74945fd528dce77c1797de3ddfeabf00bcc1282dadbd5ebd87f09fbd4505f5499247ce19a5791ce341ecc9fdc00856
7
+ data.tar.gz: 3498f269f7bb8b654d75d377fde1c5e3d02693783eee78c604df51a5e052dfb680e59c6d0812ff2c88d9db015cd89dca17ab4c9e24235e3073a473e504217faf
data/Gemfile.lock ADDED
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ web_authn (0.3.0)
5
+ activesupport
6
+ cbor
7
+ cose-key (>= 0.2.0)
8
+ json-jwt
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ activesupport (5.2.1)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ aes_key_wrap (1.0.1)
19
+ bindata (2.4.4)
20
+ cbor (0.5.9.3)
21
+ concurrent-ruby (1.0.5)
22
+ cose-key (0.2.0)
23
+ cbor
24
+ diff-lcs (1.3)
25
+ docile (1.3.1)
26
+ i18n (1.1.1)
27
+ concurrent-ruby (~> 1.0)
28
+ json (2.1.0)
29
+ json-jwt (1.9.4)
30
+ activesupport
31
+ aes_key_wrap
32
+ bindata
33
+ minitest (5.11.3)
34
+ rake (10.5.0)
35
+ rspec (3.8.0)
36
+ rspec-core (~> 3.8.0)
37
+ rspec-expectations (~> 3.8.0)
38
+ rspec-mocks (~> 3.8.0)
39
+ rspec-core (3.8.0)
40
+ rspec-support (~> 3.8.0)
41
+ rspec-expectations (3.8.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.8.0)
44
+ rspec-its (1.2.0)
45
+ rspec-core (>= 3.0.0)
46
+ rspec-expectations (>= 3.0.0)
47
+ rspec-mocks (3.8.0)
48
+ diff-lcs (>= 1.2.0, < 2.0)
49
+ rspec-support (~> 3.8.0)
50
+ rspec-support (3.8.0)
51
+ simplecov (0.16.1)
52
+ docile (~> 1.1)
53
+ json (>= 1.8, < 3)
54
+ simplecov-html (~> 0.10.0)
55
+ simplecov-html (0.10.2)
56
+ thread_safe (0.3.6)
57
+ tzinfo (1.2.5)
58
+ thread_safe (~> 0.1)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ rake (~> 10.0)
65
+ rspec
66
+ rspec-its
67
+ simplecov
68
+ web_authn!
69
+
70
+ BUNDLED WITH
71
+ 1.17.1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -16,7 +16,9 @@ module WebAuthn
16
16
  nil
17
17
  when 'android-safetynet'
18
18
  AttestationStatement::AndroidSafetynet.decode att_stmt
19
- when 'packed', 'tpm', 'android-key', 'fido-u2f'
19
+ when 'packed'
20
+ AttestationStatement::Packed.decode att_stmt
21
+ when 'tpm', 'android-key', 'fido-u2f'
20
22
  raise NotImplementedError, "Unsupported Attestation Format: #{format}"
21
23
  else
22
24
  raise InvalidContext, 'Unknown Attestation Format'
@@ -4,3 +4,4 @@ module WebAuthn
4
4
  end
5
5
 
6
6
  require 'web_authn/attestation_statement/android_safetynet'
7
+ require 'web_authn/attestation_statement/packed'
@@ -18,7 +18,6 @@ module WebAuthn
18
18
  verify_signature!
19
19
  verify_certificate!
20
20
 
21
- # TODO: put more ref.) https://www.w3.org/TR/webauthn/#android-safetynet-attestation
22
21
  unless response[:ctsProfileMatch]
23
22
  raise InvalidAttestation, 'Invalid Android Safetynet Response: ctsProfileMatch'
24
23
  end
@@ -0,0 +1,54 @@
1
+ module WebAuthn
2
+ class AttestationStatement
3
+ class Packed < AttestationStatement
4
+ attr_accessor :alg, :sig, :x5c, :ecdaa_key_id
5
+
6
+ def initialize(alg:, sig:, x5c:, ecdaa_key_id:)
7
+ self.alg = alg
8
+ self.sig = sig
9
+ self.x5c = Array(x5c)
10
+ self.ecdaa_key_id = ecdaa_key_id
11
+ end
12
+
13
+ def verify!(authenticator_data, client_data_json)
14
+ verify_signature! authenticator_data, client_data_json
15
+ end
16
+
17
+ private
18
+
19
+ def self_issued?
20
+ [x5c, ecdaa_key_id].all?(&:blank?)
21
+ end
22
+
23
+ def verify_signature!(authenticator_data, client_data_json)
24
+ signature_base_string = [
25
+ authenticator_data.raw,
26
+ OpenSSL::Digest::SHA256.digest(client_data_json.raw)
27
+ ].join
28
+
29
+ if self_issued? && authenticator_data.attested_credential_data.anonymous?
30
+ public_cose_key = authenticator_data.attested_credential_data.public_cose_key
31
+ unless alg == public_cose_key.alg
32
+ raise InvalidAttestation, 'Invalid Packed Self Attestation: alg'
33
+ end
34
+ unless public_cose_key.verify sig, signature_base_string
35
+ raise InvalidAttestation, 'Invalid Packed Self Attestation: signature'
36
+ end
37
+ else
38
+ raise NotImplementedError, "Unsupported Attestation Format: packed"
39
+ end
40
+ end
41
+
42
+ class << self
43
+ def decode(att_stmt)
44
+ new(
45
+ alg: att_stmt[:alg],
46
+ sig: att_stmt[:sig],
47
+ x5c: att_stmt[:x5c],
48
+ ecdaa_key_id: att_stmt[:ecdaaKeyId]
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -9,6 +9,10 @@ module WebAuthn
9
9
  self.public_cose_key = public_cose_key
10
10
  end
11
11
 
12
+ def anonymous?
13
+ aaguid == 'AAAAAAAAAAAAAAAAAAAAAA' # NOTE: equals to `Base64.urlsafe_encode64("\0" * 16, padding: false)``
14
+ end
15
+
12
16
  class << self
13
17
  def decode(attested_credential_data)
14
18
  length = (
@@ -44,6 +44,51 @@ RSpec.describe WebAuthn::Context::Registration do
44
44
  end
45
45
  its(:sign_count) { should == sign_count }
46
46
 
47
+ context 'when packed attestation given' do
48
+ let(:context) do
49
+ {
50
+ origin: 'https://web-authn.self-issued.app',
51
+ challenge: 'random-string-generated-by-rp-server'
52
+ }
53
+ end
54
+ let(:client_data_json) do
55
+ 'eyJjaGFsbGVuZ2UiOiJjbUZ1Wkc5dExYTjBjbWx1WnkxblpXNWxjbUYwWldRdFlua3RjbkF0YzJWeWRtVnkiLCJvcmlnaW4iOiJodHRwczovL3dlYi1hdXRobi5zZWxmLWlzc3VlZC5hcHAiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0'
56
+ end
57
+
58
+ context 'when self-attestation' do
59
+ let(:attestation_object) do
60
+ 'o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEYwRAIgOprGUE_GZMIbRBAPLPw6IiNdSk4dxFb4cRbqDgVfFXQCIHnRdm64FfnShyIhq1Z2qfn3ygp0auT32gy-eL35Uo6YaGF1dGhEYXRhWMQyy4DcrMPDUkYssB87_jAt5vNxLzD9IOzRnDuluFiUlUVb2_sTAAAAAAAAAAAAAAAAAAAAAABAAKUVEhUfjXl7S9MbcWXRfXltc39Spl6yuLxOuUtQJ-y-5DkR61Ge8riwY7dRXZFNSaWhsw9LfsknL57eZEB1gKUBAgMmIAEhWCCfkZcOMoafdVwFi4cNNPQlJS1JNUkq34sJ5fKhDODsfyJYIKD89fXxjNhcX6gDxsTwH3VL_TG7HAHdKFgUjAFumfmr'
61
+ end
62
+
63
+ it do
64
+ expect do
65
+ subject
66
+ end.not_to raise_error
67
+ end
68
+
69
+ context 'when client_data_json is invalid' do
70
+ let(:client_data_json) do
71
+ Base64.urlsafe_encode64({
72
+ type: "webauthn.create",
73
+ challenge: "cmFuZG9tLXN0cmluZy1nZW5lcmF0ZWQtYnktcnAtc2VydmVy",
74
+ origin: "https://web-authn.self-issued.app",
75
+ malformed: 'malformed'
76
+ }.to_json, padding: false)
77
+ end
78
+
79
+ it do
80
+ expect do
81
+ subject
82
+ end.to raise_error WebAuthn::InvalidAttestation, 'Invalid Packed Self Attestation: signature'
83
+ end
84
+ end
85
+ end
86
+
87
+ context 'otherwise' do
88
+ it :TODO
89
+ end
90
+ end
91
+
47
92
  context 'when android-safetynet attestation given' do
48
93
  let(:context) do
49
94
  {
data/web_authn.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.required_ruby_version = '>= 2.3'
15
15
  gem.add_runtime_dependency 'activesupport'
16
16
  gem.add_runtime_dependency 'cbor'
17
- gem.add_runtime_dependency 'cose-key'
17
+ gem.add_runtime_dependency 'cose-key', '>= 0.2.0'
18
18
  gem.add_runtime_dependency 'json-jwt'
19
19
  gem.add_development_dependency 'rake', '~> 10.0'
20
20
  gem.add_development_dependency 'simplecov'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web_authn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nov matake
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-12 00:00:00.000000000 Z
11
+ date: 2018-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.2.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.2.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json-jwt
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +134,7 @@ files:
134
134
  - ".rspec"
135
135
  - ".travis.yml"
136
136
  - Gemfile
137
+ - Gemfile.lock
137
138
  - LICENSE.txt
138
139
  - README.md
139
140
  - Rakefile
@@ -144,6 +145,7 @@ files:
144
145
  - lib/web_authn/attestation_object.rb
145
146
  - lib/web_authn/attestation_statement.rb
146
147
  - lib/web_authn/attestation_statement/android_safetynet.rb
148
+ - lib/web_authn/attestation_statement/packed.rb
147
149
  - lib/web_authn/attested_credential_data.rb
148
150
  - lib/web_authn/authenticator_data.rb
149
151
  - lib/web_authn/authenticator_data/flags.rb
@@ -181,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
183
  version: '0'
182
184
  requirements: []
183
185
  rubyforge_project:
184
- rubygems_version: 2.5.2
186
+ rubygems_version: 2.7.3
185
187
  signing_key:
186
188
  specification_version: 4
187
189
  summary: WebAuthn RP library