Module: TwoFactorAuth

Defined in:
app/models/two_factor_auth/registration_response.rb,
lib/two_factor_auth.rb,
lib/two_factor_auth/engine.rb,
lib/two_factor_auth/version.rb,
lib/two_factor_auth/registration_hook.rb,
app/models/two_factor_auth/client_data.rb,
app/models/two_factor_auth/registration.rb,
lib/two_factor_auth/authentication_hook.rb,
app/helpers/two_factor_auth/application_helper.rb,
app/models/two_factor_auth/registration_request.rb,
app/helpers/two_factor_auth/registrations_helper.rb,
app/models/two_factor_auth/registration_verifier.rb,
lib/generators/two_factor_auth/install_generator.rb,
app/models/two_factor_auth/authentication_request.rb,
app/helpers/two_factor_auth/authentications_helper.rb,
app/models/two_factor_auth/authentication_response.rb,
app/models/two_factor_auth/authentication_verifier.rb,
app/models/two_factor_auth/authentication_client_data.rb,
app/controllers/two_factor_auth/registrations_controller.rb,
app/controllers/two_factor_auth/trusted_facets_controller.rb,
app/controllers/two_factor_auth/authentications_controller.rb,
app/controllers/two_factor_auth/two_factor_auth_controller.rb

Overview

See FIDO U2F “Raw Message Formats” documentation, section 4.3 “Registration Response Message: Success”

Defined Under Namespace

Modules: ApplicationHelper, AuthenticationHook, AuthenticationsHelper, Generators, RegistrationHook, RegistrationsHelper Classes: AuthenticationClientData, AuthenticationRequest, AuthenticationResponse, AuthenticationVerifier, AuthenticationsController, CantGenerateRandomNumbers, ClientData, Engine, InvalidFacetDomain, InvalidPublicKey, Registration, RegistrationRequest, RegistrationResponse, RegistrationVerifier, RegistrationsController, TrustedFacetsController, TwoFactorAuthController, TwoFactorAuthError

Constant Summary collapse

U2F_VERSION =
'U2F_V2'
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.decode_pubkey(raw) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/two_factor_auth.rb', line 74

def self.decode_pubkey raw
  bn = OpenSSL::BN.new(raw, 2)
  group = OpenSSL::PKey::EC::Group.new('prime256v1')
  point = OpenSSL::PKey::EC::Point.new(group, bn)
rescue OpenSSL::PKey::EC::Point::Error => e
  raise InvalidPublicKey, "Invalid public key: #{e.message}"
end

.facet_domainObject



32
33
34
# File 'lib/two_factor_auth.rb', line 32

def self.facet_domain
  @facet_domain
end

.facet_domain=(facet_domain) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/two_factor_auth.rb', line 18

def self.facet_domain= facet_domain
  if facet_domain =~ /localhost(:\d+)?\/?$/
    raise InvalidFacetDomain, "Facet domain can't be localhost, edit /etc/hosts to make a custom hostname"
  end
  if facet_domain =~ /\.dev(:\d+)?\/?$/
    raise InvalidFacetDomain, "Facet domain needs a real TLD, not .dev. Edit /etc/hosts to make a custom hostname"
  end
  if facet_domain == "https://www.example.com"
    raise InvalidFacetDomain, "You need to cusomize the facet_domain in config/initializers/two_factor_auth.rb"
  end

  @facet_domain = facet_domain.sub(/\/$/, '')
end

.facetsObject



48
49
50
51
52
53
54
# File 'lib/two_factor_auth.rb', line 48

def self.facets
  if @facets.nil? or @facets.empty?
    [facet_domain]
  else
    @facets
  end
end

.facets=(facets) ⇒ Object



44
45
46
# File 'lib/two_factor_auth.rb', line 44

def self.facets= facets
  @facets = facets
end

.pubkey_valid?(raw) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
85
86
87
# File 'lib/two_factor_auth.rb', line 82

def self.pubkey_valid? raw
  pk = decode_pubkey raw
  pk.on_curve?
rescue InvalidPublicKey
  false
end

.random_encoded_challengeObject



67
68
69
70
71
72
# File 'lib/two_factor_auth.rb', line 67

def self.random_encoded_challenge
  random = OpenSSL::Random.pseudo_bytes(32)
  TwoFactorAuth::websafe_base64_encode(random)
rescue OpenSSL::Random::RandomError
  raise CantGenerateRandomNumbers, "Not enough entropy to generate secure challenges"
end

.trusted_facet_list_urlObject



40
41
42
# File 'lib/two_factor_auth.rb', line 40

def self.trusted_facet_list_url
  @trusted_facet_list_url or "#{facet_domain}/two_factor_auth/trusted_facets"
end

.trusted_facet_list_url=(url) ⇒ Object



36
37
38
# File 'lib/two_factor_auth.rb', line 36

def self.trusted_facet_list_url= url
  @trusted_facet_list_url = url
end

.websafe_base64_decode(encoded) ⇒ Object



61
62
63
64
65
# File 'lib/two_factor_auth.rb', line 61

def self.websafe_base64_decode encoded
  # pad back out to decode
  padded = encoded.ljust((encoded.length/4.0).ceil * 4, '=')
  Base64.urlsafe_decode64(padded)
end

.websafe_base64_encode(str) ⇒ Object



56
57
58
59
# File 'lib/two_factor_auth.rb', line 56

def self.websafe_base64_encode str
  # PHP code removes trailing =s, don't know why
  Base64.urlsafe_encode64(str).sub(/=+$/,'')
end