webauthn 2.0.0.beta1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +65 -13
- data/.travis.yml +22 -18
- data/Appraisals +4 -0
- data/CHANGELOG.md +72 -25
- data/CONTRIBUTING.md +0 -5
- data/README.md +172 -15
- data/SECURITY.md +4 -4
- data/gemfiles/openssl_2_2.gemfile +7 -0
- data/lib/cose/rsapkcs1_algorithm.rb +43 -0
- data/lib/webauthn/attestation_object.rb +43 -0
- data/lib/webauthn/attestation_statement.rb +20 -20
- data/lib/webauthn/attestation_statement/android_key.rb +28 -30
- data/lib/webauthn/attestation_statement/android_safetynet.rb +30 -20
- data/lib/webauthn/attestation_statement/base.rb +124 -14
- data/lib/webauthn/attestation_statement/fido_u2f.rb +13 -9
- data/lib/webauthn/attestation_statement/packed.rb +14 -42
- data/lib/webauthn/attestation_statement/tpm.rb +38 -54
- data/lib/webauthn/authenticator_assertion_response.rb +7 -36
- data/lib/webauthn/authenticator_attestation_response.rb +24 -46
- data/lib/webauthn/authenticator_data.rb +51 -51
- data/lib/webauthn/authenticator_data/attested_credential_data.rb +29 -50
- data/lib/webauthn/authenticator_response.rb +15 -10
- data/lib/webauthn/configuration.rb +23 -0
- data/lib/webauthn/credential.rb +4 -4
- data/lib/webauthn/credential_creation_options.rb +1 -1
- data/lib/webauthn/fake_authenticator.rb +7 -3
- data/lib/webauthn/fake_authenticator/attestation_object.rb +7 -3
- data/lib/webauthn/fake_authenticator/authenticator_data.rb +2 -4
- data/lib/webauthn/fake_client.rb +17 -4
- data/lib/webauthn/public_key.rb +68 -0
- data/lib/webauthn/public_key_credential.rb +13 -3
- data/lib/webauthn/public_key_credential/creation_options.rb +2 -2
- data/lib/webauthn/u2f_migrator.rb +5 -4
- data/lib/webauthn/version.rb +1 -1
- data/script/ci/install-openssl +7 -0
- data/script/ci/install-ruby +13 -0
- data/webauthn.gemspec +14 -9
- metadata +70 -42
- data/lib/android_safetynet/attestation_response.rb +0 -84
- data/lib/cose/algorithm.rb +0 -38
- data/lib/tpm/constants.rb +0 -22
- data/lib/tpm/s_attest.rb +0 -26
- data/lib/tpm/s_attest/s_certify_info.rb +0 -14
- data/lib/tpm/sized_buffer.rb +0 -13
- data/lib/tpm/t_public.rb +0 -32
- data/lib/tpm/t_public/s_ecc_parms.rb +0 -17
- data/lib/tpm/t_public/s_rsa_parms.rb +0 -17
- data/lib/webauthn/attestation_statement/android_key/authorization_list.rb +0 -39
- data/lib/webauthn/attestation_statement/android_key/key_description.rb +0 -37
- data/lib/webauthn/attestation_statement/tpm/cert_info.rb +0 -44
- data/lib/webauthn/attestation_statement/tpm/pub_area.rb +0 -85
- data/lib/webauthn/signature_verifier.rb +0 -65
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4094023fc463d77a38548e294121f819e874bfb1c075ca43b1fb38e41cfd53a2
|
4
|
+
data.tar.gz: f410f8d7e000822943be953265a32e8f81423908e6aff282486d5afa4ab62eb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23ea57e2264cc45024174e8d7a54bc3d4f373cca916c4453079d5cfccf46caa4dbc5aa4013a54404121274a35e71f97f90a061062a21ca270a8b58d474345fb8
|
7
|
+
data.tar.gz: 3b49c5b5b845fdcfc3b0b647a16aeab07ad219210e8e29835d171e387d6bcc4ac5fe08a4f9d2978ee6db1022363d1c2b06fe0a163a8625038aca51e1d274e903
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
|
1
4
|
inherit_mode:
|
2
5
|
merge:
|
3
6
|
- AllowedNames
|
4
7
|
|
5
8
|
AllCops:
|
6
|
-
TargetRubyVersion: 2.
|
9
|
+
TargetRubyVersion: 2.4
|
7
10
|
DisabledByDefault: true
|
8
11
|
Exclude:
|
9
12
|
- "gemfiles/**/*"
|
13
|
+
- "vendor/**/*"
|
10
14
|
|
11
15
|
Bundler:
|
12
16
|
Enabled: true
|
@@ -17,18 +21,69 @@ Gemspec:
|
|
17
21
|
Layout:
|
18
22
|
Enabled: true
|
19
23
|
|
20
|
-
|
24
|
+
Layout/ClassStructure:
|
25
|
+
Enabled: true
|
26
|
+
|
27
|
+
Layout/FirstMethodArgumentLineBreak:
|
21
28
|
Enabled: true
|
22
29
|
|
23
|
-
|
30
|
+
Layout/LineLength:
|
24
31
|
Max: 120
|
25
32
|
Exclude:
|
26
33
|
- spec/support/seeds.rb
|
27
34
|
|
35
|
+
Layout/MultilineAssignmentLayout:
|
36
|
+
Enabled: true
|
37
|
+
|
38
|
+
Layout/MultilineMethodArgumentLineBreaks:
|
39
|
+
Enabled: true
|
40
|
+
|
41
|
+
Lint:
|
42
|
+
Enabled: true
|
43
|
+
|
28
44
|
Naming:
|
29
45
|
Enabled: true
|
30
46
|
|
31
|
-
|
47
|
+
RSpec/Be:
|
48
|
+
Enabled: true
|
49
|
+
|
50
|
+
RSpec/BeforeAfterAll:
|
51
|
+
Enabled: true
|
52
|
+
|
53
|
+
RSpec/EmptyExampleGroup:
|
54
|
+
Enabled: true
|
55
|
+
|
56
|
+
RSpec/EmptyLineAfterExample:
|
57
|
+
Enabled: true
|
58
|
+
|
59
|
+
RSpec/EmptyLineAfterExampleGroup:
|
60
|
+
Enabled: true
|
61
|
+
|
62
|
+
RSpec/EmptyLineAfterFinalLet:
|
63
|
+
Enabled: true
|
64
|
+
|
65
|
+
RSpec/EmptyLineAfterHook:
|
66
|
+
Enabled: true
|
67
|
+
|
68
|
+
RSpec/EmptyLineAfterSubject:
|
69
|
+
Enabled: true
|
70
|
+
|
71
|
+
RSpec/HookArgument:
|
72
|
+
Enabled: true
|
73
|
+
|
74
|
+
RSpec/LeadingSubject:
|
75
|
+
Enabled: true
|
76
|
+
|
77
|
+
RSpec/NamedSubject:
|
78
|
+
Enabled: true
|
79
|
+
|
80
|
+
RSpec/ScatteredLet:
|
81
|
+
Enabled: true
|
82
|
+
|
83
|
+
RSpec/ScatteredSetup:
|
84
|
+
Enabled: true
|
85
|
+
|
86
|
+
Naming/MethodParameterName:
|
32
87
|
AllowedNames:
|
33
88
|
- rp
|
34
89
|
|
@@ -38,9 +93,6 @@ Security:
|
|
38
93
|
Style/BlockComments:
|
39
94
|
Enabled: true
|
40
95
|
|
41
|
-
Style/BracesAroundHashParameters:
|
42
|
-
Enabled: true
|
43
|
-
|
44
96
|
Style/CaseEquality:
|
45
97
|
Enabled: true
|
46
98
|
|
@@ -146,9 +198,15 @@ Style/RedundantException:
|
|
146
198
|
Style/RedundantFreeze:
|
147
199
|
Enabled: true
|
148
200
|
|
201
|
+
Style/RedundantInterpolation:
|
202
|
+
Enabled: true
|
203
|
+
|
149
204
|
Style/RedundantParentheses:
|
150
205
|
Enabled: true
|
151
206
|
|
207
|
+
Style/RedundantPercentQ:
|
208
|
+
Enabled: true
|
209
|
+
|
152
210
|
Style/RedundantReturn:
|
153
211
|
Enabled: true
|
154
212
|
|
@@ -182,12 +240,6 @@ Style/TrailingMethodEndStatement:
|
|
182
240
|
Style/TrivialAccessors:
|
183
241
|
Enabled: true
|
184
242
|
|
185
|
-
Style/UnneededInterpolation:
|
186
|
-
Enabled: true
|
187
|
-
|
188
|
-
Style/UnneededPercentQ:
|
189
|
-
Enabled: true
|
190
|
-
|
191
243
|
Style/UnpackFirst:
|
192
244
|
Enabled: true
|
193
245
|
|
data/.travis.yml
CHANGED
@@ -1,35 +1,39 @@
|
|
1
|
-
dist:
|
1
|
+
dist: bionic
|
2
2
|
language: ruby
|
3
|
-
cache: bundler
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
- 2.
|
4
|
+
cache:
|
5
|
+
bundler: true
|
6
|
+
directories:
|
7
|
+
- /home/travis/.rvm/
|
8
|
+
|
9
|
+
env:
|
10
|
+
- LIBSSL=1.1 RB=2.7.1
|
11
|
+
- LIBSSL=1.1 RB=2.6.6
|
12
|
+
- LIBSSL=1.1 RB=2.5.8
|
13
|
+
- LIBSSL=1.1 RB=2.4.10
|
14
|
+
- LIBSSL=1.1 RB=ruby-head
|
15
|
+
- LIBSSL=1.0 RB=2.7.1
|
16
|
+
- LIBSSL=1.0 RB=2.6.6
|
17
|
+
- LIBSSL=1.0 RB=2.5.8
|
18
|
+
- LIBSSL=1.0 RB=2.4.10
|
19
|
+
- LIBSSL=1.0 RB=ruby-head
|
12
20
|
|
13
21
|
gemfile:
|
14
22
|
- gemfiles/cose_head.gemfile
|
15
23
|
- gemfiles/openssl_head.gemfile
|
24
|
+
- gemfiles/openssl_2_2.gemfile
|
16
25
|
- gemfiles/openssl_2_1.gemfile
|
17
26
|
- gemfiles/openssl_2_0.gemfile
|
18
27
|
|
19
28
|
matrix:
|
20
29
|
fast_finish: true
|
21
30
|
allow_failures:
|
22
|
-
-
|
23
|
-
-
|
31
|
+
- env: LIBSSL=1.1 RB=ruby-head
|
32
|
+
- env: LIBSSL=1.0 RB=ruby-head
|
24
33
|
- gemfile: gemfiles/cose_head.gemfile
|
25
34
|
- gemfile: gemfiles/openssl_head.gemfile
|
26
35
|
|
27
36
|
before_install:
|
28
|
-
-
|
29
|
-
-
|
37
|
+
- ./script/ci/install-openssl
|
38
|
+
- ./script/ci/install-ruby
|
30
39
|
- gem install bundler -v "~> 2.0"
|
31
|
-
|
32
|
-
before_script:
|
33
|
-
- export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1
|
34
|
-
- export DONT_FAKE_MONOTONIC=1
|
35
|
-
- export FAKETIME_NO_CACHE=1
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,39 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [v2.
|
3
|
+
## [v2.3.0] - 2020-06-27
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Ability to access extension outputs with `PublicKeyCredential#client_extension_outputs` and `PublicKeyCredential#authenticator_extension_outputs` ([@santiagorodriguez96])
|
8
|
+
|
9
|
+
## [v2.2.1] - 2020-06-06
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- Fixed compatibility with OpenSSL-C (libssl) v1.0.2 ([@santiagorodriguez96])
|
14
|
+
|
15
|
+
## [v2.2.0] - 2020-03-14
|
16
|
+
|
17
|
+
### Added
|
18
|
+
|
19
|
+
- Verification step that checks the received credential public key algorithm during registration matches one of the configured algorithms
|
20
|
+
- [EXPERIMENTAL] Attestation trustworthiness verification default steps for "tpm", "android-key" and "android-safetynet" ([@bdewater], [@padulafacundo]). Still manual configuration needed for "packed" and "fido-u2f".
|
21
|
+
|
22
|
+
Note: Expect possible breaking changes for "EXPERIMENTAL" features.
|
23
|
+
|
24
|
+
## [v2.1.0] - 2019-12-30
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- Ability to convert stored credential public key back to a ruby object with `WebAuthn::PublicKey.deserialize(stored_public_key)`, included the validation during de-serialization ([@ssuttner], [@padulafacundo])
|
29
|
+
- Improved TPM attestation validation by checking "Subject Alternative Name" ([@bdewater])
|
30
|
+
- Improved SafetyNet attestation validation by checking timestamp ([@padulafacundo])
|
31
|
+
- [EXPERIMENTAL] Ability to optionally "Assess the attestation trustworthiness" during registration by setting `acceptable_attestation_types` and `attestation_root_certificates_finders` configuration values ([@padulafacundo])
|
32
|
+
- Ruby 2.7 support without warnings
|
33
|
+
|
34
|
+
Note: Expect possible breaking changes for "EXPERIMENTAL" features.
|
35
|
+
|
36
|
+
## [v2.0.0] - 2019-10-03
|
4
37
|
|
5
38
|
### Added
|
6
39
|
|
@@ -13,7 +46,7 @@
|
|
13
46
|
- All the above automatically handle encoding/decoding for necessary values. The specific encoding scheme can
|
14
47
|
be set (or even turned off) in `WebAutnn.configuration.encoding=`. Defaults to `:base64url`.
|
15
48
|
- `WebAuthn::FakeClient#get` better fakes a real client by including `userHandle` in the returned hash.
|
16
|
-
- Expose AAGUID and attestationCertificateKey for MDS lookup during attestation (@
|
49
|
+
- Expose AAGUID and attestationCertificateKey for MDS lookup during attestation ([@bdewater])
|
17
50
|
|
18
51
|
### Changed
|
19
52
|
|
@@ -21,8 +54,9 @@
|
|
21
54
|
Please replace with `public_key:` and `sign_count:` keyword arguments. If you're not performing sign count
|
22
55
|
verification, signal opt-out with `sign_count: false`.
|
23
56
|
|
24
|
-
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by using
|
25
|
-
keys instead of snake_case symbol keys in the returned hash.
|
57
|
+
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by using lowerCamelCase
|
58
|
+
string keys instead of snake_case symbol keys in the returned hash.
|
59
|
+
|
26
60
|
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by not padding the
|
27
61
|
returned base64url-encoded `id` value.
|
28
62
|
|
@@ -45,8 +79,8 @@ pass it.
|
|
45
79
|
Please replace with `public_key:` and `sign_count:` keyword arguments. If you're not performing sign count
|
46
80
|
verification, signal opt-out with `sign_count: false`.
|
47
81
|
|
48
|
-
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by using
|
49
|
-
keys instead of snake_case symbol keys in the returned hash.
|
82
|
+
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by using lowerCamelCase
|
83
|
+
string keys instead of snake_case symbol keys in the returned hash.
|
50
84
|
|
51
85
|
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by not padding the
|
52
86
|
returned base64url-encoded `id` value.
|
@@ -55,23 +89,23 @@ returned base64url-encoded `id` value.
|
|
55
89
|
|
56
90
|
### Added
|
57
91
|
|
58
|
-
- Ability to migrate U2F credentials to WebAuthn ([#211](https://github.com/cedarcode/webauthn-ruby/pull/211)) (@bdewater + @jdongelmans)
|
59
|
-
- Ability to skip attestation statement verification ([#219](https://github.com/cedarcode/webauthn-ruby/pull/219)) (@MaximeNdutiye)
|
60
|
-
- Ability to configure default credential options timeout ([#243](https://github.com/cedarcode/webauthn-ruby/pull/243)) (@MaximeNdutiye)
|
92
|
+
- Ability to migrate U2F credentials to WebAuthn ([#211](https://github.com/cedarcode/webauthn-ruby/pull/211)) ([@bdewater] + [@jdongelmans])
|
93
|
+
- Ability to skip attestation statement verification ([#219](https://github.com/cedarcode/webauthn-ruby/pull/219)) ([@MaximeNdutiye])
|
94
|
+
- Ability to configure default credential options timeout ([#243](https://github.com/cedarcode/webauthn-ruby/pull/243)) ([@MaximeNdutiye])
|
61
95
|
- AttestedCredentialData presence verification ([#237](https://github.com/cedarcode/webauthn-ruby/pull/237))
|
62
96
|
- FakeClient learns how to increment sign count ([#225](https://github.com/cedarcode/webauthn-ruby/pull/225))
|
63
97
|
|
64
98
|
### Fixed
|
65
99
|
|
66
|
-
- Properly verify SafetyNet certificates from input ([#233](https://github.com/cedarcode/webauthn-ruby/pull/233)) (@bdewater)
|
67
|
-
- FakeClient default origin URL ([#242](https://github.com/cedarcode/webauthn-ruby/pull/242)) (@kalebtesfay)
|
100
|
+
- Properly verify SafetyNet certificates from input ([#233](https://github.com/cedarcode/webauthn-ruby/pull/233)) ([@bdewater])
|
101
|
+
- FakeClient default origin URL ([#242](https://github.com/cedarcode/webauthn-ruby/pull/242)) ([@kalebtesfay])
|
68
102
|
|
69
103
|
## [v1.17.0] - 2019-06-18
|
70
104
|
|
71
105
|
### Added
|
72
106
|
|
73
|
-
- Support ES384, ES512, PS384, PS512, RS384 and RS512 credentials. Off by default. Enable by adding any of them to `WebAuthn.configuration.algorithms` array
|
74
|
-
- Support [Signature Counter](https://www.w3.org/TR/webauthn/#signature-counter) verification
|
107
|
+
- Support ES384, ES512, PS384, PS512, RS384 and RS512 credentials. Off by default. Enable by adding any of them to `WebAuthn.configuration.algorithms` array ([@bdewater])
|
108
|
+
- Support [Signature Counter](https://www.w3.org/TR/webauthn/#signature-counter) verification ([@bdewater])
|
75
109
|
|
76
110
|
## [v1.16.0] - 2019-06-13
|
77
111
|
|
@@ -79,7 +113,7 @@ returned base64url-encoded `id` value.
|
|
79
113
|
|
80
114
|
- Ability to enforce [user verification](https://www.w3.org/TR/webauthn/#user-verification) with extra argument in the `#verify` method.
|
81
115
|
- Support RS1 (RSA w/ SHA-1) credentials. Off by default. Enable by adding `"RS1"` to `WebAuthn.configuration.algorithms` array.
|
82
|
-
- Support PS256 (RSA Probabilistic Signature Scheme w/ SHA-256) credentials. On by default
|
116
|
+
- Support PS256 (RSA Probabilistic Signature Scheme w/ SHA-256) credentials. On by default ([@bdewater])
|
83
117
|
|
84
118
|
## [v1.15.0] - 2019-05-16
|
85
119
|
|
@@ -101,11 +135,11 @@ returned base64url-encoded `id` value.
|
|
101
135
|
- Verify 'none' attestation statement is really empty.
|
102
136
|
- Verify 'packed' attestation statement certificates start/end dates.
|
103
137
|
- Verify 'packed' attestation statement signature algorithm.
|
104
|
-
- Verify 'fiod-u2f attestation statement AAGUID is zeroed out
|
138
|
+
- Verify 'fiod-u2f attestation statement AAGUID is zeroed out ([@bdewater])
|
105
139
|
- Verify 'android-key' attestation statement signature algorithm.
|
106
140
|
- Verify assertion response signature algorithm.
|
107
141
|
- Verify collectedClientData.tokenBinding format.
|
108
|
-
- `WebAuthn.credential_creation_options` now accept `rp_name`, `user_id`, `user_name` and `display_name` as keyword arguments
|
142
|
+
- `WebAuthn.credential_creation_options` now accept `rp_name`, `user_id`, `user_name` and `display_name` as keyword arguments ([@bdewater])
|
109
143
|
|
110
144
|
## [v1.12.0] - 2019-04-03
|
111
145
|
|
@@ -127,11 +161,11 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
|
|
127
161
|
|
128
162
|
### Added
|
129
163
|
|
130
|
-
- `WebAuthn::AuthenticatorAttestationResponse#verify` supports `android-key` attestation statements
|
164
|
+
- `WebAuthn::AuthenticatorAttestationResponse#verify` supports `android-key` attestation statements ([@bdewater])
|
131
165
|
|
132
166
|
### Fixed
|
133
167
|
|
134
|
-
- Verify matching AAGUID if needed when verifying `packed` attestation statements
|
168
|
+
- Verify matching AAGUID if needed when verifying `packed` attestation statements ([@bdewater])
|
135
169
|
|
136
170
|
## [v1.10.0] - 2019-03-05
|
137
171
|
|
@@ -149,7 +183,7 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
|
|
149
183
|
|
150
184
|
### Added
|
151
185
|
|
152
|
-
- Make challenge validation inside `#valid?` method resistant to timing attacks
|
186
|
+
- Make challenge validation inside `#valid?` method resistant to timing attacks (@tomek-bt)
|
153
187
|
- Support for ruby 2.6
|
154
188
|
|
155
189
|
### Changed
|
@@ -161,7 +195,7 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
|
|
161
195
|
### Added
|
162
196
|
|
163
197
|
- _Registration_ ceremony
|
164
|
-
- `WebAuthn::AuthenticatorAttestationResponse` exposes attestation type and trust path via `#attestation_type` and `#attestation_trust_path` methods
|
198
|
+
- `WebAuthn::AuthenticatorAttestationResponse` exposes attestation type and trust path via `#attestation_type` and `#attestation_trust_path` methods ([@bdewater])
|
165
199
|
|
166
200
|
## [v1.6.0] - 2018-11-01
|
167
201
|
|
@@ -173,21 +207,21 @@ Note #2: You don't need to do any convesion before passing the public key in `Au
|
|
173
207
|
|
174
208
|
### Added
|
175
209
|
|
176
|
-
- Works with ruby 2.3
|
210
|
+
- Works with ruby 2.3 ([@bdewater])
|
177
211
|
|
178
212
|
## [v1.4.0] - 2018-10-11
|
179
213
|
|
180
214
|
### Added
|
181
215
|
|
182
216
|
- _Registration_ ceremony
|
183
|
-
- `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `android-safetynet` attestation statements
|
217
|
+
- `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `android-safetynet` attestation statements ([@bdewater])
|
184
218
|
|
185
219
|
## [v1.3.0] - 2018-10-11
|
186
220
|
|
187
221
|
### Added
|
188
222
|
|
189
223
|
- _Registration_ ceremony
|
190
|
-
- `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `packed` attestation statements
|
224
|
+
- `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `packed` attestation statements ([@sorah])
|
191
225
|
|
192
226
|
## [v1.2.0] - 2018-10-08
|
193
227
|
|
@@ -205,7 +239,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
|
|
205
239
|
### Added
|
206
240
|
|
207
241
|
- _Registration_ ceremony
|
208
|
-
- `WebAuthn::AuthenticatorAttestationResponse.valid?` optionally accepts rp_id
|
242
|
+
- `WebAuthn::AuthenticatorAttestationResponse.valid?` optionally accepts rp_id ([@sorah])
|
209
243
|
- _Authentication_ ceremony
|
210
244
|
- `WebAuthn::AuthenticatorAssertionResponse.valid?` optionally accepts rp_id.
|
211
245
|
|
@@ -260,7 +294,11 @@ Note: Both additions should help making it compatible with Chrome for Android 70
|
|
260
294
|
- `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
|
261
295
|
- Works with ruby 2.5
|
262
296
|
|
263
|
-
[v2.
|
297
|
+
[v2.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.2.1...v2.3.0/
|
298
|
+
[v2.2.1]: https://github.com/cedarcode/webauthn-ruby/compare/v2.2.0...v2.2.1/
|
299
|
+
[v2.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.1.0...v2.2.0/
|
300
|
+
[v2.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v2.0.0...v2.1.0/
|
301
|
+
[v2.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.18.0...v2.0.0/
|
264
302
|
[v1.18.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.17.0...v1.18.0/
|
265
303
|
[v1.17.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.16.0...v1.17.0/
|
266
304
|
[v1.16.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.15.0...v1.16.0/
|
@@ -282,3 +320,12 @@ Note: Both additions should help making it compatible with Chrome for Android 70
|
|
282
320
|
[v1.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.2.0...v1.0.0/
|
283
321
|
[v0.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.1.0...v0.2.0/
|
284
322
|
[v0.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.0.0...v0.1.0/
|
323
|
+
|
324
|
+
[@bdewater]: https://github.com/bdewater
|
325
|
+
[@jdongelmans]: https://github.com/jdongelmans
|
326
|
+
[@kalebtesfay]: https://github.com/kalebtesfay
|
327
|
+
[@MaximeNdutiye]: https://github.com/MaximeNdutiye
|
328
|
+
[@sorah]: https://github.com/sorah
|
329
|
+
[@ssuttner]: https://github.com/ssuttner
|
330
|
+
[@padulafacundo]: https://github.com/padulafacundo
|
331
|
+
[@santiagorodriguez96]: https://github.com/santiagorodriguez96
|
data/CONTRIBUTING.md
CHANGED
@@ -14,11 +14,6 @@
|
|
14
14
|
|
15
15
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests and code-style checks. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
16
16
|
|
17
|
-
Some tests require stubbing time with [libfaketime](https://github.com/wolfcw/libfaketime) in order to pass, otherwise they're skipped. You can install this library with your package manager. Follow libfaketime's instructions for your OS to preload the library before running the tests, and use the `DONT_FAKE_MONOTONIC=1 FAKETIME_NO_CACHE=1` options. E.g. when installed via homebrew on macOS:
|
18
|
-
```shell
|
19
|
-
DYLD_INSERT_LIBRARIES=/usr/local/Cellar/libfaketime/2.9.7_1/lib/faketime/libfaketime.1.dylib DYLD_FORCE_FLAT_NAMESPACE=1 DONT_FAKE_MONOTONIC=1 FAKETIME_NO_CACHE=1 bundle exec rspec
|
20
|
-
```
|
21
|
-
|
22
17
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
23
18
|
|
24
19
|
### Styleguide
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
__Note__: You are viewing the README for the development version of webauthn-ruby.
|
2
|
-
For the current release version see https://github.com/cedarcode/webauthn-ruby/blob/
|
2
|
+
For the current release version see https://github.com/cedarcode/webauthn-ruby/blob/2-stable/README.md.
|
3
3
|
|
4
4
|
# webauthn-ruby
|
5
5
|
|
@@ -64,12 +64,12 @@ Known conformant pairs are, for example:
|
|
64
64
|
- Google Chrome for Android 70+ and Android's Fingerprint-based platform authenticator
|
65
65
|
- Microsoft Edge and Windows 10 platform authenticator
|
66
66
|
- Mozilla Firefox for Desktop and Yubico's Security Key roaming authenticator via USB
|
67
|
+
- Safari in iOS 13.3+ and YubiKey 5 NFC via NFC
|
67
68
|
|
68
|
-
For a
|
69
|
-
|
70
|
-
- [apowers313/fido2-webauthn-status](https://github.com/apowers313/fido2-webauthn-status)
|
71
|
-
- [FIDO certified products](https://fidoalliance.org/certification/fido-certified-products)
|
69
|
+
For a complete list:
|
72
70
|
|
71
|
+
- User Agents (Clients): [Can I Use: Web Authentication API](https://caniuse.com/#search=webauthn)
|
72
|
+
- Authenticators: [FIDO certified products](https://fidoalliance.org/certification/fido-certified-products) (search for Type=Authenticator and Specification=FIDO2)
|
73
73
|
|
74
74
|
## Install
|
75
75
|
|
@@ -108,11 +108,11 @@ WebAuthn.configure do |config|
|
|
108
108
|
config.rp_name = "Example Inc."
|
109
109
|
|
110
110
|
# Optionally configure a client timeout hint, in milliseconds.
|
111
|
-
# This hint specifies how long the browser should wait for
|
112
|
-
#
|
111
|
+
# This hint specifies how long the browser should wait for any
|
112
|
+
# interaction with the user.
|
113
113
|
# This hint may be overridden by the browser.
|
114
114
|
# https://www.w3.org/TR/webauthn/#dom-publickeycredentialcreationoptions-timeout
|
115
|
-
config.credential_options_timeout =
|
115
|
+
# config.credential_options_timeout = 120_000
|
116
116
|
|
117
117
|
# You can optionally specify a different Relying Party ID
|
118
118
|
# (https://www.w3.org/TR/webauthn/#relying-party-identifier)
|
@@ -127,7 +127,12 @@ WebAuthn.configure do |config|
|
|
127
127
|
# used in your client-side (user agent) code before sending the credential to the server.
|
128
128
|
# Supported values: `:base64url` (default), `:base64` or `false` to disable all encoding.
|
129
129
|
#
|
130
|
-
# config.encoding =
|
130
|
+
# config.encoding = :base64url
|
131
|
+
|
132
|
+
# Possible values: "ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "RS256", "RS384", "RS512", "RS1"
|
133
|
+
# Default: ["ES256", "PS256", "RS256"]
|
134
|
+
#
|
135
|
+
# config.algorithms << "ES384"
|
131
136
|
end
|
132
137
|
```
|
133
138
|
|
@@ -145,7 +150,7 @@ if !user.webauthn_id
|
|
145
150
|
end
|
146
151
|
|
147
152
|
options = WebAuthn::Credential.options_for_create(
|
148
|
-
user: { id: user.webauthn_id, name: user.name }
|
153
|
+
user: { id: user.webauthn_id, name: user.name },
|
149
154
|
exclude: user.credentials.map { |c| c.webauthn_id }
|
150
155
|
)
|
151
156
|
|
@@ -247,25 +252,177 @@ rescue WebAuthn::Error => e
|
|
247
252
|
end
|
248
253
|
```
|
249
254
|
|
255
|
+
### Extensions
|
256
|
+
|
257
|
+
> The mechanism for generating public key credentials, as well as requesting and generating Authentication assertions, as defined in Web Authentication API, can be extended to suit particular use cases. Each case is addressed by defining a registration extension and/or an authentication extension.
|
258
|
+
|
259
|
+
> When creating a public key credential or requesting an authentication assertion, a WebAuthn Relying Party can request the use of a set of extensions. These extensions will be invoked during the requested ceremony if they are supported by the WebAuthn Client and/or the WebAuthn Authenticator. The Relying Party sends the client extension input for each extension in the get() call (for authentication extensions) or create() call (for registration extensions) to the WebAuthn client. [[source](https://www.w3.org/TR/webauthn-2/#sctn-extensions)]
|
260
|
+
|
261
|
+
Extensions can be requested in the initiation phase in both Credential Registration and Authentication ceremonies by adding the extension parameter when generating the options for create/get:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
# Credential Registration
|
265
|
+
creation_options = WebAuthn::Credential.options_for_create(
|
266
|
+
user: { id: user.webauthn_id, name: user.name },
|
267
|
+
exclude: user.credentials.map { |c| c.webauthn_id },
|
268
|
+
extensions: { appidExclude: domain.to_s }
|
269
|
+
)
|
270
|
+
|
271
|
+
# OR
|
272
|
+
|
273
|
+
# Credential Authentication
|
274
|
+
options = WebAuthn::Credential.options_for_get(
|
275
|
+
allow: user.credentials.map { |c| c.webauthn_id },
|
276
|
+
extensions: { appid: domain.to_s }
|
277
|
+
)
|
278
|
+
```
|
279
|
+
|
280
|
+
Consequently, after these `options` are sent to the WebAuthn client:
|
281
|
+
|
282
|
+
> The WebAuthn client performs client extension processing for each extension that the client supports, and augments the client data as specified by each extension, by including the extension identifier and client extension output values.
|
283
|
+
|
284
|
+
> For authenticator extensions, as part of the client extension processing, the client also creates the CBOR authenticator extension input value for each extension (often based on the corresponding client extension input value), and passes them to the authenticator in the create() call (for registration extensions) or the get() call (for authentication extensions).
|
285
|
+
|
286
|
+
> The authenticator, in turn, performs additional processing for the extensions that it supports, and returns the CBOR authenticator extension output for each as specified by the extension. Part of the client extension processing for authenticator extensions is to use the authenticator extension output as an input to creating the client extension output. [[source](https://www.w3.org/TR/webauthn-2/#sctn-extensions)]
|
287
|
+
|
288
|
+
Finally, you can check the values returned for each extension by calling `client_extension_outputs` and `authenticator_extension_outputs` respectively.
|
289
|
+
For example, following the initialization phase for the Credential Authentication ceremony specified in the above example:
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
webauthn_credential = WebAuthn::Credential.from_get(credential_get_result_hash)
|
293
|
+
|
294
|
+
webauthn_credential.client_extension_outputs #=> { "appid" => true }
|
295
|
+
webauthn_credential.authenticator_extension_outputs #=> nil
|
296
|
+
```
|
297
|
+
|
298
|
+
A list of all currently defined extensions:
|
299
|
+
|
300
|
+
- [Last published version](https://www.w3.org/TR/webauthn-2/#sctn-defined-extensions)
|
301
|
+
- [Next version (in draft)](https://w3c.github.io/webauthn/#sctn-defined-extensions)
|
302
|
+
|
250
303
|
## API
|
251
304
|
|
252
|
-
|
305
|
+
#### `WebAuthn.generate_user_id`
|
306
|
+
|
307
|
+
Generates a [WebAuthn User Handle](https://www.w3.org/TR/webauthn-2/#user-handle) that follows the WebAuthn spec recommendations.
|
308
|
+
|
309
|
+
```ruby
|
310
|
+
WebAuthn.generate_user_id # "lWoMZTGf_ml2RoY5qPwbwrkxrvTqWjGOxEoYBgxft3zG-LlrICvE-y8bxFi06zMyIOyNsJoWx4Fa2TOqoRmnxA"
|
311
|
+
```
|
312
|
+
|
313
|
+
#### `WebAuthn::Credential.options_for_create(options)`
|
314
|
+
|
315
|
+
Helper method to build the necessary [PublicKeyCredentialCreationOptions](https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialcreationoptions)
|
316
|
+
to be used in the client-side code to call `navigator.credentials.create({ "publicKey": publicKeyCredentialCreationOptions })`.
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
creation_options = WebAuthn::Credential.options_for_create(
|
320
|
+
user: { id: user.webauthn_id, name: user.name }
|
321
|
+
exclude: user.credentials.map { |c| c.webauthn_id }
|
322
|
+
)
|
323
|
+
|
324
|
+
# Store the newly generated challenge somewhere so you can have it
|
325
|
+
# for the verification phase.
|
326
|
+
session[:creation_challenge] = creation_options.challenge
|
327
|
+
|
328
|
+
# Send `creation_options` back to the browser, so that they can be used
|
329
|
+
# to call `navigator.credentials.create({ "publicKey": creationOptions })`
|
330
|
+
#
|
331
|
+
# You can call `creation_options.as_json` to get a ruby hash with a JSON representation if needed.
|
332
|
+
|
333
|
+
# If inside a Rails controller, `render json: creation_options` will just work.
|
334
|
+
# I.e. it will encode and convert the options to JSON automatically.
|
335
|
+
```
|
253
336
|
|
254
|
-
|
337
|
+
#### `WebAuthn::Credential.options_for_get([options])`
|
338
|
+
|
339
|
+
Helper method to build the necessary [PublicKeyCredentialRequestOptions](https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialrequestoptions)
|
340
|
+
to be used in the client-side code to call `navigator.credentials.get({ "publicKey": publicKeyCredentialRequestOptions })`.
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
request_options = WebAuthn::Credential.options_for_get(allow: user.credentials.map { |c| c.webauthn_id })
|
344
|
+
|
345
|
+
# Store the newly generated challenge somewhere so you can have it
|
346
|
+
# for the verification phase.
|
347
|
+
session[:authentication_challenge] = request_options.challenge
|
348
|
+
|
349
|
+
# Send `request_options` back to the browser, so that they can be used
|
350
|
+
# to call `navigator.credentials.get({ "publicKey": requestOptions })`
|
351
|
+
|
352
|
+
# You can call `request_options.as_json` to get a ruby hash with a JSON representation if needed.
|
353
|
+
|
354
|
+
# If inside a Rails controller, `render json: request_options` will just work.
|
355
|
+
# I.e. it will encode and convert the options to JSON automatically.
|
356
|
+
```
|
357
|
+
|
358
|
+
#### `WebAuthn::Credential.from_create(credential_create_result)`
|
359
|
+
|
360
|
+
```ruby
|
361
|
+
credential_with_attestation = WebAuthn::Credential.from_create(params[:publicKeyCredential])
|
362
|
+
```
|
363
|
+
|
364
|
+
#### `WebAuthn::Credential.from_get(credential_get_result)`
|
365
|
+
|
366
|
+
```ruby
|
367
|
+
credential_with_assertion = WebAuthn::Credential.from_get(params[:publicKeyCredential])
|
368
|
+
```
|
369
|
+
|
370
|
+
#### `PublicKeyCredentialWithAttestation#verify(challenge)`
|
371
|
+
|
372
|
+
Verifies the created WebAuthn credential is [valid](https://www.w3.org/TR/webauthn-2/#sctn-registering-a-new-credential).
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
credential_with_attestation.verify(session[:creation_challenge])
|
376
|
+
```
|
377
|
+
|
378
|
+
#### `PublicKeyCredentialWithAssertion#verify(challenge, public_key:, sign_count:)`
|
379
|
+
|
380
|
+
Verifies the asserted WebAuthn credential is [valid](https://www.w3.org/TR/webauthn-2/#sctn-verifying-assertion).
|
381
|
+
|
382
|
+
Mainly, that the client provided a valid cryptographic signature for the corresponding stored credential public
|
383
|
+
key, among other extra validations.
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
credential_with_assertion.verify(
|
387
|
+
session[:authentication_challenge],
|
388
|
+
public_key: stored_credential.public_key,
|
389
|
+
sign_count: stored_credential.sign_count
|
390
|
+
)
|
391
|
+
```
|
392
|
+
|
393
|
+
#### `PublicKeyCredential#client_extension_outputs`
|
394
|
+
|
395
|
+
```ruby
|
396
|
+
credential = WebAuthn::Credential.from_create(params[:publicKeyCredential])
|
397
|
+
|
398
|
+
credential.client_extension_outputs
|
399
|
+
```
|
400
|
+
|
401
|
+
#### `PublicKeyCredential#authenticator_extension_outputs`
|
402
|
+
|
403
|
+
```ruby
|
404
|
+
credential = WebAuthn::Credential.from_create(params[:publicKeyCredential])
|
405
|
+
|
406
|
+
credential.authenticator_extension_outputs
|
407
|
+
```
|
408
|
+
|
409
|
+
## Attestation
|
410
|
+
|
411
|
+
### Attestation Statement Format
|
255
412
|
|
256
413
|
| Attestation Statement Format | Supported? |
|
257
414
|
| -------- | :--------: |
|
258
415
|
| packed (self attestation) | Yes |
|
259
416
|
| packed (x5c attestation) | Yes |
|
260
|
-
| packed (ECDAA attestation) | No |
|
261
417
|
| tpm (x5c attestation) | Yes |
|
262
|
-
| tpm (ECDAA attestation) | No |
|
263
418
|
| android-key | Yes |
|
264
419
|
| android-safetynet | Yes |
|
265
420
|
| fido-u2f | Yes |
|
266
421
|
| none | Yes |
|
267
422
|
|
268
|
-
|
423
|
+
### Attestation Types
|
424
|
+
|
425
|
+
You can define what trust policy to enforce by setting `acceptable_attestation_types` config to a subset of `['None', 'Self', 'Basic', 'AttCA', 'Basic_or_AttCA']` and `attestation_root_certificates_finders` to an object that responds to `#find` and returns the corresponding root certificate for each registration. The `#find` method will be called passing keyword arguments `attestation_format`, `aaguid` and `attestation_certificate_key_id`.
|
269
426
|
|
270
427
|
## Testing Your Integration
|
271
428
|
|