Class: MobileSecrets::SecretsHandler

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

Constant Summary collapse

SUPPORTED_ALGORITHMS =
%w[XOR AES-GCM].freeze

Instance Method Summary collapse

Instance Method Details

#encrypt(output_file_path, string, gpg_path) ⇒ Object



61
62
63
64
65
66
# File 'lib/src/secrets_handler.rb', line 61

def encrypt output_file_path, string, gpg_path
  gpg_path = "." unless gpg_path
  gpg_path =  "#{Dir.pwd}/#{gpg_path}"
  dotgpg = Dotgpg::Dir.new(gpg_path)
  dotgpg.encrypt output_file_path, string
end

#encrypt_file(password, file, output_file_path) ⇒ Object



68
69
70
71
72
73
74
# File 'lib/src/secrets_handler.rb', line 68

def encrypt_file password, file, output_file_path
  encryptor = FileHandler.new password
  abort("Configuration contains file #{file} that cannot be found! Please check your mobile-secrets configuration or add the file into directory.") unless File.exist? file
  encrypted_content = encryptor.encrypt file

  File.open(output_file_path, "wb") { |f| f.write encrypted_content }
end

#export_secrets(path, from_encrypted_file_name) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/src/secrets_handler.rb', line 15

def export_secrets path, from_encrypted_file_name
  decrypted_config = decrypt_secrets(from_encrypted_file_name)
  file_names_bytes, secrets_bytes, algorithm = process_yaml_config decrypted_config

  renderer = MobileSecrets::SourceRenderer.new "swift"
  renderer.render_template secrets_bytes, file_names_bytes, "#{path}/secrets.swift", algorithm
  decrypted_config
end

#process_yaml_config(yaml_string) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/src/secrets_handler.rb', line 24

def process_yaml_config yaml_string
  config = YAML.safe_load(yaml_string)["MobileSecrets"]
  hash_key = config["hashKey"]
  secrets_dict = config["secrets"]
  files = config["files"]
  should_include_password = config["shouldIncludePassword"]
  algorithm = (config["alg"] || "XOR").upcase

  abort("Unsupported algorithm '#{algorithm}'. Valid options: #{SUPPORTED_ALGORITHMS.join(', ')}.") \
    unless SUPPORTED_ALGORITHMS.include?(algorithm)
  abort("hashKey must be exactly 32 characters for AES-GCM encryption.") \
    if algorithm == "AES-GCM" && hash_key.length != 32

  secrets_bytes = should_include_password ? [hash_key.bytes] : []
  file_names_bytes = []
  obfuscator = MobileSecrets::Obfuscator.new hash_key

  secrets_dict.each do |key, value|
    if algorithm == "AES-GCM"
      secrets_bytes << key.bytes << encrypt_aes_gcm(value.to_s, hash_key, key)
    else
      encrypted = obfuscator.obfuscate(value.to_s)
      secrets_bytes << key.bytes << encrypted.bytes
    end
  end

  if files
    abort("hashKey must be 32 characters long for files encryption.") if hash_key.length != 32
    files.each do |f|
      encrypt_file hash_key, f, "#{f}.enc"
      file_names_bytes << f.bytes
    end
  end

  return file_names_bytes, secrets_bytes, algorithm
end