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 +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/webauthn/attestation_statement.rb +4 -0
- data/lib/webauthn/attestation_statement/android_safetynet.rb +81 -0
- data/lib/webauthn/version.rb +1 -1
- data/webauthn.gemspec +3 -0
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14d13c4bce35ebbe6cde4332ab9f5af2b5e0a9592fdc1fcb6d902954764ff656
|
4
|
+
data.tar.gz: 28f671cb2e1baeffa0f0662863867e6c12c05338fd5d4a780c2e8f6bc54344f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/webauthn/version.rb
CHANGED
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.
|
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: '
|
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.
|
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
|