Newer
Older
// This package kms implements a simplistic key management system (kms) for
// Quantum Key Distribution Networks (QKDN) which is a simple emulated KMS. x
// It relies on the emulated quantum link out of the quantumlayer package
package kms
import (
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/metadata"
pbIC "code.fbi.h-da.de/danet/quant/goKMS/api/gen/proto/go/kmsintercom"
"code.fbi.h-da.de/danet/quant/goKMS/config"
akmsInterfaceClient "code.fbi.h-da.de/danet/quant/goKMS/kms/akmsInterface/client"
akmsInterfaceServer "code.fbi.h-da.de/danet/quant/goKMS/kms/akmsInterface/server"
"code.fbi.h-da.de/danet/quant/goKMS/kms/crypto"
etsi14Server "code.fbi.h-da.de/danet/quant/goKMS/kms/etsi/etsi14/server"
"code.fbi.h-da.de/danet/quant/goKMS/kms/event"
"code.fbi.h-da.de/danet/quant/goKMS/kms/peers"
"code.fbi.h-da.de/danet/quant/goKMS/kms/receiver"
"code.fbi.h-da.de/danet/quant/goKMS/kms/store"
kmstls "code.fbi.h-da.de/danet/quant/goKMS/kms/tls"
"code.fbi.h-da.de/danet/quant/goKMS/kms/util"
pbQS "code.fbi.h-da.de/danet/quipsec/gen/go/quipsec"
"github.com/google/uuid"
)
PathId uuid.UUID
Previous *peers.KmsPeer
Next *peers.KmsPeer
type BitKeyLength string
const (
BitKeyLen128 BitKeyLength = "128"
BitKeyLen256 BitKeyLength = "256"
BitKeyLen512 BitKeyLength = "512"
)
type PlatformKey struct {
Id uuid.UUID
Value []byte
ProcessId string
}
kmsName string
kmsUUID uuid.UUID
interComAddr string
quantumAddress string
tlsConfig config.TLSConfig
gRPCTimeout time.Duration
// TODO create a mapping between ids and address
remoteKMSMapping map[string]*util.RemoteKMS
remoteKMSMappingMutex sync.RWMutex
quantumModules map[string]peers.QuantumModule
quantumModulesMutex sync.RWMutex
// NOTE: There is probably a better way to handle this
PKStore map[string]map[uuid.UUID]*PlatformKey
// TODO(maba): find a better name for this
routingTable map[uuid.UUID]*Route
routingTableMutex sync.RWMutex
KmsPeers map[string]*peers.KmsPeer
pbIC.UnimplementedKmsTalkerServer
supportedKeyLengths map[BitKeyLength]bool
eventBus *event.EventBus
receiver *receiver.Receiver
// Akms things
ckmsAkmsClient *akmsInterfaceClient.CkmsAkmsClient
ckmsAkmsServer *akmsInterfaceServer.AKMSReceiverServer
etsi14Server *etsi14Server.ETSI14RESTService
keyStoreChannel chan []crypto.KSAKey
// Will keep information about the quantum elements that this EKMS is talking to
// This actually constitutes a quantum element with only a single link
/*
type QuantumElementInterface interface {
GetQlID() qlElementId
}*/
func NewKMS(kmsUUID uuid.UUID, logOutput io.Writer, logLevel log.Level, logInJson bool, config *config.Config, receiver *receiver.Receiver) (newKMS *KMS) {
/*
* 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(&log.TextFormatter{})
} else {
log.SetFormatter(&log.JSONFormatter{})
}
// print code function if level is set to Trace
if logLevel == log.TraceLevel {
log.SetReportCaller(true)
} else {
log.SetReportCaller(false)
}
var ckmsAkmsClient *akmsInterfaceClient.CkmsAkmsClient
var err error
if config.AKMS.RemoteAddress != "" {
ckmsAkmsClient, err = akmsInterfaceClient.NewCkmsAkmsClient(config.AKMS.RemoteAddress, config.AKMS.ClientTLS)
if err != nil {
log.Fatalf("Failed to setup CkmsAkmsClient: %s", err)
}
gRPCTimeoutInSecondsDuration := time.Duration(config.GRPCTimeoutInSeconds) * time.Second
kmsUUID: kmsUUID,
interComAddr: config.InterComAddr,
quantumAddress: config.QuantumAddr,
tlsConfig: config.KmsTLS,
gRPCTimeout: gRPCTimeoutInSecondsDuration,
remoteKMSMapping: make(map[string]*util.RemoteKMS),
quantumModules: make(map[string]peers.QuantumModule),
routingTable: make(map[uuid.UUID]*Route),
PKStore: make(map[string]map[uuid.UUID]*PlatformKey),
KmsPeers: make(map[string]*peers.KmsPeer),
supportedKeyLengths: make(map[BitKeyLength]bool),
eventBus: event.NewEventBus(),
ckmsAkmsClient: ckmsAkmsClient,
createdKMS.supportedKeyLengths[BitKeyLen256] = true
// start the inter communication gRPC server
go createdKMS.startGRPC()
err = createdKMS.initializePeers(config)
if err != nil {
log.Fatalf("Failed to initialize peers: %s", err)
}
// Start the akmsCkmsReceiverServer
if config.AKMS.ServerPort != "" {
createdKMS.ckmsAkmsServer, err = akmsInterfaceServer.NewAKMSReceiver(config.AKMS.ServerPort, createdKMS.eventBus, receiver, createdKMS.GenerateAndSendKSAKey, config.AKMS.ServerTLS)
if err != nil {
log.Fatalf("Failed to initialize CkmsAkmsServer: %s", err)
}
log.Infof("Starting AKMS receiver server on port: %s", config.AKMS.ServerPort)
go createdKMS.ckmsAkmsServer.Serve()
}
// Setup ETSI14 Server if info is in config
if config.ETSI14Server != nil {
remoteCKMSID, err := uuid.Parse(config.ETSI14Server.RemoteCKMSID)
if err != nil {
log.Error(err)
}
createdKMS.etsi14Server = etsi14Server.NewETSI14RESTService(config.ETSI14Server.Address, remoteCKMSID, createdKMS.exchangeKeyAfterETSI14GetKeyRequest)
go createdKMS.etsi14Server.Run()
createdKMS.keyStoreChannel = createdKMS.etsi14Server.KeyStoreChannel
} else {
log.Info("No ETSI14 server running.")
}
func (kms *KMS) initializePeers(config *config.Config) error {
var qm peers.QuantumModule
var err error
err = resolveHostnameToIPForQuantumModule(&peer)
if err != nil {
log.Error(err)
continue
}
pqm := peer.QuantumModule
switch qmt := peer.QuantumModule.QmType; qmt {
case "emulated":
qm = peers.NewDanetQuantumModule(pqm.Address, config.Id)
Fabian Seidl
committed
qm, err = peers.NewETSI014HTTPQuantumModule(pqm.Address, config.Id, pqm.LocalSAEID, pqm.TargetSAEID,
peer.QuantumModule.TLS, pqm.MasterMode,
peer.QuantumModule.KeyFetchInterval, int64(peer.QuantumModule.KeyFetchAmount), uint64(peer.QuantumModule.MaxKeyFillLevel))
if err != nil {
log.Fatalf("Failed to create ETSI QKD module: %s", err)
return nil
}
default:
log.Fatalf("Unknown type: %s for quantum module", qmt)
return nil
}
if err != nil {
log.Fatalf("Failed to add quantum element: %s", err)
return nil
}
gRPCTransportCreds, err := kmstls.GenerateGRPCClientTransportCredsBasedOnTLSFlag(kms.tlsConfig)
if err != nil {
return fmt.Errorf("unable to generate gRPC transport creds: %w", err)
newPeerConn, err := grpc.NewClient(peer.PeerInterComAddr, grpc.WithTransportCredentials(gRPCTransportCreds))
if err != nil {
return nil
}
client := &peers.GRPCClient{}
switch pt := peer.Type; pt {
case "danet":
client.KmsTalkerClient = pbIC.NewKmsTalkerClient(newPeerConn)
}
_, err = kms.AddPeer(peer.PeerId, peer.PeerInterComAddr, qm, client)
if err != nil {
log.Fatalf("Failed to create a peer: %s", err)
return nil
}
}
return nil
}
func (kms *KMS) startGRPC() {
interKMSLis, err := net.Listen("tcp", kms.interComAddr)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
gRPCTransportCreds, err := kmstls.GenerateGRPCServerTransportCredsBasedOnTLSFlag(kms.tlsConfig)
if err != nil {
log.Fatalf("unable to generate gRPC server: %v", err)
}
interKMSServer := grpc.NewServer(grpc.Creds(gRPCTransportCreds))
healthCheck := health.NewServer()
healthpb.RegisterHealthServer(interKMSServer, healthCheck)
pbIC.RegisterKmsTalkerServer(interKMSServer, &kmsTalkerServer{
keyNegotiationMap: make(map[uuid.UUID]*store.KmsKSElement),
if kms.quantumAddress != "" {
quantumLis, err := net.Listen("tcp", kms.quantumAddress)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
quantumServ := grpc.NewServer()
pbQS.RegisterKmsQkdmCommunicationServiceServer(quantumServ, &quipSecServer{
KMS: kms,
})
log.Infof("quantum server listening at %v", quantumLis.Addr())
go quantumServ.Serve(quantumLis) //nolint:errcheck
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("inter KMS server listening at %v", interKMSLis.Addr())
if err := interKMSServer.Serve(interKMSLis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
func (kms *KMS) AddQuantumElement(qm peers.QuantumModule) error {
kms.quantumModulesMutex.Lock()
defer kms.quantumModulesMutex.Unlock()
log.Infof("quantum module address: %s ", qm.Address())
kms.quantumModules[qm.Address()] = qm
func (kms *KMS) AddPeer(peerKmsId string, kmsPeerSocket string, servingQLE peers.QuantumModule, client *peers.GRPCClient) (*peers.KmsPeer, error) {
_, err := kms.FindPeerById(peerKmsId)
if err == nil {
log.Errorf("Trying to add existing peer %s, with KMS ID %s", kmsPeerSocket, peerKmsId)
return nil, fmt.Errorf("trying to add existing peer %s, with KMS ID %s", kmsPeerSocket, peerKmsId)
peer, err := peers.NewKmsPeer(peerKmsId, servingQLE, kmsPeerSocket, client, kms.eventBus, kms.gRPCTimeout)
kms.kmsPeersMutex.Lock()
defer kms.kmsPeersMutex.Unlock()
kms.KmsPeers[peerKmsId] = peer
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
go func() {
restartWaitingTime := time.Duration(3) * time.Second
ticker := time.NewTicker(restartWaitingTime)
defer ticker.Stop()
InitialResetLoop:
for !peer.QuantumModule().IsActive() {
select {
case <-ticker.C:
if client := peer.Client().KmsTalkerClient; client != nil {
log.Debugf("Sending initial peer setup request to peer: %s with the request to reset the corresponding key store", peerKmsId)
ctx, cancel := context.WithTimeout(context.Background(), kms.gRPCTimeout)
defer cancel()
_, err := client.InterComCapabilities(ctx, &pbIC.InterComCapabilitiesRequest{
Timestamp: time.Now().Unix(),
KmsId: kms.kmsUUID.String(),
ResetKeyStore: true,
})
if err == nil {
if err := peer.QuantumModule().Initialize(); err != nil {
log.Fatalf("Failed to initialized quantum module: %s for peer: %s", peer.QuantumModule().ID(), peer.GetKmsPeerId())
}
log.Debugf("Successfully initialized quantum module: %s for peer %s", peer.QuantumModule().ID(), peerKmsId)
break InitialResetLoop
}
}
}
}
log.Debugf("Successfully initialized peer: %s", peerKmsId)
}()
func (kms *KMS) AssignForwardingRoute(pId, pHop, nHop string, remoteKMS *util.RemoteKMS) error {
pathId, err := uuid.Parse(pId)
if err != nil {
return fmt.Errorf("the given path id %s is no uuid; err = %w", pathId, err)
var previousHop *peers.KmsPeer
var nextHop *peers.KmsPeer
previousHop, err = kms.FindPeerById(pHop)
if err != nil {
return fmt.Errorf("no peer found for %s", pHop)
nextHop, err = kms.FindPeerById(nHop)
if err != nil {
return fmt.Errorf("no peer found for %s", pHop)
PathId: pathId,
Previous: previousHop,
Next: nextHop,
RemoteKMS: remoteKMS,
kms.routingTableMutex.Lock()
// set the route within routing table
kms.routingTableMutex.Unlock()
if tmpRoute.RemoteKMS != nil {
kms.remoteKMSMappingMutex.Lock()
if _, ok := kms.remoteKMSMapping[tmpRoute.RemoteKMS.Id]; !ok {
kms.remoteKMSMapping[tmpRoute.RemoteKMS.Id] = tmpRoute.RemoteKMS
}
kms.remoteKMSMappingMutex.Unlock()
}
if tmpRoute.Previous == nil && tmpRoute.Next != nil && tmpRoute.RemoteKMS != nil {
// generate pk key
pk, err := crypto.Random256BitKey()
if err != nil {
return err
}
// generate process id
processId := uuid.New()
kms.AddSpecificPlatformKey(tmpRoute.RemoteKMS.Id, pathId, processId, pk)
err = tmpRoute.Next.SendInitialPayloadBasedOnGRPCClient(pk, tmpRoute.PathId, processId, kms.kmsUUID.String(), remoteKMS)
if err != nil {
log.Error(err)
return err
}
}
func (kms *KMS) AddSpecificPlatformKey(remoteKMSId string, pathId uuid.UUID, processId uuid.UUID, key *crypto.Key) {
kms.PKStoreMutex.Lock()
defer kms.PKStoreMutex.Unlock()
keys, ok := kms.PKStore[remoteKMSId]
if !ok {
kms.PKStore[remoteKMSId] = map[uuid.UUID]*PlatformKey{
pathId: {
Id: key.ID,
Value: key.Key,
ProcessId: processId.String(),
},
}
} else {
keys[pathId] = &PlatformKey{
Id: key.ID,
Value: key.Key,
ProcessId: processId.String(),
}
}
log.Debug("Current store of platform keys: ", kms.PKStore)
}
func (kms *KMS) GetSpecificPlatformKey(remoteKMSId string, keyId uuid.UUID) (*PlatformKey, error) {
kms.PKStoreMutex.Lock()
defer kms.PKStoreMutex.Unlock()
keyIDs, ok := kms.PKStore[remoteKMSId]
if !ok {
return nil, fmt.Errorf("no entry for given KMS id: %s", remoteKMSId)
pk, ok := keyIDs[keyId]
if !ok {
return nil, fmt.Errorf("no key ready to use for given KMS id: %s", remoteKMSId)
}
delete(keyIDs, keyId)
return pk, nil
}
func (kms *KMS) GetRemoteKMS(remoteKMSId string) (*util.RemoteKMS, error) {
kms.remoteKMSMappingMutex.RLock()
defer kms.remoteKMSMappingMutex.RUnlock()
remoteKMS, ok := kms.remoteKMSMapping[remoteKMSId]
if !ok {
return nil, fmt.Errorf("address for remoteKMS with id %s not found", remoteKMSId)
}
return remoteKMS, nil
}
// NOTE: address/remoteid still have to decide.
func (kms *KMS) GenerateAndSendKSAKey(remoteKMSId string, pathId uuid.UUID, requestID string, number int) error {
if number < 1 {
log.Errorf("number must be positive and at least 1, provided: %d\n", number)
return fmt.Errorf("number must be positive and at least 1, provided: %d", number)
}
log.Infof("KMS store: %v", kms.remoteKMSMapping)
remoteKMS, err := kms.GetRemoteKMS(remoteKMSId)
if err != nil {
log.Error(err)
return err
}
platformKey, err := kms.GetSpecificPlatformKey(remoteKMSId, pathId)
if err != nil {
log.Error(err)
return err
}
akmsKSAKeys := make([]crypto.KSAKey, number)
cryptoAlgo := crypto.NewAES()
for i := 0; i < number; i++ {
ksaKey, akmsKSAKey, err := generateNewKSAKey(cryptoAlgo, platformKey.Value)
if err != nil {
log.Error(err)
return err
}
ksaKeys[i] = ksaKey
akmsKSAKeys[i] = *akmsKSAKey
remoteKMSAdrress := fmt.Sprintf("%s:%d", remoteKMS.Address, remoteKMS.Port)
err = kms.sendKSAKeysToPlatformKmsPeer(remoteKMSAdrress, platformKey.Id.String(), requestID, ksaKeys)
if err != nil {
log.Error(err)
return err
}
// Use the real processID when we know what it is
err = kms.ckmsAkmsClient.SendKSAKeysToRequestingInstances(requestID, platformKey.ProcessId, akmsKSAKeys)
if err != nil {
log.Error(err)
return err
}
func (kms *KMS) EventBus() *event.EventBus {
return kms.eventBus
}
func (kms *KMS) RemovePeer(kmsPeerSocket string) error {
_, err := kms.FindPeerById(kmsPeerSocket)
if err != nil {
return fmt.Errorf("Could not remove peer with id: %s, not found", kmsPeerSocket)
kms.kmsPeersMutex.Lock()
defer kms.kmsPeersMutex.Unlock()
// peer.quit <- true
delete(kms.KmsPeers, kmsPeerSocket)
return nil
func (kms *KMS) FindPeerById(id string) (*peers.KmsPeer, error) {
kms.kmsPeersMutex.RLock()
defer kms.kmsPeersMutex.RUnlock()
peer, ok := kms.KmsPeers[id]
if !ok {
return nil, fmt.Errorf("No peer found for id: %s", id)
func (kms *KMS) RoutingTableDeepCopy() map[uuid.UUID]*Route {
routingTableCopy := make(map[uuid.UUID]*Route, len(kms.KmsPeers))
kms.routingTableMutex.Lock()
defer kms.routingTableMutex.Unlock()
for k, v := range kms.routingTable {
func (kms *KMS) PeersDeepCopy() map[string]*peers.KmsPeer {
peersCopy := make(map[string]*peers.KmsPeer, len(kms.KmsPeers))
kms.kmsPeersMutex.RLock()
defer kms.kmsPeersMutex.RUnlock()
for k, v := range kms.KmsPeers {
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
func resolveHostnameToIPForQuantumModule(peer *config.Peer) error {
const connectionRetries = 60
var ipAddr []net.IP
var err error
// If the address is not set, try to resolve the hostname.
if peer.QuantumModule.Address == "" && peer.QuantumModule.Hostname != "" {
log.Info("Trying to get IP from hostname for quantum module: ", peer.QuantumModule.Hostname)
for j := 0; j < connectionRetries; j++ {
ipAddr, err = net.LookupIP(peer.QuantumModule.Hostname)
if err == nil {
break
}
log.Errorf("Failed to get IP from hostname %s, retrying in 2 seconds (attempt %d/%d)", peer.QuantumModule.Hostname, j+1, connectionRetries)
time.Sleep(2 * time.Second)
}
if err != nil {
return fmt.Errorf("IP address not set and failed to resolve hostname for two minutes for quantum module: %s. Error: %s", peer.QuantumModule.Hostname, err.Error())
}
// Just use the first valid IP for now.
ipAdrrString := ipAddr[0].String()
log.Infof("Resolved hostname to IP address for quantum module. Hostname: %s, IP: %s", peer.QuantumModule.Hostname, ipAdrrString)
peer.QuantumModule.Address = ipAdrrString
} else if peer.QuantumModule.Address == "" && peer.QuantumModule.Hostname == "" {
return fmt.Errorf("IP address and hostname not set for quantum module. Erros may occur and the module might not work properly.")
}
return nil
}
func generateNewKSAKey(cryptoAlgo crypto.CryptoAlgorithm, platformKeyValue []byte) (*pbIC.Key, *crypto.KSAKey, error) {
// generate ksa key
ksaKeyId := uuid.New()
ksaKey, err := crypto.Random256BitKey()
if err != nil {
log.Error(err)
return nil, nil, err
}
// encrypt the key
nonce, encryptedKSAKey, err := cryptoAlgo.Encrypt(ksaKey.Key, platformKeyValue)
if err != nil {
log.Error(err)
return nil, nil, err
}
ksaKeyAsString := base64.StdEncoding.EncodeToString(ksaKey.Key)
encryptedKSAKeyAsString := base64.StdEncoding.EncodeToString(encryptedKSAKey)
nonceAsString := base64.StdEncoding.EncodeToString(nonce)
ksaKeyToSend := &pbIC.Key{
Id: ksaKeyId.String(),
Nonce: nonceAsString,
Key: encryptedKSAKeyAsString,
}
akmsKSAKey := &crypto.KSAKey{
KeyID: ksaKeyId.String(),
Key: ksaKeyAsString,
}
return ksaKeyToSend, akmsKSAKey, nil
}
func (kms *KMS) sendKSAKeysToPlatformKmsPeer(kmsPeerAddress, platformKeyID, requestID string, ksaKeys []*pbIC.Key) error {
gRPCTransportCreds, err := kmstls.GenerateGRPCClientTransportCredsBasedOnTLSFlag(kms.tlsConfig)
if err != nil {
return fmt.Errorf("unable to generate gRPC transport creds: %w", err)
}
remoteConn, err := grpc.NewClient(kmsPeerAddress, grpc.WithTransportCredentials(gRPCTransportCreds))
if err != nil {
log.Error(err)
return err
}
remoteClient := pbIC.NewKmsTalkerClient(remoteConn)
ctx, cancel := context.WithTimeout(context.Background(), kms.gRPCTimeout)
// create a new context with some metadata
md := metadata.Pairs("hostname", kms.kmsName)
ctx = metadata.NewOutgoingContext(ctx, md)
defer cancel()
_, err = remoteClient.KeyDelivery(ctx, &pbIC.KeyDeliveryRequest{
KeyId: platformKeyID,
RequestId: requestID,
KmsId: kms.kmsUUID.String(),
Keys: ksaKeys,
})
if err != nil {
log.Error(err)
return err
}
return nil
}
func (kms *KMS) exchangeKeyAfterETSI14GetKeyRequest(receivingCKMSID uuid.UUID, number int64, requestID string) ([]crypto.KSAKey, error) {
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
// CreateRouteRequest
pathID := uuid.New()
log.Debugf("(ETSI14) created new path id: %s, for incoming ETSI14 key request", pathID)
receiverChan, err := kms.receiver.RequestReceiverChannel(pathID)
if err != nil {
log.Error(err)
return nil, err
}
err = kms.eventBus.Publish(event.NewCreateRouteEvent(pathID.String(), receivingCKMSID.String()))
if err != nil {
log.Errorf("(ETSI14) Failed sending a create route request: %s", err)
return nil, err
}
select {
case <-receiverChan:
case <-time.After(20 * time.Second):
if err := kms.receiver.RemoveReceiver(pathID); err != nil {
log.Errorf("Failed removing receiver for pathId: %s ; err: %v", pathID, err)
}
log.Errorf("(ETSI14) Platform Key exchange failed for PathID: %s", pathID)
return nil, fmt.Errorf("Platform Key exchange failed for PathID: %s", pathID)
}
// GenerateAndSend
return kms.generateAndReturnKsaKey(receivingCKMSID, pathID, number, requestID)
func (kms *KMS) generateAndReturnKsaKey(receivingCKMSID, pathID uuid.UUID, number int64, requestID string) ([]crypto.KSAKey, error) {
if number < 1 {
log.Errorf("number must be positive and at least 1, provided: %d\n", number)
return nil, fmt.Errorf("number must be positive and at least 1, provided: %d", number)
}
log.Infof("KMS store: %v", kms.remoteKMSMapping)
remoteKMS, err := kms.GetRemoteKMS(receivingCKMSID.String())
if err != nil {
log.Error(err)
return nil, err
}
platformKey, err := kms.GetSpecificPlatformKey(receivingCKMSID.String(), pathID)
if err != nil {
log.Error(err)
return nil, err
}
ksaKeysToSendToRemoteKMS := make([]*pbIC.Key, number)
ksaKeysToReturn := make([]crypto.KSAKey, number)
cryptoAlgo := crypto.NewAES()
for i := int64(0); i < number; i++ {
remoteKSAKey, localKSAKey, err := generateNewKSAKey(cryptoAlgo, platformKey.Value)
if err != nil {
log.Error(err)
return nil, err
}
ksaKeysToReturn[i] = *localKSAKey
ksaKeysToSendToRemoteKMS[i] = remoteKSAKey
}
remoteKMSAdrress := fmt.Sprintf("%s:%d", remoteKMS.Address, remoteKMS.Port)
err = kms.sendKSAKeysToPlatformKmsPeer(remoteKMSAdrress, platformKey.Id.String(), requestID, ksaKeysToSendToRemoteKMS)
if err != nil {
log.Error(err)
return nil, err
}
return ksaKeysToReturn, nil
}
func (kms *KMS) GetID() uuid.UUID {
return kms.kmsUUID
}