From a2fbf6f866770b3891581197b025643c6e242468 Mon Sep 17 00:00:00 2001 From: Malte Bauch <malte.bauch@stud.h-da.de> Date: Wed, 19 Jul 2023 09:39:02 +0000 Subject: [PATCH] Wg3 --- go.mod | 2 +- go.sum | 4 +- kms/kms-keystore.go | 12 +++--- kms/kms.go | 12 ++++-- kms/kmsetsi.go | 37 ++++++++++++++++-- kms/kmspeers.go | 92 ++++++++++++++++++++++++++++++++++++--------- kms/util.go | 16 ++++++++ 7 files changed, 140 insertions(+), 35 deletions(-) create mode 100644 kms/util.go diff --git a/go.mod b/go.mod index 898522e..117c183 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/google/uuid v1.3.0 - google.golang.org/grpc v1.56.1 + google.golang.org/grpc v1.56.2 google.golang.org/protobuf v1.31.0 ) diff --git a/go.sum b/go.sum index c53bd58..dd5cac2 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= -google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= diff --git a/kms/kms-keystore.go b/kms/kms-keystore.go index bdf7240..c04cfbf 100644 --- a/kms/kms-keystore.go +++ b/kms/kms-keystore.go @@ -22,7 +22,7 @@ type kmsKSElement struct { type kmsKeyStore struct { keyStoreMutex sync.Mutex - keyStore map[string]kmsKSElement + keyStore map[string]*kmsKSElement } func (ks *kmsKeyStore) addKey(bulkKeyId int64, keyToadd []byte) { @@ -40,7 +40,7 @@ func (ks *kmsKeyStore) addKey(bulkKeyId int64, keyToadd []byte) { return } // ok to add - ks.keyStore[newKeyElement.keyID] = newKeyElement + ks.keyStore[newKeyElement.keyID] = &newKeyElement } @@ -54,13 +54,11 @@ func (ks *kmsKeyStore) KeyChopper256Bit(bulkKey *quantumlayer.QuantumLayerBulkKe // Let's chop! key := *bulkKey.BulkKey - for len(key) > 8 { - tmpkey := key[:8] + for len(key) > 32 { + tmpkey := key[:32] ks.addKey(bulkKey.BulkKeyId, tmpkey) // shorten the key storage - key = key[8:] - + key = key[32:] } return nil - } diff --git a/kms/kms.go b/kms/kms.go index 11fd477..73eadff 100644 --- a/kms/kms.go +++ b/kms/kms.go @@ -80,10 +80,10 @@ func (kms *EKMS) AddQuantumElement(kmsUDPAddrr string) *QuantumElement { ql.PowerOn() ksl := kmsKeyStore{ - keyStore: make(map[string]kmsKSElement), + keyStore: make(map[string]*kmsKSElement), } ksr := kmsKeyStore{ - keyStore: make(map[string]kmsKSElement), + keyStore: make(map[string]*kmsKSElement), } qle := QuantumElement{ @@ -181,7 +181,13 @@ func (kms *EKMS) AddPeer(kmsPeerSocket string, servingQLE *QuantumElement) { // TODO/XXX error handling func (kms *EKMS) RemovePeer(kmsPeerSocket string) { - + if _, there := kms.KmsPeers[kmsPeerSocket]; there { + //peer.quit <- true + delete(kms.KmsPeers, kmsPeerSocket) + return + } + log.Printf("Can not find a peer with socekt: %s", kmsPeerSocket) + return } func (kms *EKMS) AddExternalNotifierQLE(in chan uint32) { diff --git a/kms/kmsetsi.go b/kms/kmsetsi.go index 6351d30..cc5ac8e 100644 --- a/kms/kmsetsi.go +++ b/kms/kmsetsi.go @@ -2,14 +2,18 @@ package kms import ( "context" + "encoding/base64" "errors" "flag" "fmt" "log" "net" + "os/exec" pb "code.fbi.h-da.de/demoquandt/proto-kms/api/gen/proto/go/kmsetsi" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -19,6 +23,7 @@ var ( type etsiServer struct { pb.UnimplementedKmsETSIServer handlingEkms *EKMS + visitedKeys map[*kmsKSElement]bool } func (es *etsiServer) ETSICapabilities(ctx context.Context, in *pb.ETSICapabilitiesRequest) (capReply *pb.ETSICapabilitiesReply, err error) { @@ -92,15 +97,38 @@ func (es *etsiServer) ETSIGetPeerList(ctx context.Context, in *pb.ETSIKMSPeerLis return r, nil } -func (es *etsiServer) GetEncryptKeys256Bit(ctx context.Context, in *pb.ETSIGetEncryptKeys256BitRequest) (*pb.ETSIGetEncryptKeys256BitReply, error) { +func (es *etsiServer) ETSIGetEncryptKeys256Bit(ctx context.Context, in *pb.ETSIGetEncryptKeys256BitRequest) (*pb.ETSIGetEncryptKeys256BitReply, error) { log.Printf("Received request for n=%d keys", in.GetAmount()) - testBytes := []byte{120, 120, 120} + var randomKey *kmsKSElement + var err error + // NOTE: change change change! + for _, qe := range es.handlingEkms.QuantumElements { + quantumElementLocalKeyStore := qe.keyStoreLocal + randomKey, err = randomItemFromMap[string, *kmsKSElement](quantumElementLocalKeyStore.keyStore, es.visitedKeys) + if err != nil { + return nil, status.Errorf(codes.Internal, "%v", err) + } + es.visitedKeys[randomKey] = true + } + + keyAsString := base64.StdEncoding.EncodeToString(randomKey.key) + // push the key to the encryptor via ssh + ssh := "ssh" + complexArg := fmt.Sprintf("(rc=$(sed \"12 c PresharedKey = %s\" /etc/wireguard/wg0.conf); echo \"$rc\" > /etc/wireguard/wg0.conf)", keyAsString) + args := []string{"root@172.20.0.5", "-oStrictHostKeyChecking=no", complexArg} + + cmd := exec.Command(ssh, args...) + err = cmd.Run() + if err != nil { + log.Println("could not execute command") + return nil, status.Errorf(codes.Internal, "%v", err) + } // Construct any response return &pb.ETSIGetEncryptKeys256BitReply{ - KeyID: "2", - Key: testBytes, + KeyID: randomKey.keyID, + Key: randomKey.key, }, nil } @@ -115,6 +143,7 @@ func StartETSI(listenAddr string, callingKMS *EKMS) { s := grpc.NewServer() pb.RegisterKmsETSIServer(s, &etsiServer{ handlingEkms: callingKMS, + visitedKeys: make(map[*kmsKSElement]bool), }) log.Printf("server listening at %v", lis.Addr()) if err := s.Serve(lis); err != nil { diff --git a/kms/kmspeers.go b/kms/kmspeers.go index d3089f3..65207e2 100644 --- a/kms/kmspeers.go +++ b/kms/kmspeers.go @@ -2,8 +2,11 @@ package kms import ( "context" + "encoding/base64" + "fmt" "log" "net" + "os/exec" "time" pb "code.fbi.h-da.de/demoquandt/proto-kms/api/gen/proto/go/kmsetsi" @@ -35,6 +38,7 @@ type kmsPeer struct { tcpSocketStr string // string rep. of tcpSocket name string // the name of the kms peer id uuid.UUID // uuid of the peer + quit chan bool // cancel the peer goroutine } func NewKmsPeer(servQLE *QuantumElement, in chan string) (peer kmsPeer) { @@ -43,12 +47,12 @@ func NewKmsPeer(servQLE *QuantumElement, in chan string) (peer kmsPeer) { servingQLE: servQLE, id: uuid.New(), externalNotifierKMSPeer: in, + quit: make(chan bool), } } // Handles everything with respect to a specific KMS peer func (ph *kmsPeer) PeerHandler(kmsName string) { - log.Printf("%s started PeerHandler for %s:", kmsName, ph.tcpSocketStr) // contact peer @@ -73,11 +77,58 @@ func (ph *kmsPeer) PeerHandler(kmsName string) { if ph.externalNotifierKMSPeer != nil { ph.externalNotifierKMSPeer <- ph.tcpSocketStr } - return } + + // NOTE: If a session is created, we also request a encryption key for now + //quantumElementRequest, err := c.ETSIGetQuantumInterfaces(ctx, &pb.ETSIKMSQuantumInterfaceListRequest{}) + //if err != nil { + // log.Println("Could not request quantum elements: ", err) + // ph.peerStatus = KmsPeerDown + // // Send notification about change + // if ph.externalNotifierKMSPeer != nil { + // ph.externalNotifierKMSPeer <- ph.tcpSocketStr + // } + // return + //} + + //if quantumElementRequest.QlElementInfo != nil { + // peerQuantumElement := quantumElementRequest.QlElementInfo[0].QleID + //} else { + // // return error?! + //} + // Works and peer moves to kmsPeerUp ph.peerStatus = KmsPeerUp + encryptKeyRequest, err := c.ETSIGetEncryptKeys256Bit(ctx, &pb.ETSIGetEncryptKeys256BitRequest{Amount: 1}) + if err != nil { + log.Println("could not request a encryption key: ", err) + ph.peerStatus = KmsPeerDown + // Send notification about change + if ph.externalNotifierKMSPeer != nil { + ph.externalNotifierKMSPeer <- ph.tcpSocketStr + } + return + } + + // check if key is in remoteKeyStore + if key, ok := ph.servingQLE.keyStoreRemote.keyStore[encryptKeyRequest.KeyID]; ok { + keyAsString := base64.StdEncoding.EncodeToString(key.key) + log.Printf("Agreed Key: %s", keyAsString) + + // push the key to the encryptor via ssh + ssh := "ssh" + complexArg := fmt.Sprintf("(rc=$(sed \"12 c PresharedKey = %s\" /etc/wireguard/wg0.conf); echo \"$rc\" > /etc/wireguard/wg0.conf)", keyAsString) + args := []string{"root@172.20.0.4", "-oStrictHostKeyChecking=no", complexArg} + + cmd := exec.Command(ssh, args...) + err := cmd.Run() + if err != nil { + log.Println("could not execute command") + return + } + } + // Send notification about change if ph.externalNotifierKMSPeer != nil { ph.externalNotifierKMSPeer <- ph.tcpSocketStr @@ -85,23 +136,28 @@ func (ph *kmsPeer) PeerHandler(kmsName string) { log.Printf("Greeting: %s which is now in peerStatus %d", r.GetPeerKmsName(), ph.peerStatus) + // NOTE: should be possible to cancel! // By now, do check only the liveliness of the peer, nothing else. - for { - time.Sleep(30 * time.Second) - // Contact the server and print out its response. - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - _, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName}) - if err != nil { - log.Printf("could not greet: %v", err) - ph.peerStatus = KmsPeerDown - // Send notification about change - if ph.externalNotifierKMSPeer != nil { - ph.externalNotifierKMSPeer <- ph.tcpSocketStr - } - } - - } + //for { + // select { + // case <-ph.quit: + // return + // default: + // // Contact the server and print out its response. + // ctx, cancel := context.WithTimeout(context.Background(), time.Second) + // defer cancel() + // _, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName}) + // if err != nil { + // log.Printf("could not greet: %v", err) + // ph.peerStatus = KmsPeerDown + // // Send notification about change + // if ph.externalNotifierKMSPeer != nil { + // ph.externalNotifierKMSPeer <- ph.tcpSocketStr + // } + // } + // time.Sleep(30 * time.Second) + // } + //} } func (ph *kmsPeer) GetKmsPeerStatus() KmsPeerStatus { diff --git a/kms/util.go b/kms/util.go new file mode 100644 index 0000000..b9b5c35 --- /dev/null +++ b/kms/util.go @@ -0,0 +1,16 @@ +package kms + +import "fmt" + +// Ewww... don't +func randomItemFromMap[T, M comparable](m map[T]M, v map[M]bool) (M, error) { + for _, item := range m { + if v[item] { + continue + } + return item, nil + } + + var r M + return r, fmt.Errorf("Could not return a random item from map %v", m) +} -- GitLab