Class: FidoMetadata::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/fido_metadata/client.rb

Defined Under Namespace

Classes: DataIntegrityError, InvalidHashError, UnverifiedSigningKeyError

Constant Summary collapse

DEFAULT_HEADERS =
{
  "Content-Type" => "application/json",
  "User-Agent" => "fido_metadata/#{FidoMetadata::VERSION} (Ruby)"
}.freeze
FIDO_ROOT_CERTIFICATES =
[OpenSSL::X509::Certificate.new(
  File.read(File.join(__dir__, "..", "Root.cer"))
)].freeze

Instance Method Summary collapse

Constructor Details

#initialize(token) ⇒ Client

Returns a new instance of Client.



26
27
28
# File 'lib/fido_metadata/client.rb', line 26

def initialize(token)
  @token = token
end

Instance Method Details

#download_entry(uri, expected_hash:) ⇒ Object



47
48
49
50
51
52
53
54
55
56
# File 'lib/fido_metadata/client.rb', line 47

def download_entry(uri, expected_hash:)
  response = get_with_token(uri)
  decoded_hash = Base64.urlsafe_decode64(expected_hash)
  unless OpenSSL.fixed_length_secure_compare(OpenSSL::Digest::SHA256.digest(response), decoded_hash)
    raise(InvalidHashError)
  end

  decoded_body = Base64.urlsafe_decode64(response)
  JSON.parse(decoded_body)
end

#download_toc(uri, trusted_certs: FIDO_ROOT_CERTIFICATES) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/fido_metadata/client.rb', line 30

def download_toc(uri, trusted_certs: FIDO_ROOT_CERTIFICATES)
  response = get_with_token(uri)
  payload, _ = JWT.decode(response, nil, true, algorithms: ["ES256"]) do |headers|
    jwt_certificates = headers["x5c"].map do |encoded|
      OpenSSL::X509::Certificate.new(Base64.strict_decode64(encoded))
    end
    crls = download_crls(jwt_certificates)

    begin
      X5cKeyFinder.from(jwt_certificates, trusted_certs, crls)
    rescue JWT::VerificationError => e
      raise(UnverifiedSigningKeyError, e.message)
    end
  end
  payload
end