webauthn 1.18.0 → 2.0.0.beta1
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 +8 -0
- data/.travis.yml +7 -3
- data/Appraisals +8 -0
- data/CHANGELOG.md +52 -0
- data/README.md +88 -80
- data/SECURITY.md +18 -0
- data/gemfiles/cose_head.gemfile +7 -0
- data/gemfiles/openssl_head.gemfile +7 -0
- data/lib/webauthn.rb +9 -1
- data/lib/webauthn/attestation_statement/android_safetynet.rb +4 -4
- data/lib/webauthn/attestation_statement/base.rb +4 -4
- data/lib/webauthn/attestation_statement/fido_u2f.rb +1 -2
- data/lib/webauthn/authenticator_assertion_response.rb +33 -35
- data/lib/webauthn/authenticator_attestation_response.rb +30 -0
- data/lib/webauthn/authenticator_data.rb +3 -1
- data/lib/webauthn/authenticator_data/attested_credential_data.rb +1 -0
- data/lib/webauthn/authenticator_response.rb +1 -2
- data/lib/webauthn/client_data.rb +2 -1
- data/lib/webauthn/configuration.rb +9 -0
- data/lib/webauthn/credential.rb +26 -0
- data/lib/webauthn/credential_creation_options.rb +5 -1
- data/lib/webauthn/credential_request_options.rb +5 -0
- data/lib/webauthn/encoder.rb +8 -1
- data/lib/webauthn/fake_authenticator.rb +1 -0
- data/lib/webauthn/fake_client.rb +26 -22
- data/lib/webauthn/public_key_credential.rb +10 -50
- data/lib/webauthn/public_key_credential/creation_options.rb +92 -0
- data/lib/webauthn/public_key_credential/entity.rb +44 -0
- data/lib/webauthn/public_key_credential/options.rb +72 -0
- data/lib/webauthn/public_key_credential/request_options.rb +36 -0
- data/lib/webauthn/public_key_credential/rp_entity.rb +23 -0
- data/lib/webauthn/public_key_credential/user_entity.rb +24 -0
- data/lib/webauthn/public_key_credential_with_assertion.rb +35 -0
- data/lib/webauthn/public_key_credential_with_attestation.rb +30 -0
- data/lib/webauthn/u2f_migrator.rb +1 -1
- data/lib/webauthn/version.rb +1 -1
- data/webauthn.gemspec +3 -2
- metadata +33 -8
- data/webauthn-ruby.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6181693e3c34f1ca289fb2056df36c35a5e144076288eef34e774e2dfc1794b5
|
4
|
+
data.tar.gz: 87883fa3fe7c7bd5da885025b7a571dfedfdfe1c27c6a5c8edeee54956bd98bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a69f7870a89344a5d00b1c75b55dd6e25741719bf2fd79d03e83348530a964ef237f8330dea55edbb58b9fe5ee0522f2f41b5d9d46f7d975112b9dd8a05889bd
|
7
|
+
data.tar.gz: 19b32618b9e83e2618abe361aca398933030fe2963502c8a9054dc291b22678107e3257be5d7a711bdf0d826dc1d444e28d726282fa6306abf336f675e3794df
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
inherit_mode:
|
2
|
+
merge:
|
3
|
+
- AllowedNames
|
4
|
+
|
1
5
|
AllCops:
|
2
6
|
TargetRubyVersion: 2.3
|
3
7
|
DisabledByDefault: true
|
@@ -24,6 +28,10 @@ Metrics/LineLength:
|
|
24
28
|
Naming:
|
25
29
|
Enabled: true
|
26
30
|
|
31
|
+
Naming/UncommunicativeMethodParamName:
|
32
|
+
AllowedNames:
|
33
|
+
- rp
|
34
|
+
|
27
35
|
Security:
|
28
36
|
Enabled: true
|
29
37
|
|
data/.travis.yml
CHANGED
@@ -5,12 +5,14 @@ cache: bundler
|
|
5
5
|
rvm:
|
6
6
|
- ruby-head
|
7
7
|
- 2.7.0-preview1
|
8
|
-
- 2.6.
|
9
|
-
- 2.5.
|
10
|
-
- 2.4.
|
8
|
+
- 2.6.4
|
9
|
+
- 2.5.6
|
10
|
+
- 2.4.7
|
11
11
|
- 2.3.8
|
12
12
|
|
13
13
|
gemfile:
|
14
|
+
- gemfiles/cose_head.gemfile
|
15
|
+
- gemfiles/openssl_head.gemfile
|
14
16
|
- gemfiles/openssl_2_1.gemfile
|
15
17
|
- gemfiles/openssl_2_0.gemfile
|
16
18
|
|
@@ -19,6 +21,8 @@ matrix:
|
|
19
21
|
allow_failures:
|
20
22
|
- rvm: ruby-head
|
21
23
|
- rvm: 2.7.0-preview1
|
24
|
+
- gemfile: gemfiles/cose_head.gemfile
|
25
|
+
- gemfile: gemfiles/openssl_head.gemfile
|
22
26
|
|
23
27
|
before_install:
|
24
28
|
- wget http://archive.ubuntu.com/ubuntu/pool/universe/f/faketime/libfaketime_0.9.7-3_amd64.deb
|
data/Appraisals
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
appraise "cose_head" do
|
4
|
+
gem "cose", git: "https://github.com/cedarcode/cose-ruby"
|
5
|
+
end
|
6
|
+
|
7
|
+
appraise "openssl_head" do
|
8
|
+
gem "openssl", git: "https://github.com/ruby/openssl"
|
9
|
+
end
|
10
|
+
|
3
11
|
appraise "openssl_2_1" do
|
4
12
|
gem "openssl", "~> 2.1.0"
|
5
13
|
end
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,56 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v2.0.0.beta1] - 2019-09-16
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Smarter new public API methods:
|
8
|
+
- `WebAuthn.generate_user_id`
|
9
|
+
- `WebAuthn::Credential.options_for_create`
|
10
|
+
- `WebAuthn::Credential.options_for_get`
|
11
|
+
- `WebAuthn::Credential.from_create`
|
12
|
+
- `WebAuthn::Credential.from_get`
|
13
|
+
- All the above automatically handle encoding/decoding for necessary values. The specific encoding scheme can
|
14
|
+
be set (or even turned off) in `WebAutnn.configuration.encoding=`. Defaults to `:base64url`.
|
15
|
+
- `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 (@bdwater)
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- `WebAuthn::AuthenticatorAssertionResponse#verify` no longer accepts `allowed_credentials:` keyword argument.
|
21
|
+
Please replace with `public_key:` and `sign_count:` keyword arguments. If you're not performing sign count
|
22
|
+
verification, signal opt-out with `sign_count: false`.
|
23
|
+
|
24
|
+
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by using camelBack string
|
25
|
+
keys instead of snake_case symbol keys in the returned hash.
|
26
|
+
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by not padding the
|
27
|
+
returned base64url-encoded `id` value.
|
28
|
+
|
29
|
+
### Deprecated
|
30
|
+
|
31
|
+
- `WebAuthn.credential_creation_options` method. Please consider using `WebAuthn::Credential.options_for_create`.
|
32
|
+
- `WebAuthn.credential_request_options` method. Please consider using `WebAuthn::Credential.options_for_get`.
|
33
|
+
|
34
|
+
### Removed
|
35
|
+
|
36
|
+
- `WebAuthn::AuthenticatorAssertionResponse.new` no longer accepts `credential_id`. No replacement needed, just don't
|
37
|
+
pass it.
|
38
|
+
|
39
|
+
### BREAKING CHANGES
|
40
|
+
|
41
|
+
- `WebAuthn::AuthenticatorAssertionResponse.new` no longer accepts `credential_id`. No replacement needed, just don't
|
42
|
+
pass it.
|
43
|
+
|
44
|
+
- `WebAuthn::AuthenticatorAssertionResponse#verify` no longer accepts `allowed_credentials:` keyword argument.
|
45
|
+
Please replace with `public_key:` and `sign_count:` keyword arguments. If you're not performing sign count
|
46
|
+
verification, signal opt-out with `sign_count: false`.
|
47
|
+
|
48
|
+
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by using camelBack string
|
49
|
+
keys instead of snake_case symbol keys in the returned hash.
|
50
|
+
|
51
|
+
- `WebAuthn::FakeClient#create` and `WebAuthn::FakeClient#get` better fakes a real client by not padding the
|
52
|
+
returned base64url-encoded `id` value.
|
53
|
+
|
3
54
|
## [v1.18.0] - 2019-07-27
|
4
55
|
|
5
56
|
### Added
|
@@ -209,6 +260,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
|
|
209
260
|
- `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
|
210
261
|
- Works with ruby 2.5
|
211
262
|
|
263
|
+
[v2.0.0.beta1]: https://github.com/cedarcode/webauthn-ruby/compare/v1.18.0...v2.0.0.beta1/
|
212
264
|
[v1.18.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.17.0...v1.18.0/
|
213
265
|
[v1.17.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.16.0...v1.17.0/
|
214
266
|
[v1.16.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.15.0...v1.16.0/
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
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/1-stable/README.md.
|
3
|
+
|
1
4
|
# webauthn-ruby
|
2
5
|
|
3
|
-

|
6
|
+

|
4
7
|
|
5
8
|
[](https://rubygems.org/gems/webauthn)
|
6
9
|
[](https://travis-ci.org/cedarcode/webauthn-ruby)
|
@@ -30,7 +33,9 @@ a user [credential](https://www.w3.org/TR/webauthn/#public-key-credential), incl
|
|
30
33
|
|
31
34
|
## Security
|
32
35
|
|
33
|
-
|
36
|
+
Please report security vulnerabilities to security@cedarcode.com.
|
37
|
+
|
38
|
+
_More_: [SECURITY](SECURITY.md)
|
34
39
|
|
35
40
|
## Background
|
36
41
|
|
@@ -117,126 +122,129 @@ WebAuthn.configure do |config|
|
|
117
122
|
# the suffix "example.com"
|
118
123
|
#
|
119
124
|
# config.rp_id = "example.com"
|
125
|
+
|
126
|
+
# Configure preferred binary-to-text encoding scheme. This should match the encoding scheme
|
127
|
+
# used in your client-side (user agent) code before sending the credential to the server.
|
128
|
+
# Supported values: `:base64url` (default), `:base64` or `false` to disable all encoding.
|
129
|
+
#
|
130
|
+
# config.encoding = false
|
120
131
|
end
|
121
132
|
```
|
122
133
|
|
123
|
-
### Registration
|
134
|
+
### Credential Registration
|
135
|
+
|
136
|
+
> The ceremony where a user, a Relying Party, and the user’s client (containing at least one authenticator) work in concert to create a public key credential and associate it with the user’s Relying Party account. Note that this includes employing a test of user presence or user verification.
|
137
|
+
> [[source](https://www.w3.org/TR/webauthn-2/#registration-ceremony)]
|
124
138
|
|
125
139
|
#### Initiation phase
|
126
140
|
|
127
141
|
```ruby
|
128
|
-
|
142
|
+
# Generate and store the WebAuthn User ID the first time the user registers a credential
|
143
|
+
if !user.webauthn_id
|
144
|
+
user.update!(webauthn_id: WebAuthn.generate_user_id)
|
145
|
+
end
|
146
|
+
|
147
|
+
options = WebAuthn::Credential.options_for_create(
|
148
|
+
user: { id: user.webauthn_id, name: user.name }
|
149
|
+
exclude: user.credentials.map { |c| c.webauthn_id }
|
150
|
+
)
|
129
151
|
|
130
152
|
# Store the newly generated challenge somewhere so you can have it
|
131
153
|
# for the verification phase.
|
154
|
+
session[:creation_challenge] = options.challenge
|
155
|
+
|
156
|
+
# Send `options` back to the browser, so that they can be used
|
157
|
+
# to call `navigator.credentials.create({ "publicKey": options })`
|
132
158
|
#
|
133
|
-
# You can
|
134
|
-
credential_creation_options[:challenge]
|
159
|
+
# You can call `options.as_json` to get a ruby hash with a JSON representation if needed.
|
135
160
|
|
136
|
-
#
|
137
|
-
#
|
161
|
+
# If inside a Rails controller, `render json: options` will just work.
|
162
|
+
# I.e. it will encode and convert the options to JSON automatically.
|
163
|
+
|
164
|
+
# For your frontend code, you might find @github/webauthn-json npm package useful.
|
165
|
+
# Especially for handling the necessary decoding of the options, and sending the
|
166
|
+
# `PublicKeyCredential` object back to the server.
|
138
167
|
```
|
139
168
|
|
140
169
|
#### Verification phase
|
141
170
|
|
142
171
|
```ruby
|
143
|
-
#
|
144
|
-
#
|
145
|
-
|
146
|
-
# `navigator.credentials.create` returned through the wire.
|
147
|
-
#
|
148
|
-
# Then you need to decode that data before passing it to the `#verify` method.
|
149
|
-
#
|
150
|
-
# E.g. in https://github.com/cedarcode/webauthn-rails-demo-app we use `Base64.strict_decode64`
|
151
|
-
# on the user-agent encoded data before calling `#verify`
|
152
|
-
attestation_object = "..."
|
153
|
-
client_data_json = "..."
|
154
|
-
|
155
|
-
attestation_response = WebAuthn::AuthenticatorAttestationResponse.new(
|
156
|
-
attestation_object: attestation_object,
|
157
|
-
client_data_json: client_data_json
|
158
|
-
)
|
159
|
-
|
172
|
+
# Assuming you're using @github/webauthn-json package to send the `PublicKeyCredential` object back
|
173
|
+
# in params[:publicKeyCredential]:
|
174
|
+
webauthn_credential = WebAuthn::Credential.from_create(params[:publicKeyCredential])
|
160
175
|
|
161
176
|
begin
|
162
|
-
|
163
|
-
|
164
|
-
#
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
rescue WebAuthn::VerificationError => e
|
177
|
+
webauthn_credential.verify(session[:creation_challenge])
|
178
|
+
|
179
|
+
# Store Credential ID, Credential Public Key and Sign Count for future authentications
|
180
|
+
user.credentials.create!(
|
181
|
+
webauthn_id: webauthn_credential.id,
|
182
|
+
public_key: webauthn_credential.public_key,
|
183
|
+
sign_count: webauthn_credential.sign_count
|
184
|
+
)
|
185
|
+
rescue WebAuthn::Error => e
|
172
186
|
# Handle error
|
173
187
|
end
|
174
188
|
```
|
175
189
|
|
176
|
-
### Authentication
|
190
|
+
### Credential Authentication
|
177
191
|
|
178
|
-
|
192
|
+
> The ceremony where a user, and the user’s client (containing at least one authenticator) work in concert to cryptographically prove to a Relying Party that the user controls the credential private key associated with a previously-registered public key credential (see Registration). Note that this includes a test of user presence or user verification. [[source](https://www.w3.org/TR/webauthn-2/#authentication-ceremony)]
|
179
193
|
|
180
|
-
|
194
|
+
#### Initiation phase
|
181
195
|
|
182
196
|
```ruby
|
183
|
-
|
184
|
-
credential_request_options[:allowCredentials] << { id: credential_id, type: "public-key" }
|
197
|
+
options = WebAuthn::Credential.options_for_get(allow: user.credentials.map { |c| c.webauthn_id })
|
185
198
|
|
186
199
|
# Store the newly generated challenge somewhere so you can have it
|
187
200
|
# for the verification phase.
|
188
|
-
|
189
|
-
|
190
|
-
|
201
|
+
session[:authentication_challenge] = options.challenge
|
202
|
+
|
203
|
+
# Send `options` back to the browser, so that they can be used
|
204
|
+
# to call `navigator.credentials.get({ "publicKey": options })`
|
205
|
+
|
206
|
+
# You can call `options.as_json` to get a ruby hash with a JSON representation if needed.
|
207
|
+
|
208
|
+
# If inside a Rails controller, `render json: options` will just work.
|
209
|
+
# I.e. it will encode and convert the options to JSON automatically.
|
191
210
|
|
192
|
-
#
|
193
|
-
#
|
211
|
+
# For your frontend code, you might find @github/webauthn-json npm package useful.
|
212
|
+
# Especially for handling the necessary decoding of the options, and sending the
|
213
|
+
# `PublicKeyCredential` object back to the server.
|
194
214
|
```
|
195
215
|
|
196
216
|
#### Verification phase
|
197
217
|
|
198
|
-
|
218
|
+
You need to look up the stored credential for a user by matching the `id` attribute from the PublicKeyCredential
|
219
|
+
interface returned by the browser to the stored `credential_id`. The corresponding `public_key` and `sign_count`
|
220
|
+
attributes must be passed as keyword arguments to the `verify` method call.
|
199
221
|
|
200
222
|
```ruby
|
201
|
-
#
|
202
|
-
#
|
203
|
-
|
204
|
-
# `navigator.credentials.get` returned through the wire.
|
205
|
-
#
|
206
|
-
# Then you need to decode that data before passing it to the `#verify` method.
|
207
|
-
#
|
208
|
-
# E.g. in https://github.com/cedarcode/webauthn-rails-demo-app we use `Base64.strict_decode64`
|
209
|
-
# on the user-agent encoded data before calling `#verify`
|
210
|
-
selected_credential_id = "..."
|
211
|
-
authenticator_data = "..."
|
212
|
-
client_data_json = "..."
|
213
|
-
signature = "..."
|
214
|
-
|
215
|
-
assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
|
216
|
-
credential_id: selected_credential_id,
|
217
|
-
authenticator_data: authenticator_data,
|
218
|
-
client_data_json: client_data_json,
|
219
|
-
signature: signature
|
220
|
-
)
|
223
|
+
# Assuming you're using @github/webauthn-json package to send the `PublicKeyCredential` object back
|
224
|
+
# in params[:publicKeyCredential]:
|
225
|
+
webauthn_credential = WebAuthn::Credential.from_get(params[:publicKeyCredential])
|
221
226
|
|
222
|
-
|
223
|
-
# previously stored credential for the user that is attempting to sign in.
|
224
|
-
allowed_credential = {
|
225
|
-
id: credential_id,
|
226
|
-
public_key: credential_public_key,
|
227
|
-
sign_count: sign_count,
|
228
|
-
}
|
227
|
+
stored_credential = user.credentials.find_by(webauthn_id: webauthn_credential.id)
|
229
228
|
|
230
229
|
begin
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
230
|
+
webauthn_credential.verify(
|
231
|
+
session[:authentication_challenge],
|
232
|
+
public_key: stored_credential.public_key,
|
233
|
+
sign_count: stored_credential.sign_count
|
234
|
+
)
|
235
|
+
|
236
|
+
# Update the stored credential sign count with the value from `webauthn_credential.sign_count`
|
237
|
+
stored_credential.update!(sign_count: webauthn_credential.sign_count)
|
238
|
+
|
239
|
+
# Continue with successful sign in or 2FA verification...
|
240
|
+
|
241
|
+
rescue WebAuthn::SignCountVerificationError => e
|
242
|
+
# Cryptographic verification of the authenticator data succeeded, but the signature counter was less then or equal
|
243
|
+
# to the stored value. This can have several reasons and depending on your risk tolerance you can choose to fail or
|
244
|
+
# pass authentication. For more information see https://www.w3.org/TR/webauthn/#sign-counter
|
245
|
+
rescue WebAuthn::Error => e
|
235
246
|
# Handle error
|
236
247
|
end
|
237
|
-
|
238
|
-
# Find the selected credential in your data storage using `selected_credential_id`
|
239
|
-
# Update the stored sign count with the value from `assertion_response.authenticator_data.sign_count`
|
240
248
|
```
|
241
249
|
|
242
250
|
## API
|
data/SECURITY.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Supported Versions
|
4
|
+
|
5
|
+
| Version | Supported |
|
6
|
+
| ------- | ------------------ |
|
7
|
+
| 1.18.z | :white_check_mark: |
|
8
|
+
| 1.17.z | :white_check_mark: |
|
9
|
+
| 1.16.z | :white_check_mark: |
|
10
|
+
| 1.15.z | :white_check_mark: |
|
11
|
+
| < 1.15 | :x: |
|
12
|
+
|
13
|
+
## Reporting a Vulnerability
|
14
|
+
|
15
|
+
If you have discovered a security bug, please send an email to security@cedarcode.com
|
16
|
+
instead of posting to the GitHub issue tracker.
|
17
|
+
|
18
|
+
Thank you!
|
data/lib/webauthn.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "webauthn/configuration"
|
4
|
+
require "webauthn/credential"
|
4
5
|
require "webauthn/credential_creation_options"
|
5
6
|
require "webauthn/credential_request_options"
|
6
|
-
require "webauthn/public_key_credential"
|
7
7
|
require "webauthn/version"
|
8
|
+
|
9
|
+
module WebAuthn
|
10
|
+
TYPE_PUBLIC_KEY = "public-key"
|
11
|
+
|
12
|
+
def self.generate_user_id
|
13
|
+
configuration.encoder.encode(SecureRandom.random_bytes(64))
|
14
|
+
end
|
15
|
+
end
|
@@ -20,6 +20,10 @@ module WebAuthn
|
|
20
20
|
[WebAuthn::AttestationStatement::ATTESTATION_TYPE_BASIC, attestation_certificate]
|
21
21
|
end
|
22
22
|
|
23
|
+
def attestation_certificate
|
24
|
+
attestation_response.certificate_chain[0]
|
25
|
+
end
|
26
|
+
|
23
27
|
private
|
24
28
|
|
25
29
|
# FIXME: This should be a responsibility of AndroidSafetynet::AttestationResponse#verify
|
@@ -46,10 +50,6 @@ module WebAuthn
|
|
46
50
|
attestation_response.cts_profile_match?
|
47
51
|
end
|
48
52
|
|
49
|
-
def attestation_certificate
|
50
|
-
attestation_response.certificate_chain[0]
|
51
|
-
end
|
52
|
-
|
53
53
|
def signing_certificates
|
54
54
|
attestation_response.certificate_chain[1..-1]
|
55
55
|
end
|
@@ -26,6 +26,10 @@ module WebAuthn
|
|
26
26
|
raise NotImpelementedError
|
27
27
|
end
|
28
28
|
|
29
|
+
def attestation_certificate
|
30
|
+
attestation_certificate_chain&.first
|
31
|
+
end
|
32
|
+
|
29
33
|
private
|
30
34
|
|
31
35
|
attr_reader :statement
|
@@ -42,10 +46,6 @@ module WebAuthn
|
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
45
|
-
def attestation_certificate
|
46
|
-
attestation_certificate_chain&.first
|
47
|
-
end
|
48
|
-
|
49
49
|
def attestation_certificate_chain
|
50
50
|
@attestation_certificate_chain ||= raw_attestation_certificates&.map do |raw_certificate|
|
51
51
|
OpenSSL::X509::Certificate.new(raw_certificate)
|