mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 23:19:39 -05:00
Add aTLS endpoint to KMS (#236)
* Move file watcher and validator to internal * Add aTLS endpoint to KMS for Kubernetes external requests * Update Go version in Dockerfiles * Move most KMS packages to internal Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
042f668d20
commit
f9a581f329
2
.github/workflows/build-kms-image.yml
vendored
2
.github/workflows/build-kms-image.yml
vendored
@ -30,5 +30,5 @@ jobs:
|
||||
with:
|
||||
name: kmsserver
|
||||
projectVersion: '0.0.0'
|
||||
dockerfile: Dockerfile.kms
|
||||
dockerfile: kms/server/Dockerfile
|
||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -43,7 +43,7 @@ jobs:
|
||||
"activation-service" )
|
||||
echo "microServiceDockerfile=activation/Dockerfile" >> $GITHUB_ENV ;;
|
||||
"kmsserver" )
|
||||
echo "microServiceDockerfile=Dockerfile.kms" >> $GITHUB_ENV ;;
|
||||
echo "microServiceDockerfile=kms/server/Dockerfile" >> $GITHUB_ENV ;;
|
||||
"verification-service" )
|
||||
echo "microServiceDockerfile=verify/Dockerfile" >> $GITHUB_ENV ;;
|
||||
esac
|
||||
|
@ -5,7 +5,7 @@ RUN dnf -y update && \
|
||||
dnf clean all
|
||||
|
||||
# Install Go
|
||||
ARG GO_VER=1.18
|
||||
ARG GO_VER=1.18.3
|
||||
RUN wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz && \
|
||||
tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && \
|
||||
rm go${GO_VER}.linux-amd64.tar.gz
|
||||
|
@ -5,7 +5,7 @@ RUN dnf -y update && \
|
||||
dnf clean all
|
||||
|
||||
# Install Go
|
||||
ARG GO_VER=1.18
|
||||
ARG GO_VER=1.18.3
|
||||
RUN wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz && \
|
||||
tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && \
|
||||
rm go${GO_VER}.linux-amd64.tar.gz
|
||||
@ -25,7 +25,7 @@ WORKDIR /constellation/activation
|
||||
ARG PROJECT_VERSION=0.0.0
|
||||
RUN CGO_ENABLED=0 go build -o activation-service -trimpath -buildvcs=false -ldflags "-s -w -buildid='' -X github.com/edgelesssys/constellation/internal/constants.VersionInfo=${PROJECT_VERSION}" ./cmd/
|
||||
|
||||
# We would like to use a scratch image here, but we require CA certificates to be installed for some operations.
|
||||
# We would like to use a scratch image here, but we require CA certificates to be installed for aTLS operations on GCP.
|
||||
FROM fedora@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 as release
|
||||
COPY --from=build /constellation/activation/activation-service /activation
|
||||
ENTRYPOINT [ "/activation" ]
|
||||
|
@ -9,13 +9,12 @@ import (
|
||||
"github.com/edgelesssys/constellation/activation/kubeadm"
|
||||
"github.com/edgelesssys/constellation/activation/kubernetesca"
|
||||
"github.com/edgelesssys/constellation/activation/server"
|
||||
"github.com/edgelesssys/constellation/activation/validator"
|
||||
"github.com/edgelesssys/constellation/activation/watcher"
|
||||
"github.com/edgelesssys/constellation/internal/atls"
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/internal/watcher"
|
||||
"github.com/spf13/afero"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
@ -34,7 +33,7 @@ func main() {
|
||||
|
||||
handler := file.NewHandler(afero.NewOsFs())
|
||||
|
||||
validator, err := validator.New(log.Named("validator"), *provider, handler)
|
||||
validator, err := watcher.NewValidator(log.Named("validator"), *provider, handler)
|
||||
if err != nil {
|
||||
flag.Usage()
|
||||
log.With(zap.Error(err)).Fatalf("Failed to create validator")
|
||||
@ -63,8 +62,8 @@ func main() {
|
||||
defer watcher.Close()
|
||||
|
||||
go func() {
|
||||
log.Infof("starting file watcher for measurements file %s", filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename))
|
||||
if err := watcher.Watch(filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename)); err != nil {
|
||||
log.Infof("starting file watcher for measurements file %s", filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename))
|
||||
if err := watcher.Watch(filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename)); err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to watch measurements file")
|
||||
}
|
||||
}()
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
||||
"github.com/edgelesssys/constellation/kms/kmsproto"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
||||
"github.com/edgelesssys/constellation/kms/kmsproto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
|
@ -124,7 +124,7 @@ func (s *Server) activateNode(ctx context.Context, diskUUID, nodeName string) (n
|
||||
log := s.log.With(zap.String("peerAddress", grpclog.PeerAddrFromContext(ctx)))
|
||||
log.Infof("Loading IDs")
|
||||
var id attestationtypes.ID
|
||||
if err := s.file.ReadJSON(filepath.Join(constants.ActivationBasePath, constants.ActivationIDFilename), &id); err != nil {
|
||||
if err := s.file.ReadJSON(filepath.Join(constants.ServiceBasePath, constants.IDFilename), &id); err != nil {
|
||||
log.With(zap.Error(err)).Errorf("Unable to load IDs")
|
||||
return nodeParameters{}, status.Errorf(codes.Internal, "unable to load IDs: %s", err)
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ func TestActivateNode(t *testing.T) {
|
||||
|
||||
file := file.NewHandler(afero.NewMemMapFs())
|
||||
if len(tc.id) > 0 {
|
||||
require.NoError(file.Write(filepath.Join(constants.ActivationBasePath, constants.ActivationIDFilename), tc.id, 0o644))
|
||||
require.NoError(file.Write(filepath.Join(constants.ServiceBasePath, constants.IDFilename), tc.id, 0o644))
|
||||
}
|
||||
api := New(
|
||||
logger.NewTest(t),
|
||||
@ -217,7 +217,7 @@ func TestActivateWorkerNode(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
file := file.NewHandler(afero.NewMemMapFs())
|
||||
require.NoError(file.Write(filepath.Join(constants.ActivationBasePath, constants.ActivationIDFilename), tc.id, 0o644))
|
||||
require.NoError(file.Write(filepath.Join(constants.ServiceBasePath, constants.IDFilename), tc.id, 0o644))
|
||||
|
||||
api := New(
|
||||
logger.NewTest(t),
|
||||
@ -322,7 +322,7 @@ func TestActivateControlPlaneNode(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
file := file.NewHandler(afero.NewMemMapFs())
|
||||
require.NoError(file.Write(filepath.Join(constants.ActivationBasePath, constants.ActivationIDFilename), tc.id, 0o644))
|
||||
require.NoError(file.Write(filepath.Join(constants.ServiceBasePath, constants.IDFilename), tc.id, 0o644))
|
||||
|
||||
api := New(
|
||||
logger.NewTest(t),
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/coordinator/state"
|
||||
"github.com/edgelesssys/constellation/internal/atls"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||
"github.com/edgelesssys/constellation/internal/oid"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/deploy/user"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
kmsSetup "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kmsSetup "github.com/edgelesssys/constellation/kms/setup"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||
"github.com/edgelesssys/constellation/internal/oid"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||
"github.com/edgelesssys/constellation/internal/oid"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||
"github.com/edgelesssys/constellation/internal/oid"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -138,7 +138,7 @@ func NewActivationDaemonset(csp, measurementsJSON, idJSON string) *activationDae
|
||||
Image: activationImage,
|
||||
Ports: []k8s.ContainerPort{
|
||||
{
|
||||
ContainerPort: 9090,
|
||||
ContainerPort: constants.ActivationServicePort,
|
||||
Name: "tcp",
|
||||
},
|
||||
},
|
||||
@ -148,13 +148,12 @@ func NewActivationDaemonset(csp, measurementsJSON, idJSON string) *activationDae
|
||||
Args: []string{
|
||||
fmt.Sprintf("--cloud-provider=%s", csp),
|
||||
fmt.Sprintf("--kms-endpoint=kms.kube-system:%d", constants.KMSPort),
|
||||
"--v=5",
|
||||
},
|
||||
VolumeMounts: []k8s.VolumeMount{
|
||||
{
|
||||
Name: "config",
|
||||
ReadOnly: true,
|
||||
MountPath: constants.ActivationBasePath,
|
||||
MountPath: constants.ServiceBasePath,
|
||||
},
|
||||
{
|
||||
Name: "kubeadm",
|
||||
|
@ -14,7 +14,8 @@ import (
|
||||
|
||||
type kmsDeployment struct {
|
||||
ServiceAccount k8s.ServiceAccount
|
||||
Service k8s.Service
|
||||
ServiceInternal k8s.Service
|
||||
ServiceExternal k8s.Service
|
||||
ClusterRole rbac.ClusterRole
|
||||
ClusterRoleBinding rbac.ClusterRoleBinding
|
||||
Deployment apps.Deployment
|
||||
@ -23,7 +24,7 @@ type kmsDeployment struct {
|
||||
}
|
||||
|
||||
// NewKMSDeployment creates a new *kmsDeployment to use as the key management system inside Constellation.
|
||||
func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
||||
func NewKMSDeployment(csp string, masterSecret []byte) *kmsDeployment {
|
||||
return &kmsDeployment{
|
||||
ServiceAccount: k8s.ServiceAccount{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
@ -35,7 +36,7 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
},
|
||||
Service: k8s.Service{
|
||||
ServiceInternal: k8s.Service{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Service",
|
||||
@ -59,6 +60,31 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
||||
},
|
||||
},
|
||||
},
|
||||
ServiceExternal: k8s.Service{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "kms-external",
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
Spec: k8s.ServiceSpec{
|
||||
Type: k8s.ServiceTypeNodePort,
|
||||
Ports: []k8s.ServicePort{
|
||||
{
|
||||
Name: "atls",
|
||||
Protocol: k8s.ProtocolTCP,
|
||||
Port: constants.KMSATLSPort,
|
||||
TargetPort: intstr.FromInt(constants.KMSATLSPort),
|
||||
NodePort: constants.KMSNodePort,
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"k8s-app": "kms",
|
||||
},
|
||||
},
|
||||
},
|
||||
ClusterRole: rbac.ClusterRole{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||
@ -161,14 +187,35 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
||||
},
|
||||
Volumes: []k8s.Volume{
|
||||
{
|
||||
Name: "mastersecret",
|
||||
Name: "config",
|
||||
VolumeSource: k8s.VolumeSource{
|
||||
Secret: &k8s.SecretVolumeSource{
|
||||
SecretName: constants.ConstellationMasterSecretStoreName,
|
||||
Items: []k8s.KeyToPath{
|
||||
Projected: &k8s.ProjectedVolumeSource{
|
||||
Sources: []k8s.VolumeProjection{
|
||||
{
|
||||
Key: constants.ConstellationMasterSecretKey,
|
||||
Path: "constellation-mastersecret.base64",
|
||||
ConfigMap: &k8s.ConfigMapProjection{
|
||||
LocalObjectReference: k8s.LocalObjectReference{
|
||||
Name: "activation-config",
|
||||
},
|
||||
Items: []k8s.KeyToPath{
|
||||
{
|
||||
Key: constants.MeasurementsFilename,
|
||||
Path: constants.MeasurementsFilename,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Secret: &k8s.SecretProjection{
|
||||
LocalObjectReference: k8s.LocalObjectReference{
|
||||
Name: constants.ConstellationMasterSecretStoreName,
|
||||
},
|
||||
Items: []k8s.KeyToPath{
|
||||
{
|
||||
Key: constants.ConstellationMasterSecretKey,
|
||||
Path: constants.MasterSecretFilename,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -181,14 +228,15 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
||||
Name: "kms",
|
||||
Image: kmsImage,
|
||||
Args: []string{
|
||||
fmt.Sprintf("--atls-port=%d", constants.KMSATLSPort),
|
||||
fmt.Sprintf("--port=%d", constants.KMSPort),
|
||||
"--v=5",
|
||||
fmt.Sprintf("--cloud-provider=%s", csp),
|
||||
},
|
||||
VolumeMounts: []k8s.VolumeMount{
|
||||
{
|
||||
Name: "mastersecret",
|
||||
Name: "config",
|
||||
ReadOnly: true,
|
||||
MountPath: "/constellation/",
|
||||
MountPath: constants.ServiceBasePath,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -12,7 +12,7 @@ func TestKMSMarshalUnmarshal(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
|
||||
kmsDepl := NewKMSDeployment(testMS)
|
||||
kmsDepl := NewKMSDeployment("test", testMS)
|
||||
data, err := kmsDepl.Marshal()
|
||||
require.NoError(err)
|
||||
|
||||
|
@ -142,7 +142,7 @@ func (k *KubeWrapper) InitCluster(
|
||||
return fmt.Errorf("setting up pod network: %w", err)
|
||||
}
|
||||
|
||||
kms := resources.NewKMSDeployment(masterSecret)
|
||||
kms := resources.NewKMSDeployment(k.cloudProvider, masterSecret)
|
||||
if err = k.clusterUtil.SetupKMS(k.client, kms); err != nil {
|
||||
return fmt.Errorf("setting up kms: %w", err)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||
"github.com/edgelesssys/constellation/internal/oid"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/edgelesssys/constellation/state/keyservice/keyproto"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/coordinator/state"
|
||||
attestationtypes "github.com/edgelesssys/constellation/internal/attestation/types"
|
||||
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||
)
|
||||
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
||||
"github.com/edgelesssys/constellation/internal/deploy/user"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"go.uber.org/zap/zapcore"
|
||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/coordinator/peer"
|
||||
"github.com/edgelesssys/constellation/coordinator/state"
|
||||
"github.com/edgelesssys/constellation/coordinator/store"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||
)
|
||||
|
||||
|
@ -28,12 +28,17 @@ const (
|
||||
VerifyServicePortGRPC = 9090
|
||||
VerifyServiceNodePortHTTP = 30080
|
||||
VerifyServiceNodePortGRPC = 30081
|
||||
KMSPort = 9000
|
||||
CoordinatorPort = 9000
|
||||
EnclaveSSHPort = 2222
|
||||
SSHPort = 22
|
||||
WireguardPort = 51820
|
||||
NVMEOverTCPPort = 8009
|
||||
// KMSPort is the port the KMS server listens on.
|
||||
KMSPort = 9000
|
||||
// KMSATLSPort is the port the KMS aTLS server listens on.
|
||||
KMSATLSPort = 9001
|
||||
// KMSNodePort is the aTLS port exposed as a NodePort.
|
||||
KMSNodePort = 30091
|
||||
CoordinatorPort = 9000
|
||||
EnclaveSSHPort = 2222
|
||||
SSHPort = 22
|
||||
WireguardPort = 51820
|
||||
NVMEOverTCPPort = 8009
|
||||
// Default NodePort Range
|
||||
// https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
||||
NodePortFrom = 30000
|
||||
@ -53,10 +58,16 @@ const (
|
||||
CoreOSAdminConfFilename = "/etc/kubernetes/admin.conf"
|
||||
KubeadmCertificateDir = "/etc/kubernetes/pki"
|
||||
|
||||
// Filenames for the Activation service.
|
||||
ActivationBasePath = "/var/config"
|
||||
ActivationMeasurementsFilename = "measurements"
|
||||
ActivationIDFilename = "id"
|
||||
//
|
||||
// Filenames for Constellation's micro services.
|
||||
//
|
||||
|
||||
// ServiceBasePath is the base path for the mounted micro services files.
|
||||
ServiceBasePath = "/var/config"
|
||||
// MeasurementsFilename is the filename of CC measurements.
|
||||
MeasurementsFilename = "measurements"
|
||||
// IDFilename is the filename of Constellation's IDs.
|
||||
IDFilename = "id"
|
||||
|
||||
//
|
||||
// Cryptographic constants.
|
||||
|
@ -1,4 +1,4 @@
|
||||
package validator
|
||||
package watcher
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
@ -25,8 +25,8 @@ type Updatable struct {
|
||||
atls.Validator
|
||||
}
|
||||
|
||||
// New initializes a new updatable validator.
|
||||
func New(log *logger.Logger, csp string, fileHandler file.Handler) (*Updatable, error) {
|
||||
// NewValidator initializes a new updatable validator.
|
||||
func NewValidator(log *logger.Logger, csp string, fileHandler file.Handler) (*Updatable, error) {
|
||||
var newValidator newValidatorFunc
|
||||
switch cloudprovider.FromString(csp) {
|
||||
case cloudprovider.Azure:
|
||||
@ -71,7 +71,7 @@ func (u *Updatable) Update() error {
|
||||
u.log.Infof("Updating expected measurements")
|
||||
|
||||
var measurements map[uint32][]byte
|
||||
if err := u.fileHandler.ReadJSON(filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename), &measurements); err != nil {
|
||||
if err := u.fileHandler.ReadJSON(filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename), &measurements); err != nil {
|
||||
return err
|
||||
}
|
||||
u.log.Debugf("New measurements: %v", measurements)
|
@ -1,4 +1,4 @@
|
||||
package validator
|
||||
package watcher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -60,7 +60,7 @@ func TestNewUpdateableValidator(t *testing.T) {
|
||||
handler := file.NewHandler(afero.NewMemMapFs())
|
||||
if tc.writeFile {
|
||||
require.NoError(handler.WriteJSON(
|
||||
filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename),
|
||||
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
|
||||
map[uint32][]byte{
|
||||
11: {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
},
|
||||
@ -68,7 +68,7 @@ func TestNewUpdateableValidator(t *testing.T) {
|
||||
))
|
||||
}
|
||||
|
||||
_, err := New(
|
||||
_, err := NewValidator(
|
||||
logger.NewTest(t),
|
||||
tc.provider,
|
||||
handler,
|
||||
@ -104,7 +104,7 @@ func TestUpdate(t *testing.T) {
|
||||
|
||||
// write measurement config
|
||||
require.NoError(handler.WriteJSON(
|
||||
filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename),
|
||||
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
|
||||
map[uint32][]byte{
|
||||
11: {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
},
|
||||
@ -155,7 +155,7 @@ func TestUpdateConcurrency(t *testing.T) {
|
||||
},
|
||||
}
|
||||
require.NoError(handler.WriteJSON(
|
||||
filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename),
|
||||
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
|
||||
map[uint32][]byte{
|
||||
11: {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||
},
|
@ -59,7 +59,7 @@ func (f *FileWatcher) Watch(file string) error {
|
||||
// file changes may be indicated by either a WRITE, CHMOD, CREATE or RENAME event
|
||||
if event.Op&(fsnotify.Write|fsnotify.Chmod|fsnotify.Create|fsnotify.Rename) != 0 {
|
||||
if err := f.updater.Update(); err != nil {
|
||||
log.With(zap.Error(err)).Errorf("Failed to update activation validator")
|
||||
log.With(zap.Error(err)).Errorf("Update failed")
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
FROM ubuntu@sha256:7cc0576c7c0ec2384de5cbf245f41567e922aab1b075f3e8ad565f508032df17 as build
|
||||
FROM fedora@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 as build
|
||||
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
RUN apt-get update && apt-get install wget git -y
|
||||
RUN dnf -y update && \
|
||||
dnf install -y wget git
|
||||
|
||||
# Install Go
|
||||
ARG GO_VER=1.18
|
||||
RUN wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz
|
||||
RUN tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && rm go${GO_VER}.linux-amd64.tar.gz
|
||||
ARG GO_VER=1.18.3
|
||||
RUN wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz && \
|
||||
tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && \
|
||||
rm go${GO_VER}.linux-amd64.tar.gz
|
||||
ENV PATH ${PATH}:/usr/local/go/bin
|
||||
|
||||
# Download go dependencies
|
||||
@ -25,6 +27,7 @@ WORKDIR /constellation/kms/server/cmd
|
||||
ARG PROJECT_VERSION=0.0.0
|
||||
RUN CGO_ENABLED=0 go build -o /constellation/build/kmsserver -trimpath -buildvcs=false -ldflags "-s -w -buildid='' -X github.com/edgelesssys/constellation/internal/constants.VersionInfo=${PROJECT_VERSION}"
|
||||
|
||||
FROM scratch as release
|
||||
# We would like to use a scratch image here, but we require CA certificates to be installed for aTLS operations on GCP.
|
||||
FROM fedora@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 as release
|
||||
COPY --from=build /constellation/build/kmsserver /kmsserver
|
||||
ENTRYPOINT ["/kmsserver"]
|
108
kms/cmd/main.go
Normal file
108
kms/cmd/main.go
Normal file
@ -0,0 +1,108 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/atls"
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/internal/watcher"
|
||||
"github.com/edgelesssys/constellation/kms/internal/server"
|
||||
"github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/spf13/afero"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := flag.String("port", strconv.Itoa(constants.KMSPort), "Port gRPC server listens on")
|
||||
portATLS := flag.String("atls-port", strconv.Itoa(constants.KMSNodePort), "Port aTLS server listens on")
|
||||
provider := flag.String("cloud-provider", "", "cloud service provider this binary is running on")
|
||||
masterSecretPath := flag.String("master-secret", filepath.Join(constants.ServiceBasePath, constants.MasterSecretFilename), "Path to the Constellation master secret")
|
||||
|
||||
flag.Parse()
|
||||
log := logger.New(logger.JSONLog, zapcore.InfoLevel)
|
||||
|
||||
log.With(zap.String("version", constants.VersionInfo), zap.String("cloudProvider", *provider)).
|
||||
Infof("Constellation Key Management Service")
|
||||
|
||||
validator, err := watcher.NewValidator(log.Named("validator"), *provider, file.NewHandler(afero.NewOsFs()))
|
||||
if err != nil {
|
||||
flag.Usage()
|
||||
log.With(zap.Error(err)).Fatalf("Failed to create validator")
|
||||
}
|
||||
creds := atlscredentials.New(nil, []atls.Validator{validator})
|
||||
|
||||
// set up Key Management Service
|
||||
masterKey, err := readMainSecret(*masterSecretPath)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to read master secret")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||
defer cancel()
|
||||
conKMS, err := setup.SetUpKMS(ctx, setup.NoStoreURI, setup.ClusterKMSURI)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to setup KMS")
|
||||
}
|
||||
if err := conKMS.CreateKEK(ctx, "Constellation", masterKey); err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to create KMS KEK from MasterKey")
|
||||
}
|
||||
|
||||
// set up listeners
|
||||
atlsListener, err := net.Listen("tcp", net.JoinHostPort("", *portATLS))
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to listen on port %s", *portATLS)
|
||||
}
|
||||
plainListener, err := net.Listen("tcp", net.JoinHostPort("", *port))
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to listen on port %s", *port)
|
||||
}
|
||||
|
||||
// start the measurements file watcher
|
||||
watcher, err := watcher.New(log.Named("fileWatcher"), validator)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to create watcher for measurements updates")
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
go func() {
|
||||
log.Infof("starting file watcher for measurements file %s", filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename))
|
||||
if err := watcher.Watch(filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename)); err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to watch measurements file")
|
||||
}
|
||||
}()
|
||||
|
||||
// start the server
|
||||
if err := server.New(log.Named("server"), conKMS).Run(atlsListener, plainListener, creds); err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to run KMS server")
|
||||
}
|
||||
}
|
||||
|
||||
// readMainSecret reads the base64 encoded main secret file from specified path and returns the secret as bytes.
|
||||
func readMainSecret(fileName string) ([]byte, error) {
|
||||
if fileName == "" {
|
||||
return nil, errors.New("no filename to master secret provided")
|
||||
}
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
|
||||
secretBytes, err := fileHandler.Read(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(secretBytes) < constants.MasterSecretLengthMin {
|
||||
return nil, fmt.Errorf("provided master secret is smaller than the required minimum of %d bytes", constants.MasterSecretLengthMin)
|
||||
}
|
||||
|
||||
return secretBytes, nil
|
||||
}
|
108
kms/internal/server/server.go
Normal file
108
kms/internal/server/server.go
Normal file
@ -0,0 +1,108 @@
|
||||
// Package server implements an API to manage encryption keys.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/grpclog"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kmsproto"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Server implements an encryption key management server.
|
||||
// The server serves aTLS for cluster external requests
|
||||
// and plain gRPC for cluster internal requests.
|
||||
type Server struct {
|
||||
log *logger.Logger
|
||||
conKMS kms.CloudKMS
|
||||
kmsproto.UnimplementedAPIServer
|
||||
}
|
||||
|
||||
// New creates a new Server.
|
||||
func New(log *logger.Logger, conKMS kms.CloudKMS) *Server {
|
||||
return &Server{
|
||||
log: log,
|
||||
conKMS: conKMS,
|
||||
}
|
||||
}
|
||||
|
||||
// Run starts both the plain gRPC server and the aTLS gRPC server.
|
||||
// If one of the servers fails, the other server will be closed and the error will be returned.
|
||||
func (s *Server) Run(atlsListener, plainListener net.Listener, credentials *atlscredentials.Credentials) error {
|
||||
var err error
|
||||
var once sync.Once
|
||||
var wg sync.WaitGroup
|
||||
|
||||
atlsServer := grpc.NewServer(
|
||||
grpc.Creds(credentials),
|
||||
s.log.Named("gRPC.aTLS").GetServerUnaryInterceptor(),
|
||||
)
|
||||
kmsproto.RegisterAPIServer(atlsServer, s)
|
||||
|
||||
plainServer := grpc.NewServer(s.log.Named("gRPC.cluster").GetServerUnaryInterceptor())
|
||||
kmsproto.RegisterAPIServer(plainServer, s)
|
||||
|
||||
s.log.Named("gRPC").WithIncreasedLevel(zapcore.WarnLevel).ReplaceGRPCLogger()
|
||||
|
||||
// start the plain gRPC server
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer atlsServer.GracefulStop()
|
||||
|
||||
s.log.Infof("Starting Constellation key management service on %s", plainListener.Addr().String())
|
||||
plainErr := plainServer.Serve(plainListener)
|
||||
if plainErr != nil {
|
||||
once.Do(func() { err = plainErr })
|
||||
}
|
||||
}()
|
||||
|
||||
// start the aTLS server
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer plainServer.GracefulStop()
|
||||
|
||||
s.log.Infof("Starting Constellation aTLS key management service on %s", atlsListener.Addr().String())
|
||||
atlsErr := atlsServer.Serve(atlsListener)
|
||||
if atlsErr != nil {
|
||||
once.Do(func() { err = atlsErr })
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDataKey returns a data key.
|
||||
func (s *Server) GetDataKey(ctx context.Context, in *kmsproto.GetDataKeyRequest) (*kmsproto.GetDataKeyResponse, error) {
|
||||
log := s.log.With("peerAddress", grpclog.PeerAddrFromContext(ctx))
|
||||
|
||||
// Error on 0 key length
|
||||
if in.Length == 0 {
|
||||
log.Errorf("Requested key length is zero")
|
||||
return nil, status.Error(codes.InvalidArgument, "can't derive key with length zero")
|
||||
}
|
||||
|
||||
// Error on empty DataKeyId
|
||||
if in.DataKeyId == "" {
|
||||
log.Errorf("No data key ID specified")
|
||||
return nil, status.Error(codes.InvalidArgument, "no data key ID specified")
|
||||
}
|
||||
|
||||
key, err := s.conKMS.GetDEK(ctx, "Constellation", "key-"+in.DataKeyId, int(in.Length))
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Errorf("Failed to get data key")
|
||||
return nil, status.Errorf(codes.Internal, "%v", err)
|
||||
}
|
||||
return &kmsproto.GetDataKeyResponse{DataKey: key}, nil
|
||||
}
|
117
kms/internal/server/server_test.go
Normal file
117
kms/internal/server/server_test.go
Normal file
@ -0,0 +1,117 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/kmsproto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
goleak.VerifyTestMain(m)
|
||||
}
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
closeErr := errors.New("closed")
|
||||
|
||||
var err error
|
||||
var wg sync.WaitGroup
|
||||
server := New(logger.NewTest(t), &stubKMS{})
|
||||
|
||||
creds := atlscredentials.New(nil, nil)
|
||||
|
||||
atlsListener, plainListener := setUpTestListeners()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err = server.Run(atlsListener, plainListener, creds)
|
||||
}()
|
||||
assert.NoError(plainListener.Close())
|
||||
wg.Wait()
|
||||
assert.Equal(closeErr, err)
|
||||
|
||||
atlsListener, plainListener = setUpTestListeners()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err = server.Run(atlsListener, plainListener, creds)
|
||||
}()
|
||||
assert.NoError(atlsListener.Close())
|
||||
wg.Wait()
|
||||
assert.Equal(closeErr, err)
|
||||
|
||||
atlsListener, plainListener = setUpTestListeners()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err = server.Run(atlsListener, plainListener, creds)
|
||||
}()
|
||||
go assert.NoError(atlsListener.Close())
|
||||
go assert.NoError(plainListener.Close())
|
||||
wg.Wait()
|
||||
assert.Equal(closeErr, err)
|
||||
}
|
||||
|
||||
func TestGetDataKey(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
log := logger.NewTest(t)
|
||||
|
||||
kms := &stubKMS{derivedKey: []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5}}
|
||||
api := New(log, kms)
|
||||
|
||||
res, err := api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{DataKeyId: "1", Length: 32})
|
||||
require.NoError(err)
|
||||
assert.Equal(kms.derivedKey, res.DataKey)
|
||||
|
||||
// Test no data key id
|
||||
res, err = api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{Length: 32})
|
||||
require.Error(err)
|
||||
assert.Nil(res)
|
||||
|
||||
// Test no / zero key length
|
||||
res, err = api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{DataKeyId: "1"})
|
||||
require.Error(err)
|
||||
assert.Nil(res)
|
||||
|
||||
// Test derive key error
|
||||
api = New(log, &stubKMS{deriveKeyErr: errors.New("error")})
|
||||
res, err = api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{DataKeyId: "1", Length: 32})
|
||||
assert.Error(err)
|
||||
assert.Nil(res)
|
||||
}
|
||||
|
||||
func setUpTestListeners() (net.Listener, net.Listener) {
|
||||
atlsListener := testdialer.NewBufconnDialer().GetListener(net.JoinHostPort("192.0.2.1", "9001"))
|
||||
plainListener := testdialer.NewBufconnDialer().GetListener(net.JoinHostPort("192.0.2.1", "9000"))
|
||||
return atlsListener, plainListener
|
||||
}
|
||||
|
||||
type stubKMS struct {
|
||||
masterKey []byte
|
||||
derivedKey []byte
|
||||
deriveKeyErr error
|
||||
}
|
||||
|
||||
func (c *stubKMS) CreateKEK(ctx context.Context, keyID string, kek []byte) error {
|
||||
c.masterKey = kek
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *stubKMS) GetDEK(ctx context.Context, kekID string, dekID string, dekSize int) ([]byte, error) {
|
||||
if c.deriveKeyErr != nil {
|
||||
return nil, c.deriveKeyErr
|
||||
}
|
||||
return c.derivedKey, nil
|
||||
}
|
@ -10,7 +10,7 @@ import (
|
||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
)
|
||||
|
||||
type awsS3ClientAPI interface {
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
)
|
||||
|
||||
type azureContainerAPI interface {
|
@ -1,6 +1,6 @@
|
||||
//go:build integration
|
||||
|
||||
package integration
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/api/option"
|
||||
@ -43,7 +42,7 @@ func TestGoogleCloudStorage(t *testing.T) {
|
||||
t.Log("Running test...")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*50)
|
||||
defer cancel()
|
||||
store, err := storage.NewGoogleCloudStorage(ctx, projectName, bucketName, nil, option.WithoutAuthentication())
|
||||
store, err := NewGoogleCloudStorage(ctx, projectName, bucketName, nil, option.WithoutAuthentication())
|
||||
require.NoError(err)
|
||||
|
||||
testDEK1 := []byte("test DEK")
|
||||
@ -67,7 +66,7 @@ func TestGoogleCloudStorage(t *testing.T) {
|
||||
|
||||
_, err = store.Get(ctx, "invalid:key")
|
||||
assert.Error(err)
|
||||
assert.ErrorIs(err, storage.ErrDEKUnset)
|
||||
assert.ErrorIs(err, ErrDEKUnset)
|
||||
}
|
||||
|
||||
func setupEmulator(ctx context.Context, cli *client.Client, imageName string) (container.ContainerCreateCreatedBody, error) {
|
@ -14,9 +14,9 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/kms"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
kmsconfig "github.com/edgelesssys/constellation/kms/config"
|
||||
kmsconfig "github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
awsInterface "github.com/edgelesssys/constellation/kms/kms/aws"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
@ -8,9 +8,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms/azure"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
@ -8,9 +8,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms/gcp"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
@ -11,10 +11,10 @@ import (
|
||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kms"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kms/types"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -16,9 +16,9 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kms"
|
||||
"github.com/aws/aws-sdk-go-v2/service/kms/types"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -12,10 +12,10 @@ import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys/crypto"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
)
|
||||
|
||||
type hsmClientAPI interface {
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys/crypto"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -12,10 +12,10 @@ import (
|
||||
"time"
|
||||
|
||||
kms "cloud.google.com/go/kms/apiv1"
|
||||
"github.com/edgelesssys/constellation/kms/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/config"
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/googleapis/gax-go/v2"
|
||||
"google.golang.org/api/option"
|
||||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
"github.com/googleapis/gax-go/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/api/option"
|
||||
|
@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.0
|
||||
// protoc v3.20.1
|
||||
// source: kmsapi.proto
|
||||
// source: kms.proto
|
||||
|
||||
package kmsproto
|
||||
|
||||
@ -32,7 +32,7 @@ type GetDataKeyRequest struct {
|
||||
func (x *GetDataKeyRequest) Reset() {
|
||||
*x = GetDataKeyRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kmsapi_proto_msgTypes[0]
|
||||
mi := &file_kms_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -45,7 +45,7 @@ func (x *GetDataKeyRequest) String() string {
|
||||
func (*GetDataKeyRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetDataKeyRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kmsapi_proto_msgTypes[0]
|
||||
mi := &file_kms_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -58,7 +58,7 @@ func (x *GetDataKeyRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetDataKeyRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetDataKeyRequest) Descriptor() ([]byte, []int) {
|
||||
return file_kmsapi_proto_rawDescGZIP(), []int{0}
|
||||
return file_kms_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *GetDataKeyRequest) GetDataKeyId() string {
|
||||
@ -86,7 +86,7 @@ type GetDataKeyResponse struct {
|
||||
func (x *GetDataKeyResponse) Reset() {
|
||||
*x = GetDataKeyResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_kmsapi_proto_msgTypes[1]
|
||||
mi := &file_kms_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -99,7 +99,7 @@ func (x *GetDataKeyResponse) String() string {
|
||||
func (*GetDataKeyResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetDataKeyResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_kmsapi_proto_msgTypes[1]
|
||||
mi := &file_kms_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -112,7 +112,7 @@ func (x *GetDataKeyResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetDataKeyResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetDataKeyResponse) Descriptor() ([]byte, []int) {
|
||||
return file_kmsapi_proto_rawDescGZIP(), []int{1}
|
||||
return file_kms_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *GetDataKeyResponse) GetDataKey() []byte {
|
||||
@ -122,50 +122,49 @@ func (x *GetDataKeyResponse) GetDataKey() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_kmsapi_proto protoreflect.FileDescriptor
|
||||
var File_kms_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_kmsapi_proto_rawDesc = []byte{
|
||||
0x0a, 0x0c, 0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
|
||||
0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x22, 0x4b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74,
|
||||
0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x64,
|
||||
0x61, 0x74, 0x61, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6c,
|
||||
0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e,
|
||||
0x67, 0x74, 0x68, 0x22, 0x2f, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, 0x74,
|
||||
0x61, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x61, 0x74,
|
||||
0x61, 0x4b, 0x65, 0x79, 0x32, 0x4a, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x43, 0x0a, 0x0a, 0x47,
|
||||
0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x6b, 0x6d, 0x73, 0x61,
|
||||
0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65,
|
||||
0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
||||
0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6b, 0x6d, 0x73, 0x2f, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x2f, 0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x2f, 0x6b, 0x6d, 0x73, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
var file_kms_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x6b, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x6b, 0x6d, 0x73,
|
||||
0x22, 0x4b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6b, 0x65,
|
||||
0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61,
|
||||
0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x2f, 0x0a,
|
||||
0x12, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x32, 0x44,
|
||||
0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x3d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x16, 0x2e, 0x6b, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74,
|
||||
0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6b, 0x6d,
|
||||
0x73, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63,
|
||||
0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6b, 0x6d, 0x73,
|
||||
0x2f, 0x6b, 0x6d, 0x73, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_kmsapi_proto_rawDescOnce sync.Once
|
||||
file_kmsapi_proto_rawDescData = file_kmsapi_proto_rawDesc
|
||||
file_kms_proto_rawDescOnce sync.Once
|
||||
file_kms_proto_rawDescData = file_kms_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_kmsapi_proto_rawDescGZIP() []byte {
|
||||
file_kmsapi_proto_rawDescOnce.Do(func() {
|
||||
file_kmsapi_proto_rawDescData = protoimpl.X.CompressGZIP(file_kmsapi_proto_rawDescData)
|
||||
func file_kms_proto_rawDescGZIP() []byte {
|
||||
file_kms_proto_rawDescOnce.Do(func() {
|
||||
file_kms_proto_rawDescData = protoimpl.X.CompressGZIP(file_kms_proto_rawDescData)
|
||||
})
|
||||
return file_kmsapi_proto_rawDescData
|
||||
return file_kms_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_kmsapi_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_kmsapi_proto_goTypes = []interface{}{
|
||||
(*GetDataKeyRequest)(nil), // 0: kmsapi.GetDataKeyRequest
|
||||
(*GetDataKeyResponse)(nil), // 1: kmsapi.GetDataKeyResponse
|
||||
var file_kms_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_kms_proto_goTypes = []interface{}{
|
||||
(*GetDataKeyRequest)(nil), // 0: kms.GetDataKeyRequest
|
||||
(*GetDataKeyResponse)(nil), // 1: kms.GetDataKeyResponse
|
||||
}
|
||||
var file_kmsapi_proto_depIdxs = []int32{
|
||||
0, // 0: kmsapi.API.GetDataKey:input_type -> kmsapi.GetDataKeyRequest
|
||||
1, // 1: kmsapi.API.GetDataKey:output_type -> kmsapi.GetDataKeyResponse
|
||||
var file_kms_proto_depIdxs = []int32{
|
||||
0, // 0: kms.API.GetDataKey:input_type -> kms.GetDataKeyRequest
|
||||
1, // 1: kms.API.GetDataKey:output_type -> kms.GetDataKeyResponse
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
@ -173,13 +172,13 @@ var file_kmsapi_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_kmsapi_proto_init() }
|
||||
func file_kmsapi_proto_init() {
|
||||
if File_kmsapi_proto != nil {
|
||||
func init() { file_kms_proto_init() }
|
||||
func file_kms_proto_init() {
|
||||
if File_kms_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_kmsapi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_kms_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetDataKeyRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@ -191,7 +190,7 @@ func file_kmsapi_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_kmsapi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_kms_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetDataKeyResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@ -208,18 +207,18 @@ func file_kmsapi_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_kmsapi_proto_rawDesc,
|
||||
RawDescriptor: file_kms_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_kmsapi_proto_goTypes,
|
||||
DependencyIndexes: file_kmsapi_proto_depIdxs,
|
||||
MessageInfos: file_kmsapi_proto_msgTypes,
|
||||
GoTypes: file_kms_proto_goTypes,
|
||||
DependencyIndexes: file_kms_proto_depIdxs,
|
||||
MessageInfos: file_kms_proto_msgTypes,
|
||||
}.Build()
|
||||
File_kmsapi_proto = out.File
|
||||
file_kmsapi_proto_rawDesc = nil
|
||||
file_kmsapi_proto_goTypes = nil
|
||||
file_kmsapi_proto_depIdxs = nil
|
||||
File_kms_proto = out.File
|
||||
file_kms_proto_rawDesc = nil
|
||||
file_kms_proto_goTypes = nil
|
||||
file_kms_proto_depIdxs = nil
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package kmsapi;
|
||||
package kms;
|
||||
|
||||
option go_package = "github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto";
|
||||
option go_package = "github.com/edgelesssys/constellation/kms/kmsproto";
|
||||
|
||||
service API {
|
||||
rpc GetDataKey(GetDataKeyRequest) returns (GetDataKeyResponse);
|
@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.20.1
|
||||
// source: kmsapi.proto
|
||||
// source: kms.proto
|
||||
|
||||
package kmsproto
|
||||
|
||||
@ -35,7 +35,7 @@ func NewAPIClient(cc grpc.ClientConnInterface) APIClient {
|
||||
|
||||
func (c *aPIClient) GetDataKey(ctx context.Context, in *GetDataKeyRequest, opts ...grpc.CallOption) (*GetDataKeyResponse, error) {
|
||||
out := new(GetDataKeyResponse)
|
||||
err := c.cc.Invoke(ctx, "/kmsapi.API/GetDataKey", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/kms.API/GetDataKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -80,7 +80,7 @@ func _API_GetDataKey_Handler(srv interface{}, ctx context.Context, dec func(inte
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/kmsapi.API/GetDataKey",
|
||||
FullMethod: "/kms.API/GetDataKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(APIServer).GetDataKey(ctx, req.(*GetDataKeyRequest))
|
||||
@ -92,7 +92,7 @@ func _API_GetDataKey_Handler(srv interface{}, ctx context.Context, dec func(inte
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var API_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "kmsapi.API",
|
||||
ServiceName: "kms.API",
|
||||
HandlerType: (*APIServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
@ -101,5 +101,5 @@ var API_ServiceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "kmsapi.proto",
|
||||
Metadata: "kms.proto",
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
||||
"github.com/edgelesssys/constellation/kms/server/setup"
|
||||
"github.com/spf13/afero"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := flag.String("port", "9000", "Port gRPC server listens on")
|
||||
masterSecretPath := flag.String("master-secret", "/constellation/constellation-mastersecret.base64", "Path to the Constellation master secret")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
log := logger.New(logger.JSONLog, zapcore.InfoLevel)
|
||||
|
||||
log.With(zap.String("version", constants.VersionInfo)).Infof("Constellation Key Management Service")
|
||||
|
||||
masterKey, err := readMainSecret(*masterSecretPath)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to read master secret")
|
||||
}
|
||||
|
||||
conKMS, err := setup.SetUpKMS(context.Background(), setup.NoStoreURI, setup.ClusterKMSURI)
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to setup KMS")
|
||||
}
|
||||
|
||||
if err := conKMS.CreateKEK(context.Background(), "Constellation", masterKey); err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to create KMS KEK from MasterKey")
|
||||
}
|
||||
|
||||
lis, err := net.Listen("tcp", net.JoinHostPort("", *port))
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to listen")
|
||||
}
|
||||
|
||||
srv := kmsapi.New(log.Named("server"), conKMS)
|
||||
|
||||
log.Named("gRPC").WithIncreasedLevel(zapcore.WarnLevel).ReplaceGRPCLogger()
|
||||
// TODO: Launch server with aTLS to allow attestation for clients.
|
||||
grpcServer := grpc.NewServer(log.Named("gRPC").GetServerUnaryInterceptor())
|
||||
|
||||
kmsproto.RegisterAPIServer(grpcServer, srv)
|
||||
|
||||
log.Infof("Starting key management service on %s", lis.Addr().String())
|
||||
if err := grpcServer.Serve(lis); err != nil {
|
||||
log.With(zap.Error(err)).Fatalf("Failed to serve")
|
||||
}
|
||||
}
|
||||
|
||||
// readMainSecret reads the base64 encoded main secret file from specified path and returns the secret as bytes.
|
||||
func readMainSecret(fileName string) ([]byte, error) {
|
||||
if fileName == "" {
|
||||
return nil, errors.New("no filename to master secret provided")
|
||||
}
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
|
||||
secretBytes, err := fileHandler.Read(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(secretBytes) < constants.MasterSecretLengthMin {
|
||||
return nil, fmt.Errorf("provided master secret is smaller than the required minimum of %d bytes", constants.MasterSecretLengthMin)
|
||||
}
|
||||
|
||||
return secretBytes, nil
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
// Package kmsapi implements an API to manage encryption keys.
|
||||
package kmsapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/grpc/grpclog"
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// API resembles an encryption key management api server through logger, CloudKMS and proto-unimplemented server.
|
||||
type API struct {
|
||||
log *logger.Logger
|
||||
conKMS kms.CloudKMS
|
||||
kmsproto.UnimplementedAPIServer
|
||||
}
|
||||
|
||||
// New creates a new API.
|
||||
func New(log *logger.Logger, conKMS kms.CloudKMS) *API {
|
||||
return &API{
|
||||
log: log,
|
||||
conKMS: conKMS,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDataKey returns a data key.
|
||||
func (a *API) GetDataKey(ctx context.Context, in *kmsproto.GetDataKeyRequest) (*kmsproto.GetDataKeyResponse, error) {
|
||||
log := a.log.With("peerAddress", grpclog.PeerAddrFromContext(ctx))
|
||||
|
||||
// Error on 0 key length
|
||||
if in.Length == 0 {
|
||||
log.Errorf("Requested key length is zero")
|
||||
return nil, status.Error(codes.InvalidArgument, "can't derive key with length zero")
|
||||
}
|
||||
|
||||
// Error on empty DataKeyId
|
||||
if in.DataKeyId == "" {
|
||||
log.Errorf("No data key ID specified")
|
||||
return nil, status.Error(codes.InvalidArgument, "no data key ID specified")
|
||||
}
|
||||
|
||||
key, err := a.conKMS.GetDEK(ctx, "Constellation", "key-"+in.DataKeyId, int(in.Length))
|
||||
if err != nil {
|
||||
log.With(zap.Error(err)).Errorf("Failed to get data key")
|
||||
return nil, status.Errorf(codes.Internal, "%v", err)
|
||||
}
|
||||
return &kmsproto.GetDataKeyResponse{DataKey: key}, nil
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package kmsapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/logger"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetDataKey(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
log := logger.NewTest(t)
|
||||
|
||||
kms := &stubKMS{derivedKey: []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5}}
|
||||
api := New(log, kms)
|
||||
|
||||
res, err := api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{DataKeyId: "1", Length: 32})
|
||||
require.NoError(err)
|
||||
assert.Equal(kms.derivedKey, res.DataKey)
|
||||
|
||||
// Test no data key id
|
||||
res, err = api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{Length: 32})
|
||||
require.Error(err)
|
||||
assert.Nil(res)
|
||||
|
||||
// Test no / zero key length
|
||||
res, err = api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{DataKeyId: "1"})
|
||||
require.Error(err)
|
||||
assert.Nil(res)
|
||||
|
||||
// Test derive key error
|
||||
api = New(log, &stubKMS{deriveKeyErr: errors.New("error")})
|
||||
res, err = api.GetDataKey(context.Background(), &kmsproto.GetDataKeyRequest{DataKeyId: "1", Length: 32})
|
||||
assert.Error(err)
|
||||
assert.Nil(res)
|
||||
}
|
||||
|
||||
type stubKMS struct {
|
||||
masterKey []byte
|
||||
derivedKey []byte
|
||||
deriveKeyErr error
|
||||
}
|
||||
|
||||
func (c *stubKMS) CreateKEK(ctx context.Context, keyID string, kek []byte) error {
|
||||
c.masterKey = kek
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *stubKMS) GetDEK(ctx context.Context, kekID string, dekID string, dekSize int) ([]byte, error) {
|
||||
if c.deriveKeyErr != nil {
|
||||
return nil, c.deriveKeyErr
|
||||
}
|
||||
return c.derivedKey, nil
|
||||
}
|
@ -6,12 +6,12 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||
"github.com/edgelesssys/constellation/kms/kms"
|
||||
"github.com/edgelesssys/constellation/kms/kms/aws"
|
||||
"github.com/edgelesssys/constellation/kms/kms/azure"
|
||||
"github.com/edgelesssys/constellation/kms/kms/cluster"
|
||||
"github.com/edgelesssys/constellation/kms/kms/gcp"
|
||||
"github.com/edgelesssys/constellation/kms/storage"
|
||||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
||||
)
|
||||
|
@ -46,7 +46,7 @@ RUN protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_o
|
||||
|
||||
## key management
|
||||
WORKDIR /kms
|
||||
COPY kms/server/kmsapi/kmsproto/*.proto /kms
|
||||
COPY kms/kmsproto/*.proto /kms
|
||||
RUN protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative *.proto
|
||||
|
||||
## activation
|
||||
@ -64,6 +64,6 @@ COPY --from=build /pubapi/*.go coordinator/pubapi/pubproto/
|
||||
COPY --from=build /vpnapi/*.go coordinator/vpnapi/vpnproto/
|
||||
COPY --from=build /disk-mapper/*.go state/keyservice/keyproto/
|
||||
COPY --from=build /service/*.go debugd/service/
|
||||
COPY --from=build /kms/*.go kms/server/kmsapi/kmsproto/
|
||||
COPY --from=build /kms/*.go kms/kmsproto/
|
||||
COPY --from=build /activation/*.go activation/activationproto/
|
||||
COPY --from=build /verify/*.go verify/verifyproto/
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/internal/atls"
|
||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||
"github.com/edgelesssys/constellation/internal/oid"
|
||||
kms "github.com/edgelesssys/constellation/kms/server/setup"
|
||||
kms "github.com/edgelesssys/constellation/kms/setup"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
Loading…
Reference in New Issue
Block a user