kms_encrypted 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d6182ffbaae6402f3cfd620f93242fe457a37aeda8609362d7eb08572f020e0
4
- data.tar.gz: e2241d145e0407fcc6238e94ae653dc98de17538b95b4ee7df8c8ff48a94cbf3
3
+ metadata.gz: 67d1e3fb931f190e380e35875f1c6346025ebbdd101cdef33ed028d57f2e1b9d
4
+ data.tar.gz: fe2286f23847db1ee9314cd505fb00478574682a6edd9c7e754e2ce231926e4c
5
5
  SHA512:
6
- metadata.gz: b696faad41fce6bba45b23f981ec1eb1e557b9048e7e7bc79ebb4f70ee090a0bf0b8dbc68ef9226db88c2d75f3e13a1e04feabba5002a43466b845f9abb30b3c
7
- data.tar.gz: 569fc18fcb7d7c7751735310867efd5a8411f1756f539cc2073ed3360ea1ca05a761ef3d67694427ee810f3c556d4ef1c7ea122a88ff9ddb763c480ba60f9b61
6
+ metadata.gz: 9c651b9fad6d49d6ae4d2a6006ac34d65f7d0f2072446f7cb622c1f48c2c050fc7d70fc6baa0c8883fbe86e34c0ce4e0a00e1b6907d6577209b3389dd94cbced
7
+ data.tar.gz: 21eeadd0dbb9ed008ca9d2feb34bd43b5dee9c0527aa56b3a1a8a318535ef4707f3690acf504af6091837ec52a81abf1041e7166ef3a2a110cfa35824adebcde
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 1.3.0 (2021-10-10)
2
+
3
+ - Added support for `google-cloud-kms` gem
4
+
5
+ ## 1.2.4 (2021-06-20)
6
+
7
+ - Fixed another argument error with Google Cloud KMS and Ruby 3
8
+
9
+ ## 1.2.3 (2021-06-02)
10
+
11
+ - Fixed argument error with Google Cloud KMS and Ruby 3
12
+
13
+ ## 1.2.2 (2021-05-17)
14
+
15
+ - Added `key_id` method
16
+
1
17
  ## 1.2.1 (2020-09-28)
2
18
 
3
19
  - Fixed `Version not active` error when switching keys
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2020 Andrew Kane
1
+ Copyright (c) 2017-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -14,7 +14,7 @@ Supports [AWS KMS](https://aws.amazon.com/kms/), [Google Cloud KMS](https://clou
14
14
 
15
15
  Check out [this post](https://ankane.org/sensitive-data-rails) for more info on securing sensitive data with Rails
16
16
 
17
- [![Build Status](https://travis-ci.org/ankane/kms_encrypted.svg?branch=master)](https://travis-ci.org/ankane/kms_encrypted)
17
+ [![Build Status](https://github.com/ankane/kms_encrypted/workflows/build/badge.svg?branch=master)](https://github.com/ankane/kms_encrypted/actions)
18
18
 
19
19
  ## How It Works
20
20
 
@@ -48,7 +48,7 @@ gem 'aws-sdk-kms'
48
48
 
49
49
  Create an [Amazon Web Services](https://aws.amazon.com/) account if you don’t have one. KMS works great whether or not you run your infrastructure on AWS.
50
50
 
51
- Create a [KMS master key](https://console.aws.amazon.com/iam/home#/encryptionKeys) and set it in your environment along with your AWS credentials ([dotenv](https://github.com/bkeepers/dotenv) is great for this)
51
+ Create a [KMS master key](https://console.aws.amazon.com/kms/home#/kms/keys) and set it in your environment along with your AWS credentials ([dotenv](https://github.com/bkeepers/dotenv) is great for this)
52
52
 
53
53
  ```sh
54
54
  KMS_KEY_ID=arn:aws:kms:...
@@ -67,7 +67,7 @@ KMS_KEY_ID=alias/my-alias
67
67
  Add this line to your application’s Gemfile:
68
68
 
69
69
  ```ruby
70
- gem 'google-api-client'
70
+ gem 'google-cloud-kms'
71
71
  ```
72
72
 
73
73
  Create a [Google Cloud Platform](https://cloud.google.com/) account if you don’t have one. KMS works great whether or not you run your infrastructure on GCP.
@@ -75,13 +75,7 @@ Create a [Google Cloud Platform](https://cloud.google.com/) account if you don
75
75
  Create a [KMS key ring and key](https://console.cloud.google.com/iam-admin/kms) and set it in your environment along with your GCP credentials ([dotenv](https://github.com/bkeepers/dotenv) is great for this)
76
76
 
77
77
  ```sh
78
- KMS_KEY_ID=projects/.../locations/.../keyRings/.../cryptoKeys/...
79
- ```
80
-
81
- The Google API client logs requests by default. Be sure to turn off the logger in production or it will leak the plaintext.
82
-
83
- ```ruby
84
- Google::Apis.logger = Logger.new(nil)
78
+ KMS_KEY_ID=projects/my-project/locations/global/keyRings/my-key-ring/cryptoKeys/my-key
85
79
  ```
86
80
 
87
81
  ### Vault
@@ -335,9 +329,15 @@ For testing, you can prevent network calls to KMS by setting:
335
329
  KMS_KEY_ID=insecure-test-key
336
330
  ```
337
331
 
332
+ In a Rails application, you can also create `config/initializers/kms_encrypted.rb` with:
333
+
334
+ ```ruby
335
+ KmsEncrypted.key_id = Rails.env.test? ? "insecure-test-key" : ENV["KMS_KEY_ID"]
336
+ ```
337
+
338
338
  ## Key Rotation
339
339
 
340
- Key management services allow you to rotate the master key.
340
+ Key management services allow you to rotate the master key without any code changes.
341
341
 
342
342
  AWS KMS supports [automatic key rotation](https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html).
343
343
 
@@ -3,7 +3,7 @@ module KmsEncrypted
3
3
  attr_reader :key_id, :version, :previous_versions
4
4
 
5
5
  def initialize(key_id: nil, version: nil, previous_versions: nil)
6
- @key_id = key_id || ENV["KMS_KEY_ID"]
6
+ @key_id = key_id || KmsEncrypted.key_id
7
7
  @version = version || 1
8
8
  @previous_versions = previous_versions || {}
9
9
  end
@@ -1,11 +1,9 @@
1
1
  module KmsEncrypted
2
2
  class Client
3
- delegate :encrypt, :decrypt, to: :client
4
-
5
3
  attr_reader :key_id, :data_key
6
4
 
7
5
  def initialize(key_id: nil, legacy_context: false, data_key: false)
8
- @key_id = key_id || ENV["KMS_KEY_ID"]
6
+ @key_id = key_id || KmsEncrypted.key_id
9
7
  @legacy_context = legacy_context
10
8
  @data_key = data_key
11
9
  end
@@ -11,12 +11,18 @@ module KmsEncrypted
11
11
 
12
12
  # ensure namespace gets loaded
13
13
  client = KmsEncrypted.google_client
14
- request = ::Google::Apis::CloudkmsV1::EncryptRequest.new(options)
15
- response = client.encrypt_crypto_key(key_id, request)
16
14
 
17
- @last_key_version = response.name
18
-
19
- response.ciphertext
15
+ if defined?(::Google::Apis::CloudkmsV1::CloudKMSService) && KmsEncrypted.google_client.is_a?(::Google::Apis::CloudkmsV1::CloudKMSService)
16
+ request = ::Google::Apis::CloudkmsV1::EncryptRequest.new(**options)
17
+ response = client.encrypt_crypto_key(key_id, request)
18
+ @last_key_version = response.name
19
+ response.ciphertext
20
+ else
21
+ options[:name] = key_id
22
+ response = client.encrypt(**options)
23
+ @last_key_version = response.name
24
+ response.ciphertext
25
+ end
20
26
  end
21
27
 
22
28
  def decrypt(ciphertext, context: nil)
@@ -27,12 +33,23 @@ module KmsEncrypted
27
33
 
28
34
  # ensure namespace gets loaded
29
35
  client = KmsEncrypted.google_client
30
- request = ::Google::Apis::CloudkmsV1::DecryptRequest.new(options)
31
- begin
32
- client.decrypt_crypto_key(key_id, request).plaintext
33
- rescue ::Google::Apis::ClientError => e
34
- decryption_failed! if e.message.include?("Decryption failed")
35
- raise e
36
+
37
+ if defined?(::Google::Apis::CloudkmsV1::CloudKMSService) && KmsEncrypted.google_client.is_a?(::Google::Apis::CloudkmsV1::CloudKMSService)
38
+ request = ::Google::Apis::CloudkmsV1::DecryptRequest.new(**options)
39
+ begin
40
+ client.decrypt_crypto_key(key_id, request).plaintext
41
+ rescue ::Google::Apis::ClientError => e
42
+ decryption_failed! if e.message.include?("Decryption failed")
43
+ raise e
44
+ end
45
+ else
46
+ options[:name] = key_id
47
+ begin
48
+ client.decrypt(**options).plaintext
49
+ rescue ::Google::Cloud::InvalidArgumentError => e
50
+ decryption_failed! if e.message.include?("Decryption failed")
51
+ raise e
52
+ end
36
53
  end
37
54
  end
38
55
  end
@@ -12,6 +12,8 @@ module KmsEncrypted
12
12
  def decrypt(ciphertext, context: nil)
13
13
  prefix, plaintext, stored_context = ciphertext.split(":")
14
14
 
15
+ decryption_failed! if prefix != PREFIX
16
+
15
17
  context = generate_context(context) if context
16
18
  decryption_failed! if context != stored_context
17
19
 
@@ -30,6 +30,9 @@ module KmsEncrypted
30
30
  rescue ::Vault::HTTPClientError => e
31
31
  decryption_failed! if e.message.include?("unable to decrypt")
32
32
  raise e
33
+ rescue ::Vault::HTTPServerError => e
34
+ decryption_failed! if e.message.include?("message authentication failed")
35
+ raise e
33
36
  rescue Encoding::UndefinedConversionError
34
37
  decryption_failed!
35
38
  end
@@ -1,7 +1,7 @@
1
1
  module KmsEncrypted
2
2
  module Model
3
3
  def has_kms_key(name: nil, key_id: nil, eager_encrypt: false, version: 1, previous_versions: nil, upgrade_context: false)
4
- key_id ||= ENV["KMS_KEY_ID"]
4
+ key_id ||= KmsEncrypted.key_id
5
5
 
6
6
  key_method = name ? "kms_key_#{name}" : "kms_key"
7
7
  key_column = "encrypted_#{key_method}"
@@ -1,3 +1,3 @@
1
1
  module KmsEncrypted
2
- VERSION = "1.2.1"
2
+ VERSION = "1.3.0"
3
3
  end
data/lib/kms_encrypted.rb CHANGED
@@ -27,6 +27,7 @@ module KmsEncrypted
27
27
  attr_writer :aws_client
28
28
  attr_writer :google_client
29
29
  attr_writer :vault_client
30
+ attr_writer :key_id
30
31
 
31
32
  def aws_client
32
33
  @aws_client ||= Aws::KMS::Client.new(
@@ -38,15 +39,24 @@ module KmsEncrypted
38
39
 
39
40
  def google_client
40
41
  @google_client ||= begin
41
- require "google/apis/cloudkms_v1"
42
- client = ::Google::Apis::CloudkmsV1::CloudKMSService.new
43
- client.authorization = ::Google::Auth.get_application_default(
44
- "https://www.googleapis.com/auth/cloud-platform"
45
- )
46
- client.client_options.log_http_requests = false
47
- client.client_options.open_timeout_sec = 2
48
- client.client_options.read_timeout_sec = 2
49
- client
42
+ begin
43
+ require "google/apis/cloudkms_v1"
44
+
45
+ client = ::Google::Apis::CloudkmsV1::CloudKMSService.new
46
+ client.authorization = ::Google::Auth.get_application_default(
47
+ "https://www.googleapis.com/auth/cloud-platform"
48
+ )
49
+ client.client_options.log_http_requests = false
50
+ client.client_options.open_timeout_sec = 2
51
+ client.client_options.read_timeout_sec = 2
52
+ client
53
+ rescue LoadError
54
+ require "google/cloud/kms"
55
+
56
+ Google::Cloud::Kms.key_management_service do |config|
57
+ config.timeout = 2
58
+ end
59
+ end
50
60
  end
51
61
  end
52
62
 
@@ -54,6 +64,10 @@ module KmsEncrypted
54
64
  @vault_client ||= ::Vault::Client.new
55
65
  end
56
66
 
67
+ def key_id
68
+ @key_id ||= ENV["KMS_KEY_ID"]
69
+ end
70
+
57
71
  # hash is independent of key, but specific to audit device
58
72
  def context_hash(context, path:)
59
73
  context = Base64.encode64(context.to_json)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kms_encrypted
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-28 00:00:00.000000000 Z
11
+ date: 2021-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,162 +24,8 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
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: rake
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: minitest
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: sqlite3
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: activerecord
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: attr_encrypted
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: lockbox
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: 0.4.7
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: 0.4.7
125
- - !ruby/object:Gem::Dependency
126
- name: aws-sdk-kms
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: google-api-client
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: vault
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: carrierwave
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
- description:
182
- email: andrew@chartkick.com
27
+ description:
28
+ email: andrew@ankane.org
183
29
  executables: []
184
30
  extensions: []
185
31
  extra_rdoc_files: []
@@ -203,7 +49,7 @@ homepage: https://github.com/ankane/kms_encrypted
203
49
  licenses:
204
50
  - MIT
205
51
  metadata: {}
206
- post_install_message:
52
+ post_install_message:
207
53
  rdoc_options: []
208
54
  require_paths:
209
55
  - lib
@@ -218,8 +64,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
64
  - !ruby/object:Gem::Version
219
65
  version: '0'
220
66
  requirements: []
221
- rubygems_version: 3.1.2
222
- signing_key:
67
+ rubygems_version: 3.2.22
68
+ signing_key:
223
69
  specification_version: 4
224
70
  summary: Simple, secure key management for Lockbox and attr_encrypted
225
71
  test_files: []