diff --git a/go.mod b/go.mod index 8628f46fafb45b308fa95a0247ffe2eda56ed629..88c297be87bdc3b80e5d33beae02f9d51c3b0609 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,22 @@ module code.fbi.h-da.de/danet/proto-kms -go 1.20 +go 1.21 require ( - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/sirupsen/logrus v1.9.3 - google.golang.org/grpc v1.56.2 + google.golang.org/grpc v1.58.2 google.golang.org/protobuf v1.31.0 ) require ( + code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/golang/protobuf v1.5.3 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/stretchr/testify v1.8.4 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect ) diff --git a/go.sum b/go.sum index d03b5e77e82b5bd48952a6ba0acdbdf4d461bc2c..ae1df24502653a73e8917bc1b557cdad887315ca 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,49 @@ +code.fbi.h-da.de/danet/ekms v0.0.0-20231027141805-c77e2d25accb h1:6PbnWyn8QwhZWPVN5L3cSO148gGxk7X5GGYkL5awMl8= +code.fbi.h-da.de/danet/ekms v0.0.0-20231027141805-c77e2d25accb/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= +code.fbi.h-da.de/danet/ekms v0.0.0-20231030172039-48ca51ab722d h1:wfjIMNVdMf0fr1xMgNwImlE9UsWgDBRj/bQY9QtzlW8= +code.fbi.h-da.de/danet/ekms v0.0.0-20231030172039-48ca51ab722d/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= +code.fbi.h-da.de/danet/ekms v0.0.0-20231030180651-55420c3dc33f h1:JXRwaYLIcQ1uuH1PVRJ8jcXvLjXKmup2RLlDpnUYqvo= +code.fbi.h-da.de/danet/ekms v0.0.0-20231030180651-55420c3dc33f/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= +code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617 h1:tceO3twY87RXD5Jet7YZdC0SXo5NuWHr0IZ/IvCO/0s= +code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 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.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= -google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= 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= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/kms/kmsintercom.go b/kms/kmsintercom.go index 78cd85502e2d52c17534f794e26bad77a36ad27e..7076f2782ac1a43349906703d5dde62ced521824 100644 --- a/kms/kmsintercom.go +++ b/kms/kmsintercom.go @@ -4,12 +4,14 @@ import ( "context" "encoding/base64" "flag" + "io/ioutil" "net" "time" "github.com/google/uuid" log "github.com/sirupsen/logrus" + etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client" pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -38,6 +40,52 @@ func (s *kmsTalkerServer) InterComCapabilities(ctx context.Context, in *pb.Inter }, nil } +func (s *kmsTalkerServer) KeyIdNotification(ctx context.Context, in *pb.KeyIdNotificationRequest) (*pb.KeyIdNotificationResponse, error) { + // check if a peer exists + peer, ok := s.eKMS.KmsPeers[in.GetInterComAddr()] + if !ok { + //TODO: proper error message + return nil, status.Error(codes.Internal, "peer does not exist") + } + + eqm, ok := peer.servingQuantumModul.(*ETSI014HTTPQuantumModule) + if !ok { + return nil, status.Error(codes.Internal, "expected etsi014 quantum module") + } + + etsi14KeyIds := make([]etsi14.KeyIDsRequestKeyIDsInner, len(in.KeyIds)) + for i, keyid := range in.KeyIds { + etsi14KeyIds[i] = etsi14.KeyIDsRequestKeyIDsInner{ + KeyID: keyid, + } + } + + keyContainer, resp, err := eqm.client.GetKeyWithIdPost(eqm.masterSAEID, etsi14KeyIds) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + // TODO: add proper status code handling + if resp.StatusCode != 200 { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return nil, status.Error(codes.Aborted, string(body)) + } + + // TODO: could be run in go routine + if err := addETSIKeysToKeystore(eqm.keyStore, keyContainer.GetKeys()); err != nil { + return nil, status.Error(codes.Internal, "expected etsi014 quantum module") + } + + return &pb.KeyIdNotificationResponse{ + Timestamp: time.Now().Unix(), + }, nil +} + // TODO: should be removed as soon as the emulated quantum module has been // changed; is specific for emulated quantum module func (s *kmsTalkerServer) SyncQkdBulk(ctx context.Context, in *pb.SyncQkdBulkRequest) (*pb.SyncQkdBulkResponse, error) { diff --git a/kms/module.go b/kms/module.go index 736cc6858345ed51f63a614e2b2d9a99d4b8cdac..dd0a5a23790cbf19563678676703943b8316f6ca 100644 --- a/kms/module.go +++ b/kms/module.go @@ -6,9 +6,12 @@ import ( "fmt" "io" "net" + "net/url" "sync" "time" + etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client" + restclient "code.fbi.h-da.de/danet/ekms/restclient" pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom" "code.fbi.h-da.de/danet/proto-kms/quantumlayer" "github.com/google/uuid" @@ -174,7 +177,114 @@ func (eqe *EmulatedQuantumModule) KeyChopper(bulkKey *quantumlayer.QuantumLayerB } type ETSI014HTTPQuantumModule struct { - id uuid.UUID - keyStore *kmsKeyStore - peer *kmsPeer + id uuid.UUID + keyStore *kmsKeyStore + peer *kmsPeer + client *restclient.ClientImpl + slaveSAEID string + masterSAEID string +} + +func NewETSI014HTTPQuantumModule(addr, slaveSAEID, masterSAEID string) (*ETSI014HTTPQuantumModule, error) { + parsedUrl, err := url.Parse("http://" + addr) + if err != nil { + return nil, err + } + + restClientConf := &etsi14.Configuration{ + Debug: true, + Servers: etsi14.ServerConfigurations{ + { + URL: parsedUrl.String(), + Description: "QKD Module with ETSI14 implemented as API.", + }, + }, + Scheme: parsedUrl.Scheme, + // HTTPClient: &http.Client{ + // Transport: &http.Transport{ + // TLSClientConfig: &tls.Config{}, + // }, + // }, + } + + // TODO: we might want to add mastersaeid here aswell + client, err := restclient.NewClientImpl(slaveSAEID, restClientConf) + if err != nil { + return nil, err + } + + return &ETSI014HTTPQuantumModule{ + id: uuid.New(), + keyStore: NewKmsKeyStore(256), + peer: nil, + client: client, + slaveSAEID: slaveSAEID, + masterSAEID: masterSAEID, + }, nil +} + +func (eqe *ETSI014HTTPQuantumModule) ID() uuid.UUID { + return eqe.id +} + +func (eqe *ETSI014HTTPQuantumModule) Initialize() error { + // start polling + go func() { + ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() + + // TODO: add context/channel to stop + for { + select { + case <-ticker.C: + container, _, err := eqe.client.GetKey() + if err != nil { + log.Error(err) + break + } + + keyIds := make([]string, len(container.GetKeys())) + for i, keyItem := range container.GetKeys() { + keyIds[i] = keyItem.GetKeyID() + } + + _, err = eqe.peer.peerClient.KeyIdNotification(context.Background(), + &pbIC.KeyIdNotificationRequest{ + Timestamp: time.Now().Unix(), + InterComAddr: eqe.peer.interComAddr, + KeyIds: keyIds, + }) + if err != nil { + log.Error(err) + break + } + + if err := addETSIKeysToKeystore(eqe.keyStore, container.GetKeys()); err != nil { + log.Error(err) + break + } + } + } + }() + return nil +} + +func (eqe *ETSI014HTTPQuantumModule) Address() net.Addr { + return nil +} + +func (eqe *ETSI014HTTPQuantumModule) KeyStore() *kmsKeyStore { + return eqe.keyStore +} + +func (eqe *ETSI014HTTPQuantumModule) Peer() *kmsPeer { + return eqe.peer +} + +func (eqe *ETSI014HTTPQuantumModule) SetPeer(peer *kmsPeer) { + eqe.peer = peer +} + +func (eqe *ETSI014HTTPQuantumModule) Sync() error { + return nil } diff --git a/kms/util.go b/kms/util.go index 696ab67a597dca78b97158191ad130884e484376..c17bf87f27edd757c57e11ad9cebabe6d0f02a44 100644 --- a/kms/util.go +++ b/kms/util.go @@ -2,8 +2,12 @@ package kms import ( "bytes" + "encoding/base64" "fmt" "net/http" + "strconv" + + etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client" ) func randomItemFromMap[T comparable, M any](m map[T]M) (M, error) { @@ -37,6 +41,29 @@ func keysOfMap[T comparable, M any](m map[T]M) []T { return keys } +func addETSIKeysToKeystore(keyStore *kmsKeyStore, keyContainer []etsi14.KeyContainerKeysInner) error { + for _, keyItem := range keyContainer { + // decode base64 encoded key string + key, err := base64.StdEncoding.DecodeString(keyItem.GetKey()) + if err != nil { + return err + } + + // key id to uint + keyId := keyItem.GetKeyID() + keyIdUint, err := strconv.ParseUint(keyId, 10, 64) + if err != nil { + return err + } + + // add to keystore + keyStore.keyStoreMutex.Lock() + keyStore.addKey(keyIdUint, key) + keyStore.keyStoreMutex.Unlock() + } + return nil +} + // NOTE: For demo purpose only func sendKmsInfoMessage(url string, json []byte) error { request, err := http.NewRequest("POST", url, bytes.NewBuffer(json)) diff --git a/main_test.go b/main_test.go index da2e697a1fbe6d889f2f3af8a08641b58f29f731..1ce88b4aa61f521bc8d2af59029be237121ef4de 100644 --- a/main_test.go +++ b/main_test.go @@ -88,9 +88,6 @@ func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAdd // Start the SDN/management and key retrieval interface go kms.StartETSI(myUDPAddr, emuKMS) - - // // TODO/XXX catch errors! - // emuKMS.GlobalKeyHandler(7 * time.Second) } func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, rightUDPAddr, rightInterComAddr string) {