class WebAuthn::Context::Authentication

Attributes

authenticator_data[RW]

Public Instance Methods

authentication?() click to toggle source
# File lib/web_authn/context/authentication.rb, line 11
def authentication?
  true
end
verify!(encoded_authenticator_data, sign_count:, signature:, public_key: nil, public_cose_key: nil, digest: OpenSSL::Digest::SHA256.new) click to toggle source
# File lib/web_authn/context/authentication.rb, line 15
def verify!(encoded_authenticator_data, sign_count:, signature:, public_key: nil, public_cose_key: nil, digest: OpenSSL::Digest::SHA256.new)
  unless public_key || public_cose_key
    raise ArgumentError, 'missing keyword: public_key or public_cose_key'
  end

  self.authenticator_data = AuthenticatorData.decode(
    Base64.urlsafe_decode64 encoded_authenticator_data
  )
  verify_flags!
  verify_sign_count!(sign_count)
  verify_signature!(public_key, public_cose_key, signature, digest)
  self
end

Private Instance Methods

verify_flags!() click to toggle source
Calls superclass method WebAuthn::Context#verify_flags!
# File lib/web_authn/context/authentication.rb, line 31
def verify_flags!
  super
  raise InvalidAssertion, 'Unexpected Flag: "at"' if flags.at?
end
verify_sign_count!(before) click to toggle source
# File lib/web_authn/context/authentication.rb, line 36
def verify_sign_count!(before)
  if before == 0 && sign_count == 0
    self # NOTE: no counter supported on the authenticator
  elsif before < sign_count
    self
  else
    raise InvalidAssertion, 'Invalid Sign Count'
  end
end
verify_signature!(public_key, public_cose_key, signature, digest) click to toggle source
# File lib/web_authn/context/authentication.rb, line 46
def verify_signature!(public_key, public_cose_key, signature, digest)
  signature_base_string = [
    authenticator_data.raw,
    OpenSSL::Digest::SHA256.digest(client_data_json.raw)
  ].join
  if public_cose_key
    public_key, digest = [public_cose_key.to_key, public_cose_key.digest]
  end
  verification_method = case public_key
  when OpenSSL::PKey::RSA
    :verify_pss
  when OpenSSL::PKey::EC
    :verify
  end
  result = public_key.send(
    verification_method,
    digest,
    Base64.urlsafe_decode64(signature),
    signature_base_string
  )
  if result
    self
  else
    raise InvalidAssertion, 'Invalid Signature'
  end
end