porky_lib 0.1.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 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: []