cici 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0e0d27ce6125fb072e36aa5a3e197bd3ad70742d5171c2f2f360b771179d23a
4
- data.tar.gz: bd919b3ef9990aa2952461ee646febdb9c803fbafe2c2f298d5168ea0b286731
3
+ metadata.gz: fc0f1060894123ec9ccd7d9679db5a3a43f16cfd30194ebfc9446b7b424e3398
4
+ data.tar.gz: c30d7439f9088bd33b935749c9f42628abf5e3b23d3d899957acacd83ceb4a72
5
5
  SHA512:
6
- metadata.gz: d1f5f125bbcfb71b5975f1cec0a5aeb7a442af524ceca952d6e8583da752bfb79627397958768bacd88dc89aa44c4333053f0f8fe76a5de58c6b5a381fddd735
7
- data.tar.gz: 71614938679b2d015f7224e5d4d4f754d2d116a8a687fe3a5b36fed1aded3e429720fe3640b8475a7703d4e1acae5e73d17bf68d2cbb320c456d143a3d7e27be
6
+ metadata.gz: 28e9d08d9cf1e40bcc983593234fac72fa27cbff47ee98f85f6b9e683f7715a09477f3b135681788e7958cd7dda9dd88dfebbbcb72fdd28ba5a03e348890d2aa
7
+ data.tar.gz: e78fa84bb9d79582a794ade9464a449ffa6ecb0d1b27143b6e6ed394828e4b4ef3d99e68d8a712442f0e6eb03672f7977c65b772cd238a8c9cf9853495fbfe03
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [0.2.0] - 2020-03-03
2
+
3
+ ### Changed
4
+ - Reuse the key/iv values to encrypt. [Issue](https://github.com/levibostian/cici/issues/2)
5
+
1
6
  ## [0.1.0] - 2019-12-17
2
7
 
3
8
  ### Added
data/lib/cici/cli.rb CHANGED
@@ -24,6 +24,9 @@ module CICI
24
24
  @config = CICI::Config.new(@ui)
25
25
  @config.load
26
26
 
27
+ @decrypter = CICI::Decrypt.new(@ui, @config)
28
+ @encrypter = CICI::Encrypt.new(@ui, @decrypter, @config)
29
+
27
30
  run_command
28
31
  end
29
32
 
@@ -82,11 +85,11 @@ module CICI
82
85
  end
83
86
 
84
87
  def encrypt
85
- CICI::Encrypt.new(@ui, @config).start
88
+ @encrypter.start
86
89
  end
87
90
 
88
91
  def decrypt
89
- CICI::Decrypt.new(@ui, @config).start(@options.set)
92
+ @decrypter.start(@options.set)
90
93
  end
91
94
  end
92
95
  end
data/lib/cici/decrypt.rb CHANGED
@@ -25,29 +25,35 @@ module CICI
25
25
  @set = set
26
26
 
27
27
  assert_encrypted_secret_exist
28
- decrypt
28
+ plain = decrypt(Base64.decode64(@util.get_env(CICI::DECRYPT_KEY_ENV_VAR)), Base64.decode64(@util.get_env(CICI::DECRYPT_IV_ENV_VAR)))
29
+ if !plain.empty?
30
+ File.write(@config.output_file, plain)
31
+ else
32
+ @ui.fail('Wrong key/iv pair for decryption.')
33
+ end
29
34
  decompress
30
35
  copy_files
31
36
 
32
37
  @ui.success('Files successfully decrypted and copied to their destination!')
33
38
  end
34
39
 
35
- private
36
-
37
- def assert_encrypted_secret_exist
38
- @ui.fail("Encrypted secrets file, #{@config.output_file_encrypted}, does not exist") unless File.file?(@config.output_file_encrypted)
39
- end
40
-
41
- def decrypt
40
+ def decrypt(key, iv)
42
41
  @ui.verbose('Decrypting secrets encrypted file.')
43
42
 
44
43
  decipher = OpenSSL::Cipher.new('AES-256-CBC')
45
44
  decipher.decrypt
46
- decipher.key = Base64.decode64(@util.get_env(CICI::DECRYPT_KEY_ENV_VAR))
47
- decipher.iv = Base64.decode64(@util.get_env(CICI::DECRYPT_IV_ENV_VAR))
45
+ decipher.key = key
46
+ decipher.iv = iv
48
47
 
49
48
  plain = decipher.update(File.read(@config.output_file_encrypted)) + decipher.final
50
- File.write(@config.output_file, plain)
49
+
50
+ plain
51
+ end
52
+
53
+ private
54
+
55
+ def assert_encrypted_secret_exist
56
+ @ui.fail("Encrypted secrets file, #{@config.output_file_encrypted}, does not exist") unless File.file?(@config.output_file_encrypted)
51
57
  end
52
58
 
53
59
  def decompress
data/lib/cici/encrypt.rb CHANGED
@@ -14,14 +14,24 @@ module CICI
14
14
  class Encrypt
15
15
  include CICI
16
16
 
17
- def initialize(ui, config)
17
+ def initialize(ui, decrypter, config)
18
18
  @ui = ui
19
19
  @config = config
20
20
  @util = CICI::Util.new(@ui)
21
+ @decrypter = decrypter
22
+
23
+ # Default key/iv that's generated for you. We can change these values later before encryption.
24
+ aes = OpenSSL::Cipher.new('AES-256-CBC')
25
+ aes.encrypt
26
+ @encryption_key = aes.random_key
27
+ @encryption_iv = aes.random_iv
28
+ @first_time_encrypting = false
21
29
  end
22
30
 
23
31
  def start
24
32
  assert_secret_files_exist
33
+ # We want to reuse key/iv values for encryption. So, let's get those values before moving forward.
34
+ prompt_for_keys
25
35
  compress
26
36
  assert_files_in_gitignore
27
37
  encrypt
@@ -45,6 +55,30 @@ module CICI
45
55
  end
46
56
  end
47
57
 
58
+ def prompt_for_keys
59
+ has_encrypted_before = File.exist?(@config.output_file)
60
+
61
+ if has_encrypted_before
62
+ @ui.message('It looks like you have encrypted your secrets before.')
63
+ @ui.message('Enter the key you use to encrypt:')
64
+ key = Base64.decode64(STDIN.gets.chomp)
65
+ @ui.message('Enter the IV you use to encrypt:')
66
+ iv = Base64.decode64(STDIN.gets.chomp)
67
+
68
+ plain = @decrypter.decrypt(key, iv)
69
+ @ui.fail('Key or IV value does not match the key/IV pair used when previously encrypting') if plain.empty?
70
+
71
+ @encryption_key = key
72
+ @encryption_iv = iv
73
+ else
74
+ @ui.debug("Encrypted output file, #{@config.output_file}, does not exist. Therefore, let's assume this is the first time encrypting secrets.")
75
+
76
+ @ui.message('It looks like this is the first time that you are encrypting secrets.')
77
+ @ui.message('Generating secure keys for you...')
78
+ @first_time_encrypting = true
79
+ end
80
+ end
81
+
48
82
  def compress
49
83
  @ui.verbose('Compressing secrets...')
50
84
 
@@ -57,14 +91,23 @@ module CICI
57
91
  aes = OpenSSL::Cipher.new('AES-256-CBC')
58
92
  data = File.binread(@config.output_file)
59
93
  aes.encrypt
60
- key = aes.random_key
61
- iv = aes.random_iv
94
+ aes.key = @encryption_key
95
+ aes.iv = @encryption_iv
62
96
  File.write(@config.output_file_encrypted, aes.update(data) + aes.final)
63
97
 
64
- @ui.success('Success! Now, you need to follow these last few steps:')
65
- @ui.success("1. Make sure to add #{@config.output_file_encrypted} to your source code repository")
66
- @ui.success("2. Create a *secret* environment variable with key: #{CICI::DECRYPT_KEY_ENV_VAR} with value: #{Base64.encode64(key).strip}")
67
- @ui.success("3. Create a *secret* environment variable with key: #{CICI::DECRYPT_IV_ENV_VAR} with value: #{Base64.encode64(iv).strip}")
98
+ if @first_time_encrypting
99
+ @ui.success('Success! Now, you need to follow these last few steps:')
100
+ @ui.success("1. Make sure to add #{@config.output_file_encrypted} to your version control")
101
+ @ui.success('Below you will find secret keys used to encrypt and decrypt your secrets in the future.')
102
+ @ui.success('**These will not be revealed ever again!** Store these in a safe and secure place.')
103
+ @ui.success('')
104
+ @ui.success('2. Share these secret keys with your team. They must provide the same keys to encrypt again. Keep secrets up-to-date with a git hook.')
105
+ @ui.success('3. Set these *secret* environment variables in your CI server for decryption.')
106
+ @ui.success("Key: #{CICI::DECRYPT_KEY_ENV_VAR} and value: #{Base64.encode64(@encryption_key).strip}")
107
+ @ui.success("Key: #{CICI::DECRYPT_IV_ENV_VAR} and value: #{Base64.encode64(@encryption_iv).strip}")
108
+ else
109
+ @ui.success('Success!')
110
+ end
68
111
  end
69
112
 
70
113
  def assert_files_in_gitignore
data/lib/cici/ui.rb CHANGED
@@ -18,6 +18,11 @@ module CICI
18
18
  abort(message.colorize(:red))
19
19
  end
20
20
 
21
+ # No way to disable this. These are message that must be outputted.
22
+ def message(message)
23
+ puts message
24
+ end
25
+
21
26
  def warning(message)
22
27
  puts message.to_s.colorize(:yellow)
23
28
  end
data/lib/cici/version.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module CICI
4
4
  class Version
5
5
  def self.get
6
- '0.1.0'
6
+ '0.2.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cici
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Levi Bostian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-18 00:00:00.000000000 Z
11
+ date: 2020-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize