secure_data_bag 2.2.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +165 -46
- data/Rakefile +1 -2
- data/lib/chef/config.rb +2 -4
- data/lib/chef/dsl/data_query.rb +1 -2
- data/lib/chef/knife/secure_bag_edit.rb +31 -33
- data/lib/chef/knife/secure_bag_from_file.rb +13 -22
- data/lib/chef/knife/secure_bag_open.rb +37 -0
- data/lib/chef/knife/secure_bag_show.rb +40 -35
- data/lib/chef/knife/secure_data_bag/base_mixin.rb +80 -0
- data/lib/chef/knife/secure_data_bag/defaults_mixin.rb +32 -0
- data/lib/chef/knife/secure_data_bag/export_mixin.rb +85 -0
- data/lib/chef/knife/secure_data_bag/secrets_mixin.rb +57 -0
- data/lib/secure_data_bag.rb +5 -7
- data/lib/secure_data_bag/check_encrypted.rb +29 -0
- data/lib/secure_data_bag/constants.rb +5 -0
- data/lib/secure_data_bag/decryptor.rb +149 -0
- data/lib/secure_data_bag/dsl/data_query.rb +6 -6
- data/lib/secure_data_bag/encryptor.rb +185 -0
- data/lib/secure_data_bag/exceptions.rb +4 -0
- data/lib/secure_data_bag/item.rb +197 -149
- data/lib/secure_data_bag/version.rb +1 -3
- data/secure_data_bag.gemspec +14 -13
- data/spec/item_spec.rb +15 -16
- data/spec/spec_helper.rb +0 -1
- metadata +112 -7
- data/lib/chef/knife/secure_bag_base.rb +0 -74
@@ -13,19 +13,19 @@ module SecureDataBag
|
|
13
13
|
Chef::DataBag.validate_name!(bag.to_s)
|
14
14
|
SecureDataBag::Item.validate_id!(item)
|
15
15
|
SecureDataBag::Item.load(bag, item)
|
16
|
-
rescue
|
16
|
+
rescue StandardError
|
17
17
|
Chef::Log.error("Failed to load secure data bag item: #{bag.inspect} #{item.inspect}")
|
18
18
|
raise
|
19
19
|
end
|
20
|
+
|
21
|
+
node.run_state[:secure_data_bag][bag][item] ||= data_bag_item if cache
|
22
|
+
data_bag_item
|
20
23
|
end
|
21
24
|
|
22
|
-
def secure_data_bag_item!(item,
|
23
|
-
secure = SecureDataBag::Item.from_item
|
24
|
-
secure.encoded_fields.concat(Array(fields))
|
25
|
+
def secure_data_bag_item!(item, metadata = {})
|
26
|
+
secure = SecureDataBag::Item.from_item(item, metadata)
|
25
27
|
secure
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
30
|
-
|
31
|
-
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'secure_data_bag/exceptions'
|
2
|
+
|
3
|
+
module SecureDataBag
|
4
|
+
module Encryptor
|
5
|
+
# Instantiate an Encryptor object responsable for encrypting the
|
6
|
+
# raw_hash with the secret.
|
7
|
+
#
|
8
|
+
# The optional metadata may contain hints as to how we should encrypt the
|
9
|
+
# raw_hash. Should hints not be provided, this will do it's best to
|
10
|
+
# detect the appropriate defaults.
|
11
|
+
#
|
12
|
+
# @param raw_hash [Hash] the raw hash to encrypt
|
13
|
+
# @param secret [String] the secret to encrypt with
|
14
|
+
# @param metadata [Hash] the optional metdata to configure the encryptor
|
15
|
+
# @return [SecureDataBag::NestedDecryptor] the object capable of decrypting
|
16
|
+
# @since 3.0.0
|
17
|
+
def self.new(raw_hash, secret, metadata = {})
|
18
|
+
metadata = Mash.new(metadata)
|
19
|
+
format = (metadata[:encryption_format] || metadata[:decryption_format])
|
20
|
+
case format
|
21
|
+
when 'encrypted'
|
22
|
+
SecureDataBag::FlatEncryptor.new(raw_hash, secret, metadata)
|
23
|
+
else
|
24
|
+
SecureDataBag::NestedEncryptor.new(raw_hash, secret, metadata)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Encryptor object responsable for encrypting the raw_hash with the
|
30
|
+
# secret. This object is just a wrapper around
|
31
|
+
# Chef::EncryptedDataBagItem.
|
32
|
+
#
|
33
|
+
# @since 3.0.0
|
34
|
+
class FlatEncryptor
|
35
|
+
# The keys to encrypt
|
36
|
+
# @since 3.0.0
|
37
|
+
attr_reader :encrypted_keys
|
38
|
+
|
39
|
+
# The encrypted hash generated
|
40
|
+
# @since 3.0.0
|
41
|
+
attr_reader :encrypted_hash
|
42
|
+
|
43
|
+
# The decrypted hash to encrypt
|
44
|
+
# @since 3.0.0
|
45
|
+
attr_reader :decrypted_hash
|
46
|
+
|
47
|
+
# The metadata used to create the encrypted_hash
|
48
|
+
attr_reader :metadata
|
49
|
+
|
50
|
+
# Initializer
|
51
|
+
# @param decrypted_hash [Hash,String] the encrypted hash to encrypt
|
52
|
+
# @param secret [String] the secret to encrypt with
|
53
|
+
# @param metadata [Hash] optional metadata
|
54
|
+
# @since 3.0.0
|
55
|
+
def initialize(decrypted_hash, secret, metadata = {})
|
56
|
+
@secret = secret
|
57
|
+
@metadata = metadata
|
58
|
+
@encrypted_hash = {}
|
59
|
+
@encrypted_keys = []
|
60
|
+
@decrypted_hash = decrypted_hash
|
61
|
+
end
|
62
|
+
|
63
|
+
# Method called to encrpt the data structure and return it.
|
64
|
+
# @return [Hash] the encrypted value
|
65
|
+
# @since 3.0.0
|
66
|
+
def encrypt!
|
67
|
+
@encrypted_hash = encrypt
|
68
|
+
end
|
69
|
+
|
70
|
+
# Method called to encrpt the data structure and return it.
|
71
|
+
# @return [Hash] the encrypted value
|
72
|
+
# @since 3.0.0
|
73
|
+
def encrypt
|
74
|
+
## NO WORKY
|
75
|
+
## NO WORKY
|
76
|
+
## NO WORKY
|
77
|
+
## NO WORKY
|
78
|
+
## NO WORKY
|
79
|
+
## NO WORKY
|
80
|
+
Chef::EncryptedDataBagItem.encrypt_data_bag_item(
|
81
|
+
@decrypted_hash,
|
82
|
+
@secret
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Method name preserved for compatibility with
|
87
|
+
# Chef::EncryptedDataBagItem::Encryptor.
|
88
|
+
# @since 3.0.0
|
89
|
+
alias :for_encrypted_item :encrypt!
|
90
|
+
end
|
91
|
+
|
92
|
+
# Encryptor object responsable for encrypting the raw_hash with the
|
93
|
+
# secret. This object will recursively step through the raw_hash, looking for
|
94
|
+
# keys matching `encrypted_keys` and encrypt their values.
|
95
|
+
#
|
96
|
+
# @since 3.0.0
|
97
|
+
class NestedEncryptor
|
98
|
+
# The keys to encrypt
|
99
|
+
# @since 3.0.0
|
100
|
+
attr_reader :encrypted_keys
|
101
|
+
|
102
|
+
# The encrypted hash generated
|
103
|
+
# @since 3.0.0
|
104
|
+
attr_reader :encrypted_hash
|
105
|
+
|
106
|
+
# The decrypted hash to encrypt
|
107
|
+
# @since 3.0.0
|
108
|
+
attr_reader :decrypted_hash
|
109
|
+
|
110
|
+
# The metadata used to create the encrypted_hash
|
111
|
+
attr_reader :metadata
|
112
|
+
|
113
|
+
# Initializer
|
114
|
+
# @param decrypted_hash [Hash,String] the encrypted hash to encrypt
|
115
|
+
# @param secret [String] the secret to encrypt with
|
116
|
+
# @param metadata [Hash] optional metadata
|
117
|
+
# @since 3.0.0
|
118
|
+
def initialize(decrypted_hash, secret, metadata = {})
|
119
|
+
@secret = secret
|
120
|
+
@metadata = metadata
|
121
|
+
@encrypted_hash = {}
|
122
|
+
@encrypted_keys = case metadata[:encryption_format]
|
123
|
+
when 'plain' then @encrypted_keys = []
|
124
|
+
else metadata[:encrypted_keys] || []
|
125
|
+
end
|
126
|
+
@decrypted_hash = decrypted_hash
|
127
|
+
end
|
128
|
+
|
129
|
+
# Method called to encrpt the data structure and return it.
|
130
|
+
# @return [Hash] the encrypted value
|
131
|
+
# @since 3.0.0
|
132
|
+
def encrypt!
|
133
|
+
@encrypted_hash = encrypt
|
134
|
+
end
|
135
|
+
|
136
|
+
# Method called to encrpt the data structure and return it.
|
137
|
+
# @return [Hash] the encrypted value
|
138
|
+
# @since 3.0.0
|
139
|
+
def encrypt
|
140
|
+
encrypt_data(@decrypted_hash)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Method name preserved for compatibility with
|
144
|
+
# Chef::EncryptedDataBagItem::Encryptor.
|
145
|
+
# @since 3.0.0
|
146
|
+
alias :for_encrypted_item :encrypt!
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
# Recursively encrypt hash values where keys match encryptable_key?
|
151
|
+
# @param raw_hash [Hash] the hash to encrypt
|
152
|
+
# @return [Hash] the encrypted hash
|
153
|
+
# @since 3.0.0
|
154
|
+
def encrypt_data(raw_hash)
|
155
|
+
encrypted_hash = Mash.new
|
156
|
+
|
157
|
+
raw_hash.each do |key, value|
|
158
|
+
value = if encryptable_key?(key)
|
159
|
+
encrypt_value(value)
|
160
|
+
elsif value.is_a?(Hash)
|
161
|
+
encrypt_data(value)
|
162
|
+
else value
|
163
|
+
end
|
164
|
+
encrypted_hash[key] = value
|
165
|
+
end
|
166
|
+
|
167
|
+
encrypted_hash
|
168
|
+
end
|
169
|
+
|
170
|
+
# Determine whether the hash key should be encrypted
|
171
|
+
# @return [Boolean]
|
172
|
+
# @since 3.0.0
|
173
|
+
def encryptable_key?(key)
|
174
|
+
@encrypted_keys.include?(key)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Encrypt a single value
|
178
|
+
# @return [Hash] the encrypted value
|
179
|
+
# @since 3.0.0
|
180
|
+
def encrypt_value(value)
|
181
|
+
Chef::EncryptedDataBagItem::Encryptor
|
182
|
+
.new(value, @secret).for_encrypted_item
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/lib/secure_data_bag/item.rb
CHANGED
@@ -1,192 +1,240 @@
|
|
1
|
-
|
2
|
-
require 'open-uri'
|
3
1
|
require 'chef/data_bag_item'
|
4
2
|
require 'chef/encrypted_data_bag_item'
|
5
|
-
require '
|
6
|
-
require '
|
3
|
+
require 'secure_data_bag/constants'
|
4
|
+
require 'secure_data_bag/decryptor'
|
5
|
+
require 'secure_data_bag/encryptor'
|
7
6
|
|
8
7
|
module SecureDataBag
|
9
|
-
#
|
10
|
-
# SecureDataBagItem extends the standard DataBagItem by providing it
|
11
|
-
# with encryption / decryption capabilities.
|
12
|
-
#
|
13
|
-
# Although it does provide methods which may be used to specifically perform
|
14
|
-
# crypto functions, it should be used the same way.
|
15
|
-
#
|
16
|
-
|
17
8
|
class Item < Chef::DataBagItem
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
9
|
+
class << self
|
10
|
+
# Class method used to load the secret key from path
|
11
|
+
# @param path [String] the optional path to the file
|
12
|
+
# @return [String] the secret
|
13
|
+
# @since 3.0.0
|
14
|
+
def load_secret(path = nil)
|
15
|
+
path ||= (
|
16
|
+
Chef::Config[:knife][:secure_data_bag][:secret_file] ||
|
17
|
+
Chef::Config[:encrypted_data_bag_secret]
|
18
|
+
)
|
19
|
+
Chef::EncryptedDataBagItem.load_secret(path)
|
22
20
|
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
# Load a data_bag_item and convert into the a SecureDataBag::Item.
|
23
|
+
# @param data_bag [String] the data_bag to load the item from
|
24
|
+
# @param name [String] the data_bag_item id
|
25
|
+
# @param opts [Hash] optional options to pass to SecureDataBag::Item.new
|
26
|
+
# @return [SecureDataBag::Item]
|
27
|
+
# @since 3.0.0
|
28
|
+
def load(data_bag, name, opts = {})
|
29
|
+
data = {
|
30
|
+
'data_bag' => data_bag,
|
31
|
+
'id' => name
|
32
|
+
}.merge(
|
33
|
+
Chef::DataBagItem.load(data_bag, name).to_hash
|
34
|
+
)
|
35
|
+
item = from_hash(data, opts)
|
36
|
+
item
|
37
|
+
end
|
27
38
|
|
28
|
-
|
29
|
-
|
30
|
-
|
39
|
+
# Create a new SecureDataBag::Item from a hash and optional options.
|
40
|
+
# @param hash [Hash] the data
|
41
|
+
# @param opts [Hash] the optional options to pass to Item.new
|
42
|
+
# @return [SecureDataBag::Item]
|
43
|
+
# @since 3.0.0
|
44
|
+
def from_hash(hash, opts = {})
|
45
|
+
data = hash.dup
|
46
|
+
data.delete('chef_type')
|
47
|
+
data.delete('json_class')
|
48
|
+
|
49
|
+
metadata = Mash.new(data.delete(SecureDataBag::METADATA_KEY) || {})
|
50
|
+
metadata = metadata.merge(opts)
|
51
|
+
|
52
|
+
item = new(metadata)
|
53
|
+
item.data_bag(data.delete('data_bag')) if data.key?('data_bag')
|
54
|
+
item.raw_data = data.key?('raw_data') ? data['raw_data'] : data
|
55
|
+
item
|
56
|
+
end
|
31
57
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
58
|
+
# Create a new SecureDataBag::Item from a DataBagItem.
|
59
|
+
# @param data_bag_item [Chef::DataBagItem] the item to create from
|
60
|
+
# @param opts [Hash] the optional options ot pass to Item.new
|
61
|
+
# @return [SecureDataBag::Item]
|
62
|
+
# @since 3.0.0
|
63
|
+
def from_item(data_bag_item, opts = {})
|
64
|
+
data = data_bag_item.to_hash
|
65
|
+
from_hash(data, opts)
|
66
|
+
end
|
39
67
|
end
|
40
68
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
69
|
+
# Initializer
|
70
|
+
# @param opts [Hash] optional options to configure the SecureDataBag::Item
|
71
|
+
# opts[:data] the initial data to set
|
72
|
+
# opts[:secret] the secret key to use when encrypting/decrypting
|
73
|
+
# opts[:secret_path] the path to the secret key
|
74
|
+
# opts[:encrypted_keys] an array of keys to encrypt
|
75
|
+
# opts[:format] the SecureDataBag::Item format to enforce
|
76
|
+
# @since 3.0.0
|
77
|
+
def initialize(opts = {})
|
78
|
+
opts = Mash.new(opts)
|
46
79
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@secret = arg unless arg.nil?
|
52
|
-
@secret ||= load_secret
|
53
|
-
end
|
80
|
+
# Initiate the APIClient in Chef 12.3+
|
81
|
+
begin super(chef_server_rest: opts.delete(:chef_server_rest))
|
82
|
+
rescue ArgumentError; super()
|
83
|
+
end
|
54
84
|
|
55
|
-
|
56
|
-
@
|
57
|
-
end
|
85
|
+
# Optionally define the Item vesion
|
86
|
+
@version = opts[:version] || SecureDataBag::VERSION
|
58
87
|
|
59
|
-
|
60
|
-
|
61
|
-
|
88
|
+
# Optionally define the Item formats
|
89
|
+
@encryption_format = opts[:encryption_format]
|
90
|
+
@decryption_format = opts[:decryption_format]
|
62
91
|
|
63
|
-
|
64
|
-
|
65
|
-
#
|
66
|
-
def self.load(data_bag, name, opts={})
|
67
|
-
data = super(data_bag, name)
|
68
|
-
new(opts.merge(data:data.to_hash))
|
69
|
-
end
|
92
|
+
# Optionally provide the shared secret
|
93
|
+
@secret = opts[:secret] if opts[:secret]
|
70
94
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
# - pass it to DataBagItem for additional validation
|
75
|
-
# - ensure the data has the encryption hash
|
76
|
-
# - decode the data
|
77
|
-
#
|
78
|
-
def raw_data=(data)
|
79
|
-
data = Mash.new(data)
|
80
|
-
super(data)
|
81
|
-
decode_data!
|
82
|
-
end
|
95
|
+
# Optionally provide a path to the shared secret. If not provided, the
|
96
|
+
# secret loader will automatically attempt to select one.
|
97
|
+
@secret_path = opts[:secret_path]
|
83
98
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
99
|
+
# Optionally provide a list of keys that should be encrypted or attempt
|
100
|
+
# to determine it based on configuration options.
|
101
|
+
@encrypted_keys = (
|
102
|
+
opts[:encrypted_keys] ||
|
103
|
+
Chef::Config[:knife][:secure_data_bag][:encrypted_keys] ||
|
104
|
+
[]
|
105
|
+
).uniq
|
92
106
|
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
def decode_data!
|
97
|
-
@raw_data = decoded_data
|
98
|
-
@raw_data
|
107
|
+
self.raw_data = opts[:data] if opts[:data]
|
108
|
+
self
|
99
109
|
end
|
100
110
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
111
|
+
# Array of hash keys which should be encrypted when encrypting this item.
|
112
|
+
# For previously decrypted items, this will contain the keys which has
|
113
|
+
# previously been encrypted.
|
114
|
+
# @since 3.0.0
|
115
|
+
attr_accessor :encrypted_keys
|
106
116
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
decode_value(v)
|
112
|
-
elsif v.is_a?(Hash)
|
113
|
-
decode_hash(v)
|
114
|
-
else v
|
115
|
-
end
|
116
|
-
hash[k] = v
|
117
|
-
end
|
118
|
-
hash
|
119
|
-
end
|
117
|
+
# Format to enforce when encrypting this Item. This item will automatically
|
118
|
+
# be updated when importing encrypted data.
|
119
|
+
# @since 3.0.0
|
120
|
+
attr_accessor :encryption_format
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
# Format to enforce when decrypting this Item. This item will automatically
|
123
|
+
# be updated when importing decrypted data.
|
124
|
+
# @since 3.0.0
|
125
|
+
attr_accessor :decryption_format
|
125
126
|
|
126
|
-
|
127
|
-
|
127
|
+
# Fetch, Set or optionally Load the shared secret
|
128
|
+
# @param arg [String] optionally set the shared set
|
129
|
+
# @return [String] the shared secret
|
130
|
+
# @since 3.0.0
|
131
|
+
def secret(arg = nil)
|
132
|
+
@secret = arg unless arg.nil?
|
133
|
+
@secret ||= load_secret
|
128
134
|
end
|
129
135
|
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
+
# Hash representing the metadata associated to this Item
|
137
|
+
# @return [Hash] the metadata
|
138
|
+
# @since 3.0.0
|
139
|
+
def metadata
|
140
|
+
Mash.new(
|
141
|
+
encryption_format: @encryption_format,
|
142
|
+
decryption_format: @decryption_format,
|
143
|
+
encrypted_keys: @encrypted_keys,
|
144
|
+
version: @version
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Override the default setter to first ensure that the data is a Mash and
|
149
|
+
# then to automatically decrypt the data.
|
150
|
+
# @param new_data [Hash] the potentially encrypted data
|
151
|
+
# @since 3.0.0
|
152
|
+
def raw_data=(new_data)
|
153
|
+
new_data = Mash.new(new_data)
|
154
|
+
new_data.delete(SecureDataBag::METADATA_KEY)
|
155
|
+
super(decrypt_data!(new_data))
|
156
|
+
end
|
157
|
+
|
158
|
+
# Export this SecureDataBag::Item to it's raw_data
|
159
|
+
# @param opts [Hash] the optional options
|
160
|
+
# @return [Hash]
|
161
|
+
# @since 3.0.0
|
162
|
+
def to_data(opts = {})
|
163
|
+
opts = Mash.new(opts)
|
164
|
+
result = encrypt_data(raw_data)
|
165
|
+
result[SecureDataBag::METADATA_KEY] = metadata if opts[:metadata]
|
166
|
+
result
|
136
167
|
end
|
137
168
|
|
138
|
-
|
139
|
-
|
169
|
+
# Export this SecureDataBag::Item to a Chef::DataBagItem compatible hash
|
170
|
+
# @param opts [Hash] the optional options
|
171
|
+
# @return [Hash]
|
172
|
+
# @since 3.0.0
|
173
|
+
def to_hash(opts = {})
|
174
|
+
opts = Mash.new(opts)
|
175
|
+
result = to_data(opts)
|
176
|
+
result['chef_type'] = 'data_bag_item'
|
177
|
+
result['data_bag'] = data_bag.to_s
|
178
|
+
result
|
140
179
|
end
|
141
180
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
181
|
+
# Export this SecureDataBag::Item to a Chef::DataBagItem compatible json
|
182
|
+
# @return [String]
|
183
|
+
# @since 3.0.0
|
184
|
+
def to_json(*a)
|
185
|
+
result = {
|
186
|
+
'name' => object_name,
|
187
|
+
'json_class' => 'Chef::DataBagItem',
|
188
|
+
'chef_type' => 'data_bag_item',
|
189
|
+
'data_bag' => data_bag.to_s,
|
190
|
+
'raw_data' => encrypt_data(raw_data)
|
191
|
+
}
|
192
|
+
result.to_json(*a)
|
151
193
|
end
|
152
194
|
|
153
|
-
|
154
|
-
|
155
|
-
|
195
|
+
private
|
196
|
+
|
197
|
+
# Load the shared secret from the configured secret_path (or auto-detect
|
198
|
+
# the path if undefined).
|
199
|
+
# @return [String] the shared secret
|
200
|
+
# @since 3.0.0
|
201
|
+
def load_secret
|
202
|
+
@secret = self.class.load_secret(@secret_path)
|
156
203
|
end
|
157
204
|
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
|
162
|
-
|
163
|
-
|
205
|
+
# Decrypt the data, save the both the decrypted_keys and format for
|
206
|
+
# possible re-encryption, and return the descrypted hash.
|
207
|
+
# @param data [Hash] the potentially encrypted hash
|
208
|
+
# @param save [Boolean] whether to save the encrypted keys and format
|
209
|
+
# @return [Hash] the decrypted hash
|
210
|
+
# @since 3.0.0
|
211
|
+
def decrypt_data(data, save: false)
|
212
|
+
decryptor = SecureDataBag::Decryptor.for(data, secret, metadata)
|
213
|
+
decryptor.decrypt!
|
214
|
+
@encrypted_keys.concat(decryptor.decrypted_keys).uniq! if save
|
215
|
+
@decryption_format = decryptor.format if save
|
216
|
+
decryptor.decrypted_hash
|
164
217
|
end
|
165
218
|
|
166
|
-
def
|
167
|
-
|
168
|
-
item.data_bag h.data_bag
|
169
|
-
item.encoded_fields h.encoded_fields if h.respond_to?(:encoded_fields)
|
170
|
-
item
|
219
|
+
def decrypt_data!(data)
|
220
|
+
decrypt_data(data, save: true)
|
171
221
|
end
|
172
222
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
223
|
+
# Encrypt the data and save the encrypted_keys.
|
224
|
+
# @param data [Hash] the hash to encrypt
|
225
|
+
# @param save [Boolean] whether to save the encrypted keys
|
226
|
+
# @return [Hash] the encrypted hash
|
227
|
+
# @since 3.0.0
|
228
|
+
def encrypt_data(data, _save: false)
|
229
|
+
encryptor = SecureDataBag::Encryptor.new(data, secret, metadata)
|
230
|
+
encryptor.encrypt!
|
231
|
+
encryptor.encrypted_hash
|
178
232
|
end
|
179
233
|
|
180
|
-
def
|
181
|
-
|
182
|
-
name: self.object_name,
|
183
|
-
json_class: "Chef::DataBagItem",
|
184
|
-
chef_type: "data_bag_item",
|
185
|
-
data_bag: data_bag,
|
186
|
-
raw_data: encoded_data
|
187
|
-
}
|
188
|
-
result.to_json(*a)
|
234
|
+
def encrypt_data!(data)
|
235
|
+
encrypt_data(data, save: true)
|
189
236
|
end
|
190
237
|
end
|
191
238
|
end
|
192
239
|
|
240
|
+
SecureDataBagItem = SecureDataBag::Item
|