fido_metadata 0.4.0 → 0.5.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/.github/dependabot.yml +6 -0
- data/.github/workflows/ci.yml +33 -0
- data/.github/workflows/lint.yml +18 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -6
- data/.ruby-version +1 -0
- data/Appraisals +9 -0
- data/CHANGELOG.md +14 -5
- data/Gemfile +6 -0
- data/Gemfile.lock +66 -51
- data/README.md +0 -1
- data/Rakefile +3 -7
- data/bin/console +0 -8
- data/fido_metadata.gemspec +3 -5
- data/gemfiles/jwt_2.gemfile +8 -0
- data/gemfiles/jwt_3.gemfile +8 -0
- data/lib/Root.cer +19 -13
- data/lib/fido_metadata/authenticator_get_info.rb +31 -0
- data/lib/fido_metadata/client.rb +13 -34
- data/lib/fido_metadata/coercer/authenticator_get_info.rb +15 -0
- data/lib/fido_metadata/coercer/statement.rb +15 -0
- data/lib/fido_metadata/entry.rb +2 -0
- data/lib/fido_metadata/refinement/fixed_length_secure_compare.rb +1 -1
- data/lib/fido_metadata/statement.rb +10 -16
- data/lib/fido_metadata/store.rb +3 -8
- data/lib/fido_metadata/verification_method_descriptor.rb +1 -2
- data/lib/fido_metadata/version.rb +1 -1
- data/lib/fido_metadata.rb +0 -1
- metadata +34 -48
- data/.travis.yml +0 -18
- data/lib/fido_metadata/constants.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1899edc776f8d77121b90f9487e5c4ed915aad1407899e32f28c6a209efcb287
|
4
|
+
data.tar.gz: ad903aaa648ad7591d69883cd1cf61dba63228c07f9256b02d29a6e9e0642b9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19da5080beafc9fefb641f15419f1753123254aaa947a2b70682e56d4a865e50f18eb42ab3df7f0b4c219355b142ef6d58d42d472399c833942679823e76472d
|
7
|
+
data.tar.gz: 3ca8419fb3cf241c63ec0e100e46559940b82efb54cbfa61369727e396b1bbf1d483193412fa2cb90ca97aa9c53fc98983efa6efa24d2f8d356c5510b4a0f8be
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: ["2.5", "2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"]
|
14
|
+
gemfile:
|
15
|
+
- jwt_2
|
16
|
+
- jwt_3
|
17
|
+
|
18
|
+
env:
|
19
|
+
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
20
|
+
|
21
|
+
steps:
|
22
|
+
- uses: actions/checkout@v5
|
23
|
+
|
24
|
+
- run: rm Gemfile.lock
|
25
|
+
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
bundler-cache: true # 'bundle install' and cache gems
|
30
|
+
ruby-version: ${{ matrix.ruby }}
|
31
|
+
|
32
|
+
- name: Run tests
|
33
|
+
run: bundle exec rspec
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: Lint
|
2
|
+
|
3
|
+
on: push
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
lint:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
name: Rubocop
|
10
|
+
|
11
|
+
steps:
|
12
|
+
- uses: actions/checkout@v5
|
13
|
+
- name: Set up Ruby
|
14
|
+
uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
bundler-cache: true # 'bundle install' and cache gems
|
17
|
+
- name: Run Rubocop
|
18
|
+
run: bundle exec rubocop
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -21,7 +21,7 @@ Layout:
|
|
21
21
|
Lint:
|
22
22
|
Enabled: true
|
23
23
|
|
24
|
-
|
24
|
+
Layout/LineLength:
|
25
25
|
Max: 120
|
26
26
|
|
27
27
|
Naming:
|
@@ -33,9 +33,6 @@ Security:
|
|
33
33
|
Style/BlockComments:
|
34
34
|
Enabled: true
|
35
35
|
|
36
|
-
Style/BracesAroundHashParameters:
|
37
|
-
Enabled: true
|
38
|
-
|
39
36
|
Style/CaseEquality:
|
40
37
|
Enabled: true
|
41
38
|
|
@@ -181,10 +178,10 @@ Style/TrailingMethodEndStatement:
|
|
181
178
|
Style/TrivialAccessors:
|
182
179
|
Enabled: true
|
183
180
|
|
184
|
-
Style/
|
181
|
+
Style/RedundantInterpolation:
|
185
182
|
Enabled: true
|
186
183
|
|
187
|
-
Style/
|
184
|
+
Style/RedundantPercentQ:
|
188
185
|
Enabled: true
|
189
186
|
|
190
187
|
Style/UnpackFirst:
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.4.5
|
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.5.0] - 2025-09-12
|
10
|
+
### Added
|
11
|
+
- Add support for FIDO MDS v3. ([#10](https://github.com/cedarcode/fido_metadata/pull/10))
|
12
|
+
- Follow HTTP 302 redirects when downloading CRLs. ([#14](https://github.com/cedarcode/fido_metadata/pull/14))
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- Update `jwt` dependency to support both v2 and v3. ([#23](https://github.com/cedarcode/fido_metadata/pull/23))
|
16
|
+
|
9
17
|
## [0.4.0] - 2019-12-28
|
10
18
|
### Added
|
11
19
|
- Set `expires_in` and `race_condition_ttl` options during caching.
|
@@ -29,8 +37,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
29
37
|
### Added
|
30
38
|
- Extracted from [webauthn-ruby PR 208](https://github.com/cedarcode/webauthn-ruby/pull/208) after discussion with the maintainers. Thanks for the feedback @grzuy and @brauliomartinezlm!
|
31
39
|
|
32
|
-
[Unreleased]: https://github.com/
|
33
|
-
[0.
|
34
|
-
[0.
|
35
|
-
[0.
|
36
|
-
[0.
|
40
|
+
[Unreleased]: https://github.com/cedarcode/fido_metadata/compare/v0.5.0...HEAD
|
41
|
+
[0.5.0]: https://github.com/cedarcode/fido_metadata/compare/v0.4.0...v0.5.0
|
42
|
+
[0.4.0]: https://github.com/cedarcode/fido_metadata/compare/v0.3.0...v0.4.0
|
43
|
+
[0.3.0]: https://github.com/cedarcode/fido_metadata/compare/v0.2.0...v0.3.0
|
44
|
+
[0.2.0]: https://github.com/cedarcode/fido_metadata/compare/v0.1.0...v0.2.0
|
45
|
+
[0.1.0]: https://github.com/cedarcode/fido_metadata/releases/tag/v0.1.0
|
data/Gemfile
CHANGED
@@ -6,3 +6,9 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
6
|
|
7
7
|
# Specify your gem's dependencies in fido_metadata.gemspec
|
8
8
|
gemspec
|
9
|
+
|
10
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
|
11
|
+
gem "rubocop", "~> 1.80", require: false
|
12
|
+
end
|
13
|
+
|
14
|
+
gem "appraisal", "~> 2.5"
|
data/Gemfile.lock
CHANGED
@@ -1,61 +1,77 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fido_metadata (0.
|
5
|
-
|
4
|
+
fido_metadata (0.5.0)
|
5
|
+
base64 (>= 0.1.0)
|
6
|
+
jwt (>= 2.0, < 4)
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
10
|
-
addressable (2.7
|
11
|
-
public_suffix (>= 2.0.2, <
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
rspec
|
11
|
+
addressable (2.8.7)
|
12
|
+
public_suffix (>= 2.0.2, < 7.0)
|
13
|
+
appraisal (2.5.0)
|
14
|
+
bundler
|
15
|
+
rake
|
16
|
+
thor (>= 0.14.0)
|
17
|
+
ast (2.4.3)
|
18
|
+
base64 (0.3.0)
|
19
|
+
bigdecimal (3.2.2)
|
20
|
+
crack (1.0.0)
|
21
|
+
bigdecimal
|
22
|
+
rexml
|
23
|
+
diff-lcs (1.6.2)
|
24
|
+
hashdiff (1.2.0)
|
25
|
+
json (2.13.2)
|
26
|
+
jwt (3.1.2)
|
27
|
+
base64
|
28
|
+
language_server-protocol (3.17.0.5)
|
29
|
+
lint_roller (1.1.0)
|
30
|
+
parallel (1.27.0)
|
31
|
+
parser (3.3.9.0)
|
32
|
+
ast (~> 2.4.1)
|
33
|
+
racc
|
34
|
+
prism (1.4.0)
|
35
|
+
public_suffix (6.0.2)
|
36
|
+
racc (1.8.1)
|
37
|
+
rainbow (3.1.1)
|
38
|
+
rake (13.3.0)
|
39
|
+
regexp_parser (2.11.2)
|
40
|
+
rexml (3.4.2)
|
41
|
+
rspec (3.13.1)
|
42
|
+
rspec-core (~> 3.13.0)
|
43
|
+
rspec-expectations (~> 3.13.0)
|
44
|
+
rspec-mocks (~> 3.13.0)
|
45
|
+
rspec-core (3.13.5)
|
46
|
+
rspec-support (~> 3.13.0)
|
47
|
+
rspec-expectations (3.13.5)
|
41
48
|
diff-lcs (>= 1.2.0, < 2.0)
|
42
|
-
rspec-support (~> 3.
|
43
|
-
rspec-mocks (3.
|
49
|
+
rspec-support (~> 3.13.0)
|
50
|
+
rspec-mocks (3.13.5)
|
44
51
|
diff-lcs (>= 1.2.0, < 2.0)
|
45
|
-
rspec-support (~> 3.
|
46
|
-
rspec-support (3.
|
47
|
-
rubocop (
|
48
|
-
|
52
|
+
rspec-support (~> 3.13.0)
|
53
|
+
rspec-support (3.13.5)
|
54
|
+
rubocop (1.80.1)
|
55
|
+
json (~> 2.3)
|
56
|
+
language_server-protocol (~> 3.17.0.2)
|
57
|
+
lint_roller (~> 1.1.0)
|
49
58
|
parallel (~> 1.10)
|
50
|
-
parser (>= 2
|
59
|
+
parser (>= 3.3.0.2)
|
51
60
|
rainbow (>= 2.2.2, < 4.0)
|
61
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
62
|
+
rubocop-ast (>= 1.46.0, < 2.0)
|
52
63
|
ruby-progressbar (~> 1.7)
|
53
|
-
unicode-display_width (>=
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
64
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
65
|
+
rubocop-ast (1.46.0)
|
66
|
+
parser (>= 3.3.7.2)
|
67
|
+
prism (~> 1.4)
|
68
|
+
ruby-progressbar (1.13.0)
|
69
|
+
thor (1.4.0)
|
70
|
+
unicode-display_width (3.1.5)
|
71
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
72
|
+
unicode-emoji (4.0.4)
|
73
|
+
webmock (3.25.1)
|
74
|
+
addressable (>= 2.8.0)
|
59
75
|
crack (>= 0.3.2)
|
60
76
|
hashdiff (>= 0.4.0, < 2.0.0)
|
61
77
|
|
@@ -63,13 +79,12 @@ PLATFORMS
|
|
63
79
|
ruby
|
64
80
|
|
65
81
|
DEPENDENCIES
|
66
|
-
|
82
|
+
appraisal (~> 2.5)
|
67
83
|
fido_metadata!
|
68
|
-
|
69
|
-
rake (~> 10.0)
|
84
|
+
rake (~> 13.0)
|
70
85
|
rspec (~> 3.8)
|
71
|
-
rubocop (
|
86
|
+
rubocop (~> 1.80)
|
72
87
|
webmock (~> 3.6)
|
73
88
|
|
74
89
|
BUNDLED WITH
|
75
|
-
|
90
|
+
2.7.1
|
data/README.md
CHANGED
@@ -26,7 +26,6 @@ First, you need to [register for an access token](https://mds2.fidoalliance.org/
|
|
26
26
|
The cache interface is compatible with Rails' [`ActiveSupport::Cache::Store`](https://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html), which means you can configure the gem to use your existing cache or a separate one:
|
27
27
|
```ruby
|
28
28
|
FidoMetadata.configure do |config|
|
29
|
-
config.metadata_token = "your token"
|
30
29
|
config.cache_backend = Rails.cache # or something like `ActiveSupport::Cache::FileStore.new(...)`
|
31
30
|
end
|
32
31
|
```
|
data/Rakefile
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
|
-
require "
|
4
|
+
require "rspec/core/rake_task"
|
5
5
|
|
6
|
-
|
7
|
-
t.libs << "test"
|
8
|
-
t.libs << "lib"
|
9
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
10
|
-
end
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
7
|
|
12
|
-
task default: :
|
8
|
+
task default: :spec
|
data/bin/console
CHANGED
@@ -7,18 +7,10 @@ require "fido_metadata"
|
|
7
7
|
# Configure in-memory cache
|
8
8
|
require "fido_metadata/test_cache_store"
|
9
9
|
FidoMetadata.configure do |config|
|
10
|
-
config.metadata_token = ENV["MDS_TOKEN"]
|
11
10
|
config.cache_backend = FidoMetadata::TestCacheStore.new
|
12
11
|
end
|
13
12
|
|
14
|
-
unless FidoMetadata.configuration.metadata_token
|
15
|
-
puts <<~TOKEN_HINT
|
16
|
-
No MDS token configured via the MDS_TOKEN environment variable.
|
17
|
-
Set one for this session: FidoMetadata.configuration.metadata_token = 'your token'
|
18
|
-
TOKEN_HINT
|
19
|
-
end
|
20
13
|
puts "Reset the cache via: FidoMetadata.configuration.cache_backend.clear"
|
21
14
|
|
22
15
|
# Start REPL
|
23
|
-
require "pry-byebug"
|
24
16
|
Pry.start
|
data/fido_metadata.gemspec
CHANGED
@@ -31,11 +31,9 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.required_ruby_version = ">= 2.3"
|
33
33
|
|
34
|
-
spec.add_dependency "
|
35
|
-
spec.
|
36
|
-
spec.add_development_dependency "
|
37
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_dependency "base64", ">= 0.1.0"
|
35
|
+
spec.add_dependency "jwt", ">= 2.0", "< 4"
|
36
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
38
37
|
spec.add_development_dependency "rspec", "~> 3.8"
|
39
|
-
spec.add_development_dependency "rubocop", "0.75.0"
|
40
38
|
spec.add_development_dependency "webmock", "~> 3.6"
|
41
39
|
end
|
data/lib/Root.cer
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
2
|
+
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
|
3
|
+
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
|
4
|
+
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
|
5
|
+
MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
|
6
|
+
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
|
7
|
+
hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
|
8
|
+
RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
|
9
|
+
gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
|
10
|
+
KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
|
11
|
+
QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
|
12
|
+
XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
|
13
|
+
DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
|
14
|
+
LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
|
15
|
+
RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
|
16
|
+
jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
|
17
|
+
6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
|
18
|
+
mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
|
19
|
+
Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
|
20
|
+
WD9f
|
15
21
|
-----END CERTIFICATE-----
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fido_metadata/attributes"
|
4
|
+
|
5
|
+
module FidoMetadata
|
6
|
+
class AuthenticatorGetInfo
|
7
|
+
extend Attributes
|
8
|
+
|
9
|
+
json_accessor("versions")
|
10
|
+
json_accessor("extensions")
|
11
|
+
json_accessor("aaguid")
|
12
|
+
json_accessor("options")
|
13
|
+
json_accessor("maxMsgSize")
|
14
|
+
json_accessor("pinUvAuthProtocols")
|
15
|
+
json_accessor("maxCredentialCountInList")
|
16
|
+
json_accessor("maxCredentialIdLength")
|
17
|
+
json_accessor("transports")
|
18
|
+
json_accessor("algorithms")
|
19
|
+
json_accessor("maxSerializedLargeBlobArray")
|
20
|
+
json_accessor("forcePINChange")
|
21
|
+
json_accessor("minPINLength")
|
22
|
+
json_accessor("firmwareVersion")
|
23
|
+
json_accessor("maxCredBlobLength")
|
24
|
+
json_accessor("maxRPIDsForSetMinPINLength")
|
25
|
+
json_accessor("preferredPlatformUvAttempts")
|
26
|
+
json_accessor("uvModality")
|
27
|
+
json_accessor("certifications")
|
28
|
+
json_accessor("remainingDiscoverableCredentials")
|
29
|
+
json_accessor("vendorPrototypeConfigCommands")
|
30
|
+
end
|
31
|
+
end
|
data/lib/fido_metadata/client.rb
CHANGED
@@ -23,13 +23,9 @@ module FidoMetadata
|
|
23
23
|
File.read(File.join(__dir__, "..", "Root.cer"))
|
24
24
|
)].freeze
|
25
25
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def download_toc(uri, trusted_certs: FIDO_ROOT_CERTIFICATES)
|
31
|
-
response = get_with_token(uri)
|
32
|
-
payload, _ = JWT.decode(response, nil, true, algorithms: ["ES256"]) do |headers|
|
26
|
+
def download_toc(uri, algorithms: ["RS256"], trusted_certs: FIDO_ROOT_CERTIFICATES)
|
27
|
+
response = get(uri)
|
28
|
+
payload, _ = JWT.decode(response, nil, true, algorithms: algorithms) do |headers|
|
33
29
|
jwt_certificates = headers["x5c"].map do |encoded|
|
34
30
|
OpenSSL::X509::Certificate.new(Base64.strict_decode64(encoded))
|
35
31
|
end
|
@@ -44,43 +40,26 @@ module FidoMetadata
|
|
44
40
|
payload
|
45
41
|
end
|
46
42
|
|
47
|
-
def download_entry(uri, expected_hash:)
|
48
|
-
response = get_with_token(uri)
|
49
|
-
decoded_hash = Base64.urlsafe_decode64(expected_hash)
|
50
|
-
unless OpenSSL.fixed_length_secure_compare(OpenSSL::Digest::SHA256.digest(response), decoded_hash)
|
51
|
-
raise(InvalidHashError)
|
52
|
-
end
|
53
|
-
|
54
|
-
decoded_body = Base64.urlsafe_decode64(response)
|
55
|
-
JSON.parse(decoded_body)
|
56
|
-
end
|
57
|
-
|
58
43
|
private
|
59
44
|
|
60
|
-
def get_with_token(uri)
|
61
|
-
if @token && !@token.empty?
|
62
|
-
uri.path += "/" unless uri.path.end_with?("/")
|
63
|
-
uri.query = "token=#{@token}"
|
64
|
-
end
|
65
|
-
get(uri)
|
66
|
-
end
|
67
|
-
|
68
45
|
def get(uri)
|
69
46
|
get = Net::HTTP::Get.new(uri, DEFAULT_HEADERS)
|
70
47
|
response = http(uri).request(get)
|
71
48
|
response.value
|
72
49
|
response.body
|
50
|
+
rescue Net::HTTPRetriableError => e
|
51
|
+
if e.response.is_a? Net::HTTPResponse
|
52
|
+
get(URI(e.response["location"]))
|
53
|
+
end
|
73
54
|
end
|
74
55
|
|
75
56
|
def http(uri)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
http
|
83
|
-
end
|
57
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
58
|
+
http.use_ssl = uri.port == 443
|
59
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
60
|
+
http.open_timeout = 5
|
61
|
+
http.read_timeout = 5
|
62
|
+
http
|
84
63
|
end
|
85
64
|
|
86
65
|
def download_crls(certificates)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fido_metadata/authenticator_get_info"
|
4
|
+
|
5
|
+
module FidoMetadata
|
6
|
+
module Coercer
|
7
|
+
module AuthenticatorGetInfo
|
8
|
+
def self.coerce(value)
|
9
|
+
return value if value.is_a?(FidoMetadata::AuthenticatorGetInfo)
|
10
|
+
|
11
|
+
FidoMetadata::AuthenticatorGetInfo.from_json(value) if value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fido_metadata/statement"
|
4
|
+
|
5
|
+
module FidoMetadata
|
6
|
+
module Coercer
|
7
|
+
module Statement
|
8
|
+
def self.coerce(value)
|
9
|
+
return value if value.is_a?(FidoMetadata::Statement)
|
10
|
+
|
11
|
+
FidoMetadata::Statement.from_json(value) if value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/fido_metadata/entry.rb
CHANGED
@@ -6,6 +6,7 @@ require "fido_metadata/status_report"
|
|
6
6
|
require "fido_metadata/coercer/date"
|
7
7
|
require "fido_metadata/coercer/escaped_uri"
|
8
8
|
require "fido_metadata/coercer/objects"
|
9
|
+
require "fido_metadata/coercer/statement"
|
9
10
|
|
10
11
|
module FidoMetadata
|
11
12
|
class Entry
|
@@ -21,5 +22,6 @@ module FidoMetadata
|
|
21
22
|
json_accessor("timeOfLastStatusChange", Coercer::Date)
|
22
23
|
json_accessor("rogueListURL", Coercer::EscapedURI)
|
23
24
|
json_accessor("rogueListHash")
|
25
|
+
json_accessor("metadataStatement", Coercer::Statement)
|
24
26
|
end
|
25
27
|
end
|
@@ -7,7 +7,7 @@ module FidoMetadata
|
|
7
7
|
module FixedLengthSecureCompare
|
8
8
|
unless OpenSSL.singleton_class.method_defined?(:fixed_length_secure_compare)
|
9
9
|
refine OpenSSL.singleton_class do
|
10
|
-
def fixed_length_secure_compare(a, b) # rubocop:disable Naming/
|
10
|
+
def fixed_length_secure_compare(a, b) # rubocop:disable Naming/MethodParameterName
|
11
11
|
raise ArgumentError, "inputs must be of equal length" unless a.bytesize == b.bytesize
|
12
12
|
|
13
13
|
# borrowed from Rack::Utils
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "fido_metadata/attributes"
|
4
|
-
require "fido_metadata/constants"
|
5
4
|
require "fido_metadata/verification_method_descriptor"
|
6
5
|
require "fido_metadata/coercer/assumed_value"
|
7
6
|
require "fido_metadata/coercer/bit_field"
|
8
7
|
require "fido_metadata/coercer/certificates"
|
9
8
|
require "fido_metadata/coercer/magic_number"
|
10
9
|
require "fido_metadata/coercer/user_verification_details"
|
10
|
+
require "fido_metadata/coercer/authenticator_get_info"
|
11
11
|
|
12
12
|
module FidoMetadata
|
13
13
|
class Statement
|
@@ -22,31 +22,25 @@ module FidoMetadata
|
|
22
22
|
json_accessor("authenticatorVersion")
|
23
23
|
json_accessor("protocolFamily", Coercer::AssumedValue.new("uaf"))
|
24
24
|
json_accessor("upv")
|
25
|
-
json_accessor("
|
26
|
-
json_accessor("
|
27
|
-
json_accessor("
|
28
|
-
Coercer::MagicNumber.new(Constants::AUTHENTICATION_ALGORITHMS, array: true))
|
29
|
-
json_accessor("publicKeyAlgAndEncoding", Coercer::MagicNumber.new(Constants::PUBLIC_KEY_FORMATS))
|
30
|
-
json_accessor("publicKeyAlgAndEncodings",
|
31
|
-
Coercer::MagicNumber.new(Constants::PUBLIC_KEY_FORMATS, array: true))
|
32
|
-
json_accessor("attestationTypes", Coercer::MagicNumber.new(Constants::ATTESTATION_TYPES, array: true))
|
25
|
+
json_accessor("authenticationAlgorithms")
|
26
|
+
json_accessor("publicKeyAlgAndEncodings")
|
27
|
+
json_accessor("attestationTypes")
|
33
28
|
json_accessor("userVerificationDetails", Coercer::UserVerificationDetails)
|
34
|
-
json_accessor("keyProtection"
|
29
|
+
json_accessor("keyProtection")
|
35
30
|
json_accessor("isKeyRestricted", Coercer::AssumedValue.new(true))
|
36
31
|
json_accessor("isFreshUserVerificationRequired", Coercer::AssumedValue.new(true))
|
37
|
-
json_accessor("matcherProtection"
|
38
|
-
Coercer::BitField.new(Constants::MATCHER_PROTECTION_TYPES, single_value: true))
|
32
|
+
json_accessor("matcherProtection")
|
39
33
|
json_accessor("cryptoStrength")
|
40
|
-
json_accessor("
|
41
|
-
json_accessor("
|
42
|
-
json_accessor("isSecondFactorOnly")
|
43
|
-
json_accessor("tcDisplay", Coercer::BitField.new(Constants::TRANSACTION_CONFIRMATION_DISPLAY_TYPES))
|
34
|
+
json_accessor("attachmentHint")
|
35
|
+
json_accessor("tcDisplay")
|
44
36
|
json_accessor("tcDisplayContentType")
|
45
37
|
json_accessor("tcDisplayPNGCharacteristics")
|
46
38
|
json_accessor("attestationRootCertificates")
|
47
39
|
json_accessor("ecdaaTrustAnchors")
|
48
40
|
json_accessor("icon")
|
49
41
|
json_accessor("supportedExtensions")
|
42
|
+
json_accessor("schema")
|
43
|
+
json_accessor("authenticatorGetInfo", Coercer::AuthenticatorGetInfo)
|
50
44
|
|
51
45
|
# Lazy load certificates for compatibility ActiveSupport::Cache. Can be removed once we require a version of
|
52
46
|
# OpenSSL which includes https://github.com/ruby/openssl/pull/281
|
data/lib/fido_metadata/store.rb
CHANGED
@@ -6,7 +6,7 @@ require "fido_metadata/statement"
|
|
6
6
|
|
7
7
|
module FidoMetadata
|
8
8
|
class Store
|
9
|
-
METADATA_ENDPOINT = URI("https://
|
9
|
+
METADATA_ENDPOINT = URI("https://mds.fidoalliance.org/")
|
10
10
|
TOC_CACHE_KEY = "metadata_toc"
|
11
11
|
STATEMENT_CACHE_KEY = "statement_%s"
|
12
12
|
|
@@ -51,8 +51,7 @@ module FidoMetadata
|
|
51
51
|
end
|
52
52
|
return unless entry
|
53
53
|
|
54
|
-
|
55
|
-
statement = FidoMetadata::Statement.from_json(json)
|
54
|
+
statement = entry.metadata_statement
|
56
55
|
cache_backend.write(
|
57
56
|
key,
|
58
57
|
statement,
|
@@ -78,16 +77,12 @@ module FidoMetadata
|
|
78
77
|
FidoMetadata.configuration.cache_backend || raise("no cache_backend configured")
|
79
78
|
end
|
80
79
|
|
81
|
-
def metadata_token
|
82
|
-
FidoMetadata.configuration.metadata_token || raise("no metadata_token configured")
|
83
|
-
end
|
84
|
-
|
85
80
|
def race_condition_ttl
|
86
81
|
FidoMetadata.configuration.race_condition_ttl
|
87
82
|
end
|
88
83
|
|
89
84
|
def client
|
90
|
-
@client ||= FidoMetadata::Client.new
|
85
|
+
@client ||= FidoMetadata::Client.new
|
91
86
|
end
|
92
87
|
end
|
93
88
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "fido_metadata/attributes"
|
4
4
|
require "fido_metadata/biometric_accuracy_descriptor"
|
5
|
-
require "fido_metadata/constants"
|
6
5
|
require "fido_metadata/code_accuracy_descriptor"
|
7
6
|
require "fido_metadata/pattern_accuracy_descriptor"
|
8
7
|
require "fido_metadata/coercer/magic_number"
|
@@ -12,7 +11,7 @@ module FidoMetadata
|
|
12
11
|
class VerificationMethodDescriptor
|
13
12
|
extend Attributes
|
14
13
|
|
15
|
-
json_accessor("
|
14
|
+
json_accessor("userVerificationMethod")
|
16
15
|
json_accessor("caDesc")
|
17
16
|
json_accessor("baDesc")
|
18
17
|
json_accessor("paDesc")
|
data/lib/fido_metadata.rb
CHANGED
metadata
CHANGED
@@ -1,71 +1,63 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fido_metadata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bart de Water
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: base64
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.17'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
24
|
+
- - ">="
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
26
|
+
version: 0.1.0
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
28
|
+
name: jwt
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
|
33
|
+
version: '2.0'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '4'
|
37
|
+
type: :runtime
|
49
38
|
prerelease: false
|
50
39
|
version_requirements: !ruby/object:Gem::Requirement
|
51
40
|
requirements:
|
52
41
|
- - ">="
|
53
42
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
43
|
+
version: '2.0'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '4'
|
55
47
|
- !ruby/object:Gem::Dependency
|
56
48
|
name: rake
|
57
49
|
requirement: !ruby/object:Gem::Requirement
|
58
50
|
requirements:
|
59
51
|
- - "~>"
|
60
52
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
53
|
+
version: '13.0'
|
62
54
|
type: :development
|
63
55
|
prerelease: false
|
64
56
|
version_requirements: !ruby/object:Gem::Requirement
|
65
57
|
requirements:
|
66
58
|
- - "~>"
|
67
59
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
60
|
+
version: '13.0'
|
69
61
|
- !ruby/object:Gem::Dependency
|
70
62
|
name: rspec
|
71
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,20 +72,6 @@ dependencies:
|
|
80
72
|
- - "~>"
|
81
73
|
- !ruby/object:Gem::Version
|
82
74
|
version: '3.8'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '='
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 0.75.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - '='
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 0.75.0
|
97
75
|
- !ruby/object:Gem::Dependency
|
98
76
|
name: webmock
|
99
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,14 +88,18 @@ dependencies:
|
|
110
88
|
version: '3.6'
|
111
89
|
description: Client for looking up metadata about FIDO authenticators, for use by
|
112
90
|
WebAuthn relying parties
|
113
|
-
email:
|
91
|
+
email:
|
114
92
|
executables: []
|
115
93
|
extensions: []
|
116
94
|
extra_rdoc_files: []
|
117
95
|
files:
|
96
|
+
- ".github/dependabot.yml"
|
97
|
+
- ".github/workflows/ci.yml"
|
98
|
+
- ".github/workflows/lint.yml"
|
118
99
|
- ".gitignore"
|
119
100
|
- ".rubocop.yml"
|
120
|
-
- ".
|
101
|
+
- ".ruby-version"
|
102
|
+
- Appraisals
|
121
103
|
- CHANGELOG.md
|
122
104
|
- CODE_OF_CONDUCT.md
|
123
105
|
- Gemfile
|
@@ -130,22 +112,26 @@ files:
|
|
130
112
|
- bin/rubocop
|
131
113
|
- bin/setup
|
132
114
|
- fido_metadata.gemspec
|
115
|
+
- gemfiles/jwt_2.gemfile
|
116
|
+
- gemfiles/jwt_3.gemfile
|
133
117
|
- lib/Root.cer
|
134
118
|
- lib/fido_metadata.rb
|
135
119
|
- lib/fido_metadata/attributes.rb
|
120
|
+
- lib/fido_metadata/authenticator_get_info.rb
|
136
121
|
- lib/fido_metadata/biometric_accuracy_descriptor.rb
|
137
122
|
- lib/fido_metadata/biometric_status_report.rb
|
138
123
|
- lib/fido_metadata/client.rb
|
139
124
|
- lib/fido_metadata/code_accuracy_descriptor.rb
|
140
125
|
- lib/fido_metadata/coercer/assumed_value.rb
|
126
|
+
- lib/fido_metadata/coercer/authenticator_get_info.rb
|
141
127
|
- lib/fido_metadata/coercer/bit_field.rb
|
142
128
|
- lib/fido_metadata/coercer/certificates.rb
|
143
129
|
- lib/fido_metadata/coercer/date.rb
|
144
130
|
- lib/fido_metadata/coercer/escaped_uri.rb
|
145
131
|
- lib/fido_metadata/coercer/magic_number.rb
|
146
132
|
- lib/fido_metadata/coercer/objects.rb
|
133
|
+
- lib/fido_metadata/coercer/statement.rb
|
147
134
|
- lib/fido_metadata/coercer/user_verification_details.rb
|
148
|
-
- lib/fido_metadata/constants.rb
|
149
135
|
- lib/fido_metadata/entry.rb
|
150
136
|
- lib/fido_metadata/pattern_accuracy_descriptor.rb
|
151
137
|
- lib/fido_metadata/refinement/fixed_length_secure_compare.rb
|
@@ -164,7 +150,7 @@ metadata:
|
|
164
150
|
homepage_uri: https://github.com/bdewater/fido_metadata
|
165
151
|
source_code_uri: https://github.com/bdewater/fido_metadata
|
166
152
|
changelog_uri: https://github.com/bdewater/fido_metadata/blob/master/CHANGELOG.md
|
167
|
-
post_install_message:
|
153
|
+
post_install_message:
|
168
154
|
rdoc_options: []
|
169
155
|
require_paths:
|
170
156
|
- lib
|
@@ -179,8 +165,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
165
|
- !ruby/object:Gem::Version
|
180
166
|
version: '0'
|
181
167
|
requirements: []
|
182
|
-
rubygems_version: 3.1
|
183
|
-
signing_key:
|
168
|
+
rubygems_version: 3.2.1
|
169
|
+
signing_key:
|
184
170
|
specification_version: 4
|
185
171
|
summary: FIDO Alliance Metadata Service client
|
186
172
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FidoMetadata
|
4
|
-
module Constants
|
5
|
-
# https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-registry-v2.0-rd-20180702.html
|
6
|
-
|
7
|
-
ATTACHMENT_HINTS = {
|
8
|
-
0x0001 => "INTERNAL",
|
9
|
-
0x0002 => "EXTERNAL",
|
10
|
-
0x0004 => "WIRED",
|
11
|
-
0x0008 => "WIRELESS",
|
12
|
-
0x0010 => "NFC",
|
13
|
-
0x0020 => "BLUETOOTH",
|
14
|
-
0x0040 => "NETWORK",
|
15
|
-
0x0080 => "READY",
|
16
|
-
0x0100 => "WIFI_DIRECT",
|
17
|
-
}.freeze
|
18
|
-
|
19
|
-
ATTESTATION_TYPES = {
|
20
|
-
0x3E07 => "BASIC_FULL", # 'Basic' in WebAuthn
|
21
|
-
0x3E08 => "BASIC_SURROGATE", # 'Self' in WebAuthn
|
22
|
-
0x3E09 => "ECDAA",
|
23
|
-
0x3E0A => "ATTCA",
|
24
|
-
}.freeze
|
25
|
-
|
26
|
-
AUTHENTICATION_ALGORITHMS = {
|
27
|
-
0x0001 => "SECP256R1_ECDSA_SHA256_RAW",
|
28
|
-
0x0002 => "SECP256R1_ECDSA_SHA256_DER",
|
29
|
-
0x0003 => "RSASSA_PSS_SHA256_RAW",
|
30
|
-
0x0004 => "RSASSA_PSS_SHA256_DER",
|
31
|
-
0x0005 => "SECP256K1_ECDSA_SHA256_RAW",
|
32
|
-
0x0006 => "SECP256K1_ECDSA_SHA256_DER",
|
33
|
-
0x0007 => "SM2_SM3_RAW",
|
34
|
-
0x0008 => "RSA_EMSA_PKCS1_SHA256_RAW",
|
35
|
-
0x0009 => "RSA_EMSA_PKCS1_SHA256_DER",
|
36
|
-
0x000A => "RSASSA_PSS_SHA384_RAW",
|
37
|
-
0x000B => "RSASSA_PSS_SHA512_RAW",
|
38
|
-
0x000C => "RSASSA_PKCSV15_SHA256_RAW",
|
39
|
-
0x000D => "RSASSA_PKCSV15_SHA384_RAW",
|
40
|
-
0x000E => "RSASSA_PKCSV15_SHA512_RAW",
|
41
|
-
0x000F => "RSASSA_PKCSV15_SHA1_RAW",
|
42
|
-
0x0010 => "SECP384R1_ECDSA_SHA384_RAW",
|
43
|
-
0x0011 => "SECP521R1_ECDSA_SHA512_RAW",
|
44
|
-
0x0012 => "ED25519_EDDSA_SHA256_RAW",
|
45
|
-
}.freeze
|
46
|
-
|
47
|
-
KEY_PROTECTION_TYPES = {
|
48
|
-
0x0001 => "SOFTWARE",
|
49
|
-
0x0002 => "HARDWARE",
|
50
|
-
0x0004 => "TEE",
|
51
|
-
0x0008 => "SECURE_ELEMENT",
|
52
|
-
0x0010 => "REMOTE_HANDLE",
|
53
|
-
}.freeze
|
54
|
-
|
55
|
-
MATCHER_PROTECTION_TYPES = {
|
56
|
-
0x0001 => "SOFTWARE",
|
57
|
-
0x0002 => "TEE",
|
58
|
-
0x0004 => "ON_CHIP",
|
59
|
-
}.freeze
|
60
|
-
|
61
|
-
PUBLIC_KEY_FORMATS = {
|
62
|
-
0x0100 => "ECC_X962_RAW",
|
63
|
-
0x0101 => "ECC_X962_DER",
|
64
|
-
0x0102 => "RSA_2048_RAW",
|
65
|
-
0x0103 => "RSA_2048_DER",
|
66
|
-
0x0104 => "COSE",
|
67
|
-
}.freeze
|
68
|
-
|
69
|
-
TRANSACTION_CONFIRMATION_DISPLAY_TYPES = {
|
70
|
-
0x0001 => "ANY",
|
71
|
-
0x0002 => "PRIVILEGED_SOFTWARE",
|
72
|
-
0x0004 => "TEE",
|
73
|
-
0x0008 => "HARDWARE",
|
74
|
-
0x0010 => "REMOTE",
|
75
|
-
}.freeze
|
76
|
-
|
77
|
-
USER_VERIFICATION_METHODS = {
|
78
|
-
0x00000001 => "PRESENCE",
|
79
|
-
0x00000002 => "FINGERPRINT",
|
80
|
-
0x00000004 => "PASSCODE",
|
81
|
-
0x00000008 => "VOICEPRINT",
|
82
|
-
0x00000010 => "FACEPRINT",
|
83
|
-
0x00000020 => "LOCATION",
|
84
|
-
0x00000040 => "EYEPRINT",
|
85
|
-
0x00000080 => "PATTERN",
|
86
|
-
0x00000100 => "HANDPRINT",
|
87
|
-
0x00000200 => "NONE",
|
88
|
-
0x00000400 => "ALL",
|
89
|
-
}.freeze
|
90
|
-
end
|
91
|
-
end
|