class Fastlane::Flint::Encrypt
Public Class Methods
new()
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 11 def initialize() # Keep the password in the memory so we can reuse it later on @tmp_password = nil end
Public Instance Methods
clear_password(git_url)
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 48 def clear_password(git_url) @tmp_password = "" end
decrypt_repo(path: nil, git_url: nil, manual_password: nil)
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 61 def decrypt_repo(path: nil, git_url: nil, manual_password: nil) iterate(path) do |current| begin decrypt(path: current, password: manual_password || password(git_url)) rescue UI.error("Couldn't decrypt the repo, please make sure you enter the right password! %s" % manual_password || password(git_url)) UI.user_error!("Invalid password passed via 'FLINT_PASSWORD'") if ENV["FLINT_PASSWORD"] clear_password(git_url) password(git_url) decrypt_repo(path: path, git_url: git_url) return end UI.success("🔓 Decrypted '#{File.basename(current)}'") if FastlaneCore::Globals.verbose? end UI.success("🔓 Successfully decrypted keystores repo") end
encrypt_repo(path: nil, git_url: nil)
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 52 def encrypt_repo(path: nil, git_url: nil) iterate(path) do |current| encrypt(path: current, password: password(git_url)) UI.success("🔒 Encrypted '#{File.basename(current)}'") if FastlaneCore::Globals.verbose? end UI.success("🔒 Successfully encrypted keystores repo") end
password(git_url)
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 20 def password(git_url) password = ENV["FLINT_PASSWORD"] unless password if @tmp_password password = @tmp_password end end unless password && password != '' if !UI.interactive? UI.error("The FLINT_PASSWORD environment variable did not contain a password.") UI.error("Bailing out instead of asking for a password, since this is non-interactive mode.") UI.user_error!("Try setting the FLINT_PASSWORD environment variable, or temporarily enable interactive mode to store a password.") else UI.important("Enter the passphrase that should be used to encrypt/decrypt your keystores") UI.important("Make sure to remember the password, as you'll need it when you run flint again") password = ChangePassword.ask_password(confirm: true) store_password(git_url, password) end end return password end
server_name(git_url)
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 16 def server_name(git_url) ["flint", git_url].join("_") end
store_password(git_url, password)
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 44 def store_password(git_url, password) @tmp_password = password end
Private Instance Methods
decrypt(path: nil, password: nil, hash_algorithm: "MD5")
click to toggle source
The encryption parameters in this implementations reflect the old behaviour which depended on the users' local OpenSSL version 1.0.x OpenSSL and earlier versions use MD5, 1.1.0c and newer uses SHA256, we try both before giving an error
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 115 def decrypt(path: nil, password: nil, hash_algorithm: "MD5") stored_data = Base64.decode64(File.read(path)) salt = stored_data[8..15] data_to_decrypt = stored_data[16..-1] decipher = OpenSSL::Cipher.new('AES-256-CBC') decipher.decrypt decipher.pkcs5_keyivgen(password, salt, 1, hash_algorithm) decrypted_data = decipher.update(data_to_decrypt) + decipher.final File.binwrite(path, decrypted_data) rescue => error fallback_hash_algorithm = "SHA256" if hash_algorithm != fallback_hash_algorithm decrypt(path, password, fallback_hash_algorithm) else UI.error(error.to_s) UI.crash!("Error decrypting '#{path}'") end end
encrypt(path: nil, password: nil)
click to toggle source
We encrypt with MD5 because that was the most common default value in older fastlane versions which used the local OpenSSL installation A more secure key and IV generation is needed in the future IV should be randomly generated and provided unencrypted salt should be randomly generated and provided unencrypted (like in the current implementation) key should be generated with OpenSSL::KDF::pbkdf2_hmac with properly chosen parameters Short explanation about salt and IV: stackoverflow.com/a/1950674/6324550
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 94 def encrypt(path: nil, password: nil) UI.user_error!("No password supplied") if password.to_s.strip.length == 0 data_to_encrypt = File.read(path) salt = SecureRandom.random_bytes(8) cipher = OpenSSL::Cipher.new('AES-256-CBC') cipher.encrypt cipher.pkcs5_keyivgen(password, salt, 1, "MD5") encrypted_data = "Salted__" + salt + cipher.update(data_to_encrypt) + cipher.final File.write(path, Base64.encode64(encrypted_data)) rescue FastlaneCore::Interface::FastlaneError raise rescue => error UI.error(error.to_s) UI.crash!("Error encrypting '#{path}'") end
iterate(source_path) { |path| ... }
click to toggle source
# File lib/fastlane/plugin/flint/helper/encrypt.rb, line 81 def iterate(source_path) Dir[File.join(source_path, "**", "*.{keystore}")].each do |path| next if File.directory?(path) yield(path) end end