Skip to content

Commit 54aead0

Browse files
nickgwjoshcooper
authored andcommitted
(PUP-10589) Add a generate_request option to puppet ssl
1 parent 3d4c34b commit 54aead0

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

lib/puppet/application/ssl.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ def help
5959
the CSR. Otherwise a new key pair will be generated. If a CSR has already
6060
been submitted with the given `certname`, then the operation will fail.
6161
62+
* generate_request:
63+
Generate a certificate signing request (CSR). If
64+
a private and public key pair already exist, they will be used to generate
65+
the CSR. Otherwise a new key pair will be generated.
66+
6267
* download_cert:
6368
Download a certificate for this host. If the current private key matches
6469
the downloaded certificate, then the certificate will be saved and used
@@ -136,6 +141,8 @@ def main
136141
unless cert
137142
raise Puppet::Error, _("The certificate for '%{name}' has not yet been signed") % { name: certname }
138143
end
144+
when 'generate_request'
145+
generate_request(certname)
139146
when 'verify'
140147
verify(certname)
141148
when 'clean'
@@ -187,6 +194,26 @@ def submit_request(ssl_context)
187194
raise Puppet::Error.new(_("Failed to submit certificate request: %{message}") % { message: e.message }, e)
188195
end
189196

197+
def generate_request(certname)
198+
key = @cert_provider.load_private_key(certname)
199+
unless key
200+
if Puppet[:key_type] == 'ec'
201+
Puppet.info _("Creating a new EC SSL key for %{name} using curve %{curve}") % { name: certname, curve: Puppet[:named_curve] }
202+
key = OpenSSL::PKey::EC.generate(Puppet[:named_curve])
203+
else
204+
Puppet.info _("Creating a new SSL key for %{name}") % { name: certname }
205+
key = OpenSSL::PKey::RSA.new(Puppet[:keylength].to_i)
206+
end
207+
@cert_provider.save_private_key(certname, key)
208+
end
209+
210+
csr = @cert_provider.create_request(certname, key)
211+
@cert_provider.save_request(certname, csr)
212+
Puppet.notice _("Generated certificate request for '%{name}' at %{requestdir}") % { name: certname, requestdir: Puppet[:requestdir] }
213+
rescue => e
214+
raise Puppet::Error.new(_("Failed to generate certificate request: %{message}") % { message: e.message }, e)
215+
end
216+
190217
def download_cert(ssl_context)
191218
key = @cert_provider.load_private_key(Puppet[:certname])
192219

spec/unit/application/ssl_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,50 @@ def expects_command_to_fail(message)
171171
end
172172
end
173173

174+
context 'when generating a CSR' do
175+
let(:csr_path) { Puppet[:hostcsr] }
176+
let(:requestdir) { Puppet[:requestdir] }
177+
178+
before do
179+
ssl.command_line.args << 'generate_request'
180+
end
181+
182+
it 'generates an RSA private key' do
183+
File.unlink(Puppet[:hostprivkey])
184+
185+
expects_command_to_pass(%r{Generated certificate request for '#{name}' at #{requestdir}})
186+
end
187+
188+
it 'generates an EC private key' do
189+
Puppet[:key_type] = 'ec'
190+
File.unlink(Puppet[:hostprivkey])
191+
192+
expects_command_to_pass(%r{Generated certificate request for '#{name}' at #{requestdir}})
193+
end
194+
195+
it 'registers OIDs' do
196+
expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
197+
198+
expects_command_to_pass(%r{Generated certificate request for '#{name}' at #{requestdir}})
199+
end
200+
201+
it 'saves the CSR locally' do
202+
expects_command_to_pass(%r{Generated certificate request for '#{name}' at #{requestdir}})
203+
204+
expect(Puppet::FileSystem).to be_exist(csr_path)
205+
end
206+
207+
it 'accepts dns alt names' do
208+
Puppet[:dns_alt_names] = 'majortom'
209+
210+
expects_command_to_pass
211+
212+
csr = Puppet::SSL::CertificateRequest.new(name)
213+
csr.read(csr_path)
214+
expect(csr.subject_alt_names).to include('DNS:majortom')
215+
end
216+
end
217+
174218
context 'when downloading a certificate' do
175219
before do
176220
ssl.command_line.args << 'download_cert'

0 commit comments

Comments
 (0)