server: HTTP echo + TLS reference (control-plane security measurements)
- POST /v1/echo: returns the received request head + body (base64) and the observed TLS parameters (version, cipher, SNI, ALPN, resumed). The client diffs against what it sent to detect header injection/stripping, transparent proxying, or TLS interception (sec.http_echo). http-echo added to the capability set. - GET /v1/tls-reference: the served leaf-first DER chain + pin, so the app can compare an out-of-band copy against its own handshake (sec.tls_reference). Always available, no auth — public handshake info. - Optional CLEARTEXT http-echo listener (ECHOLOT_HTTP_ECHO_LISTEN, default off) exposing only /v1/echo for the plaintext-path tampering test. Live-smoke-tested (HTTPS echo reflected an injected header + observed TLS1.3; cleartext variant reports tls:none); httptest unit tests added. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
379153219e
commit
38fb73c34e
@@ -41,6 +41,8 @@ type Server struct {
|
||||
StunPort int
|
||||
// SPKI pin of the serving cert, for the profile's pins[] field.
|
||||
PinB64 string
|
||||
// CertChain is the served leaf-first DER chain, for GET /v1/tls-reference.
|
||||
CertChain [][]byte
|
||||
// Capabilities as computed at startup from what is actually wired up.
|
||||
Capabilities []string
|
||||
// TCPRecent returns recent TCP-echo connections for a source IP (may be nil).
|
||||
@@ -61,11 +63,21 @@ func (s *Server) Handler() http.Handler {
|
||||
mux.HandleFunc("DELETE /v1/sessions/{id}", s.deleteSession)
|
||||
mux.HandleFunc("GET /v1/sessions/{id}/observations", s.observations)
|
||||
mux.HandleFunc("POST /v1/sessions/{id}/actions", s.actions)
|
||||
// TODO(spec §4): POST /v1/echo, GET /v1/tls-reference; TLS-echo/JA4
|
||||
mux.HandleFunc("POST /v1/echo", s.httpEcho)
|
||||
mux.HandleFunc("GET /v1/tls-reference", s.tlsReference)
|
||||
// TODO(spec §4): TLS-echo/JA4 (tls-echo capability, needs ClientHello capture)
|
||||
// TODO(spec §5): downtrain, big_send, frag_send, throughput
|
||||
return mux
|
||||
}
|
||||
|
||||
// EchoHandler exposes just the HTTP-echo endpoint for the optional cleartext
|
||||
// listener (spec §4: plaintext-path tampering test).
|
||||
func (s *Server) EchoHandler() http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("POST /v1/echo", s.httpEcho)
|
||||
return mux
|
||||
}
|
||||
|
||||
// sessionAuth resolves {id} and requires the bearer to be the owning device.
|
||||
func (s *Server) sessionAuth(w http.ResponseWriter, r *http.Request) *session.Session {
|
||||
dev := s.Store.DeviceByCredential(bearer(r))
|
||||
|
||||
Reference in New Issue
Block a user