webauthn 1.3.0 → 1.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
2
  SHA256:
3
- metadata.gz: 8dd2e6fbccb0b180e0a36f4980939a1ba3a66d0cc744a7d50b140feb01917a35
4
- data.tar.gz: 403281bfe63aa4ca9929bd0ca2e8cc9ff3af4ae66b21251f26118138fb355051
3
+ metadata.gz: 14d13c4bce35ebbe6cde4332ab9f5af2b5e0a9592fdc1fcb6d902954764ff656
4
+ data.tar.gz: 28f671cb2e1baeffa0f0662863867e6c12c05338fd5d4a780c2e8f6bc54344f1
5
5
  SHA512:
6
- metadata.gz: 4ab428637bed52191bdee14a96a9676df44019170ffab49862bc28e84c59202f3fb8302b36fd0bc29321608352712ea18cdecbe0311dfc02a167da1b2bf1d3b5
7
- data.tar.gz: cb98ae9cbfbe66804e2bea396121da2874b667b6e25ee58790195dbfd2a6b6d936cca70e50d7b9d796f2af0928c164cbdd3093987a202171f19e365bbdefd6a1
6
+ metadata.gz: c44f926b6046f13b9ff0b71646a8ce72ff87ac064b82cfc8e1a273889d1878567655455d874619361aa1c9906cdc06234e4e5502736c18148e3721e36c790fff
7
+ data.tar.gz: ac6e06366d290ef51ad1257386d3a44a0b9eae9a3fd7e4071392c73a0a1cd39784da6bf942ac984fd84d0ef2100bff4cf0dbaf83df064cc6df5f2cdffa5ddc22
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.4.0] - 2018-10-11
4
+
5
+ ### Added
6
+
7
+ - _Registration_ ceremony
8
+ - `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `android-safetynet` attestation statements. Thank you @bdewater!
9
+
3
10
  ## [v1.3.0] - 2018-10-11
4
11
 
5
12
  ### Added
@@ -78,6 +85,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
78
85
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
79
86
  - Works with ruby 2.5
80
87
 
88
+ [v1.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.3.0...v1.4.0/
81
89
  [v1.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.2.0...v1.3.0/
82
90
  [v1.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.1.0...v1.2.0/
83
91
  [v1.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.0.0...v1.1.0/
@@ -7,6 +7,7 @@ module WebAuthn
7
7
  ATTESTATION_FORMAT_NONE = "none"
8
8
  ATTESTATION_FORMAT_FIDO_U2F = "fido-u2f"
9
9
  ATTESTATION_FORMAT_PACKED = 'packed'
10
+ ATTESTATION_FORMAT_ANDROID_SAFETYNET = "android-safetynet"
10
11
 
11
12
  def self.from(format, statement)
12
13
  case format
@@ -19,6 +20,9 @@ module WebAuthn
19
20
  when ATTESTATION_FORMAT_PACKED
20
21
  require "webauthn/attestation_statement/packed"
21
22
  WebAuthn::AttestationStatement::Packed.new(statement)
23
+ when ATTESTATION_FORMAT_ANDROID_SAFETYNET
24
+ require "webauthn/attestation_statement/android_safetynet"
25
+ WebAuthn::AttestationStatement::AndroidSafetynet.new(statement)
22
26
  else
23
27
  raise FormatNotSupportedError, "Unsupported attestation format '#{format}'"
24
28
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jwt"
4
+ require "openssl"
5
+ require "webauthn/attestation_statement/base"
6
+
7
+ module WebAuthn
8
+ module AttestationStatement
9
+ # Implements https://www.w3.org/TR/2018/CR-webauthn-20180807/#android-safetynet-attestation
10
+ class AndroidSafetynet < Base
11
+ def self.default_trust_store
12
+ OpenSSL::X509::Store.new.tap { |trust_store| trust_store.set_default_paths }
13
+ end
14
+
15
+ def valid?(authenticator_data, client_data_hash, trust_store: self.class.default_trust_store)
16
+ trusted_attestation_certificate?(trust_store) &&
17
+ valid_signature? &&
18
+ valid_attestation_domain? &&
19
+ valid_version? &&
20
+ valid_nonce?(authenticator_data, client_data_hash) &&
21
+ cts_profile_match?
22
+ end
23
+
24
+ private
25
+
26
+ def trusted_attestation_certificate?(trust_store)
27
+ signing_certificates.each do |certificate|
28
+ trust_store.add_cert(certificate)
29
+ end
30
+ trust_store.verify(attestation_certificate)
31
+ end
32
+
33
+ def valid_signature?
34
+ signed_payload, _, base64_signature = statement["response"].rpartition(".")
35
+ signature = Base64.urlsafe_decode64(base64_signature)
36
+ attestation_certificate.public_key.verify(OpenSSL::Digest::SHA256.new, signature, signed_payload)
37
+ end
38
+
39
+ def valid_attestation_domain?
40
+ subject = attestation_certificate.subject.to_a
41
+ subject.assoc('CN')[1] == "attest.android.com"
42
+ end
43
+
44
+ # TODO: improve once the spec has clarifications https://github.com/w3c/webauthn/issues/968
45
+ def valid_version?
46
+ !statement["ver"].empty?
47
+ end
48
+
49
+ def valid_nonce?(authenticator_data, client_data_hash)
50
+ nonce = unverified_jws_result[0]["nonce"]
51
+ nonce == verification_data(authenticator_data, client_data_hash)
52
+ end
53
+
54
+ def cts_profile_match?
55
+ unverified_jws_result[0]["ctsProfileMatch"]
56
+ end
57
+
58
+ def verification_data(authenticator_data, client_data_hash)
59
+ Digest::SHA256.base64digest(authenticator_data.data + client_data_hash)
60
+ end
61
+
62
+ def attestation_certificate
63
+ attestation_certificate_chain[0]
64
+ end
65
+
66
+ def signing_certificates
67
+ attestation_certificate_chain[1..-1]
68
+ end
69
+
70
+ def attestation_certificate_chain
71
+ @attestation_certificate_chain ||= unverified_jws_result[1]["x5c"].map do |cert|
72
+ OpenSSL::X509::Certificate.new(Base64.strict_decode64(cert))
73
+ end
74
+ end
75
+
76
+ def unverified_jws_result
77
+ @unverified_jws_result ||= JWT.decode(statement["response"], nil, false)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "1.3.0"
4
+ VERSION = "1.4.0"
5
5
  end
data/webauthn.gemspec CHANGED
@@ -27,8 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
+ spec.required_ruby_version = ">= 2.4"
31
+
30
32
  spec.add_dependency "cbor", "~> 0.5.9.2"
31
33
  spec.add_dependency "cose", "~> 0.1.0"
34
+ spec.add_dependency "jwt", [">= 1.5", "< 3.0"]
32
35
 
33
36
  spec.add_development_dependency "bundler", "~> 1.16"
34
37
  spec.add_development_dependency "byebug", "~> 10.0"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webauthn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
@@ -39,6 +39,26 @@ dependencies:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: 0.1.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: jwt
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '1.5'
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '3.0'
52
+ type: :runtime
53
+ prerelease: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '1.5'
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
42
62
  - !ruby/object:Gem::Dependency
43
63
  name: bundler
44
64
  requirement: !ruby/object:Gem::Requirement
@@ -131,6 +151,7 @@ files:
131
151
  - lib/cose/ecdsa.rb
132
152
  - lib/webauthn.rb
133
153
  - lib/webauthn/attestation_statement.rb
154
+ - lib/webauthn/attestation_statement/android_safetynet.rb
134
155
  - lib/webauthn/attestation_statement/base.rb
135
156
  - lib/webauthn/attestation_statement/fido_u2f.rb
136
157
  - lib/webauthn/attestation_statement/none.rb
@@ -160,7 +181,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
160
181
  requirements:
161
182
  - - ">="
162
183
  - !ruby/object:Gem::Version
163
- version: '0'
184
+ version: '2.4'
164
185
  required_rubygems_version: !ruby/object:Gem::Requirement
165
186
  requirements:
166
187
  - - ">="
@@ -168,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
189
  version: '0'
169
190
  requirements: []
170
191
  rubyforge_project:
171
- rubygems_version: 2.7.7
192
+ rubygems_version: 2.7.6
172
193
  signing_key:
173
194
  specification_version: 4
174
195
  summary: WebAuthn in ruby ― Ruby implementation of a WebAuthn Relying Party