Skip to content
Snippets Groups Projects
server.go 3.65 KiB
Newer Older
  • Learn to ignore specific revisions
  • package server
    
    
    import (
    	"encoding/json"
    
    	"net/http"
    
    	"code.fbi.h-da.de/danet/quant/goKMS/config"
    
    	"code.fbi.h-da.de/danet/quant/goKMS/kms/event"
    
    	"code.fbi.h-da.de/danet/quant/goKMS/kms/receiver"
    
    	kmstls "code.fbi.h-da.de/danet/quant/goKMS/kms/tls"
    
    	"github.com/google/uuid"
    
    	"github.com/sirupsen/logrus"
    )
    
    type AKMSReceiverServer struct {
    
    	server    *http.Server
    	tlsConfig config.TLSConfig
    
    func NewAKMSReceiver(port string, eventBus *event.EventBus, receiver *receiver.Receiver, generateAndSend func(string, uuid.UUID, string, int) error, tlsConfig config.TLSConfig) (*AKMSReceiverServer, error) {
    
    	router := http.NewServeMux()
    
    
    	router.HandleFunc("/api/v1/keys/ksa_key_req", ksaReqHandler(eventBus, receiver, generateAndSend))
    
    
    	server := &http.Server{
    		Addr:    ":" + port,
    		Handler: router,
    	}
    
    
    	if tlsConfig.Active {
    		tlsLibraryConfig, err := kmstls.GenerateServerTLSLibraryConfig(tlsConfig)
    		if err != nil {
    			return nil, fmt.Errorf("unable to generate TLS config: %w", err)
    		}
    		server.TLSConfig = tlsLibraryConfig
    	}
    
    
    	AKMSReceiver := &AKMSReceiverServer{
    
    		server:    server,
    		tlsConfig: tlsConfig,
    
    	return AKMSReceiver, nil
    
    }
    
    func (akmsReceiver *AKMSReceiverServer) Serve() {
    
    	if akmsReceiver.tlsConfig.Active {
    		go akmsReceiver.server.ListenAndServeTLS("", "") //nolint:errcheck
    	} else {
    		go akmsReceiver.server.ListenAndServe() //nolint:errcheck
    	}
    
    }
    
    type KeyProperties struct {
    	Number    int `json:"number"`
    	KeyLength int `json:"key_length"`
    	Timeout   int `json:"timeout"`
    	TTL       int `json:"TTL"`
    }
    
    type KMSKeyRequest struct {
    
    Neil-Jocelyn Schark's avatar
    Neil-Jocelyn Schark committed
    	ReceivingCKMSID string        `json:"receiving_CKMS_ID"`
    	RequestID       string        `json:"request_ID"`
    	KeyProperties   KeyProperties `json:"key_properties"`
    
    func ksaReqHandler(eventBus *event.EventBus, receiver *receiver.Receiver, generateAndSend func(string, uuid.UUID, string, int) error) http.HandlerFunc {
    
    	return func(w http.ResponseWriter, r *http.Request) {
    		var kmsKeyRequest KMSKeyRequest
    		err := json.NewDecoder(r.Body).Decode(&kmsKeyRequest)
    		if err != nil {
    			http.Error(w, err.Error(), http.StatusBadRequest)
    
    			logrus.Errorf("error decoding ksa key request: %s", err)
    
    		logrus.Debugf("received KSA key request for receiving CKMS %s, request ID %s, and key properties %v",
    
    Neil-Jocelyn Schark's avatar
    Neil-Jocelyn Schark committed
    			kmsKeyRequest.ReceivingCKMSID, kmsKeyRequest.RequestID, kmsKeyRequest.KeyProperties)
    
    		pathId := uuid.New()
    
    
    		logrus.Debugf("created new path id: %s, for incoming KSA key request", pathId)
    
    
    		receiverChan, err := receiver.RequestReceiverChannel(pathId)
    
    		if err != nil {
    			http.Error(w, err.Error(), http.StatusInternalServerError)
    		}
    
    
    		err = eventBus.Publish(event.NewCreateRouteEvent(pathId.String(), kmsKeyRequest.ReceivingCKMSID))
    
    Neil-Jocelyn Schark's avatar
    Neil-Jocelyn Schark committed
    		if err != nil {
    			http.Error(w, err.Error(), http.StatusInternalServerError)
    
    			logrus.Errorf("Failed sending a create route request: %s", err)
    
    Neil-Jocelyn Schark's avatar
    Neil-Jocelyn Schark committed
    			return
    
    		select {
    		case <-receiverChan:
    		case <-time.After(20 * time.Second):
    
    			if err := receiver.RemoveReceiver(pathId); err != nil {
    				logrus.Errorf("Failed removing receiver for pathId: %s ; err: %v", pathId, err)
    			}
    
    			http.Error(w, fmt.Sprintf("Platform Key exchange failed for RequestID: %s", kmsKeyRequest.RequestID), http.StatusInternalServerError)
    			logrus.Errorf("Platform Key exchange failed for RequestID: %s", kmsKeyRequest.RequestID)
    			return
    		}
    
    
    		err = generateAndSend(kmsKeyRequest.ReceivingCKMSID, pathId, kmsKeyRequest.RequestID, kmsKeyRequest.KeyProperties.Number)
    
    		if err != nil {
    			http.Error(w, err.Error(), http.StatusInternalServerError)
    			logrus.Errorf("error generating and sending KSA key: %s", err)
    			return
    		}
    
    		logrus.Info("requested all keys")
    		w.WriteHeader(http.StatusNoContent)
    	}
    }