diff --git a/lib/puppet/ssl/oids.rb b/lib/puppet/ssl/oids.rb index 81fe52be93a..0fca9e68884 100644 --- a/lib/puppet/ssl/oids.rb +++ b/lib/puppet/ssl/oids.rb @@ -71,6 +71,7 @@ module Puppet::SSL::Oids ["1.3.6.1.4.1.34380.1.3", 'ppAuthCertExt', 'Puppet Certificate Authorization Extension'], ["1.3.6.1.4.1.34380.1.3.1", 'pp_authorization', 'Certificate Extension Authorization'], + ["1.3.6.1.4.1.34380.1.3.2", 'pp_auth_auto_renew', 'Auto-Renew Certificate Extension'], ["1.3.6.1.4.1.34380.1.3.13", 'pp_auth_role', 'Puppet Node Role Name for Authorization'], ] diff --git a/lib/puppet/x509/cert_provider.rb b/lib/puppet/x509/cert_provider.rb index 097eb0cb61e..faa11f8eb2e 100644 --- a/lib/puppet/x509/cert_provider.rb +++ b/lib/puppet/x509/cert_provider.rb @@ -311,6 +311,13 @@ def create_request(name, private_key) options[:extension_requests] = csr_attributes.extension_requests end + # Adds auto-renew extension to CSR if the agent supports auto-renewal of + # certificates + if Puppet[:hostcert_renewal_interval] && Puppet[:hostcert_renewal_interval] > 0 + options[:extension_requests] ||= {} + options[:extension_requests].merge!({'1.3.6.1.4.1.34380.1.3.2' => 'true'}) + end + csr = Puppet::SSL::CertificateRequest.new(name) csr.generate(private_key, options) end diff --git a/spec/unit/ssl/state_machine_spec.rb b/spec/unit/ssl/state_machine_spec.rb index a89993af28e..938638e7dd1 100644 --- a/spec/unit/ssl/state_machine_spec.rb +++ b/spec/unit/ssl/state_machine_spec.rb @@ -843,7 +843,8 @@ def write_csr_attributes(data) csr.request_extensions ).to contain_exactly( {'oid' => '1.3.6.1.4.1.34380.1.1.31415', 'value' => 'pi'}, - {'oid' => '1.3.6.1.4.1.34380.1.1.2718', 'value' => 'e'} + {'oid' => '1.3.6.1.4.1.34380.1.1.2718', 'value' => 'e'}, + {'oid' => 'pp_auth_auto_renew', 'value' => 'true'} ) end.to_return(status: 200) diff --git a/spec/unit/x509/cert_provider_spec.rb b/spec/unit/x509/cert_provider_spec.rb index 30a64786542..c71dd6d58c0 100644 --- a/spec/unit/x509/cert_provider_spec.rb +++ b/spec/unit/x509/cert_provider_spec.rb @@ -586,6 +586,29 @@ def expects_private_file(path) end end + context 'when creating' do + context 'requests' do + let(:name) { 'tom' } + let(:requestdir) { tmpdir('cert_provider') } + let(:provider) { create_provider(requestdir: requestdir) } + let(:key) { OpenSSL::PKey::RSA.new(Puppet[:keylength]) } + + it 'has the auto-renew extension by default for agents that support automatic renewal' do + csr = provider.create_request(name, key) + # need to create CertificateRequest instance from csr in order to use request_extensions() + wrapped_csr = Puppet::SSL::CertificateRequest.from_instance csr + expect(wrapped_csr.request_extensions).to include('oid' => 'pp_auth_auto_renew', 'value' => 'true') + end + + it 'does not have the auto-renew extension for agents that do not support automatic renewal' do + Puppet[:hostcert_renewal_interval] = 0 + csr = provider.create_request(name, key) + wrapped_csr = Puppet::SSL::CertificateRequest.from_instance csr + expect(wrapped_csr.request_extensions.length).to eq(0) + end + end + end + context 'CA last update time' do let(:ca_path) { tmpfile('pem_ca') }