diff --git a/Batali b/Batali index f9723d0..cdd22bb 100644 --- a/Batali +++ b/Batali @@ -37,5 +37,6 @@ Batali.define do cookbook 'nodejs', '~> 3.0.0' cookbook 'ark' cookbook 'logrotate' + cookbook 'openssl', '~> 7.0.1' end diff --git a/batali.manifest b/batali.manifest index 1ed1cd4..4ae84b2 100644 --- a/batali.manifest +++ b/batali.manifest @@ -326,30 +326,38 @@ } }, { - "name": "apt", + "name": "postgresql", "dependencies": [ - + [ + "compat_resource", + ">= 12.16.3" + ], + [ + "build-essential", + ">= 2.0.0" + ], + [ + "openssl", + ">= 4.0" + ] ], - "version": "2.9.2", + "version": "6.1.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apt/versions/2.9.2/download", - "version": "2.9.2" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postgresql/versions/6.1.1/download", + "version": "6.1.1" } }, { "name": "openssl", "dependencies": [ - [ - "chef-sugar", - ">= 3.1.1" - ] + ], - "version": "4.4.0", + "version": "7.0.1", "source": { "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/openssl/versions/4.4.0/download", - "version": "4.4.0" + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/openssl/versions/7.0.1/download", + "version": "7.0.1" } }, { @@ -387,6 +395,18 @@ "version": "2.7.6" } }, + { + "name": "apt", + "dependencies": [ + + ], + "version": "2.9.2", + "source": { + "type": "Batali::Source::Site", + "url": "https://supermarket.chef.io:443/api/v1/cookbooks/apt/versions/2.9.2/download", + "version": "2.9.2" + } + }, { "name": "bluepill", "dependencies": [ @@ -1002,29 +1022,6 @@ "version": "2.5.4" } }, - { - "name": "postgresql", - "dependencies": [ - [ - "compat_resource", - ">= 12.16.3" - ], - [ - "build-essential", - ">= 2.0.0" - ], - [ - "openssl", - ">= 4.0" - ] - ], - "version": "6.1.1", - "source": { - "type": "Batali::Source::Site", - "url": "https://supermarket.chef.io:443/api/v1/cookbooks/postgresql/versions/6.1.1/download", - "version": "6.1.1" - } - }, { "name": "omnibus_updater", "dependencies": [ diff --git a/cookbooks/openssl/.foodcritic b/cookbooks/openssl/.foodcritic new file mode 100644 index 0000000..b9f8767 --- /dev/null +++ b/cookbooks/openssl/.foodcritic @@ -0,0 +1 @@ +~FC016 diff --git a/cookbooks/openssl/CHANGELOG.md b/cookbooks/openssl/CHANGELOG.md index 4c67fbc..a65e2fe 100644 --- a/cookbooks/openssl/CHANGELOG.md +++ b/cookbooks/openssl/CHANGELOG.md @@ -1,28 +1,73 @@ -openssl Cookbook CHANGELOG -========================== +# openssl Cookbook CHANGELOG + This file is used to list changes made in each version of the openssl cookbook. -v4.4.0 (2015-08-28) -------------------- +## 7.0.1 (2017-03-21) + +- Fix compatibility with Chef 12.5.1 + +## 7.0.0 (2017-03-06) + +- Converted LWRPs to custom resources, increasing the chef-client dependency to 12.5+. This fixes the bus where each resource notified on every run even if it didn't actually update the files on disk. +- Added testing for Chef 13 +- Test with Local Delivery instead of Rake + +## 6.1.1 (2017-01-19) + +- Resolve deprecation warnings in chefspec +- Use proper ::File class and fix ^2 validation of dhparam key length +- Disable .zero? in cookstyle for now + +## 6.1.0 (2017-01-18) + +- [#37] Support for Subject Alternative Names on generated self-signed certificates +- rubocop +- Cookstyle fixes + +## 6.0.0 (2016-09-08) + +- Update the minimum chef release to 12.1 + +## 5.0.1 (2016-09-01) +- Update docs from node.normal as node.set has been deprecated +- Testing updates + +## 5.0.0 (2016-08-27) + +- Remove the need for the chef-sugar cookbook +- Remove the default['openssl']['packages'] attribute in the upgrades recipe and instead use the correct openssl packages based on platform +- Remove support for Debian 6 and Ubuntu 10.04 in the upgrade recipe +- Add support for Fedora and Suse in the upgrade recipe +- Prevent errors with unset variable in error raising within the random password helper +- Add cookstyle and resolve all warnings +- Add testing, contributing, and maintainers documentation +- Add integration testing in Travis CI with kitchen-dokken +- Add issues_url, source_url and chef_version metadata +- Update the requirements section of the README +- Update the Chefspecs to avoid errors and run using caching for faster runs +- Add issues and PR templates for Github + +## v4.4.0 (2015-08-28) + - NEW: x509 certificates are now signed via SHA-256 instead of SHA-1 - FIX: gen_dhparam error now correctly fails with TypeError instead of ArgumentError if Generator argument isn't an integer -v4.3.2 (2015-08-01) -------------------- +## v4.3.2 (2015-08-01) + - FIX: Updated changelog -v4.3 (2015-08-01) -------------------- +## v4.3 (2015-08-01) + - NEW: Add rsa_key lwrp - FIX: dhparam lwrp now correctly honors the generator parameter -v4.2 (2015-06-23) -------------------- +## v4.2 (2015-06-23) + - NEW: Add dhparam lwrp - FIX: x509 lwrp now updates resource count correctly -v4.1.2 (2015-06-20) -------------------- +## v4.1.2 (2015-06-20) + - Add Serverspec suite - Removed update suite from .kitchen.yml - Add explicit license to test cookbook recipes @@ -31,41 +76,42 @@ v4.1.2 (2015-06-20) - Add helper library - Update x509 LWRP to verify existing keys, if specified -v4.1.1 (2015-06-11) -------------------- +## v4.1.1 (2015-06-11) + - README.md fixes -v4.1.0 (2015-06-11) -------------------- +## v4.1.0 (2015-06-11) + - Add new random_password Mixin (Thanks, Seth!) - Rewritten README.md - Refactor specs - Clear Rubocop violations -v4.0.0 (2015-02-19) -------------------- +## v4.0.0 (2015-02-19) + - Reverting to Opscode module namespace -v3.0.2 (2015-12-18) -------------------- +## v3.0.2 (2015-12-18) + - Accidently released 2.0.2 as 3.0.2 - Re-namespaced `Opscode::OpenSSL::Password` module as `Chef::OpenSSL::Password` -v2.0.2 (2014-12-30) -------------------- +## v2.0.2 (2014-12-30) + - Call cert.to_pem before recipe DSL -v2.0.0 (2014-06-11) -------------------- +## v2.0.0 (2014-06-11) -- #1 - **[COOK-847](https://tickets.chef.io/browse/COOK-847)** - Add LWRP for generating self signed certs -- #4 - **[COOK-4715](https://tickets.chef.io/browse/COOK-4715)** - add upgrade recipe and complete test harness +- # 1 - **[COOK-847](https://tickets.chef.io/browse/COOK-847)** - Add LWRP for generating self signed certs + +- # 4 - **[COOK-4715](https://tickets.chef.io/browse/COOK-4715)** - add upgrade recipe and complete test harness + +## v1.1.0 -v1.1.0 ------- ### Improvement + - **[COOK-3222](https://tickets.chef.io/browse/COOK-3222)** - Allow setting length for `secure_password` -v1.0.2 ------- +## v1.0.2 + - Add name attribute to metadata diff --git a/cookbooks/openssl/CONTRIBUTING.md b/cookbooks/openssl/CONTRIBUTING.md new file mode 100644 index 0000000..ef2f2b8 --- /dev/null +++ b/cookbooks/openssl/CONTRIBUTING.md @@ -0,0 +1,2 @@ +Please refer to +https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD diff --git a/cookbooks/openssl/MAINTAINERS.md b/cookbooks/openssl/MAINTAINERS.md new file mode 100644 index 0000000..645ed14 --- /dev/null +++ b/cookbooks/openssl/MAINTAINERS.md @@ -0,0 +1,15 @@ + + +# Maintainers + +This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead. + +Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead. + +# Project Maintainer +* [Tim Smith](https://github.com/tas50) + +# Maintainers +* [Jennifer Davis](https://github.com/sigje) +* [Tim Smith](https://github.com/tas50) +* [Thom May](https://github.com/thommay) diff --git a/cookbooks/openssl/README.md b/cookbooks/openssl/README.md index f329acc..da19dbc 100644 --- a/cookbooks/openssl/README.md +++ b/cookbooks/openssl/README.md @@ -1,42 +1,41 @@ -OpenSSL Cookbook -================ -[![Build Status](https://travis-ci.org/opscode-cookbooks/openssl.svg?branch=master)](https://travis-ci.org/opscode-cookbooks/openssl) +# OpenSSL Cookbook + +[![Build Status](https://travis-ci.org/chef-cookbooks/openssl.svg?branch=master)](http://travis-ci.org/chef-cookbooks/openssl) [![Cookbook Version](https://img.shields.io/cookbook/v/openssl.svg)](https://supermarket.chef.io/cookbooks/openssl) This cookbook provides tools for working with the Ruby OpenSSL library. It includes: + - A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library. -- An LWRP for generating RSA private keys. -- An LWRP for generating x509 certificates. -- An LWRP for generating dhparam.pem files. +- A resource for generating RSA private keys. +- A resource for generating x509 certificates. +- A resource for generating dhparam.pem files. - An attribute-driven recipe for upgrading OpenSSL packages. -Requirements ------------- +## Platforms The `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef. -The `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` LWRPs work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef. +The `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` resources work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef. The `upgrade` recipe has been tested on the following platforms: -* Ubuntu 12.04, 14.04 -* Debian 7.4 -* CentOS 6.5 +- Debian / Ubuntu derivatives +- RHEL and derivatives +- Fedora +- openSUSE / SUSE Linux Enterprises -The recipe may work on other platforms or different versions of the above platforms, but this has not been tested. +## Chef -Dependencies ------------- +- Chef 12.5+ -This cookbook depends on the [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) cookbook. [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) is used to make the default attribute settings easier to reason about. (See [Attributes](#attributes)) +## Cookbooks -Attributes ----------- +- none -* `node['openssl']['packages']` - An array of packages required to use openssl. The default attributes attempt to be smart about which packages are the default, but this may need to be changed by users of the `openssl::upgrade` recipe. -* `node['openssl']['restart_services']` - An array of service resources that depend on the packages listed in the `node['openssl']['packages']` attribute. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. *Note* Each service listed in this array should represent a "`service`" resource specified in the recipes of the node's run list. +## Attributes -Recipes -------- +- `node['openssl']['restart_services']` - An array of service resources that depend on the openssl packages. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. _Note_ Each service listed in this array should represent a "`service`" resource specified in the recipes of the node's run list. + +## Recipes ### default @@ -63,8 +62,7 @@ include_recipe 'openssl::upgrade' When executed, this recipe will ensure that openssl is upgraded to the latest version, and that the `stats_collector` service is restarted to pick up the latest security fixes released in the openssl package. -Libraries & LWRPs ------------------ +## Libraries & Resources There are two mixins packaged with this cookbook. @@ -73,13 +71,14 @@ There are two mixins packaged with this cookbook. The `RandomPassword` mixin can be used to generate secure random passwords in Chef cookbooks, usually for assignment to a variable or an attribute. `random_password` uses Ruby's SecureRandom library and is customizable. #### Example Usage + ```ruby Chef::Recipe.send(:include, OpenSSLCookbook::RandomPassword) -node.set['my_secure_attribute'] = random_password -node.set_unless['my_secure_attribute'] = random_password -node.set['my_secure_attribute'] = random_password(length: 50) -node.set['my_secure_attribute'] = random_password(length: 50, mode: :base64) -node.set['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII') +node.normal['my_secure_attribute'] = random_password +node.normal_unless['my_secure_attribute'] = random_password +node.normal['my_secure_attribute'] = random_password(length: 50) +node.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64) +node.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII') ``` Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk. @@ -89,31 +88,34 @@ Note that node attributes are widely accessible. Storing unencrypted passwords i This library should be considered deprecated and will be removed in a future version. Please use `OpenSSLCookbook::RandomPassword` instead. The documentation is kept here for historical reasons. #### ~~Example Usage~~ + ```ruby ::Chef::Recipe.send(:include, Opscode::OpenSSL::Password) -node.set_unless['my_password'] = secure_password +node.normal_unless['my_password'] = secure_password ``` ~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~ ### openssl_x509 -This LWRP generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the LWRP will automatically generate a passwordless key with the certificate. +This resource generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate. #### Attributes -| Name | Type | Description | -| ----- | ---- | ------------ | -| `common_name` | String (Required) | Value for the `CN` certificate field. | -| `org` | String (Required) | Value for the `O` certificate field. | -| `org_unit` | String (Required) | Value for the `OU` certificate field. | -| `country` | String (Required) | Value for the `C` ssl field. | -| `expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period. | -| `key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the LWRP will attempt to source a key from this location. If no key file is found, the LWRP will generate a new key file at this location. If the `key_file` attribute is not specified, the LWRP will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate. -| `key_pass` | String (Optional) | The passphrase for an existing key's passphrase -| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ | -| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ | -| `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ | -| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0400"_ | + +Name | Type | Description +------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +`common_name` | String (Required) | Value for the `CN` certificate field. +`org` | String (Required) | Value for the `O` certificate field. +`org_unit` | String (Required) | Value for the `OU` certificate field. +`country` | String (Required) | Value for the `C` ssl field. +`expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period. +`subject_alt_name` | Array (Optional) | Array of _Subject Alternative Name_ entries, in format `DNS:example.com` or `IP:1.2.3.4` _Default: empty_ +`key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the resource will attempt to source a key from this location. If no key file is found, the resource will generate a new key file at this location. If the `key_file` attribute is not specified, the resource will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate. +`key_pass` | String (Optional) | The passphrase for an existing key's passphrase +`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ +`owner` | String (optional) | The owner of all files created by the resource. _Default: "root"_ +`group` | String (optional) | The group of all files created by the resource. _Default: "root"_ +`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: "0400"_ #### Example Usage @@ -132,16 +134,17 @@ When executed, this recipe will generate a key certificate at `/etc/httpd/ssl/my ### openssl_dhparam -This LWRP generates 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. +This resource generates 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. #### Attributes -| Name | Type | Description | -| ----- | ---- | ------------ | -| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ | -| `generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. | -| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ | -| `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ | -| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0644"_ | + +Name | Type | Description +------------ | --------------------------- | --------------------------------------------------------------------------- +`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ +`generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. +`owner` | String (optional) | The owner of all files created by the resource. _Default: "root"_ +`group` | String (optional) | The group of all files created by the resource. _Default: "root"_ +`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: "0644"_ #### Example Usage @@ -149,7 +152,7 @@ In this example, an administrator wishes to create a dhparam.pem file for use wi ```ruby openssl_dhparam '/etc/httpd/ssl/dhparam.pem' do - key_length 2048 + key_length 2048 generator 2 end ``` @@ -158,16 +161,17 @@ When executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhpar ### openssl_rsa_key -This LWRP generates rsa 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. +This resource generates rsa 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. #### Attributes -| Name | Type | Description | -| ----- | ---- | ------------ | -| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ | -| `key_pass` | String (Optional) | The desired passphrase for the key. | -| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ | -| `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ | -| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0644"_ | + +Name | Type | Description +------------ | --------------------------- | --------------------------------------------------------------------------- +`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ +`key_pass` | String (Optional) | The desired passphrase for the key. +`owner` | String (optional) | The owner of all files created by the resource. _Default: "root"_ +`group` | String (optional) | The group of all files created by the resource. _Default: "root"_ +`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: "0644"_ #### Example Usage @@ -175,25 +179,21 @@ In this example, an administrator wishes to create a new RSA private key file in ```ruby openssl_rsa_key '/etc/httpd/ssl/server.key' do - key_length 2048 + key_length 2048 end ``` When executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`. +## License and Author -License and Author ------------------- - -Author:: Jesse Nelson () -Author:: Seth Vargo () -Author:: Charles Johnson () -Author:: Joshua Timberman () - -======= +Author:: Jesse Nelson ([spheromak@gmail.com](mailto:spheromak@gmail.com))
+Author:: Seth Vargo ([sethvargo@gmail.com](mailto:sethvargo@gmail.com))
+Author:: Charles Johnson ([charles@chef.io](mailto:charles@chef.io))
+Author:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io)) ```text -Copyright:: 2009-2015, Chef Software, Inc +Copyright:: 2009-2016, Chef Software, Inc Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cookbooks/openssl/attributes/default.rb b/cookbooks/openssl/attributes/default.rb index d4945a3..b22f210 100644 --- a/cookbooks/openssl/attributes/default.rb +++ b/cookbooks/openssl/attributes/default.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Attributes:: default # -# Copyright 2014, Chef Software, Inc. +# Copyright:: 2014-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,5 +17,4 @@ # limitations under the License. # -default['openssl']['packages'] = [] default['openssl']['restart_services'] = [] diff --git a/cookbooks/openssl/libraries/helpers.rb b/cookbooks/openssl/libraries/helpers.rb index bb81dff..4bb17d3 100644 --- a/cookbooks/openssl/libraries/helpers.rb +++ b/cookbooks/openssl/libraries/helpers.rb @@ -20,7 +20,7 @@ module OpenSSLCookbook 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) + return false unless ::File.exist?(dhparam_pem_path) dhparam = OpenSSL::PKey::DH.new File.read(dhparam_pem_path) dhparam.params_ok? end @@ -28,21 +28,21 @@ module OpenSSLCookbook def key_file_valid?(key_file_path, key_password = nil) # Check if the key file exists # Verify the key file contains a private key - return false unless File.exist?(key_file_path) + return false unless ::File.exist?(key_file_path) key = OpenSSL::PKey::RSA.new File.read(key_file_path), key_password key.private? end # Generators def gen_dhparam(key_length, generator) - fail ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length) - fail TypeError, 'Generator must be an integer' unless generator.is_a?(Integer) + 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 def gen_rsa_key(key_length) - fail ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(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 @@ -50,8 +50,8 @@ module OpenSSLCookbook # Key manipulation helpers # Returns a pem string def encrypt_rsa_key(rsa_key, key_password) - fail TypeError, 'rsa_key must be a Ruby OpenSSL::PKey::RSA object' unless rsa_key.is_a?(OpenSSL::PKey::RSA) - fail TypeError, 'RSA key password must be a string' unless key_password.is_a?(String) + raise TypeError, 'rsa_key must be a Ruby OpenSSL::PKey::RSA object' unless rsa_key.is_a?(OpenSSL::PKey::RSA) + raise TypeError, 'RSA key password must be a string' unless key_password.is_a?(String) cipher = OpenSSL::Cipher::Cipher.new('des3') rsa_key.to_pem(cipher, key_password) diff --git a/cookbooks/openssl/libraries/random_password.rb b/cookbooks/openssl/libraries/random_password.rb index c488301..89dbee9 100644 --- a/cookbooks/openssl/libraries/random_password.rb +++ b/cookbooks/openssl/libraries/random_password.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Library:: random_password # Author:: Seth Vargo # -# Copyright 2015, Seth Vargo +# Copyright:: 2015-2017, Seth Vargo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ module OpenSSLCookbook end class InvalidPasswordMode < StandardError - def initialize(given, acceptable) + def initialize(given, _acceptable = nil) super <<-EOH The given password mode '#{given}' is not valid. Valid password modes are :hex, :base64, and :random_bytes! @@ -73,7 +73,7 @@ EOH when :random_bytes length else - fail InvalidPasswordMode.new(mode) + raise InvalidPasswordMode.new(mode) end SecureRandom.send(mode, length).force_encoding(encoding) diff --git a/cookbooks/openssl/libraries/secure_password.rb b/cookbooks/openssl/libraries/secure_password.rb index 75f7f50..90051da 100644 --- a/cookbooks/openssl/libraries/secure_password.rb +++ b/cookbooks/openssl/libraries/secure_password.rb @@ -1,9 +1,9 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Library:: secure_password # Author:: Joshua Timberman # -# Copyright 2009, Chef Software, Inc. +# Copyright:: 2009-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/openssl/metadata.json b/cookbooks/openssl/metadata.json index aef92df..6e6d604 100644 --- a/cookbooks/openssl/metadata.json +++ b/cookbooks/openssl/metadata.json @@ -1 +1 @@ -{"name":"openssl","version":"4.4.0","description":"Provides a library with a method for generating secure random passwords.","long_description":"OpenSSL Cookbook\n================\n[![Build Status](https://travis-ci.org/opscode-cookbooks/openssl.svg?branch=master)](https://travis-ci.org/opscode-cookbooks/openssl)\n\nThis cookbook provides tools for working with the Ruby OpenSSL library. It includes:\n- A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library.\n- An LWRP for generating RSA private keys.\n- An LWRP for generating x509 certificates.\n- An LWRP for generating dhparam.pem files.\n- An attribute-driven recipe for upgrading OpenSSL packages.\n\nRequirements\n------------\n\nThe `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef.\n\nThe `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` LWRPs work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef.\n\nThe `upgrade` recipe has been tested on the following platforms:\n\n* Ubuntu 12.04, 14.04\n* Debian 7.4\n* CentOS 6.5\n\nThe recipe may work on other platforms or different versions of the above platforms, but this has not been tested.\n\nDependencies\n------------\n\nThis cookbook depends on the [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) cookbook. [Chef Sugar](http://supermarket.chef.io/cookbooks/chef-sugar/) is used to make the default attribute settings easier to reason about. (See [Attributes](#attributes))\n\nAttributes\n----------\n\n* `node['openssl']['packages']` - An array of packages required to use openssl. The default attributes attempt to be smart about which packages are the default, but this may need to be changed by users of the `openssl::upgrade` recipe.\n* `node['openssl']['restart_services']` - An array of service resources that depend on the packages listed in the `node['openssl']['packages']` attribute. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. *Note* Each service listed in this array should represent a \"`service`\" resource specified in the recipes of the node's run list.\n\nRecipes\n-------\n\n### default\n\nAn empty placeholder recipe. Takes no action.\n\n### upgrade\n\nThe upgrade recipe iterates over the list of packages in the `node['openssl']['packages']` attribute, and manages them with the `:upgrade` action. Each package will send a `:restart` notification to service resources named in the `node['openssl']['restart_services']` attribute.\n\n#### Example Usage\n\nIn this example, assume the node is running the `stats_collector` daemon, which depends on the openssl library. Imagine that a new openssl vulnerability has been disclosed, and the operating system vendor has released an update to openssl to address this vulnerability. In order to protect the node, an administrator crafts this recipe:\n\n```ruby\nnode.default['openssl']['restart_services'] = ['stats_collector']\n\n# other recipe code here...\nservice 'stats_collector' do\n action [:enable, :start]\nend\n\ninclude_recipe 'openssl::upgrade'\n```\n\nWhen executed, this recipe will ensure that openssl is upgraded to the latest version, and that the `stats_collector` service is restarted to pick up the latest security fixes released in the openssl package.\n\nLibraries & LWRPs\n-----------------\n\nThere are two mixins packaged with this cookbook.\n\n### random_password (`OpenSSLCookbook::RandomPassword`)\n\nThe `RandomPassword` mixin can be used to generate secure random passwords in Chef cookbooks, usually for assignment to a variable or an attribute. `random_password` uses Ruby's SecureRandom library and is customizable.\n\n#### Example Usage\n```ruby\nChef::Recipe.send(:include, OpenSSLCookbook::RandomPassword)\nnode.set['my_secure_attribute'] = random_password\nnode.set_unless['my_secure_attribute'] = random_password\nnode.set['my_secure_attribute'] = random_password(length: 50)\nnode.set['my_secure_attribute'] = random_password(length: 50, mode: :base64)\nnode.set['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII')\n```\n\nNote that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.\n\n### ~~secure_password (`Opscode::OpenSSL::Password`)~~\n\nThis library should be considered deprecated and will be removed in a future version. Please use `OpenSSLCookbook::RandomPassword` instead. The documentation is kept here for historical reasons.\n\n#### ~~Example Usage~~\n```ruby\n::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)\nnode.set_unless['my_password'] = secure_password\n```\n\n~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~\n\n### openssl_x509\n\nThis LWRP generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the LWRP will automatically generate a passwordless key with the certificate.\n\n#### Attributes\n| Name | Type | Description |\n| ----- | ---- | ------------ |\n| `common_name` | String (Required) | Value for the `CN` certificate field. |\n| `org` | String (Required) | Value for the `O` certificate field. |\n| `org_unit` | String (Required) | Value for the `OU` certificate field. |\n| `country` | String (Required) | Value for the `C` ssl field. |\n| `expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period. |\n| `key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the LWRP will attempt to source a key from this location. If no key file is found, the LWRP will generate a new key file at this location. If the `key_file` attribute is not specified, the LWRP will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate.\n| `key_pass` | String (Optional) | The passphrase for an existing key's passphrase \n| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |\n| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: \"root\"_ |\n| `group` | String (optional) | The group of all files created by the LWRP. _Default: \"root\"_ |\n| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: \"0400\"_ |\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a self-signed x509 certificate for use with a web server. In order to create the certificate, the administrator crafts this recipe:\n\n```ruby\nopenssl_x509 '/etc/httpd/ssl/mycert.pem' do\n common_name 'www.f00bar.com'\n org 'Foo Bar'\n org_unit 'Lab'\n country 'US'\nend\n```\n\nWhen executed, this recipe will generate a key certificate at `/etc/httpd/ssl/mycert.key`. It will then use that key to generate a new certificate file at `/etc/httpd/ssl/mycert.pem`.\n\n### openssl_dhparam\n\nThis LWRP generates 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.\n\n#### Attributes\n| Name | Type | Description |\n| ----- | ---- | ------------ |\n| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |\n| `generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. |\n| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: \"root\"_ |\n| `group` | String (optional) | The group of all files created by the LWRP. _Default: \"root\"_ |\n| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: \"0644\"_ |\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a dhparam.pem file for use with a web server. In order to create the .pem file, the administrator crafts this recipe:\n\n```ruby\nopenssl_dhparam '/etc/httpd/ssl/dhparam.pem' do\n key_length 2048 \n generator 2\nend\n```\n\nWhen executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhparam.pem`.\n\n### openssl_rsa_key\n\nThis LWRP generates rsa 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.\n\n#### Attributes\n| Name | Type | Description |\n| ----- | ---- | ------------ |\n| `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |\n| `key_pass` | String (Optional) | The desired passphrase for the key. |\n| `owner` | String (optional) | The owner of all files created by the LWRP. _Default: \"root\"_ |\n| `group` | String (optional) | The group of all files created by the LWRP. _Default: \"root\"_ |\n| `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: \"0644\"_ |\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a new RSA private key file in order to generate other certificates and public keys. In order to create the key file, the administrator crafts this recipe:\n\n```ruby\nopenssl_rsa_key '/etc/httpd/ssl/server.key' do\n key_length 2048 \nend\n```\n\nWhen executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`.\n\n\nLicense and Author\n------------------\n\nAuthor:: Jesse Nelson () \nAuthor:: Seth Vargo () \nAuthor:: Charles Johnson () \nAuthor:: Joshua Timberman ()\n\n=======\n\n```text\nCopyright:: 2009-2015, Chef Software, Inc \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache 2.0","platforms":{},"dependencies":{"chef-sugar":">= 3.1.1"},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"openssl":"Empty, this cookbook provides a library, see README.md","upgrade":"Upgrade OpenSSL library and restart dependent services"}} \ No newline at end of file +{"name":"openssl","version":"7.0.1","description":"Provides a library with a method for generating secure random passwords.","long_description":"# OpenSSL Cookbook\n\n[![Build Status](https://travis-ci.org/chef-cookbooks/openssl.svg?branch=master)](http://travis-ci.org/chef-cookbooks/openssl) [![Cookbook Version](https://img.shields.io/cookbook/v/openssl.svg)](https://supermarket.chef.io/cookbooks/openssl)\n\nThis cookbook provides tools for working with the Ruby OpenSSL library. It includes:\n\n- A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library.\n- A resource for generating RSA private keys.\n- A resource for generating x509 certificates.\n- A resource for generating dhparam.pem files.\n- An attribute-driven recipe for upgrading OpenSSL packages.\n\n## Platforms\n\nThe `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef.\n\nThe `openssl_x509`, `openssl_rsa_key` and `openssl_dhparam` resources work on any platform with the OpenSSL Ruby bindings installed. These bindings are already included with Chef.\n\nThe `upgrade` recipe has been tested on the following platforms:\n\n- Debian / Ubuntu derivatives\n- RHEL and derivatives\n- Fedora\n- openSUSE / SUSE Linux Enterprises\n\n## Chef\n\n- Chef 12.5+\n\n## Cookbooks\n\n- none\n\n## Attributes\n\n- `node['openssl']['restart_services']` - An array of service resources that depend on the openssl packages. This array is empty by default, as Chef has no reasonable way to detect which applications or services are compiled against these packages. _Note_ Each service listed in this array should represent a \"`service`\" resource specified in the recipes of the node's run list.\n\n## Recipes\n\n### default\n\nAn empty placeholder recipe. Takes no action.\n\n### upgrade\n\nThe upgrade recipe iterates over the list of packages in the `node['openssl']['packages']` attribute, and manages them with the `:upgrade` action. Each package will send a `:restart` notification to service resources named in the `node['openssl']['restart_services']` attribute.\n\n#### Example Usage\n\nIn this example, assume the node is running the `stats_collector` daemon, which depends on the openssl library. Imagine that a new openssl vulnerability has been disclosed, and the operating system vendor has released an update to openssl to address this vulnerability. In order to protect the node, an administrator crafts this recipe:\n\n```ruby\nnode.default['openssl']['restart_services'] = ['stats_collector']\n\n# other recipe code here...\nservice 'stats_collector' do\n action [:enable, :start]\nend\n\ninclude_recipe 'openssl::upgrade'\n```\n\nWhen executed, this recipe will ensure that openssl is upgraded to the latest version, and that the `stats_collector` service is restarted to pick up the latest security fixes released in the openssl package.\n\n## Libraries & Resources\n\nThere are two mixins packaged with this cookbook.\n\n### random_password (`OpenSSLCookbook::RandomPassword`)\n\nThe `RandomPassword` mixin can be used to generate secure random passwords in Chef cookbooks, usually for assignment to a variable or an attribute. `random_password` uses Ruby's SecureRandom library and is customizable.\n\n#### Example Usage\n\n```ruby\nChef::Recipe.send(:include, OpenSSLCookbook::RandomPassword)\nnode.normal['my_secure_attribute'] = random_password\nnode.normal_unless['my_secure_attribute'] = random_password\nnode.normal['my_secure_attribute'] = random_password(length: 50)\nnode.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64)\nnode.normal['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII')\n```\n\nNote that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.\n\n### ~~secure_password (`Opscode::OpenSSL::Password`)~~\n\nThis library should be considered deprecated and will be removed in a future version. Please use `OpenSSLCookbook::RandomPassword` instead. The documentation is kept here for historical reasons.\n\n#### ~~Example Usage~~\n\n```ruby\n::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)\nnode.normal_unless['my_password'] = secure_password\n```\n\n~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~\n\n### openssl_x509\n\nThis resource generates self-signed, PEM-formatted x509 certificates. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate.\n\n#### Attributes\n\nName | Type | Description\n------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n`common_name` | String (Required) | Value for the `CN` certificate field.\n`org` | String (Required) | Value for the `O` certificate field.\n`org_unit` | String (Required) | Value for the `OU` certificate field.\n`country` | String (Required) | Value for the `C` ssl field.\n`expire` | Fixnum (Optional) | Value representing the number of days from _now_ through which the issued certificate cert will remain valid. The certificate will expire after this period.\n`subject_alt_name` | Array (Optional) | Array of _Subject Alternative Name_ entries, in format `DNS:example.com` or `IP:1.2.3.4` _Default: empty_\n`key_file` | String (Optional) | The path to a certificate key file on the filesystem. If the `key_file` attribute is specified, the resource will attempt to source a key from this location. If no key file is found, the resource will generate a new key file at this location. If the `key_file` attribute is not specified, the resource will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate.\n`key_pass` | String (Optional) | The passphrase for an existing key's passphrase\n`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_\n`owner` | String (optional) | The owner of all files created by the resource. _Default: \"root\"_\n`group` | String (optional) | The group of all files created by the resource. _Default: \"root\"_\n`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: \"0400\"_\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a self-signed x509 certificate for use with a web server. In order to create the certificate, the administrator crafts this recipe:\n\n```ruby\nopenssl_x509 '/etc/httpd/ssl/mycert.pem' do\n common_name 'www.f00bar.com'\n org 'Foo Bar'\n org_unit 'Lab'\n country 'US'\nend\n```\n\nWhen executed, this recipe will generate a key certificate at `/etc/httpd/ssl/mycert.key`. It will then use that key to generate a new certificate file at `/etc/httpd/ssl/mycert.pem`.\n\n### openssl_dhparam\n\nThis resource generates 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.\n\n#### Attributes\n\nName | Type | Description\n------------ | --------------------------- | ---------------------------------------------------------------------------\n`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_\n`generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_.\n`owner` | String (optional) | The owner of all files created by the resource. _Default: \"root\"_\n`group` | String (optional) | The group of all files created by the resource. _Default: \"root\"_\n`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: \"0644\"_\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a dhparam.pem file for use with a web server. In order to create the .pem file, the administrator crafts this recipe:\n\n```ruby\nopenssl_dhparam '/etc/httpd/ssl/dhparam.pem' do\n key_length 2048\n generator 2\nend\n```\n\nWhen executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhparam.pem`.\n\n### openssl_rsa_key\n\nThis resource generates rsa 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.\n\n#### Attributes\n\nName | Type | Description\n------------ | --------------------------- | ---------------------------------------------------------------------------\n`key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_\n`key_pass` | String (Optional) | The desired passphrase for the key.\n`owner` | String (optional) | The owner of all files created by the resource. _Default: \"root\"_\n`group` | String (optional) | The group of all files created by the resource. _Default: \"root\"_\n`mode` | String or Fixnum (Optional) | The permission mode of all files created by the resource. _Default: \"0644\"_\n\n#### Example Usage\n\nIn this example, an administrator wishes to create a new RSA private key file in order to generate other certificates and public keys. In order to create the key file, the administrator crafts this recipe:\n\n```ruby\nopenssl_rsa_key '/etc/httpd/ssl/server.key' do\n key_length 2048\nend\n```\n\nWhen executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`.\n\n## License and Author\n\nAuthor:: Jesse Nelson ([spheromak@gmail.com](mailto:spheromak@gmail.com))
\nAuthor:: Seth Vargo ([sethvargo@gmail.com](mailto:sethvargo@gmail.com))
\nAuthor:: Charles Johnson ([charles@chef.io](mailto:charles@chef.io))
\nAuthor:: Joshua Timberman ([joshua@chef.io](mailto:joshua@chef.io))\n\n```text\nCopyright:: 2009-2016, Chef Software, Inc \n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","maintainer":"Chef Software, Inc.","maintainer_email":"cookbooks@chef.io","license":"Apache-2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{"openssl":"Empty, this cookbook provides a library, see README.md","upgrade":"Upgrade OpenSSL library and restart dependent services"},"source_url":"https://github.com/chef-cookbooks/openssl","issues_url":"https://github.com/chef-cookbooks/openssl/issues","chef_version":">= 12.5","ohai_version":{}} \ No newline at end of file diff --git a/cookbooks/openssl/providers/dhparam.rb b/cookbooks/openssl/providers/dhparam.rb deleted file mode 100644 index 4b6e4c3..0000000 --- a/cookbooks/openssl/providers/dhparam.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# dhparam.pem provider -# -# Author:: Charles Johnson -# - -include OpenSSLCookbook::Helpers - -use_inline_resources - -def whyrun_supported? - true -end - -action :create do - converge_by("Create a dhparam file #{@new_resource}") do - unless dhparam_pem_valid?(new_resource.name) - dhparam_content = gen_dhparam(new_resource.key_length, new_resource.generator).to_pem - - log "Generating #{new_resource.key_length} bit "\ - "dhparam file at #{new_resource.name}, this may take some time" - - file new_resource.name do - action :create - owner new_resource.owner - group new_resource.group - mode new_resource.mode - sensitive true - content dhparam_content - end - end - end -end diff --git a/cookbooks/openssl/providers/rsa_key.rb b/cookbooks/openssl/providers/rsa_key.rb deleted file mode 100644 index 0a4dd42..0000000 --- a/cookbooks/openssl/providers/rsa_key.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# dhparam.pem provider -# -# Author:: Charles Johnson -# - -include OpenSSLCookbook::Helpers - -use_inline_resources - -def whyrun_supported? - true -end - -action :create do - converge_by("Create an RSA key #{@new_resource}") do - unless key_file_valid?(new_resource.name, new_resource.key_pass) - - log "Generating #{new_resource.key_length} bit "\ - "RSA key file at #{new_resource.name}, this may take some time" - - if new_resource.key_pass - unencrypted_rsa_key = gen_rsa_key(new_resource.key_length) - rsa_key_content = encrypt_rsa_key(unencrypted_rsa_key, new_resource.key_pass) - else - rsa_key_content = gen_rsa_key(new_resource.key_length).to_pem - end - - file new_resource.name do - action :create - owner new_resource.owner - group new_resource.group - mode new_resource.mode - sensitive true - content rsa_key_content - end - end - end -end diff --git a/cookbooks/openssl/providers/x509.rb b/cookbooks/openssl/providers/x509.rb deleted file mode 100644 index 433300a..0000000 --- a/cookbooks/openssl/providers/x509.rb +++ /dev/null @@ -1,104 +0,0 @@ -# -# x509 self signed cert provider -# -# Author:: Jesse Nelson -# - -include OpenSSLCookbook::Helpers - -use_inline_resources - -def whyrun_supported? - true -end - -attr_reader :key_file, :key, :cert, :ef - -action :create do - converge_by("Create #{@new_resource}") do - unless ::File.exist? new_resource.name - create_keys - cert_content = cert.to_pem - key_content = key.to_pem - - file new_resource.name do - action :create_if_missing - mode new_resource.mode - owner new_resource.owner - group new_resource.group - sensitive true - content cert_content - end - - file new_resource.key_file do - action :create_if_missing - mode new_resource.mode - owner new_resource.owner - group new_resource.group - sensitive true - content key_content - end - new_resource.updated_by_last_action(true) - end - end -end - -protected - - # rubocop:disable Metrics/AbcSize, Style/IndentationConsistency - def key_file - unless new_resource.key_file - path, file = ::File.split(new_resource.name) - filename = ::File.basename(file, ::File.extname(file)) - new_resource.key_file path + '/' + filename + '.key' - end - new_resource.key_file - end - - def key - @key ||= if key_file_valid?(key_file, new_resource.key_pass) - OpenSSL::PKey::RSA.new ::File.read(key_file), new_resource.key_pass - else - OpenSSL::PKey::RSA.new(new_resource.key_length) - end - @key - end - - def cert - @cert ||= OpenSSL::X509::Certificate.new - end - - def gen_cert - cert - cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject) - cert.not_before = Time.now - cert.not_after = Time.now + (new_resource.expire.to_i * 24 * 60 * 60) - cert.public_key = key.public_key - cert.serial = 0x0 - cert.version = 2 - end - - def subject - @subject ||= '/C=' + new_resource.country + - '/O=' + new_resource.org + - '/OU=' + new_resource.org_unit + - '/CN=' + new_resource.common_name - end - - def extensions - [ - ef.create_extension('basicConstraints', 'CA:TRUE', true), - ef.create_extension('subjectKeyIdentifier', 'hash') - ] - end - - def create_keys - gen_cert - @ef ||= OpenSSL::X509::ExtensionFactory.new - ef.subject_certificate = cert - ef.issuer_certificate = cert - cert.extensions = extensions - cert.add_extension ef.create_extension('authorityKeyIdentifier', - 'keyid:always,issuer:always') - cert.sign key, OpenSSL::Digest::SHA256.new - end diff --git a/cookbooks/openssl/recipes/default.rb b/cookbooks/openssl/recipes/default.rb index b0465e1..0311040 100644 --- a/cookbooks/openssl/recipes/default.rb +++ b/cookbooks/openssl/recipes/default.rb @@ -2,7 +2,7 @@ # Cookbook Name:: openssl # Recipe:: default # -# Copyright 2009, Chef Software, Inc. +# Copyright 2009-2016, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/cookbooks/openssl/recipes/upgrade.rb b/cookbooks/openssl/recipes/upgrade.rb index c31923b..d9d6f4a 100644 --- a/cookbooks/openssl/recipes/upgrade.rb +++ b/cookbooks/openssl/recipes/upgrade.rb @@ -1,8 +1,8 @@ # -# Cookbook Name:: openssl +# Cookbook:: openssl # Recipe:: upgrade # -# Copyright 2015, Chef Software, Inc. +# Copyright:: 2015-2017, Chef Software, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,22 +16,17 @@ # See the License for the specific language governing permissions and # limitations under the License. # -include_recipe 'chef-sugar' -# Attributes are set here and not in attributes/default.rb because of the -# chef-sugar dependency for the methods evaluated in the case statement. -case -when debian_before_or_at_squeeze?, ubuntu_before_or_at_lucid? - node.default['openssl']['packages'] = %w(libssl0.9.8 openssl) -when debian_after_or_at_wheezy?, ubuntu_after_or_at_precise? - node.default['openssl']['packages'] = %w(libssl1.0.0 openssl) -when rhel? - node.default['openssl']['packages'] = %w(openssl) +case node['platform_family'] +when 'debian', 'ubuntu' + packages = %w(libssl1.0.0 openssl) +when 'rhel', 'fedora', 'suse' + packages = %w(openssl) else - node.default['openssl']['packages'] = [] + packages = [] end -node['openssl']['packages'].each do |ssl_pkg| +packages.each do |ssl_pkg| package ssl_pkg do action :upgrade node['openssl']['restart_services'].each do |ssl_svc| diff --git a/cookbooks/openssl/resources/dhparam.rb b/cookbooks/openssl/resources/dhparam.rb index 1a8bd14..c3d4d97 100644 --- a/cookbooks/openssl/resources/dhparam.rb +++ b/cookbooks/openssl/resources/dhparam.rb @@ -1,10 +1,28 @@ +include OpenSSLCookbook::Helpers -actions [:create] -default_action :create +property :name, 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 +property :group, String +property :mode, [Integer, String] -attribute :name, :kind_of => String, :name_attribute => true -attribute :key_length, :equal_to => [1024, 2048, 4096, 8192], :default => 2048 -attribute :generator, :equal_to => [2, 5], :default => 2 -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :mode, :kind_of => [Integer, String] +action :create do + unless dhparam_pem_valid?(new_resource.name) # ~FC023 + converge_by("Create a dhparam file #{@new_resource}") do + dhparam_content = gen_dhparam(new_resource.key_length, new_resource.generator).to_pem + + log "Generating #{new_resource.key_length} bit "\ + "dhparam file at #{new_resource.name}, this may take some time" + + file new_resource.name do + action :create + owner new_resource.owner + group new_resource.group + mode new_resource.mode + sensitive true + content dhparam_content + end + end + end +end diff --git a/cookbooks/openssl/resources/rsa_key.rb b/cookbooks/openssl/resources/rsa_key.rb index f1e46bb..5b2b170 100644 --- a/cookbooks/openssl/resources/rsa_key.rb +++ b/cookbooks/openssl/resources/rsa_key.rb @@ -1,10 +1,33 @@ +include OpenSSLCookbook::Helpers -actions [:create] -default_action :create +property :name, String, name_property: true +property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 +property :key_pass, String +property :owner, String +property :group, String +property :mode, [Integer, String] -attribute :name, :kind_of => String, :name_attribute => true -attribute :key_length, :equal_to => [1024, 2048, 4096, 8192], :default => 2048 -attribute :key_pass, :kind_of => String, :default => nil -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :mode, :kind_of => [Integer, String] +action :create do + unless key_file_valid?(new_resource.name, new_resource.key_pass) + converge_by("Create an RSA key #{@new_resource}") do + log "Generating #{new_resource.key_length} bit "\ + "RSA key file at #{new_resource.name}, this may take some time" + + if new_resource.key_pass + unencrypted_rsa_key = gen_rsa_key(new_resource.key_length) + rsa_key_content = encrypt_rsa_key(unencrypted_rsa_key, new_resource.key_pass) + else + rsa_key_content = gen_rsa_key(new_resource.key_length).to_pem + end + + file new_resource.name do + action :create + owner new_resource.owner + group new_resource.group + mode new_resource.mode + sensitive true + content rsa_key_content + end + end + end +end diff --git a/cookbooks/openssl/resources/x509.rb b/cookbooks/openssl/resources/x509.rb index 5685778..2929cbf 100644 --- a/cookbooks/openssl/resources/x509.rb +++ b/cookbooks/openssl/resources/x509.rb @@ -1,16 +1,118 @@ +include OpenSSLCookbook::Helpers -actions [:create] -default_action :create +property :name, String, name_property: true +property :owner, String +property :group, String +property :expire, Integer +property :mode, [Integer, String] +property :org, String, required: true +property :org_unit, String, required: true +property :country, String, required: true +property :common_name, String, required: true +property :subject_alt_name, Array, default: [] +property :key_file, String +property :key_pass, String +property :key_length, equal_to: [1024, 2048, 4096, 8192], default: 2048 -attribute :name, :kind_of => String, :name_attribute => true -attribute :owner, :kind_of => String -attribute :group, :kind_of => String -attribute :expire, :kind_of => Integer -attribute :mode, :kind_of => [Integer, String] -attribute :org, :kind_of => String, :required => true -attribute :org_unit, :kind_of => String, :required => true -attribute :country, :kind_of => String, :required => true -attribute :common_name, :kind_of => String, :required => true -attribute :key_file, :kind_of => String, :default => nil -attribute :key_pass, :kind_of => String, :default => nil -attribute :key_length, :equal_to => [1024, 2048, 4096, 8192], :default => 2048 +action :create do + unless ::File.exist? new_resource.name + converge_by("Create #{@new_resource}") do + create_keys + cert_content = cert.to_pem + key_content = key.to_pem + + file new_resource.name do + action :create_if_missing + mode new_resource.mode + owner new_resource.owner + group new_resource.group + sensitive true + content cert_content + end + + file new_resource.key_file do + action :create_if_missing + mode new_resource.mode + owner new_resource.owner + group new_resource.group + sensitive true + content key_content + end + end + end +end + +action_class.class_eval do + def generate_key_file + unless new_resource.key_file + path, file = ::File.split(new_resource.name) + filename = ::File.basename(file, ::File.extname(file)) + new_resource.key_file path + '/' + filename + '.key' + end + new_resource.key_file + end + + def key + @key ||= if key_file_valid?(generate_key_file, new_resource.key_pass) + OpenSSL::PKey::RSA.new ::File.read(generate_key_file), new_resource.key_pass + else + OpenSSL::PKey::RSA.new(new_resource.key_length) + end + @key + end + + def cert + @cert ||= OpenSSL::X509::Certificate.new + end + + def gen_cert + cert + cert.subject = cert.issuer = OpenSSL::X509::Name.parse(subject) + cert.not_before = Time.now + cert.not_after = Time.now + (new_resource.expire.to_i * 24 * 60 * 60) + cert.public_key = key.public_key + cert.serial = 0x0 + cert.version = 2 + end + + def subject + @subject ||= '/C=' + new_resource.country + + '/O=' + new_resource.org + + '/OU=' + new_resource.org_unit + + '/CN=' + new_resource.common_name + end + + def extensions + exts = [] + exts << @ef.create_extension('basicConstraints', 'CA:TRUE', true) + exts << @ef.create_extension('subjectKeyIdentifier', 'hash') + + unless new_resource.subject_alt_name.empty? + san = {} + counters = {} + new_resource.subject_alt_name.each do |an| + kind, value = an.split(':', 2) + counters[kind] ||= 0 + counters[kind] += 1 + san["#{kind}.#{counters[kind]}"] = value + end + @ef.config['alt_names'] = san + exts << @ef.create_extension('subjectAltName', '@alt_names') + end + + exts + end + + def create_keys + gen_cert + @ef ||= OpenSSL::X509::ExtensionFactory.new + @ef.subject_certificate = cert + @ef.issuer_certificate = cert + @ef.config = OpenSSL::Config.load(OpenSSL::Config::DEFAULT_CONFIG_FILE) + + cert.extensions = extensions + cert.add_extension @ef.create_extension('authorityKeyIdentifier', + 'keyid:always,issuer:always') + cert.sign key, OpenSSL::Digest::SHA256.new + end +end