diff --git a/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go b/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go index 80cf822b317b6a457997549b0dd6b7342046b459..af7a507c7f40823c4620e0881f2e02cf744ee169 100644 --- a/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go +++ b/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go @@ -27,7 +27,7 @@ type QuantumElementInfo struct { unknownFields protoimpl.UnknownFields Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - QleID uint64 `protobuf:"varint,2,opt,name=qleID,proto3" json:"qleID,omitempty"` + QleID string `protobuf:"bytes,2,opt,name=qleID,proto3" json:"qleID,omitempty"` UdpAddr string `protobuf:"bytes,3,opt,name=udpAddr,proto3" json:"udpAddr,omitempty"` } @@ -70,11 +70,11 @@ func (x *QuantumElementInfo) GetTimestamp() int64 { return 0 } -func (x *QuantumElementInfo) GetQleID() uint64 { +func (x *QuantumElementInfo) GetQleID() string { if x != nil { return x.QleID } - return 0 + return "" } func (x *QuantumElementInfo) GetUdpAddr() string { @@ -305,7 +305,7 @@ type ETSIKMSPeerRequest struct { Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` KmsPeerSocket string `protobuf:"bytes,2,opt,name=kmsPeerSocket,proto3" json:"kmsPeerSocket,omitempty"` - KmsLocalQLEId uint32 `protobuf:"varint,3,opt,name=kmsLocalQLEId,proto3" json:"kmsLocalQLEId,omitempty"` + KmsLocalQLEId string `protobuf:"bytes,3,opt,name=kmsLocalQLEId,proto3" json:"kmsLocalQLEId,omitempty"` } func (x *ETSIKMSPeerRequest) Reset() { @@ -354,11 +354,11 @@ func (x *ETSIKMSPeerRequest) GetKmsPeerSocket() string { return "" } -func (x *ETSIKMSPeerRequest) GetKmsLocalQLEId() uint32 { +func (x *ETSIKMSPeerRequest) GetKmsLocalQLEId() string { if x != nil { return x.KmsLocalQLEId } - return 0 + return "" } type ETSIKMSPeerReply struct { @@ -912,7 +912,7 @@ var file_kmsetsi_kmsetsiproto_proto_rawDesc = []byte{ 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x6c, 0x65, - 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x71, 0x6c, 0x65, 0x49, 0x44, 0x12, + 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x64, 0x70, 0x41, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x64, 0x70, 0x41, 0x64, 0x64, 0x72, 0x22, 0x55, 0x0a, 0x17, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, @@ -945,7 +945,7 @@ var file_kmsetsi_kmsetsiproto_proto_rawDesc = []byte{ 0x65, 0x72, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x6d, 0x73, 0x50, 0x65, 0x65, 0x72, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x6d, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c, 0x45, 0x49, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6b, 0x6d, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x6d, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c, 0x45, 0x49, 0x64, 0x22, 0x52, 0x0a, 0x10, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, diff --git a/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto b/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto index 261dd51b19f928ed0d9bb1ce6ab05da8b500ab6f..0c2e19616074c7f60c2bad21491d1d43a7a0a5a6 100644 --- a/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto +++ b/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto @@ -18,7 +18,7 @@ service KmsETSI{ // NB for myself: this be used to link QLE mit KMS-Session! message QuantumElementInfo { int64 timestamp = 1; - uint64 qleID = 2; + string qleID = 2; string udpAddr = 3; } @@ -46,7 +46,7 @@ message ETSIKMSQuantumInterfaceListReply { message ETSIKMSPeerRequest { int64 timestamp = 1; string kmsPeerSocket = 2; - uint32 kmsLocalQLEId = 3; + string kmsLocalQLEId = 3; } message ETSIKMSPeerReply { diff --git a/internal/docs/run.sh b/internal/docs/run.sh index 1d8c279948e159d298295bc764eb17be891ec018..a48acc17a8cfcff54b5a2db34d74c1d59ddc85ca 100755 --- a/internal/docs/run.sh +++ b/internal/docs/run.sh @@ -1,3 +1,3 @@ grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "", "prevHop" : "[::1]:50932"}' --import-path ../api/kmsetsi/kmsetsi --proto kmsetsiproto.proto --plaintext [::1]:50901 kmsetsi.KmsETSI.ETSIAssignForwarding -grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50931", "prevHop": "[::1]:50930"}' --import-path ../api/kmsetsi//kmsetsi --proto kmsetsiproto.proto --plaintext [::1]:50902 kmsetsi.KmsETSI.ETSIAssignForwarding -grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50932"}' --import-path ../api/kmsetsi//kmsetsi --proto kmsetsiproto.proto --plaintext [::1]:50900 kmsetsi.KmsETSI.ETSIAssignForwarding +grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50931", "prevHop": "[::1]:50930"}' --import-path ../api/kmsetsi/kmsetsi --proto kmsetsiproto.proto --plaintext [::1]:50902 kmsetsi.KmsETSI.ETSIAssignForwarding +grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50932"}' --import-path ../api/kmsetsi/kmsetsi --proto kmsetsiproto.proto --plaintext [::1]:50900 kmsetsi.KmsETSI.ETSIAssignForwarding diff --git a/internal/kms/kms-keystore.go b/internal/kms/kms-keystore.go index b3f3de46da4c1fdfe58d8012539f4ee2729ab939..93a29b740a1f4da5ff0077ab8365e54a41f5b7bc 100644 --- a/internal/kms/kms-keystore.go +++ b/internal/kms/kms-keystore.go @@ -1,7 +1,6 @@ package kms import ( - "errors" "fmt" "sync" @@ -32,19 +31,18 @@ type kmsKSElement struct { } type kmsKeyStore struct { - keyStoreMutex sync.Mutex - underlyingBulkId int64 - keyStore map[uint64]*kmsKSElement - keySingleSize uint // the size of a single key, given as unit of bits - indexCounter uint64 + keyStoreMutex sync.Mutex + keyStore map[uint64]*kmsKSElement + keySingleSize uint // the size of a single key, given as unit of bits + indexCounter uint64 } func NewKmsKeyStore(desiredkeySingleSizeLength uint) *kmsKeyStore { return &kmsKeyStore{ - underlyingBulkId: 0, - keyStore: make(map[uint64]*kmsKSElement), - keySingleSize: desiredkeySingleSizeLength, - indexCounter: 0, + // NOTE: could be useful to use something like a ordered map here + keyStore: make(map[uint64]*kmsKSElement), + keySingleSize: desiredkeySingleSizeLength, + indexCounter: 0, } } @@ -54,7 +52,7 @@ func (ks *kmsKeyStore) addKey(keyId uint64, keyToadd []byte) { // test for collisions if _, notThere := ks.keyStore[keyId]; notThere { - log.Errorf("Whop: addKey collission of key id %s for bulkKeyID %d", keyId, ks.underlyingBulkId) + log.Errorf("Whop: addKey collission of key id %s", keyId) return } @@ -86,37 +84,27 @@ func (ks *kmsKeyStore) GetKey() (*kmsKSElement, error) { return nil, fmt.Errorf("Key with index: %d is already reserved.", ks.indexCounter) } -// Takes a bulk of keys and chops them in chopFactor keys each -// Any remainder is discarded -func (ks *kmsKeyStore) KeyChopper(bulkKey *quantumlayer.QuantumLayerBulkKey) (err error) { - if ks.keySingleSize == 0 { - err = errors.New("KeyChopper: no keySingleSize set") - return err - } - // TODO check if multiple of 8 (1 Byte) +func (ks *kmsKeyStore) GetKeyWithID(id uint64) (*kmsKSElement, error) { + ks.keyStoreMutex.Lock() + defer ks.keyStoreMutex.Unlock() - if bulkKey.BulkKeyLength != len(*bulkKey.BulkKey) { - err = errors.New("bulkKey length mismatch") - return err + key, ok := ks.keyStore[id] + if !ok { + return nil, fmt.Errorf("Could not find a key for id: %d", ks.indexCounter) } + if key.status == AVAILABLE { + // change status of key to reserved + key.status = RESERVED + // increase index counter + ks.indexCounter = ks.indexCounter + 1 - // Store underlying bulkID - ks.underlyingBulkId = bulkKey.BulkKeyId - // reset indexCounter - ks.indexCounter = 0 - - var keyId uint64 - keyId = 0 - - // Let's chop! - chopFactor := ks.keySingleSize >> 3 - key := *bulkKey.BulkKey - for len(key) > int(chopFactor) { - tmpkey := key[:chopFactor] - ks.addKey(keyId, tmpkey) - keyId++ - // shorten the key storage - key = key[chopFactor:] + return key, nil } - return nil + return nil, fmt.Errorf("Key with index: %d is already reserved.", ks.indexCounter) +} + +func (ks *kmsKeyStore) DeleteKey(keyId uint64) { + ks.keyStoreMutex.Lock() + delete(ks.keyStore, keyId) + ks.keyStoreMutex.Unlock() } diff --git a/internal/kms/kms.go b/internal/kms/kms.go index 6b7c925d59dd02eff1d1f203024e62f2dc1371b6..696c0ea328b726c56edd220280fb94ca07625231 100644 --- a/internal/kms/kms.go +++ b/internal/kms/kms.go @@ -5,31 +5,27 @@ package kms import ( - "crypto/rand" - "encoding/binary" "fmt" "io" "sync" - "time" log "github.com/sirupsen/logrus" 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" - "code.fbi.h-da.de/danet/proto-kms/quantumlayer" "github.com/google/uuid" ) -type Qkdnkms interface { - //AddExternalNotifierGeneral(chan bool) // used to indicate unspecific changes - AddExternalNotifierQLE(chan uint32) // used to indicate changes to specific Quantum Link Element (QLE) - AddExternalNotifierKMSPeer(chan string) // used to indicate changes to specific KMSPeer - AddQuantumElement() *QuantumElement - GlobalKeyHandler(time.Duration) error - AddPeer(kmsPeerSocket string, servingQLE *QuantumElement) - RemovePeer(kmsPeerSocket string) - FindPeerUuid(uuid.UUID) *kmsPeer -} +//type Qkdnkms interface { +// //AddExternalNotifierGeneral(chan bool) // used to indicate unspecific changes +// AddExternalNotifierQLE(chan uint32) // used to indicate changes to specific Quantum Link Element (QLE) +// AddExternalNotifierKMSPeer(chan string) // used to indicate changes to specific KMSPeer +// AddQuantumElement() *EmulatedQuantumModule +// GlobalKeyHandler(time.Duration) error +// AddPeer(kmsPeerSocket string, servingQLE *EmulatedQuantumModule) +// RemovePeer(kmsPeerSocket string) +// FindPeerUuid(uuid.UUID) *kmsPeer +//} type Route struct { Previous *kmsPeer @@ -50,7 +46,8 @@ type EKMS struct { kmsUUID uuid.UUID interComAddr string qleMapMutex sync.Mutex - QuantumElements map[uint32]*QuantumElement + quantumModules map[uuid.UUID]QuantumModule + quantumModulesMutex sync.RWMutex externalNotifierQLE chan uint32 kmsPeersMutex sync.Mutex // TODO(maba): find a better name for this @@ -71,15 +68,6 @@ type QuantumElementInterface interface { GetQlID() qlElementId }*/ -type QuantumElement struct { - QlID uint32 - QuantumElementLink *quantumlayer.QuantumlayerEmuPRNG // contains information about the quantum links - //key stores of unchopped bulk keys go here - rawBulkKeysMutex sync.Mutex - rawBulkKeys map[int64]*quantumlayer.QuantumLayerBulkKey - keyStorePeer *kmsKeyStore // the keys used between two peers. -} - func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel log.Level, logInJson bool, interComAddr string) (newEKMS *EKMS) { /* * Setup logging @@ -105,7 +93,7 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo kmsName: kmsName, kmsUUID: kmsUUID, interComAddr: interComAddr, - QuantumElements: make(map[uint32]*QuantumElement), + quantumModules: make(map[uuid.UUID]QuantumModule), routingTable: make(map[uuid.UUID]*Route), KmsPeers: make(map[string]*kmsPeer), externalNotifierQLE: nil, // just be surely set to nil! @@ -121,86 +109,14 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo return createdEKMS } -func (kms *EKMS) AddQuantumElement(kmsUDPAddrr string, generateKeys bool, logOutput io.Writer, logLevel log.Level, logInJson bool) *QuantumElement { - - //Get an emulated Quantumlayer - ql := quantumlayer.NewQuantumlayerEmuPRNG(logOutput, logLevel, logInJson) - ql.Configure(kmsUDPAddrr) - ql.PowerOn(generateKeys) - - qle := QuantumElement{ - QuantumElementLink: ql, - rawBulkKeys: make(map[int64]*quantumlayer.QuantumLayerBulkKey), - // keyStorePeer: not set, will be set later on, if key size is negotiated. - } - - // generate a ID for this quantum element that is unique locally - var randError error - qle.QlID, randError = kms.GenerateNewQleID() - if randError != nil { - log.Fatalf("%s: GenerateNewQleID: %s", kms.kmsName, randError) - return nil - } - - kms.QuantumElements[qle.QlID] = &qle - - return &qle -} - -// TODO: Name of this function is misleading, as it only reads the bulk keys, but nothing more else -func (kms *EKMS) GlobalKeyHandler(waitTime time.Duration) error { - // periodically walk through QuantumElements and retrieve the - // - key bulk buffer for each peer - // feed this into the corresponding key buffers of the kmss - for { - for currentQE := range kms.QuantumElements { - log.Debugf("%s GlobalKeyHandler reading...\n", kms.kmsName) - - bulkKeys, err := kms.QuantumElements[currentQE].QuantumElementLink.GetKeyBulkPeer() - if err != nil { - log.Errorf("%s failed to retrieve bulkkeys with error %s", kms.kmsName, err) - } else { - // Add to the slice, but not process yet. - log.Debugf("%s produced %d bytes of key", kms.kmsName, bulkKeys.BulkKeyLength) - kms.QuantumElements[currentQE].rawBulkKeysMutex.Lock() - //kms.QuantumElements[currentQE].rawBulkKeys = append(kms.QuantumElements[currentQE].rawBulkKeys, &bulkKeys) - kms.QuantumElements[currentQE].rawBulkKeys[bulkKeys.BulkKeyId] = &bulkKeys - kms.QuantumElements[currentQE].rawBulkKeysMutex.Unlock() - - //kms.QuantumElements[currentQE].keyStorePeer.KeyChopper256Bit(&bulkKeys) - - } - } - // TODO: Better approach required than a sleep timer! - time.Sleep(waitTime) - } -} - -// This has a design flaw, as the generated ID is returned to the calling function and used there. -// However, when being used a potential other caller might received the same qlElementId -// TODO/XXX: This would be collision and must be eventually avoided -func (kms *EKMS) GenerateNewQleID() (uint32, error) { - for { // this needs a condition to stop! - // create buffer for uint32, so reserve 4 bytes - buf := make([]byte, 4) - - // fill the buffer from rand - _, err := rand.Read(buf) - if err != nil { - return 0, err - } - - propopsedQlElementID := binary.BigEndian.Uint32(buf) - - // check if ID is already taken - if kms.QuantumElements[propopsedQlElementID] == nil { - return propopsedQlElementID, nil - } - //keep going.... - } +func (kms *EKMS) AddQuantumElement(qm QuantumModule) error { + kms.quantumModulesMutex.Lock() + kms.quantumModules[qm.ID()] = qm + kms.quantumModulesMutex.Unlock() + return nil } -func (kms *EKMS) AddPeer(kmsPeerSocket string, servingQLE *QuantumElement) (*kmsPeer, error) { +func (kms *EKMS) AddPeer(kmsPeerSocket string, servingQLE QuantumModule) (*kmsPeer, error) { //check if peer exists if _, there := kms.KmsPeers[kmsPeerSocket]; there { log.Errorf("Trying to add existing peer %s", kmsPeerSocket) diff --git a/internal/kms/kmsetsi.go b/internal/kms/kmsetsi.go index 8dc0e4f79910eabdd55fa373dea405411700be93..689611937e19ad2bea90bfdb6d47c73c1c853098 100644 --- a/internal/kms/kmsetsi.go +++ b/internal/kms/kmsetsi.go @@ -2,7 +2,6 @@ package kms import ( "context" - "encoding/json" "errors" "flag" "fmt" @@ -40,10 +39,10 @@ func (es *etsiServer) ETSIGetQuantumInterfaces(ctx context.Context, in *pb.ETSIK qleList := make([]*pb.QuantumElementInfo, 1) // Walk through QuantumLayerInterfaces and return their information - for _, qlWorks := range es.handlingEkms.QuantumElements { + for _, qlWorks := range es.handlingEkms.quantumModules { qleElement := pb.QuantumElementInfo{ - QleID: uint64(qlWorks.QlID), - UdpAddr: fmt.Sprintf("%s:%d", qlWorks.QuantumElementLink.GetLocalQLPort().IP.String(), qlWorks.QuantumElementLink.GetLocalQLPort().Port), + QleID: qlWorks.ID().String(), + UdpAddr: qlWorks.Address().String(), } qleList = append(qleList, &qleElement) } @@ -57,8 +56,8 @@ func (es *etsiServer) ETSIAddKMSPeer(ctx context.Context, in *pb.ETSIKMSPeerRequ log.Debugf("AddKMSPeer called.") // Check first if KmsLocalQLEId is actually one of ours... - qleID := in.KmsLocalQLEId - servingQLE, _ := es.handlingEkms.QuantumElements[qleID] + qleID := uuid.MustParse(in.KmsLocalQLEId) + servingQLE, _ := es.handlingEkms.quantumModules[qleID] if servingQLE == nil { //no such element! err := errors.New(fmt.Sprintf("Unknown local quantum element with ID %d", qleID)) @@ -146,19 +145,19 @@ func (es *etsiServer) ETSISendPayload(ctx context.Context, in *pb.ETSISendPayloa } // NOTE: For demo purpose only - json, err := json.Marshal(KMSInfo{ - Name: es.handlingEkms.kmsName, - EncryptedMessage: in.Payload, - DecryptedMessage: in.Payload, - }) - if err != nil { - log.Println("Failed to marshal: ", err) - } - - err = sendKmsInfoMessage("http://172.20.10.21:4000/kmsinfo", json) - if err != nil { - log.Println("Failed to send KMS info message: ", err) - } + //json, err := json.Marshal(KMSInfo{ + // Name: es.handlingEkms.kmsName, + // EncryptedMessage: in.Payload, + // DecryptedMessage: in.Payload, + //}) + //if err != nil { + // log.Println("Failed to marshal: ", err) + //} + + //err = sendKmsInfoMessage("http://172.20.10.21:4000/kmsinfo", json) + //if err != nil { + // log.Println("Failed to send KMS info message: ", err) + //} if err := route.Next.SendPayload([]byte(in.GetPayload()), pathId); err != nil { return nil, status.Errorf(codes.Internal, "Failed to send payload: ", err) @@ -169,42 +168,6 @@ func (es *etsiServer) ETSISendPayload(ctx context.Context, in *pb.ETSISendPayloa }, nil } -//func (es *etsiServer) ETSIGetEncryptKeys256Bit(ctx context.Context, in *pb.ETSIGetEncryptKeys256BitRequest) (*pb.ETSIGetEncryptKeys256BitReply, error) { -// log.Printf("Received request for n=%d keys", in.GetAmount()) -// -// var randomKey *kmsKSElement -// var err error -// // NOTE: change change change! -// for _, qe := range es.handlingEkms.QuantumElements { -// quantumElementLocalKeyStore := qe.keyStorePeer -// randomKey, err = randomItemFromMap[uint64, *kmsKSElement](quantumElementLocalKeyStore.keyStore, es.visitedKeys) -// if err != nil { -// return nil, status.Errorf(codes.Internal, "%v", err) -// } -// es.visitedKeys[randomKey] = true -// } -// -// // TODO: Remove/move ssh-kind prototype code below -// 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.Errorf("could not execute ssh command with parameters") -// return nil, status.Errorf(codes.Internal, "%v", err) -// } -// -// // Construct any response -// return &pb.ETSIGetEncryptKeys256BitReply{ -// KeyID: randomKey.keyID, -// Key: randomKey.key, -// }, nil -//} - func StartETSI(listenAddr string, callingKMS *EKMS) { flag.Parse() diff --git a/internal/kms/kmsintercom.go b/internal/kms/kmsintercom.go index 42670803e1bc5eb6264a2f1e8740b84bf3f889f0..78cd85502e2d52c17534f794e26bad77a36ad27e 100644 --- a/internal/kms/kmsintercom.go +++ b/internal/kms/kmsintercom.go @@ -3,7 +3,6 @@ package kms import ( "context" "encoding/base64" - "encoding/json" "flag" "net" "time" @@ -39,6 +38,8 @@ func (s *kmsTalkerServer) InterComCapabilities(ctx context.Context, in *pb.Inter }, 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) { // NOTE: with "google.golang.org/grpc/peer" it would be possible to get the client ip directly @@ -49,19 +50,24 @@ func (s *kmsTalkerServer) SyncQkdBulk(ctx context.Context, in *pb.SyncQkdBulkReq return nil, status.Errorf(codes.Internal, "peer does not exist") } + eqm, ok := peer.servingQuantumModul.(*EmulatedQuantumModule) + if !ok { + return nil, status.Errorf(codes.Internal, "expected emulated quantum module") + } + for _, bulkId := range in.BulkId { - rawBulkKeyIds := keysOfMap[int64](peer.servingQLE.rawBulkKeys) + rawBulkKeyIds := keysOfMap[int64](eqm.rawBulkKeys) log.Info("PEER BULK KEYS: ", rawBulkKeyIds) - if bulk, ok := peer.servingQLE.rawBulkKeys[bulkId]; ok { - peer.servingQLE.keyStorePeer = NewKmsKeyStore(256) - if err := peer.servingQLE.keyStorePeer.KeyChopper(bulk); err != nil { + if bulk, ok := eqm.rawBulkKeys[bulkId]; ok { + eqm.keyStore = NewKmsKeyStore(256) + if err := eqm.KeyChopper(bulk); err != nil { //TODO: proper error message return nil, status.Errorf(codes.Internal, "chopping failed") } - peer.servingQLE.rawBulkKeysMutex.Lock() - delete(peer.servingQLE.rawBulkKeys, bulkId) - peer.servingQLE.rawBulkKeysMutex.Unlock() + eqm.rawBulkKeysMutex.Lock() + delete(eqm.rawBulkKeys, bulkId) + eqm.rawBulkKeysMutex.Unlock() return &pb.SyncQkdBulkResponse{ Timestamp: time.Now().Unix(), @@ -101,13 +107,14 @@ func (s *kmsTalkerServer) InterComTransportKeyNegotiation(ctx context.Context, i // return nil, status.Errorf(codes.Internal, "A transport key for pathID: %s has already been negotiated.", in.PathID) //} - quantumElementRemoteKeyStore := route.Previous.servingQLE.keyStorePeer + quantumModuleKeyStore := route.Previous.servingQuantumModul.KeyStore() - key, ok := quantumElementRemoteKeyStore.keyStore[keyID] - if !ok { - return nil, status.Errorf(codes.Internal, "Key with ID: %s could not be found.", keyID) + key, err := quantumModuleKeyStore.GetKeyWithID(keyID) + if err != nil { + return nil, status.Errorf(codes.Internal, "%v", err) } + // TODO: mutex s.keyNegotiationMap[pathId] = key return &pb.InterComTransportKeyNegotiationResponse{Timestamp: time.Now().Unix()}, nil @@ -148,21 +155,21 @@ func (s *kmsTalkerServer) KeyForwarding(ctx context.Context, in *pb.KeyForwardin log.Infof("%s received the final payload: ", s.eKMS.kmsName, string(decryptedPayload)) } - // NOTE: For demo purpose only - json, err := json.Marshal(KMSInfo{ - Name: s.eKMS.kmsName, - EncryptedMessage: in.Payload, - DecryptedMessage: string(decryptedPayload), - Key: base64.StdEncoding.EncodeToString(decryptKey.key), - }) - if err != nil { - log.Println("Failed to marshal: ", err) - } + //// NOTE: For demo purpose only + //json, err := json.Marshal(KMSInfo{ + // Name: s.eKMS.kmsName, + // EncryptedMessage: in.Payload, + // DecryptedMessage: string(decryptedPayload), + // Key: base64.StdEncoding.EncodeToString(decryptKey.key), + //}) + //if err != nil { + // log.Println("Failed to marshal: ", err) + //} - err = sendKmsInfoMessage("http://172.20.10.21:4000/kmsinfo", json) - if err != nil { - log.Println("Failed to send KMS info message: ", err) - } + //err = sendKmsInfoMessage("http://172.20.10.21:4000/kmsinfo", json) + //if err != nil { + // log.Println("Failed to send KMS info message: ", err) + //} return &pb.KeyForwardingResponse{Timestamp: time.Now().Unix()}, nil } diff --git a/internal/kms/kmspeers.go b/internal/kms/kmspeers.go index 6e42f8f78e47394572c9be6ab3e22affd27ff930..494cb3b1d62b3b70e68b498d27d4f71d92d6510c 100644 --- a/internal/kms/kmspeers.go +++ b/internal/kms/kmspeers.go @@ -9,7 +9,6 @@ import ( pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom" "github.com/google/uuid" - "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -36,7 +35,7 @@ type kmsPeer struct { peerClient pbIC.KmsTalkerClient peerStatus KmsPeerStatus interComAddr string - servingQLE *QuantumElement + servingQuantumModul QuantumModule tcpSocket net.TCPAddr // the IP address and TCP port (aka socket) of the kms peer tcpSocketStr string // string rep. of tcpSocket et CryptoAlgorithm @@ -45,178 +44,42 @@ type kmsPeer struct { quit chan bool // cancel the peer goroutine } -func NewKmsPeer(servQLE *QuantumElement, tcpSocketStr string, interComAddr string, in chan string) (peer *kmsPeer, err error) { +func NewKmsPeer(servQM QuantumModule, tcpSocketStr string, interComAddr string, in chan string) (*kmsPeer, error) { + if servQM.Peer() != nil { + return nil, fmt.Errorf("QuantumModule with ID: , already has a peer", servQM.ID()) + } newPeerConn, err := grpc.Dial(tcpSocketStr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, err } peerClient := pbIC.NewKmsTalkerClient(newPeerConn) - return &kmsPeer{ + peer := &kmsPeer{ externalNotifierKMSPeer: in, - peerClient: peerClient, + // TODO: rename to client + peerClient: peerClient, // TODO: change this, only for demo purposes peerStatus: KmsPeerUp, // TODO: move this into a config - interComAddr: interComAddr, - servingQLE: servQLE, - tcpSocketStr: tcpSocketStr, - et: NewAES(), - id: uuid.New(), - quit: make(chan bool), - }, nil -} - -// Handles everything with respect to a specific KMS peer -//func (ph *kmsPeer) PeerHandler(kmsName string) { -// // log.Infof("%s started PeerHandler for %s:", kmsName, ph.tcpSocketStr) -// -// // contact peer -// newPeerConn, err := grpc.Dial(ph.tcpSocketStr, grpc.WithTransportCredentials(insecure.NewCredentials())) -// if err != nil { -// log.Errorf("%s: did not connect: %v", kmsName, err) -// ph.peerStatus = KmsPeerDown -// return -// } -// defer newPeerConn.Close() -// -// c := pb.NewKmsETSIClient(newPeerConn) -// -// // Contact the server and print out its response. -// ctx, cancel := context.WithTimeout(context.Background(), time.Second) -// defer cancel() -// r, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName}) -// if err != nil { -// log.Errorf("%s: could not greet: %v", kmsName, err) -// ph.peerStatus = KmsPeerDown -// // Send notification about change -// if ph.externalNotifierKMSPeer != nil { -// ph.externalNotifierKMSPeer <- ph.tcpSocketStr -// } -// } -// // 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.Errorf("%s: could not request a encryption key: %s", kmsName, err) -// ph.peerStatus = KmsPeerDown -// // Send notification about change -// if ph.externalNotifierKMSPeer != nil { -// ph.externalNotifierKMSPeer <- ph.tcpSocketStr -// } -// return -// } -// -// // check if key is in KeyStore -// if key, ok := ph.servingQLE.keyStorePeer.keyStore[encryptKeyRequest.KeyID]; ok { -// keyAsString := base64.StdEncoding.EncodeToString(key.key) -// log.Debugf("Agreed Key: %s", keyAsString) -// -// // TODO: Remove/move ssh-kind prototype code below -// // 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.Errorf("%s: could not execute ssh command with parameters", kmsName) -// return -// } -// } -// -// // Send notification about change -// if ph.externalNotifierKMSPeer != nil { -// ph.externalNotifierKMSPeer <- ph.tcpSocketStr -// } -// -// 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 { -// // 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) SyncBulkKeys() error { - rawBulkKeyIds := keysOfMap[int64](ph.servingQLE.rawBulkKeys) - logrus.Info("Found the following bulk key ids for usage: ", rawBulkKeyIds) - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - initialPeerSetupResponse, err := ph.peerClient.SyncQkdBulk(ctx, &pbIC.SyncQkdBulkRequest{ - Timestamp: time.Now().Unix(), - InterComAddr: ph.interComAddr, - BulkId: rawBulkKeyIds, - }) - if err != nil { - return err + interComAddr: interComAddr, + servingQuantumModul: servQM, + tcpSocketStr: tcpSocketStr, + et: NewAES(), + id: uuid.New(), + quit: make(chan bool), } - bulkKey, ok := ph.servingQLE.rawBulkKeys[initialPeerSetupResponse.BulkId] - if !ok { - // TODO: add proper error message - return fmt.Errorf("Could not find raw bulk key with id: %d", initialPeerSetupResponse.BulkId) - } - - // TODO: Initially the peer partners should discuss about the key length, - // for now it is hardcoded. - ph.servingQLE.keyStorePeer = NewKmsKeyStore(256) + servQM.SetPeer(peer) - if err := ph.servingQLE.keyStorePeer.KeyChopper(bulkKey); err != nil { - return err + if err := servQM.Initialize(); err != nil { + return nil, err } - ph.servingQLE.rawBulkKeysMutex.Lock() - delete(ph.servingQLE.rawBulkKeys, initialPeerSetupResponse.BulkId) - ph.servingQLE.rawBulkKeysMutex.Unlock() - - // update the peer status to up - ph.peerStatus = KmsPeerUp - // Send notification about change - if ph.externalNotifierKMSPeer != nil { - ph.externalNotifierKMSPeer <- ph.tcpSocketStr - } + return peer, nil +} - return nil +func (ph *kmsPeer) SyncBulkKeys() error { + return ph.servingQuantumModul.Sync() } // TransportKeyNegotiation sends a request for a transport key negotiation to @@ -229,7 +92,9 @@ func (ph *kmsPeer) TransportKeyNegotiation() error { } func (ph *kmsPeer) SendPayload(payload []byte, pathId uuid.UUID) error { - if len(ph.servingQLE.keyStorePeer.keyStore) <= int(ph.servingQLE.keyStorePeer.indexCounter) { + // NOTE: It should be assumed that there are keys available if we try to + // send. + if len(ph.servingQuantumModul.KeyStore().keyStore) <= int(ph.servingQuantumModul.KeyStore().indexCounter) { log.Debug("Syncing bulk keys before sending the payload") err := ph.SyncBulkKeys() if err != nil { @@ -237,11 +102,10 @@ func (ph *kmsPeer) SendPayload(payload []byte, pathId uuid.UUID) error { } } - // TODO: Remove; for demo purposes only - time.Sleep(5 * time.Second) + // TODO: Return a message if keys are empty // select a key from key store - key, err := ph.servingQLE.keyStorePeer.GetKey() + key, err := ph.servingQuantumModul.KeyStore().GetKey() if err != nil { return err } @@ -292,7 +156,3 @@ func (ph *kmsPeer) GetKmsPeerStatus() KmsPeerStatus { func (ph *kmsPeer) GetKmsPeerId() uuid.UUID { return ph.id } - -func (ph *kmsPeer) GetKmsPeerQkdiId() uint32 { - return uint32(ph.servingQLE.QlID) -} diff --git a/internal/kms/module.go b/internal/kms/module.go new file mode 100644 index 0000000000000000000000000000000000000000..0b170ba5e3b24d410c16d87e1cd6977efdbfb73c --- /dev/null +++ b/internal/kms/module.go @@ -0,0 +1,179 @@ +package kms + +import ( + "context" + "errors" + "fmt" + "io" + "net" + "sync" + "time" + + 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" + "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" +) + +// QuantumModule ... +type QuantumModule interface { + ID() uuid.UUID + Initialize() error + // NOTE: Sync will be removed as soon as the emulated quantum module has been + // changed to push a constant byte stream. + Sync() error + Manufacturer() string + KeyStore() *kmsKeyStore + Peer() *kmsPeer + SetPeer(*kmsPeer) + Address() net.Addr +} + +type EmulatedQuantumModule struct { + QlID uuid.UUID + QuantumElementLink *quantumlayer.QuantumlayerEmuPRNG // contains information about the quantum links + //key stores of unchopped bulk keys go here + rawBulkKeysMutex sync.Mutex + rawBulkKeys map[int64]*quantumlayer.QuantumLayerBulkKey + keyStore *kmsKeyStore // the keys used between two peers. + peer *kmsPeer +} + +func NewEmulatedQuantumModule(kmsUDPAddr string, generateKeys bool, logOutput io.Writer, logLevel log.Level, logInJson bool) *EmulatedQuantumModule { + // create an emulated quantum layer + ql := quantumlayer.NewQuantumlayerEmuPRNG(logOutput, logLevel, logInJson) + ql.Configure(kmsUDPAddr) + ql.PowerOn(generateKeys) + + return &EmulatedQuantumModule{ + QlID: uuid.New(), + QuantumElementLink: ql, + rawBulkKeys: make(map[int64]*quantumlayer.QuantumLayerBulkKey), + keyStore: NewKmsKeyStore(256), + peer: nil, + } +} + +func (eqe *EmulatedQuantumModule) ID() uuid.UUID { + return eqe.QlID +} + +func (eqe *EmulatedQuantumModule) Manufacturer() string { + return "danet" +} + +func (eqe *EmulatedQuantumModule) Initialize() error { + // TODO: error handling + go eqe.keyHandler() + return nil +} + +func (eqe *EmulatedQuantumModule) Address() net.Addr { + return eqe.QuantumElementLink.GetLocalQLPort() +} + +func (eqe *EmulatedQuantumModule) KeyStore() *kmsKeyStore { + return eqe.keyStore +} + +func (eqe *EmulatedQuantumModule) Sync() error { + rawBulkKeyIds := keysOfMap[int64](eqe.rawBulkKeys) + logrus.Info("Found the following bulk key ids for usage: ", rawBulkKeyIds) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + initialPeerSetupResponse, err := eqe.peer.peerClient.SyncQkdBulk(ctx, &pbIC.SyncQkdBulkRequest{ + Timestamp: time.Now().Unix(), + InterComAddr: eqe.peer.interComAddr, + BulkId: rawBulkKeyIds, + }) + if err != nil { + return err + } + + bulkKey, ok := eqe.rawBulkKeys[initialPeerSetupResponse.BulkId] + if !ok { + // TODO: add proper error message + return fmt.Errorf("Could not find raw bulk key with id: %d", initialPeerSetupResponse.BulkId) + } + + // TODO: Initially the peer partners should discuss about the key length, + // for now it is hardcoded. + eqe.keyStore = NewKmsKeyStore(256) + + if err := eqe.KeyChopper(bulkKey); err != nil { + return err + } + + eqe.rawBulkKeysMutex.Lock() + delete(eqe.rawBulkKeys, initialPeerSetupResponse.BulkId) + eqe.rawBulkKeysMutex.Unlock() + + // update the peer status to up + eqe.peer.peerStatus = KmsPeerUp + // Send notification about change + if eqe.peer.externalNotifierKMSPeer != nil { + eqe.peer.externalNotifierKMSPeer <- eqe.peer.tcpSocketStr + } + + return nil +} + +func (eqe *EmulatedQuantumModule) Peer() *kmsPeer { + return eqe.peer +} + +func (eqe *EmulatedQuantumModule) SetPeer(peer *kmsPeer) { + eqe.peer = peer +} + +func (eqe *EmulatedQuantumModule) keyHandler() { + // periodically walk through quantum element and retrieve the key bulk buffer + for { + log.Debugf("%s: KeyHandler reading...\n", eqe.ID()) + bulkKeys, err := eqe.QuantumElementLink.GetKeyBulkPeer() + if err != nil { + log.Errorf("%s: failed to retrieve bulkkeys with error %s", eqe.ID(), err) + } else { + // Add to the slice, but not process yet. + log.Debugf("%s: produced %d bytes of key", eqe.ID(), bulkKeys.BulkKeyLength) + eqe.rawBulkKeysMutex.Lock() + eqe.rawBulkKeys[bulkKeys.BulkKeyId] = &bulkKeys + eqe.rawBulkKeysMutex.Unlock() + } + // TODO: hardcoded + time.Sleep(5 * time.Second) + } +} + +// Takes a bulk of keys and chops them in chopFactor keys each +// Any remainder is discarded +func (eqe *EmulatedQuantumModule) KeyChopper(bulkKey *quantumlayer.QuantumLayerBulkKey) error { + if eqe.keyStore.keySingleSize == 0 { + return errors.New("KeyChopper: no keySingleSize set") + } + // TODO check if multiple of 8 (1 Byte) + + if bulkKey.BulkKeyLength != len(*bulkKey.BulkKey) { + return errors.New("bulkKey length mismatch") + } + + // reset indexCounter + eqe.keyStore.indexCounter = 0 + + var keyId uint64 + keyId = 0 + + // Let's chop! + chopFactor := eqe.keyStore.keySingleSize >> 3 + key := *bulkKey.BulkKey + for len(key) > int(chopFactor) { + tmpkey := key[:chopFactor] + eqe.keyStore.addKey(keyId, tmpkey) + keyId++ + // shorten the key storage + key = key[chopFactor:] + } + return nil +} diff --git a/internal/main_test.go b/internal/main_test.go index 9775621673bd106c66a1683bcfaf70ca9cd95423..3c59b5c785224bdc0879d45e616c86ed4f8d8bce 100644 --- a/internal/main_test.go +++ b/internal/main_test.go @@ -64,8 +64,14 @@ func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAdd // Attach to eKMS emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr) + eqm := kms.NewEmulatedQuantumModule(myUDPAddr, false, os.Stdout, log.TraceLevel, false) + // Fire up Quantum LinK - myQL := emuKMS.AddQuantumElement(myUDPAddr, false, os.Stdout, log.TraceLevel, false) + err := emuKMS.AddQuantumElement(eqm) + if err != nil { + log.Println("failed to create emulated quantum module") + return + } udpQL2Addr, err := net.ResolveUDPAddr("udp", peerUDPAddr) if err != nil { @@ -73,9 +79,9 @@ func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAdd return } - myQL.QuantumElementLink.AddPeer(udpQL2Addr) + eqm.QuantumElementLink.AddPeer(udpQL2Addr) - _, err = emuKMS.AddPeer(peerInterComAddr, myQL) + _, err = emuKMS.AddPeer(peerInterComAddr, eqm) if err != nil { log.Println("PEERERROR: ", err) } @@ -83,8 +89,8 @@ 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) + // // TODO/XXX catch errors! + // emuKMS.GlobalKeyHandler(7 * time.Second) } func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, rightUDPAddr, rightInterComAddr string) { @@ -92,8 +98,8 @@ func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr) // create two quantum modules that generate keys - qlForLeft := emuKMS.AddQuantumElement("[::1]:50910", true, os.Stdout, log.TraceLevel, false) - qlForRight := emuKMS.AddQuantumElement("[::1]:50911", true, os.Stdout, log.TraceLevel, false) + 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 { @@ -107,6 +113,19 @@ func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, 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) @@ -123,9 +142,6 @@ func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, // Start the SDN/management and key retrieval interface go kms.StartETSI(myUDPAddr, emuKMS) - // TODO/XXX catch errors! - go emuKMS.GlobalKeyHandler(7 * time.Second) - time.Sleep(time.Second * 15) if err := peerLeft.SyncBulkKeys(); err != nil { log.Println("SYNC ERROR: ", err) diff --git a/internal/quantumlayer/quantumlayer-emu-prng.go b/internal/quantumlayer/quantumlayer-emu-prng.go index b2a2013b144d2adcdc94aee94dfcfed3d3d84a3d..76dcd1dfb268c61a2039e2011dd7eac747ad24c6 100644 --- a/internal/quantumlayer/quantumlayer-emu-prng.go +++ b/internal/quantumlayer/quantumlayer-emu-prng.go @@ -137,6 +137,7 @@ func (qlemuprng *QuantumlayerEmuPRNG) PowerOn(enableKeyGeneration bool) { // 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 { @@ -248,8 +249,8 @@ func (qlemuprng *QuantumlayerEmuPRNG) RemovePeer() { qlemuprng.qlPeerMutex.Unlock() } -func (qlemuprng *QuantumlayerEmuPRNG) GetLocalQLPort() (myAddr net.UDPAddr) { - return *qlemuprng.qlLocalPort +func (qlemuprng *QuantumlayerEmuPRNG) GetLocalQLPort() (myAddr *net.UDPAddr) { + return qlemuprng.qlLocalPort } func (qlemuprng *QuantumlayerEmuPRNG) GenerateRandomNumbers() (randNums []byte) {