diff options
author | Tim Smith <tsmith@chef.io> | 2018-01-22 07:44:28 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-22 07:44:28 -0800 |
commit | 9ef5c2d239b2501cad5fc01bdfc9d617ddef5430 (patch) | |
tree | 899d755703c7e861bdc9f0e0e7eba066842db7b2 | |
parent | 84fb46aeb7e6c457665dc4bf5ac5719b4f5eefd5 (diff) | |
parent | 1a88d51c49b23365c8af5c6a6f5a9306eccae225 (diff) | |
download | chef-9ef5c2d239b2501cad5fc01bdfc9d617ddef5430.tar.gz |
Merge pull request #6736 from chef/openssl_resources
Add dhparam, rsa_private_key and rsa_public_key resources
-rw-r--r-- | kitchen-tests/cookbooks/base/recipes/default.rb | 20 | ||||
-rw-r--r-- | lib/chef/mixin/openssl.rb | 118 | ||||
-rw-r--r-- | lib/chef/resource/openssl_dhparam.rb | 59 | ||||
-rw-r--r-- | lib/chef/resource/openssl_rsa_private_key.rb | 69 | ||||
-rw-r--r-- | lib/chef/resource/openssl_rsa_public_key.rb | 56 | ||||
-rw-r--r-- | lib/chef/resources.rb | 3 | ||||
-rw-r--r-- | spec/unit/mixin/openssl_spec.rb | 252 | ||||
-rw-r--r-- | spec/unit/resource/openssl_dhparam.rb | 51 | ||||
-rw-r--r-- | spec/unit/resource/openssl_rsa_private_key.rb | 59 | ||||
-rw-r--r-- | spec/unit/resource/openssl_rsa_public_key.rb | 39 |
10 files changed, 726 insertions, 0 deletions
diff --git a/kitchen-tests/cookbooks/base/recipes/default.rb b/kitchen-tests/cookbooks/base/recipes/default.rb index 8b0eac0e6e..1811245b13 100644 --- a/kitchen-tests/cookbooks/base/recipes/default.rb +++ b/kitchen-tests/cookbooks/base/recipes/default.rb @@ -60,4 +60,24 @@ include_recipe "cron" include_recipe "git" +directory "/etc/ssl" + +# Generate new key and certificate +openssl_dhparam "/etc/ssl/dhparam.pem" do + key_length 1024 + action :create +end + +# Generate new key with aes-128-cbc cipher +openssl_rsa_private_key "/etc/ssl/rsakey_aes128cbc.pem" do + key_length 1024 + key_cipher "aes-128-cbc" + action :create +end + +openssl_rsa_public_key "/etc/ssl/rsakey_aes128cbc.pub" do + private_key_path "/etc/ssl/rsakey_aes128cbc.pem" + action :create +end + include_recipe "::tests" diff --git a/lib/chef/mixin/openssl.rb b/lib/chef/mixin/openssl.rb new file mode 100644 index 0000000000..e868da9ac4 --- /dev/null +++ b/lib/chef/mixin/openssl.rb @@ -0,0 +1,118 @@ +# +# Copyright:: Copyright 2013-2018, Chef Software 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 + module Mixin + module OpenSSL + def self.included(_base) + require "openssl" unless defined?(::OpenSSL) + end + + # determine the key filename from the cert filename + # @param [String] cert_filename the path to the certfile + # @return [String] the path to the keyfile + def get_key_filename(cert_filename) + cert_file_path, cert_filename = ::File.split(cert_filename) + cert_filename = ::File.basename(cert_filename, ::File.extname(cert_filename)) + cert_file_path + ::File::SEPARATOR + cert_filename + ".key" + end + + # is the key length a valid key length + # @param [Integer] number + # @return [Boolean] is length valid + def key_length_valid?(number) + number >= 1024 && ( number & (number - 1) == 0 ) + end + + # validate a dhparam file from path + # @param [String] dhparam_pem_path the path to the pem file + # @return [Boolean] is the key valid + def dhparam_pem_valid?(dhparam_pem_path) + # Check if the dhparam.pem file exists + # Verify the dhparam.pem file contains a key + return false unless ::File.exist?(dhparam_pem_path) + dhparam = ::OpenSSL::PKey::DH.new File.read(dhparam_pem_path) + dhparam.params_ok? + end + + # given either a key file path or key file content see if it's actually + # a private key + # @param [String] key_file the path to the keyfile or the key contents + # @param [String] key_password optional password to the keyfile + # @return [Boolean] is the key valid? + def priv_key_file_valid?(key_file, key_password = nil) + # if the file exists try to read the content + # if not assume we were passed the key and set the string to the content + key_content = ::File.exist?(key_file) ? File.read(key_file) : key_file + + begin + key = ::OpenSSL::PKey::RSA.new key_content, key_password + rescue ::OpenSSL::PKey::RSAError + return false + end + key.private? + end + + # generate a dhparam file + # @param [String] key_length the length of the key + # @param [Integer] generator the dhparam generator to use + # @return [OpenSSL::PKey::DH] + def gen_dhparam(key_length, generator) + raise ArgumentError, "Key length must be a power of 2 greater than or equal to 1024" unless key_length_valid?(key_length) + raise TypeError, "Generator must be an integer" unless generator.is_a?(Integer) + + ::OpenSSL::PKey::DH.new(key_length, generator) + end + + # generate an RSA private key given key length + # @param [Integer] key_length the key length of the private key + # @return [OpenSSL::PKey::DH] + def gen_rsa_priv_key(key_length) + raise ArgumentError, "Key length must be a power of 2 greater than or equal to 1024" unless key_length_valid?(key_length) + + ::OpenSSL::PKey::RSA.new(key_length) + end + + # generate pem format of the public key given a private key + # @param [String] priv_key either the contents of the private key or the path to the file + # @param [String] priv_key_password optional password for the private key + # @return [String] pem format of the public key + def gen_rsa_pub_key(priv_key, priv_key_password = nil) + # if the file exists try to read the content + # if not assume we were passed the key and set the string to the content + key_content = ::File.exist?(priv_key) ? File.read(priv_key) : priv_key + key = ::OpenSSL::PKey::RSA.new key_content, priv_key_password + key.public_key.to_pem + end + + # generate a pem file given a cipher, key, an optional key_password + # @param [OpenSSL::PKey::RSA] rsa_key the private key object + # @param [String] key_password the password for the private key + # @param [String] key_cipher the cipher to use + # @return [String] pem contents + def encrypt_rsa_key(rsa_key, key_password, key_cipher) + raise TypeError, "rsa_key must be a Ruby OpenSSL::PKey::RSA object" unless rsa_key.is_a?(::OpenSSL::PKey::RSA) + raise TypeError, "key_password must be a string" unless key_password.is_a?(String) + raise TypeError, "key_cipher must be a string" unless key_cipher.is_a?(String) + raise ArgumentError, "Specified key_cipher is not available on this system" unless ::OpenSSL::Cipher.ciphers.include?(key_cipher) + + cipher = ::OpenSSL::Cipher.new(key_cipher) + rsa_key.to_pem(cipher, key_password) + end + end + end +end diff --git a/lib/chef/resource/openssl_dhparam.rb b/lib/chef/resource/openssl_dhparam.rb new file mode 100644 index 0000000000..cec27d21bd --- /dev/null +++ b/lib/chef/resource/openssl_dhparam.rb @@ -0,0 +1,59 @@ +# +# Copyright:: Copyright 2009-2018, Chef Software 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 "chef/resource" + +class Chef + class Resource + # a resource for generating dhparam.pem files. + # If a valid dhparam.pem file is found at the specified location, no new + # file will be created. If a file is found at the specified location but it + # is not a valid dhparam file, it will be overwritten. + # + # @since 14.0 + class OpensslDhparam < Chef::Resource + require "chef/mixin/openssl" + include Chef::Mixin::OpenSSL + + resource_name :openssl_dhparam + + property :path, String, name_property: true + property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 + property :generator, equal_to: [2, 5], default: 2 + property :owner, [String, nil] + property :group, [String, nil] + property :mode, [Integer, String], default: "0640" + + action :create do + unless dhparam_pem_valid?(new_resource.path) + converge_by("Create a dhparam file #{new_resource.path}") do + dhparam_content = gen_dhparam(new_resource.key_length, new_resource.generator).to_pem + + declare_resource(:file, new_resource.path) do + action :create + owner new_resource.owner unless new_resource.owner.nil? + group new_resource.group unless new_resource.group.nil? + mode new_resource.mode + sensitive true + content dhparam_content + end + end + end + end + end + end +end diff --git a/lib/chef/resource/openssl_rsa_private_key.rb b/lib/chef/resource/openssl_rsa_private_key.rb new file mode 100644 index 0000000000..32c394846b --- /dev/null +++ b/lib/chef/resource/openssl_rsa_private_key.rb @@ -0,0 +1,69 @@ +# +# Copyright:: Copyright 2009-2018, Chef Software 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 "chef/resource" + +class Chef + class Resource + # A resource for generating rsa private key files. + # If a valid rsa key file can be opened at the specified location, no new file + # will be created. If the RSA key file cannot be opened, either because it + # does not exist or because the password to the RSA key file does not match + # the password in the recipe, it will be overwritten. + # + # @since 14.0 + class OpensslRsaPrivateKey < Chef::Resource + require "chef/mixin/openssl" + include Chef::Mixin::OpenSSL + + resource_name :openssl_rsa_private_key + provides :openssl_rsa_private_key + provides :openssl_rsa_key # legacy cookbook resource name + + property :path, String, name_property: true + property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 + property :key_pass, String + property :key_cipher, String, default: "des3", equal_to: OpenSSL::Cipher.ciphers + property :owner, [String, nil] + property :group, [String, nil] + property :mode, [Integer, String], default: "0600" + property :force, [true, false], default: false + + action :create do + return if new_resource.force || priv_key_file_valid?(new_resource.path, new_resource.key_pass) + + converge_by("create #{new_resource.key_length} bit RSA key #{new_resource.path}") do + if new_resource.key_pass + unencrypted_rsa_key = gen_rsa_priv_key(new_resource.key_length) + rsa_key_content = encrypt_rsa_key(unencrypted_rsa_key, new_resource.key_pass, new_resource.key_cipher) + else + rsa_key_content = gen_rsa_priv_key(new_resource.key_length).to_pem + end + + declare_resource(:file, new_resource.path) do + action :create + owner new_resource.owner unless new_resource.owner.nil? + group new_resource.group unless new_resource.group.nil? + mode new_resource.mode + sensitive true + content rsa_key_content + end + end + end + end + end +end diff --git a/lib/chef/resource/openssl_rsa_public_key.rb b/lib/chef/resource/openssl_rsa_public_key.rb new file mode 100644 index 0000000000..602b48065e --- /dev/null +++ b/lib/chef/resource/openssl_rsa_public_key.rb @@ -0,0 +1,56 @@ +# +# Copyright:: Copyright 2009-2018, Chef Software 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 "chef/resource" + +class Chef + class Resource + # A resource for generating rsa public key files given a rsa private key. + # + # @since 14.0 + class OpensslRsaPublicKey < Chef::Resource + require "chef/mixin/openssl" + include Chef::Mixin::OpenSSL + + resource_name :openssl_rsa_public_key + + property :path, String, name_property: true + property :private_key_path, String + property :private_key_content, String + property :private_key_pass, String + property :owner, [String, nil] + property :group, [String, nil] + property :mode, [Integer, String], default: "0640" + + action :create do + raise ArgumentError, "You cannot specify both 'private_key_path' and 'private_key_content' properties at the same time." if new_resource.private_key_path && new_resource.private_key_content + raise ArgumentError, "You must specify the private key with either 'private_key_path' or 'private_key_content' properties." unless new_resource.private_key_path || new_resource.private_key_content + raise "#{new_resource.private_key_path} not a valid private RSA key or password is invalid" unless priv_key_file_valid?((new_resource.private_key_path || new_resource.private_key_content), new_resource.private_key_pass) + + rsa_key_content = gen_rsa_pub_key((new_resource.private_key_path || new_resource.private_key_content), new_resource.private_key_pass) + + declare_resource(:file, new_resource.path) do + action :create + owner new_resource.owner unless new_resource.owner.nil? + group new_resource.group unless new_resource.group.nil? + mode new_resource.mode + content rsa_key_content + end + end + end + end +end diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index 0723f1b45a..9fee978432 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -53,6 +53,9 @@ require "chef/resource/mdadm" require "chef/resource/mount" require "chef/resource/ohai" require "chef/resource/openbsd_package" +require "chef/resource/openssl_dhparam" +require "chef/resource/openssl_rsa_private_key" +require "chef/resource/openssl_rsa_public_key" require "chef/resource/package" require "chef/resource/pacman_package" require "chef/resource/paludis_package" diff --git a/spec/unit/mixin/openssl_spec.rb b/spec/unit/mixin/openssl_spec.rb new file mode 100644 index 0000000000..8a0206116c --- /dev/null +++ b/spec/unit/mixin/openssl_spec.rb @@ -0,0 +1,252 @@ +# +# Copyright 2009-2018, Chef Software, Inc <legal@chef.io> +# +# 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 "spec_helper" +require "chef/mixin/openssl" + +describe Chef::Mixin::OpenSSL do + let(:instance) do + Class.new { include Chef::Mixin::OpenSSL }.new + end + + describe ".included" do + it "requires openssl" do + instance + expect(defined?(OpenSSL)).to_not be(false) + end + end + + # Path helpers + describe "#get_key_filename" do + context "When the input is not a string" do + it "Throws a TypeError" do + expect do + instance.get_key_filename(33) + end.to raise_error(TypeError) + end + end + + context "when the input is a string" do + it "Generates valid keyfile names" do + expect(instance.get_key_filename("/etc/temp.crt")).to match("/etc/temp.key") + end + end + end + + # Validation helpers + describe "#key_length_valid?" do + context "When the number is less than 1024" do + it "returns false" do + expect(instance.key_length_valid?(1023)).to be_falsey + expect(instance.key_length_valid?(2)).to be_falsey + expect(instance.key_length_valid?(64)).to be_falsey + expect(instance.key_length_valid?(512)).to be_falsey + end + end + + context "When the number is greater than 1024 but is not a power of 2" do + it "returns false" do + expect(instance.key_length_valid?(1025)).to be_falsey + expect(instance.key_length_valid?(6666)).to be_falsey + expect(instance.key_length_valid?(8191)).to be_falsey + end + end + + context "When the number is a power of 2, equal to or greater than 1024" do + it "returns true" do + expect(instance.key_length_valid?(1024)).to be_truthy + expect(instance.key_length_valid?(2048)).to be_truthy + expect(instance.key_length_valid?(4096)).to be_truthy + expect(instance.key_length_valid?(8192)).to be_truthy + end + end + end + + describe "#dhparam_pem_valid?" do + require "tempfile" + + before(:each) do + @dhparam_file = Tempfile.new("dhparam") + end + + context "When the dhparam.pem file does not exist" do + it "returns false" do + expect(instance.dhparam_pem_valid?("/tmp/bad_filename")).to be_falsey + end + end + + context "When the dhparam.pem file does exist, but does not contain a valid dhparam key" do + it "Throws an OpenSSL::PKey::DHError exception" do + expect do + @dhparam_file.puts("I_am_not_a_key_I_am_a_free_man") + @dhparam_file.close + instance.dhparam_pem_valid?(@dhparam_file.path) + end.to raise_error(::OpenSSL::PKey::DHError) + end + end + + context "When the dhparam.pem file does exist, and does contain a vaild dhparam key" do + it "returns true" do + @dhparam_file.puts(::OpenSSL::PKey::DH.new(1024).to_pem) + @dhparam_file.close + expect(instance.dhparam_pem_valid?(@dhparam_file.path)).to be_truthy + end + end + + after(:each) do + @dhparam_file.unlink + end + end + + describe "#priv_key_file_valid?" do + require "tempfile" + require "openssl" unless defined?(OpenSSL) + + cipher = ::OpenSSL::Cipher.new("des3") + + before(:each) do + @keyfile = Tempfile.new("keyfile") + end + + context "When the key file does not exist" do + it "returns false" do + expect(instance.priv_key_file_valid?("/tmp/bad_filename")).to be_falsey + end + end + + context "When the key file does exist, but does not contain a valid rsa private key" do + it "Throws an OpenSSL::PKey::RSAError exception" do + @keyfile.write("I_am_not_a_key_I_am_a_free_man") + @keyfile.close + expect(instance.priv_key_file_valid?(@keyfile.path)).to be_falsey + end + end + + context "When the key file does exist, and does contain a vaild rsa private key" do + it "returns true" do + @keyfile.write(::OpenSSL::PKey::RSA.new(1024).to_pem) + @keyfile.close + expect(instance.priv_key_file_valid?(@keyfile.path)).to be_truthy + end + end + + context "When a valid keyfile requires a passphrase, and an invalid passphrase is supplied" do + it "returns false" do + @keyfile.write(::OpenSSL::PKey::RSA.new(1024).to_pem(cipher, "oink")) + @keyfile.close + expect(instance.priv_key_file_valid?(@keyfile.path, "poml")).to be_falsey + end + end + + context "When a valid keyfile requires a passphrase, and a valid passphrase is supplied" do + it "returns true" do + @keyfile.write(::OpenSSL::PKey::RSA.new(1024).to_pem(cipher, "oink")) + @keyfile.close + expect(instance.priv_key_file_valid?(@keyfile.path, "oink")).to be_truthy + end + end + + after(:each) do + @keyfile.unlink + end + end + + # Generators + describe "#gen_dhparam" do + context "When given an invalid key length" do + it "Throws an ArgumentError" do + expect do + instance.gen_dhparam(2046, 2) + end.to raise_error(ArgumentError) + end + end + + context "When given an invalid generator id" do + it "Throws a TypeError" do + expect do + instance.gen_dhparam(2048, "bob") + end.to raise_error(TypeError) + end + end + + context "When a proper key length and generator id are given" do + it "Generates a dhparam object" do + expect(instance.gen_dhparam(1024, 2)).to be_kind_of(::OpenSSL::PKey::DH) + end + end + end + + describe "#gen_rsa_priv_key" do + context "When given an invalid key length" do + it "Throws an ArgumentError" do + expect do + instance.gen_rsa_priv_key(4093) + end.to raise_error(ArgumentError) + end + end + + context "When a proper key length is given" do + it "Generates an RSA key object" do + expect(instance.gen_rsa_priv_key(1024)).to be_kind_of(::OpenSSL::PKey::RSA) + end + end + end + + describe "#encrypt_rsa_key" do + before(:all) do + @rsa_key = ::OpenSSL::PKey::RSA.new(1024) + end + + context "When given anything other than an RSA key object to encrypt" do + it "Raises a TypeError" do + expect do + instance.encrypt_rsa_key("abcd", "efgh", "des3") + end.to raise_error(TypeError) + end + end + + context "When given anything other than a string as the passphrase" do + it "Raises a TypeError" do + expect do + instance.encrypt_rsa_key(@rsa_key, 1234, "des3") + end.to raise_error(TypeError) + end + end + + context "When given anything other than a string as the cipher" do + it "Raises a TypeError" do + expect do + instance.encrypt_rsa_key(@rsa_key, "1234", 1234) + end.to raise_error(TypeError) + end + end + + context "When given an invalid cipher string" do + it "Raises an ArgumentError" do + expect do + instance.encrypt_rsa_key(@rsa_key, "1234", "des3_bogus") + end.to raise_error(ArgumentError) + end + end + + context "When given a valid RSA key and a valid passphrase string" do + it "Generates a valid encrypted PEM" do + @encrypted_key = instance.encrypt_rsa_key(@rsa_key, "oink", "des3") + expect(@encrypted_key).to be_kind_of(String) + expect(::OpenSSL::PKey::RSA.new(@encrypted_key, "oink").private?).to be_truthy + end + end + end +end diff --git a/spec/unit/resource/openssl_dhparam.rb b/spec/unit/resource/openssl_dhparam.rb new file mode 100644 index 0000000000..d1021d4f7e --- /dev/null +++ b/spec/unit/resource/openssl_dhparam.rb @@ -0,0 +1,51 @@ +# +# Copyright:: Copyright 2018, Chef Software, 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 "spec_helper" + +describe Chef::Resource::OpensslDhparam do + + let(:resource) { Chef::Resource::OpensslDhparam.new("dhparam") } + + it "has a resource name of :openssl_dhparam" do + expect(resource.resource_name).to eql(:openssl_dhparam) + end + + it "has a default action of create" do + expect(resource.action).to eql([:create]) + end + + it "has a default mode of '0640'" do + expect(resource.mode).to eql("0640") + end + + it "has a default generator of 2" do + expect(resource.generator).to eql(2) + end + + it "has a default key_length of 2048" do + expect(resource.key_length).to eql(2048) + end + + it "only accepts valid key length" do + expect { resource.key_length 1234 }.to raise_error(ArgumentError) + end + + it "the path property is the name property" do + expect(resource.path).to eql("dhparam") + end +end diff --git a/spec/unit/resource/openssl_rsa_private_key.rb b/spec/unit/resource/openssl_rsa_private_key.rb new file mode 100644 index 0000000000..67bebf17fe --- /dev/null +++ b/spec/unit/resource/openssl_rsa_private_key.rb @@ -0,0 +1,59 @@ +# +# Copyright:: Copyright 2018, Chef Software, 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 "spec_helper" + +describe Chef::Resource::OpensslRsaPrivateKey do + + let(:resource) { Chef::Resource::OpensslRsaPrivateKey.new("key") } + + it "has a resource name of :openssl_rsa_private_key" do + expect(resource.resource_name).to eql(:openssl_rsa_private_key) + end + + it "has a default action of create" do + expect(resource.action).to eql([:create]) + end + + it "has a default mode of '0600'" do + expect(resource.mode).to eql("0600") + end + + it "has a default key_cipher of 'des3'" do + expect(resource.key_cipher).to eql("des3") + end + + it "only accepts valid key_cipher values" do + expect { resource.key_cipher "fako" }.to raise_error(ArgumentError) + end + + it "has a default key_length of 2048" do + expect(resource.key_length).to eql(2048) + end + + it "only accepts valid key length" do + expect { resource.key_length 1234 }.to raise_error(ArgumentError) + end + + it "has a default force value of of false" do + expect(resource.force).to eql(false) + end + + it "the path property is the name property" do + expect(resource.path).to eql("key") + end +end diff --git a/spec/unit/resource/openssl_rsa_public_key.rb b/spec/unit/resource/openssl_rsa_public_key.rb new file mode 100644 index 0000000000..d624e10338 --- /dev/null +++ b/spec/unit/resource/openssl_rsa_public_key.rb @@ -0,0 +1,39 @@ +# +# Copyright:: Copyright 2018, Chef Software, 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 "spec_helper" + +describe Chef::Resource::OpensslRsaPublicKey do + + let(:resource) { Chef::Resource::OpensslRsaPublicKey.new("key") } + + it "has a resource name of :openssl_rsa_public_key" do + expect(resource.resource_name).to eql(:openssl_rsa_public_key) + end + + it "has a default action of create" do + expect(resource.action).to eql([:create]) + end + + it "has a default mode of '0640'" do + expect(resource.mode).to eql("0640") + end + + it "the path property is the name property" do + expect(resource.path).to eql("key") + end +end |