rapid-vaults 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +94 -0
- data/bin/rapid-vaults +4 -0
- data/lib/rapid-vaults/api.rb +20 -0
- data/lib/rapid-vaults/cli.rb +47 -0
- data/lib/rapid-vaults/decrypt.rb +27 -0
- data/lib/rapid-vaults/encrypt.rb +24 -0
- data/lib/rapid-vaults/generate.rb +19 -0
- data/lib/rapid-vaults.rb +51 -0
- data/spec/fixtures/file.yaml +1 -0
- data/spec/rapid-vaults/api_spec.rb +16 -0
- data/spec/rapid-vaults/cli_spec.rb +20 -0
- data/spec/rapid-vaults/decrypt_spec.rb +29 -0
- data/spec/rapid-vaults/encrypt_spec.rb +28 -0
- data/spec/rapid-vaults/generate_spec.rb +25 -0
- data/spec/rapid-vaults_spec.rb +32 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/system/system_spec.rb +54 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d67262209d01142c67ff7d217f1cc967e6adeb4e
|
4
|
+
data.tar.gz: 3702f2c91fb43a52189ab806c7bd7fb6b74c6bf9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f11460cc7949a564f78d17488a63e0751058833d69715e5153ec3ee45f934dc1c0c22c9a2acd666f7f9d590573bf5157c9f5b6561d89a46c587e7d16501e708d
|
7
|
+
data.tar.gz: 11e1eb5da4c8c61a7012e8f966866b6d4e0eb88aadd96a75f8bb1b1c30bcf90012f8e9a722355fa20edaf4268ce4fc68f9b6c71cd94a370791205f0cf4276485
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# Rapid Vaults
|
2
|
+
Currently in beta and can be used without expectation of support.
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/mschuchard/rapid-vaults.svg?branch=master)](https://travis-ci.org/mschuchard/rapid-vaults)
|
5
|
+
|
6
|
+
- [Description](#description)
|
7
|
+
- [Usage](#usage)
|
8
|
+
- [CLI](#cli)
|
9
|
+
- [API](#api)
|
10
|
+
- [Contributing](#contributing)
|
11
|
+
|
12
|
+
## Description
|
13
|
+
|
14
|
+
Rapid Vaults is a gem that performs ad-hoc encryption and decryption of data behind multiple layers of protection via OpenSSL or GPG. It is lightweight and easy-to-use software to secure and retrieve your data with multiple layers of defense and verification.
|
15
|
+
|
16
|
+
### Comparative Software
|
17
|
+
|
18
|
+
Ansible-Vault is very similar to Rapid Vaults. Both are streamlined and easy to use ad-hoc encryption and decryption tools. The two primary differences are that Rapid Vaults has a Ruby API instead of a Python API and that Rapid Vaults offers additional verification and defense layers. The API can also be considered similar to the high level recipes provided by PyCA's Cryptography.
|
19
|
+
|
20
|
+
### Non-Comparative Software
|
21
|
+
|
22
|
+
Rapid Vaults is not similar to tools like RbNaCl or Hashicorp's Vault. RbNaCl offers advanced encryption techniques by providing bindings to libsodium. Rapid Vaults relies upon AES-256-GCM or GPG. Hashicorp's Vault is Enterprise level software with many powerful features and conveniences. Rapid Vaults is a lightweight and narrowly focused tool.
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
### CLI
|
27
|
+
|
28
|
+
```
|
29
|
+
usage: rapid-vaults [options] file
|
30
|
+
-g, --generate Generate a key and nonce for encryption and decryption.
|
31
|
+
-e, --encrypt Encrypt a file using a key and nonce and generate a tag.
|
32
|
+
-d, --decrypt Decrypt a file using a key, nonce, and tag.
|
33
|
+
-k, --key key Key file to be used for encryption or decryption.
|
34
|
+
-n, --nonce nonce Nonce file to be used for encryption or decryption.
|
35
|
+
-t, --tag tag Tag file to be used for decryption.
|
36
|
+
-p, --password password (optional) Password to be used for encryption or decryption.
|
37
|
+
```
|
38
|
+
|
39
|
+
#### Generate Key and Nonce
|
40
|
+
`rapid-vaults -g`
|
41
|
+
|
42
|
+
#### Encrypt File with SSL
|
43
|
+
|
44
|
+
`rapid-vaults -e -k cert.key -n nonce.txt -p secret unencrypted.txt`
|
45
|
+
|
46
|
+
#### Decrypt a File with SSL
|
47
|
+
|
48
|
+
`rapid-vaults -d -k cert.key -n nonce.txt -t tag.txt -p secret encrypted.txt`
|
49
|
+
|
50
|
+
### API
|
51
|
+
|
52
|
+
#### Generate Key and Nonce
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
require 'rapid-vaults'
|
56
|
+
|
57
|
+
options = {}
|
58
|
+
options[:action] = :generate
|
59
|
+
key, nonce = RapidVaults::API.main(options)
|
60
|
+
```
|
61
|
+
|
62
|
+
#### Encrypt with SSL
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
require 'rapid-vaults'
|
66
|
+
|
67
|
+
options = {}
|
68
|
+
options[:action] = :encrypt
|
69
|
+
options[:file] = '/path/to/data.txt'
|
70
|
+
options[:key] = '/path/to/cert.key'
|
71
|
+
options[:nonce] = '/path/to/nonce.txt'
|
72
|
+
options[:pw] = File.read('/path/to/password.txt') # optional
|
73
|
+
encrypted_contents, tag = RapidVaults::API.main(options)
|
74
|
+
```
|
75
|
+
|
76
|
+
#### Decrypt with SSL
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
require 'rapid-vaults'
|
80
|
+
|
81
|
+
options = {}
|
82
|
+
options[:action] = :decrypt
|
83
|
+
options[:file] = '/path/to/data.txt'
|
84
|
+
options[:key] = '/path/to/cert.key'
|
85
|
+
options[:nonce] = '/path/to/nonce.txt'
|
86
|
+
options[:tag] = '/path/to/tag.txt'
|
87
|
+
options[:pw] = File.read('/path/to/password.txt') # optional
|
88
|
+
decrypted_contents = RapidVaults::API.main(options)
|
89
|
+
```
|
90
|
+
|
91
|
+
## Contributing
|
92
|
+
Code should pass all spec tests. New features should involve new spec tests. Adherence to Rubocop and Reek is expected where not overly onerous or where the check is of dubious cost/benefit.
|
93
|
+
|
94
|
+
A [Dockerfile](Dockerfile) is provided for easy rake testing. A [Vagrantfile](Vagrantfile) is provided for easy gem building, installation, and post-installation testing.
|
data/bin/rapid-vaults
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../rapid-vaults'
|
2
|
+
|
3
|
+
# provides an application programming interface to interact with rapid vaults
|
4
|
+
class RapidVaults::API
|
5
|
+
# lightweight api
|
6
|
+
def self.main(settings)
|
7
|
+
# parse settings in api and denote using api
|
8
|
+
RapidVaults.settings = parse(settings)
|
9
|
+
|
10
|
+
# run RapidVaults with specified file
|
11
|
+
RapidVaults.new.main
|
12
|
+
end
|
13
|
+
|
14
|
+
# parse api options
|
15
|
+
def self.parse(settings)
|
16
|
+
# establish settings for api
|
17
|
+
settings[:ui] = :api
|
18
|
+
settings
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../rapid-vaults'
|
2
|
+
|
3
|
+
# provides a command line interface to interact with rapid vaults
|
4
|
+
class RapidVaults::CLI
|
5
|
+
# point of entry from executable
|
6
|
+
def self.main(args)
|
7
|
+
# parse args in cli and denote using cli
|
8
|
+
parse(args)
|
9
|
+
unless RapidVaults.settings[:action] == :generate
|
10
|
+
args.empty? ? (raise 'rapid-vaults: no file specified; try using --help') : RapidVaults.settings[:file] = args.first
|
11
|
+
end
|
12
|
+
|
13
|
+
# run RapidVaults with specified file
|
14
|
+
RapidVaults.new.main
|
15
|
+
0
|
16
|
+
end
|
17
|
+
|
18
|
+
# parse cli options
|
19
|
+
def self.parse(args)
|
20
|
+
require 'optparse'
|
21
|
+
|
22
|
+
# show help message if no args specified
|
23
|
+
args = %w[-h] if args.empty?
|
24
|
+
|
25
|
+
# specify cli being used
|
26
|
+
RapidVaults.settings[:ui] = :cli
|
27
|
+
|
28
|
+
opt_parser = OptionParser.new do |opts|
|
29
|
+
# usage
|
30
|
+
opts.banner = 'usage: rapid-vaults [options] file'
|
31
|
+
|
32
|
+
# generate, encrypt, or decrypt
|
33
|
+
opts.on('-g', '--generate', 'Generate a key and nonce for encryption and decryption.') { RapidVaults.settings[:action] = :generate }
|
34
|
+
opts.on('-e', '--encrypt', 'Encrypt a file using a key and nonce and generate a tag.') { RapidVaults.settings[:action] = :encrypt }
|
35
|
+
opts.on('-d', '--decrypt', 'Decrypt a file using a key, nonce, and tag.') { RapidVaults.settings[:action] = :decrypt }
|
36
|
+
|
37
|
+
# key, nonce, password, and tag
|
38
|
+
opts.on('-k', '--key key', String, 'Key file to be used for encryption or decryption.') { |arg| RapidVaults.settings[:key] = arg }
|
39
|
+
opts.on('-n', '--nonce nonce', String, 'Nonce file to be used for encryption or decryption.') { |arg| RapidVaults.settings[:nonce] = arg }
|
40
|
+
opts.on('-t', '--tag tag', String, 'Tag file to be used for decryption.') { |arg| RapidVaults.settings[:tag] = arg }
|
41
|
+
opts.on('-p', '--password password', String, '(optional) Password to be used for encryption or decryption.') { |arg| RapidVaults.settings[:pw] = arg }
|
42
|
+
opts.on('-f', '--file-password password.txt', String, '(optional) Text file containing a password to be used for encryption or decryption.') { |arg| RapidVaults.settings[:pw] = File.read(arg) }
|
43
|
+
end
|
44
|
+
|
45
|
+
opt_parser.parse!(args)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
# decrypts strings using supplied decryption settings
|
4
|
+
class Decrypt
|
5
|
+
# decrypts a string
|
6
|
+
def self.main(settings)
|
7
|
+
# check tag size
|
8
|
+
raise 'Tag is not 16 bytes.' unless settings[:tag].bytesize == 16
|
9
|
+
|
10
|
+
# setup the decryption parameters
|
11
|
+
decipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt
|
12
|
+
decipher.key = settings[:key]
|
13
|
+
decipher.iv = settings[:nonce]
|
14
|
+
decipher.auth_tag = settings[:tag]
|
15
|
+
decipher.auth_data = settings.key?(:pw) ? settings[:pw] : ''
|
16
|
+
|
17
|
+
# output the decrypted file
|
18
|
+
if settings[:ui] == :cli
|
19
|
+
# output to file
|
20
|
+
File.write('decrypted.txt', decipher.update(settings[:file]) + decipher.final)
|
21
|
+
puts 'Your decrypted.txt has been written out to the current directory.'
|
22
|
+
elsif settings[:ui] == :api
|
23
|
+
# output to string
|
24
|
+
decipher.update(settings[:file]) + decipher.final
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
# encrypts strings using supplied encryption settings
|
4
|
+
class Encrypt
|
5
|
+
# encrypts a string
|
6
|
+
def self.main(settings)
|
7
|
+
# setup the encryption parameters
|
8
|
+
cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
|
9
|
+
cipher.key = settings[:key]
|
10
|
+
cipher.iv = settings[:nonce]
|
11
|
+
cipher.auth_data = settings.key?(:pw) ? settings[:pw] : ''
|
12
|
+
|
13
|
+
# output the encrypted file and associated tag
|
14
|
+
if settings[:ui] == :cli
|
15
|
+
# output to file
|
16
|
+
File.write('encrypted.txt', cipher.update(settings[:file]) + cipher.final)
|
17
|
+
File.write('tag.txt', cipher.auth_tag)
|
18
|
+
puts 'Your encrypted.txt and associated tag.txt for this encryption have been generated in your current directory.'
|
19
|
+
elsif settings[:ui] == :api
|
20
|
+
# output to array
|
21
|
+
[cipher.update(settings[:file]) + cipher.final, cipher.auth_tag]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require_relative '../rapid-vaults'
|
3
|
+
|
4
|
+
# generates files necessary for encryption and decryption
|
5
|
+
class Generate
|
6
|
+
# generates a key and nonce
|
7
|
+
def self.main(settings)
|
8
|
+
cipher = OpenSSL::Cipher.new('aes-256-gcm').encrypt
|
9
|
+
if settings[:ui] == :cli
|
10
|
+
# output to file
|
11
|
+
File.write('key.txt', cipher.random_key)
|
12
|
+
File.write('nonce.txt', cipher.random_iv)
|
13
|
+
puts 'Your key.txt and nonce.txt have been generated in your current directory.'
|
14
|
+
elsif settings[:ui] == :api
|
15
|
+
# output to string
|
16
|
+
[cipher.random_key, cipher.random_iv]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rapid-vaults.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative 'rapid-vaults/decrypt'
|
2
|
+
require_relative 'rapid-vaults/encrypt'
|
3
|
+
require_relative 'rapid-vaults/generate'
|
4
|
+
|
5
|
+
# interfaces from cli/api, validates settings, and then distributes actions to appropriate classes
|
6
|
+
class RapidVaults
|
7
|
+
# initialize settings hash
|
8
|
+
@settings = {}
|
9
|
+
|
10
|
+
# allow cli and api read/write access to settings with self since this is singleton
|
11
|
+
class << self
|
12
|
+
attr_accessor :settings
|
13
|
+
end
|
14
|
+
|
15
|
+
# main runner for software
|
16
|
+
def main
|
17
|
+
# short circuit if we are generating
|
18
|
+
return Generate.main(self.class.settings) if self.class.settings[:action] == :generate
|
19
|
+
|
20
|
+
# process settings
|
21
|
+
self.class.process
|
22
|
+
|
23
|
+
# execute desired action via dynamic call
|
24
|
+
# public_send("#{self.class.settings[:action].capitalize}.main".to_sym)
|
25
|
+
case self.class.settings[:action]
|
26
|
+
when :encrypt then Encrypt.main(self.class.settings)
|
27
|
+
when :decrypt then Decrypt.main(self.class.settings)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# method for processing the settings and inputs
|
32
|
+
def self.process
|
33
|
+
# check for problems with arguments
|
34
|
+
case @settings[:action]
|
35
|
+
when :encrypt
|
36
|
+
raise 'File, key, and nonce arguments are required for encryption.' unless @settings.key?(:file) && @settings.key?(:key) && @settings.key?(:nonce)
|
37
|
+
when :decrypt
|
38
|
+
raise 'File, key, nonce, and tag arguments are required for decryption.' unless @settings.key?(:file) && @settings.key?(:key) && @settings.key?(:nonce) && @settings.key?(:tag)
|
39
|
+
else
|
40
|
+
raise 'Action must be one of generate, encrypt, or decrypt.'
|
41
|
+
end
|
42
|
+
|
43
|
+
# check for problems with inputs and read in files
|
44
|
+
raise 'Password must be a string.' if @settings.key?(:pw) && !settings[:pw].is_a?(String)
|
45
|
+
File.file?(@settings[:file]) ? @settings[:file] = File.read(@settings[:file]) : (raise 'Input file is not an existing file.')
|
46
|
+
File.file?(@settings[:key]) ? @settings[:key] = File.read(@settings[:key]) : (raise 'Input key is not an existing file.')
|
47
|
+
File.file?(@settings[:nonce]) ? @settings[:nonce] = File.read(@settings[:nonce]) : (raise 'Input nonce is not an existing file.')
|
48
|
+
return unless @settings[:action] == :decrypt
|
49
|
+
File.file?(@settings[:tag]) ? @settings[:tag] = File.read(@settings[:tag]) : (raise 'Input tag is not an existing file.')
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
foo: bar
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/rapid-vaults/api'
|
3
|
+
|
4
|
+
describe RapidVaults::API do
|
5
|
+
context '.parse' do
|
6
|
+
it 'correctly parses the settings for encrypt' do
|
7
|
+
expect(RapidVaults::API.parse(action: :encrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')).to eq(ui: :api, action: :encrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')
|
8
|
+
end
|
9
|
+
it 'correctly parses the settings for decrypt' do
|
10
|
+
expect(RapidVaults::API.parse(action: :decrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')).to eq(ui: :api, action: :decrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')
|
11
|
+
end
|
12
|
+
it 'correctly parses the settings for decrypt' do
|
13
|
+
expect(RapidVaults::API.parse(action: :generate)).to eq(ui: :api, action: :generate)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/rapid-vaults/cli'
|
3
|
+
|
4
|
+
describe RapidVaults::CLI do
|
5
|
+
context '.parse' do
|
6
|
+
it 'correctly parses the user arguments for encrypt' do
|
7
|
+
RapidVaults::CLI.parse(%w[-e -k key.txt -n nonce.txt -p secret file.txt])
|
8
|
+
expect(RapidVaults.instance_variable_get(:@settings)).to eq(ui: :cli, action: :encrypt, key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')
|
9
|
+
end
|
10
|
+
it 'correctly parses the arguments for decrypt' do
|
11
|
+
RapidVaults::CLI.parse(%w[-d -k key.txt -n nonce.txt -t tag.txt -p secret file.txt])
|
12
|
+
expect(RapidVaults.instance_variable_get(:@settings)).to eq(ui: :cli, action: :decrypt, key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')
|
13
|
+
end
|
14
|
+
it 'correctly parses the arguments for generate' do
|
15
|
+
RapidVaults.instance_variable_set(:@settings, {})
|
16
|
+
RapidVaults::CLI.parse(%w[-g])
|
17
|
+
expect(RapidVaults.instance_variable_get(:@settings)).to eq(ui: :cli, action: :generate)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/rapid-vaults/encrypt'
|
3
|
+
require_relative '../../lib/rapid-vaults/decrypt'
|
4
|
+
|
5
|
+
describe Decrypt do
|
6
|
+
before(:all) do
|
7
|
+
Encrypt.main(ui: :cli, file: "foo: bar\n", key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M')
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:all) do
|
11
|
+
%w[tag.txt encrypted.txt decrypted.txt].each { |file| File.delete(file) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context '.decrypt' do
|
15
|
+
it 'outputs a decrypted file with the key, nonce, and tag from the cli' do
|
16
|
+
Decrypt.main(ui: :cli, file: File.read('encrypted.txt'), key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M', tag: File.read('tag.txt'))
|
17
|
+
expect(File.file?('decrypted.txt')).to be true
|
18
|
+
expect(File.read('decrypted.txt')).to eq("foo: bar\n")
|
19
|
+
end
|
20
|
+
it 'outputs decrypted content with the key, nonce, and tag from the api' do
|
21
|
+
decrypt = Decrypt.main(ui: :api, file: File.read('encrypted.txt'), key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M', tag: File.read('tag.txt'))
|
22
|
+
expect(decrypt).to be_a(String)
|
23
|
+
expect(decrypt).to eq("foo: bar\n")
|
24
|
+
end
|
25
|
+
it 'raises an error for an invalid tag size' do
|
26
|
+
expect { Decrypt.main(file: File.read('encrypted.txt'), key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M', tag: "�a����e�O_H|�\n") }.to raise_error('Tag is not 16 bytes.')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/rapid-vaults/encrypt'
|
3
|
+
|
4
|
+
describe Encrypt do
|
5
|
+
after(:all) do
|
6
|
+
%w[tag.txt encrypted.txt].each { |file| File.delete(file) }
|
7
|
+
end
|
8
|
+
|
9
|
+
context '.encrypt' do
|
10
|
+
it 'outputs an encrypted file with the key and nonce from the cli' do
|
11
|
+
Encrypt.main(ui: :cli, file: "foo: bar\n", key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M')
|
12
|
+
expect(File.file?('tag.txt')).to be true
|
13
|
+
expect(File.file?('encrypted.txt')).to be true
|
14
|
+
end
|
15
|
+
it 'outputs an encrypted file with the key, nonce, and password from the cli' do
|
16
|
+
Encrypt.main(ui: :cli, file: "foo: bar\n", key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M', password: 'password')
|
17
|
+
expect(File.file?('tag.txt')).to be true
|
18
|
+
expect(File.file?('encrypted.txt')).to be true
|
19
|
+
end
|
20
|
+
it 'outputs an array of encrypted content and tag with the key and nonce from the api' do
|
21
|
+
encrypt = Encrypt.main(ui: :api, file: "foo: bar\n", key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M')
|
22
|
+
expect(encrypt).to be_a(Array)
|
23
|
+
expect(encrypt[0]).to be_a(String)
|
24
|
+
expect(encrypt[1]).to be_a(String)
|
25
|
+
expect(encrypt.length).to eq(2)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/rapid-vaults/generate'
|
3
|
+
|
4
|
+
describe RapidVaults do
|
5
|
+
after(:all) do
|
6
|
+
%w[key.txt nonce.txt].each { |file| File.delete(file) }
|
7
|
+
end
|
8
|
+
|
9
|
+
context '.generate' do
|
10
|
+
it 'generates the key and nonce files from the cli' do
|
11
|
+
Generate.main(ui: :cli)
|
12
|
+
expect(File.file?('key.txt')).to be true
|
13
|
+
expect(File.file?('nonce.txt')).to be true
|
14
|
+
expect(File.read('key.txt')).to be_a(String)
|
15
|
+
expect(File.read('nonce.txt')).to be_a(String)
|
16
|
+
end
|
17
|
+
it 'outputs an array with the key and nonce from the api' do
|
18
|
+
generate = Generate.main(ui: :api)
|
19
|
+
expect(generate).to be_a(Array)
|
20
|
+
expect(generate[0]).to be_a(String)
|
21
|
+
expect(generate[1]).to be_a(String)
|
22
|
+
expect(generate.length).to eq(2)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative '../lib/rapid-vaults'
|
3
|
+
|
4
|
+
describe RapidVaults do
|
5
|
+
# let(:rapidvaults) { RapidVaults.new('fixtures/foo.yml', 'fixtures/key.txt', 'fixtures/nonce.txt', 'fixtures/tag.txt') }
|
6
|
+
|
7
|
+
context '.process' do
|
8
|
+
it 'raises an error for a non-string password' do
|
9
|
+
RapidVaults.instance_variable_set(:@settings, action: :encrypt, file: 'a', key: 'b', nonce: 'c', pw: 1)
|
10
|
+
expect { RapidVaults.process }.to raise_error('Password must be a string.')
|
11
|
+
end
|
12
|
+
it 'raises an error for a missing argument to encrypt' do
|
13
|
+
RapidVaults.instance_variable_set(:@settings, action: :encrypt, file: 'a', key: 'b')
|
14
|
+
expect { RapidVaults.process }.to raise_error('File, key, and nonce arguments are required for encryption.')
|
15
|
+
end
|
16
|
+
it 'raises an error for a missing argument to decrypt' do
|
17
|
+
RapidVaults.instance_variable_set(:@settings, action: :decrypt, file: 'a', key: 'b', nonce: 'c')
|
18
|
+
expect { RapidVaults.process }.to raise_error('File, key, nonce, and tag arguments are required for decryption.')
|
19
|
+
end
|
20
|
+
it 'raises an error for a missing action' do
|
21
|
+
RapidVaults.instance_variable_set(:@settings, file: 'a', key: 'b', nonce: 'c', tag: 'd')
|
22
|
+
expect { RapidVaults.process }.to raise_error('Action must be one of generate, encrypt, or decrypt.')
|
23
|
+
end
|
24
|
+
it 'raises an error for a nonexistent input file' do
|
25
|
+
RapidVaults.instance_variable_set(:@settings, action: :encrypt, file: 'a', key: 'b', nonce: 'c', tag: 'd')
|
26
|
+
expect { RapidVaults.process }.to raise_error('Input file is not an existing file.')
|
27
|
+
end
|
28
|
+
it 'reads in all input files correctly for decryption' do
|
29
|
+
#
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require_relative '../../lib/rapid-vaults/cli'
|
3
|
+
require_relative '../../lib/rapid-vaults/api'
|
4
|
+
|
5
|
+
describe RapidVaults do
|
6
|
+
after(:all) do
|
7
|
+
%w[key.txt nonce.txt tag.txt encrypted.txt decrypted.txt].each { |file| File.delete(file) }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'executed as a system from the CLI with settings and a file to be processed' do
|
11
|
+
it 'generates key and nonce, encrypts a file, and then decrypts a file in order' do
|
12
|
+
# generate and utilize files inside suitable directory
|
13
|
+
Dir.chdir(fixtures_dir)
|
14
|
+
|
15
|
+
# generate key and nonce
|
16
|
+
RapidVaults::CLI.main(%w[-g])
|
17
|
+
expect(File.file?('key.txt')).to be true
|
18
|
+
expect(File.file?('nonce.txt')).to be true
|
19
|
+
|
20
|
+
# generate encrypted file
|
21
|
+
RapidVaults::CLI.main(%w[-e -k key.txt -n nonce.txt -p password file.yaml])
|
22
|
+
expect(File.file?('tag.txt')).to be true
|
23
|
+
expect(File.file?('encrypted.txt')).to be true
|
24
|
+
|
25
|
+
# generate decrypted file
|
26
|
+
RapidVaults::CLI.main(%w[-d -k key.txt -n nonce.txt -t tag.txt -p password encrypted.txt])
|
27
|
+
expect(File.file?('decrypted.txt')).to be true
|
28
|
+
expect(File.read('decrypted.txt')).to eq("foo: bar\n")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'executed as a system from the API with settings and a file to be processed' do
|
33
|
+
it 'generates key and nonce, encrypts a file, and then decrypts a file in order' do
|
34
|
+
# generate and utilize files inside suitable directory
|
35
|
+
Dir.chdir(fixtures_dir)
|
36
|
+
|
37
|
+
# generate key and nonce
|
38
|
+
RapidVaults::API.main(action: :generate)
|
39
|
+
expect(File.file?('key.txt')).to be true
|
40
|
+
expect(File.file?('nonce.txt')).to be true
|
41
|
+
|
42
|
+
# generate encrypted file
|
43
|
+
encrypt, tag = RapidVaults::API.main(action: :encrypt, file: 'file.yaml', key: 'key.txt', nonce: 'nonce.txt', password: 'password')
|
44
|
+
expect(encrypt).to be_a(String)
|
45
|
+
expect(tag).to be_a(String)
|
46
|
+
|
47
|
+
# generate decrypted file
|
48
|
+
File.write('encrypted.txt', encrypt)
|
49
|
+
File.write('tag.txt', tag)
|
50
|
+
decrypt = RapidVaults::API.main(action: :decrypt, file: 'encrypted.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', password: 'password')
|
51
|
+
expect(decrypt).to eq("foo: bar\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rapid-vaults
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Schuchard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '9'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '13'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '9'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '13'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: reek
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '4.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rubocop
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
description: Ad-hoc encrypt and decrypt data behind multiple layers of protection
|
76
|
+
via OpenSSL or GPG.
|
77
|
+
email:
|
78
|
+
executables:
|
79
|
+
- rapid-vaults
|
80
|
+
extensions: []
|
81
|
+
extra_rdoc_files: []
|
82
|
+
files:
|
83
|
+
- README.md
|
84
|
+
- bin/rapid-vaults
|
85
|
+
- lib/rapid-vaults.rb
|
86
|
+
- lib/rapid-vaults/api.rb
|
87
|
+
- lib/rapid-vaults/cli.rb
|
88
|
+
- lib/rapid-vaults/decrypt.rb
|
89
|
+
- lib/rapid-vaults/encrypt.rb
|
90
|
+
- lib/rapid-vaults/generate.rb
|
91
|
+
- spec/fixtures/file.yaml
|
92
|
+
- spec/rapid-vaults/api_spec.rb
|
93
|
+
- spec/rapid-vaults/cli_spec.rb
|
94
|
+
- spec/rapid-vaults/decrypt_spec.rb
|
95
|
+
- spec/rapid-vaults/encrypt_spec.rb
|
96
|
+
- spec/rapid-vaults/generate_spec.rb
|
97
|
+
- spec/rapid-vaults_spec.rb
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/system/system_spec.rb
|
100
|
+
homepage: https://www.github.com/mschuchard/rapid-vaults
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 2.1.0
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.5.2.1
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Ad-hoc encrypt and decrypt data.
|
124
|
+
test_files:
|
125
|
+
- spec/fixtures/file.yaml
|
126
|
+
- spec/rapid-vaults/api_spec.rb
|
127
|
+
- spec/rapid-vaults/cli_spec.rb
|
128
|
+
- spec/rapid-vaults/decrypt_spec.rb
|
129
|
+
- spec/rapid-vaults/encrypt_spec.rb
|
130
|
+
- spec/rapid-vaults/generate_spec.rb
|
131
|
+
- spec/rapid-vaults_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
- spec/system/system_spec.rb
|