Class: Cyphera::Client
- Inherits:
-
Object
- Object
- Cyphera::Client
- Defined in:
- lib/cyphera/cyphera.rb
Class Method Summary collapse
- .from_config(config) ⇒ Object
- .from_file(path) ⇒ Object
- .load ⇒ Object
- .resolve_key_source(name, config) ⇒ Object
Instance Method Summary collapse
-
#access(protected_value, configuration_name = nil) ⇒ Object
Reverse a protected value.
- #protect(value, configuration_name) ⇒ Object
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 |
.load ⇒ Object
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
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/cyphera/cyphera.rb', line 135 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
Reverse a protected value. The SDK uses the loaded configurations to figure out which one applies — it checks the leading bytes of ‘protected_value` against the registered headers (longest first to avoid prefix collisions), strips the matched header, and decrypts.
The optional ‘configuration_name` is an escape hatch for unique situations where the protected value has no header (mainframe formats, fixed-width legacy systems, etc.). When provided, the value is decrypted as raw headerless ciphertext using the named configuration. Prefer the 1-arg form for normal use; the 2-arg form is intentionally not pushed in examples.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/cyphera/cyphera.rb', line 52 def access(protected_value, configuration_name = nil) if configuration_name configuration = get_configuration(configuration_name) case configuration['engine'] when 'mask' raise ArgumentError, "cannot reverse '#{configuration_name}' — mask is irreversible" when 'hash' raise ArgumentError, "cannot reverse '#{configuration_name}' — hash is irreversible" end return access_fpe(protected_value, configuration) end @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' end |
#protect(value, configuration_name) ⇒ Object
31 32 33 34 35 36 37 38 39 |
# File 'lib/cyphera/cyphera.rb', line 31 def protect(value, configuration_name) configuration = get_configuration(configuration_name) case configuration['engine'] when 'ff1', 'ff3', 'ff31' then protect_fpe(value, configuration) when 'mask' then protect_mask(value, configuration) when 'hash' then protect_hash(value, configuration) else raise ArgumentError, "unknown engine: #{configuration['engine']}" end end |