Skip to content

[PKI PR-014b] Implement RFC 7030 EST adapter - #60

Open
arvindh123 wants to merge 7 commits into
certificatesfrom
pki/pr-014b-est-adapter
Open

[PKI PR-014b] Implement RFC 7030 EST adapter#60
arvindh123 wants to merge 7 commits into
certificatesfrom
pki/pr-014b-est-adapter

Conversation

@arvindh123

@arvindh123 arvindh123 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Objective

Implement PR-014b by exposing the existing subject-driven enrollment service through the RFC 7030 EST operations cacerts, simpleenroll, simplereenroll, serverkeygen, and csrattrs.

Dependencies

Changes

  • Add exact RFC 7030 routes on the dedicated enrollment TLS listener, with no EST additional-path selector.
  • Add HTTP Basic password and Atom Bearer authentication for first enrollment, generated-key enrollment, and CSR attributes.
  • Require the verified TLS leaf certificate for re-enrollment.
  • Derive the maximum accepted DER size from the enrollment service's canonical PEM limit (including envelope and line wrapping), then decode bounded base64 and validate PKCS#10 structure before authentication or database work.
  • Produce certs-only PKCS#7 with the maintained RustCrypto cms implementation.
  • Map serverkeygen to the existing generated-key issuance path and return a one-time PKCS#8 key in multipart/mixed.
  • Resolve CSR requirements through the enrollment service and encode RFC 7030 CSRAttrs.
  • Reuse PR-003's trust-bundle source for cacerts.
  • Observe service-level failures from simpleenroll, simplereenroll, and serverkeygen through the existing structured audit/outbox path with non-sensitive EST metadata.
  • Add operator and API documentation.
  • Add CI provisioning for the pinned independent GlobalSign EST client.

The only supporting enrollment-service changes are transport-neutral entry points for existing generated issuance and applicable-profile CSR requirements; authorization, scope, issuer selection, profile selection, rate limits, persistence, and audit decisions remain outside the adapter.

Acceptance criteria validation

  • A standard EST client enrolls and re-enrolls without Atom-specific protocol code. tests/m41_pki_est.rs invokes GlobalSign estclient v1.0.7 for cacerts, enroll, reenroll, and serverkeygen; CI execution is pending.
  • EST and native issuance have equivalent profile, issuer, and identity. The parity assertion compares issuer/profile IDs, identity URI, key usage, EKU, basic constraints, and identity SAN through the shared service path.
  • simplereenroll accepts only the certificate being replaced and rejects expired or revoked credentials. The route accepts only VerifiedPeerCertificate; the integration test covers successful exact-leaf renewal plus revoked and database-expired rejection.
  • Clients cannot select issuer, tenant, or profile. Scope comes from authentication; selector query/header attempts are ignored and an additional-path selector returns 404. Cross-tenant assertions prove issuance stays in the authenticated subject's tenant.
  • cacerts matches PR-003's trust bundle. The endpoint reads provisioning::trust_bundle; the independent client decodes CMS and the test compares sorted SHA-256 certificate fingerprints.
  • Malformed PKCS#10, oversized bodies, and invalid base64 fail cheaply. Media type, exact DER-to-PEM capacity, encoded size, base64, decoded size, and structural DER checks run before authentication/service calls; tests cover the exact boundary plus 400, 413, and 415 outcomes.
  • No enrollment logic is in the EST adapter. The adapter owns only authentication, bounded wire decoding, RFC encodings, and response mapping; policy and lifecycle decisions remain in the enrollment/certificate services.

Mandatory tests

  • Independent client interoperability: GlobalSign estclient v1.0.7 is pinned and built by CI.
  • Enroll and re-enroll flows: implemented in m41_pki_est.
  • Expired and revoked re-enrollment rejection: implemented in m41_pki_est.
  • serverkeygen key handling and one-time delivery: two independently parsed responses prove key/certificate matching, unique keys, and absence from persisted metadata.
  • csrattrs correctness: exact P-256 RFC CSRAttrs DER and applicable-profile requirements are asserted.
  • cacerts agreement: independently decoded fingerprint sets are asserted.
  • Cross-tenant attempts: authenticated-scope issuer/profile/tenant assertions plus selector injection coverage.
  • Malformed input: invalid base64, malformed DER, oversized request, wrong media type, and forged peer header coverage.
  • Native-adapter parity: issuer, profile, identity, and extension-shape assertions.

Local commands and results:

  • cargo fmt --check — PASS.
  • cargo test --no-run --locked — PASS for all library, binary, and integration-test targets with the available Rust 1.92 nightly compiler.
  • cargo test --lib certs::enrollment::est::tests --locked — PASS (3 tests, including the exact DER/PEM boundary).
  • cargo test --lib --locked — PASS (163 passed, 11 ignored).
  • cargo clippy --tests --locked -- -D warnings -A clippy::nonminimal_bool -A clippy::const_is_empty — PASS; the two allowances are local-only for newer-nightly findings in unchanged pre-existing code and are not present in source or CI.
  • git diff --check — PASS.
  • go install github.com/globalsign/est/cmd/estclient@v1.0.7 with Go 1.26.5 — PASS.
  • ATOM_EST_CLIENT=... DATABASE_URL=... cargo test --test m41_pki_est --locked -- --include-ignored --test-threads=1 reached and applied all repository migrations against PGlite with pgcrypto, then stopped because PGlite's multiplexed connections reuse SQLx prepared-statement names. No EST assertion ran in that emulator. The test remains enabled and hosted CI supplies real PostgreSQL 16.

Additional validation

  • Reviewed the complete diff against PR-014b scope, non-goals, adapter boundaries, tenant isolation, sensitive-key handling, and error ordering.
  • Verified the published Git tree exactly matches the reviewed local commit tree.
  • Verified the GlobalSign client builds with Go 1.26.5 and inspected its command flags for all invoked operations.
  • Verified the maintained CMS encoder compiles and its exact response is exercised by the independent client test.

Review corrections

  • Every EST mutation now calls audit::observe_error only on the service Err branch. The PostgreSQL interoperability test forces failures in all three mutation routes and verifies event, outcome, transport, and mode without persisting CSR, certificate, or key material.
  • The EST decoder no longer treats the configured PEM byte limit as a DER limit. A tested binary-search boundary includes the PEM header/footer, base64 expansion, 64-column wrapping, and line breaks, so any accepted DER request is accepted by the shared enrollment service.
  • Formatting, complete test compilation, the focused EST unit suite, clippy for changed code, and diff checks were rerun after these corrections and passed. Hosted CI supplies PostgreSQL 16 for the ignored independent-client test.

Non-goals

No TLS-SRP, EST-over-CoAP, arbitrary EST operations, additional-path routing, ACME state, or client-selectable tenant/issuer/profile behavior was added.

Compatibility and risks

  • Existing native enrollment routes and request/response contracts are unchanged.
  • No database migration or persistent protocol state is introduced.
  • EST remains opt-in behind the existing enrollment listener configuration and generated-key issuance retains its existing feature gate.
  • Private keys are represented by the existing redacted, zeroizing one-time type, encoded into the response, never persisted, and never logged.
  • The EST body limit is derived from the largest DER request whose canonical PEM representation fits the shared service limit; the decoder independently enforces encoded and decoded bounds.
  • CI adds a pinned Go-built interoperability dependency; application runtime and deployment images do not gain a Go dependency.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
atom-docs e5fb49b Commit Preview URL

Branch Preview URL
Aug 06 2026, 06:25 PM

@arvindh123
arvindh123 marked this pull request as ready for review August 6, 2026 18:07
@arvindh123 arvindh123 closed this Aug 6, 2026
@arvindh123 arvindh123 reopened this Aug 6, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0496b386b4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/certs/enrollment/est.rs Outdated
Comment thread src/certs/enrollment/est.rs Outdated
@arvindh123 arvindh123 closed this Aug 6, 2026
@arvindh123 arvindh123 reopened this Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Please review the latest head after the resolved EST failure-observation and DER/PEM boundary regressions.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@arvindh123 arvindh123 closed this Aug 6, 2026
@arvindh123 arvindh123 reopened this Aug 6, 2026
@dborovcanin

Copy link
Copy Markdown
Contributor

@arvindh123 please fix CI. @SammyOina please review.

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

Successfully merging this pull request may close these issues.

2 participants