[PUP-9459] Create SSL state machine for generating a client cert Created: 2019/01/23  Updated: 2019/12/03  Resolved: 2019/03/20

Status: Closed
Project: Puppet
Component/s: None
Affects Version/s: None
Fix Version/s: PUP 6.4.0

Type: New Feature Priority: Normal
Reporter: Josh Cooper Assignee: Josh Cooper
Resolution: Fixed Votes: 0
Labels: resolved-issue-added
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
is duplicated by PUP-4568 Puppet agent does not resend certific... Closed
is duplicated by PUP-6207 expired certificates cause recursion Closed
is duplicated by PUP-7295 Puppet is too permissive about skippi... Closed
is duplicated by PUP-7903 Do not cache invalid node certificate... Closed
Epic Link: Simplify agent SSL initialization
Team: Coremunity
CVE-ID: CVE-2018-11751
Sprint: Platform Core KANBAN
Release Notes: New Feature
Release Notes Summary: Puppet now uses the SSL state machine to generate its private key, submit a CSR, and retrieve its client cert.
QA Risk Assessment: Needs Assessment


Create an SSL state machine for loading/generating a private key, loading/submitting a CSR, and loading/downloading a client cert. The state machine should verify the consistency of the data before committing changes to disk and moving to the next state. For example, if we download the client cert, but its public key doesn't match our private key, then the cert should be discarded and an error generated. Connections should always authenticate the server (VERIFY_PEER) and never downgrade to VERIFY_NONE. The state machine should generate an SSLContext initialized with the CA certs, CRL bundle, client cert and private key so that all future connections are mutually authenticated.

Comment by Josh Cooper [ 2019/03/12 ]

Acceptance criteria

  1. Private key should have permissions based on Puppet[:hostprivkey]. When running on a puppetserver host, the private key and client cert must be owned by the puppet user so it is readable by puppetserver.
  2. The state machine should download a missing CA
  3. If Puppet[:certificate_revocation] = :leaf or :chain, then the state machine should download a missing CRL.
  4. If Puppet[:certificate_revocation] = false, then the agent should not download or load a CRL. It should successfully connect to the server, even if the server's cert has been revoked.
  5. Calling Puppet::SSL::Host.localhost should run the client state machine, as there is existing code relying on that behavior: https://github.com/puppetlabs/puppet-agent-bootstrap/blob/master/lib/puppet/face/bootstrap.rb#L50
  6. The generated CSR should contain custom_attributes and extension_requests if specified in Puppet[:csr_attributes]. The former are only added to the CSR. The latter are added to the CSR and copied to the signed client cert.
  7. The client state machine should work when autosigning is enabled
  8. If autosigning is disabled, and the agent should wait for Puppet[:waitforcert] seconds and try again. When the CSR is next signed, the agent should download the cert and finish its run.
  9. If Puppet[:waitforcert] = 0 or Puppet[:onetime] = true (which occurs when running puppet agent -t), then puppet should exit with an error message Exiting; no certificate found and waitforcert is disabled and exit code 1, like it does today.
  10. If an agent submits a CSR, but doesn't have a client cert, and you run puppetserver ca clean --certname <agent>, then the next time the agent runs (or wakes up), it should successfully submit the CSR again.
  11. If an agent has a client cert, but you clean the agent (puppet ssl clean), and run puppet agent -t, then puppet should submit a new CSR, but result in an error that the server's CSR doesn't match the client's. It should be possible to run puppetserver ca clean --certname <agent> on the server, and when the agent next checks it, it should successfully submit the CSR. You shouldn't have to delete any files from the agent.
Comment by Josh Cooper [ 2019/03/19 ]

Merged to master in https://github.com/puppetlabs/puppet/commit/b49c11b6425738441d6f33285d2630fa434a123e

Comment by Josh Cooper [ 2019/03/20 ]

Passed CI in e5cc701e7fcbc7c70896f37e6ea4c6dd3dcb59a3

Generated at Sun Sep 27 16:52:05 PDT 2020 using Jira 8.5.2#805002-sha1:a66f9354b9e12ac788984e5d84669c903a370049.