Skip to content
Snippets Groups Projects
Commit 6e044c11 authored by Malte Bauch's avatar Malte Bauch
Browse files

Move quantumlayer in its own repository

parent f9c18bf0
No related branches found
No related tags found
1 merge request!1Move proto kms into ekms
...@@ -3,18 +3,18 @@ module code.fbi.h-da.de/danet/proto-kms ...@@ -3,18 +3,18 @@ module code.fbi.h-da.de/danet/proto-kms
go 1.21 go 1.21
require ( require (
code.fbi.h-da.de/danet/ekms v0.0.0-20231101170413-671634b8e3b3
code.fbi.h-da.de/danet/quipsec/gen/go/quipsec v0.0.0-20231113131315-e0a0cd3d28e3
github.com/google/uuid v1.3.1 github.com/google/uuid v1.3.1
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
google.golang.org/grpc v1.58.2 google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.31.0
) )
require ( require (
code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617 // indirect buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20231030212536-12f9cba37c9d.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect code.fbi.h-da.de/danet/quantumlayer v0.0.0-20231113142846-ae276faa2a9a // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // 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/net v0.15.0 // indirect
golang.org/x/sys v0.13.0 // indirect golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect
......
code.fbi.h-da.de/danet/ekms v0.0.0-20231027141805-c77e2d25accb h1:6PbnWyn8QwhZWPVN5L3cSO148gGxk7X5GGYkL5awMl8= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20231030212536-12f9cba37c9d.2 h1:m8rKyv88R8ZIR1549RMXckZ4FZJGxrq/7aRYl6U3WHc=
code.fbi.h-da.de/danet/ekms v0.0.0-20231027141805-c77e2d25accb/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20231030212536-12f9cba37c9d.2/go.mod h1:xafc+XIsTxTy76GJQ1TKgvJWsSugFBqMaN27WhUblew=
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-20231101170413-671634b8e3b3 h1:ABpjLMNTDQIykwpDQOxBZ9ukm+suBu8oJHqq3GZCzzc=
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-20231101170413-671634b8e3b3/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/quantumlayer v0.0.0-20231113142846-ae276faa2a9a h1:urBXx1zWxvP/0QdEkIbViPqaILJV2BMhPJ34r0d5omk=
code.fbi.h-da.de/danet/ekms v0.0.0-20231030180651-55420c3dc33f/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= code.fbi.h-da.de/danet/quantumlayer v0.0.0-20231113142846-ae276faa2a9a/go.mod h1:L+el1b356QSGNH21HuA0uSqs58Ix5HyySYsTRmsBEaA=
code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617 h1:tceO3twY87RXD5Jet7YZdC0SXo5NuWHr0IZ/IvCO/0s= code.fbi.h-da.de/danet/quipsec/gen/go/quipsec v0.0.0-20231113131315-e0a0cd3d28e3 h1:PXz62uU6MEdcafEZnVwKINPRxSL0y0Ht0Pzp/NSSTew=
code.fbi.h-da.de/danet/ekms v0.0.0-20231031082917-60e1f07a8617/go.mod h1:qVaZ1wGJ+XrE+S3eW1CEB0gAarzClnxYEog06BLnD4k= code.fbi.h-da.de/danet/quipsec/gen/go/quipsec v0.0.0-20231113131315-e0a0cd3d28e3/go.mod h1:lPCd19Jk8aL5B3xSk+h6y5sziXVPqyCXgO7dILvJFfQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
...@@ -37,8 +37,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= ...@@ -37,8 +37,8 @@ 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= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= 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.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 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.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
......
...@@ -7,12 +7,17 @@ package kms ...@@ -7,12 +7,17 @@ package kms
import ( import (
"fmt" "fmt"
"io" "io"
"net"
"sync" "sync"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
pbETSI "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsetsi" pbETSI "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsetsi"
pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom" pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
pbQS "code.fbi.h-da.de/danet/quipsec/gen/go/quipsec"
"github.com/google/uuid" "github.com/google/uuid"
) )
...@@ -46,7 +51,7 @@ type EKMS struct { ...@@ -46,7 +51,7 @@ type EKMS struct {
kmsUUID uuid.UUID kmsUUID uuid.UUID
interComAddr string interComAddr string
qleMapMutex sync.Mutex qleMapMutex sync.Mutex
quantumModules map[uuid.UUID]QuantumModule quantumModules map[string]QuantumModule
quantumModulesMutex sync.RWMutex quantumModulesMutex sync.RWMutex
externalNotifierQLE chan uint32 externalNotifierQLE chan uint32
kmsPeersMutex sync.Mutex kmsPeersMutex sync.Mutex
...@@ -94,7 +99,7 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo ...@@ -94,7 +99,7 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo
kmsName: kmsName, kmsName: kmsName,
kmsUUID: kmsUUID, kmsUUID: kmsUUID,
interComAddr: interComAddr, interComAddr: interComAddr,
quantumModules: make(map[uuid.UUID]QuantumModule), quantumModules: make(map[string]QuantumModule),
routingTable: make(map[uuid.UUID]*Route), routingTable: make(map[uuid.UUID]*Route),
KmsPeers: make(map[string]*kmsPeer), KmsPeers: make(map[string]*kmsPeer),
externalNotifierQLE: nil, // just be surely set to nil! externalNotifierQLE: nil, // just be surely set to nil!
...@@ -105,14 +110,46 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo ...@@ -105,14 +110,46 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo
createdEKMS.supportedKeyLengths[BitKeyLen256] = true createdEKMS.supportedKeyLengths[BitKeyLen256] = true
// start the inter communication gRPC server // start the inter communication gRPC server
go StartInterComm(interComAddr, createdEKMS) go createdEKMS.startGRPC(interComAddr)
return createdEKMS return createdEKMS
} }
func (kms *EKMS) startGRPC(interComAddr string) {
lis, err := net.Listen("tcp", interComAddr)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
healthCheck := health.NewServer()
healthpb.RegisterHealthServer(s, healthCheck)
pbIC.RegisterKmsTalkerServer(s, &kmsTalkerServer{
keyNegotiationMap: make(map[uuid.UUID]*kmsKSElement),
eKMS: kms,
})
pbQS.RegisterKmsQkdmCommunicationServiceServer(s, &quipSecServer{
eKMS: kms,
})
go func() {
// set status to serving
healthCheck.SetServingStatus(pbIC.KmsTalker_ServiceDesc.ServiceName, healthpb.HealthCheckResponse_SERVING)
// TODO: add logic for adjusting health status based on operating status of
// the services
// for{}
}()
log.Infof("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
func (kms *EKMS) AddQuantumElement(qm QuantumModule) error { func (kms *EKMS) AddQuantumElement(qm QuantumModule) error {
kms.quantumModulesMutex.Lock() kms.quantumModulesMutex.Lock()
kms.quantumModules[qm.ID()] = qm log.Info(qm.Address())
kms.quantumModules[qm.Address()] = qm
kms.quantumModulesMutex.Unlock() kms.quantumModulesMutex.Unlock()
return nil return nil
} }
......
...@@ -42,7 +42,7 @@ func (es *etsiServer) ETSIGetQuantumInterfaces(ctx context.Context, in *pb.ETSIK ...@@ -42,7 +42,7 @@ func (es *etsiServer) ETSIGetQuantumInterfaces(ctx context.Context, in *pb.ETSIK
for _, qlWorks := range es.handlingEkms.quantumModules { for _, qlWorks := range es.handlingEkms.quantumModules {
qleElement := pb.QuantumElementInfo{ qleElement := pb.QuantumElementInfo{
QleID: qlWorks.ID().String(), QleID: qlWorks.ID().String(),
UdpAddr: qlWorks.Address().String(), UdpAddr: qlWorks.Address(),
} }
qleList = append(qleList, &qleElement) qleList = append(qleList, &qleElement)
} }
...@@ -51,13 +51,14 @@ func (es *etsiServer) ETSIGetQuantumInterfaces(ctx context.Context, in *pb.ETSIK ...@@ -51,13 +51,14 @@ func (es *etsiServer) ETSIGetQuantumInterfaces(ctx context.Context, in *pb.ETSIK
}, nil }, nil
} }
// TODO: reimplement
func (es *etsiServer) ETSIAddKMSPeer(ctx context.Context, in *pb.ETSIKMSPeerRequest) (*pb.ETSIKMSPeerReply, error) { func (es *etsiServer) ETSIAddKMSPeer(ctx context.Context, in *pb.ETSIKMSPeerRequest) (*pb.ETSIKMSPeerReply, error) {
//determine the kms structure to call //determine the kms structure to call
log.Debugf("AddKMSPeer called.") log.Debugf("AddKMSPeer called.")
// Check first if KmsLocalQLEId is actually one of ours... // Check first if KmsLocalQLEId is actually one of ours...
qleID := uuid.MustParse(in.KmsLocalQLEId) qleID := uuid.MustParse(in.KmsLocalQLEId)
servingQLE, _ := es.handlingEkms.quantumModules[qleID] servingQLE, _ := es.handlingEkms.quantumModules[""]
if servingQLE == nil { if servingQLE == nil {
//no such element! //no such element!
err := errors.New(fmt.Sprintf("Unknown local quantum element with ID %d", qleID)) err := errors.New(fmt.Sprintf("Unknown local quantum element with ID %d", qleID))
...@@ -127,7 +128,7 @@ func (es *etsiServer) ETSIAssignForwarding(ctx context.Context, in *pb.ETSIAssig ...@@ -127,7 +128,7 @@ func (es *etsiServer) ETSIAssignForwarding(ctx context.Context, in *pb.ETSIAssig
Next: nextHop, Next: nextHop,
} }
log.Info("ROUTINGTABLE: ", es.handlingEkms.routingTable) log.Infof("%s added a routing table entry for path id: %s", es.handlingEkms.kmsName, pathId.String())
return &pb.ETSIAssignForwardingReply{ return &pb.ETSIAssignForwardingReply{
Timestamp: time.Now().Unix(), Timestamp: time.Now().Unix(),
......
...@@ -3,9 +3,7 @@ package kms ...@@ -3,9 +3,7 @@ package kms
import ( import (
"context" "context"
"encoding/base64" "encoding/base64"
"flag"
"io/ioutil" "io/ioutil"
"net"
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
...@@ -13,10 +11,7 @@ import ( ...@@ -13,10 +11,7 @@ import (
etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client" 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" pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
"google.golang.org/grpc"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
...@@ -251,33 +246,3 @@ func (s *kmsTalkerServer) KeyForwarding(ctx context.Context, in *pb.KeyForwardin ...@@ -251,33 +246,3 @@ func (s *kmsTalkerServer) KeyForwarding(ctx context.Context, in *pb.KeyForwardin
return &pb.KeyForwardingResponse{Timestamp: time.Now().Unix()}, nil return &pb.KeyForwardingResponse{Timestamp: time.Now().Unix()}, nil
} }
func StartInterComm(addr string, eKMS *EKMS) {
flag.Parse()
lis, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
healthCheck := health.NewServer()
healthpb.RegisterHealthServer(s, healthCheck)
pb.RegisterKmsTalkerServer(s, &kmsTalkerServer{
keyNegotiationMap: make(map[uuid.UUID]*kmsKSElement),
eKMS: eKMS,
})
go func() {
// set status to serving
healthCheck.SetServingStatus(pb.KmsTalker_ServiceDesc.ServiceName, healthpb.HealthCheckResponse_SERVING)
// TODO: add logic for adjusting health status based on operating status of
// the services
// for{}
}()
log.Infof("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
...@@ -5,7 +5,6 @@ import ( ...@@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net"
"net/url" "net/url"
"sync" "sync"
"time" "time"
...@@ -13,7 +12,7 @@ import ( ...@@ -13,7 +12,7 @@ import (
etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client" etsi14 "code.fbi.h-da.de/danet/ekms/api/go/rest/etsi/client"
restclient "code.fbi.h-da.de/danet/ekms/restclient" restclient "code.fbi.h-da.de/danet/ekms/restclient"
pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom" pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
"code.fbi.h-da.de/danet/proto-kms/quantumlayer" "code.fbi.h-da.de/danet/quantumlayer"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
...@@ -29,28 +28,30 @@ type QuantumModule interface { ...@@ -29,28 +28,30 @@ type QuantumModule interface {
Sync() error Sync() error
Peer() *kmsPeer Peer() *kmsPeer
SetPeer(*kmsPeer) SetPeer(*kmsPeer)
Address() net.Addr Address() string
} }
type EmulatedQuantumModule struct { type EmulatedQuantumModule struct {
QlID uuid.UUID QlID uuid.UUID
QuantumElementLink *quantumlayer.QuantumlayerEmuPRNG // contains information about the quantum links //QuantumElementLink *quantumlayer.QuantumlayerEmuPRNG // contains information about the quantum links
//key stores of unchopped bulk keys go here //key stores of unchopped bulk keys go here
addr string
rawBulkKeysMutex sync.Mutex rawBulkKeysMutex sync.Mutex
rawBulkKeys map[int64]*quantumlayer.QuantumLayerBulkKey rawBulkKeys map[int64]*quantumlayer.QuantumLayerBulkKey
keyStore *kmsKeyStore // the keys used between two peers. keyStore *kmsKeyStore // the keys used between two peers.
peer *kmsPeer peer *kmsPeer
} }
func NewEmulatedQuantumModule(kmsUDPAddr string, generateKeys bool, logOutput io.Writer, logLevel log.Level, logInJson bool) *EmulatedQuantumModule { func NewEmulatedQuantumModule(kmsUDPAddr string, logOutput io.Writer, logLevel log.Level, logInJson bool) *EmulatedQuantumModule {
// create an emulated quantum layer // create an emulated quantum layer
ql := quantumlayer.NewQuantumlayerEmuPRNG(logOutput, logLevel, logInJson) // ql := quantumlayer.NewQuantumlayerEmuPRNG(logOutput, logLevel, logInJson)
ql.Configure(kmsUDPAddr) // ql.Configure(kmsUDPAddr)
ql.PowerOn(generateKeys) // ql.PowerOn(generateKeys)
return &EmulatedQuantumModule{ return &EmulatedQuantumModule{
QlID: uuid.New(), QlID: uuid.New(),
QuantumElementLink: ql, //QuantumElementLink: ql,
addr: kmsUDPAddr,
rawBulkKeys: make(map[int64]*quantumlayer.QuantumLayerBulkKey), rawBulkKeys: make(map[int64]*quantumlayer.QuantumLayerBulkKey),
keyStore: NewKmsKeyStore(256), keyStore: NewKmsKeyStore(256),
peer: nil, peer: nil,
...@@ -63,12 +64,12 @@ func (eqe *EmulatedQuantumModule) ID() uuid.UUID { ...@@ -63,12 +64,12 @@ func (eqe *EmulatedQuantumModule) ID() uuid.UUID {
func (eqe *EmulatedQuantumModule) Initialize() error { func (eqe *EmulatedQuantumModule) Initialize() error {
// TODO: error handling // TODO: error handling
go eqe.keyHandler() //go eqe.keyHandler()
return nil return nil
} }
func (eqe *EmulatedQuantumModule) Address() net.Addr { func (eqe *EmulatedQuantumModule) Address() string {
return eqe.QuantumElementLink.GetLocalQLPort() return eqe.addr
} }
func (eqe *EmulatedQuantumModule) Sync() error { func (eqe *EmulatedQuantumModule) Sync() error {
...@@ -141,24 +142,24 @@ func (eqe *EmulatedQuantumModule) SetPeer(peer *kmsPeer) { ...@@ -141,24 +142,24 @@ func (eqe *EmulatedQuantumModule) SetPeer(peer *kmsPeer) {
eqe.peer = peer eqe.peer = peer
} }
func (eqe *EmulatedQuantumModule) keyHandler() { //func (eqe *EmulatedQuantumModule) keyHandler() {
// periodically walk through quantum element and retrieve the key bulk buffer // // periodically walk through quantum element and retrieve the key bulk buffer
for { // for {
log.Debugf("%s: KeyHandler reading...\n", eqe.ID()) // log.Debugf("%s: KeyHandler reading...\n", eqe.ID())
bulkKeys, err := eqe.QuantumElementLink.GetKeyBulkPeer() // bulkKeys, err := eqe.QuantumElementLink.GetKeyBulkPeer()
if err != nil { // if err != nil {
log.Errorf("%s: failed to retrieve bulkkeys with error %s", eqe.ID(), err) // log.Errorf("%s: failed to retrieve bulkkeys with error %s", eqe.ID(), err)
} else { // } else {
// Add to the slice, but not process yet. // // Add to the slice, but not process yet.
log.Debugf("%s: produced %d bytes of key", eqe.ID(), bulkKeys.BulkKeyLength) // log.Debugf("%s: produced %d bytes of key", eqe.ID(), bulkKeys.BulkKeyLength)
eqe.rawBulkKeysMutex.Lock() // eqe.rawBulkKeysMutex.Lock()
eqe.rawBulkKeys[bulkKeys.BulkKeyId] = &bulkKeys // eqe.rawBulkKeys[bulkKeys.BulkKeyId] = &bulkKeys
eqe.rawBulkKeysMutex.Unlock() // eqe.rawBulkKeysMutex.Unlock()
} // }
// TODO: hardcoded // // TODO: hardcoded
time.Sleep(5 * time.Second) // time.Sleep(5 * time.Second)
} // }
} //}
// Takes a bulk of keys and chops them in chopFactor keys each // Takes a bulk of keys and chops them in chopFactor keys each
// Any remainder is discarded // Any remainder is discarded
...@@ -204,14 +205,16 @@ func (eqe *EmulatedQuantumModule) KeyChopper(bulkKey *quantumlayer.QuantumLayerB ...@@ -204,14 +205,16 @@ func (eqe *EmulatedQuantumModule) KeyChopper(bulkKey *quantumlayer.QuantumLayerB
type ETSI014HTTPQuantumModule struct { type ETSI014HTTPQuantumModule struct {
id uuid.UUID id uuid.UUID
addr string
keyStore *kmsKeyStore keyStore *kmsKeyStore
peer *kmsPeer peer *kmsPeer
client *restclient.ClientImpl client *restclient.ClientImpl
slaveSAEID string slaveSAEID string
masterSAEID string masterSAEID string
master bool
} }
func NewETSI014HTTPQuantumModule(addr, slaveSAEID, masterSAEID string) (*ETSI014HTTPQuantumModule, error) { func NewETSI014HTTPQuantumModule(addr, slaveSAEID, masterSAEID string, master bool) (*ETSI014HTTPQuantumModule, error) {
parsedUrl, err := url.Parse("http://" + addr) parsedUrl, err := url.Parse("http://" + addr)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -241,11 +244,13 @@ func NewETSI014HTTPQuantumModule(addr, slaveSAEID, masterSAEID string) (*ETSI014 ...@@ -241,11 +244,13 @@ func NewETSI014HTTPQuantumModule(addr, slaveSAEID, masterSAEID string) (*ETSI014
return &ETSI014HTTPQuantumModule{ return &ETSI014HTTPQuantumModule{
id: uuid.New(), id: uuid.New(),
addr: addr,
keyStore: NewKmsKeyStore(256), keyStore: NewKmsKeyStore(256),
peer: nil, peer: nil,
client: client, client: client,
slaveSAEID: slaveSAEID, slaveSAEID: slaveSAEID,
masterSAEID: masterSAEID, masterSAEID: masterSAEID,
master: master,
}, nil }, nil
} }
...@@ -255,6 +260,7 @@ func (eqe *ETSI014HTTPQuantumModule) ID() uuid.UUID { ...@@ -255,6 +260,7 @@ func (eqe *ETSI014HTTPQuantumModule) ID() uuid.UUID {
func (eqe *ETSI014HTTPQuantumModule) Initialize() error { func (eqe *ETSI014HTTPQuantumModule) Initialize() error {
// start polling // start polling
if eqe.master {
go func() { go func() {
ticker := time.NewTicker(2 * time.Second) ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop() defer ticker.Stop()
...@@ -292,11 +298,12 @@ func (eqe *ETSI014HTTPQuantumModule) Initialize() error { ...@@ -292,11 +298,12 @@ func (eqe *ETSI014HTTPQuantumModule) Initialize() error {
} }
} }
}() }()
}
return nil return nil
} }
func (eqe *ETSI014HTTPQuantumModule) Address() net.Addr { func (eqe *ETSI014HTTPQuantumModule) Address() string {
return nil return eqe.addr
} }
func (eqe *ETSI014HTTPQuantumModule) KeyStore() *kmsKeyStore { func (eqe *ETSI014HTTPQuantumModule) KeyStore() *kmsKeyStore {
......
package kms
import (
"context"
"net"
"strconv"
"time"
"code.fbi.h-da.de/danet/quantumlayer"
pb "code.fbi.h-da.de/danet/quipsec/gen/go/quipsec"
"github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/status"
)
type quipSecServer struct {
pb.UnimplementedKmsQkdmCommunicationServiceServer
eKMS *EKMS
}
func (qs *quipSecServer) PushKeys(ctx context.Context, req *pb.PushKeysRequest) (*pb.PushKeysResponse, error) {
p, _ := peer.FromContext(ctx)
host, _, err := net.SplitHostPort(p.Addr.String())
if err != nil {
}
for _, qm := range qs.eKMS.quantumModules {
if qm.Address() == host {
eqm, ok := qm.(*EmulatedQuantumModule)
if !ok {
return nil, status.Errorf(codes.Internal, "quantum module is of wrong type")
}
bulkKeyId, err := strconv.ParseInt(req.GetKeyBulk().GetKeyId(), 10, 64)
if err != nil {
return nil, status.Errorf(codes.Internal, "could not get bulkkeyid")
}
req.GetKeyBulk().GetKeyId()
req.GetKeyBulk().GetKeys()
eqm.rawBulkKeysMutex.Lock()
eqm.rawBulkKeys[bulkKeyId] = &quantumlayer.QuantumLayerBulkKey{
BulkKeyId: bulkKeyId,
BulkKeyLength: int(req.GetKeyBulk().GetKeyLength()),
BulkKey: &req.GetKeyBulk().Keys,
}
eqm.rawBulkKeysMutex.Unlock()
logrus.Infof("%s received a new bulk with id: %s and a length of: %d", qs.eKMS.kmsName, req.GetKeyBulk().GetKeyId(), req.GetKeyBulk().GetKeyLength())
return &pb.PushKeysResponse{Timestamp: time.Now().Unix()}, nil
}
}
return nil, status.Errorf(codes.Internal, "could not find a quantum module for host address: %s", host)
}
package main package main
// go generate protoc --proto_path=kmsintercomproto --go_out=kmsintercomproto --go_opt=paths=source_relative --go-grpc_out=kmsintercomproto --go-grpc_opt=paths=source_relative kmsintercom.proto
// go generate protoc --proto_path=kmsetsiproto --go_out=kmsetsiproto --go_opt=paths=source_relative --go-grpc_out=kmsetsiproto --go-grpc_opt=paths=source_relative kmsetsiproto.proto
import ( import (
"flag" "flag"
"net"
"os" "os"
"testing" "testing"
"time"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
...@@ -51,36 +46,28 @@ func TestMain(m *testing.M) { ...@@ -51,36 +46,28 @@ func TestMain(m *testing.M) {
if selfTesting == true { if selfTesting == true {
log.Infof("%s in self-testing mode", ql1Name) log.Infof("%s in self-testing mode", ql1Name)
go emulatedKMS("leftKMS", "[::1]:50900", "[::1]:50930", "[::1]:50910", "[::1]:50932") go emulatedKMS("leftKMS", "[::1]:50900", "[::1]:50930", "[::1]:50931", true)
go emulatedKMS("rightKMS", "[::1]:50901", "[::1]:50931", "[::1]:50911", "[::1]:50932") emulatedKMS("rightKMS", "[::1]:50901", "[::1]:50931", "[::1]:50930", false)
middleKMS("middleKMS", "[::1]:50902", "[::1]:50932", "[::1]:50900", "[::1]:50930", "[::1]:50901", "[::1]:50931")
} else { } else {
// log.Infof("%s in regular mode of operation", ql1Name) // log.Infof("%s in regular mode of operation", ql1Name)
// emulatedKMS(ql1Name, udpQL1AddrString, udpQL2AddrString) // emulatedKMS(ql1Name, udpQL1AddrString, udpQL2AddrString)
} }
} }
func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAddr string) { func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerInterComAddr string, master bool) {
// Attach to eKMS // Attach to eKMS
emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr) emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr)
eqm := kms.NewEmulatedQuantumModule(myUDPAddr, false, os.Stdout, log.TraceLevel, false) eqm := kms.NewEmulatedQuantumModule("::1", os.Stdout, log.TraceLevel, false)
// Fire up Quantum LinK // Fire up Quantum LinK
err := emuKMS.AddQuantumElement(eqm) err := emuKMS.AddQuantumElement(eqm)
if err != nil { if err != nil {
log.Println("failed to create emulated quantum module") log.Println("failed to add emulated quantum module")
return
}
udpQL2Addr, err := net.ResolveUDPAddr("udp", peerUDPAddr)
if err != nil {
log.Fatalf("%s: QuantumlayerEmuPRNG UDP failure: %s", myName, err)
return return
} }
eqm.QuantumElementLink.AddPeer(udpQL2Addr)
_, err = emuKMS.AddPeer(myName, peerInterComAddr, eqm) _, err = emuKMS.AddPeer(myName, peerInterComAddr, eqm)
if err != nil { if err != nil {
log.Println("PEERERROR: ", err) log.Println("PEERERROR: ", err)
...@@ -88,64 +75,6 @@ func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAdd ...@@ -88,64 +75,6 @@ func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAdd
// Start the SDN/management and key retrieval interface // Start the SDN/management and key retrieval interface
go kms.StartETSI(myUDPAddr, emuKMS) go kms.StartETSI(myUDPAddr, emuKMS)
}
func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, rightUDPAddr, rightInterComAddr string) {
// Attach to eKMS
emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr)
// create two quantum modules that generate keys
qlForLeft := kms.NewEmulatedQuantumModule("[::1]:50910", true, os.Stdout, log.TraceLevel, false)
qlForRight := kms.NewEmulatedQuantumModule("[::1]:50911", true, os.Stdout, log.TraceLevel, false)
netLeftUDPAddr, err := net.ResolveUDPAddr("udp", leftUDPAddr)
if err != nil {
log.Fatalf("%s: QuantumlayerEmuPRNG UDP failure: %s", myName, err)
return
}
netRightUDPAddr, err := net.ResolveUDPAddr("udp", rightUDPAddr)
if err != nil {
log.Fatalf("%s: QuantumlayerEmuPRNG UDP failure: %s", myName, err)
return
}
// Fire up Quantum LinK
err = emuKMS.AddQuantumElement(qlForLeft)
if err != nil {
log.Println("failed to create emulated quantum module")
return
}
err = emuKMS.AddQuantumElement(qlForRight)
if err != nil {
log.Println("failed to create emulated quantum module")
return
}
qlForLeft.QuantumElementLink.AddPeer(netLeftUDPAddr)
qlForRight.QuantumElementLink.AddPeer(netRightUDPAddr)
peerLeft, err := emuKMS.AddPeer("leftKMS", leftInterComAddr, qlForLeft)
if err != nil {
log.Println(err)
}
peerRight, err := emuKMS.AddPeer("rightKMS", rightInterComAddr, qlForRight)
if err != nil {
log.Println(err)
}
// Start the SDN/management and key retrieval interface
go kms.StartETSI(myUDPAddr, emuKMS)
time.Sleep(time.Second * 15)
if err := peerLeft.SyncBulkKeys(); err != nil {
log.Println("SYNC ERROR: ", err)
}
if err := peerRight.SyncBulkKeys(); err != nil {
log.Println("SYNC ERROR: ", err)
}
for { for {
} }
......
package quantumlayer
/*
*
* This packages "implements", actually it only emulates, the output of a
* quantum link, i.e., the transmitted random numbers from one quantum
* sender to a quantum receiver.
* This relies on crypto/rand to generate the random numbers that will be
* transmitted to the other end.
*
*/
import (
"context"
"crypto/rand"
"encoding/json"
"errors"
"io"
"math/big"
"net"
"sync"
"time"
"github.com/sirupsen/logrus"
logi "github.com/sirupsen/logrus"
)
type QuantumPayloadElement struct {
BulkKeyId int64 `json:"bulk-key-id"` // the unique ID of this bulk of keys
BulkKeyLength int `json:"bulk-key-length"` // the length, counted in bytes, of bulkKey
BulkKey *[]byte `json:"bulk-key"` // the bulk key
}
type QuantumlayerEmuPRNG struct {
configured bool
poweron bool // set to yes if operation, i.e., generating keys
generateKeys bool // set to yes, if this qle should generate random number.
incomingRandNums chan QuantumPayloadElement
peerNumbers *NumberStore
myNumbers *NumberStore
localQLAddress string
udpSrvConn *net.UDPConn
qlPeer string
qlPeerCancel context.CancelFunc
qlLocalPort *net.UDPAddr
qlPeerMutex sync.Mutex
}
// We use our own logrus instance, as we would like to have different log levels for different parts.
var log = logrus.New()
func NewQuantumlayerEmuPRNG(logOutput io.Writer, logLevel logi.Level, logInJson bool) (newql *QuantumlayerEmuPRNG) {
/*
* Setup logging
*/
//What level
log.SetLevel(logLevel)
// Where to send log out put
log.SetOutput(logOutput)
// and plain-text (standard) or json
if !logInJson {
log.SetFormatter(&logi.TextFormatter{})
} else {
log.SetFormatter(&logi.JSONFormatter{})
}
// print code function if level is set to Trace
if logLevel == logi.TraceLevel {
log.SetReportCaller(true)
} else {
log.SetReportCaller(false)
}
// Return PRNG Quantum Layer
return &QuantumlayerEmuPRNG{
configured: false,
poweron: false,
generateKeys: false,
incomingRandNums: make(chan QuantumPayloadElement),
peerNumbers: NewNumberStore(40000),
myNumbers: NewNumberStore(40000),
qlPeer: "",
}
}
// Configure the quantum emulation, but do not start if yet
func (qlemuprng *QuantumlayerEmuPRNG) Configure(localQLAddress ...string) {
// Start receiving numberstores
go qlemuprng.peerNumbers.receiveNumbers(qlemuprng.incomingRandNums)
// Determine if a local UDP address should be used or not
if len(localQLAddress) == 0 {
// No input
qlemuprng.localQLAddress = ":0"
} else {
qlemuprng.localQLAddress = localQLAddress[0]
}
qlemuprng.configured = true
}
// Power on the quantum layer, i.e., open up the communication ports for the
// other quantum module
func (qlemuprng *QuantumlayerEmuPRNG) PowerOn(enableKeyGeneration bool) {
if !qlemuprng.configured {
// nothing do here move on
log.Errorf("QuantumlayerEmuPRNG: Sorry, the quantum layer is not configured for action. You've missed Configure()")
return
}
//qlemuprng.poweron = false
log.Infof("QuantumlayerEmuPRNG: is powering on...charging.")
if enableKeyGeneration {
log.Infof("QuantumlayerEmuPRNG: will GENERATE random keys")
}
qlemuprng.generateKeys = enableKeyGeneration
// serve UDP incoming
if qlemuprng.udpSrvConn == nil {
go func() {
// Get UDP server part going...
log.Debugf("QuantumlayerEmuPRNG: localQLAddress is %s", qlemuprng.localQLAddress)
// This reads random numbers from other Quantum end
udpSrvPort, err := net.ResolveUDPAddr("udp", qlemuprng.localQLAddress)
if err != nil {
log.Fatalf("QuantumlayerEmuPRNG: UDP failure: %s", err)
return
}
qlemuprng.udpSrvConn, err = net.ListenUDP("udp", udpSrvPort)
if err != nil {
log.Fatalf("QuantumlayerEmuPRNG: UDP failure: %s", err)
return
}
defer qlemuprng.udpSrvConn.Close()
// Retrieve local UDP address and store it for further actions.
qlemuprng.qlLocalPort = qlemuprng.udpSrvConn.LocalAddr().(*net.UDPAddr)
// TODO: This does not seem to be necessary if the gle is not generating rands
log.Infof("QuantumlayerEmuPRNG: started server, waiting for incoming rands on port %s \n", qlemuprng.udpSrvConn.LocalAddr().(*net.UDPAddr).String())
inBuffer := make([]byte, 1500)
for {
// Buffer for reading from "Quantum link"
n, addr, err := qlemuprng.udpSrvConn.ReadFromUDP(inBuffer)
if err != nil {
log.Errorf("QuantumlayerEmuPRNG: Could not read from UDP: %s", err)
} else {
log.Debugf("QuantumlayerEmuPRNG: read %d bytes from %s\n", n, addr)
// Check if sender of datagram is qlPeer
// Warning this is not checking the validity of the sender, i.e., spoofing is possible
if addr.String() == qlemuprng.qlPeer {
log.Debugf("QuantumlayerEmuPRNG: Peer %s listed", addr)
//dumb the received data into the channel and carry on
// TODO/XXX: no vetting for anything
// Unmarshall out of JSON
var inQBuffer QuantumPayloadElement
unmarshallErr := json.Unmarshal(inBuffer[0:n], &inQBuffer)
if unmarshallErr == nil {
qlemuprng.incomingRandNums <- inQBuffer
}
} else {
log.Infof("QuantumlayerEmuPRNG: Peer %s NOT listed", addr)
}
}
}
}()
}
// Wait for listening UDP socket in the above go-routine to get ready
for qlemuprng.udpSrvConn == nil {
}
// Ready, set, go!
qlemuprng.poweron = true
log.Infof("QuantumlayerEmuPRNG: is charged and powered on.")
}
// Power off the quantum layer, i.e., close the communication ports for the
// other quantum module
func (qlemuprng *QuantumlayerEmuPRNG) PowerOff() {
qlemuprng.poweron = false
log.Println("QuantumlayerEmuPRNG: is powered off...discharging.")
}
func (qlemuprng *QuantumlayerEmuPRNG) AddPeer(addr *net.UDPAddr) {
if !qlemuprng.poweron {
return
}
//TODO/XXX check the incoming addr
// Add peer to the ....
qlemuprng.qlPeerMutex.Lock()
qlemuprng.qlPeer = addr.String()
qlemuprng.qlPeerMutex.Unlock()
// generate only keys if requested to do so.
if qlemuprng.generateKeys {
ctx, cancel := context.WithCancel(context.Background())
qlemuprng.qlPeerCancel = cancel
// Start the generation and shipping of random numbers
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
if qlemuprng.poweron {
// retrieve a new back of random numbers
newNumberBatch := qlemuprng.GenerateRandomNumbers()
// TODO: Replace this by some generic encapsulation reader and not just JSON
//Get JSON for transmission ready
qpe := QuantumPayloadElement{time.Now().UnixNano(), len(newNumberBatch), &newNumberBatch}
// XXX/TODO: error must be handled
jsonPayload, err := json.Marshal(qpe)
if err != nil {
log.Errorf("QuantumlayerEmuPRNG: json.Marshal error %s", err)
}
_, _, err = qlemuprng.udpSrvConn.WriteMsgUDP(jsonPayload, nil, addr)
if err != nil {
log.Fatalf("QuantumlayerEmuPRNG: WriteMsgUDPAddrPort failed: %s", err)
}
qlemuprng.incomingRandNums <- qpe
}
// TODO: This sleep timer has to replaced by something for clever.
time.Sleep(5 * time.Second)
}
}
}(ctx)
}
}
func (qlemuprng *QuantumlayerEmuPRNG) RemovePeer() {
if !qlemuprng.poweron {
return
}
// Stop the generation and shipping of random numbers
qlemuprng.qlPeerCancel()
// delete peer
qlemuprng.qlPeerMutex.Lock()
qlemuprng.qlPeer = ""
qlemuprng.qlPeerMutex.Unlock()
}
func (qlemuprng *QuantumlayerEmuPRNG) GetLocalQLPort() (myAddr *net.UDPAddr) {
return qlemuprng.qlLocalPort
}
func (qlemuprng *QuantumlayerEmuPRNG) GenerateRandomNumbers() (randNums []byte) {
numRands, randError := rand.Int(rand.Reader, big.NewInt(1000))
if randError != nil {
log.Fatalf("QuantumlayerEmuPRNG: %s", randError)
return
}
b := make([]byte, numRands.Uint64())
_, randError = rand.Read(b)
if randError != nil {
log.Fatalf("QuantumlayerEmuPRNG: %s", randError)
return
}
return b
}
func (qlemuprng *QuantumlayerEmuPRNG) GetKeyBulkPeer() (QuantumLayerBulkKey, error) {
return qlemuprng.peerNumbers.GetBulk()
}
// GetStatus returns the current status of the QuantumLayerEmuPRNG. This
// includes the information if the QLE is powered, aswell as if the QLE is
// enabled for key generation.
func (qlemuprng *QuantumlayerEmuPRNG) GetStatus() (poweredOn, enabled bool) {
return qlemuprng.poweron, qlemuprng.generateKeys
}
type NumberStore struct {
mu sync.Mutex
maxBytes int
storage []byte
bulkKeyStorage []QuantumLayerBulkKey
topOfStorage int
}
// Generates a new store with given maximum number of bytes
func NewNumberStore(maxBytes int) (newNS *NumberStore) {
return &NumberStore{
maxBytes: maxBytes,
storage: make([]byte, maxBytes),
topOfStorage: 0,
}
}
func (store *NumberStore) GetBulk() (bulk QuantumLayerBulkKey, err error) {
store.mu.Lock()
defer store.mu.Unlock()
for nextID := range store.bulkKeyStorage {
next := store.bulkKeyStorage[nextID]
// Preprare to return
a := QuantumLayerBulkKey{
BulkKeyId: next.BulkKeyId,
BulkKeyLength: next.BulkKeyLength,
BulkKey: nil,
}
bulkKey := make([]byte, next.BulkKeyLength)
copy(bulkKey, *next.BulkKey)
a.BulkKey = &bulkKey
// Delete from key store
store.bulkKeyStorage = store.bulkKeyStorage[1:]
// and return
return a, nil
}
returnErr := errors.New("no bulk key to retrieve")
b := QuantumLayerBulkKey{}
return b, returnErr
}
func (store *NumberStore) GetBatch() (batch []byte) {
store.mu.Lock()
defer store.mu.Unlock()
if store.topOfStorage != 0 {
log.Debugf("QuantumlayerEmuPRNG: Have Storage in my belly")
}
// prepare to return full batch of numbers
batchReturn := make([]byte, store.topOfStorage)
copy(batchReturn, store.storage)
store.topOfStorage = 0
return batchReturn
}
func (store *NumberStore) receiveNumbers(incoming chan QuantumPayloadElement) {
for {
receivedNumbers := <-incoming
// add received to our buffer, if buffer still last
store.mu.Lock()
mem := QuantumLayerBulkKey{
BulkKeyId: receivedNumbers.BulkKeyId,
BulkKeyLength: receivedNumbers.BulkKeyLength,
BulkKey: receivedNumbers.BulkKey,
}
//store.bulkKeyStorage[receivedNumbers.BulkKeyId] = mem
store.bulkKeyStorage = append(store.bulkKeyStorage, mem)
store.mu.Unlock()
}
}
package quantumlayer
// Some tests
import (
"fmt"
"net"
"os"
"testing"
"time"
logrus "github.com/sirupsen/logrus"
)
func TestQuantumLayer(t *testing.T) {
// Generate UDPAddr for ql1 peer
udpQL2AddrString := fmt.Sprintf("127.0.0.1:%d", 5002)
udpQL2Addr, err := net.ResolveUDPAddr("udp", udpQL2AddrString)
if err != nil {
t.Fatalf("QuantumlayerEmuPRNG UDP failure: %s", err)
return
}
// Generate UDPAddr for ql2 peer
udpQL1AddrString := fmt.Sprintf("127.0.0.1:%d", 5001)
udpQL1Addr, err := net.ResolveUDPAddr("udp", udpQL1AddrString)
if err != nil {
t.Fatalf("QuantumlayerEmuPRNG UDP failure: %s", err)
return
}
ql1 := NewQuantumlayerEmuPRNG(os.Stdout, logrus.DebugLevel, false)
ql1.Configure(udpQL1AddrString)
ql1.PowerOn(true) // this one generates keys
defer ql1.PowerOff()
ql2 := NewQuantumlayerEmuPRNG(os.Stdout, logrus.DebugLevel, false)
ql2.Configure(udpQL2AddrString)
ql2.PowerOn(false) // this one does NOT generate keys
defer ql2.PowerOff()
ql1.AddPeer(udpQL2Addr)
ql2.AddPeer(udpQL1Addr)
// Wait for key gen to get up and running
time.Sleep(5 * time.Second)
for n := 0; n < 2; n++ {
resultQl1, err := ql1.GetKeyBulkPeer()
if err == nil {
t.Logf("run %d, *ql1* keyid %d \t keylen %d", n, resultQl1.BulkKeyId, resultQl1.BulkKeyLength)
} else {
t.Fatalf("Couldn't read local ql1 batch with error %s", err)
}
// TODO: Calculate checksum of BulkKey and double-check
time.Sleep(5 * time.Second)
}
}
// This package aims at emulating a quantum link and is extendable to different models
// One can use most of the sourc code of emu-prng and reuse it.
// To add a different quantum module one should only modify the GenerateRandomNumbers function
package quantumlayer
type QuantumLayerBulkKey struct {
BulkKeyId int64 // the unique ID of this bulk of keys
BulkKeyLength int // the length, counted in bytes, of bulkKey
// TODO: Pointer of slice should have a well thought reason;
// ask Martin if this is really necessary here
BulkKey *[]byte // the bulk key
}
type QuantumLayer interface {
Configure(...string) // configure the interface, e.g., used IP/Port config if emulated
PowerOn(enableKeyGeneration bool) // switch on the quantum layer element
PowerOff() // switch off the quantum layer element
GetStatus() (poweredOn bool) // returns true if quantum layer element is powered on
AddPeer() // Adds a Quantum Layer Peer to the peer list
RemovePeer() // Remmoves a Quantum Layer Peer to the peer list
GetLocalQLPort() // Returns the information about the local quantum layer IP and port
GetKeyBulkPeer() (QuantumLayerBulkKey, error) // retrieve the bulk key received from peer
GenerateRandomNumbers() []byte // generate a number of random numbers
}
type NumberLayer interface {
GetBatch() []byte // allows to retrieve the current available batch of numbers
GetBulk() (QuantumLayerBulkKey, error)
receiveNumbers(chan []byte)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment