Architecture¶
go-pki-est is a protocol layer. The client turns Go calls into EST requests. The server turns EST
requests into calls to a CA interface that your application implements. TLS, the CA itself, the
decision who may enroll and any storage stay with your application.
Components¶
flowchart LR
Client[est.Client or another EST client] -->|TLS or TLS-SRP| Listener[Host TLS listener]
Listener --> Router[Router from NewRouter]
Router --> Hooks[Authentication and check hooks]
Router --> Refusals[RefusalRecorder]
Router --> CA[Host CA]
| Component | Provided by | Role |
|---|---|---|
est.Client |
Library | Connects, signs in and runs one EST operation per call |
| TLS listener | Host | Terminates TLS or TLS-SRP and requests client certificates |
| Router | Library, built by NewRouter |
Checks and decodes requests, checks renewals and encodes responses |
CA |
Host | Returns CA certificates and CSR attributes and issues certificates |
CheckBasicAuth, CheckBearerToken |
Host, optional | Decide who may enroll |
CheckCSRSignature, VerifyClientCertificate |
Host, optional | Replace signature checks that crypto/x509 cannot do |
RefusalRecorder |
Host, optional | Receives the requests the router refuses itself |
Logger |
Host, optional | Receives one entry per request and the server errors |
The router is a plain http.Handler. You serve it with your own http.Server, next to other
handlers if you like. It reads the TLS state from http.Request.TLS and the TLS-SRP username from
the request context, where your listener puts it with WithSRPUsername.
Request handling on the server¶
Every request passes these steps in order. A step that refuses the request answers at once.
- A timeout of
ServerConfig.Timeout, 60 seconds by default, bounds the request context. - A request ID is assigned. With
TrustProxyHeadersthe client address comes fromX-Real-IPorX-Forwarded-For. - The request is logged when it completes. A panic in a handler or in the CA is recovered, logged with its stack and answered with 500.
- The
Server,Strict-Transport-SecurityandX-Content-Type-Optionsheaders are set. - With
AllowedHosts, the Host header must name an allowed host. - The body is limited to
MaxRequestBody, 64 KiB by default. - With
RateLimit, a shared rate limiter answers 429 when it is empty. - An additional path segment longer than 255 bytes answers 414.
- For
POSToperations the content type must match the operation. - For
POSToperations and/healthcheck, authentication runsCheckBearerTokenorCheckBasicAuth. See Authentication. - The operation decodes the body, parses the CSR and checks its signature.
- For
/simplereenrollthe renewal checks compare the request with the client certificate and verify that certificate. - The router calls the CA and encodes its answer or sends its error.
Embedding the server lists the endpoints. Errors lists the status and message of each refusal.
Request handling on the client¶
Each client method:
- Picks a proxy from
Client.Proxyor the environment and opens a TCP connection, through aCONNECTtunnel when a proxy applies. - Runs the TLS handshake with the trust anchors and client certificate or the TLS-SRP
handshake with
SRPUsernameandSRPPassword.OnConnectthen sees the connection. - For
EnrollandReenrollwithSigningKeyset, signs the CSR again with thetls-uniquevalue of this connection as its challenge password. Only TLS 1.2, including TLS-SRP, has that value. Only an RSA or ECDSASigningKeycan sign the new request. - Sends one request with the Basic or bearer credentials and
AdditionalHeaders, throughWrapTransportwhen it is set. - Reads at most
MaxResponseBodybytes, returns any status other than 200 as anest.Errorand decodes the rest.
The connection is closed when the method returns. The client keeps no state between calls, so one
Client value can run any number of operations.
What stays with the host¶
- TLS. The host chooses the server certificate, the TLS versions and which client certificates the handshake accepts.
- The CA. Signing, certificate profiles, revocation and any approval workflow are behind the
CAinterface. - Who may enroll. Without
CheckBasicAuthorCheckBearerTokenevery enrollment request is accepted. - Proof of possession. The router does not check the
tls-uniquechallenge password. A CA that needs the binding checks it. - Retries. A CA that answers 202 with a
Retry-Aftervalue does not get polled. The client returns the status and the value and the caller decides when to try again.