webauthn 2.5.0 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e6487b19f172c0c7e96af23d04e47f91bebd2ef7d20f144f99f85e761a2db86
4
- data.tar.gz: 7623405e7cd01708f29897a0d4183fbc8c9b2a3dfb06b9c182646ddaf9c6cb0d
3
+ metadata.gz: c1e5f50210b030860b4f7c5356420c2f462e6d4eae1f1adb254d1c69e90eead5
4
+ data.tar.gz: aab42b79101469b6783b522bdcefd6cd70c20ca055b10ffa85a2847cb400afab
5
5
  SHA512:
6
- metadata.gz: d2f8d2137b2ee140a3258fbbff8d62e49264b2eafa80f0726dacc16a742addf75625b9da51696db6f3862a85e63f44ca5fc2b73320b1c256dd1c57f96121de24
7
- data.tar.gz: dcb2ea914a14944b4bf7c4682394df12e00ddd4a4b0cc1076a03a7368bf4d563d08b61fbbe27ece3ddcbc05a9ed542d8236c1bfce833669c9b60c5d3387b35b4
6
+ metadata.gz: eb440aeec87f78c45890e13cb1587eb736b457b791b23644ede24952cd3590ee5ff69a55975a5813cbd34699a21c593463907f592c668356efb1c020f73cecda
7
+ data.tar.gz: a9b6015c20a893ad8916e0251ff79a3d1871544acb027e1faf7a8553a3c8b70111c7a1beae9a590950e484248a70c490d0d0017f4d9c92fc14935e58cc083642
@@ -16,17 +16,13 @@ jobs:
16
16
  fail-fast: false
17
17
  matrix:
18
18
  ruby:
19
+ - '3.1'
19
20
  - '3.0'
20
21
  - '2.7'
21
22
  - '2.6'
22
23
  - '2.5'
23
24
  - '2.4'
24
25
  - truffleruby
25
- gemfile:
26
- - openssl_2_2
27
- - openssl_2_1
28
- env:
29
- BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
30
26
  steps:
31
27
  - uses: actions/checkout@v2
32
28
  - uses: ruby/setup-ruby@v1
@@ -0,0 +1,21 @@
1
+ # Syntax reference:
2
+ # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions
3
+ name: Git Checks
4
+
5
+ on:
6
+ pull_request:
7
+ types: [opened, synchronize]
8
+
9
+ jobs:
10
+ # Fixup commits are OK in pull requests, but should generally be squashed
11
+ # before merging to master, e.g. using `git rebase -i --autosquash master`.
12
+ # See https://github.com/marketplace/actions/block-autosquash-commits
13
+ block-fixup:
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2.0.0
18
+ - name: Block autosquash commits
19
+ uses: xt0rted/block-autosquash-commits-action@v2
20
+ with:
21
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
data/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@
6
6
 
7
7
  - Ability to define multiple relying parties with the introduction of the `WebAuthn::RelyingParty` class ([@padulafacundo], [@brauliomartinezlm])
8
8
 
9
+ ## [v2.5.1] - 2022-03-20
10
+
11
+ ### Added
12
+
13
+ - Updated openssl support to be ~>2.2 [@bdewater]
14
+
15
+ ### Removed
16
+
17
+ - Removed dependency [secure_compare dependency] (https://rubygems.org/gems/secure_compare/versions/0.0.1) and use OpenSSL#secure_compare instead [@bdewater]
18
+
9
19
  ## [v2.5.0] - 2021-03-14
10
20
 
11
21
  ### Added
@@ -325,6 +335,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
325
335
  - Works with ruby 2.5
326
336
 
327
337
  [v3.0.0.alpha1]: https://github.com/cedarcode/webauthn-ruby/compare/2-stable...v3.0.0.alpha1/
338
+ [v2.5.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.5.0...v2.5.1/
328
339
  [v2.5.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.4.1...v2.5.0/
329
340
  [v2.4.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.4.0...v2.4.1/
330
341
  [v2.4.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.3.0...v2.4.0/
@@ -367,3 +378,5 @@ Note: Both additions should help making it compatible with Chrome for Android 70
367
378
  [@lgarron]: https://github.com/lgarron
368
379
  [@juanarias93]: https://github.com/juanarias93
369
380
  [@kingjan1999]: https://github.com/@kingjan1999
381
+ [@jdongelmans]: https://github.com/jdongelmans
382
+ [@petergoldstein]: https://github.com/petergoldstein
data/README.md CHANGED
@@ -96,6 +96,8 @@ If you are migrating an existing application from the legacy FIDO U2F JavaScript
96
96
 
97
97
  ### Configuration
98
98
 
99
+ If you have a multi-tenant application or just need to configure WebAuthn differently for separate parts of your application (e.g. if your users authenticate to different subdomains in the same application), we strongly recommend you look at this [Advanced Configuration](docs/advanced_configuration.md) section instead of this.
100
+
99
101
  For a Rails application this would go in `config/initializers/webauthn.rb`.
100
102
 
101
103
  ```ruby
@@ -0,0 +1,174 @@
1
+ # Advanced Configuration
2
+
3
+ ## Global vs Instance Based Configuration
4
+
5
+ Which approach suits best your needs will depend on the architecture of your application and how do your users need to register and authenticate to it.
6
+
7
+ If you have a multi-tenant application, or any application segmenation, where your users register and authenticate to each of these tenants or segments individuallly using different hostnames, or with different security needs, you need to go through [Instance Based Configuration](#instance-based-configuration).
8
+
9
+ However, if your application is served for just one hostname, or else if your users authenticate to only one subdmain (e.g. your application serves www.example.com and admin.example.com but all you users authenticate through auth.example.com) you can still rely on one [Global Configuration](../README.md#configuration).
10
+
11
+ If you are still not sure, or want to keep your options open, be aware that [Instance Based Configuration](#instance-based-configuration) is also a valid way of defining a single instance configuration and how you share such configuration across your application, it's up to you.
12
+
13
+
14
+ ## Instance Based Configuration
15
+
16
+ Intead of the [Global Configuration](../README.md#configuration) you place in `config/initializers/webauthn.rb`,
17
+ you can now have an on-demand instance of `WebAuthn::RelyingParty` with the same configuration options, that
18
+ you can build anywhere in you application, in the following way:
19
+
20
+ ```ruby
21
+ relying_party = WebAuthn::RelyingParty.new(
22
+ # This value needs to match `window.location.origin` evaluated by
23
+ # the User Agent during registration and authentication ceremonies.
24
+ origin: "https://admin.example.com"
25
+
26
+ # Relying Party name for display purposes
27
+ name: "Admin Site for Example Inc."
28
+
29
+ # Optionally configure a client timeout hint, in milliseconds.
30
+ # This hint specifies how long the browser should wait for any
31
+ # interaction with the user.
32
+ # This hint may be overridden by the browser.
33
+ # https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-timeout
34
+ # credential_options_timeout: 120_000
35
+
36
+ # You can optionally specify a different Relying Party ID
37
+ # (https://www.w3.org/TR/webauthn/#relying-party-identifier)
38
+ # if it differs from the default one.
39
+ #
40
+ # In this case the default would be "admin.example.com", but you can set it to
41
+ # the suffix "example.com"
42
+ #
43
+ # rp_id: "example.com"
44
+
45
+ # Configure preferred binary-to-text encoding scheme. This should match the encoding scheme
46
+ # used in your client-side (user agent) code before sending the credential to the server.
47
+ # Supported values: `:base64url` (default), `:base64` or `false` to disable all encoding.
48
+ #
49
+ # encoding: :base64url
50
+
51
+ # Possible values: "ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "RS256", "RS384", "RS512", "RS1"
52
+ # Default: ["ES256", "PS256", "RS256"]
53
+ #
54
+ # algorithms: ["ES384"]
55
+ )
56
+ ```
57
+
58
+ ## Instance Based API
59
+
60
+ **DISCLAIMER: This API was released on version 3.0.0.alpha1 and is still under evaluation. Although it has been throughly tested and it is fully functional it might be changed until the final release of version 3.0.0.**
61
+
62
+ The explanation for each ceremony can be found in depth in [Credential Registration](../README.md#credential-registration) and [Credential Authentication](../README.md#credential-authentication) but if you choose this instance based approach to define your WebAuthn configurations and assuming `relying_party` is the result of an instance you get through `WebAuthn::RelytingParty.new(...)` the code in those explanations needs to be updated to:
63
+
64
+ ### Credential Registration
65
+
66
+ #### Initiation phase
67
+
68
+ ```ruby
69
+ # Generate and store the WebAuthn User ID the first time the user registers a credential
70
+ if !user.webauthn_id
71
+ user.update!(webauthn_id: WebAuthn.generate_user_id)
72
+ end
73
+
74
+ options = relying_party.options_for_create(
75
+ user: { id: user.webauthn_id, name: user.name },
76
+ exclude: user.credentials.map { |c| c.webauthn_id }
77
+ )
78
+
79
+ # Store the newly generated challenge somewhere so you can have it
80
+ # for the verification phase.
81
+ session[:creation_challenge] = options.challenge
82
+
83
+ # Send `options` back to the browser, so that they can be used
84
+ # to call `navigator.credentials.create({ "publicKey": options })`
85
+ #
86
+ # You can call `options.as_json` to get a ruby hash with a JSON representation if needed.
87
+
88
+ # If inside a Rails controller, `render json: options` will just work.
89
+ # I.e. it will encode and convert the options to JSON automatically.
90
+
91
+ # For your frontend code, you might find @github/webauthn-json npm package useful.
92
+ # Especially for handling the necessary decoding of the options, and sending the
93
+ # `PublicKeyCredential` object back to the server.
94
+ ```
95
+
96
+ #### Verification phase
97
+
98
+ ```ruby
99
+ # Assuming you're using @github/webauthn-json package to send the `PublicKeyCredential` object back
100
+ # in params[:publicKeyCredential]:
101
+ begin
102
+ webauthn_credential = relying_party.verify_registration(
103
+ params[:publicKeyCredential],
104
+ params[:create_challenge]
105
+ )
106
+
107
+ # Store Credential ID, Credential Public Key and Sign Count for future authentications
108
+ user.credentials.create!(
109
+ webauthn_id: webauthn_credential.id,
110
+ public_key: webauthn_credential.public_key,
111
+ sign_count: webauthn_credential.sign_count
112
+ )
113
+ rescue WebAuthn::Error => e
114
+ # Handle error
115
+ end
116
+ ```
117
+
118
+ ### Credential Authentication
119
+
120
+ #### Initiation phase
121
+
122
+ ```ruby
123
+ options = relying_party.options_for_get(allow: user.credentials.map { |c| c.webauthn_id })
124
+
125
+ # Store the newly generated challenge somewhere so you can have it
126
+ # for the verification phase.
127
+ session[:authentication_challenge] = options.challenge
128
+
129
+ # Send `options` back to the browser, so that they can be used
130
+ # to call `navigator.credentials.get({ "publicKey": options })`
131
+
132
+ # You can call `options.as_json` to get a ruby hash with a JSON representation if needed.
133
+
134
+ # If inside a Rails controller, `render json: options` will just work.
135
+ # I.e. it will encode and convert the options to JSON automatically.
136
+
137
+ # For your frontend code, you might find @github/webauthn-json npm package useful.
138
+ # Especially for handling the necessary decoding of the options, and sending the
139
+ # `PublicKeyCredential` object back to the server.
140
+ ```
141
+
142
+ #### Verification phase
143
+
144
+ ```ruby
145
+ begin
146
+ # Assuming you're using @github/webauthn-json package to send the `PublicKeyCredential` object back
147
+ # in params[:publicKeyCredential]:
148
+ webauthn_credential, stored_credential = relying_party.verify_authentication(
149
+ params[:publicKeyCredential],
150
+ session[:authentication_challenge]
151
+ ) do
152
+ # the returned object needs to respond to #public_key and #sign_count
153
+ user.credentials.find_by(webauthn_id: webauthn_credential.id)
154
+ end
155
+
156
+ # Update the stored credential sign count with the value from `webauthn_credential.sign_count`
157
+ stored_credential.update!(sign_count: webauthn_credential.sign_count)
158
+
159
+ # Continue with successful sign in or 2FA verification...
160
+
161
+ rescue WebAuthn::SignCountVerificationError => e
162
+ # Cryptographic verification of the authenticator data succeeded, but the signature counter was less then or equal
163
+ # to the stored value. This can have several reasons and depending on your risk tolerance you can choose to fail or
164
+ # pass authentication. For more information see https://www.w3.org/TR/webauthn/#sign-counter
165
+ rescue WebAuthn::Error => e
166
+ # Handle error
167
+ end
168
+ ```
169
+
170
+ ## Moving from Global to Instance Based Configuration
171
+
172
+ Adding a configuration for a new instance does not mean you need to get rid of your Global configuration. They can co-exist in your application and be both available for the different usages you might have. `WebAuthn.configuration.relying_party` will always return the global one while `WebAuthn::RelyingParty.new`, executed anywhere in your codebase, will allow you to create a different instance as you see the need. They will not collide and instead operate in isolation without any shared state.
173
+
174
+ The gem API described in the current [Usage](../README.md#usage) section for the [Global Configuration](../README.md#configuration) approach will still valid but the [Instance Based API](#instance-based-api) also works with the global `relying_party` that is maintain globally at `WebAuthn.configuration.relying_party`.
@@ -82,7 +82,7 @@ During authentication verification phase, you must pass either the original AppI
82
82
 
83
83
  ```ruby
84
84
  assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
85
- credential_id: params[:id],
85
+ user_handle: params[:response][:userHandle],
86
86
  authenticator_data: params[:response][:authenticatorData],
87
87
  client_data_json: params[:response][:clientDataJSON],
88
88
  signature: params[:response][:signature],
@@ -90,7 +90,8 @@ assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
90
90
 
91
91
  assertion_response.verify(
92
92
  expected_challenge,
93
- allowed_credentials: [credential],
93
+ public_key: credential.public_key,
94
+ sign_count: credential.count,
94
95
  rp_id: params[:clientExtensionResults][:appid] ? domain.to_s : domain.host,
95
96
  )
96
97
  ```
@@ -37,10 +37,10 @@ module WebAuthn
37
37
  private
38
38
 
39
39
  def valid_nonce?(authenticator_data, client_data_hash)
40
- extension = cred_cert&.extensions&.detect { |ext| ext.oid == NONCE_EXTENSION_OID }
40
+ extension = cred_cert&.find_extension(NONCE_EXTENSION_OID)
41
41
 
42
42
  if extension
43
- sequence = OpenSSL::ASN1.decode(OpenSSL::ASN1.decode(extension.to_der).value[1].value)
43
+ sequence = OpenSSL::ASN1.decode(extension.value_der)
44
44
 
45
45
  sequence.tag == OpenSSL::ASN1::SEQUENCE &&
46
46
  sequence.value.size == 1 &&
@@ -45,7 +45,7 @@ module WebAuthn
45
45
  end
46
46
 
47
47
  def attestation_certificate_key_id
48
- raw_subject_key_identifier&.unpack("H*")&.[](0)
48
+ attestation_certificate.subject_key_identifier&.unpack("H*")&.[](0)
49
49
  end
50
50
 
51
51
  private
@@ -53,12 +53,10 @@ module WebAuthn
53
53
  attr_reader :statement
54
54
 
55
55
  def matching_aaguid?(attested_credential_data_aaguid)
56
- extension = attestation_certificate&.extensions&.detect { |ext| ext.oid == AAGUID_EXTENSION_OID }
56
+ extension = attestation_certificate&.find_extension(AAGUID_EXTENSION_OID)
57
57
  if extension
58
- # `extension.value` mangles data into ASCII, so we must manually compare bytes
59
- # see https://github.com/ruby/openssl/pull/234
60
- extension.to_der[-WebAuthn::AuthenticatorData::AttestedCredentialData::AAGUID_LENGTH..-1] ==
61
- attested_credential_data_aaguid
58
+ aaguid_value = OpenSSL::ASN1.decode(extension.value_der).value
59
+ aaguid_value == attested_credential_data_aaguid
62
60
  else
63
61
  true
64
62
  end
@@ -141,15 +139,6 @@ module WebAuthn
141
139
  end
142
140
  end
143
141
 
144
- def raw_subject_key_identifier
145
- extension = attestation_certificate.extensions.detect { |ext| ext.oid == "subjectKeyIdentifier" }
146
- return unless extension
147
-
148
- ext_asn1 = OpenSSL::ASN1.decode(extension.to_der)
149
- ext_value = ext_asn1.value.last
150
- OpenSSL::ASN1.decode(ext_value.value).value
151
- end
152
-
153
142
  def valid_signature?(authenticator_data, client_data_hash, public_key = attestation_certificate.public_key)
154
143
  raise("Incompatible algorithm and key") unless cose_algorithm.compatible_key?(public_key)
155
144
 
@@ -46,7 +46,7 @@ module WebAuthn
46
46
 
47
47
  attestation_certificate.version == 2 &&
48
48
  subject.assoc('OU')&.at(1) == "Authenticator Attestation" &&
49
- attestation_certificate.extensions.find { |ext| ext.oid == 'basicConstraints' }&.value == 'CA:FALSE'
49
+ attestation_certificate.find_extension('basicConstraints')&.value == 'CA:FALSE'
50
50
  else
51
51
  true
52
52
  end
@@ -3,7 +3,6 @@
3
3
  require "webauthn/authenticator_data"
4
4
  require "webauthn/client_data"
5
5
  require "webauthn/error"
6
- require "webauthn/security_utils"
7
6
 
8
7
  module WebAuthn
9
8
  TYPES = { create: "webauthn.create", get: "webauthn.get" }.freeze
@@ -79,7 +78,7 @@ module WebAuthn
79
78
  end
80
79
 
81
80
  def valid_challenge?(expected_challenge)
82
- WebAuthn::SecurityUtils.secure_compare(client_data.challenge, expected_challenge)
81
+ OpenSSL.secure_compare(client_data.challenge, expected_challenge)
83
82
  end
84
83
 
85
84
  def valid_origin?(expected_origin)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "2.5.0"
4
+ VERSION = "2.5.1"
5
5
  end
data/webauthn.gemspec CHANGED
@@ -38,12 +38,10 @@ Gem::Specification.new do |spec|
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", "~> 2.1"
41
+ spec.add_dependency "openssl", "~> 2.2"
42
42
  spec.add_dependency "safety_net_attestation", "~> 0.4.0"
43
- spec.add_dependency "securecompare", "~> 1.0"
44
43
  spec.add_dependency "tpm-key_attestation", "~> 0.10.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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webauthn
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-03-14 00:00:00.000000000 Z
12
+ date: 2022-03-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: android_key_attestation
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '2.1'
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.1'
97
+ version: '2.2'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: safety_net_attestation
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -109,20 +109,6 @@ 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
@@ -137,20 +123,6 @@ dependencies:
137
123
  - - "~>"
138
124
  - !ruby/object:Gem::Version
139
125
  version: 0.10.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'
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,6 @@ 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/security_utils.rb
329
299
  - lib/webauthn/u2f_migrator.rb
330
300
  - lib/webauthn/version.rb
331
301
  - webauthn.gemspec
@@ -351,7 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
351
321
  - !ruby/object:Gem::Version
352
322
  version: '0'
353
323
  requirements: []
354
- rubygems_version: 3.2.14
324
+ rubygems_version: 3.0.3.1
355
325
  signing_key:
356
326
  specification_version: 4
357
327
  summary: WebAuthn ruby server library
data/Appraisals DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- appraise "openssl_2_2" do
4
- gem "openssl", "~> 2.2.0"
5
- end
6
-
7
- appraise "openssl_2_1" do
8
- gem "openssl", "~> 2.1.0"
9
- end
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "openssl", "~> 2.1.0"
6
-
7
- gemspec path: "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "openssl", "~> 2.2.0"
6
-
7
- gemspec path: "../"
@@ -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