diff options
author | Xabier de Zuazo <xabier@onddo.com> | 2014-07-06 21:07:42 +0200 |
---|---|---|
committer | Xabier de Zuazo <xabier@onddo.com> | 2014-07-06 21:07:42 +0200 |
commit | 67fe30df3a5700927788b363fbcbf9423ceeb3d2 (patch) | |
tree | e8acd191a921205eb33aa2a87452ea2bd0c778cd /lib/chef/encrypted_data_bag_item | |
parent | 1864ec8293923210738cca0c11aef5b96786cb86 (diff) | |
download | chef-67fe30df3a5700927788b363fbcbf9423ceeb3d2.tar.gz |
[CHEF-5356-gcm] If the requirements to use Encryted Data Bags 3 are not met, give a meaningful error message
Diffstat (limited to 'lib/chef/encrypted_data_bag_item')
4 files changed, 106 insertions, 18 deletions
diff --git a/lib/chef/encrypted_data_bag_item/assertions.rb b/lib/chef/encrypted_data_bag_item/assertions.rb new file mode 100644 index 0000000000..6e90008523 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/assertions.rb @@ -0,0 +1,54 @@ +# +# Author:: Xabier de Zuazo (<xabier@onddo.com>) +# Copyright:: Copyright (c) 2014 Onddo Labs, SL. +# 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 EncryptedDataBagRequirementsFailure < StandardError + end + + module Assertions + + def 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 + + def assert_valid_cipher!(requested_cipher, algorithm) + # In the future, chef may support configurable ciphers. For now, only + # aes-256-cbc and aes-256-gcm are supported. + unless requested_cipher == algorithm + raise UnsupportedCipher, + "Cipher '#{requested_cipher}' is not supported by this version of Chef. Available ciphers: ['#{ALGORITHM}', '#{AEAD_ALGORITHM}']" + end + end + + def assert_aead_requirements_met!(algorithm) + unless OpenSSL::Cipher::Cipher.method_defined?(:auth_data=) + raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires Ruby >= 1.9" + end + unless OpenSSL::Cipher::Cipher.ciphers.include?(algorithm) + raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires an OpenSSL version with \"#{algorithm}\" algorithm support" + end + end + + end + +end diff --git a/lib/chef/encrypted_data_bag_item/decryptor.rb b/lib/chef/encrypted_data_bag_item/decryptor.rb index 82d04c0d67..b269868c53 100644 --- a/lib/chef/encrypted_data_bag_item/decryptor.rb +++ b/lib/chef/encrypted_data_bag_item/decryptor.rb @@ -26,6 +26,7 @@ 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' +require 'chef/encrypted_data_bag_item/assertions' class Chef::EncryptedDataBagItem @@ -37,6 +38,7 @@ class Chef::EncryptedDataBagItem # to create an instance of the appropriate strategy for the given encrypted # data bag value. module Decryptor + extend Chef::EncryptedDataBagItem::Assertions # Detects the encrypted data bag item format version and instantiates a # decryptor object for that version. Call #for_decrypted_item on the @@ -67,15 +69,8 @@ class Chef::EncryptedDataBagItem 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 + include Chef::EncryptedDataBagItem::Assertions attr_reader :encrypted_data attr_reader :key @@ -155,7 +150,7 @@ class Chef::EncryptedDataBagItem def openssl_decryptor @openssl_decryptor ||= begin - assert_valid_cipher! + assert_valid_cipher!(@encrypted_data["cipher"], algorithm) d = OpenSSL::Cipher::Cipher.new(algorithm) d.decrypt # We must set key before iv: https://bugs.ruby-lang.org/issues/8221 @@ -165,15 +160,6 @@ class Chef::EncryptedDataBagItem end end - def assert_valid_cipher! - # In the future, chef may support configurable ciphers. For now, only - # aes-256-cbc and aes-256-gcm are 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}', '#{AEAD_ALGORITHM}']" - end - end end class Version2Decryptor < Version1Decryptor @@ -208,6 +194,12 @@ class Chef::EncryptedDataBagItem class Version3Decryptor < Version1Decryptor + def initialize(encrypted_data, key) + super + assert_aead_requirements_met!(algorithm) + end + + # Returns the used decryption algorithm def algorithm AEAD_ALGORITHM diff --git a/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb b/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb new file mode 100644 index 0000000000..4d116715f6 --- /dev/null +++ b/lib/chef/encrypted_data_bag_item/encrypted_data_bag_item_assertions.rb @@ -0,0 +1,37 @@ +# +# Author:: Xabier de Zuazo (<xabier@onddo.com>) +# Copyright:: Copyright (c) 2014 Onddo Labs, SL. +# 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 EncryptedDataBagRequirementsFailure < StandardError + end + + module Assertions + + def assert_requirements_met! + unless OpenSSL::Cipher::Cipher.method_defined?(:auth_data=) + raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires Ruby >= 1.9" + end + unless OpenSSL::Cipher::Cipher.ciphers.include?(algorithm) + raise EncryptedDataBagRequirementsFailure, "The used Encrypted Data Bags version requires an OpenSSL version with \"#{algorithm}\" algorithm support" + end + end + + end + +end diff --git a/lib/chef/encrypted_data_bag_item/encryptor.rb b/lib/chef/encrypted_data_bag_item/encryptor.rb index a3f3011c21..5b4eaa7c98 100644 --- a/lib/chef/encrypted_data_bag_item/encryptor.rb +++ b/lib/chef/encrypted_data_bag_item/encryptor.rb @@ -23,6 +23,7 @@ require 'ffi_yajl' require 'chef/encrypted_data_bag_item' require 'chef/encrypted_data_bag_item/unsupported_encrypted_data_bag_item_format' require 'chef/encrypted_data_bag_item/encryption_failure' +require 'chef/encrypted_data_bag_item/assertions' class Chef::EncryptedDataBagItem @@ -53,6 +54,8 @@ class Chef::EncryptedDataBagItem attr_reader :key attr_reader :plaintext_data + include Chef::EncryptedDataBagItem::Assertions + # Create a new Encryptor for +data+, which will be encrypted with the given # +key+. # @@ -149,9 +152,11 @@ class Chef::EncryptedDataBagItem end class Version3Encryptor < Version1Encryptor + include Chef::EncryptedDataBagItem::Assertions def initialize(plaintext_data, key, iv=nil) super + assert_aead_requirements_met!(algorithm) @auth_tag = nil end |