-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: use metadata to retrieve root CAs for verifying packed attestation
With this commit, all the metadata server tests in the FIDO conformance tools pass
- Loading branch information
Showing
17 changed files
with
395 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,5 @@ | |
/Gemfile.lock | ||
/gemfiles/*.gemfile.lock | ||
.byebug_history | ||
|
||
/spec/conformance/metadata.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# frozen_string_literal: true | ||
|
||
require "webauthn/metadata/client" | ||
require "webauthn/metadata/table_of_contents" | ||
|
||
module WebAuthn | ||
module Metadata | ||
class Store | ||
METADATA_ENDPOINT = URI("https://mds2.fidoalliance.org/") | ||
|
||
def fetch_entry_by_aaguid(aaguid) | ||
table_of_contents.entries.detect do |entry| | ||
entry.aaguid == aaguid | ||
end | ||
end | ||
|
||
def fetch_statement_by_aaguid(aaguid) | ||
key = "statement_#{aaguid}" | ||
statement = cache_backend.read(key) | ||
return statement if statement | ||
|
||
entry = fetch_entry_by_aaguid(aaguid) | ||
return unless entry | ||
|
||
json = client.download_entry(entry.url, expected_hash: entry.hash) | ||
statement = WebAuthn::Metadata::Statement.from_json(json) | ||
cache_backend.write(key, statement) | ||
statement | ||
end | ||
|
||
private | ||
|
||
def cache_backend | ||
WebAuthn.configuration.cache_backend || raise("no cache_backend configured") | ||
end | ||
|
||
def metadata_token | ||
WebAuthn.configuration.metadata_token || raise("no metadata_token configured") | ||
end | ||
|
||
def client | ||
@client ||= WebAuthn::Metadata::Client.new(metadata_token) | ||
end | ||
|
||
def table_of_contents | ||
@table_of_contents ||= begin | ||
key = "metadata_toc" | ||
toc = cache_backend.read(key) | ||
return toc if toc | ||
|
||
json = client.download_toc(METADATA_ENDPOINT) | ||
toc = WebAuthn::Metadata::TableOfContents.from_json(json) | ||
cache_backend.write(key, toc) | ||
toc | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# frozen_string_literal: true | ||
|
||
require "zip" | ||
require_relative "../support/test_cache_store" | ||
|
||
class ConformanceCacheStore < TestCacheStore | ||
def setup_authenticators | ||
filename = "metadata.zip" | ||
puts("#{filename} not found, this will affect Metadata Service Test results.") unless File.exist?(filename) | ||
|
||
Zip::File.open(filename).glob("metadataStatements/*.json") do |file| | ||
json = JSON.parse(file.get_input_stream.read) | ||
statement = WebAuthn::Metadata::Statement.from_json(json) | ||
write("statement_#{statement.aaguid}", statement) | ||
end | ||
end | ||
|
||
def setup_metadata_store | ||
puts("Setting up metadata store TOC") | ||
response = Net::HTTP.post( | ||
URI("https://fidoalliance.co.nz/mds/getEndpoints"), | ||
{ endpoint: WebAuthn.configuration.origin }.to_json, | ||
WebAuthn::Metadata::Client::DEFAULT_HEADERS | ||
) | ||
response.value | ||
possible_endpoints = JSON.parse(response.body)["result"] | ||
|
||
client = WebAuthn::Metadata::Client.new(nil) | ||
json = possible_endpoints.each_with_index do |uri, index| | ||
begin | ||
puts("Trying endpoint #{index}: #{uri}") | ||
break client.download_toc(URI(uri), trust_store: conformance_trust_store) | ||
rescue WebAuthn::Metadata::Client::DataIntegrityError, JWT::VerificationError | ||
nil | ||
end | ||
end | ||
|
||
if json.is_a?(Hash) && json.keys == ["legalHeader", "no", "nextUpdate", "entries"] | ||
puts("TOC setup done!") | ||
toc = WebAuthn::Metadata::TableOfContents.from_json(json) | ||
write("metadata_toc", toc) | ||
else | ||
puts("Unable to setup TOC!") | ||
end | ||
end | ||
|
||
private | ||
|
||
def conformance_trust_store | ||
store = OpenSSL::X509::Store.new | ||
store.purpose = OpenSSL::X509::PURPOSE_ANY | ||
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK | OpenSSL::X509::V_FLAG_CRL_CHECK_ALL | ||
file = File.read(File.join(__dir__, "..", "support", "MDSROOT.crt")) | ||
store.add_cert(OpenSSL::X509::Certificate.new(file)) | ||
end | ||
end |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# frozen_string_literal: true | ||
|
||
# A very simple cache story for the test suite that mimics the ActiveSupport::Cache::Store interface | ||
class TestCacheStore | ||
def initialize | ||
@store = {} | ||
end | ||
|
||
def read(name, _options = nil) | ||
@store[name] | ||
end | ||
|
||
def write(name, value, _options = nil) | ||
@store[name] = value | ||
end | ||
|
||
def delete(name, _options = nil) | ||
@store.delete(name) | ||
end | ||
|
||
def clear(_options = nil) | ||
@store.clear | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ | ||
dWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAw | ||
MDBaGA8yMDUwMDkwNDAwMDAwMFowLjEsMCoGA1UEAxMjWXViaWNvIFUyRiBSb290 | ||
IENBIFNlcmlhbCA0NTcyMDA2MzEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK | ||
AoIBAQC/jwYuhBVlqaiYWEMsrWFisgJ+PtM91eSrpI4TK7U53mwCIawSDHy8vUmk | ||
5N2KAj9abvT9NP5SMS1hQi3usxoYGonXQgfO6ZXyUA9a+KAkqdFnBnlyugSeCOep | ||
8EdZFfsaRFtMjkwz5Gcz2Py4vIYvCdMHPtwaz0bVuzneueIEz6TnQjE63Rdt2zbw | ||
nebwTG5ZybeWSwbzy+BJ34ZHcUhPAY89yJQXuE0IzMZFcEBbPNRbWECRKgjq//qT | ||
9nmDOFVlSRCt2wiqPSzluwn+v+suQEBsUjTGMEd25tKXXTkNW21wIWbxeSyUoTXw | ||
LvGS6xlwQSgNpk2qXYwf8iXg7VWZAgMBAAGjQjBAMB0GA1UdDgQWBBQgIvz0bNGJ | ||
hjgpToksyKpP9xv9oDAPBgNVHRMECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAN | ||
BgkqhkiG9w0BAQsFAAOCAQEAjvjuOMDSa+JXFCLyBKsycXtBVZsJ4Ue3LbaEsPY4 | ||
MYN/hIQ5ZM5p7EjfcnMG4CtYkNsfNHc0AhBLdq45rnT87q/6O3vUEtNMafbhU6kt | ||
hX7Y+9XFN9NpmYxr+ekVY5xOxi8h9JDIgoMP4VB1uS0aunL1IGqrNooL9mmFnL2k | ||
LVVee6/VR6C5+KSTCMCWppMuJIZII2v9o4dkoZ8Y7QRjQlLfYzd3qGtKbw7xaF1U | ||
sG/5xUb/Btwb2X2g4InpiB/yt/3CpQXpiWX/K4mBvUKiGn05ZsqeY1gx4g0xLBqc | ||
U9psmyPzK+Vsgw2jeRQ5JlKDyqE0hebfC1tvFu0CCrJFcw== | ||
-----END CERTIFICATE----- |
Oops, something went wrong.