webauthn 1.16.0 → 1.17.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: 42985c0e7686cf588be02d1afef8e315e0692561533f076e36419cd2ef3b2c74
4
- data.tar.gz: 3970cd2424034f2a28e1ffb92954151aa1ae113391731f63f9d1734c10a61bce
3
+ metadata.gz: d4cc833d8288e0519614728a71e26e4e7842ec0c597bd7fc839fe9bacbb44c61
4
+ data.tar.gz: 712c9ad093705954409facf4ee171752ba76865cbca831121a0f88a4c4d9430c
5
5
  SHA512:
6
- metadata.gz: 6993542bbc3ec899929f6ba5e13b34a347692f13da9efd7cab541de38e0473f2271c0c9e67085bd5e22439c59c97c7dc86680b7579cf578fd973eabc23fea2c4
7
- data.tar.gz: c30c9f9e9c43fddf01621eff5f1068b9ecc280649801a53ba7daa736fb1eb88724efaf8e50e4d8768544ce8b2a725318693eec3b84c6d8cef0137d8d712f6e85
6
+ metadata.gz: 6fd66258429cadca7660ce7c69640b630b13bd21ac4b690d60c37834edcf4b6ce368688186f1b1a23fba8dc4856767314f7a7308e1ae9932f2f51776fabe89cb
7
+ data.tar.gz: a28362aa5cf1bd451a5b0303750bb55ffd80f2b47c63c9ef04b7f04e300c8b4f997ec0d6a808361503ecb0b780c263d2447c36bde0239657bc3cc5fd6b106719
@@ -24,9 +24,6 @@ Metrics/LineLength:
24
24
  Naming:
25
25
  Enabled: true
26
26
 
27
- Performance:
28
- Enabled: true
29
-
30
27
  Security:
31
28
  Enabled: true
32
29
 
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.17.0] - 2019-06-18
4
+
5
+ ### Added
6
+
7
+ - Support ES384, ES512, PS384, PS512, RS384 and RS512 credentials. Off by default. Enable by adding any of them to `WebAuthn.configuration.algorithms` array. Thank you @bdewater.
8
+ - Support [Signature Counter](https://www.w3.org/TR/webauthn/#signature-counter) verification. Thank you @bdewater.
9
+
3
10
  ## [v1.16.0] - 2019-06-13
4
11
 
5
12
  ### Added
@@ -187,6 +194,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
187
194
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
188
195
  - Works with ruby 2.5
189
196
 
197
+ [v1.17.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.16.0...v1.17.0/
190
198
  [v1.16.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.15.0...v1.16.0/
191
199
  [v1.15.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.14.0...v1.15.0/
192
200
  [v1.14.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.13.0...v1.14.0/
data/README.md CHANGED
@@ -127,11 +127,12 @@ begin
127
127
  attestation_response.verify(expected_challenge)
128
128
 
129
129
  # 1. Register the new user and
130
- # 2. Keep Credential ID and Credential Public Key under storage
130
+ # 2. Keep Credential ID, Credential Public Key and Sign Count under storage
131
131
  # for future authentications
132
132
  # Access by invoking:
133
133
  # `attestation_response.credential.id`
134
134
  # `attestation_response.credential.public_key`
135
+ # `attestation_response.authenticator_data.sign_count`
135
136
  rescue WebAuthn::VerificationError => e
136
137
  # Handle error
137
138
  end
@@ -171,11 +172,13 @@ Assuming you have the previously stored Credential Public Key, now in variable `
171
172
  #
172
173
  # E.g. in https://github.com/cedarcode/webauthn-rails-demo-app we use `Base64.strict_decode64`
173
174
  # on the user-agent encoded data before calling `#verify`
175
+ selected_credential_id = "..."
174
176
  authenticator_data = "..."
175
177
  client_data_json = "..."
176
178
  signature = "..."
177
179
 
178
180
  assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
181
+ credential_id: selected_credential_id,
179
182
  authenticator_data: authenticator_data,
180
183
  client_data_json: client_data_json,
181
184
  signature: signature
@@ -185,7 +188,8 @@ assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
185
188
  # previously stored credential for the user that is attempting to sign in.
186
189
  allowed_credential = {
187
190
  id: credential_id,
188
- public_key: credential_public_key
191
+ public_key: credential_public_key,
192
+ sign_count: sign_count,
189
193
  }
190
194
 
191
195
  begin
@@ -195,6 +199,9 @@ begin
195
199
  rescue WebAuthn::VerificationError => e
196
200
  # Handle error
197
201
  end
202
+
203
+ # Find the selected credential in your data storage using `selected_credential_id`
204
+ # Update the stored sign count with the value from `assertion_response.authenticator_data.sign_count`
198
205
  ```
199
206
 
200
207
  ## Attestation Statement Formats
@@ -27,6 +27,12 @@ module COSE
27
27
  end
28
28
 
29
29
  COSE::Algorithm.register(-7, "ES256", "SHA256", COSE::Key::EC2::KTY_EC2, "prime256v1")
30
+ COSE::Algorithm.register(-35, "ES384", "SHA384", COSE::Key::EC2::KTY_EC2, "prime256v1")
31
+ COSE::Algorithm.register(-36, "ES512", "SHA512", COSE::Key::EC2::KTY_EC2, "prime256v1")
30
32
  COSE::Algorithm.register(-37, "PS256", "SHA256", COSE::Key::RSA::KTY_RSA)
33
+ COSE::Algorithm.register(-38, "PS384", "SHA384", COSE::Key::RSA::KTY_RSA)
34
+ COSE::Algorithm.register(-39, "PS512", "SHA512", COSE::Key::RSA::KTY_RSA)
31
35
  COSE::Algorithm.register(-257, "RS256", "SHA256", COSE::Key::RSA::KTY_RSA)
36
+ COSE::Algorithm.register(-258, "RS384", "SHA384", COSE::Key::RSA::KTY_RSA)
37
+ COSE::Algorithm.register(-259, "RS512", "SHA512", COSE::Key::RSA::KTY_RSA)
32
38
  COSE::Algorithm.register(-65535, "RS1", "SHA1", COSE::Key::RSA::KTY_RSA)
@@ -13,6 +13,7 @@ module TPM
13
13
  ALG_SHA256 = 0x000B
14
14
  ALG_NULL = 0x0010
15
15
  ALG_RSASSA = 0x0014
16
+ ALG_RSAPSS = 0x0016
16
17
  ALG_ECDSA = 0x0018
17
18
  ALG_ECC = 0x0023
18
19
 
@@ -40,7 +40,7 @@ module WebAuthn
40
40
  def valid_signature?
41
41
  WebAuthn::SignatureVerifier
42
42
  .new(algorithm, attestation_certificate.public_key)
43
- .verify(signature, verification_data)
43
+ .verify(signature, verification_data, rsa_pss_salt_length: :auto)
44
44
  end
45
45
 
46
46
  def valid_attestation_certificate?
@@ -17,7 +17,8 @@ module WebAuthn
17
17
  }.freeze
18
18
 
19
19
  COSE_RSA_TO_TPM_ALG = {
20
- COSE::Algorithm.by_name("RS256").id => ::TPM::ALG_RSASSA
20
+ COSE::Algorithm.by_name("RS256").id => ::TPM::ALG_RSASSA,
21
+ COSE::Algorithm.by_name("PS256").id => ::TPM::ALG_RSAPSS,
21
22
  }.freeze
22
23
 
23
24
  COSE_TO_TPM_CURVE = {
@@ -10,6 +10,7 @@ require "webauthn/signature_verifier"
10
10
  module WebAuthn
11
11
  class CredentialVerificationError < VerificationError; end
12
12
  class SignatureVerificationError < VerificationError; end
13
+ class SignCountVerificationError < VerificationError; end
13
14
 
14
15
  class AuthenticatorAssertionResponse < AuthenticatorResponse
15
16
  def initialize(credential_id:, authenticator_data:, signature:, **options)
@@ -25,6 +26,7 @@ module WebAuthn
25
26
 
26
27
  verify_item(:credential, allowed_credentials)
27
28
  verify_item(:signature, credential_cose_key(allowed_credentials))
29
+ verify_item(:sign_count, allowed_credentials)
28
30
 
29
31
  true
30
32
  end
@@ -43,6 +45,20 @@ module WebAuthn
43
45
  .verify(signature, authenticator_data_bytes + client_data.hash)
44
46
  end
45
47
 
48
+ def valid_sign_count?(allowed_credentials)
49
+ matched_credential = allowed_credentials.find do |credential|
50
+ credential[:id] == credential_id
51
+ end
52
+ # TODO: make passing sign count mandatory in next major version
53
+ stored_sign_count = matched_credential.fetch(:sign_count, 0)
54
+
55
+ if authenticator_data.sign_count.nonzero? || stored_sign_count.nonzero?
56
+ authenticator_data.sign_count > stored_sign_count
57
+ else
58
+ true
59
+ end
60
+ end
61
+
46
62
  def valid_credential?(allowed_credentials)
47
63
  allowed_credential_ids = allowed_credentials.map { |credential| credential[:id] }
48
64
 
@@ -35,7 +35,8 @@ module WebAuthn
35
35
  client_data_hash:,
36
36
  user_present: true,
37
37
  user_verified: false,
38
- aaguid: AuthenticatorData::AAGUID
38
+ aaguid: AuthenticatorData::AAGUID,
39
+ sign_count: 0
39
40
  )
40
41
  credential_options = credentials[rp_id]
41
42
 
@@ -47,6 +48,7 @@ module WebAuthn
47
48
  user_present: user_present,
48
49
  user_verified: user_verified,
49
50
  aaguid: aaguid,
51
+ sign_count: sign_count,
50
52
  ).serialize
51
53
 
52
54
  signature = credential_key.sign("SHA256", authenticator_data + client_data_hash)
@@ -41,7 +41,7 @@ module WebAuthn
41
41
  }
42
42
  end
43
43
 
44
- def get(challenge: fake_challenge, rp_id: nil, user_present: true, user_verified: false)
44
+ def get(challenge: fake_challenge, rp_id: nil, user_present: true, user_verified: false, sign_count: 0)
45
45
  rp_id ||= URI.parse(origin).host
46
46
 
47
47
  client_data_json = data_json_for(:get, challenge)
@@ -51,7 +51,8 @@ module WebAuthn
51
51
  rp_id: rp_id,
52
52
  client_data_hash: client_data_hash,
53
53
  user_present: user_present,
54
- user_verified: user_verified
54
+ user_verified: user_verified,
55
+ sign_count: sign_count,
55
56
  )
56
57
 
57
58
  {
@@ -22,10 +22,10 @@ module WebAuthn
22
22
  validate
23
23
  end
24
24
 
25
- def verify(signature, verification_data)
25
+ def verify(signature, verification_data, rsa_pss_salt_length: :digest)
26
26
  if rsa_pss?
27
27
  public_key.verify_pss(cose_algorithm.hash, signature, verification_data,
28
- salt_length: :digest, mgf1_hash: cose_algorithm.hash)
28
+ salt_length: rsa_pss_salt_length, mgf1_hash: cose_algorithm.hash)
29
29
  else
30
30
  public_key.verify(cose_algorithm.hash, signature, verification_data)
31
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "1.16.0"
4
+ VERSION = "1.17.0"
5
5
  end
@@ -43,5 +43,5 @@ Gem::Specification.new do |spec|
43
43
  spec.add_development_dependency "byebug", "~> 11.0"
44
44
  spec.add_development_dependency "rake", "~> 12.3"
45
45
  spec.add_development_dependency "rspec", "~> 3.8"
46
- spec.add_development_dependency "rubocop", "0.67.2"
46
+ spec.add_development_dependency "rubocop", "0.71.0"
47
47
  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.16.0
4
+ version: 1.17.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: 2019-06-13 00:00:00.000000000 Z
12
+ date: 2019-06-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bindata
@@ -183,14 +183,14 @@ dependencies:
183
183
  requirements:
184
184
  - - '='
185
185
  - !ruby/object:Gem::Version
186
- version: 0.67.2
186
+ version: 0.71.0
187
187
  type: :development
188
188
  prerelease: false
189
189
  version_requirements: !ruby/object:Gem::Requirement
190
190
  requirements:
191
191
  - - '='
192
192
  - !ruby/object:Gem::Version
193
- version: 0.67.2
193
+ version: 0.71.0
194
194
  description: |-
195
195
  WebAuthn ruby server library ― Make your application a W3C Web Authentication conformant
196
196
  Relying Party and allow your users to authenticate with U2F and FIDO 2.0 authenticators.
@@ -283,7 +283,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
283
  - !ruby/object:Gem::Version
284
284
  version: '0'
285
285
  requirements: []
286
- rubygems_version: 3.0.3
286
+ rubygems_version: 3.0.4
287
287
  signing_key:
288
288
  specification_version: 4
289
289
  summary: WebAuthn ruby server library