diff options
author | John Keiser <jkeiser@opscode.com> | 2013-12-03 12:51:07 -0800 |
---|---|---|
committer | John Keiser <jkeiser@opscode.com> | 2013-12-03 12:51:07 -0800 |
commit | 9bbc9b101d00c309b205f2fdfccc4c7a093d9d31 (patch) | |
tree | b7ac0c7cf4f9191cb8690a94b5826c44d6ce2e89 | |
parent | ca77ec8471560de11ca1ca3244c8fdaa178741cc (diff) | |
download | chef-9bbc9b101d00c309b205f2fdfccc4c7a093d9d31.tar.gz |
Split EncryptedDataBagItem into multiple files
7 files changed, 434 insertions, 303 deletions
diff --git a/lib/chef/encrypted_data_bag_item.rb b/lib/chef/encrypted_data_bag_item.rb index 452a8224df..1f8d6cdf33 100644 --- a/lib/chef/encrypted_data_bag_item.rb +++ b/lib/chef/encrypted_data_bag_item.rb @@ -16,11 +16,10 @@ # limitations under the License. # -require 'base64' -require 'openssl' +require 'chef/config' require 'chef/data_bag_item' -require 'yaml' -require 'yajl' +require 'chef/encrypted_data_bag_item/decryptor' +require 'chef/encrypted_data_bag_item/encryptor' require 'open-uri' # An EncryptedDataBagItem represents a read-only data bag item where @@ -50,305 +49,6 @@ require 'open-uri' class Chef::EncryptedDataBagItem ALGORITHM = 'aes-256-cbc' - class UnacceptableEncryptedDataBagItemFormat < StandardError - end - - class UnsupportedEncryptedDataBagItemFormat < StandardError - end - - class DecryptionFailure < StandardError - end - - class UnsupportedCipher < StandardError - end - - # Implementation class for converting plaintext data bag item values to an - # encrypted value, including any necessary wrappers and metadata. - module Encryptor - - # "factory" method that creates an encryptor object with the proper class - # for the desired encrypted data bag format version. - # - # +Chef::Config[:data_bag_encrypt_version]+ determines which version is used. - def self.new(value, secret, iv=nil) - format_version = Chef::Config[:data_bag_encrypt_version] - case format_version - when 1 - Version1Encryptor.new(value, secret, iv) - when 2 - Version2Encryptor.new(value, secret, iv) - else - raise UnsupportedEncryptedDataBagItemFormat, - "Invalid encrypted data bag format version `#{format_version}'. Supported versions are '1', '2'" - end - end - - class Version1Encryptor - attr_reader :key - attr_reader :plaintext_data - - # Create a new Encryptor for +data+, which will be encrypted with the given - # +key+. - # - # === Arguments: - # * data: An object of any type that can be serialized to json - # * key: A String representing the desired passphrase - # * iv: The optional +iv+ parameter is intended for testing use only. When - # *not* supplied, Encryptor will use OpenSSL to generate a secure random - # IV, which is what you want. - def initialize(plaintext_data, key, iv=nil) - @plaintext_data = plaintext_data - @key = key - @iv = iv && Base64.decode64(iv) - end - - # Returns a wrapped and encrypted version of +plaintext_data+ suitable for - # using as the value in an encrypted data bag item. - def for_encrypted_item - { - "encrypted_data" => encrypted_data, - "iv" => Base64.encode64(iv), - "version" => 1, - "cipher" => ALGORITHM - } - end - - # Generates or returns the IV. - def iv - # Generated IV comes from OpenSSL::Cipher::Cipher#random_iv - # This gets generated when +openssl_encryptor+ gets created. - openssl_encryptor if @iv.nil? - @iv - end - - # Generates (and memoizes) an OpenSSL::Cipher::Cipher object and configures - # it for the specified iv and encryption key. - def openssl_encryptor - @openssl_encryptor ||= begin - encryptor = OpenSSL::Cipher::Cipher.new(ALGORITHM) - encryptor.encrypt - @iv ||= encryptor.random_iv - encryptor.iv = @iv - encryptor.key = Digest::SHA256.digest(key) - encryptor - end - end - - # Encrypts and Base64 encodes +serialized_data+ - def encrypted_data - @encrypted_data ||= begin - enc_data = openssl_encryptor.update(serialized_data) - enc_data << openssl_encryptor.final - Base64.encode64(enc_data) - end - end - - # Wraps the data in a single key Hash (JSON Object) and converts to JSON. - # The wrapper is required because we accept values (such as Integers or - # Strings) that do not produce valid JSON when serialized without the - # wrapper. - def serialized_data - Yajl::Encoder.encode(:json_wrapper => plaintext_data) - end - end - - class Version2Encryptor < Version1Encryptor - - # Returns a wrapped and encrypted version of +plaintext_data+ suitable for - # using as the value in an encrypted data bag item. - def for_encrypted_item - { - "encrypted_data" => encrypted_data, - "hmac" => hmac, - "iv" => Base64.encode64(iv), - "version" => 2, - "cipher" => ALGORITHM - } - end - - # Generates an HMAC-SHA2-256 of the encrypted data (encrypt-then-mac) - def hmac - @hmac ||= begin - digest = OpenSSL::Digest::Digest.new("sha256") - raw_hmac = OpenSSL::HMAC.digest(digest, key, encrypted_data) - Base64.encode64(raw_hmac) - end - end - - end - end - - #=== Decryptor - # For backwards compatibility, Chef implements decryption/deserialization for - # older encrypted data bag item formats in addition to the current version. - # Each decryption/deserialization strategy is implemented as a class in this - # namespace. For convenience the factory method +Decryptor.for()+ can be used - # to create an instance of the appropriate strategy for the given encrypted - # data bag value. - module Decryptor - - # Detects the encrypted data bag item format version and instantiates a - # decryptor object for that version. Call #for_decrypted_item on the - # resulting object to decrypt and deserialize it. - def self.for(encrypted_value, key) - format_version = format_version_of(encrypted_value) - assert_format_version_acceptable!(format_version) - case format_version - when 2 - Version2Decryptor.new(encrypted_value, key) - when 1 - Version1Decryptor.new(encrypted_value, key) - when 0 - Version0Decryptor.new(encrypted_value, key) - else - raise UnsupportedEncryptedDataBagItemFormat, - "This version of chef does not support encrypted data bag item format version '#{format_version}'" - end - end - - def self.format_version_of(encrypted_value) - if encrypted_value.respond_to?(:key?) - encrypted_value["version"] - else - 0 - end - end - - def self.assert_format_version_acceptable!(format_version) - unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version] - raise UnacceptableEncryptedDataBagItemFormat, - "The encrypted data bag item has format version `#{format_version}', " + - "but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'" - end - end - - class Version1Decryptor - - attr_reader :encrypted_data - attr_reader :key - - def initialize(encrypted_data, key) - @encrypted_data = encrypted_data - @key = key - end - - def for_decrypted_item - Yajl::Parser.parse(decrypted_data)["json_wrapper"] - rescue Yajl::ParseError - # convert to a DecryptionFailure error because the most likely scenario - # here is that the decryption step was unsuccessful but returned bad - # data rather than raising an error. - raise DecryptionFailure, "Error decrypting data bag value. Most likely the provided key is incorrect" - end - - def encrypted_bytes - Base64.decode64(@encrypted_data["encrypted_data"]) - end - - def iv - Base64.decode64(@encrypted_data["iv"]) - end - - def decrypted_data - @decrypted_data ||= begin - plaintext = openssl_decryptor.update(encrypted_bytes) - plaintext << openssl_decryptor.final - rescue OpenSSL::Cipher::CipherError => e - raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect" - end - end - - def openssl_decryptor - @openssl_decryptor ||= begin - assert_valid_cipher! - d = OpenSSL::Cipher::Cipher.new(ALGORITHM) - d.decrypt - d.key = Digest::SHA256.digest(key) - d.iv = iv - d - end - end - - def assert_valid_cipher! - # In the future, chef may support configurable ciphers. For now, only - # aes-256-cbc is supported. - requested_cipher = @encrypted_data["cipher"] - unless requested_cipher == ALGORITHM - raise UnsupportedCipher, - "Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}']" - end - end - - end - - class Version2Decryptor < Version1Decryptor - - def decrypted_data - validate_hmac! unless @decrypted_data - super - end - - def validate_hmac! - digest = OpenSSL::Digest::Digest.new("sha256") - raw_hmac = OpenSSL::HMAC.digest(digest, key, @encrypted_data["encrypted_data"]) - - if candidate_hmac_matches?(raw_hmac) - true - else - raise DecryptionFailure, "Error decrypting data bag value: invalid hmac. Most likely the provided key is incorrect" - end - end - - private - - def candidate_hmac_matches?(expected_hmac) - return false unless @encrypted_data["hmac"] - expected_bytes = expected_hmac.bytes.to_a - candidate_hmac_bytes = Base64.decode64(@encrypted_data["hmac"]).bytes.to_a - valid = expected_bytes.size ^ candidate_hmac_bytes.size - expected_bytes.zip(candidate_hmac_bytes) { |x, y| valid |= x ^ y.to_i } - valid == 0 - end - end - - class Version0Decryptor - - attr_reader :encrypted_data - attr_reader :key - - def initialize(encrypted_data, key) - @encrypted_data = encrypted_data - @key = key - end - - def for_decrypted_item - YAML.load(decrypted_data) - end - - def decrypted_data - @decrypted_data ||= begin - plaintext = openssl_decryptor.update(encrypted_bytes) - plaintext << openssl_decryptor.final - rescue OpenSSL::Cipher::CipherError => e - raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect" - end - end - - def encrypted_bytes - Base64.decode64(@encrypted_data) - end - - def openssl_decryptor - @openssl_decryptor ||= begin - d = OpenSSL::Cipher::Cipher.new(ALGORITHM) - d.decrypt - d.pkcs5_keyivgen(key) - d - end - end - end - end - def initialize(enc_hash, secret) @enc_hash = enc_hash @secret = secret diff --git a/lib/chef/encrypted_data_bag_item/decryption_failure.rb b/lib/chef/encrypted_data_bag_item/decryption_failure.rb new file mode 100644 index 0000000000..47d263f197 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/decryption_failure.rb @@ -0,0 +1,22 @@ +# +# Author:: Seth Falcon (<seth@opscode.com>) +# Copyright:: Copyright 2010-2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class Chef::EncryptedDataBagItem + class DecryptionFailure < StandardError + end +end diff --git a/lib/chef/encrypted_data_bag_item/decryptor.rb b/lib/chef/encrypted_data_bag_item/decryptor.rb new file mode 100644 index 0000000000..9ee38a12c4 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/decryptor.rb @@ -0,0 +1,201 @@ +# +# Author:: Seth Falcon (<seth@opscode.com>) +# Copyright:: Copyright 2010-2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'yaml' +require 'yajl' +require 'openssl' +require 'base64' +require 'digest/sha2' +require 'chef/encrypted_data_bag_item' +require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format' +require 'chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format' +require 'chef/encrypted_data_bag_item/decryption_failure' +require 'chef/encrypted_data_bag_item/unsupported_cipher' + +class Chef::EncryptedDataBagItem + + #=== Decryptor + # For backwards compatibility, Chef implements decryption/deserialization for + # older encrypted data bag item formats in addition to the current version. + # Each decryption/deserialization strategy is implemented as a class in this + # namespace. For convenience the factory method +Decryptor.for()+ can be used + # to create an instance of the appropriate strategy for the given encrypted + # data bag value. + module Decryptor + + # Detects the encrypted data bag item format version and instantiates a + # decryptor object for that version. Call #for_decrypted_item on the + # resulting object to decrypt and deserialize it. + def self.for(encrypted_value, key) + format_version = format_version_of(encrypted_value) + assert_format_version_acceptable!(format_version) + case format_version + when 2 + Version2Decryptor.new(encrypted_value, key) + when 1 + Version1Decryptor.new(encrypted_value, key) + when 0 + Version0Decryptor.new(encrypted_value, key) + else + raise UnsupportedEncryptedDataBagItemFormat, + "This version of chef does not support encrypted data bag item format version '#{format_version}'" + end + end + + def self.format_version_of(encrypted_value) + if encrypted_value.respond_to?(:key?) + encrypted_value["version"] + else + 0 + end + end + + def self.assert_format_version_acceptable!(format_version) + unless format_version.kind_of?(Integer) and format_version >= Chef::Config[:data_bag_decrypt_minimum_version] + raise UnacceptableEncryptedDataBagItemFormat, + "The encrypted data bag item has format version `#{format_version}', " + + "but the config setting 'data_bag_decrypt_minimum_version' requires version `#{Chef::Config[:data_bag_decrypt_minimum_version]}'" + end + end + + class Version0Decryptor + + attr_reader :encrypted_data + attr_reader :key + + def initialize(encrypted_data, key) + @encrypted_data = encrypted_data + @key = key + end + + def for_decrypted_item + YAML.load(decrypted_data) + end + + def decrypted_data + @decrypted_data ||= begin + plaintext = openssl_decryptor.update(encrypted_bytes) + plaintext << openssl_decryptor.final + rescue OpenSSL::Cipher::CipherError => e + raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect" + end + end + + def encrypted_bytes + Base64.decode64(@encrypted_data) + end + + def openssl_decryptor + @openssl_decryptor ||= begin + d = OpenSSL::Cipher::Cipher.new(ALGORITHM) + d.decrypt + d.pkcs5_keyivgen(key) + d + end + end + end + + class Version1Decryptor + + attr_reader :encrypted_data + attr_reader :key + + def initialize(encrypted_data, key) + @encrypted_data = encrypted_data + @key = key + end + + def for_decrypted_item + Yajl::Parser.parse(decrypted_data)["json_wrapper"] + rescue Yajl::ParseError + # convert to a DecryptionFailure error because the most likely scenario + # here is that the decryption step was unsuccessful but returned bad + # data rather than raising an error. + raise DecryptionFailure, "Error decrypting data bag value. Most likely the provided key is incorrect" + end + + def encrypted_bytes + Base64.decode64(@encrypted_data["encrypted_data"]) + end + + def iv + Base64.decode64(@encrypted_data["iv"]) + end + + def decrypted_data + @decrypted_data ||= begin + plaintext = openssl_decryptor.update(encrypted_bytes) + plaintext << openssl_decryptor.final + rescue OpenSSL::Cipher::CipherError => e + raise DecryptionFailure, "Error decrypting data bag value: '#{e.message}'. Most likely the provided key is incorrect" + end + end + + def openssl_decryptor + @openssl_decryptor ||= begin + assert_valid_cipher! + d = OpenSSL::Cipher::Cipher.new(ALGORITHM) + d.decrypt + d.key = Digest::SHA256.digest(key) + d.iv = iv + d + end + end + + def assert_valid_cipher! + # In the future, chef may support configurable ciphers. For now, only + # aes-256-cbc is supported. + requested_cipher = @encrypted_data["cipher"] + unless requested_cipher == ALGORITHM + raise UnsupportedCipher, + "Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}']" + end + end + end + + class Version2Decryptor < Version1Decryptor + + def decrypted_data + validate_hmac! unless @decrypted_data + super + end + + def validate_hmac! + digest = OpenSSL::Digest::Digest.new("sha256") + raw_hmac = OpenSSL::HMAC.digest(digest, key, @encrypted_data["encrypted_data"]) + + if candidate_hmac_matches?(raw_hmac) + true + else + raise DecryptionFailure, "Error decrypting data bag value: invalid hmac. Most likely the provided key is incorrect" + end + end + + private + + def candidate_hmac_matches?(expected_hmac) + return false unless @encrypted_data["hmac"] + expected_bytes = expected_hmac.bytes.to_a + candidate_hmac_bytes = Base64.decode64(@encrypted_data["hmac"]).bytes.to_a + valid = expected_bytes.size ^ candidate_hmac_bytes.size + expected_bytes.zip(candidate_hmac_bytes) { |x, y| valid |= x ^ y.to_i } + valid == 0 + end + end + end +end diff --git a/lib/chef/encrypted_data_bag_item/encryptor.rb b/lib/chef/encrypted_data_bag_item/encryptor.rb new file mode 100644 index 0000000000..f99c913c62 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/encryptor.rb @@ -0,0 +1,142 @@ +# +# Author:: Seth Falcon (<seth@opscode.com>) +# Copyright:: Copyright 2010-2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'base64' +require 'digest/sha2' +require 'openssl' +require 'yajl' +require 'chef/encrypted_data_bag_item' +require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format' + +class Chef::EncryptedDataBagItem + + # Implementation class for converting plaintext data bag item values to an + # encrypted value, including any necessary wrappers and metadata. + module Encryptor + + # "factory" method that creates an encryptor object with the proper class + # for the desired encrypted data bag format version. + # + # +Chef::Config[:data_bag_encrypt_version]+ determines which version is used. + def self.new(value, secret, iv=nil) + format_version = Chef::Config[:data_bag_encrypt_version] + case format_version + when 1 + Version1Encryptor.new(value, secret, iv) + when 2 + Version2Encryptor.new(value, secret, iv) + else + raise UnsupportedEncryptedDataBagItemFormat, + "Invalid encrypted data bag format version `#{format_version}'. Supported versions are '1', '2'" + end + end + + class Version1Encryptor + attr_reader :key + attr_reader :plaintext_data + + # Create a new Encryptor for +data+, which will be encrypted with the given + # +key+. + # + # === Arguments: + # * data: An object of any type that can be serialized to json + # * key: A String representing the desired passphrase + # * iv: The optional +iv+ parameter is intended for testing use only. When + # *not* supplied, Encryptor will use OpenSSL to generate a secure random + # IV, which is what you want. + def initialize(plaintext_data, key, iv=nil) + @plaintext_data = plaintext_data + @key = key + @iv = iv && Base64.decode64(iv) + end + + # Returns a wrapped and encrypted version of +plaintext_data+ suitable for + # using as the value in an encrypted data bag item. + def for_encrypted_item + { + "encrypted_data" => encrypted_data, + "iv" => Base64.encode64(iv), + "version" => 1, + "cipher" => ALGORITHM + } + end + + # Generates or returns the IV. + def iv + # Generated IV comes from OpenSSL::Cipher::Cipher#random_iv + # This gets generated when +openssl_encryptor+ gets created. + openssl_encryptor if @iv.nil? + @iv + end + + # Generates (and memoizes) an OpenSSL::Cipher::Cipher object and configures + # it for the specified iv and encryption key. + def openssl_encryptor + @openssl_encryptor ||= begin + encryptor = OpenSSL::Cipher::Cipher.new(ALGORITHM) + encryptor.encrypt + @iv ||= encryptor.random_iv + encryptor.iv = @iv + encryptor.key = Digest::SHA256.digest(key) + encryptor + end + end + + # Encrypts and Base64 encodes +serialized_data+ + def encrypted_data + @encrypted_data ||= begin + enc_data = openssl_encryptor.update(serialized_data) + enc_data << openssl_encryptor.final + Base64.encode64(enc_data) + end + end + + # Wraps the data in a single key Hash (JSON Object) and converts to JSON. + # The wrapper is required because we accept values (such as Integers or + # Strings) that do not produce valid JSON when serialized without the + # wrapper. + def serialized_data + Yajl::Encoder.encode(:json_wrapper => plaintext_data) + end + end + + class Version2Encryptor < Version1Encryptor + + # Returns a wrapped and encrypted version of +plaintext_data+ suitable for + # using as the value in an encrypted data bag item. + def for_encrypted_item + { + "encrypted_data" => encrypted_data, + "hmac" => hmac, + "iv" => Base64.encode64(iv), + "version" => 2, + "cipher" => ALGORITHM + } + end + + # Generates an HMAC-SHA2-256 of the encrypted data (encrypt-then-mac) + def hmac + @hmac ||= begin + digest = OpenSSL::Digest::Digest.new("sha256") + raw_hmac = OpenSSL::HMAC.digest(digest, key, encrypted_data) + Base64.encode64(raw_hmac) + end + end + end + end +end diff --git a/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb b/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb new file mode 100644 index 0000000000..2f3b07c7f3 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/unacceptable_encrypted_data_bag_item_format.rb @@ -0,0 +1,22 @@ +# +# Author:: Seth Falcon (<seth@opscode.com>) +# Copyright:: Copyright 2010-2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class Chef::EncryptedDataBagItem + class UnacceptableEncryptedDataBagItemFormat < StandardError + end +end diff --git a/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb b/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb new file mode 100644 index 0000000000..1df5cd5efd --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/unsupported_cipher.rb @@ -0,0 +1,22 @@ +# +# Author:: Seth Falcon (<seth@opscode.com>) +# Copyright:: Copyright 2010-2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class Chef::EncryptedDataBagItem + class UnsupportedCipher < StandardError + end +end diff --git a/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb b/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb new file mode 100644 index 0000000000..e7cf087307 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format.rb @@ -0,0 +1,22 @@ +# +# Author:: Seth Falcon (<seth@opscode.com>) +# Copyright:: Copyright 2010-2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class Chef::EncryptedDataBagItem + class UnsupportedEncryptedDataBagItemFormat < StandardError + end +end |