2022-09-12 04:32:01 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
|
2022-09-21 07:47:57 -04:00
|
|
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
2022-09-12 04:32:01 -04:00
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Server struct {
|
2022-09-12 05:04:51 -04:00
|
|
|
log *logger.Logger
|
|
|
|
server http.Server
|
|
|
|
measurements map[uint32][]byte
|
|
|
|
done chan<- struct{}
|
2022-09-12 04:32:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func New(log *logger.Logger, done chan<- struct{}) *Server {
|
|
|
|
return &Server{
|
|
|
|
log: log,
|
|
|
|
done: done,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
|
|
|
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 map[uint32][]byte
|
|
|
|
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])
|
2022-09-12 05:04:51 -04:00
|
|
|
|
|
|
|
s.measurements = pcrs
|
|
|
|
|
2022-09-12 04:32:01 -04:00
|
|
|
s.done <- struct{}{}
|
|
|
|
}
|
2022-09-12 05:04:51 -04:00
|
|
|
|
|
|
|
func (s *Server) GetMeasurements() map[uint32][]byte {
|
|
|
|
return s.measurements
|
|
|
|
}
|