Skip to content

Commit

Permalink
Merge pull request #153 from zilchms/CAsigning
Browse files Browse the repository at this point in the history
add ability to certificate provider to get signed against a CA cert
  • Loading branch information
bastelfreak committed May 21, 2023
2 parents 3b65cbb + cc6240e commit 0a6cc8b
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 10 deletions.
35 changes: 35 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ The following parameters are available in the `openssl::certificate::x509` defin
* [`csr`](#-openssl--certificate--x509--csr)
* [`key`](#-openssl--certificate--x509--key)
* [`encrypted`](#-openssl--certificate--x509--encrypted)
* [`ca`](#-openssl--certificate--x509--ca)
* [`cakey`](#-openssl--certificate--x509--cakey)

##### <a name="-openssl--certificate--x509--ensure"></a>`ensure`

Expand Down Expand Up @@ -631,6 +633,24 @@ Defaults to true (key is encrypted)

Default value: `true`

##### <a name="-openssl--certificate--x509--ca"></a>`ca`

Data type: `Optional[Stdlib::Absolutepath]`

Path to CA certificate for signing. Undef means no CA will be
provided for signing the certificate.

Default value: `undef`

##### <a name="-openssl--certificate--x509--cakey"></a>`cakey`

Data type: `Optional[Stdlib::Absolutepath]`

Path to CA private key for signing. Undef mean no CAkey will be
provided.

Default value: `undef`

### <a name="openssl--config"></a>`openssl::config`

Generates an openssl.conf file using defaults
Expand Down Expand Up @@ -1233,6 +1253,9 @@ Default value: `present`
The following parameters are available in the `x509_cert` type.

* [`authentication`](#-x509_cert--authentication)
* [`ca`](#-x509_cert--ca)
* [`cakey`](#-x509_cert--cakey)
* [`csr`](#-x509_cert--csr)
* [`days`](#-x509_cert--days)
* [`force`](#-x509_cert--force)
* [`password`](#-x509_cert--password)
Expand All @@ -1250,6 +1273,18 @@ The authentication algorithm: 'rsa', 'dsa or ec'

Default value: `rsa`

##### <a name="-x509_cert--ca"></a>`ca`

The optional ca certificate filepath

##### <a name="-x509_cert--cakey"></a>`cakey`

The optional ca private key filepath

##### <a name="-x509_cert--csr"></a>`csr`

The optional certificate signing request path

##### <a name="-x509_cert--days"></a>`days`

Valid values: `%r{\d+}`
Expand Down
31 changes: 23 additions & 8 deletions lib/puppet/provider/x509_cert/openssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,29 @@ def exists?
end

def create
options = [
'req',
'-config', resource[:template],
'-new', '-x509',
'-days', resource[:days],
'-key', resource[:private_key],
'-out', resource[:path]
]
if resource[:csr]
options = [
'x509',
'-req',
'-days', resource[:days],
'-in', resource[:csr],
'-out', resource[:path]
]
if resource[:ca]
options << ['-CAcreateserial']
options << ['-CA', resource[:ca]]
options << ['-CAkey', resource[:cakey]]
end
else
options = [
'req',
'-config', resource[:template],
'-new', '-x509',
'-days', resource[:days],
'-key', resource[:private_key],
'-out', resource[:path]
]
end
options << ['-passin', "pass:#{resource[:password]}"] if resource[:password]
options << ['-extensions', 'req_ext'] if resource[:req_ext] != :false
openssl options
Expand Down
12 changes: 12 additions & 0 deletions lib/puppet/type/x509_cert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@
defaultto :rsa
end

newparam(:csr) do
desc 'The optional certificate signing request path'
end

newparam(:ca) do
desc 'The optional ca certificate filepath'
end

newparam(:cakey) do
desc 'The optional ca private key filepath'
end

autorequire(:file) do
self[:template]
end
Expand Down
11 changes: 11 additions & 0 deletions manifests/certificate/x509.pp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
# specifying the -nodes option during the CSR generation. Turning
# off encryption is needed by some applications, such as OpenLDAP.
# Defaults to true (key is encrypted)
# @param ca
# Path to CA certificate for signing. Undef means no CA will be
# provided for signing the certificate.
# @param cakey
# Path to CA private key for signing. Undef mean no CAkey will be
# provided.
#
# @example basic usage
#
Expand Down Expand Up @@ -142,6 +148,8 @@
Boolean $force = true,
String $cnf_tpl = 'openssl/cert.cnf.erb',
Boolean $encrypted = true,
Optional[Stdlib::Absolutepath] $ca = undef,
Optional[Stdlib::Absolutepath] $cakey = undef,
) {
$_key_owner = pick($key_owner, $owner)
$_key_group = pick($key_group, $group)
Expand Down Expand Up @@ -182,6 +190,9 @@
req_ext => $req_ext,
force => $force,
require => File[$_cnf],
ca => $ca,
cakey => $cakey,
csr => $csr,
}

x509_request { $_csr:
Expand Down
30 changes: 28 additions & 2 deletions spec/unit/puppet/provider/x509_cert/openssl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@

it 'creates a certificate with the proper options' do
expect(provider_class).to receive(:openssl).with([
'req', '-config', '/tmp/foo.cnf', '-new', '-x509',
'req',
'-config', '/tmp/foo.cnf',
'-new',
'-x509',
'-days', 3650,
'-key', '/tmp/foo.key',
'-out', '/tmp/foo.crt',
Expand All @@ -40,7 +43,10 @@
it 'creates a certificate with the proper options' do
resource[:password] = '2x6${'
expect(provider_class).to receive(:openssl).with([
'req', '-config', '/tmp/foo.cnf', '-new', '-x509',
'req',
'-config', '/tmp/foo.cnf',
'-new',
'-x509',
'-days', 3650,
'-key', '/tmp/foo.key',
'-out', '/tmp/foo.crt',
Expand All @@ -52,6 +58,26 @@
end
end

context 'when using a CA for signing' do
it 'creates a certificate with the proper options' do
resource[:csr] = '/tmp/foo.csr'
resource[:ca] = '/tmp/foo-ca.crt'
resource[:cakey] = '/tmp/foo-ca.key'
expect(provider_class).to receive(:openssl).with([
'x509',
'-req',
'-days', 3650,
'-in', '/tmp/foo.csr',
'-out', '/tmp/foo.crt',
['-CAcreateserial'],
['-CA', '/tmp/foo-ca.crt'],
['-CAkey', '/tmp/foo-ca.key'],
['-extensions', 'req_ext']
])
resource.provider.create
end
end

context 'when forcing key' do
it 'exists? should return true if certificate exists and is synced' do
resource[:force] = true
Expand Down
5 changes: 5 additions & 0 deletions spec/unit/puppet/type/x509_cert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,9 @@
resource[:authentication] = :foo
end.to raise_error(Puppet::Error, %r{Invalid value :foo})
end

it 'accepts a valid csr parameter' do
resource[:csr] = '/tmp/foo.csr'
expect(resource[:csr]).to eq('/tmp/foo.csr')
end
end

0 comments on commit 0a6cc8b

Please sign in to comment.