porky_lib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cc40805a9b711ba76325becb50acc00ed3bedb28
4
+ data.tar.gz: 728228c4441a2362bf8dbee387db06db13e1adb3
5
+ SHA512:
6
+ metadata.gz: dbb89bca0d5f79bec39b326e148e589a499c95ae5a618755bf592bce71c53949161a1a2f06699e30a2ca33a7f439212f17e2a2453c039b3fb067602ec5c2ace2
7
+ data.tar.gz: aedfd5f8356dbf49994518e6ec2dd99ac7372c01183d0985e34084a68cbf62e7f446f3685fe8c927895697cc0864e0ae9ec18ef29d59375366e01c2f943353cc
@@ -0,0 +1,58 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ parallelism: 2
5
+ working_directory: ~/porky_lib
6
+ environment:
7
+ - CODECOV_TOKEN: 4d03ca51-5054-4858-87c7-b37c376ffb6a
8
+ docker:
9
+ - image: zetatango/circle-ruby-2.3.7-openssl
10
+
11
+ steps:
12
+ - checkout
13
+
14
+ - restore_cache:
15
+ name: Restore bundle cache
16
+ keys:
17
+ - porky_lib-bundle-{{ checksum "Gemfile.lock" }}
18
+ - porky_lib-bundle-
19
+
20
+ - run:
21
+ name: Bundle Install
22
+ command: bundle install
23
+
24
+ - save_cache:
25
+ name: Store bundle cache
26
+ key: porky_lib-bundle-{{ checksum "Gemfile.lock" }}
27
+ paths:
28
+ - vendor/bundle
29
+
30
+ - run:
31
+ name: Run rubocop
32
+ command: |
33
+ bundle exec rubocop --out test_results/rubocop.txt --format fuubar --require rubocop-rspec --config .rubocop.yml
34
+
35
+ - run:
36
+ name: Run bundle-audit
37
+ command: |
38
+ bundle exec bundle-audit check --update
39
+
40
+ - run:
41
+ name: Run rspec tests
42
+ command: |
43
+ bundle exec rspec \
44
+ --profile 10 \
45
+ --format RspecJunitFormatter \
46
+ --out test_results/rspec.xml \
47
+ --format progress
48
+
49
+ - store_test_results:
50
+ path: test_results
51
+
52
+ - store_artifacts:
53
+ path: test_results
54
+ prefix: tests
55
+
56
+ - store_artifacts:
57
+ path: coverage
58
+ prefix: coverage
@@ -0,0 +1,19 @@
1
+ *Related Issue(s) or Task(s)*
2
+
3
+ List the issues or tasks that are related to this pull request.
4
+
5
+ *Why?*
6
+
7
+ Explain the high-level reason(s) why this change is required.
8
+
9
+ *How?*
10
+
11
+ Explain the development-level approach you are using in this solution.
12
+
13
+ *Risks*
14
+
15
+ Explain the risks that are involved with making this change, if any.
16
+
17
+ *Requested Reviewers*
18
+
19
+ List the developers that should review this pull request.
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ .byebug_history
14
+
15
+ .DS_Store
16
+ /.idea/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,46 @@
1
+ require: rubocop-rspec
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - bin/*
6
+ - db/**/*.rb
7
+ - node_modules/**/*
8
+ - output/**/*
9
+ - vendor/**/*
10
+ TargetRubyVersion: 2.3.7
11
+ RSpec:
12
+ Patterns:
13
+ - _spec.rb
14
+ - "(?:^|/)spec/"
15
+ SpecTypes:
16
+ Feature: 'spec/features/**/*'
17
+
18
+ Documentation:
19
+ Enabled: false
20
+
21
+ Metrics/LineLength:
22
+ Max: 160
23
+
24
+ Metrics/ClassLength:
25
+ Enabled: false
26
+
27
+ Metrics/BlockLength:
28
+ Enabled: false
29
+
30
+ Metrics/AbcSize:
31
+ Max: 50
32
+
33
+ Metrics/MethodLength:
34
+ Max: 50
35
+
36
+ Style/StringLiterals:
37
+ Enabled: false
38
+
39
+ Style/ClassAndModuleChildren:
40
+ EnforcedStyle: compact
41
+
42
+ RSpec/MultipleExpectations:
43
+ Max: 5
44
+
45
+ RSpec/ExampleLength:
46
+ Max: 10
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in porky_lib.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,109 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ porky_lib (0.1.0)
5
+ aws-sdk-kms
6
+ msgpack
7
+ rbnacl-libsodium
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ast (2.4.0)
13
+ aws-eventstream (1.0.1)
14
+ aws-partitions (1.95.0)
15
+ aws-sdk-core (3.22.1)
16
+ aws-eventstream (~> 1.0)
17
+ aws-partitions (~> 1.0)
18
+ aws-sigv4 (~> 1.0)
19
+ jmespath (~> 1.0)
20
+ aws-sdk-kms (1.6.0)
21
+ aws-sdk-core (~> 3)
22
+ aws-sigv4 (~> 1.0)
23
+ aws-sigv4 (1.0.3)
24
+ bundler-audit (0.6.0)
25
+ bundler (~> 1.2)
26
+ thor (~> 0.18)
27
+ byebug (10.0.2)
28
+ codecov (0.1.10)
29
+ json
30
+ simplecov
31
+ url
32
+ diff-lcs (1.3)
33
+ docile (1.3.1)
34
+ ffi (1.9.25)
35
+ jaro_winkler (1.5.1)
36
+ jmespath (1.4.0)
37
+ json (2.1.0)
38
+ msgpack (1.2.4)
39
+ parallel (1.12.1)
40
+ parser (2.5.1.0)
41
+ ast (~> 2.4.0)
42
+ powerpack (0.1.2)
43
+ rainbow (3.0.0)
44
+ rake (12.3.1)
45
+ rbnacl (5.0.0)
46
+ ffi
47
+ rbnacl-libsodium (1.0.16)
48
+ rbnacl (>= 3.0.1)
49
+ rspec (3.7.0)
50
+ rspec-core (~> 3.7.0)
51
+ rspec-expectations (~> 3.7.0)
52
+ rspec-mocks (~> 3.7.0)
53
+ rspec-collection_matchers (1.1.3)
54
+ rspec-expectations (>= 2.99.0.beta1)
55
+ rspec-core (3.7.1)
56
+ rspec-support (~> 3.7.0)
57
+ rspec-expectations (3.7.0)
58
+ diff-lcs (>= 1.2.0, < 2.0)
59
+ rspec-support (~> 3.7.0)
60
+ rspec-mocks (3.7.0)
61
+ diff-lcs (>= 1.2.0, < 2.0)
62
+ rspec-support (~> 3.7.0)
63
+ rspec-support (3.7.1)
64
+ rspec_junit_formatter (0.4.1)
65
+ rspec-core (>= 2, < 4, != 2.12.0)
66
+ rubocop (0.57.2)
67
+ jaro_winkler (~> 1.5.1)
68
+ parallel (~> 1.10)
69
+ parser (>= 2.5)
70
+ powerpack (~> 0.1)
71
+ rainbow (>= 2.2.2, < 4.0)
72
+ ruby-progressbar (~> 1.7)
73
+ unicode-display_width (~> 1.0, >= 1.0.1)
74
+ rubocop-rspec (1.27.0)
75
+ rubocop (>= 0.56.0)
76
+ rubocop_runner (2.1.0)
77
+ ruby-progressbar (1.9.0)
78
+ simplecov (0.16.1)
79
+ docile (~> 1.1)
80
+ json (>= 1.8, < 3)
81
+ simplecov-html (~> 0.10.0)
82
+ simplecov-html (0.10.2)
83
+ thor (0.20.0)
84
+ timecop (0.9.1)
85
+ unicode-display_width (1.4.0)
86
+ url (0.3.2)
87
+
88
+ PLATFORMS
89
+ ruby
90
+
91
+ DEPENDENCIES
92
+ bundler
93
+ bundler-audit
94
+ byebug
95
+ codecov
96
+ porky_lib!
97
+ rake
98
+ rspec
99
+ rspec-collection_matchers
100
+ rspec-mocks
101
+ rspec_junit_formatter
102
+ rubocop
103
+ rubocop-rspec
104
+ rubocop_runner
105
+ simplecov
106
+ timecop
107
+
108
+ BUNDLED WITH
109
+ 1.16.1
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ [![CircleCI](https://circleci.com/gh/Zetatango/porky_lib.svg?style=svg&circle-token=f1a41896097b814585e5042a8e38425b4d1cdc0b)](https://circleci.com/gh/Zetatango/porky_lib) [![codecov](https://codecov.io/gh/Zetatango/porky_lib/branch/master/graph/badge.svg?token=WxED9350q4)](https://codecov.io/gh/Zetatango/porky_lib)
2
+
3
+ # PorkyLib
4
+
5
+ This gem is a cryptographic services library. PorkyLib uses AWS Key Management Service (KMS) for key management and RbNaCl for
6
+ performing cryptographic operations.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'porky_lib'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle install
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install porky_lib
23
+
24
+ Inside of your Ruby program do:
25
+
26
+ ```ruby
27
+ require 'porky_lib'
28
+ ```
29
+ ... to pull it in as a dependency.
30
+
31
+ ## Usage
32
+
33
+ ### Initialization
34
+ Something like the following should be included in an initializer in your Rails project:
35
+ ```ruby
36
+ # Use PorkyLib's AWS KMS mock client except in production, for example
37
+ use_mock_client = !Rails.env.production?
38
+ PorkyLib::Config.configure(aws_region: ENV[AWS_REGION],
39
+ aws_key_id: ENV[AWS_KEY_ID],
40
+ aws_key_secret: ENV[AWS_KEY_SECRET],
41
+ aws_client_mock: use_mock_client)
42
+ PorkyLib::Config.initialize_aws
43
+ ```
44
+
45
+ ### Creating a New CMK
46
+ To create a new customer master key (CMK) within AWS:
47
+ ```ruby
48
+ # Where tags is a list of key/value pairs (i.e [{ key1: 'value1' }])
49
+ # key_alias is an optional parameter, and if provided will create an alias with the provided value for the newly created key
50
+ # key_rotation_enabled is an optional parameter, and if true will enable automatic key rotation for the new created key. Default is true.
51
+ key_id = PorkyLib::Symmetric.instance.create_key(tags, key_alias, key_rotation_enabled)
52
+ ```
53
+
54
+ ### Creating an Alias for an Existing CMK
55
+ To create a new alias for an existing customer master key (CMK) within AWS:
56
+ ```ruby
57
+ # Where key_id is the AWS key ID or Amazon Resource Name (ARN)
58
+ # key_alias is the value of the alias to create
59
+ PorkyLib::Symmetric.instance.create_alias(key_id, key_alias)
60
+ ```
61
+
62
+ ### Enabling Key Rotation for an Existing CMK
63
+ To create a new alias for an existing customer master key (CMK) within AWS:
64
+ ```ruby
65
+ # Where key_id is the AWS key ID or Amazon Resource Name (ARN)
66
+ PorkyLib::Symmetric.instance.enable_key_rotation(key_id)
67
+ ```
68
+
69
+ ### Encrypting Data
70
+ To encrypt data:
71
+ ```ruby
72
+ # Where data is the data to encrypt
73
+ # cmk_key_id is the AWS key ID, Amazon Resource Name (ARN) or alias for the CMK to use to generate the data encryption key (DEK)
74
+ # encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
75
+ [ciphertext_dek, ciphertext, nonce] = PorkyLib::Symmetric.instance.encrypt(data, cmk_key_id, encryption_context)
76
+ ```
77
+
78
+ ### Decrypting Data
79
+ To decrypt data:
80
+ ```ruby
81
+ # Where ciphertext_dek is the encrypted data encryption key (DEK)
82
+ # ciphertext is the encrypted data to be decrypted
83
+ # nonce is the nonce value associated with ciphertext
84
+ # encryption_context is an optional parameter to provide additional authentication data for decrypting the DEK. Default is nil. Note, this must match the value that was used to encrypt.
85
+ plaintext_data = PorkyLib::Symmetric.instance.decrypt(ciphertext_dek, ciphertext, nonce, encryption_context)
86
+ ```
87
+
88
+ ## Development
89
+
90
+ Development on this project should occur on separate feature branches and pull requests should be submitted. When submitting a
91
+ pull request, the pull request comment template should be filled out as much as possible to ensure a quick review and increase
92
+ the likelihood of the pull request being accepted.
93
+
94
+ ### Running Tests
95
+
96
+ ```ruby
97
+ rspec # Without code coverage
98
+ COVERAGE=true rspec # with code coverage
99
+ ```
100
+
101
+ ## Contributing
102
+
103
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/Zetatango/porky_lib](https://github.com/Zetatango/porky_lib)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "porky_lib"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-kms'
4
+ require 'msgpack'
5
+
6
+ ##
7
+ # This class is required for unit testing in order to mock response values from the AWS KMS SDK.
8
+ ##
9
+ class Aws::KMS::Client
10
+ MOCK_ALIAS_NAME_ALREADY_EXISTS = 'alias/dup'
11
+ MOCK_INVALID_ALIAS_NAME = 'alias/aws'
12
+ MOCK_INVALID_TAG_VALUE = 'bad_value'
13
+ MOCK_NOT_FOUND_KEY_ID = 'bad_key'
14
+ MOCK_VALID_KEY_USAGE = 'AES_256'
15
+ PLAINTEXT_KEY_LENGTH = 32
16
+
17
+ def create_key(key_usage:, origin:, tags:)
18
+ raise Aws::KMS::Errors::TagException.new(nil, nil) if tags[0].value?(MOCK_INVALID_TAG_VALUE)
19
+
20
+ Aws::KMS::Types::CreateKeyResponse.new(
21
+ key_metadata: {
22
+ aws_account_id: '123',
23
+ creation_date: Time.now.utc.iso8601,
24
+ description: '',
25
+ enabled: true,
26
+ key_id: SecureRandom.uuid,
27
+ key_state: 'Enabled',
28
+ key_usage: key_usage,
29
+ origin: origin
30
+ }
31
+ )
32
+ end
33
+
34
+ def enable_key_rotation(key_id:)
35
+ raise Aws::KMS::Errors::NotFoundException.new(nil, nil) if key_id.include?(MOCK_NOT_FOUND_KEY_ID)
36
+ end
37
+
38
+ def create_alias(target_key_id:, alias_name:)
39
+ raise Aws::KMS::Errors::InvalidAliasNameException.new(nil, nil) if alias_name == MOCK_INVALID_ALIAS_NAME
40
+ raise Aws::KMS::Errors::AlreadyExistsException.new(nil, nil) if alias_name == MOCK_ALIAS_NAME_ALREADY_EXISTS
41
+ raise Aws::KMS::Errors::NotFoundException.new(nil, nil) if target_key_id.include?(MOCK_NOT_FOUND_KEY_ID)
42
+ end
43
+
44
+ def generate_data_key(key_id:, key_spec:, encryption_context: nil)
45
+ raise Aws::KMS::Errors::InvalidKeyUsageException.new(nil, nil) unless key_spec == 'AES_256'
46
+ raise Aws::KMS::Errors::NotFoundException.new(nil, nil) if key_id.include?(MOCK_NOT_FOUND_KEY_ID)
47
+
48
+ plaintext = SecureRandom.random_bytes(PLAINTEXT_KEY_LENGTH)
49
+ Aws::KMS::Types::GenerateDataKeyResponse.new(
50
+ key_id: key_id,
51
+ plaintext: plaintext,
52
+ ciphertext_blob: [key_id, encryption_context, plaintext].to_msgpack.reverse
53
+ )
54
+ end
55
+
56
+ def decrypt(ciphertext_blob:, encryption_context: nil)
57
+ key_id, decoded_context, plaintext = MessagePack.unpack(ciphertext_blob.reverse)
58
+ decoded_context = Hash[decoded_context.map { |k, v| [k.to_sym, v] }] if decoded_context
59
+ raise Aws::KMS::Errors::InvalidCiphertextException.new(nil, nil) unless decoded_context == encryption_context
60
+
61
+ Aws::KMS::Types::DecryptResponse.new(
62
+ key_id: key_id,
63
+ plaintext: plaintext
64
+ )
65
+ rescue MessagePack::MalformedFormatError
66
+ raise Aws::KMS::Errors::InvalidCiphertextException.new(nil, nil)
67
+ end
68
+
69
+ def inspect
70
+ '#<Aws::KMS::Client (mocked)>'
71
+ end
72
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class PorkyLib::Config
4
+ @aws_region = ''
5
+ @aws_key_id = ''
6
+ @aws_key_secret = ''
7
+ @aws_client_mock = false
8
+
9
+ @config = {
10
+ aws_region: @aws_region,
11
+ aws_key_id: @aws_key_id,
12
+ aws_key_secret: @aws_key_secret,
13
+ aws_client_mock: @aws_client_mock
14
+ }
15
+
16
+ @allowed_config_keys = @config.keys
17
+
18
+ def self.configure(options = {})
19
+ options.each { |key, value| @config[key.to_sym] = value if @allowed_config_keys.include? key.to_sym }
20
+ end
21
+
22
+ def self.initialize_aws
23
+ Aws.config.update(
24
+ region: @config[:aws_region],
25
+ credentials: Aws::Credentials.new(
26
+ @config[:aws_key_id],
27
+ @config[:aws_key_secret]
28
+ )
29
+ )
30
+ end
31
+
32
+ class << self
33
+ attr_reader :config
34
+ end
35
+
36
+ def self.logger
37
+ @logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
38
+ @logger
39
+ end
40
+
41
+ class << self
42
+ attr_writer :logger
43
+ end
44
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-kms'
4
+ require 'rbnacl/libsodium'
5
+ require 'singleton'
6
+
7
+ class PorkyLib::Symmetric
8
+ include Singleton
9
+
10
+ CMK_KEY_ORIGIN = 'AWS_KMS'
11
+ CMK_KEY_USAGE = 'ENCRYPT_DECRYPT'
12
+ SYMMETRIC_KEY_SPEC = 'AES_256'
13
+
14
+ def client
15
+ require 'porky_lib/aws/kms/client' if PorkyLib::Config.config[:aws_client_mock]
16
+ @client ||= Aws::KMS::Client.new
17
+ end
18
+
19
+ def create_key(tags, key_alias = nil, key_rotation_enabled = true)
20
+ PorkyLib::Config.logger.info("Creating a new master key")
21
+ resp = client.create_key(key_usage: CMK_KEY_USAGE, origin: CMK_KEY_ORIGIN, tags: tags)
22
+ key_id = resp.to_h[:key_metadata][:key_id]
23
+
24
+ # Enable automatic key rotation for the newly created CMK
25
+ enable_key_rotation(key_id) if key_rotation_enabled
26
+
27
+ # Create an alias for the newly created CMK
28
+ create_alias(key_id, key_alias) if key_alias
29
+
30
+ key_id
31
+ end
32
+
33
+ def enable_key_rotation(key_id)
34
+ PorkyLib::Config.logger.info("Enabling automatic key rotation for master key: '#{key_id}'")
35
+ client.enable_key_rotation(key_id: key_id)
36
+ end
37
+
38
+ def create_alias(key_id, key_alias)
39
+ PorkyLib::Config.logger.info("Setting alias as '#{key_alias}' for master key: '#{key_id}'")
40
+ client.create_alias(target_key_id: key_id, alias_name: key_alias)
41
+ end
42
+
43
+ def encrypt(data, cmk_key_id, encryption_context = nil)
44
+ return if data.nil? || cmk_key_id.nil?
45
+
46
+ # Generate a new data encryption key
47
+ PorkyLib::Config.logger.info('Generating new data encryption key')
48
+
49
+ resp = {}
50
+ resp = client.generate_data_key(key_id: cmk_key_id, key_spec: SYMMETRIC_KEY_SPEC, encryption_context: encryption_context) if encryption_context
51
+ resp = client.generate_data_key(key_id: cmk_key_id, key_spec: SYMMETRIC_KEY_SPEC) unless encryption_context
52
+
53
+ plaintext_key = resp.to_h[:plaintext]
54
+ ciphertext_key = resp.to_h[:ciphertext_blob]
55
+
56
+ # Initialize the box
57
+ secret_box = RbNaCl::SecretBox.new(plaintext_key)
58
+
59
+ # rubocop:disable Lint/UselessAssignment
60
+ plaintext_key = "\0" * plaintext_key.bytesize
61
+ # rubocop:enable Lint/UselessAssignment
62
+
63
+ # First, make a nonce: A single-use value never repeated under the same key
64
+ # The nonce isn't secret, and can be sent with the ciphertext.
65
+ # The cipher instance has a nonce_bytes method for determining how many bytes should be in a nonce
66
+ nonce = RbNaCl::Random.random_bytes(secret_box.nonce_bytes)
67
+
68
+ # Encrypt a message with SecretBox
69
+ PorkyLib::Config.logger.info('Beginning encryption')
70
+ ciphertext = secret_box.encrypt(nonce, data)
71
+ PorkyLib::Config.logger.info('Encryption complete')
72
+ [ciphertext_key, ciphertext, nonce]
73
+ end
74
+
75
+ def decrypt(ciphertext_dek, ciphertext, nonce, encryption_context = nil)
76
+ return if ciphertext.nil? || ciphertext_dek.nil? || nonce.nil?
77
+
78
+ # Decrypt the data encryption key
79
+ PorkyLib::Config.logger.info('Decrypting data encryption key')
80
+
81
+ resp = {}
82
+ resp = client.decrypt(ciphertext_blob: ciphertext_dek, encryption_context: encryption_context) if encryption_context
83
+ resp = client.decrypt(ciphertext_blob: ciphertext_dek) unless encryption_context
84
+
85
+ plaintext_key = resp.to_h[:plaintext]
86
+
87
+ secret_box = RbNaCl::SecretBox.new(plaintext_key)
88
+
89
+ # rubocop:disable Lint/UselessAssignment
90
+ plaintext_key = "\0" * plaintext_key.bytesize
91
+ # rubocop:enable Lint/UselessAssignment
92
+
93
+ PorkyLib::Config.logger.info('Beginning decryption')
94
+ result = secret_box.decrypt(nonce, ciphertext)
95
+ PorkyLib::Config.logger.info('Decryption complete')
96
+ result
97
+ end
98
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PorkyLib
4
+ VERSION = "0.1.0"
5
+ end
data/lib/porky_lib.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PorkyLib
4
+ require 'porky_lib/config'
5
+ require 'porky_lib/symmetric'
6
+ require 'porky_lib/version'
7
+ end
data/porky_lib.gemspec ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'porky_lib/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "porky_lib"
9
+ spec.version = PorkyLib::VERSION
10
+ spec.authors = ["Greg Fletcher"]
11
+ spec.email = ["greg.fletcher@zetatango.com"]
12
+
13
+ spec.summary = 'A library for cryptographic services for the Zetatango platform'
14
+ spec.homepage = 'https://github.com/Zetatango/porky_lib'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'bundler-audit'
25
+ spec.add_development_dependency 'byebug'
26
+ spec.add_development_dependency 'codecov'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec'
29
+ spec.add_development_dependency 'rspec-collection_matchers'
30
+ spec.add_development_dependency 'rspec-mocks'
31
+ spec.add_development_dependency 'rspec_junit_formatter'
32
+ spec.add_development_dependency 'rubocop'
33
+ spec.add_development_dependency 'rubocop-rspec'
34
+ spec.add_development_dependency 'rubocop_runner'
35
+ spec.add_development_dependency 'simplecov'
36
+ spec.add_development_dependency 'timecop'
37
+
38
+ spec.add_dependency 'aws-sdk-kms'
39
+ spec.add_dependency 'msgpack'
40
+ spec.add_dependency 'rbnacl-libsodium'
41
+ end
metadata ADDED
@@ -0,0 +1,298 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: porky_lib
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Greg Fletcher
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-07-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler-audit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-collection_matchers
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-mocks
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit_formatter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop-rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop_runner
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: timecop
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: aws-sdk-kms
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: msgpack
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: rbnacl-libsodium
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ description:
252
+ email:
253
+ - greg.fletcher@zetatango.com
254
+ executables: []
255
+ extensions: []
256
+ extra_rdoc_files: []
257
+ files:
258
+ - ".circleci/config.yml"
259
+ - ".github/pull_request_template.md"
260
+ - ".gitignore"
261
+ - ".rspec"
262
+ - ".rubocop.yml"
263
+ - Gemfile
264
+ - Gemfile.lock
265
+ - README.md
266
+ - Rakefile
267
+ - bin/console
268
+ - bin/setup
269
+ - lib/porky_lib.rb
270
+ - lib/porky_lib/aws/kms/client.rb
271
+ - lib/porky_lib/config.rb
272
+ - lib/porky_lib/symmetric.rb
273
+ - lib/porky_lib/version.rb
274
+ - porky_lib.gemspec
275
+ homepage: https://github.com/Zetatango/porky_lib
276
+ licenses: []
277
+ metadata: {}
278
+ post_install_message:
279
+ rdoc_options: []
280
+ require_paths:
281
+ - lib
282
+ required_ruby_version: !ruby/object:Gem::Requirement
283
+ requirements:
284
+ - - ">="
285
+ - !ruby/object:Gem::Version
286
+ version: '0'
287
+ required_rubygems_version: !ruby/object:Gem::Requirement
288
+ requirements:
289
+ - - ">="
290
+ - !ruby/object:Gem::Version
291
+ version: '0'
292
+ requirements: []
293
+ rubyforge_project:
294
+ rubygems_version: 2.5.2
295
+ signing_key:
296
+ specification_version: 4
297
+ summary: A library for cryptographic services for the Zetatango platform
298
+ test_files: []