webauthn 1.7.0 → 1.8.0

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: 861ba8a05d52230a89d8ba009d93e656c42c7f9add389767f0cd3cf6bf97c8c2
4
- data.tar.gz: a3c7d357340f381c4ea06e3ed8aa5711549573eb9f59e591a332f7224a55a2dd
3
+ metadata.gz: 0e9c0949f662e12a84d1810c564633cd6feec64b1f4ed9352a19260a1840d6fc
4
+ data.tar.gz: 30725d9ebd21ce4b77b548807a9c57014983e245183bc2c1179e7eb1580d0583
5
5
  SHA512:
6
- metadata.gz: dcad6286a076eea7af7d3bfde6c708cb291a2d8102c8722db8a6372baedf6541df470d54717ed2c347a2f0e703a7bcf190cffbef9c8f90cbe6475064ee00f542
7
- data.tar.gz: 8b28576e8ce15e632ca54e78fd4cf94ac2c34a506c84b085baa19623787e50d60eb0ed7253edbd87523639353a4cdb448c7bfc94dedf1563ae764e9ff1e4cd28
6
+ metadata.gz: f0499fa6c77cc863dfd325ad84e7bf746377b18e6260cbad692add3ac3a1e1508b5652e1536ef9f72a2614026c95ab71a026a73b96212bd54ab4e088e3ad9dd5
7
+ data.tar.gz: 122fd1cd5689b051a9c39744ee3d02dce099ff9f226d4b2278ae3baf2fe2aff0d1e6dc218bed9e19f3703eafb7a0e0d142055c01c5219449ac5f118a21b94813
@@ -1,12 +1,17 @@
1
+ dist: xenial
1
2
  sudo: false
2
3
  language: ruby
3
4
  cache: bundler
4
5
  rvm:
5
- - 2.6.0-preview3
6
+ - ruby-head
7
+ - 2.6.0
6
8
  - 2.5.3
7
9
  - 2.4.5
8
10
  - 2.3.8
9
11
  matrix:
10
12
  fast_finish: true
11
13
  allow_failures:
12
- - rvm: 2.6.0-preview3
14
+ - rvm: ruby-head
15
+
16
+ before_install:
17
+ - gem install bundler -v "~> 2.0"
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.8.0] - 2019-01-17
4
+
5
+ ### Added
6
+
7
+ - Make challenge validation inside `#valid?` method resistant to timing attacks. Thank you @tomek-bt!
8
+ - Support for ruby 2.6
9
+
10
+ ### Changed
11
+
12
+ - Make current raised exception errors a bit more meaningful to aid debugging
13
+
3
14
  ## [v1.7.0] - 2018-11-08
4
15
 
5
16
  ### Added
@@ -104,6 +115,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
104
115
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
105
116
  - Works with ruby 2.5
106
117
 
118
+ [v1.8.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.7.0...v1.8.0/
107
119
  [v1.7.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.6.0...v1.7.0/
108
120
  [v1.6.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.5.0...v1.6.0/
109
121
  [v1.5.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.4.0...v1.5.0/
data/README.md CHANGED
@@ -198,6 +198,10 @@ Inspired in a subset of [Angular's Commit Message Guidelines](https://github.com
198
198
 
199
199
  Bug reports and pull requests are welcome on GitHub at https://github.com/cedarcode/webauthn-ruby.
200
200
 
201
+ ### Security
202
+
203
+ If you have discovered a security bug, please send an email to security@cedarcode.com instead of posting to the GitHub issue tracker.
204
+
201
205
  ## License
202
206
 
203
207
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -3,6 +3,7 @@
3
3
  require "cose/ecdsa"
4
4
  require "webauthn/authenticator_attestation_response"
5
5
  require "webauthn/authenticator_assertion_response"
6
+ require "webauthn/security_utils"
6
7
  require "webauthn/version"
7
8
 
8
9
  require "base64"
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "webauthn/error"
4
+
3
5
  module WebAuthn
4
6
  module AttestationStatement
5
- class FormatNotSupportedError < StandardError; end
7
+ class FormatNotSupportedError < Error; end
6
8
 
7
9
  ATTESTATION_FORMAT_NONE = "none"
8
10
  ATTESTATION_FORMAT_FIDO_U2F = "fido-u2f"
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "webauthn/error"
4
+
3
5
  module WebAuthn
4
6
  module AttestationStatement
5
7
  class Base
6
- class NotSupportedError < StandardError; end
8
+ class NotSupportedError < Error; end
7
9
 
8
10
  def initialize(statement)
9
11
  @statement = statement
@@ -51,7 +51,7 @@ module WebAuthn
51
51
  end
52
52
 
53
53
  def public_key
54
- @public_key ||= PublicKeyU2f.new(data_at(public_key_position, public_key_length))
54
+ @public_key ||= PublicKeyU2f.new(data_at(public_key_position))
55
55
  end
56
56
 
57
57
  def id_position
@@ -70,10 +70,6 @@ module WebAuthn
70
70
  id_position + id_length
71
71
  end
72
72
 
73
- def public_key_length
74
- data.size - (AAGUID_LENGTH + ID_LENGTH_LENGTH + id_length)
75
- end
76
-
77
73
  def data_at(position, length = nil)
78
74
  length ||= data.size - position
79
75
 
@@ -28,7 +28,7 @@ module WebAuthn
28
28
  end
29
29
 
30
30
  def valid_challenge?(original_challenge)
31
- Base64.urlsafe_decode64(client_data.challenge) == original_challenge
31
+ WebAuthn::SecurityUtils.secure_compare(Base64.urlsafe_decode64(client_data.challenge), original_challenge)
32
32
  end
33
33
 
34
34
  def valid_origin?(original_origin)
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "openssl"
4
+ require "webauthn/error"
4
5
 
5
6
  module WebAuthn
7
+ class ClientDataMissingError < Error; end
8
+
6
9
  class ClientData
7
10
  def initialize(client_data_json)
8
11
  @client_data_json = client_data_json
@@ -34,7 +37,7 @@ module WebAuthn
34
37
  if client_data_json
35
38
  JSON.parse(client_data_json)
36
39
  else
37
- raise "Missing client_data_json"
40
+ raise ClientDataMissingError, "Client Data JSON is missing"
38
41
  end
39
42
  end
40
43
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebAuthn
4
+ class Error < StandardError; end
5
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebAuthn
4
+ module SecurityUtils
5
+ # Constant time string comparison, for variable length strings.
6
+ # This code was adapted from Rails ActiveSupport::SecurityUtils
7
+ #
8
+ # The values are first processed by SHA256, so that we don't leak length info
9
+ # via timing attacks.
10
+ def secure_compare(first_string, second_string)
11
+ first_string_sha256 = ::Digest::SHA256.hexdigest(first_string)
12
+ second_string_sha256 = ::Digest::SHA256.hexdigest(second_string)
13
+ fixed_length_secure_compare(first_string_sha256, second_string_sha256) && first_string == second_string
14
+ end
15
+ module_function :secure_compare
16
+
17
+ private
18
+
19
+ # Constant time string comparison, for fixed length strings.
20
+ # This code was adapted from Rails ActiveSupport::SecurityUtils
21
+ #
22
+ # The values compared should be of fixed length, such as strings
23
+ # that have already been processed by HMAC. Raises in case of length mismatch.
24
+ def fixed_length_secure_compare(first_string, second_string)
25
+ raise ArgumentError, "string length mismatch." unless first_string.bytesize == second_string.bytesize
26
+
27
+ l = first_string.unpack "C#{first_string.bytesize}"
28
+
29
+ res = 0
30
+ second_string.each_byte { |byte| res |= byte ^ l.shift }
31
+ res == 0
32
+ end
33
+ module_function :fixed_length_secure_compare
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "1.7.0"
4
+ VERSION = "1.8.0"
5
5
  end
@@ -34,9 +34,9 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency "jwt", [">= 1.5", "< 3.0"]
35
35
  spec.add_dependency "openssl", "~> 2.0"
36
36
 
37
- spec.add_development_dependency "bundler", "~> 1.16"
37
+ spec.add_development_dependency "bundler", ">= 1.17", "< 3.0"
38
38
  spec.add_development_dependency "byebug", "~> 10.0"
39
- spec.add_development_dependency "rake", "~> 12.0"
40
- spec.add_development_dependency "rspec", "~> 3.0"
41
- spec.add_development_dependency "rubocop", "0.60.0"
39
+ spec.add_development_dependency "rake", "~> 12.3"
40
+ spec.add_development_dependency "rspec", "~> 3.8"
41
+ spec.add_development_dependency "rubocop", "0.61.1"
42
42
  end
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.7.0
4
+ version: 1.8.0
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: 2018-11-08 00:00:00.000000000 Z
12
+ date: 2019-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cbor
@@ -77,16 +77,22 @@ dependencies:
77
77
  name: bundler
78
78
  requirement: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '1.17'
83
+ - - "<"
81
84
  - !ruby/object:Gem::Version
82
- version: '1.16'
85
+ version: '3.0'
83
86
  type: :development
84
87
  prerelease: false
85
88
  version_requirements: !ruby/object:Gem::Requirement
86
89
  requirements:
87
- - - "~>"
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '1.17'
93
+ - - "<"
88
94
  - !ruby/object:Gem::Version
89
- version: '1.16'
95
+ version: '3.0'
90
96
  - !ruby/object:Gem::Dependency
91
97
  name: byebug
92
98
  requirement: !ruby/object:Gem::Requirement
@@ -107,42 +113,42 @@ dependencies:
107
113
  requirements:
108
114
  - - "~>"
109
115
  - !ruby/object:Gem::Version
110
- version: '12.0'
116
+ version: '12.3'
111
117
  type: :development
112
118
  prerelease: false
113
119
  version_requirements: !ruby/object:Gem::Requirement
114
120
  requirements:
115
121
  - - "~>"
116
122
  - !ruby/object:Gem::Version
117
- version: '12.0'
123
+ version: '12.3'
118
124
  - !ruby/object:Gem::Dependency
119
125
  name: rspec
120
126
  requirement: !ruby/object:Gem::Requirement
121
127
  requirements:
122
128
  - - "~>"
123
129
  - !ruby/object:Gem::Version
124
- version: '3.0'
130
+ version: '3.8'
125
131
  type: :development
126
132
  prerelease: false
127
133
  version_requirements: !ruby/object:Gem::Requirement
128
134
  requirements:
129
135
  - - "~>"
130
136
  - !ruby/object:Gem::Version
131
- version: '3.0'
137
+ version: '3.8'
132
138
  - !ruby/object:Gem::Dependency
133
139
  name: rubocop
134
140
  requirement: !ruby/object:Gem::Requirement
135
141
  requirements:
136
142
  - - '='
137
143
  - !ruby/object:Gem::Version
138
- version: 0.60.0
144
+ version: 0.61.1
139
145
  type: :development
140
146
  prerelease: false
141
147
  version_requirements: !ruby/object:Gem::Requirement
142
148
  requirements:
143
149
  - - '='
144
150
  - !ruby/object:Gem::Version
145
- version: 0.60.0
151
+ version: 0.61.1
146
152
  description:
147
153
  email:
148
154
  - gonzalo@cedarcode.com
@@ -177,7 +183,9 @@ files:
177
183
  - lib/webauthn/authenticator_data/attested_credential_data/public_key_u2f.rb
178
184
  - lib/webauthn/authenticator_response.rb
179
185
  - lib/webauthn/client_data.rb
186
+ - lib/webauthn/error.rb
180
187
  - lib/webauthn/fake_authenticator.rb
188
+ - lib/webauthn/security_utils.rb
181
189
  - lib/webauthn/version.rb
182
190
  - webauthn.gemspec
183
191
  homepage: https://github.com/cedarcode/webauthn-ruby
@@ -202,8 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
210
  - !ruby/object:Gem::Version
203
211
  version: '0'
204
212
  requirements: []
205
- rubyforge_project:
206
- rubygems_version: 2.7.7
213
+ rubygems_version: 3.0.2
207
214
  signing_key:
208
215
  specification_version: 4
209
216
  summary: WebAuthn in ruby ― Ruby implementation of a WebAuthn Relying Party