class WebAuthn::AttestationStatement::Base
Constants
- AAGUID_EXTENSION_OID
Attributes
statement[R]
Public Class Methods
new(statement)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 31 def initialize(statement) @statement = statement end
Public Instance Methods
attestation_certificate()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 43 def attestation_certificate certificates&.first end
attestation_certificate_key_id()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 47 def attestation_certificate_key_id raw_subject_key_identifier&.unpack("H*")&.[](0) end
format()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 39 def format WebAuthn::AttestationStatement::FORMAT_TO_CLASS.key(self.class) end
valid?(_authenticator_data, _client_data_hash)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 35 def valid?(_authenticator_data, _client_data_hash) raise NotImplementedError end
Private Instance Methods
algorithm()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 78 def algorithm statement["alg"] end
attestation_root_certificates_store(aaguid: nil, attestation_certificate_key_id: nil)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 112 def attestation_root_certificates_store(aaguid: nil, attestation_certificate_key_id: nil) OpenSSL::X509::Store.new.tap do |store| root_certificates( aaguid: aaguid, attestation_certificate_key_id: attestation_certificate_key_id ).each do |cert| store.add_cert(cert) end end end
attestation_trust_path()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 90 def attestation_trust_path if certificates&.any? certificates end end
certificates()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 71 def certificates @certificates ||= raw_certificates&.map do |raw_certificate| OpenSSL::X509::Certificate.new(raw_certificate) end end
configuration()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 177 def configuration WebAuthn.configuration end
cose_algorithm()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 169 def cose_algorithm @cose_algorithm ||= COSE::Algorithm.find(algorithm).tap do |alg| alg && configuration.algorithms.include?(alg.name) || raise(UnsupportedAlgorithm, "Unsupported algorithm #{algorithm}") end end
matching_aaguid?(attested_credential_data_aaguid)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 55 def matching_aaguid?(attested_credential_data_aaguid) extension = attestation_certificate&.extensions&.detect { |ext| ext.oid == AAGUID_EXTENSION_OID } if extension # `extension.value` mangles data into ASCII, so we must manually compare bytes # see https://github.com/ruby/openssl/pull/234 extension.to_der[-WebAuthn::AuthenticatorData::AttestedCredentialData::AAGUID_LENGTH..-1] == attested_credential_data_aaguid else true end end
matching_public_key?(authenticator_data)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 67 def matching_public_key?(authenticator_data) attestation_certificate.public_key.to_der == authenticator_data.credential.public_key_object.to_der end
raw_certificates()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 82 def raw_certificates statement["x5c"] end
raw_subject_key_identifier()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 144 def raw_subject_key_identifier extension = attestation_certificate.extensions.detect { |ext| ext.oid == "subjectKeyIdentifier" } return unless extension ext_asn1 = OpenSSL::ASN1.decode(extension.to_der) ext_value = ext_asn1.value.last OpenSSL::ASN1.decode(ext_value.value).value end
root_certificates(aaguid: nil, attestation_certificate_key_id: nil)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 123 def root_certificates(aaguid: nil, attestation_certificate_key_id: nil) root_certificates = configuration.attestation_root_certificates_finders.reduce([]) do |certs, finder| if certs.empty? finder.find( attestation_format: format, aaguid: aaguid, attestation_certificate_key_id: attestation_certificate_key_id ) || [] else certs end end if root_certificates.empty? && respond_to?(:default_root_certificates, true) default_root_certificates else root_certificates end end
signature()
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 86 def signature statement["sig"] end
trustworthy?(aaguid: nil, attestation_certificate_key_id: nil)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 96 def trustworthy?(aaguid: nil, attestation_certificate_key_id: nil) if ATTESTATION_TYPES_WITH_ROOT.include?(attestation_type) configuration.acceptable_attestation_types.include?(attestation_type) && valid_certificate_chain?(aaguid: aaguid, attestation_certificate_key_id: attestation_certificate_key_id) else configuration.acceptable_attestation_types.include?(attestation_type) end end
valid_certificate_chain?(aaguid: nil, attestation_certificate_key_id: nil)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 105 def valid_certificate_chain?(aaguid: nil, attestation_certificate_key_id: nil) attestation_root_certificates_store( aaguid: aaguid, attestation_certificate_key_id: attestation_certificate_key_id ).verify(attestation_certificate, attestation_trust_path) end
valid_signature?(authenticator_data, client_data_hash, public_key = attestation_certificate.public_key)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 153 def valid_signature?(authenticator_data, client_data_hash, public_key = attestation_certificate.public_key) raise("Incompatible algorithm and key") unless cose_algorithm.compatible_key?(public_key) cose_algorithm.verify( public_key, signature, verification_data(authenticator_data, client_data_hash) ) rescue COSE::Error false end
verification_data(authenticator_data, client_data_hash)
click to toggle source
# File lib/webauthn/attestation_statement/base.rb, line 165 def verification_data(authenticator_data, client_data_hash) authenticator_data.data + client_data_hash end