webauthn 2.5.0 → 3.0.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/.github/workflows/build.yml +3 -7
- data/.github/workflows/git.yml +21 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +42 -1
- data/README.md +5 -3
- data/docs/advanced_configuration.md +174 -0
- data/docs/u2f_migration.md +14 -20
- data/lib/webauthn/attestation_object.rb +9 -5
- data/lib/webauthn/attestation_statement/apple.rb +2 -2
- data/lib/webauthn/attestation_statement/base.rb +11 -25
- data/lib/webauthn/attestation_statement/packed.rb +1 -1
- data/lib/webauthn/attestation_statement/tpm.rb +2 -2
- data/lib/webauthn/attestation_statement.rb +2 -2
- data/lib/webauthn/authenticator_assertion_response.rb +4 -3
- data/lib/webauthn/authenticator_attestation_response.rb +10 -7
- data/lib/webauthn/authenticator_data/attested_credential_data.rb +10 -5
- data/lib/webauthn/authenticator_data.rb +10 -2
- data/lib/webauthn/authenticator_response.rb +7 -7
- data/lib/webauthn/configuration.rb +38 -38
- data/lib/webauthn/credential.rb +5 -4
- data/lib/webauthn/fake_authenticator/attestation_object.rb +8 -0
- data/lib/webauthn/fake_authenticator/authenticator_data.rb +20 -5
- data/lib/webauthn/fake_authenticator.rb +9 -1
- data/lib/webauthn/fake_client.rb +10 -2
- data/lib/webauthn/public_key_credential/creation_options.rb +3 -3
- data/lib/webauthn/public_key_credential/options.rb +9 -8
- data/lib/webauthn/public_key_credential/request_options.rb +11 -1
- data/lib/webauthn/public_key_credential.rb +24 -5
- data/lib/webauthn/public_key_credential_with_assertion.rb +14 -1
- data/lib/webauthn/relying_party.rb +120 -0
- data/lib/webauthn/u2f_migrator.rb +4 -1
- data/lib/webauthn/version.rb +1 -1
- data/webauthn.gemspec +3 -5
- metadata +16 -45
- data/Appraisals +0 -9
- data/gemfiles/openssl_2_1.gemfile +0 -7
- data/gemfiles/openssl_2_2.gemfile +0 -7
- data/lib/webauthn/security_utils.rb +0 -20
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "openssl"
|
4
|
+
require "webauthn/credential"
|
5
|
+
require "webauthn/encoder"
|
6
|
+
require "webauthn/error"
|
7
|
+
|
8
|
+
module WebAuthn
|
9
|
+
class RootCertificateFinderNotSupportedError < Error; end
|
10
|
+
|
11
|
+
class RelyingParty
|
12
|
+
def self.if_pss_supported(algorithm)
|
13
|
+
OpenSSL::PKey::RSA.instance_methods.include?(:verify_pss) ? algorithm : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
DEFAULT_ALGORITHMS = ["ES256", "PS256", "RS256"].compact.freeze
|
17
|
+
|
18
|
+
def initialize(
|
19
|
+
algorithms: DEFAULT_ALGORITHMS.dup,
|
20
|
+
encoding: WebAuthn::Encoder::STANDARD_ENCODING,
|
21
|
+
origin: nil,
|
22
|
+
id: nil,
|
23
|
+
name: nil,
|
24
|
+
verify_attestation_statement: true,
|
25
|
+
credential_options_timeout: 120000,
|
26
|
+
silent_authentication: false,
|
27
|
+
acceptable_attestation_types: ['None', 'Self', 'Basic', 'AttCA', 'Basic_or_AttCA', 'AnonCA'],
|
28
|
+
attestation_root_certificates_finders: [],
|
29
|
+
legacy_u2f_appid: nil
|
30
|
+
)
|
31
|
+
@algorithms = algorithms
|
32
|
+
@encoding = encoding
|
33
|
+
@origin = origin
|
34
|
+
@id = id
|
35
|
+
@name = name
|
36
|
+
@verify_attestation_statement = verify_attestation_statement
|
37
|
+
@credential_options_timeout = credential_options_timeout
|
38
|
+
@silent_authentication = silent_authentication
|
39
|
+
@acceptable_attestation_types = acceptable_attestation_types
|
40
|
+
@legacy_u2f_appid = legacy_u2f_appid
|
41
|
+
self.attestation_root_certificates_finders = attestation_root_certificates_finders
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_accessor :algorithms,
|
45
|
+
:encoding,
|
46
|
+
:origin,
|
47
|
+
:id,
|
48
|
+
:name,
|
49
|
+
:verify_attestation_statement,
|
50
|
+
:credential_options_timeout,
|
51
|
+
:silent_authentication,
|
52
|
+
:acceptable_attestation_types,
|
53
|
+
:legacy_u2f_appid
|
54
|
+
|
55
|
+
attr_reader :attestation_root_certificates_finders
|
56
|
+
|
57
|
+
# This is the user-data encoder.
|
58
|
+
# Used to decode user input and to encode data provided to the user.
|
59
|
+
def encoder
|
60
|
+
@encoder ||= WebAuthn::Encoder.new(encoding)
|
61
|
+
end
|
62
|
+
|
63
|
+
def attestation_root_certificates_finders=(finders)
|
64
|
+
if !finders.respond_to?(:each)
|
65
|
+
finders = [finders]
|
66
|
+
end
|
67
|
+
|
68
|
+
finders.each do |finder|
|
69
|
+
unless finder.respond_to?(:find)
|
70
|
+
raise RootCertificateFinderNotSupportedError, "Finder must implement `find` method"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
@attestation_root_certificates_finders = finders
|
75
|
+
end
|
76
|
+
|
77
|
+
def options_for_registration(**keyword_arguments)
|
78
|
+
WebAuthn::Credential.options_for_create(
|
79
|
+
**keyword_arguments,
|
80
|
+
relying_party: self
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def verify_registration(raw_credential, challenge, user_verification: nil)
|
85
|
+
webauthn_credential = WebAuthn::Credential.from_create(raw_credential, relying_party: self)
|
86
|
+
|
87
|
+
if webauthn_credential.verify(challenge, user_verification: user_verification)
|
88
|
+
webauthn_credential
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def options_for_authentication(**keyword_arguments)
|
93
|
+
WebAuthn::Credential.options_for_get(
|
94
|
+
**keyword_arguments,
|
95
|
+
relying_party: self
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def verify_authentication(
|
100
|
+
raw_credential,
|
101
|
+
challenge,
|
102
|
+
user_verification: nil,
|
103
|
+
public_key: nil,
|
104
|
+
sign_count: nil
|
105
|
+
)
|
106
|
+
webauthn_credential = WebAuthn::Credential.from_get(raw_credential, relying_party: self)
|
107
|
+
|
108
|
+
stored_credential = yield(webauthn_credential) if block_given?
|
109
|
+
|
110
|
+
if webauthn_credential.verify(
|
111
|
+
challenge,
|
112
|
+
public_key: public_key || stored_credential.public_key,
|
113
|
+
sign_count: sign_count || stored_credential.sign_count,
|
114
|
+
user_verification: user_verification
|
115
|
+
)
|
116
|
+
block_given? ? [webauthn_credential, stored_credential] : webauthn_credential
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -31,7 +31,10 @@ module WebAuthn
|
|
31
31
|
@credential ||=
|
32
32
|
begin
|
33
33
|
hash = authenticator_data.send(:credential)
|
34
|
-
WebAuthn::AuthenticatorData::AttestedCredentialData::Credential.new(
|
34
|
+
WebAuthn::AuthenticatorData::AttestedCredentialData::Credential.new(
|
35
|
+
id: hash[:id],
|
36
|
+
public_key: hash[:public_key].serialize
|
37
|
+
)
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
data/lib/webauthn/version.rb
CHANGED
data/webauthn.gemspec
CHANGED
@@ -31,19 +31,17 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
|
-
spec.required_ruby_version = ">= 2.
|
34
|
+
spec.required_ruby_version = ">= 2.5"
|
35
35
|
|
36
36
|
spec.add_dependency "android_key_attestation", "~> 0.3.0"
|
37
37
|
spec.add_dependency "awrence", "~> 1.1"
|
38
38
|
spec.add_dependency "bindata", "~> 2.4"
|
39
39
|
spec.add_dependency "cbor", "~> 0.5.9"
|
40
40
|
spec.add_dependency "cose", "~> 1.1"
|
41
|
-
spec.add_dependency "openssl", "
|
41
|
+
spec.add_dependency "openssl", ">= 2.2"
|
42
42
|
spec.add_dependency "safety_net_attestation", "~> 0.4.0"
|
43
|
-
spec.add_dependency "
|
44
|
-
spec.add_dependency "tpm-key_attestation", "~> 0.10.0"
|
43
|
+
spec.add_dependency "tpm-key_attestation", "~> 0.12.0"
|
45
44
|
|
46
|
-
spec.add_development_dependency "appraisal", "~> 2.4"
|
47
45
|
spec.add_development_dependency "bundler", ">= 1.17", "< 3.0"
|
48
46
|
spec.add_development_dependency "byebug", "~> 11.0"
|
49
47
|
spec.add_development_dependency "rake", "~> 13.0"
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webauthn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gonzalo Rodriguez
|
8
8
|
- Braulio Martinez
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: android_key_attestation
|
@@ -85,16 +85,16 @@ dependencies:
|
|
85
85
|
name: openssl
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '2.
|
90
|
+
version: '2.2'
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '2.
|
97
|
+
version: '2.2'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: safety_net_attestation
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,48 +109,20 @@ dependencies:
|
|
109
109
|
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: 0.4.0
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: securecompare
|
114
|
-
requirement: !ruby/object:Gem::Requirement
|
115
|
-
requirements:
|
116
|
-
- - "~>"
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '1.0'
|
119
|
-
type: :runtime
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
requirements:
|
123
|
-
- - "~>"
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '1.0'
|
126
112
|
- !ruby/object:Gem::Dependency
|
127
113
|
name: tpm-key_attestation
|
128
114
|
requirement: !ruby/object:Gem::Requirement
|
129
115
|
requirements:
|
130
116
|
- - "~>"
|
131
117
|
- !ruby/object:Gem::Version
|
132
|
-
version: 0.
|
118
|
+
version: 0.12.0
|
133
119
|
type: :runtime
|
134
120
|
prerelease: false
|
135
121
|
version_requirements: !ruby/object:Gem::Requirement
|
136
122
|
requirements:
|
137
123
|
- - "~>"
|
138
124
|
- !ruby/object:Gem::Version
|
139
|
-
version: 0.
|
140
|
-
- !ruby/object:Gem::Dependency
|
141
|
-
name: appraisal
|
142
|
-
requirement: !ruby/object:Gem::Requirement
|
143
|
-
requirements:
|
144
|
-
- - "~>"
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
version: '2.4'
|
147
|
-
type: :development
|
148
|
-
prerelease: false
|
149
|
-
version_requirements: !ruby/object:Gem::Requirement
|
150
|
-
requirements:
|
151
|
-
- - "~>"
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
version: '2.4'
|
125
|
+
version: 0.12.0
|
154
126
|
- !ruby/object:Gem::Dependency
|
155
127
|
name: bundler
|
156
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -266,10 +238,10 @@ extensions: []
|
|
266
238
|
extra_rdoc_files: []
|
267
239
|
files:
|
268
240
|
- ".github/workflows/build.yml"
|
241
|
+
- ".github/workflows/git.yml"
|
269
242
|
- ".gitignore"
|
270
243
|
- ".rspec"
|
271
244
|
- ".rubocop.yml"
|
272
|
-
- Appraisals
|
273
245
|
- CHANGELOG.md
|
274
246
|
- CONTRIBUTING.md
|
275
247
|
- Gemfile
|
@@ -279,9 +251,8 @@ files:
|
|
279
251
|
- SECURITY.md
|
280
252
|
- bin/console
|
281
253
|
- bin/setup
|
254
|
+
- docs/advanced_configuration.md
|
282
255
|
- docs/u2f_migration.md
|
283
|
-
- gemfiles/openssl_2_1.gemfile
|
284
|
-
- gemfiles/openssl_2_2.gemfile
|
285
256
|
- lib/cose/rsapkcs1_algorithm.rb
|
286
257
|
- lib/webauthn.rb
|
287
258
|
- lib/webauthn/attestation_object.rb
|
@@ -325,7 +296,7 @@ files:
|
|
325
296
|
- lib/webauthn/public_key_credential/user_entity.rb
|
326
297
|
- lib/webauthn/public_key_credential_with_assertion.rb
|
327
298
|
- lib/webauthn/public_key_credential_with_attestation.rb
|
328
|
-
- lib/webauthn/
|
299
|
+
- lib/webauthn/relying_party.rb
|
329
300
|
- lib/webauthn/u2f_migrator.rb
|
330
301
|
- lib/webauthn/version.rb
|
331
302
|
- webauthn.gemspec
|
@@ -336,7 +307,7 @@ metadata:
|
|
336
307
|
bug_tracker_uri: https://github.com/cedarcode/webauthn-ruby/issues
|
337
308
|
changelog_uri: https://github.com/cedarcode/webauthn-ruby/blob/master/CHANGELOG.md
|
338
309
|
source_code_uri: https://github.com/cedarcode/webauthn-ruby
|
339
|
-
post_install_message:
|
310
|
+
post_install_message:
|
340
311
|
rdoc_options: []
|
341
312
|
require_paths:
|
342
313
|
- lib
|
@@ -344,15 +315,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
344
315
|
requirements:
|
345
316
|
- - ">="
|
346
317
|
- !ruby/object:Gem::Version
|
347
|
-
version: '2.
|
318
|
+
version: '2.5'
|
348
319
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
349
320
|
requirements:
|
350
321
|
- - ">="
|
351
322
|
- !ruby/object:Gem::Version
|
352
323
|
version: '0'
|
353
324
|
requirements: []
|
354
|
-
rubygems_version: 3.2.
|
355
|
-
signing_key:
|
325
|
+
rubygems_version: 3.2.32
|
326
|
+
signing_key:
|
356
327
|
specification_version: 4
|
357
328
|
summary: WebAuthn ruby server library
|
358
329
|
test_files: []
|
data/Appraisals
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "securecompare"
|
4
|
-
|
5
|
-
module WebAuthn
|
6
|
-
module SecurityUtils
|
7
|
-
# Constant time string comparison, for variable length strings.
|
8
|
-
# This code was adapted from Rails ActiveSupport::SecurityUtils
|
9
|
-
#
|
10
|
-
# The values are first processed by SHA256, so that we don't leak length info
|
11
|
-
# via timing attacks.
|
12
|
-
def secure_compare(first_string, second_string)
|
13
|
-
first_string_sha256 = ::Digest::SHA256.digest(first_string)
|
14
|
-
second_string_sha256 = ::Digest::SHA256.digest(second_string)
|
15
|
-
|
16
|
-
SecureCompare.compare(first_string_sha256, second_string_sha256) && first_string == second_string
|
17
|
-
end
|
18
|
-
module_function :secure_compare
|
19
|
-
end
|
20
|
-
end
|