webauthn 1.16.0 → 1.17.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/.rubocop.yml +0 -3
- data/CHANGELOG.md +8 -0
- data/README.md +9 -2
- data/lib/cose/algorithm.rb +6 -0
- data/lib/tpm/constants.rb +1 -0
- data/lib/webauthn/attestation_statement/tpm.rb +1 -1
- data/lib/webauthn/attestation_statement/tpm/pub_area.rb +2 -1
- data/lib/webauthn/authenticator_assertion_response.rb +16 -0
- data/lib/webauthn/fake_authenticator.rb +3 -1
- data/lib/webauthn/fake_client.rb +3 -2
- data/lib/webauthn/signature_verifier.rb +2 -2
- data/lib/webauthn/version.rb +1 -1
- data/webauthn.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4cc833d8288e0519614728a71e26e4e7842ec0c597bd7fc839fe9bacbb44c61
|
4
|
+
data.tar.gz: 712c9ad093705954409facf4ee171752ba76865cbca831121a0f88a4c4d9430c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fd66258429cadca7660ce7c69640b630b13bd21ac4b690d60c37834edcf4b6ce368688186f1b1a23fba8dc4856767314f7a7308e1ae9932f2f51776fabe89cb
|
7
|
+
data.tar.gz: a28362aa5cf1bd451a5b0303750bb55ffd80f2b47c63c9ef04b7f04e300c8b4f997ec0d6a808361503ecb0b780c263d2447c36bde0239657bc3cc5fd6b106719
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -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
|
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
|
data/lib/cose/algorithm.rb
CHANGED
@@ -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)
|
data/lib/tpm/constants.rb
CHANGED
@@ -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)
|
data/lib/webauthn/fake_client.rb
CHANGED
@@ -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:
|
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
|
data/lib/webauthn/version.rb
CHANGED
data/webauthn.gemspec
CHANGED
@@ -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.
|
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.
|
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-
|
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.
|
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.
|
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.
|
286
|
+
rubygems_version: 3.0.4
|
287
287
|
signing_key:
|
288
288
|
specification_version: 4
|
289
289
|
summary: WebAuthn ruby server library
|