Class: Cyphera::Client

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_config(config) ⇒ Object



27
28
29
# File 'lib/cyphera/cyphera.rb', line 27

def self.from_config(config)
  new(config)
end

.from_file(path) ⇒ Object



22
23
24
25
# File 'lib/cyphera/cyphera.rb', line 22

def self.from_file(path)
  config = JSON.parse(File.read(path))
  from_config(config)
end

.loadObject



14
15
16
17
18
19
20
# File 'lib/cyphera/cyphera.rb', line 14

def self.load
  env = ENV['CYPHERA_CONFIG_FILE']
  return from_file(env) if env && File.exist?(env)
  return from_file('cyphera.json') if File.exist?('cyphera.json')
  return from_file('/etc/cyphera/cyphera.json') if File.exist?('/etc/cyphera/cyphera.json')
  raise 'No configuration file found. Checked: CYPHERA_CONFIG_FILE env, ./cyphera.json, /etc/cyphera/cyphera.json'
end

.resolve_key_source(name, config) ⇒ Object

Raises:

  • (ArgumentError)


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/cyphera/cyphera.rb', line 126

def self.resolve_key_source(name, config)
  source = config['source']

  case source
  when 'env'
    var_name = config['var'] or raise ArgumentError, "Key '#{name}': source 'env' requires 'var' field"
    val = ENV[var_name] or raise ArgumentError, "Key '#{name}': environment variable '#{var_name}' is not set"
    encoding = config['encoding'] || 'hex'
    return encoding == 'base64' ? val.unpack1('m') : [val].pack('H*')
  when 'file'
    path = config['path'] or raise ArgumentError, "Key '#{name}': source 'file' requires 'path' field"
    raw = File.read(path).strip
    encoding = config['encoding'] || (path.end_with?('.b64', '.base64') ? 'base64' : 'hex')
    return encoding == 'base64' ? raw.unpack1('m') : [raw].pack('H*')
  end

  if CLOUD_SOURCES.include?(source)
    begin
      require 'cyphera-keychain'
      return CypheraKeychain.resolve(source, config)
    rescue LoadError
      raise LoadError,
        "Key '#{name}' requires source '#{source}' but cyphera-keychain is not installed.\n" \
        "Install it: gem install cyphera-keychain"
    end
  end

  raise ArgumentError, "Key '#{name}': unknown source '#{source}'. Valid: env, file, #{CLOUD_SOURCES.join(', ')}"
end

Instance Method Details

#access(protected_value, configuration_name = nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/cyphera/cyphera.rb', line 42

def access(protected_value, configuration_name = nil)
  if configuration_name
    configuration = get_configuration(configuration_name)
    if configuration['header_enabled']
      raise ArgumentError,
        "configuration '#{configuration_name}' has header_enabled=true; use access(value) — " \
        'the header identifies the configuration. The two-arg form is for ' \
        'header_enabled=false configurations only.'
    end
    return access_fpe(protected_value, configuration)
  end

  access_by_header(protected_value)
end

#access_by_header(protected_value) ⇒ Object

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
# File 'lib/cyphera/cyphera.rb', line 57

def access_by_header(protected_value)
  @header_index.keys.sort_by { |h| -h.length }.each do |header|
    if protected_value.length > header.length && protected_value.start_with?(header)
      configuration = get_configuration(@header_index[header])
      stripped = protected_value[header.length..]
      return access_fpe(stripped, configuration)
    end
  end

  raise ArgumentError, 'No matching header found. Use access(value, configuration_name) for headerless values.'
end

#protect(value, configuration_name) ⇒ Object



31
32
33
34
35
36
37
38
39
40
# File 'lib/cyphera/cyphera.rb', line 31

def protect(value, configuration_name)
  configuration = get_configuration(configuration_name)
  case configuration['engine']
  when 'ff1' then protect_fpe(value, configuration, false)
  when 'ff3' then protect_fpe(value, configuration, true)
  when 'mask' then protect_mask(value, configuration)
  when 'hash' then protect_hash(value, configuration)
  else raise ArgumentError, "Unknown engine: #{configuration['engine']}"
  end
end