chef-encrypted-attributes 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|