DEV: Apply syntax_tree formatting to lib/*

This commit is contained in:
David Taylor
2023-01-09 12:10:19 +00:00
parent b0fda61a8e
commit 6417173082
507 changed files with 16550 additions and 12627 deletions

View File

@@ -35,7 +35,7 @@ module Webauthn
ChallengeSession.new(
challenge: SecureRandom.hex(30),
rp_id: Discourse.current_hostname,
rp_name: SiteSetting.title
rp_name: SiteSetting.title,
)
end
end

View File

@@ -1,21 +1,24 @@
# frozen_string_literal: true
require 'cose'
require "cose"
module Webauthn
class SecurityKeyAuthenticationService < SecurityKeyBaseValidationService
##
# See https://w3c.github.io/webauthn/#sctn-verifying-assertion for
# the steps followed here. Memoized methods are called in their
# place in the step flow to make the process clearer.
def authenticate_security_key
return false if @params.blank? || (!@params.is_a?(Hash) && !@params.is_a?(ActionController::Parameters))
if @params.blank? || (!@params.is_a?(Hash) && !@params.is_a?(ActionController::Parameters))
return false
end
# 3. Identify the user being authenticated and verify that this user is the
# owner of the public key credential source credentialSource identified by credential.id:
security_key = UserSecurityKey.find_by(credential_id: @params[:credentialId])
raise(NotFoundError, I18n.t('webauthn.validation.not_found_error')) if security_key.blank?
raise(OwnershipError, I18n.t('webauthn.validation.ownership_error')) if security_key.user != @current_user
raise(NotFoundError, I18n.t("webauthn.validation.not_found_error")) if security_key.blank?
if security_key.user != @current_user
raise(OwnershipError, I18n.t("webauthn.validation.ownership_error"))
end
# 4. Using credential.id (or credential.rawId, if base64url encoding is inappropriate for your use case),
# look up the corresponding credential public key and let credentialPublicKey be that credential public key.
@@ -67,18 +70,24 @@ module Webauthn
cose_algorithm = COSE::Algorithm.find(cose_key.alg)
if cose_algorithm.blank?
Rails.logger.error("Unknown COSE algorithm encountered. alg: #{cose_key.alg}. user_id: #{@current_user.id}. params: #{@params.inspect}")
raise(UnknownCOSEAlgorithmError, I18n.t('webauthn.validation.unknown_cose_algorithm_error'))
Rails.logger.error(
"Unknown COSE algorithm encountered. alg: #{cose_key.alg}. user_id: #{@current_user.id}. params: #{@params.inspect}",
)
raise(UnknownCOSEAlgorithmError, I18n.t("webauthn.validation.unknown_cose_algorithm_error"))
end
if !cose_key.to_pkey.verify(cose_algorithm.hash_function, signature, auth_data + client_data_hash)
raise(PublicKeyError, I18n.t('webauthn.validation.public_key_error'))
if !cose_key.to_pkey.verify(
cose_algorithm.hash_function,
signature,
auth_data + client_data_hash,
)
raise(PublicKeyError, I18n.t("webauthn.validation.public_key_error"))
end
# Success! Update the last used at time for the key.
security_key.update(last_used: Time.zone.now)
rescue OpenSSL::PKey::PKeyError
raise(PublicKeyError, I18n.t('webauthn.validation.public_key_error'))
raise(PublicKeyError, I18n.t("webauthn.validation.public_key_error"))
end
private

View File

@@ -9,29 +9,32 @@ module Webauthn
end
def validate_webauthn_type(type_to_check)
return if client_data['type'] == type_to_check
raise(InvalidTypeError, I18n.t('webauthn.validation.invalid_type_error'))
return if client_data["type"] == type_to_check
raise(InvalidTypeError, I18n.t("webauthn.validation.invalid_type_error"))
end
def validate_challenge
return if challenge_match?
raise(ChallengeMismatchError, I18n.t('webauthn.validation.challenge_mismatch_error'))
raise(ChallengeMismatchError, I18n.t("webauthn.validation.challenge_mismatch_error"))
end
def validate_origin
return if origin_match?
raise(InvalidOriginError, I18n.t('webauthn.validation.invalid_origin_error'))
raise(InvalidOriginError, I18n.t("webauthn.validation.invalid_origin_error"))
end
def validate_rp_id_hash
return if rp_id_hash_match?
raise(InvalidRelyingPartyIdError, I18n.t('webauthn.validation.invalid_relying_party_id_error'))
raise(
InvalidRelyingPartyIdError,
I18n.t("webauthn.validation.invalid_relying_party_id_error"),
)
end
def validate_user_verification
flags = auth_data[32].unpack("b*")[0].split('')
return if flags[0] == '1'
raise(UserVerificationError, I18n.t('webauthn.validation.user_verification_error'))
flags = auth_data[32].unpack("b*")[0].split("")
return if flags[0] == "1"
raise(UserVerificationError, I18n.t("webauthn.validation.user_verification_error"))
end
private
@@ -49,11 +52,11 @@ module Webauthn
end
def challenge_match?
Base64.decode64(client_data['challenge']) == @challenge_params[:challenge]
Base64.decode64(client_data["challenge"]) == @challenge_params[:challenge]
end
def origin_match?
client_data['origin'] == @challenge_params[:origin]
client_data["origin"] == @challenge_params[:origin]
end
def rp_id_hash_match?

View File

@@ -1,10 +1,9 @@
# frozen_string_literal: true
require 'cbor'
require 'cose'
require "cbor"
require "cose"
module Webauthn
class SecurityKeyRegistrationService < SecurityKeyBaseValidationService
##
# See https://w3c.github.io/webauthn/#sctn-registering-a-new-credential for
# the registration steps followed here. Memoized methods are called in their
@@ -50,8 +49,14 @@ module Webauthn
# https://w3c.github.io/webauthn/#table-attestedCredentialData
# See https://www.iana.org/assignments/cose/cose.xhtml#algorithms for supported algorithm
# codes.
credential_public_key, credential_public_key_bytes, credential_id = extract_public_key_and_credential_from_attestation(auth_data)
raise(UnsupportedPublicKeyAlgorithmError, I18n.t('webauthn.validation.unsupported_public_key_algorithm_error')) if ::Webauthn::SUPPORTED_ALGORITHMS.exclude?(credential_public_key.alg)
credential_public_key, credential_public_key_bytes, credential_id =
extract_public_key_and_credential_from_attestation(auth_data)
if ::Webauthn::SUPPORTED_ALGORITHMS.exclude?(credential_public_key.alg)
raise(
UnsupportedPublicKeyAlgorithmError,
I18n.t("webauthn.validation.unsupported_public_key_algorithm_error"),
)
end
# 14. Verify that the values of the client extension outputs in clientExtensionResults and the authenticator
# extension outputs in the extensions in authData are as expected, considering the client extension input
@@ -67,8 +72,12 @@ module Webauthn
# name [WebAuthn-Registries].
# 16. Verify that attStmt is a correct attestation statement, conveying a valid attestation signature,
# by using the attestation statement format fmts verification procedure given attStmt, authData and hash.
if ::Webauthn::VALID_ATTESTATION_FORMATS.exclude?(attestation['fmt']) || attestation['fmt'] != 'none'
raise(UnsupportedAttestationFormatError, I18n.t('webauthn.validation.unsupported_attestation_format_error'))
if ::Webauthn::VALID_ATTESTATION_FORMATS.exclude?(attestation["fmt"]) ||
attestation["fmt"] != "none"
raise(
UnsupportedAttestationFormatError,
I18n.t("webauthn.validation.unsupported_attestation_format_error"),
)
end
#==================================================
@@ -92,7 +101,9 @@ module Webauthn
# the registration, e.g. while deleting the older registration.
encoded_credential_id = Base64.strict_encode64(credential_id)
endcoded_public_key = Base64.strict_encode64(credential_public_key_bytes)
raise(CredentialIdInUseError, I18n.t('webauthn.validation.credential_id_in_use_error')) if UserSecurityKey.exists?(credential_id: encoded_credential_id)
if UserSecurityKey.exists?(credential_id: encoded_credential_id)
raise(CredentialIdInUseError, I18n.t("webauthn.validation.credential_id_in_use_error"))
end
# 20. If the attestation statement attStmt verified successfully and is found to be trustworthy,
# then register the new credential with the account that was denoted in options.user, by
@@ -103,10 +114,10 @@ module Webauthn
credential_id: encoded_credential_id,
public_key: endcoded_public_key,
name: @params[:name],
factor_type: UserSecurityKey.factor_types[:second_factor]
factor_type: UserSecurityKey.factor_types[:second_factor],
)
rescue CBOR::UnpackError, CBOR::TypeError, CBOR::MalformedFormatError, CBOR::StackError
raise MalformedAttestationError, I18n.t('webauthn.validation.malformed_attestation_error')
raise MalformedAttestationError, I18n.t("webauthn.validation.malformed_attestation_error")
end
private
@@ -116,7 +127,7 @@ module Webauthn
end
def auth_data
@auth_data ||= attestation['authData']
@auth_data ||= attestation["authData"]
end
def extract_public_key_and_credential_from_attestation(auth_data)
@@ -128,9 +139,12 @@ module Webauthn
attested_credential_data_start_position = rp_id_length + flags_length + sign_count_length # 37
attested_credential_data_length = auth_data.size - attested_credential_data_start_position
attested_credential_data = auth_data[
attested_credential_data_start_position..(attested_credential_data_start_position + attested_credential_data_length - 1)
]
attested_credential_data =
auth_data[
attested_credential_data_start_position..(
attested_credential_data_start_position + attested_credential_data_length - 1
)
]
# see https://w3c.github.io/webauthn/#attested-credential-data for lengths
# of data for extraction
@@ -139,9 +153,10 @@ module Webauthn
credential_id = attested_credential_data[18..(18 + credential_id_length - 1)]
public_key_start_position = 18 + credential_id_length
public_key_bytes = attested_credential_data[
public_key_start_position..(public_key_start_position + attested_credential_data.size - 1)
]
public_key_bytes =
attested_credential_data[
public_key_start_position..(public_key_start_position + attested_credential_data.size - 1)
]
public_key = COSE::Key.deserialize(public_key_bytes)
[public_key, public_key_bytes, credential_id]