constellation/hack/image-measurement/server/server.go
Fabian Kammel bb76a4e4c8
AB#2512 Config secrets via env var & config refactoring (#544)
* refactor measurements to use consistent types and less byte pushing
* refactor: only rely on a single multierr dependency
* extend config creation with envar support
* document changes
Signed-off-by: Fabian Kammel <fk@edgeless.systems>
2022-11-15 15:40:49 +01:00

96 lines
2.2 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package server
import (
"context"
"encoding/json"
"net"
"net/http"
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
"github.com/edgelesssys/constellation/v2/internal/logger"
"go.uber.org/zap"
)
// Server provides measurements.
type Server struct {
log *logger.Logger
server http.Server
measurements measurements.M
done chan<- struct{}
}
// New creates a new Server.
func New(log *logger.Logger, done chan<- struct{}) *Server {
return &Server{
log: log,
done: done,
}
}
// ListenAndServe on given port.
func (s *Server) ListenAndServe(port string) error {
mux := http.NewServeMux()
mux.Handle("/pcrs", http.HandlerFunc(s.logPCRs))
s.server = http.Server{
Handler: mux,
}
lis, err := net.Listen("tcp", net.JoinHostPort("", port))
if err != nil {
return err
}
s.log.Infof("Starting QEMU metadata API on %s", lis.Addr())
return s.server.Serve(lis)
}
// Shutdown server.
func (s *Server) Shutdown() error {
return s.server.Shutdown(context.Background())
}
// logPCRs allows QEMU instances to export their TPM state during boot.
func (s *Server) logPCRs(w http.ResponseWriter, r *http.Request) {
log := s.log.With(zap.String("peer", r.RemoteAddr))
if r.Method != http.MethodPost {
log.With(zap.String("method", r.Method)).Errorf("Invalid method for /log")
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
log.Infof("Serving POST request for /pcrs")
if r.Body == nil {
log.Errorf("Request body is empty")
http.Error(w, "Request body is empty", http.StatusBadRequest)
return
}
// unmarshal the request body into a map of PCRs
var pcrs measurements.M
if err := json.NewDecoder(r.Body).Decode(&pcrs); err != nil {
log.With(zap.Error(err)).Errorf("Failed to read request body")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
log.Infof("PCR 4 %x", pcrs[4])
log.Infof("PCR 8 %x", pcrs[8])
log.Infof("PCR 9 %x", pcrs[9])
s.measurements = pcrs
s.done <- struct{}{}
}
// GetMeasurements returns the static measurements for QEMU environment.
func (s *Server) GetMeasurements() measurements.M {
return s.measurements
}