Class: Chef::EncryptedAttribute

Inherits:
Object
  • Object
show all
Extended by:
API
Defined in:
lib/chef/encrypted_attribute.rb,
lib/chef/encrypted_attribute/api.rb,
lib/chef/encrypted_attribute/yajl.rb,
lib/chef/encrypted_attribute/config.rb,
lib/chef/encrypted_attribute/version.rb,
lib/chef/encrypted_attribute/cache_lru.rb,
lib/chef/encrypted_attribute/assertions.rb,
lib/chef/encrypted_attribute/exceptions.rb,
lib/chef/encrypted_attribute/local_node.rb,
lib/chef/encrypted_attribute/remote_node.rb,
lib/chef/encrypted_attribute/remote_nodes.rb,
lib/chef/encrypted_attribute/remote_users.rb,
lib/chef/encrypted_attribute/search_helper.rb,
lib/chef/encrypted_attribute/encrypted_mash.rb,
lib/chef/encrypted_attribute/remote_clients.rb,
lib/chef/encrypted_attribute/encrypted_mash/version0.rb,
lib/chef/encrypted_attribute/encrypted_mash/version1.rb,
lib/chef/encrypted_attribute/encrypted_mash/version2.rb

Overview

Main EncryptedAttribute class.

This class contains both static and instance level public methods. Internally, all work with EncryptedMash object instances.

Class Methods

The class methods (or static methods) are normally used from Chef cookbooks.

The attributes create with the class methods are encrypted only for the local node by default.

The static *_on_node methods can be used, although they have not been designed for this purpose (have not been tested).

They are # documented in the API class.

Instance Methods

The instance methods are normally used by other libraries or gems. For example, the knife extensions included in this gem uses these methods.

The instance methods will grant encrypted attribute access only to the remote node by default.

Usually only the *_from_node/*_on_node instance methods will be used.

See Also:

Defined Under Namespace

Modules: API, Assertions, SearchHelper, Yajl Classes: CacheLru, ClientNotFound, Config, DecryptionFailure, EncryptedMash, EncryptionFailure, InsufficientPrivileges, InvalidKey, InvalidPublicKey, InvalidSearchKeys, LocalNode, MessageAuthenticationFailure, RemoteClients, RemoteNode, RemoteNodes, RemoteUsers, RequirementsFailure, SearchFailure, SearchFatalError, UnacceptableEncryptedAttributeFormat, UnsupportedEncryptedAttributeFormat, UserNotFound

Constant Summary collapse

VERSION =

chef-encrypted-attributes gem version.

'0.9.0'

Instance Method Summary collapse

Methods included from API

debug, exist?, exist_on_node?, exists?, exists_on_node?, local_node, warn

Constructor Details

#initialize(c = nil) ⇒ EncryptedAttribute

Chef::EncryptedAttribute constructor.


76
77
78
# File 'lib/chef/encrypted_attribute.rb', line 76

def initialize(c = nil)
  config(c)
end

Instance Method Details

#config(arg = nil) ⇒ Config

Sets or gets the encrypted attribute configuration.

Reads the default configuration from Chef::Config[:encrypted_attributes].

When setting using a Config class, all the configuration options will be replaced.

When setting using a Hash, only the provided keys will be replaced.


92
93
94
95
96
97
98
# File 'lib/chef/encrypted_attribute.rb', line 92

def config(arg = nil)
  @config ||= EncryptedAttribute::Config.new(
    Chef::Config[:encrypted_attributes]
  )
  @config.update!(arg) unless arg.nil?
  @config
end

#create(value, keys = nil) ⇒ EncryptedMash

Creates an encrypted attribute from a Hash.

Only the keys passed as parameter and the configured keys will be able to decrypt the attribute, so beware of including your local key if you need to decrypt it in the future.

Raises:


170
171
172
173
174
175
# File 'lib/chef/encrypted_attribute.rb', line 170

def create(value, keys = nil)
  decrypted = { 'content' => value }

  enc_attr = EncryptedMash.create(config.version)
  enc_attr.encrypt(decrypted, target_keys(keys))
end

#create_on_node(name, attr_ary, value) ⇒ EncryptedMash

Creates an encrypted attribute on a remote node.

The remote node will always be able to decrypt it. The local node will not be able to decrypt it by default, you must remember to include the key in the configuration.

Raises:


206
207
208
209
210
211
212
213
214
215
216
# File 'lib/chef/encrypted_attribute.rb', line 206

def create_on_node(name, attr_ary, value)
  # read the client public key
  node_public_key = RemoteClients.get_public_key(name)

  # create the encrypted attribute
  enc_attr = create(value, [node_public_key])

  # save encrypted attribute
  remote_node = RemoteNode.new(name)
  remote_node.save_attribute(attr_ary, enc_attr)
end

#load(enc_hs, key = nil) ⇒ Hash, ...

Decrypts an encrypted attribute from a local node attribute.

Raises:


110
111
112
113
114
# File 'lib/chef/encrypted_attribute.rb', line 110

def load(enc_hs, key = nil)
  enc_attr = EncryptedMash.json_create(enc_hs)
  decrypted = enc_attr.decrypt(key || local_key)
  decrypted['content'] # TODO: check this Hash
end

#load_from_node(name, attr_ary, key = nil) ⇒ Hash, ...

Decrypts a encrypted attribute from a remote node.

Raises:


131
132
133
134
135
136
137
138
# File 'lib/chef/encrypted_attribute.rb', line 131

def load_from_node(name, attr_ary, key = nil)
  remote_node = RemoteNode.new(name)
  enc_hs =
    remote_node.load_attribute(
      attr_ary, config.search_max_rows, config.partial_search
    )
  load(enc_hs, key)
end

#update(enc_hs, keys = nil) ⇒ Boolean

Updates the keys for which a local attribute is encrypted.

In case new keys are added or some keys are removed, the attribute will be re-created again.

Only the keys passed as parameter and the configured keys will be able to decrypt the attribute, so beware of including your local key if you need to decrypt it in the future.

Uses the local key to decrypt the attribute, so the local key should be able to read the attribute. At least before updating.

Raises:

See Also:


255
256
257
258
259
260
261
262
263
264
265
# File 'lib/chef/encrypted_attribute.rb', line 255

def update(enc_hs, keys = nil)
  old_enc_attr = EncryptedMash.json_create(enc_hs)
  if old_enc_attr.needs_update?(target_keys(keys))
    hs = old_enc_attr.decrypt(local_key)
    new_enc_attr = create(hs['content'], keys) # TODO: check this Hash
    enc_hs.replace(new_enc_attr)
    true
  else
    false
  end
end

#update_on_node(name, attr_ary) ⇒ Boolean

Updates the keys for which a remote attribute is encrypted.

In case new keys are added or some keys are removed, the attribute will be re-created again.

Only the remote node and the configured keys will be able to decrypt the attribute, so beware of including your local key if you need to decrypt it in the future.

Uses the local key to decrypt the attribute, so the local key should be able to read the attribute. At least before updating.

Raises:

See Also:


303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/chef/encrypted_attribute.rb', line 303

def update_on_node(name, attr_ary)
  # read the client public key
  node_public_key = RemoteClients.get_public_key(name)

  # update the encrypted attribute
  remote_node = RemoteNode.new(name)
  enc_hs =
    remote_node.load_attribute(
      attr_ary, config.search_max_rows, config.partial_search
    )
  updated = update(enc_hs, [node_public_key])

  # save encrypted attribute
  if updated
    # TODO: Node is accessed twice (RemoteNode#load_attribute above)
    remote_node.save_attribute(attr_ary, enc_hs)
  end
  updated
end