from-scratch 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Berksfile +1 -1
  3. data/Berksfile.lock +7 -4
  4. data/cookbooks/openssl/CHANGELOG.md +43 -2
  5. data/cookbooks/openssl/README.md +149 -55
  6. data/cookbooks/openssl/libraries/helpers.rb +60 -0
  7. data/cookbooks/openssl/libraries/matchers.rb +13 -0
  8. data/cookbooks/openssl/libraries/random_password.rb +82 -0
  9. data/cookbooks/openssl/libraries/secure_password.rb +3 -2
  10. data/cookbooks/openssl/metadata.json +1 -31
  11. data/cookbooks/openssl/providers/dhparam.rb +33 -0
  12. data/cookbooks/openssl/providers/rsa_key.rb +39 -0
  13. data/cookbooks/openssl/providers/x509.rb +44 -34
  14. data/cookbooks/openssl/recipes/upgrade.rb +13 -11
  15. data/cookbooks/openssl/resources/dhparam.rb +10 -0
  16. data/cookbooks/openssl/resources/rsa_key.rb +10 -0
  17. data/cookbooks/openssl/resources/x509.rb +11 -11
  18. data/cookbooks/postgresql/.gitignore +18 -0
  19. data/cookbooks/postgresql/.kitchen.yml +175 -0
  20. data/cookbooks/postgresql/.rspec +3 -0
  21. data/cookbooks/postgresql/CHANGELOG.md +1 -1
  22. data/cookbooks/postgresql/CONTRIBUTING.md +6 -0
  23. data/cookbooks/postgresql/Cheffile +6 -0
  24. data/cookbooks/postgresql/Gemfile +12 -0
  25. data/cookbooks/postgresql/LICENSE +201 -0
  26. data/cookbooks/postgresql/Rakefile +22 -0
  27. data/cookbooks/postgresql/TESTING.md +22 -0
  28. data/cookbooks/postgresql/attributes/default.rb +72 -1
  29. data/cookbooks/postgresql/metadata.json +7 -12
  30. data/cookbooks/postgresql/providers/database.rb +73 -0
  31. data/cookbooks/postgresql/providers/user.rb +82 -0
  32. data/cookbooks/postgresql/recipes/setup_databases.rb +36 -0
  33. data/cookbooks/postgresql/recipes/setup_users.rb +17 -0
  34. data/cookbooks/postgresql/resources/database.rb +20 -0
  35. data/cookbooks/postgresql/resources/user.rb +20 -0
  36. data/cookbooks/postgresql/test/unit/debian_server_spec.rb +72 -0
  37. data/cookbooks/postgresql/test/unit/default_spec.rb +37 -0
  38. data/cookbooks/postgresql/test/unit/server_spec.rb +41 -0
  39. data/cookbooks/postgresql/test/unit/spec_helper.rb +20 -0
  40. data/cookbooks/scratchify/Berksfile +1 -1
  41. data/cookbooks/scratchify/Berksfile.lock +5 -4
  42. data/cookbooks/scratchify/lib/from-scratch.rb +1 -0
  43. data/cookbooks/scratchify/lib/from-scratch/version.rb +1 -1
  44. data/cookbooks/scratchify/templates/node.json.erb +17 -0
  45. data/from-scratch.gemspec +2 -2
  46. data/lib/from-scratch.rb +7 -3
  47. data/lib/from-scratch/version.rb +1 -1
  48. data/templates/node.json.erb +33 -0
  49. metadata +33 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5fecc9619a3c03891cb931d42dbada9d76d11546
4
- data.tar.gz: 354a0f61a77ac2a23608afcdfde4eb3966caf491
3
+ metadata.gz: 3fd33f498a44da3fa69a159e08ed8cb5abce737b
4
+ data.tar.gz: 85835eb65547f0d5c037ef56c8d253ce46c6ba20
5
5
  SHA512:
6
- metadata.gz: 38b9f37053254444604c73f57e56bb5d776be4d8ee13e40a86eaf9ce4598aba5c5f49b014b2e7a3a7036ed25db7cce17163f073f536300b87ed19cff31bcd330
7
- data.tar.gz: 4f3f887a9d83e37c73fc1f2d7c004c1290c1a2d3512e8afe8afb1ba667fbb87d2930a45479f3b5f7e0cad7eb43333ca727b58728a40eabb9cd13a4db2c6577d1
6
+ metadata.gz: 8515f8f2f281f214e96bea5c97b55b90ec131785ae8c22144963a87990bd9add9319b57696bde6f7e41602c930dab0768e465a66008d869a31ca9ff71d951308
7
+ data.tar.gz: d8daa090fdecaf523cec1b095ddb7497689e65164d9931a0a6979da206d141e859e0b4620c0161fb4e49de6db6df9261cb24aab2a85c7cf7e6212477b6159b14
data/Berksfile CHANGED
@@ -7,7 +7,7 @@ metadata
7
7
 
8
8
  cookbook 'user'
9
9
  cookbook 'rvm', github: 'fnichol/chef-rvm'
10
- cookbook 'postgresql'
10
+ cookbook 'postgresql', github: 'sandrew/postgresql', branch: 'develop'
11
11
 
12
12
  # cookbook 'dpkg_packages', git: "https://gitlab.acid.cl/acidlabs/chef-dpkg-packages.git"
13
13
  # cookbook 'nginx', git: "https://gitlab.acid.cl/acidlabs/chef-nginx.git"
data/Berksfile.lock CHANGED
@@ -1,5 +1,8 @@
1
1
  DEPENDENCIES
2
2
  postgresql
3
+ git: git://github.com/sandrew/postgresql.git
4
+ revision: a1f3ce3e2e22515bc175011a3e3faa0af98dd8db
5
+ branch: develop
3
6
  rvm
4
7
  git: git://github.com/fnichol/chef-rvm.git
5
8
  revision: 08ec265f277e112a5a2e4b201bd32ddfe1bb968c
@@ -14,12 +17,12 @@ GRAPH
14
17
  chef-sugar (3.1.1)
15
18
  chef_gem (0.1.0)
16
19
  java (1.35.0)
17
- openssl (4.0.0)
18
- chef-sugar (>= 0.0.0)
19
- postgresql (3.4.20)
20
+ openssl (4.4.0)
21
+ chef-sugar (>= 3.1.1)
22
+ postgresql (3.4.21)
20
23
  apt (>= 1.9.0)
21
24
  build-essential (>= 0.0.0)
22
- openssl (~> 4.0.0)
25
+ openssl (~> 4.0)
23
26
  rvm (0.10.1)
24
27
  chef_gem (>= 0.0.0)
25
28
  java (>= 0.0.0)
@@ -2,13 +2,54 @@ openssl Cookbook CHANGELOG
2
2
  ==========================
3
3
  This file is used to list changes made in each version of the openssl cookbook.
4
4
 
5
- v4.0.0 (2014-02-19)
5
+ v4.4.0 (2015-08-28)
6
+ -------------------
7
+ - NEW: x509 certificates are now signed via SHA-256 instead of SHA-1
8
+ - FIX: gen_dhparam error now correctly fails with TypeError instead of ArgumentError if Generator argument isn't an integer
9
+
10
+ v4.3.2 (2015-08-01)
11
+ -------------------
12
+ - FIX: Updated changelog
13
+
14
+ v4.3 (2015-08-01)
15
+ -------------------
16
+ - NEW: Add rsa_key lwrp
17
+ - FIX: dhparam lwrp now correctly honors the generator parameter
18
+
19
+ v4.2 (2015-06-23)
20
+ -------------------
21
+ - NEW: Add dhparam lwrp
22
+ - FIX: x509 lwrp now updates resource count correctly
23
+
24
+ v4.1.2 (2015-06-20)
25
+ -------------------
26
+ - Add Serverspec suite
27
+ - Removed update suite from .kitchen.yml
28
+ - Add explicit license to test cookbook recipes
29
+ - Add Whyrun support to x509 LWRP
30
+ - Expand Chefspec tests for x509 LWRP to step_into LWRP
31
+ - Add helper library
32
+ - Update x509 LWRP to verify existing keys, if specified
33
+
34
+ v4.1.1 (2015-06-11)
35
+ -------------------
36
+ - README.md fixes
37
+
38
+ v4.1.0 (2015-06-11)
39
+ -------------------
40
+ - Add new random_password Mixin (Thanks, Seth!)
41
+ - Rewritten README.md
42
+ - Refactor specs
43
+ - Clear Rubocop violations
44
+
45
+ v4.0.0 (2015-02-19)
6
46
  -------------------
7
47
  - Reverting to Opscode module namespace
8
48
 
9
- v3.0.2 (2014-12-30)
49
+ v3.0.2 (2015-12-18)
10
50
  -------------------
11
51
  - Accidently released 2.0.2 as 3.0.2
52
+ - Re-namespaced `Opscode::OpenSSL::Password` module as `Chef::OpenSSL::Password`
12
53
 
13
54
  v2.0.2 (2014-12-30)
14
55
  -------------------
@@ -1,105 +1,199 @@
1
- openssl Cookbook
1
+ OpenSSL Cookbook
2
2
  ================
3
+ [![Build Status](https://travis-ci.org/opscode-cookbooks/openssl.svg?branch=master)](https://travis-ci.org/opscode-cookbooks/openssl)
3
4
 
4
- This cookbook provides a library method to generate secure random passwords in recipes using the Ruby OpenSSL library.
5
-
6
- It also provides an attribute-driven recipe for upgrading OpenSSL packages.
5
+ This cookbook provides tools for working with the Ruby OpenSSL library. It includes:
6
+ - A library method to generate secure random passwords in recipes, using the Ruby SecureRandom library.
7
+ - An LWRP for generating RSA private keys.
8
+ - An LWRP for generating x509 certificates.
9
+ - An LWRP for generating dhparam.pem files.
10
+ - An attribute-driven recipe for upgrading OpenSSL packages.
7
11
 
8
12
  Requirements
9
13
  ------------
10
14
 
11
- The `secure_password` works on any platform with OpenSSL Ruby bindings installed, which are a requirement for Chef anyway.
15
+ The `random_password` mixin works on any platform with the Ruby SecureRandom module. This module is already included with Chef.
16
+
17
+ 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.
12
18
 
13
- The upgrade recipe works on the following tested platforms:
19
+ The `upgrade` recipe has been tested on the following platforms:
14
20
 
15
21
  * Ubuntu 12.04, 14.04
16
22
  * Debian 7.4
17
23
  * CentOS 6.5
18
24
 
19
- It may work on other platforms or versions of the above platforms with or without modification.
25
+ The recipe may work on other platforms or different versions of the above platforms, but this has not been tested.
26
+
27
+ Dependencies
28
+ ------------
20
29
 
21
- [Chef Sugar](https://github.com/sethvargo/chef-sugar) was introduced as a dependency to provide helpers that make the default attribute settings (see Attributes) easier to reason about.
30
+ 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))
22
31
 
23
32
  Attributes
24
33
  ----------
25
34
 
26
- * `node['openssl']['packages']` - An array of packages of 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.
27
- * `node['openssl']['restart_services']` - An array of service resources that use the `node['openssl']['packages']`. This is empty by default as Chef has no reliably reasonable way to detect which applications or services are compiled against these packages. *Note* These each need to be "`service`" resources specified somewhere in the recipes in the node's run list.
35
+ * `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.
36
+ * `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.
28
37
 
29
38
  Recipes
30
39
  -------
31
40
 
41
+ ### default
42
+
43
+ An empty placeholder recipe. Takes no action.
44
+
32
45
  ### upgrade
33
46
 
34
- The 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 `:restart` notification to service resources named by the `node['openssl']['restart_services']` attribute.
47
+ The 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.
35
48
 
36
- Usage
37
- -----
49
+ #### Example Usage
38
50
 
39
- Most often this will be used to generate a secure password for an attribute. In a recipe:
51
+ In 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:
40
52
 
41
53
  ```ruby
42
- ::Chef::Recipe.send(:include, Chef::OpenSSL::Password)
43
- node.set_unless[:my_password] = secure_password
54
+ node.default['openssl']['restart_services'] = ['stats_collector']
55
+
56
+ # other recipe code here...
57
+ service 'stats_collector' do
58
+ action [:enable, :start]
59
+ end
60
+
61
+ include_recipe 'openssl::upgrade'
44
62
  ```
45
63
 
46
- To use the `openssl::upgrade` recipe, set the attributes as mentioned above. For example, we have a "stats_collector" service that uses openssl. It has a recipe that looks like this:
64
+ 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.
47
65
 
48
- LWRP
49
- ====
66
+ Libraries & LWRPs
67
+ -----------------
50
68
 
51
- This cookbook includes an LWRP for generating Self Signed Certificates
69
+ There are two mixins packaged with this cookbook.
52
70
 
53
- ## openssl_x509
54
- generate a pem formatted x509 cert + key
71
+ ### random_password (`OpenSSLCookbook::RandomPassword`)
55
72
 
56
- ### Attributes
57
- `common_name` A String representing the `CN` ssl field
58
- `org` A String representing the `O` ssl field
59
- `org_unit` A String representing the `OU` ssl field
60
- `country` A String representing the `C` ssl field
61
- `expire` A Fixnum reprenting the number of days from _now_ to expire the cert
62
- `key_file` Optional A string to the key file to use. If no key is present it will generate and store one.
63
- `key_pass` A String that is the key's passphrase
64
- `key_length` A Fixnum reprenting your desired Bit Length _Default: 2048_
65
- `owner` The owner of the files _Default: "root"_
66
- `group` The group of the files _Default: "root"_
67
- `mode` The mode to store the files in _Default: "0400"_
73
+ 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.
68
74
 
69
- ### Example usage
75
+ #### Example Usage
76
+ ```ruby
77
+ Chef::Recipe.send(:include, OpenSSLCookbook::RandomPassword)
78
+ node.set['my_secure_attribute'] = random_password
79
+ node.set_unless['my_secure_attribute'] = random_password
80
+ node.set['my_secure_attribute'] = random_password(length: 50)
81
+ node.set['my_secure_attribute'] = random_password(length: 50, mode: :base64)
82
+ node.set['my_secure_attribute'] = random_password(length: 50, mode: :base64, encoding: 'ASCII')
83
+ ```
70
84
 
71
- openssl_x509 "/tmp/mycert.pem" do
72
- common_name "www.f00bar.com"
73
- org "Foo Bar"
74
- org_unit "Lab"
75
- country "US"
76
- end
85
+ Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.
77
86
 
78
-
79
- License and Author
80
- ==================
87
+ ### ~~secure_password (`Opscode::OpenSSL::Password`)~~
81
88
 
82
- Author:: Jesse Nelson (<spheromak@gmail.com>)
83
- Author:: Joshua Timberman (<joshua@chef.io>)
84
- =======
89
+ 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.
90
+
91
+ #### ~~Example Usage~~
92
+ ```ruby
93
+ ::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)
94
+ node.set_unless['my_password'] = secure_password
95
+ ```
85
96
 
97
+ ~~Note that node attributes are widely accessible. Storing unencrypted passwords in node attributes, as in this example, carries risk.~~
98
+
99
+ ### openssl_x509
100
+
101
+ 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.
102
+
103
+ #### Attributes
104
+ | Name | Type | Description |
105
+ | ----- | ---- | ------------ |
106
+ | `common_name` | String (Required) | Value for the `CN` certificate field. |
107
+ | `org` | String (Required) | Value for the `O` certificate field. |
108
+ | `org_unit` | String (Required) | Value for the `OU` certificate field. |
109
+ | `country` | String (Required) | Value for the `C` ssl field. |
110
+ | `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. |
111
+ | `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.
112
+ | `key_pass` | String (Optional) | The passphrase for an existing key's passphrase
113
+ | `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |
114
+ | `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ |
115
+ | `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ |
116
+ | `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0400"_ |
117
+
118
+ #### Example Usage
119
+
120
+ In 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:
86
121
 
87
122
  ```ruby
88
- node.default['openssl']['restart_services'] = ['stats_collector']
123
+ openssl_x509 '/etc/httpd/ssl/mycert.pem' do
124
+ common_name 'www.f00bar.com'
125
+ org 'Foo Bar'
126
+ org_unit 'Lab'
127
+ country 'US'
128
+ end
129
+ ```
89
130
 
90
- # other recipe code here...
91
- service 'stats_collector' do
92
- action [:enable, :start]
131
+ When 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`.
132
+
133
+ ### openssl_dhparam
134
+
135
+ 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.
136
+
137
+ #### Attributes
138
+ | Name | Type | Description |
139
+ | ----- | ---- | ------------ |
140
+ | `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |
141
+ | `generator` | Fixnum (Optional) | The desired Diffie-Hellmann generator. Can be _2_ or _5_. |
142
+ | `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ |
143
+ | `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ |
144
+ | `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0644"_ |
145
+
146
+ #### Example Usage
147
+
148
+ In 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:
149
+
150
+ ```ruby
151
+ openssl_dhparam '/etc/httpd/ssl/dhparam.pem' do
152
+ key_length 2048
153
+ generator 2
93
154
  end
155
+ ```
94
156
 
95
- include_recipe 'openssl::upgrade'
157
+ When executed, this recipe will generate a dhparam file at `/etc/httpd/ssl/dhparam.pem`.
158
+
159
+ ### openssl_rsa_key
160
+
161
+ 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.
162
+
163
+ #### Attributes
164
+ | Name | Type | Description |
165
+ | ----- | ---- | ------------ |
166
+ | `key_length` | Fixnum (Optional) | The desired Bit Length of the generated key. _Default: 2048_ |
167
+ | `key_pass` | String (Optional) | The desired passphrase for the key. |
168
+ | `owner` | String (optional) | The owner of all files created by the LWRP. _Default: "root"_ |
169
+ | `group` | String (optional) | The group of all files created by the LWRP. _Default: "root"_ |
170
+ | `mode` | String or Fixnum (Optional) | The permission mode of all files created by the LWRP. _Default: "0644"_ |
171
+
172
+ #### Example Usage
173
+
174
+ In 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:
175
+
176
+ ```ruby
177
+ openssl_rsa_key '/etc/httpd/ssl/server.key' do
178
+ key_length 2048
179
+ end
96
180
  ```
97
181
 
98
- This will ensure that openssl is upgraded to the latest version so the `stats_collector` service won't be exploited (hopefully!).
182
+ When executed, this recipe will generate a passwordless RSA key file at `/etc/httpd/ssl/server.key`.
183
+
184
+
185
+ License and Author
186
+ ------------------
187
+
188
+ Author:: Jesse Nelson (<spheromak@gmail.com>)
189
+ Author:: Seth Vargo (<sethvargo@gmail.com>)
190
+ Author:: Charles Johnson (<charles@chef.io>)
191
+ Author:: Joshua Timberman (<joshua@chef.io>)
192
+
193
+ =======
99
194
 
100
195
  ```text
101
- Copyright:: 2009-2011, Chef Software, Inc
102
- Copyright:: 2014, Chef Software, Inc <legal@chef.io>
196
+ Copyright:: 2009-2015, Chef Software, Inc <lega@chef.io>
103
197
 
104
198
  Licensed under the Apache License, Version 2.0 (the "License");
105
199
  you may not use this file except in compliance with the License.
@@ -0,0 +1,60 @@
1
+ module OpenSSLCookbook
2
+ # Helper functions for the OpenSSL cookbook.
3
+ module Helpers
4
+ def self.included(_base)
5
+ require 'openssl' unless defined?(OpenSSL)
6
+ end
7
+
8
+ # Path helpers
9
+ def get_key_filename(cert_filename)
10
+ cert_file_path, cert_filename = ::File.split(cert_filename)
11
+ cert_filename = ::File.basename(cert_filename, ::File.extname(cert_filename))
12
+ cert_file_path + ::File::SEPARATOR + cert_filename + '.key'
13
+ end
14
+
15
+ # Validation helpers
16
+ def key_length_valid?(number)
17
+ number >= 1024 && number & (number - 1) == 0
18
+ end
19
+
20
+ def dhparam_pem_valid?(dhparam_pem_path)
21
+ # Check if the dhparam.pem file exists
22
+ # Verify the dhparam.pem file contains a key
23
+ return false unless File.exist?(dhparam_pem_path)
24
+ dhparam = OpenSSL::PKey::DH.new File.read(dhparam_pem_path)
25
+ dhparam.params_ok?
26
+ end
27
+
28
+ def key_file_valid?(key_file_path, key_password = nil)
29
+ # Check if the key file exists
30
+ # Verify the key file contains a private key
31
+ return false unless File.exist?(key_file_path)
32
+ key = OpenSSL::PKey::RSA.new File.read(key_file_path), key_password
33
+ key.private?
34
+ end
35
+
36
+ # Generators
37
+ def gen_dhparam(key_length, generator)
38
+ fail ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length)
39
+ fail TypeError, 'Generator must be an integer' unless generator.is_a?(Integer)
40
+
41
+ OpenSSL::PKey::DH.new(key_length, generator)
42
+ end
43
+
44
+ def gen_rsa_key(key_length)
45
+ fail ArgumentError, 'Key length must be a power of 2 greater than or equal to 1024' unless key_length_valid?(key_length)
46
+
47
+ OpenSSL::PKey::RSA.new(key_length)
48
+ end
49
+
50
+ # Key manipulation helpers
51
+ # Returns a pem string
52
+ def encrypt_rsa_key(rsa_key, key_password)
53
+ fail TypeError, 'rsa_key must be a Ruby OpenSSL::PKey::RSA object' unless rsa_key.is_a?(OpenSSL::PKey::RSA)
54
+ fail TypeError, 'RSA key password must be a string' unless key_password.is_a?(String)
55
+
56
+ cipher = OpenSSL::Cipher::Cipher.new('des3')
57
+ rsa_key.to_pem(cipher, key_password)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,13 @@
1
+ if defined?(ChefSpec)
2
+ def create_x509_certificate(name)
3
+ ChefSpec::Matchers::ResourceMatcher.new(:openssl_x509, :create, name)
4
+ end
5
+
6
+ def create_dhparam_pem(name)
7
+ ChefSpec::Matchers::ResourceMatcher.new(:openssl_dhparam, :create, name)
8
+ end
9
+
10
+ def create_rsa_key(name)
11
+ ChefSpec::Matchers::ResourceMatcher.new(:openssl_rsa_key, :create, name)
12
+ end
13
+ end
@@ -0,0 +1,82 @@
1
+ #
2
+ # Cookbook Name:: openssl
3
+ # Library:: random_password
4
+ # Author:: Seth Vargo <sethvargo@gmail.com>
5
+ #
6
+ # Copyright 2015, Seth Vargo
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ # rubocop:disable UnusedMethodArgument, Style/RaiseArgs
20
+
21
+ module OpenSSLCookbook
22
+ module RandomPassword
23
+ # Override the included method to require securerandom if it is not defined.
24
+ # This avoids the need to load the class on each Chef run unless the user is
25
+ # explicitly requiring it.
26
+ def self.included(base)
27
+ require 'securerandom' unless defined?(SecureRandom)
28
+ end
29
+
30
+ class InvalidPasswordMode < StandardError
31
+ def initialize(given, acceptable)
32
+ super <<-EOH
33
+ The given password mode '#{given}' is not valid. Valid password modes are :hex,
34
+ :base64, and :random_bytes!
35
+ EOH
36
+ end
37
+ end
38
+
39
+ #
40
+ # Generates a random password using {SecureRandom}.
41
+ #
42
+ # @example Generating a random (hex) password (of 20 characters)
43
+ # random_password #=> "1930e99aa035083bdd93d1d8f11cb7ac8f625c9c"
44
+ #
45
+ # @example Generating a random base64 password that is 50 characters
46
+ # random_password(mode: :base64, length: 50) #=> "72o5oVbKHHEVYj1nOgFB2EijnzZfnrbfasVuF+oRH8wMgb0QWoYZF/OkrQricp1ENoI="
47
+ #
48
+ # @example Generate a password with a forced encoding
49
+ # random_password(encoding: "ASCII")
50
+ #
51
+ # @param [Hash] options
52
+ # @option options [Fixnum] :length
53
+ # the number of bits to use in the password
54
+ # @option options [Symbol] :mode
55
+ # the type of random password to generate - valid values are
56
+ # `:hex`, `:base64`, or `:random_bytes`
57
+ # @option options [String, Symbol, Constant] :encoding
58
+ # the encoding to force (default is "UTF-8")
59
+ #
60
+ # @return [String]
61
+ #
62
+ def random_password(options = {})
63
+ length = options[:length] || 20
64
+ mode = options[:mode] || :hex
65
+ encoding = options[:encoding] || 'UTF-8'
66
+
67
+ # Convert to a "proper" length, since the size is actually in bytes
68
+ length = case mode
69
+ when :hex
70
+ length / 2
71
+ when :base64
72
+ length * 3 / 4
73
+ when :random_bytes
74
+ length
75
+ else
76
+ fail InvalidPasswordMode.new(mode)
77
+ end
78
+
79
+ SecureRandom.send(mode, length).force_encoding(encoding)
80
+ end
81
+ end
82
+ end