chef-encrypted-attributes 0.1.1 → 0.2.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 +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/API.md +13 -4
- data/CHANGELOG.md +12 -0
- data/INTERNAL.md +54 -0
- data/README.md +51 -14
- data/TESTING.md +27 -21
- data/TODO.md +2 -2
- data/lib/chef/encrypted_attribute.rb +15 -4
- data/lib/chef/encrypted_attribute/assertions.rb +36 -0
- data/lib/chef/encrypted_attribute/encrypted_mash.rb +7 -2
- data/lib/chef/encrypted_attribute/encrypted_mash/version1.rb +3 -2
- data/lib/chef/encrypted_attribute/encrypted_mash/version2.rb +104 -0
- data/lib/chef/encrypted_attribute/exceptions.rb +1 -0
- data/lib/chef/encrypted_attribute/version.rb +1 -1
- data/lib/chef/knife/encrypted_attribute_create.rb +1 -1
- data/lib/chef/knife/encrypted_attribute_delete.rb +1 -1
- data/lib/chef/knife/encrypted_attribute_edit.rb +1 -1
- data/lib/chef/knife/encrypted_attribute_show.rb +1 -1
- data/lib/chef/knife/encrypted_attribute_update.rb +1 -1
- data/spec/benchmark_helper.rb +1 -1
- data/spec/spec_helper.rb +10 -2
- metadata +62 -38
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1bb2baddf0f4e35d5b5fb127fd7ce2df1c28612
|
4
|
+
data.tar.gz: 92504e332a6b3ae5a15746f727149fa7e6c9fcc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 919dff2768d33583bdedcf661865091c494b0e6a9a5823fe0aebed15bfa2db812c9c82c5647084f811f93c6b688cb37d314b2686c949f7a6a38fe9685934dfef
|
7
|
+
data.tar.gz: f802b87b39e85e74b402acb3ffbae41f5d3c3e51e0eb862b3b09c4692dbc1551b0a37f57a9fced0f03f6b8007c0a56f028ccd17d3a043cb7e3fac34ee7953c82
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
Binary file
|
data/API.md
CHANGED
@@ -41,7 +41,7 @@ Returns `true` if the encrypted attribute has been updated, `false` if not.
|
|
41
41
|
|
42
42
|
An exception is thrown if there is any error in the updating process.
|
43
43
|
|
44
|
-
### Chef::EncryptedAttribute.
|
44
|
+
### Chef::EncryptedAttribute.exist?(hs)
|
45
45
|
|
46
46
|
Checks whether an encrypted attribute exists.
|
47
47
|
|
@@ -86,7 +86,7 @@ An exception is thrown if there is any error in the updating process.
|
|
86
86
|
|
87
87
|
This method **requires admin privileges**. So in most cases, cannot be used from cookbooks.
|
88
88
|
|
89
|
-
### Chef::EncryptedAttribute.
|
89
|
+
### Chef::EncryptedAttribute.exist_on_node?(name, attr_ary [, config])
|
90
90
|
|
91
91
|
Checks whether an encrypted attribute exists in a remote node.
|
92
92
|
|
@@ -102,9 +102,11 @@ All the methods read the default configuration from the `Chef::Config[:encrypted
|
|
102
102
|
|
103
103
|
If the configuration value to be merged is an array or a hash (for example `keys`), the method argument configuration value has preference over the global configuration. Arrays and hashes are not merged.
|
104
104
|
|
105
|
-
Both `Chef::Config[:encrypted_attributes]` and
|
105
|
+
Both `Chef::Config[:encrypted_attributes]` and method's `config` parameter should be a hash which may have any of the following keys:
|
106
106
|
|
107
|
-
* `:version` - `EncryptedMash` format version to use, by default `1` is used which is considered
|
107
|
+
* `:version` - `EncryptedMash` format version to use, by default `1` is used which is recommended. The version `2` uses [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode) and probably should be considered the most secure, but it is disabled by default because it has some more requirements:
|
108
|
+
* Ruby `>= 2`.
|
109
|
+
* OpenSSL `>= 1.0.1`.
|
108
110
|
* `:partial_search` - Whether to use Chef Server partial search, enabled by default. It may not work in some old versions of Chef Server.
|
109
111
|
* `:client_search` - Search query for clients allowed to read the encrypted attribute. Can be a simple string or an array of queries to be *OR*-ed.
|
110
112
|
* `:users` - Array of user names to be allowed to read the encrypted attribute(s). `"*"` to allow access to all users. Keep in mind that only admin clients or admin users are allowed to read user public keys. It is **not recommended** to use this from cookbooks unless you know what you are doing.
|
@@ -125,6 +127,13 @@ To disable Partial Search locally:
|
|
125
127
|
ftp_pass = Chef::EncryptedAttribute.load(node["myapp"]["ftp_password"], { :partial_search => false })
|
126
128
|
```
|
127
129
|
|
130
|
+
To use protocol version 2 globally, which uses [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode):
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
Chef::Config[:encrypted_attributes][:version] = 2
|
134
|
+
# ...
|
135
|
+
```
|
136
|
+
|
128
137
|
If you want to use knife to work with encrypted attributes, surely you will need to save your Chef User public keys in a Data Bag (there is no need to encrypt them because they are public) and add them to the `:keys` configuration option. See the [Example Using User Keys Data Bag](README.md#example-using-user-keys-data-bag) in the README for more information on this.
|
129
138
|
|
130
139
|
## Caches
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
This file is used to list changes made in each version of `chef-encrypted-attributes`.
|
4
4
|
|
5
|
+
## 0.2.0:
|
6
|
+
|
7
|
+
* Deprecate `#exists?` methods in favor of `#exist?` methods
|
8
|
+
* Fixed all RSpec deprecation warnings
|
9
|
+
* Added Protocol Version 2 (*disabled by default*): uses [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode) as in [Chef 12 Encrypted Data Bags Version 3](https://github.com/opscode/chef/pull/1591).
|
10
|
+
* Added `RequirementsFailure` exception
|
11
|
+
* README, CONTRIBUTING, TODO: multiple documentation improvements
|
12
|
+
* Added some security related sections to the README
|
13
|
+
* Added email GPG key
|
14
|
+
* Added gem signing certificate
|
15
|
+
* gemspec: added dev dependency versions with pessimistic operator
|
16
|
+
|
5
17
|
## 0.1.1:
|
6
18
|
|
7
19
|
* gemspec: replaced open-ended chef dependency by `~> 11.4`
|
data/INTERNAL.md
CHANGED
@@ -110,3 +110,57 @@ Data to calculate the HMAC from
|
|
110
110
|
* The data used to calculate the HMAC is the encrypted data, not the clear text data (**Encrypt-then-MAC**).
|
111
111
|
* The secret used to calculate the HMAC is not the same as the secret used to encrypt the data.
|
112
112
|
* The secret used to calculate the HMAC is shared inside `encrypted_secret` field with the data secret.
|
113
|
+
|
114
|
+
### EncryptedMash::Version2
|
115
|
+
|
116
|
+
Uses public key cryptography (PKI) to encrypt a shared secret. Then this shared secret is used to encrypt the data using [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode).
|
117
|
+
|
118
|
+
* This protocol version is based on the [Chef 12 Encrypted Data Bags Version 3 implementation](https://github.com/opscode/chef/pull/1591).
|
119
|
+
* To use it, the following **special requirements** must be met:
|
120
|
+
* Ruby `>= 2`.
|
121
|
+
* OpenSSL `>= 1.0.1`.
|
122
|
+
* This implementation can be improved, is not optimized either for performance or for space.
|
123
|
+
* Every time the `EncryptedAttribute` is updated, all the shared secrets are regenerated.
|
124
|
+
|
125
|
+
#### EncryptedMash::Version2 Structure
|
126
|
+
|
127
|
+
If you try to read this encrypted attribute structure, you can see a *Mash* attribute with the following content:
|
128
|
+
|
129
|
+
```
|
130
|
+
EncryptedMash
|
131
|
+
├── chef_type: "encrypted_attribute" (string).
|
132
|
+
├── x_json_class: The used `EncryptedMash` version class name (string).
|
133
|
+
├── encrypted_data
|
134
|
+
│ ├── cipher: The used PKI algorithm, "aes-256-gcm" (string).
|
135
|
+
│ ├── data: PKI encrypted data (base64).
|
136
|
+
│ ├── auth_tag: GCM authentication tag (base64).
|
137
|
+
│ └── iv: Initialization vector (in base64).
|
138
|
+
└── encrypted_secret
|
139
|
+
├── pub_key_hash1: The shared secret encrypted for the public key 1 (base64).
|
140
|
+
├── pub_key_hash2: The shared secret encrypted for the public key 2 (base64).
|
141
|
+
└── ...
|
142
|
+
```
|
143
|
+
|
144
|
+
* `x_json_class` field is used, with the `x_` prefix, to be easily integrated with Chef in the future.
|
145
|
+
|
146
|
+
##### EncryptedMash[encrypted_data][data]
|
147
|
+
|
148
|
+
The data inside `encrypted_data` is symmetrically encrypted using the secret shared key. The data is converted to *JSON* before the encryption, then encrypted and finally encoded in *base64*. By default, the `"aes-256-gcm"` algorithm is used for encryption.
|
149
|
+
|
150
|
+
After decryption, the *JSON* has the following structure:
|
151
|
+
|
152
|
+
```
|
153
|
+
└── encrypted_data
|
154
|
+
└── data (symmetrically encrypted JSON in base64)
|
155
|
+
└── content: attribute content as a Mash.
|
156
|
+
```
|
157
|
+
|
158
|
+
* In the future, this structure may contain some metadata like default configuration values.
|
159
|
+
|
160
|
+
##### EncryptedMash[encrypted_secret][pub_key_hash1]
|
161
|
+
|
162
|
+
The `public_key_hash1` key value is the *SHA1* of the public key used for encryption.
|
163
|
+
|
164
|
+
Its content is the encrypted shared secret in *raw*. The encryption is done using the *RSA* algorithm (PKI).
|
165
|
+
|
166
|
+
After decryption, you find the the shared secret in *raw* (in *Version1* this is a *JSON* in *base64*).
|
data/README.md
CHANGED
@@ -19,6 +19,9 @@ Node clients with read access can be specified using a `client_search` query. In
|
|
19
19
|
* Ruby `>= 1.9`
|
20
20
|
* Chef Client `~> 11.4`
|
21
21
|
* yajl-ruby `~> 1.1` (included with Chef)
|
22
|
+
* If you want to use protocol version 2 to use [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode) (disabled by default):
|
23
|
+
* Ruby `>= 2`.
|
24
|
+
* OpenSSL `>= 1.0.1`.
|
22
25
|
|
23
26
|
## Usage in Recipes
|
24
27
|
|
@@ -41,7 +44,7 @@ require "chef-encrypted-attributes"
|
|
41
44
|
|
42
45
|
Chef::Recipe.send(:include, Opscode::OpenSSL::Password) # include the #secure_password method
|
43
46
|
|
44
|
-
if Chef::EncryptedAttribute.
|
47
|
+
if Chef::EncryptedAttribute.exist?(node["myapp"]["ftp_password"])
|
45
48
|
# update with the new keys
|
46
49
|
Chef::EncryptedAttribute.update(node.set["myapp"]["ftp_password"])
|
47
50
|
|
@@ -69,7 +72,7 @@ require "chef-encrypted-attributes"
|
|
69
72
|
# Allow all webapp nodes to read the attributes encrypted by me
|
70
73
|
Chef::Config[:encrypted_attributes][:client_search] = "role:webapp"
|
71
74
|
|
72
|
-
if Chef::EncryptedAttribute.
|
75
|
+
if Chef::EncryptedAttribute.exist?(node["myapp"]["encrypted_data"])
|
73
76
|
# when can used #load here as above if we need the `encrypted_data` outside this `if`
|
74
77
|
|
75
78
|
# update with the new keys
|
@@ -87,14 +90,14 @@ Then we can read this attribute from another allowed node (a `"role:webapp"` nod
|
|
87
90
|
chef_gem "chef-encrypted-attributes"
|
88
91
|
require "chef-encrypted-attributes"
|
89
92
|
|
90
|
-
if Chef::EncryptedAttribute.
|
93
|
+
if Chef::EncryptedAttribute.exist_on_node?("random.example.com", ["myapp", "encrypted_data"])
|
91
94
|
data = Chef::EncryptedAttribute.load_from_node("random.example.com", ["myapp", "encrypted_data"])
|
92
95
|
|
93
96
|
# use `data` for something here ...
|
94
97
|
end
|
95
98
|
```
|
96
99
|
|
97
|
-
**Note:** Be careful when using `#
|
100
|
+
**Note:** Be careful when using `#exist_on_node?` and `#load_from_node` and remember passing the attribute path to read as **Array of Strings** ~~instead of using `node[...]` (which points to the local node)~~.
|
98
101
|
|
99
102
|
### Example Using User Keys Data Bag
|
100
103
|
|
@@ -124,7 +127,7 @@ chef_users.delete("id") # remove the data bag "id" to avoid to confuse it with a
|
|
124
127
|
Chef::Log.debug("Admin users able to read the Encrypted Attributes: #{chef_users.keys.inspect}")
|
125
128
|
Chef::Config[:encrypted_attributes][:keys] = chef_users.values
|
126
129
|
|
127
|
-
# if Chef::EncryptedAttribute.
|
130
|
+
# if Chef::EncryptedAttribute.exist_on_node?(...)
|
128
131
|
# Chef::EncryptedAttribute.update(...)
|
129
132
|
# else
|
130
133
|
# node.set[...][...] = Chef::EncryptedAttribute.create(...)
|
@@ -254,7 +257,7 @@ For example:
|
|
254
257
|
<td> </td>
|
255
258
|
<td>--encrypted-attribute-version</td>
|
256
259
|
<td>Encrypted Attribute protocol version to use</td>
|
257
|
-
<td>"0", "1" <em>(default)</em
|
260
|
+
<td>"0", "1" <em>(default)</em>, "2"</td>
|
258
261
|
<td>create, edit, update</td>
|
259
262
|
</tr>
|
260
263
|
<tr>
|
@@ -298,18 +301,52 @@ For example:
|
|
298
301
|
|
299
302
|
See the [INTERNAL.md](INTERNAL.md) file for a more low level documentation.
|
300
303
|
|
304
|
+
## Using Signed Gems
|
305
|
+
|
306
|
+
The `chef-encrypted-attributes` gem is cryptographically signed by Onddo Labs's certificate, which identifies as *team@onddo.com*. You can obtain the official signature here:
|
307
|
+
|
308
|
+
https://raw.github.com/onddo/chef-encrypted-attributes/master/certs/team_onddo.crt
|
309
|
+
|
310
|
+
To be sure the gem you install has not been tampered with:
|
311
|
+
|
312
|
+
$ gem cert --add <(curl -Ls https://raw.github.com/onddo/chef-encrypted-attributes/master/certs/team_onddo.crt)
|
313
|
+
$ gem install chef-encrypted-attributes -P MediumSecurity
|
314
|
+
|
315
|
+
The *MediumSecurity* trust profile will verify signed gems, but allow the installation of unsigned dependencies. This is necessary because not all of `chef-encrypted-attributes`'s dependencies are signed, so we cannot use *HighSecurity*.
|
316
|
+
|
317
|
+
We recommend to remove our certificate after the gem has been successfully verified and installed:
|
318
|
+
|
319
|
+
$ gem cert --remove '/cn=team/dc=onddo/dc=com'
|
320
|
+
|
321
|
+
## Security Notes
|
322
|
+
|
323
|
+
All the cryptographic systems and algorithms used by `chef-encrypted-attributes` are carefully described in the [internal documentation](INTERNAL.md) for public review. The code was originally based on *Encrypted Data Bags* and [chef-vault](https://github.com/Nordstrom/chef-vault) implementations, then improved.
|
324
|
+
|
325
|
+
Still, this gem should be considered experimental until audited by professional cryptographers.
|
326
|
+
|
327
|
+
## Reporting Security Problems
|
328
|
+
|
329
|
+
If you have discovered a bug in `chef-encrypted-attributes` of a sensitive nature, i.e. one which can compromise the security of `chef-encrypted-attributes` users, you can report it securely by sending a GPG encrypted message. Please use the following key:
|
330
|
+
|
331
|
+
https://raw.github.com/onddo/chef-encrypted-attributes/master/zuazo.gpg
|
332
|
+
|
333
|
+
The key fingerprint is (or should be):
|
334
|
+
|
335
|
+
8EFA 5B17 7275 5F1F 42B2 26B4 8E18 8B67 9DE1 9468
|
336
|
+
|
337
|
+
## Testing
|
338
|
+
|
339
|
+
See [TESTING.md](TESTING.md).
|
340
|
+
|
301
341
|
## Contributing
|
302
342
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
4. Write your change.
|
307
|
-
5. Run the tests, ensuring they all pass (try as much as possible not to reduce coverage).
|
308
|
-
6. Submit a Pull Request using Github.
|
343
|
+
Please do not hesitate to [open an issue](https://github.com/onddo/chef-encrypted-attributes/issues/new) with any questions or problems.
|
344
|
+
|
345
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
309
346
|
|
310
|
-
|
347
|
+
## TODO
|
311
348
|
|
312
|
-
|
349
|
+
See [TODO.md](TODO.md).
|
313
350
|
|
314
351
|
## License and Author
|
315
352
|
|
data/TESTING.md
CHANGED
@@ -17,28 +17,34 @@
|
|
17
17
|
You can run some simple benchmarks, not at all realistic:
|
18
18
|
|
19
19
|
$ rspec spec/benchmark/*
|
20
|
-
|
21
|
-
Local EncryptedAttribute read (v=0) 0.
|
22
|
-
Local EncryptedAttribute read (v=1) 0.
|
23
|
-
Local
|
24
|
-
|
25
|
-
Remote EncryptedAttribute read (v=
|
26
|
-
Remote
|
27
|
-
|
28
|
-
|
29
|
-
Local
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Remote
|
37
|
-
|
38
|
-
|
20
|
+
user system total real
|
21
|
+
Local EncryptedAttribute read (v=0) 0.410000 0.000000 0.410000 ( 0.417956)
|
22
|
+
Local EncryptedAttribute read (v=1) 0.390000 0.010000 0.400000 ( 0.398934)
|
23
|
+
Local EncryptedAttribute read (v=2) 0.420000 0.000000 0.420000 ( 0.420211)
|
24
|
+
Local EncryptedDataBag read 0.010000 0.000000 0.010000 ( 0.011614)
|
25
|
+
Remote EncryptedAttribute read (v=0) 1.480000 0.070000 1.550000 ( 1.549856)
|
26
|
+
Remote EncryptedAttribute read (v=1) 1.440000 0.060000 1.500000 ( 1.486179)
|
27
|
+
Remote EncryptedAttribute read (v=2) 1.510000 0.060000 1.570000 ( 1.561124)
|
28
|
+
Remote EncryptedDataBag read 0.970000 0.060000 1.030000 ( 1.012260)
|
29
|
+
Local EncryptedAttribute write (v=0) 0.090000 0.000000 0.090000 ( 0.089210)
|
30
|
+
Local EncryptedAttribute write (v=1) 0.090000 0.000000 0.090000 ( 0.090442)
|
31
|
+
Local EncryptedAttribute write (v=2) 0.060000 0.000000 0.060000 ( 0.055671)
|
32
|
+
Local EncryptedDataBag write 0.000000 0.000000 0.000000 ( 0.012315)
|
33
|
+
Remote EncryptedAttribute write (v=0) 1.140000 0.050000 1.190000 ( 1.179739)
|
34
|
+
Remote EncryptedAttribute write (v=1) 1.090000 0.090000 1.180000 ( 1.161603)
|
35
|
+
Remote EncryptedAttribute write (v=2) 1.120000 0.060000 1.180000 ( 1.159668)
|
36
|
+
Remote EncryptedDataBag write 2.080000 0.090000 2.170000 ( 2.146914)
|
37
|
+
Local EncryptedAttribute read/write (v=0) 0.550000 0.000000 0.550000 ( 0.555362)
|
38
|
+
Local EncryptedAttribute read/write (v=1) 0.540000 0.010000 0.550000 ( 0.550447)
|
39
|
+
Local EncryptedAttribute read/write (v=2) 0.570000 0.000000 0.570000 ( 0.576107)
|
40
|
+
Local EncryptedDataBag read/write 0.950000 0.050000 1.000000 ( 0.979758)
|
41
|
+
Remote EncryptedAttribute read/write (v=0) 2.670000 0.100000 2.770000 ( 2.746405)
|
42
|
+
Remote EncryptedAttribute read/write (v=1) 2.700000 0.090000 2.790000 ( 2.758583)
|
43
|
+
Remote EncryptedAttribute read/write (v=2) 2.660000 0.110000 2.770000 ( 2.752359)
|
44
|
+
Remote EncryptedDataBag read/write 3.030000 0.140000 3.170000 ( 3.125538)
|
39
45
|
|
40
|
-
Finished in
|
41
|
-
|
46
|
+
Finished in 28.01 seconds
|
47
|
+
24 examples, 0 failures
|
42
48
|
|
43
49
|
These benchmarks run 100 passes for each test.
|
44
50
|
|
data/TODO.md
CHANGED
@@ -9,9 +9,9 @@ TODO
|
|
9
9
|
* Add Ruby `1.8` support?
|
10
10
|
* Document the Ruby code.
|
11
11
|
* Add more info/debug prints.
|
12
|
-
* Space-optimized `EncryptedMash::
|
12
|
+
* Space-optimized `EncryptedMash::Version3` class.
|
13
13
|
* Tests: Add test helper functions (key generation, ApiClients including priv keys, Node creation...).
|
14
|
-
* Tests: Add more tests for `EncryptedMash::Version1`.
|
14
|
+
* Tests: Add more tests for `EncryptedMash::Version1` and `EncryptedMash::Version2`.
|
15
15
|
* Tests: Add unit tests for `EncryptedAttribute`.
|
16
16
|
* Tests: Add unit tests for all knife commands.
|
17
17
|
* Tests: Tests `raise_error` always include regex.
|
@@ -28,6 +28,7 @@ require 'chef/encrypted_attribute/remote_clients'
|
|
28
28
|
require 'chef/encrypted_attribute/remote_users'
|
29
29
|
require 'chef/encrypted_attribute/encrypted_mash/version0'
|
30
30
|
require 'chef/encrypted_attribute/encrypted_mash/version1'
|
31
|
+
require 'chef/encrypted_attribute/encrypted_mash/version2'
|
31
32
|
|
32
33
|
Chef::Config[:encrypted_attributes] = Mash.new unless Chef::Config[:encrypted_attributes].kind_of?(Hash)
|
33
34
|
|
@@ -196,9 +197,9 @@ class Chef
|
|
196
197
|
result
|
197
198
|
end
|
198
199
|
|
199
|
-
def self.
|
200
|
+
def self.exist?(hs)
|
200
201
|
Chef::Log.debug("#{self.class.name}: Checking if Encrypted Attribute exists here: #{hs.to_s}")
|
201
|
-
result = EncryptedMash.
|
202
|
+
result = EncryptedMash.exist?(hs)
|
202
203
|
if result
|
203
204
|
Chef::Log.debug("#{self.class.name}: Encrypted Attribute found.")
|
204
205
|
else
|
@@ -207,11 +208,21 @@ class Chef
|
|
207
208
|
result
|
208
209
|
end
|
209
210
|
|
210
|
-
def self.
|
211
|
+
def self.exists?(*args)
|
212
|
+
Chef::Log.warn("#{self.name}.exists? is deprecated in favor of #{self.name}.exist?.")
|
213
|
+
exist?(*args)
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.exist_on_node?(name, attr_ary, c={})
|
211
217
|
Chef::Log.debug("#{self.class.name}: Checking if Remote Encrypted Attribute exists on #{name}")
|
212
218
|
remote_node = RemoteNode.new(name)
|
213
219
|
node_attr = remote_node.load_attribute(attr_ary, self.config(c).partial_search)
|
214
|
-
Chef::EncryptedAttribute.
|
220
|
+
Chef::EncryptedAttribute.exist?(node_attr)
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.exists_on_node?(*args)
|
224
|
+
Chef::Log.warn("#{self.name}.exists_on_node? is deprecated in favor of #{self.name}.exist_on_node?.")
|
225
|
+
exist_on_node?(*args)
|
215
226
|
end
|
216
227
|
|
217
228
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/encrypted_attribute/exceptions'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class EncryptedAttribute
|
23
|
+
module Assertions
|
24
|
+
|
25
|
+
def assert_aead_requirements_met!(algorithm)
|
26
|
+
unless OpenSSL::Cipher.method_defined?(:auth_data=)
|
27
|
+
raise RequirementsFailure, 'The used Encrypted Attributes protocol version requires Ruby >= 1.9'
|
28
|
+
end
|
29
|
+
unless OpenSSL::Cipher.ciphers.include?(algorithm)
|
30
|
+
raise RequirementsFailure, "The used Encrypted Attributes protocol version requires an OpenSSL version with \"#{algorithm}\" algorithm support"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -45,13 +45,18 @@ class Chef
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def self.
|
48
|
+
def self.exist?(enc_hs)
|
49
49
|
enc_hs.kind_of?(Hash) and
|
50
50
|
enc_hs.has_key?(JSON_CLASS) and
|
51
51
|
enc_hs[JSON_CLASS] =~ /^#{Regexp.escape(Module.nesting[1].name)}/ and
|
52
52
|
enc_hs.has_key?(CHEF_TYPE) and enc_hs[CHEF_TYPE] == CHEF_TYPE_VALUE
|
53
53
|
end
|
54
54
|
|
55
|
+
def self.exists?(*args)
|
56
|
+
Chef::Log.warn("#{self.name}.exists? is deprecated in favor of #{self.name}.exist?.")
|
57
|
+
exist?(*args)
|
58
|
+
end
|
59
|
+
|
55
60
|
def self.create(version)
|
56
61
|
klass = version_klass(version)
|
57
62
|
klass.send(:new)
|
@@ -69,7 +74,7 @@ class Chef
|
|
69
74
|
|
70
75
|
# Update the EncryptedMash from Hash
|
71
76
|
def update_from!(enc_hs)
|
72
|
-
unless self.class.
|
77
|
+
unless self.class.exist?(enc_hs)
|
73
78
|
raise UnacceptableEncryptedAttributeFormat, 'Trying to construct invalid encrypted attribute. Maybe it is not encrypted?'
|
74
79
|
end
|
75
80
|
enc_hs = enc_hs.dup
|
@@ -92,8 +92,8 @@ class Chef
|
|
92
92
|
begin
|
93
93
|
cipher = OpenSSL::Cipher.new(algo)
|
94
94
|
cipher.encrypt
|
95
|
-
enc_value['iv'] = Base64.encode64(cipher.iv = cipher.random_iv)
|
96
95
|
enc_value['secret'] = Base64.encode64(cipher.key = cipher.random_key)
|
96
|
+
enc_value['iv'] = Base64.encode64(cipher.iv = cipher.random_iv)
|
97
97
|
enc_data = cipher.update(value) + cipher.final
|
98
98
|
rescue OpenSSL::Cipher::CipherError => e
|
99
99
|
raise EncryptionFailure, "#{e.class.name}: #{e.to_s}"
|
@@ -105,8 +105,9 @@ class Chef
|
|
105
105
|
def symmetric_decrypt_value(enc_value, algo=SYMM_ALGORITHM)
|
106
106
|
cipher = OpenSSL::Cipher.new(enc_value['cipher'] || algo) # TODO maybe it's better to ignore [cipher] ?
|
107
107
|
cipher.decrypt
|
108
|
-
|
108
|
+
# We must set key before iv: https://bugs.ruby-lang.org/issues/8221
|
109
109
|
cipher.key = Base64.decode64(enc_value['secret'])
|
110
|
+
cipher.iv = Base64.decode64(enc_value['iv'])
|
110
111
|
cipher.update(Base64.decode64(enc_value['data'])) + cipher.final
|
111
112
|
rescue OpenSSL::Cipher::CipherError => e
|
112
113
|
raise DecryptionFailure, "#{e.class.name}: #{e.to_s}"
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/encrypted_attribute/encrypted_mash/version0'
|
20
|
+
require 'chef/encrypted_attribute/encrypted_mash/version1'
|
21
|
+
require 'chef/encrypted_attribute/assertions'
|
22
|
+
require 'chef/encrypted_attribute/exceptions'
|
23
|
+
|
24
|
+
# Version2 format: using RSA with a shared secret and GCM
|
25
|
+
class Chef
|
26
|
+
class EncryptedAttribute
|
27
|
+
class EncryptedMash
|
28
|
+
class Version2 < Chef::EncryptedAttribute::EncryptedMash::Version1
|
29
|
+
include Chef::EncryptedAttribute::Assertions
|
30
|
+
|
31
|
+
ALGORITHM = 'aes-256-gcm'
|
32
|
+
|
33
|
+
def initialize(enc_hs=nil)
|
34
|
+
assert_aead_requirements_met!(ALGORITHM)
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def encrypt(value, public_keys)
|
39
|
+
value_json = json_encode(value)
|
40
|
+
public_keys = parse_public_keys(public_keys)
|
41
|
+
# encrypt the data
|
42
|
+
encrypted_data = symmetric_encrypt_value(value_json)
|
43
|
+
secret = encrypted_data.delete('secret') # should no include the secret in clear
|
44
|
+
self['encrypted_data'] = encrypted_data
|
45
|
+
# encrypt the shared secret
|
46
|
+
self['encrypted_secret'] = rsa_encrypt_multi_key(secret, public_keys)
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def decrypt(key)
|
51
|
+
key = parse_decryption_key(key)
|
52
|
+
enc_value = self['encrypted_data'].dup
|
53
|
+
# decrypt the shared secret
|
54
|
+
enc_value['secret'] = rsa_decrypt_multi_key(self['encrypted_secret'], key)
|
55
|
+
# decrypt the data
|
56
|
+
value_json = symmetric_decrypt_value(enc_value)
|
57
|
+
json_decode(value_json)
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
|
62
|
+
def encrypted?
|
63
|
+
Version0.instance_method(:encrypted?).bind(self).call and
|
64
|
+
self['encrypted_data'].has_key?('iv') and
|
65
|
+
self['encrypted_data']['iv'].kind_of?(String) and
|
66
|
+
self['encrypted_data'].has_key?('auth_tag') and
|
67
|
+
self['encrypted_data']['auth_tag'].kind_of?(String) and
|
68
|
+
self['encrypted_data'].has_key?('data') and
|
69
|
+
self['encrypted_data']['data'].kind_of?(String) and
|
70
|
+
self['encrypted_secret'].kind_of?(Hash)
|
71
|
+
end
|
72
|
+
|
73
|
+
def symmetric_encrypt_value(value, algo=ALGORITHM)
|
74
|
+
enc_value = Mash.new({ 'cipher' => algo })
|
75
|
+
begin
|
76
|
+
cipher = OpenSSL::Cipher.new(algo)
|
77
|
+
cipher.encrypt
|
78
|
+
enc_value['secret'] = cipher.key = cipher.random_key
|
79
|
+
enc_value['iv'] = Base64.encode64(cipher.iv = cipher.random_iv)
|
80
|
+
enc_data = cipher.update(value) + cipher.final
|
81
|
+
enc_value['auth_tag'] = Base64.encode64(cipher.auth_tag)
|
82
|
+
rescue OpenSSL::Cipher::CipherError => e
|
83
|
+
raise EncryptionFailure, "#{e.class.name}: #{e.to_s}"
|
84
|
+
end
|
85
|
+
enc_value['data'] = Base64.encode64(enc_data)
|
86
|
+
enc_value
|
87
|
+
end
|
88
|
+
|
89
|
+
def symmetric_decrypt_value(enc_value, algo=ALGORITHM)
|
90
|
+
cipher = OpenSSL::Cipher.new(enc_value['cipher'] || algo) # TODO maybe it's better to ignore [cipher] ?
|
91
|
+
cipher.decrypt
|
92
|
+
# We must set key before iv: https://bugs.ruby-lang.org/issues/8221
|
93
|
+
cipher.key = enc_value['secret']
|
94
|
+
cipher.iv = Base64.decode64(enc_value['iv'])
|
95
|
+
cipher.auth_tag = Base64.decode64(enc_value['auth_tag'])
|
96
|
+
cipher.update(Base64.decode64(enc_value['data'])) + cipher.final
|
97
|
+
rescue OpenSSL::Cipher::CipherError => e
|
98
|
+
raise DecryptionFailure, "#{e.class.name}: #{e.to_s}"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -19,6 +19,7 @@
|
|
19
19
|
class Chef
|
20
20
|
class EncryptedAttribute
|
21
21
|
|
22
|
+
class RequirementsFailure < StandardError; end
|
22
23
|
class UnsupportedEncryptedAttributeFormat < StandardError; end
|
23
24
|
class UnacceptableEncryptedAttributeFormat < StandardError; end
|
24
25
|
class DecryptionFailure < StandardError; end
|
@@ -51,7 +51,7 @@ class Chef
|
|
51
51
|
attr_ary = attribute_path_to_ary(attr_path)
|
52
52
|
|
53
53
|
# check if the encrypted attribute already exists
|
54
|
-
if Chef::EncryptedAttribute.
|
54
|
+
if Chef::EncryptedAttribute.exist_on_node?(node_name, attr_ary)
|
55
55
|
ui.fatal('Encrypted attribute already exists')
|
56
56
|
exit 1
|
57
57
|
end
|
@@ -54,7 +54,7 @@ class Chef
|
|
54
54
|
end
|
55
55
|
|
56
56
|
attr_ary = attribute_path_to_ary(attr_path)
|
57
|
-
if Chef::EncryptedAttribute.
|
57
|
+
if Chef::EncryptedAttribute.exist_on_node?(node_name, attr_ary)
|
58
58
|
# TODO move this to lib/EncryptedAttribute
|
59
59
|
unless config[:force] # try to read the attribute
|
60
60
|
Chef::EncryptedAttribute.load_from_node(node_name, attr_ary)
|
@@ -51,7 +51,7 @@ class Chef
|
|
51
51
|
attr_ary = attribute_path_to_ary(attr_path)
|
52
52
|
|
53
53
|
# check if the encrypted attribute already exists
|
54
|
-
unless Chef::EncryptedAttribute.
|
54
|
+
unless Chef::EncryptedAttribute.exist_on_node?(node_name, attr_ary)
|
55
55
|
ui.fatal('Encrypted attribute not found')
|
56
56
|
exit 1
|
57
57
|
end
|
@@ -47,7 +47,7 @@ class Chef
|
|
47
47
|
|
48
48
|
attr_ary = attribute_path_to_ary(attr_path)
|
49
49
|
|
50
|
-
unless Chef::EncryptedAttribute.
|
50
|
+
unless Chef::EncryptedAttribute.exist_on_node?(node_name, attr_ary)
|
51
51
|
ui.fatal('Encrypted attribute not found')
|
52
52
|
exit 1
|
53
53
|
end
|
@@ -46,7 +46,7 @@ class Chef
|
|
46
46
|
attr_ary = attribute_path_to_ary(attr_path)
|
47
47
|
|
48
48
|
# check if the encrypted attribute already exists
|
49
|
-
unless Chef::EncryptedAttribute.
|
49
|
+
unless Chef::EncryptedAttribute.exist_on_node?(node_name, attr_ary)
|
50
50
|
ui.fatal('Encrypted attribute not found')
|
51
51
|
exit 1
|
52
52
|
end
|
data/spec/benchmark_helper.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'simplecov'
|
20
|
-
if ENV['TRAVIS'] and RUBY_VERSION >= '
|
20
|
+
if ENV['TRAVIS'] and RUBY_VERSION >= '2.0'
|
21
21
|
require 'coveralls'
|
22
22
|
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
23
23
|
end
|
@@ -30,9 +30,17 @@ require 'chef/exceptions'
|
|
30
30
|
|
31
31
|
require 'rspec/autorun'
|
32
32
|
|
33
|
+
require 'support/platform_helpers'
|
34
|
+
|
33
35
|
RSpec.configure do |config|
|
34
36
|
config.order = 'random'
|
35
37
|
|
36
|
-
config.
|
38
|
+
config.color = true
|
37
39
|
config.tty = true
|
40
|
+
|
41
|
+
config.filter_run_excluding :ruby_gte_19 => true unless ruby_gte_19?
|
42
|
+
config.filter_run_excluding :ruby_gte_20 => true unless ruby_gte_20?
|
43
|
+
config.filter_run_excluding :ruby_gte_20_and_openssl_gte_101 => true unless (ruby_gte_20? && openssl_gte_101?)
|
44
|
+
config.filter_run_excluding :openssl_lt_101 => true unless openssl_lt_101?
|
45
|
+
config.filter_run_excluding :ruby_lt_20 => true unless ruby_lt_20?
|
38
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-encrypted-attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Onddo Labs, SL.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDYDCCAkigAwIBAgIBATANBgkqhkiG9w0BAQUFADA7MQ0wCwYDVQQDDAR0ZWFt
|
14
|
+
MRUwEwYKCZImiZPyLGQBGRYFb25kZG8xEzARBgoJkiaJk/IsZAEZFgNjb20wHhcN
|
15
|
+
MTQwODExMDkxNDAzWhcNMTUwODExMDkxNDAzWjA7MQ0wCwYDVQQDDAR0ZWFtMRUw
|
16
|
+
EwYKCZImiZPyLGQBGRYFb25kZG8xEzARBgoJkiaJk/IsZAEZFgNjb20wggEiMA0G
|
17
|
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrbcM9ZsRca5gEkpftR/J/Rem9JTAK
|
18
|
+
0cKHuEAKgp0QvHAceDRJNJ6LoXfeXP86fPL3kpHNQdbHFW/MGsynjeWg/c/8VbAR
|
19
|
+
W0L6MBUoBuSBN91GBoqHpka1qhMHA6QnUpUHFCOUhoA5oweZ8kDsHh/W2n//vZwr
|
20
|
+
DBcnf4wRzQeZl/I+Ral6gKZSImtMyo0W7TYQT2rMbvms0LoNMKZQ6Gpw9B2NoYtH
|
21
|
+
FYBt78LB771jRc/j5Sk9O2rm/Tnvl6HW2Pb6arwk9pd0A7KVYjJzmaBF5aqOMTml
|
22
|
+
ZDgelv7lLJyIQSASKnusmTlFehppplTHWQKfev6jfKXCepS/cD5EH1wfAgMBAAGj
|
23
|
+
bzBtMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBQzPM4ZVw+kEtQm
|
24
|
+
4eA7AyE6s0gIUDAZBgNVHREEEjAQgQ50ZWFtQG9uZGRvLmNvbTAZBgNVHRIEEjAQ
|
25
|
+
gQ50ZWFtQG9uZGRvLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAZNdmm2OCr8wVxtj8
|
26
|
+
z9gnGVBWpHqE0+mPBsgsueOAhNzoqphOUGMn9JWvOQU3TwiUPHJN9QiOT92OpD0Z
|
27
|
+
UKN6ixyaqPhegRqGQQGTOC7d+l+E+mab3m6f96MyCxNuts8vEFqubs5rd+1E/NDb
|
28
|
+
ZpX7/1KENUo06s8Rpro8pPXh+CL8+177gcfkXzXBElXR6r5Tf8VSxrFPeLIRrdzs
|
29
|
+
AkPvQPEiZbg78ZKmVjcuokhXi1bzvjGVI0lMzW/JBO8GvjUyh4hl6HAfOgXMXpaz
|
30
|
+
cYe8PqNEkky7ugvF4zU3sB6TW+96XasuwDv1uJmyr35LF15U6Cs83+osMbAKJTmG
|
31
|
+
/vqKzw==
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2014-08-12 00:00:00.000000000 Z
|
12
34
|
dependencies:
|
13
35
|
- !ruby/object:Gem::Dependency
|
14
36
|
name: yajl-ruby
|
@@ -42,30 +64,30 @@ dependencies:
|
|
42
64
|
name: rake
|
43
65
|
requirement: !ruby/object:Gem::Requirement
|
44
66
|
requirements:
|
45
|
-
- -
|
67
|
+
- - ~>
|
46
68
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
69
|
+
version: '10.0'
|
48
70
|
type: :development
|
49
71
|
prerelease: false
|
50
72
|
version_requirements: !ruby/object:Gem::Requirement
|
51
73
|
requirements:
|
52
|
-
- -
|
74
|
+
- - ~>
|
53
75
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
76
|
+
version: '10.0'
|
55
77
|
- !ruby/object:Gem::Dependency
|
56
78
|
name: chef-zero
|
57
79
|
requirement: !ruby/object:Gem::Requirement
|
58
80
|
requirements:
|
59
|
-
- -
|
81
|
+
- - ~>
|
60
82
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
83
|
+
version: '2.0'
|
62
84
|
type: :development
|
63
85
|
prerelease: false
|
64
86
|
version_requirements: !ruby/object:Gem::Requirement
|
65
87
|
requirements:
|
66
|
-
- -
|
88
|
+
- - ~>
|
67
89
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
90
|
+
version: '2.0'
|
69
91
|
- !ruby/object:Gem::Dependency
|
70
92
|
name: rspec-core
|
71
93
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,67 +134,69 @@ dependencies:
|
|
112
134
|
name: coveralls
|
113
135
|
requirement: !ruby/object:Gem::Requirement
|
114
136
|
requirements:
|
115
|
-
- -
|
137
|
+
- - ~>
|
116
138
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
139
|
+
version: '0.7'
|
118
140
|
type: :development
|
119
141
|
prerelease: false
|
120
142
|
version_requirements: !ruby/object:Gem::Requirement
|
121
143
|
requirements:
|
122
|
-
- -
|
144
|
+
- - ~>
|
123
145
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
146
|
+
version: '0.7'
|
125
147
|
- !ruby/object:Gem::Dependency
|
126
148
|
name: simplecov
|
127
149
|
requirement: !ruby/object:Gem::Requirement
|
128
150
|
requirements:
|
129
|
-
- -
|
151
|
+
- - ~>
|
130
152
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
153
|
+
version: '0.9'
|
132
154
|
type: :development
|
133
155
|
prerelease: false
|
134
156
|
version_requirements: !ruby/object:Gem::Requirement
|
135
157
|
requirements:
|
136
|
-
- -
|
158
|
+
- - ~>
|
137
159
|
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
160
|
+
version: '0.9'
|
139
161
|
description: Chef plugin to add Node encrypted attributes support using client keys
|
140
162
|
email: team@onddo.com
|
141
163
|
executables: []
|
142
164
|
extensions: []
|
143
165
|
extra_rdoc_files: []
|
144
166
|
files:
|
145
|
-
- Rakefile
|
146
|
-
- LICENSE
|
147
|
-
- README.md
|
148
167
|
- API.md
|
168
|
+
- CHANGELOG.md
|
149
169
|
- INTERNAL.md
|
170
|
+
- LICENSE
|
171
|
+
- README.md
|
172
|
+
- Rakefile
|
150
173
|
- TESTING.md
|
151
174
|
- TODO.md
|
152
|
-
- CHANGELOG.md
|
153
175
|
- lib/chef-encrypted-attributes.rb
|
154
|
-
- lib/chef/
|
155
|
-
- lib/chef/
|
156
|
-
- lib/chef/knife/encrypted_attribute_create.rb
|
157
|
-
- lib/chef/knife/encrypted_attribute_show.rb
|
158
|
-
- lib/chef/knife/encrypted_attribute_update.rb
|
159
|
-
- lib/chef/knife/encrypted_attribute_delete.rb
|
160
|
-
- lib/chef/knife/encrypted_attribute_edit.rb
|
161
|
-
- lib/chef/encrypted_attribute/remote_users.rb
|
176
|
+
- lib/chef/encrypted_attribute.rb
|
177
|
+
- lib/chef/encrypted_attribute/assertions.rb
|
162
178
|
- lib/chef/encrypted_attribute/cache_lru.rb
|
163
|
-
- lib/chef/encrypted_attribute/search_helper.rb
|
164
179
|
- lib/chef/encrypted_attribute/config.rb
|
165
|
-
- lib/chef/encrypted_attribute/
|
180
|
+
- lib/chef/encrypted_attribute/encrypted_mash.rb
|
166
181
|
- lib/chef/encrypted_attribute/encrypted_mash/version0.rb
|
167
182
|
- lib/chef/encrypted_attribute/encrypted_mash/version1.rb
|
183
|
+
- lib/chef/encrypted_attribute/encrypted_mash/version2.rb
|
184
|
+
- lib/chef/encrypted_attribute/exceptions.rb
|
168
185
|
- lib/chef/encrypted_attribute/local_node.rb
|
169
|
-
- lib/chef/encrypted_attribute/encrypted_mash.rb
|
170
|
-
- lib/chef/encrypted_attribute/version.rb
|
171
186
|
- lib/chef/encrypted_attribute/remote_clients.rb
|
172
187
|
- lib/chef/encrypted_attribute/remote_node.rb
|
173
|
-
- lib/chef/encrypted_attribute.rb
|
174
|
-
-
|
188
|
+
- lib/chef/encrypted_attribute/remote_users.rb
|
189
|
+
- lib/chef/encrypted_attribute/search_helper.rb
|
190
|
+
- lib/chef/encrypted_attribute/version.rb
|
191
|
+
- lib/chef/knife/core/config.rb
|
192
|
+
- lib/chef/knife/core/encrypted_attribute_editor_options.rb
|
193
|
+
- lib/chef/knife/encrypted_attribute_create.rb
|
194
|
+
- lib/chef/knife/encrypted_attribute_delete.rb
|
195
|
+
- lib/chef/knife/encrypted_attribute_edit.rb
|
196
|
+
- lib/chef/knife/encrypted_attribute_show.rb
|
197
|
+
- lib/chef/knife/encrypted_attribute_update.rb
|
175
198
|
- spec/benchmark_helper.rb
|
199
|
+
- spec/integration_helper.rb
|
176
200
|
- spec/spec_helper.rb
|
177
201
|
homepage: http://onddo.github.io/chef-encrypted-attributes
|
178
202
|
licenses:
|
@@ -194,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
218
|
version: '0'
|
195
219
|
requirements: []
|
196
220
|
rubyforge_project:
|
197
|
-
rubygems_version: 2.
|
221
|
+
rubygems_version: 2.2.2
|
198
222
|
signing_key:
|
199
223
|
specification_version: 4
|
200
224
|
summary: Chef Encrypted Attributes
|
metadata.gz.sig
ADDED
Binary file
|