Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • danet/quant
1 result
Select Git revision
Show changes
Commits on Source (2)
Showing
with 660 additions and 323 deletions
......@@ -13,7 +13,6 @@ variables:
GOLANG_MINOR_VERSION: "${GOLANG_VERSION}.0"
DOCKER_TLS_CERTDIR: "/certs"
# Build stage
.build: &build
......@@ -137,7 +136,6 @@ build-etsi14module-latest:
- docker buildx build --push -t "$IMAGE_NAME:$TAG" -f etsi14module/Dockerfile --build-arg "GITLAB_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/" --build-arg GITLAB_LOGIN=${GITLAB_LOGIN} --build-arg GITLAB_TOKEN=${GITLAB_TOKEN} --build-arg GOLANG_VERSION=${GOLANG_VERSION} .
<<: *build-latest
# Analyze stage
lint:
stage: analyze
......@@ -175,8 +173,24 @@ unit-tests:
path: coverage.xml
needs: []
integration-test-aes:
tags:
- shell
needs: []
variables:
DEPENDENCY_PROXY: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker login -u $CI_DEPENDENCY_PROXY_USER -p $CI_DEPENDENCY_PROXY_PASSWORD $CI_DEPENDENCY_PROXY_SERVER
- ./scripts/install_go_as_user.sh $GOLANG_MINOR_VERSION
- export PATH="$HOME/go/go/bin:$PATH"
- export GOROOT="$HOME/go/go"
- export GOPATH=$HOME/go_projects
- go version
script:
- make integration-test-aes
integration-test:
integration-test-otp:
tags:
- shell
needs: []
......@@ -191,4 +205,4 @@ integration-test:
- export GOPATH=$HOME/go_projects
- go version
script:
- make integration-test
- make integration-test-otp
......@@ -15,7 +15,7 @@
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "compose-debug-up",
"preLaunchTask": "compose-debug-up"
},
{
"name": "kms02-debug",
......@@ -28,7 +28,7 @@
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "compose-debug-up",
"preLaunchTask": "compose-debug-up"
},
{
"name": "kms03-debug",
......@@ -41,7 +41,7 @@
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "compose-debug-up",
"preLaunchTask": "compose-debug-up"
},
{
"name": "kms04-debug",
......@@ -54,10 +54,10 @@
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "compose-debug-up",
"preLaunchTask": "compose-debug-up"
},
{
"name": "integration-test-kms01-debug",
"name": "integration-test-aes-kms01-debug",
"type": "go",
"request": "attach",
"mode": "remote",
......@@ -67,10 +67,10 @@
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "integration-test-debug-kms-up",
"preLaunchTask": "integration-test-aes-debug-kms-up"
},
{
"name": "integration-test-kms02-debug",
"name": "integration-test-aes-kms02-debug",
"type": "go",
"request": "attach",
"mode": "remote",
......@@ -80,7 +80,33 @@
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "integration-test-debug-kms-up",
"preLaunchTask": "integration-test-aes-debug-kms-up"
},
{
"name": "integration-test-otp-kms01-debug",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "",
"port": 4401,
"host": "127.0.0.1",
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "integration-test-otp-debug-kms-up"
},
{
"name": "integration-test-otp-kms02-debug",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "",
"port": 4402,
"host": "127.0.0.1",
"showLog": true,
"trace": "log",
"logOutput": "rpc",
"preLaunchTask": "integration-test-otp-debug-kms-up"
},
{
"name": "Launch currently open test",
......@@ -88,7 +114,7 @@
"request": "launch",
"mode": "auto",
"program": "${file}"
},
}
],
"compounds": [
{
......
......@@ -2,14 +2,19 @@
"version": "2.0.0",
"tasks": [
{
"label": "integration-test-debug-kms-up",
"command": "make integration-test-debug-compose-up",
"type": "shell",
"label": "integration-test-aes-debug-kms-up",
"command": "make integration-test-aes-debug-compose-up",
"type": "shell"
},
{
"label": "integration-test-otp-debug-kms-up",
"command": "make integration-test-otp-debug-compose-up",
"type": "shell"
},
{
"label": "compose-debug-up",
"command": "make compose-debug-up",
"type": "shell",
"type": "shell"
}
]
}
......@@ -101,7 +101,9 @@ compose-debug-up: generate-gokms-certs build-images install-gosdnc
compose-debug-down:
docker compose -f docker-compose.yml -f docker-compose.override.debug.yml down
integration-test: install-gosdnc generate-integration-test-certs build-images
integration-test: integration-test-aes integration-test-otp
integration-test-aes: install-gosdnc generate-integration-test-certs build-images
docker compose -f integration-tests/docker-compose.yml down
docker compose -f integration-tests/docker-compose.yml up -d
echo "Will sleep for the quantumlayers to get ready"
......@@ -109,13 +111,28 @@ integration-test: install-gosdnc generate-integration-test-certs build-images
go test -p 1 -count=1 -v ./integration-tests/code/*
docker compose -f integration-tests/docker-compose.yml down
integration-test-debug-compose-up: generate-integration-test-certs build-images install-gosdnc
integration-test-aes-debug-compose-up: generate-integration-test-certs build-images install-gosdnc
docker compose -f integration-tests/docker-compose.yml -f integration-tests/docker-compose.override.debug.yml down
docker compose -f integration-tests/docker-compose.yml -f integration-tests/docker-compose.override.debug.yml up -d
integration-test-debug-compose-down:
integration-test-aes-debug-compose-down:
docker compose -f integration-tests/docker-compose.yml -f integration-tests/docker-compose.override.debug.yml down
integration-test-otp: install-gosdnc generate-integration-test-certs build-images
docker compose -f integration-tests/docker-compose-otp.yml down
docker compose -f integration-tests/docker-compose-otp.yml up -d
echo "Will sleep for the quantumlayers to get ready"
sleep 45
go test -p 1 -count=1 -v ./integration-tests/code/*
docker compose -f integration-tests/docker-compose-otp.yml down
integration-test-otp-debug-compose-up: generate-integration-test-certs build-images install-gosdnc
docker compose -f integration-tests/docker-compose-otp.yml -f integration-tests/docker-compose.override.debug.yml down
docker compose -f integration-tests/docker-compose-otp.yml -f integration-tests/docker-compose.override.debug.yml up -d
integration-test-otp-debug-compose-down:
docker compose -f integration-tests/docker-compose-otp.yml -f integration-tests/docker-compose.override.debug.yml down
generate-certs: generate-root-ca generate-gokms-certs generate-integration-test-certs
generate-root-ca: pre
......
......@@ -29,4 +29,4 @@ $GOSDNC_PATH mne create --address 172.100.20.12:7030 --name kms03 --password adm
$GOSDNC_PATH mne create --address 172.100.20.13:7030 --name kms04 --password admin --plugin-id $KMS_PLUGIN --username admin --uuid 968fd594-b0e7-41f0-ba4b-de259047a933
## Add additional user for an app
$GOSDNC_PATH userCreate --u app --p TestApp --r app
$GOSDNC_PATH user create --u app --p TestApp --r app
......@@ -4,111 +4,118 @@ package kmsintercom;
// should be renamed to InterCom or KMSInterCom
service KmsTalker {
rpc InterComCapabilities (InterComCapabilitiesRequest) returns (InterComCapabilitiesReply) {}
rpc SyncQkdBulk(SyncQkdBulkRequest) returns (SyncQkdBulkResponse) {}
rpc SyncKeyIdsForBulk(SyncKeyIdsForBulkRequest) returns (SyncKeyIdsForBulkResponse) {}
rpc InterComTransportKeyNegotiation(InterComTransportKeyNegotiationRequest) returns (InterComTransportKeyNegotiationResponse) {}
rpc KeyForwarding(KeyForwardingRequest) returns (KeyForwardingResponse) {}
rpc AckKeyForwarding(AckKeyForwardingRequest) returns (AckKeyForwardingResponse) {}
// KeyIDNotification is used for ETSI GS QKD 014
rpc KeyIdNotification(KeyIdNotificationRequest) returns (KeyIdNotificationResponse) {}
rpc KeyDelivery(KeyDeliveryRequest) returns (KeyDeliveryResponse) {}
rpc InterComCapabilities(InterComCapabilitiesRequest) returns (InterComCapabilitiesReply) {}
rpc SyncQkdBulk(SyncQkdBulkRequest) returns (SyncQkdBulkResponse) {}
rpc SyncKeyIdsForBulk(SyncKeyIdsForBulkRequest) returns (SyncKeyIdsForBulkResponse) {}
rpc InterComTransportKeyNegotiation(InterComTransportKeyNegotiationRequest) returns (InterComTransportKeyNegotiationResponse) {}
rpc KeyForwarding(KeyForwardingRequest) returns (KeyForwardingResponse) {}
rpc AckKeyForwarding(AckKeyForwardingRequest) returns (AckKeyForwardingResponse) {}
// KeyIDNotification is used for ETSI GS QKD 014
rpc KeyIdNotification(KeyIdNotificationRequest) returns (KeyIdNotificationResponse) {}
rpc KeyDelivery(KeyDeliveryRequest) returns (KeyDeliveryResponse) {}
}
// Capabilities
// The request message containing the requesting kms' name.
message InterComCapabilitiesRequest {
int64 timestamp = 1;
string kmsId = 2;
bool resetKeyStore = 3;
int64 timestamp = 1;
string kmsId = 2;
bool resetKeyStore = 3;
}
// The response message containing the replying kms' name.
message InterComCapabilitiesReply {
int64 timestamp = 1;
string peerKmsName= 2;
int64 timestamp = 1;
string peerKmsName = 2;
}
message SyncQkdBulkRequest {
int64 timestamp = 1;
string kmsId = 2;
repeated int64 bulkId = 3;
//string bulkHash = 4;
int64 timestamp = 1;
string kmsId = 2;
repeated int64 bulkId = 3;
//string bulkHash = 4;
}
message SyncKeyIdsForBulkRequest {
int64 timestamp = 1;
string kmsId = 2;
int64 bulkId = 3;
repeated string keyId = 4;
int64 timestamp = 1;
string kmsId = 2;
int64 bulkId = 3;
repeated string keyId = 4;
}
message SyncKeyIdsForBulkResponse {
int64 timestamp = 1;
int64 timestamp = 1;
}
message SyncQkdBulkResponse {
int64 timestamp = 1;
int64 bulkId = 2;
int64 timestamp = 1;
int64 bulkId = 2;
}
// Beim aushandeln
message InterComTransportKeyNegotiationRequest {
int64 timestamp = 1;
string pathID = 2;
string keyToUse = 3;
int64 timestamp = 1;
string pathID = 2;
string keyToUse = 3;
}
message InterComTransportKeyNegotiationResponse {
int64 timestamp = 1;
int64 timestamp = 1;
}
message KeyForwardingRequest {
int64 timestamp = 1;
string pathId = 2;
string processId = 3;
Key key = 4;
int64 timestamp = 1;
string pathId = 2;
string processId = 3;
CryptoAlgorithm cryptoAlgorithm = 4;
Key key = 5;
}
message KeyForwardingResponse {
int64 timestamp = 1;
int64 timestamp = 1;
}
message AckKeyForwardingRequest {
int64 timestamp = 1;
string pathId = 2;
string processId = 3;
string KeyId = 4;
int64 timestamp = 1;
string pathId = 2;
string processId = 3;
string KeyId = 4;
}
message AckKeyForwardingResponse {
int64 timestamp = 1;
int64 timestamp = 1;
}
message KeyIdNotificationRequest {
int64 timestamp = 1;
string kmsId = 2;
repeated string keyIds = 3;
int64 timestamp = 1;
string kmsId = 2;
repeated string keyIds = 3;
}
message KeyIdNotificationResponse {
int64 timestamp = 1;
int64 timestamp = 1;
}
message KeyDeliveryRequest {
int64 timestamp = 1;
string kmsId = 3;
string keyId = 4;
string requestId = 5;
repeated Key keys = 6;
int64 timestamp = 1;
string kmsId = 3;
string keyId = 4;
string requestId = 5;
CryptoAlgorithm cryptoAlgorithm = 6;
repeated Key keys = 7;
}
message KeyDeliveryResponse {
int64 timestamp = 1;
int64 timestamp = 1;
}
message Key {
string id = 1;
string nonce = 2;
string key = 3;
string id = 1;
string nonce = 2;
string key = 3;
}
enum CryptoAlgorithm {
AES_256_GCM = 0;
OTP = 1;
}
......@@ -13,6 +13,7 @@ type Config struct {
QuantumAddr string `yaml:"QuantumAddr"`
AKMS AKMS `yaml:"AKMS"`
GnmiBindAddress string `yaml:"GnmiBindAddress"`
KSACryptoAlgorithm string `yaml:"KSACryptoAlgorithm"`
KmsTLS TLSConfig `yaml:"KmsTLS"`
Peers []Peer `yaml:"Peers"`
GnmiTLS TLSConfig `yaml:"GnmiTLS"`
......@@ -31,6 +32,7 @@ type AKMS struct {
type Peer struct {
PeerId string `yaml:"PeerId"`
PeerInterComAddr string `yaml:"PeerInterComAddr"`
CryptoAlgorithm string `yaml:"CryptoAlgorithm"`
Type string `yaml:"Type"`
QuantumModule QuantumModule `yaml:"QuantumModule"`
}
......
package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
)
// AES is an implementation of the CryptoAlgorithm interface.
// AES provides the methods required for performing symmetric key encryption
// and decryption using the AES algorithm.
//
// For this the aes package from the Go standard library is used.
type AES struct {
name string
}
// NewAES creates a new instance of a AES struct.
func NewAES(name string) *AES {
return &AES{
name: name,
}
}
// Encrypt encrypts the plaintext using a provided key.
// The key should have a length of 16, 24 or 32 bytes to select AES-128,
// AES-192 or AES-256.
// The method returns the nonce, the encrypted output and an error if something
// went wrong.
func (a *AES) Encrypt(plaintext []byte, key []byte) ([]byte, []byte, error) {
// create a new cipher block from the key
c, err := aes.NewCipher(key)
if err != nil {
return nil, nil, err
}
// create a new block cipher wrapped in GCM with default nonce (12
// bytes) and tag size (16 bytes).
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, nil, err
}
// generate a random nonce of nonce size (12 bytes)
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return nil, nil, err
}
// Encrypt the plaintext using AES-GCM
// Destination is set to nil, therefore seal only contains the
// ciphertext with the tag appended.
seal := gcm.Seal(nil, nonce, plaintext, nil)
return nonce, seal, nil
}
// Decrypt decrypts the ciphertext using the provided key and nonce.
// The key should have a length of 16, 24 or 32 bytes to select AES-128,
// AES-192 or AES-256.
// The method returns the decrypted input.
func (a *AES) Decrypt(nonce, ciphertext []byte, key []byte) ([]byte, error) {
// create a new cipher block from the key
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// create a new block cipher wrapped in GCM with default nonce (12
// bytes) and tag size (16 bytes).
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
// Decrypt the ciphertext using AES-GCM
return gcm.Open(nil, nonce, ciphertext, nil)
}
func (a *AES) Name() string {
return a.name
}
......@@ -49,7 +49,7 @@ func TestCrypto_AES_Encrypt(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()
aes := NewAES()
aes := NewAES("AES-256-GCM")
nonce, cipherText, err := aes.Encrypt(test.plaintext, test.key)
if test.error {
assert.Error(t, err)
......@@ -175,7 +175,7 @@ func TestCrypto_AES_Decrypt(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()
aes := NewAES()
aes := NewAES("AES-256-GCM")
plainText, err := aes.Decrypt(test.nonce, test.cipherText, test.key)
if test.error {
assert.Error(t, err)
......@@ -191,7 +191,7 @@ func TestCrypto_AES_EncryptAndDecryptPlaintext(t *testing.T) {
secret := []byte("this is a secret")
key := []byte{0xfe, 0x34, 0x64, 0x9e, 0xdf, 0x1a, 0xf1, 0xc, 0xb7, 0x28, 0xee, 0x98, 0xe7, 0x7, 0x40, 0x8f, 0x3b, 0x8, 0x9a, 0xad, 0x45, 0x7a, 0x21, 0xe8, 0x84, 0x79, 0xc5, 0x1b, 0x25, 0x13, 0xa2, 0x3c}
aes := NewAES()
aes := NewAES("AES-256-GCM")
// encrypt the secret with encrypt method
nonce, encryptedSecret, err := aes.Encrypt(secret, key)
......
package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
)
// CryptoAlgorithm is an interface that provides the methods required for
// encryption and decryption of data.
// Currently only AES is supported, but this could be extended to support other
......@@ -14,71 +7,5 @@ import (
type CryptoAlgorithm interface {
Encrypt(plaintext []byte, key []byte) ([]byte, []byte, error)
Decrypt(nonce, ciphertext []byte, key []byte) ([]byte, error)
}
// AES is an implementation of the CryptoAlgorithm interface.
// AES provides the methods required for performing symmetric key encryption
// and decryption using the AES algorithm.
//
// For this the aes package from the Go standard library is used.
type AES struct{}
// NewAES creates a new instance of a AES struct.
func NewAES() *AES {
return &AES{}
}
// Encrypt encrypts the plaintext using a provided key.
// The key should have a length of 16, 24 or 32 bytes to select AES-128,
// AES-192 or AES-256.
// The method returns the nonce, the encrypted output and an error if something
// went wrong.
func (a *AES) Encrypt(plaintext []byte, key []byte) ([]byte, []byte, error) {
// create a new cipher block from the key
c, err := aes.NewCipher(key)
if err != nil {
return nil, nil, err
}
// create a new block cipher wrapped in GCM with default nonce (12
// bytes) and tag size (16 bytes).
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, nil, err
}
// generate a random nonce of nonce size (12 bytes)
nonce := make([]byte, gcm.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return nil, nil, err
}
// Encrypt the plaintext using AES-GCM
// Destination is set to nil, therefore seal only contains the
// ciphertext with the tag appended.
seal := gcm.Seal(nil, nonce, plaintext, nil)
return nonce, seal, nil
}
// Decrypt decrypts the ciphertext using the provided key and nonce.
// The key should have a length of 16, 24 or 32 bytes to select AES-128,
// AES-192 or AES-256.
// The method returns the decrypted input.
func (a *AES) Decrypt(nonce, ciphertext []byte, key []byte) ([]byte, error) {
// create a new cipher block from the key
c, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// create a new block cipher wrapped in GCM with default nonce (12
// bytes) and tag size (16 bytes).
gcm, err := cipher.NewGCM(c)
if err != nil {
return nil, err
}
// Decrypt the ciphertext using AES-GCM
return gcm.Open(nil, nonce, ciphertext, nil)
Name() string
}
package crypto
import "fmt"
type OTP struct {
name string
}
func NewOTP(name string) *OTP {
return &OTP{
name: name,
}
}
func (o *OTP) Encrypt(plaintext []byte, key []byte) ([]byte, []byte, error) {
plainTextLen := len(plaintext)
keyLen := len(key)
if plainTextLen != keyLen {
return nil, nil, fmt.Errorf("For OTP the length of plaintext and key must not differ. Length of plaintext: %d, length of key: %d", plainTextLen, keyLen)
}
ciphertext := make([]byte, plainTextLen)
for i := range ciphertext {
ciphertext[i] = plaintext[i] ^ key[i]
}
return nil, ciphertext, nil
}
func (o *OTP) Decrypt(nonce, ciphertext []byte, key []byte) ([]byte, error) {
cipherTextLen := len(ciphertext)
keyLen := len(key)
if cipherTextLen != keyLen {
return nil, fmt.Errorf("For OTP the length of ciphertext and key must not differ. Length of ciphertext: %d, length of key: %d", cipherTextLen, keyLen)
}
plaintext := make([]byte, cipherTextLen)
for i := range plaintext {
plaintext[i] = ciphertext[i] ^ key[i]
}
return plaintext, nil
}
func (o *OTP) Name() string {
return o.name
}
package crypto
import (
"crypto/rand"
"testing"
"github.com/stretchr/testify/assert"
)
// TestCrypto_OTP tests if a byte array is XOR'ed the proper way.
func TestCrypto_OTP_XOR(t *testing.T) {
testByteArray := []byte{0xF}
testByteArray2 := []byte{0xF0}
resultByteArray := make([]byte, len(testByteArray))
for i := range testByteArray {
resultByteArray[i] = testByteArray[i] ^ testByteArray2[i]
}
assert.Equal(t, resultByteArray, []byte{0xFF})
}
func TestCrypto_OTP_EncryptAndDecryptPlaintext(t *testing.T) {
secret := []byte("this is a secret")
key := make([]byte, len(secret))
_, err := rand.Read(key)
assert.NoError(t, err)
otp := NewOTP("OTP")
// encrypt the secret with encrypt method
_, encryptedSecret, err := otp.Encrypt(secret, key)
assert.NoError(t, err)
// decrypt the encryptedSecret with decrypt method
decryptedSecret, err := otp.Decrypt(nil, encryptedSecret, key)
assert.NoError(t, err)
assert.Equal(t, secret, decryptedSecret)
}
......@@ -3,6 +3,7 @@ package crypto
import (
"crypto/rand"
"encoding/base64"
"fmt"
"github.com/google/uuid"
)
......@@ -46,3 +47,14 @@ func Random256BitKey() (*Key, error) {
KeyAsBase64: keyAsBase64String,
}, nil
}
func GetCryptoAlgorithmByName(cryptoAlgorithmName string) (CryptoAlgorithm, error) {
switch cryptoAlgorithmName {
case "AES_256_GCM":
return NewAES(cryptoAlgorithmName), nil
case "OTP":
return NewOTP(cryptoAlgorithmName), nil
default:
return nil, fmt.Errorf("The provided crypto algorithm name: %s is not supported.", cryptoAlgorithmName)
}
}
......@@ -85,8 +85,9 @@ type KMS struct {
ckmsAkmsClient *akmsInterfaceClient.CkmsAkmsClient
ckmsAkmsServer *akmsInterfaceServer.AKMSReceiverServer
// ETSI14 Server things
etsi14Server *etsi14Server.ETSI14RESTService
keyStoreChannel chan []crypto.KSAKey
etsi14Server *etsi14Server.ETSI14RESTService
keyStoreChannel chan []crypto.KSAKey
ksaCryptoAlgorithm crypto.CryptoAlgorithm
}
// Will keep information about the quantum elements that this EKMS is talking to
......@@ -149,6 +150,13 @@ func NewKMS(kmsUUID uuid.UUID, logOutput io.Writer, logLevel log.Level, logInJso
createdKMS.supportedKeyLengths[BitKeyLen256] = true
// initialize KSA crypto algorithm
createdKMS.ksaCryptoAlgorithm, err = crypto.GetCryptoAlgorithmByName(config.KSACryptoAlgorithm)
if err != nil {
log.Info("No crypto algorithm provided, or not supported -> using default.")
createdKMS.ksaCryptoAlgorithm = crypto.NewAES("AES_256_GCM")
}
// start the inter communication gRPC server
go createdKMS.startGRPC()
......@@ -235,7 +243,14 @@ func (kms *KMS) initializePeers(config *config.Config) error {
client.KmsTalkerClient = pbIC.NewKmsTalkerClient(newPeerConn)
}
_, err = kms.AddPeer(peer.PeerId, peer.PeerInterComAddr, qm, client)
cryptoAlgorithm, err := crypto.GetCryptoAlgorithmByName(peer.CryptoAlgorithm)
if err != nil {
log.Info("No crypto algorithm provided, or not supported -> using default.")
cryptoAlgorithm = crypto.NewAES("AES_256_GCM")
}
log.Infof("Using %s as crypto algorithm", cryptoAlgorithm.Name())
_, err = kms.AddPeer(peer.PeerId, peer.PeerInterComAddr, qm, client, cryptoAlgorithm)
if err != nil {
log.Fatalf("Failed to create a peer: %s", err)
return nil
......@@ -300,14 +315,14 @@ func (kms *KMS) AddQuantumElement(qm peers.QuantumModule) error {
return nil
}
func (kms *KMS) AddPeer(peerKmsId string, kmsPeerSocket string, servingQLE peers.QuantumModule, client *peers.GRPCClient) (*peers.KmsPeer, error) {
func (kms *KMS) AddPeer(peerKmsId string, kmsPeerSocket string, servingQLE peers.QuantumModule, client *peers.GRPCClient, cryptoAlgorithm crypto.CryptoAlgorithm) (*peers.KmsPeer, error) {
// check if peer exists
_, 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)
peer, err := peers.NewKmsPeer(peerKmsId, servingQLE, cryptoAlgorithm, kmsPeerSocket, client, kms.eventBus, kms.gRPCTimeout)
if err != nil {
return nil, err
}
......@@ -489,9 +504,8 @@ func (kms *KMS) GenerateAndSendKSAKey(remoteKMSId string, pathId uuid.UUID, requ
ksaKeys := make([]*pbIC.Key, number)
akmsKSAKeys := make([]crypto.KSAKey, number)
cryptoAlgo := crypto.NewAES()
for i := 0; i < number; i++ {
ksaKey, akmsKSAKey, err := generateNewKSAKey(cryptoAlgo, platformKey.Value)
ksaKey, akmsKSAKey, err := generateNewKSAKey(kms.ksaCryptoAlgorithm, platformKey.Value)
if err != nil {
log.Error(err)
return err
......@@ -653,16 +667,23 @@ func (kms *KMS) sendKSAKeysToPlatformKmsPeer(kmsPeerAddress, platformKeyID, requ
}
remoteClient := pbIC.NewKmsTalkerClient(remoteConn)
cryptoAlgorithmEnum, ok := pbIC.CryptoAlgorithm_value[kms.ksaCryptoAlgorithm.Name()]
if !ok {
log.Infof("Crypto algorithm provided: %s is not supported -> using default.", kms.ksaCryptoAlgorithm.Name())
return fmt.Errorf("Crypto algorithm provided: %s is not supported -> using default.", kms.ksaCryptoAlgorithm.Name())
}
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,
KeyId: platformKeyID,
RequestId: requestID,
CryptoAlgorithm: pbIC.CryptoAlgorithm(cryptoAlgorithmEnum),
KmsId: kms.kmsUUID.String(),
Keys: ksaKeys,
})
if err != nil {
log.Error(err)
......@@ -724,9 +745,8 @@ func (kms *KMS) generateAndReturnKsaKey(receivingCKMSID, pathID uuid.UUID, numbe
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)
remoteKSAKey, localKSAKey, err := generateNewKSAKey(kms.ksaCryptoAlgorithm, platformKey.Value)
if err != nil {
log.Error(err)
return nil, err
......
......@@ -244,7 +244,12 @@ func (s *kmsTalkerServer) KeyForwarding(ctx context.Context, in *pb.KeyForwardin
return nil, status.Errorf(codes.InvalidArgument, "")
}
decryptedKey, err := s.getDecryptedKey(decryptKey.Key, route.Previous.CryptoAlgo(), in.GetKey())
cryptoAlgorithm, err := crypto.GetCryptoAlgorithmByName(in.GetCryptoAlgorithm().String())
if err != nil {
return nil, status.Errorf(codes.Internal, "%s", err)
}
decryptedKey, err := s.getDecryptedKey(decryptKey.Key, cryptoAlgorithm, in.GetKey())
if err != nil {
return nil, status.Errorf(codes.Internal, "%s", err)
}
......@@ -308,8 +313,11 @@ func (s *kmsTalkerServer) KeyDelivery(ctx context.Context, in *pb.KeyDeliveryReq
akmsKSAKeys := make([]crypto.KSAKey, len(in.Keys))
for i, key := range in.Keys {
// decrypt the key
cryptoAlgo := crypto.NewAES()
decryptedKSAKey, err := s.getDecryptedKey(platformKey.Value, cryptoAlgo, key)
cryptoAlgorithm, err := crypto.GetCryptoAlgorithmByName(in.GetCryptoAlgorithm().String())
if err != nil {
return nil, status.Errorf(codes.Internal, "%s", err)
}
decryptedKSAKey, err := s.getDecryptedKey(platformKey.Value, cryptoAlgorithm, key)
if err != nil {
return nil, status.Errorf(codes.Internal, "%s", err)
}
......
......@@ -44,7 +44,7 @@ type KmsPeer struct {
gRPCTimeout time.Duration
tcpSocket *net.TCPAddr // the IP address and TCP port (aka socket) of the kms peer
TcpSocketStr string // string rep. of tcpSocket
et crypto.CryptoAlgorithm
cryptoAlgorithm crypto.CryptoAlgorithm
// NOTE: currently not used, could be of usage later on
// name string // the name of the kms peer
quit chan bool // cancel the peer goroutine
......@@ -52,7 +52,7 @@ type KmsPeer struct {
}
// TODO: check intercomaddr -> remove?
func NewKmsPeer(peerKmsId string, quantummodule QuantumModule, tcpSocketStr string, client *GRPCClient, eventBus *event.EventBus, gRPCTimeout time.Duration) (*KmsPeer, error) {
func NewKmsPeer(peerKmsId string, quantummodule QuantumModule, cryptoAlgorithm crypto.CryptoAlgorithm, tcpSocketStr string, client *GRPCClient, eventBus *event.EventBus, gRPCTimeout time.Duration) (*KmsPeer, error) {
var peerKmsIdUUID uuid.UUID
if peerKmsId == "" {
peerKmsIdUUID = uuid.New()
......@@ -87,7 +87,7 @@ func NewKmsPeer(peerKmsId string, quantummodule QuantumModule, tcpSocketStr stri
servingQuantumModul: quantummodule,
tcpSocket: tcpSocket,
TcpSocketStr: tcpSocketStr,
et: crypto.NewAES(),
cryptoAlgorithm: cryptoAlgorithm,
quit: make(chan bool),
eventBus: eventBus,
gRPCTimeout: gRPCTimeout,
......@@ -113,7 +113,7 @@ func (kp *KmsPeer) QuantumModule() QuantumModule {
}
func (kp *KmsPeer) CryptoAlgo() crypto.CryptoAlgorithm {
return kp.et
return kp.cryptoAlgorithm
}
func (kp *KmsPeer) SyncBulkKeys() error {
......@@ -172,7 +172,7 @@ func (kp *KmsPeer) SendPayload(payload *crypto.Key, pathId, processId uuid.UUID)
kp.servingQuantumModul.KeyStore().DeleteKey(key.KeyID)
nonce, encryptedPayload, err := kp.et.Encrypt(payload.Key, key.Key)
nonce, encryptedPayload, err := kp.cryptoAlgorithm.Encrypt(payload.Key, key.Key)
if err != nil {
return err
}
......@@ -182,12 +182,19 @@ func (kp *KmsPeer) SendPayload(payload *crypto.Key, pathId, processId uuid.UUID)
log.Infof("Sent encrypted Payload: %s with nonce: %s", encryptedPayloadAsString, nonceAsString)
cryptoAlgorithmEnum, ok := pbIC.CryptoAlgorithm_value[kp.cryptoAlgorithm.Name()]
if !ok {
log.Infof("Crypto algorithm provided: %s is not supported -> using default.", kp.cryptoAlgorithm.Name())
return fmt.Errorf("Crypto algorithm provided: %s is not supported -> using default.", kp.cryptoAlgorithm.Name())
}
ctx2, cancel2 := context.WithTimeout(context.Background(), kp.gRPCTimeout)
defer cancel2()
_, err = kp.peerClient.KeyForwarding(ctx2, &pbIC.KeyForwardingRequest{
Timestamp: time.Now().Unix(),
PathId: pathId.String(),
ProcessId: processId.String(),
Timestamp: time.Now().Unix(),
PathId: pathId.String(),
ProcessId: processId.String(),
CryptoAlgorithm: pbIC.CryptoAlgorithm(cryptoAlgorithmEnum),
Key: &pbIC.Key{
Id: payload.ID.String(),
Nonce: nonceAsString,
......
......@@ -16,6 +16,7 @@ AKMS:
CertFile: "config/ssl/kms/kms1-selfsigned.crt"
KeyFile: "config/ssl/kms/kms1-selfsigned.key"
GRPCTimeoutInSeconds: 600
KSACryptoAlgorithm: AES_256_GCM
KmsTLS:
Active: false
CAFile: "config/ssl/ca.crt"
......@@ -25,6 +26,7 @@ Peers:
# peer to kms02
- PeerId: "5e41c291-6121-4335-84f6-41e04b8bdaa2"
PeerInterComAddr: kms02:50910
CryptoAlgorithm: AES_256_GCM
Type: danet
# quantum module of type emulated at the given address
QuantumModule:
......
Id: "0ff33c82-7fe1-482b-a0ca-67565806ee4b"
Name: kms01
InterComAddr: 0.0.0.0:50910
QuantumAddr: 0.0.0.0:50911
AKMS:
RemoteAddress: "https://akms-simulator_1:4444/api/v1/keys/push_ksa_key"
ServerPort: "9696"
ClientTLS:
Active: true
CAFile: "config/ssl/ca.crt"
CertFile: "config/ssl/kms/kms1-selfsigned.crt"
KeyFile: "config/ssl/kms/kms1-selfsigned.key"
ServerTLS:
Active: true
CAFile: "config/ssl/ca.crt"
CertFile: "config/ssl/kms/kms1-selfsigned.crt"
KeyFile: "config/ssl/kms/kms1-selfsigned.key"
GRPCTimeoutInSeconds: 600
KSACryptoAlgorithm: OTP
KmsTLS:
Active: false
CAFile: "config/ssl/ca.crt"
CertFile: "config/ssl/kms/kms1-selfsigned.crt"
KeyFile: "config/ssl/kms/kms1-selfsigned.key"
Peers:
# peer to kms02
- PeerId: "5e41c291-6121-4335-84f6-41e04b8bdaa2"
PeerInterComAddr: kms02:50910
CryptoAlgorithm: OTP
Type: danet
# quantum module of type emulated at the given address
QuantumModule:
Type: emulated
Hostname: quantumlayer_1
ETSI14Server:
Address: ":1414"
RemoteCKMSID: "5e41c291-6121-4335-84f6-41e04b8bdaa2"
......@@ -16,6 +16,7 @@ AKMS:
CertFile: "config/ssl/kms/kms2-selfsigned.crt"
KeyFile: "config/ssl/kms/kms2-selfsigned.key"
GRPCTimeoutInSeconds: 600
KSACryptoAlgorithm: AES_256_GCM
KmsTLS:
Active: false
CAFile: "config/ssl/ca.crt"
......@@ -25,6 +26,7 @@ Peers:
# peer to kms01
- PeerId: "0ff33c82-7fe1-482b-a0ca-67565806ee4b"
PeerInterComAddr: kms01:50910
CryptoAlgorithm: AES_256_GCM
Type: danet
# quantum module of type emulated at the given address
QuantumModule:
......