Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ca: unsplit precert/CT/cert issuance flow #7983

Open
jsha opened this issue Jan 28, 2025 · 2 comments
Open

ca: unsplit precert/CT/cert issuance flow #7983

jsha opened this issue Jan 28, 2025 · 2 comments
Assignees

Comments

@jsha
Copy link
Contributor

jsha commented Jan 28, 2025

Right now the issuance flow looks like:

  1. RA->CA.IssuePrecertificate
  2. RA->Publisher.SubmitToSingleCTWithResult (get SCTs)
  3. RA->CA.IssueCertificateForPrecertificate

Steps (1) and (3) must use the exact same configuration for issuer and profile, otherwise the certificate will not match the precertificate. Right now we ensure this by including a hash of the issuance.ProfileConfig object in IssueCertificateForPrecertificate(). The CA then looks up the correct profile by that hash. This allows error-free deploys. But it has some problems.

Any change to an existing profile has to be a two-step change: first, deploy to all CAs a config that has both the old and the new configs, so the CAs will all have both the old and the new profile hashes available. Then update the currently issuing profile to have the new config, while keeping the old profile around under an obscure name.

Also, the profile hashing adds some complexity that we'd rather do without.

A couple possible fixes:

  1. Introduce a new, streaming, IssuePrecertAndCert. This RPC would have four message types: PrecertRequest, Precert, SCTs, FinalCert. The RA would send the PrecertRequest, wait for a Precert response on the stream, send the precert to CT logs and get SCTs, send the SCTs back to the CA on the same stream, then wait for the FinalCert.
  2. Rather than streaming, have the CA call back into the RA. The RA would call a new method CA.IssuePrecertAndCert, then the CA would call a new method RA.SubmitPrecertToCT. The RA would call out to Publisher, organize the responses, and send back SCTs to the CA. The CA would collect those into a final certificate, sign it, and send it back as the response to CA.IssuePrecertAndCert.

Advantages for streaming RPC:

  • The issuance flow is logically one set of related actions, so it makes sense to keep them together as one back-and-forth RPC.
  • The responses from the CA are tied to a specific RA request.

Disadvantages for streaming RPC:

  • The streaming gRPC APIs are annoying to work with and difficult to mock for tests, because they require mocking both the streaming object and the RPC server that returns it.
  • The streaming messages in each direction use proto3's oneof, so we need code to cast to the expected type and error out if we get an unexpected message.
  • Our metrics collection, graphing, and timeout configs are generally oriented around plain call-and-response RPCs, and including a streaming RPC in the main issuance flow makes things a bit more complicated.

Advantages for plain RPC:

  • Similar to most existing code.
  • Simple to reason about and test.

Disadvantages for plain RPC:

  • Requires opening another port from CFN to IFN. Right now the CA talks mainly to the SA.
  • The CA could call any method on the RA, not just RA.SubmitPrecertToCT. Note that we could improve on this situation by having the RA export a separate service just for precert submission, and giving the CA access to only that service. However, this is slightly annoying from a configuration and maintenance perspective.
@caenorhabditis8

This comment was marked as spam.

@caenorhabditis8

This comment was marked as spam.

@aarongable aarongable added this to the Sprint 2025-02-11 milestone Feb 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants