mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-25 07:29:38 -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:
|
with:
|
||||||
name: kmsserver
|
name: kmsserver
|
||||||
projectVersion: '0.0.0'
|
projectVersion: '0.0.0'
|
||||||
dockerfile: Dockerfile.kms
|
dockerfile: kms/server/Dockerfile
|
||||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
@ -43,7 +43,7 @@ jobs:
|
|||||||
"activation-service" )
|
"activation-service" )
|
||||||
echo "microServiceDockerfile=activation/Dockerfile" >> $GITHUB_ENV ;;
|
echo "microServiceDockerfile=activation/Dockerfile" >> $GITHUB_ENV ;;
|
||||||
"kmsserver" )
|
"kmsserver" )
|
||||||
echo "microServiceDockerfile=Dockerfile.kms" >> $GITHUB_ENV ;;
|
echo "microServiceDockerfile=kms/server/Dockerfile" >> $GITHUB_ENV ;;
|
||||||
"verification-service" )
|
"verification-service" )
|
||||||
echo "microServiceDockerfile=verify/Dockerfile" >> $GITHUB_ENV ;;
|
echo "microServiceDockerfile=verify/Dockerfile" >> $GITHUB_ENV ;;
|
||||||
esac
|
esac
|
||||||
|
@ -5,7 +5,7 @@ RUN dnf -y update && \
|
|||||||
dnf clean all
|
dnf clean all
|
||||||
|
|
||||||
# Install Go
|
# 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 && \
|
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 && \
|
tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && \
|
||||||
rm 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
|
dnf clean all
|
||||||
|
|
||||||
# Install Go
|
# 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 && \
|
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 && \
|
tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && \
|
||||||
rm 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
|
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/
|
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
|
FROM fedora@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 as release
|
||||||
COPY --from=build /constellation/activation/activation-service /activation
|
COPY --from=build /constellation/activation/activation-service /activation
|
||||||
ENTRYPOINT [ "/activation" ]
|
ENTRYPOINT [ "/activation" ]
|
||||||
|
@ -9,13 +9,12 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/activation/kubeadm"
|
"github.com/edgelesssys/constellation/activation/kubeadm"
|
||||||
"github.com/edgelesssys/constellation/activation/kubernetesca"
|
"github.com/edgelesssys/constellation/activation/kubernetesca"
|
||||||
"github.com/edgelesssys/constellation/activation/server"
|
"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/atls"
|
||||||
"github.com/edgelesssys/constellation/internal/constants"
|
"github.com/edgelesssys/constellation/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/internal/file"
|
"github.com/edgelesssys/constellation/internal/file"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"github.com/edgelesssys/constellation/internal/logger"
|
||||||
|
"github.com/edgelesssys/constellation/internal/watcher"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
@ -34,7 +33,7 @@ func main() {
|
|||||||
|
|
||||||
handler := file.NewHandler(afero.NewOsFs())
|
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 {
|
if err != nil {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
log.With(zap.Error(err)).Fatalf("Failed to create validator")
|
log.With(zap.Error(err)).Fatalf("Failed to create validator")
|
||||||
@ -63,8 +62,8 @@ func main() {
|
|||||||
defer watcher.Close()
|
defer watcher.Close()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Infof("starting file watcher for measurements file %s", filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename))
|
log.Infof("starting file watcher for measurements file %s", filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename))
|
||||||
if err := watcher.Watch(filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename)); err != nil {
|
if err := watcher.Watch(filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename)); err != nil {
|
||||||
log.With(zap.Error(err)).Fatalf("Failed to watch measurements file")
|
log.With(zap.Error(err)).Fatalf("Failed to watch measurements file")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"github.com/edgelesssys/constellation/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
"github.com/edgelesssys/constellation/kms/kmsproto"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"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"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/test/bufconn"
|
"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 := s.log.With(zap.String("peerAddress", grpclog.PeerAddrFromContext(ctx)))
|
||||||
log.Infof("Loading IDs")
|
log.Infof("Loading IDs")
|
||||||
var id attestationtypes.ID
|
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")
|
log.With(zap.Error(err)).Errorf("Unable to load IDs")
|
||||||
return nodeParameters{}, status.Errorf(codes.Internal, "unable to load IDs: %s", err)
|
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())
|
file := file.NewHandler(afero.NewMemMapFs())
|
||||||
if len(tc.id) > 0 {
|
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(
|
api := New(
|
||||||
logger.NewTest(t),
|
logger.NewTest(t),
|
||||||
@ -217,7 +217,7 @@ func TestActivateWorkerNode(t *testing.T) {
|
|||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
file := file.NewHandler(afero.NewMemMapFs())
|
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(
|
api := New(
|
||||||
logger.NewTest(t),
|
logger.NewTest(t),
|
||||||
@ -322,7 +322,7 @@ func TestActivateControlPlaneNode(t *testing.T) {
|
|||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
file := file.NewHandler(afero.NewMemMapFs())
|
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(
|
api := New(
|
||||||
logger.NewTest(t),
|
logger.NewTest(t),
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/coordinator/state"
|
"github.com/edgelesssys/constellation/coordinator/state"
|
||||||
"github.com/edgelesssys/constellation/internal/atls"
|
"github.com/edgelesssys/constellation/internal/atls"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
"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"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"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/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/deploy/user"
|
"github.com/edgelesssys/constellation/internal/deploy/user"
|
||||||
"github.com/edgelesssys/constellation/internal/file"
|
"github.com/edgelesssys/constellation/internal/file"
|
||||||
"github.com/edgelesssys/constellation/kms/kms"
|
"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"
|
"go.uber.org/zap"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"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/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"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/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
"github.com/edgelesssys/constellation/internal/grpc/dialer"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"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/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -138,7 +138,7 @@ func NewActivationDaemonset(csp, measurementsJSON, idJSON string) *activationDae
|
|||||||
Image: activationImage,
|
Image: activationImage,
|
||||||
Ports: []k8s.ContainerPort{
|
Ports: []k8s.ContainerPort{
|
||||||
{
|
{
|
||||||
ContainerPort: 9090,
|
ContainerPort: constants.ActivationServicePort,
|
||||||
Name: "tcp",
|
Name: "tcp",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -148,13 +148,12 @@ func NewActivationDaemonset(csp, measurementsJSON, idJSON string) *activationDae
|
|||||||
Args: []string{
|
Args: []string{
|
||||||
fmt.Sprintf("--cloud-provider=%s", csp),
|
fmt.Sprintf("--cloud-provider=%s", csp),
|
||||||
fmt.Sprintf("--kms-endpoint=kms.kube-system:%d", constants.KMSPort),
|
fmt.Sprintf("--kms-endpoint=kms.kube-system:%d", constants.KMSPort),
|
||||||
"--v=5",
|
|
||||||
},
|
},
|
||||||
VolumeMounts: []k8s.VolumeMount{
|
VolumeMounts: []k8s.VolumeMount{
|
||||||
{
|
{
|
||||||
Name: "config",
|
Name: "config",
|
||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
MountPath: constants.ActivationBasePath,
|
MountPath: constants.ServiceBasePath,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "kubeadm",
|
Name: "kubeadm",
|
||||||
|
@ -14,7 +14,8 @@ import (
|
|||||||
|
|
||||||
type kmsDeployment struct {
|
type kmsDeployment struct {
|
||||||
ServiceAccount k8s.ServiceAccount
|
ServiceAccount k8s.ServiceAccount
|
||||||
Service k8s.Service
|
ServiceInternal k8s.Service
|
||||||
|
ServiceExternal k8s.Service
|
||||||
ClusterRole rbac.ClusterRole
|
ClusterRole rbac.ClusterRole
|
||||||
ClusterRoleBinding rbac.ClusterRoleBinding
|
ClusterRoleBinding rbac.ClusterRoleBinding
|
||||||
Deployment apps.Deployment
|
Deployment apps.Deployment
|
||||||
@ -23,7 +24,7 @@ type kmsDeployment struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewKMSDeployment creates a new *kmsDeployment to use as the key management system inside Constellation.
|
// 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{
|
return &kmsDeployment{
|
||||||
ServiceAccount: k8s.ServiceAccount{
|
ServiceAccount: k8s.ServiceAccount{
|
||||||
TypeMeta: meta.TypeMeta{
|
TypeMeta: meta.TypeMeta{
|
||||||
@ -35,7 +36,7 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
|||||||
Namespace: "kube-system",
|
Namespace: "kube-system",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Service: k8s.Service{
|
ServiceInternal: k8s.Service{
|
||||||
TypeMeta: meta.TypeMeta{
|
TypeMeta: meta.TypeMeta{
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
Kind: "Service",
|
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{
|
ClusterRole: rbac.ClusterRole{
|
||||||
TypeMeta: meta.TypeMeta{
|
TypeMeta: meta.TypeMeta{
|
||||||
APIVersion: "rbac.authorization.k8s.io/v1",
|
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||||
@ -161,14 +187,35 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
|||||||
},
|
},
|
||||||
Volumes: []k8s.Volume{
|
Volumes: []k8s.Volume{
|
||||||
{
|
{
|
||||||
Name: "mastersecret",
|
Name: "config",
|
||||||
VolumeSource: k8s.VolumeSource{
|
VolumeSource: k8s.VolumeSource{
|
||||||
Secret: &k8s.SecretVolumeSource{
|
Projected: &k8s.ProjectedVolumeSource{
|
||||||
SecretName: constants.ConstellationMasterSecretStoreName,
|
Sources: []k8s.VolumeProjection{
|
||||||
|
{
|
||||||
|
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{
|
Items: []k8s.KeyToPath{
|
||||||
{
|
{
|
||||||
Key: constants.ConstellationMasterSecretKey,
|
Key: constants.ConstellationMasterSecretKey,
|
||||||
Path: "constellation-mastersecret.base64",
|
Path: constants.MasterSecretFilename,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -181,14 +228,15 @@ func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
|||||||
Name: "kms",
|
Name: "kms",
|
||||||
Image: kmsImage,
|
Image: kmsImage,
|
||||||
Args: []string{
|
Args: []string{
|
||||||
|
fmt.Sprintf("--atls-port=%d", constants.KMSATLSPort),
|
||||||
fmt.Sprintf("--port=%d", constants.KMSPort),
|
fmt.Sprintf("--port=%d", constants.KMSPort),
|
||||||
"--v=5",
|
fmt.Sprintf("--cloud-provider=%s", csp),
|
||||||
},
|
},
|
||||||
VolumeMounts: []k8s.VolumeMount{
|
VolumeMounts: []k8s.VolumeMount{
|
||||||
{
|
{
|
||||||
Name: "mastersecret",
|
Name: "config",
|
||||||
ReadOnly: true,
|
ReadOnly: true,
|
||||||
MountPath: "/constellation/",
|
MountPath: constants.ServiceBasePath,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ func TestKMSMarshalUnmarshal(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
|
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
|
||||||
kmsDepl := NewKMSDeployment(testMS)
|
kmsDepl := NewKMSDeployment("test", testMS)
|
||||||
data, err := kmsDepl.Marshal()
|
data, err := kmsDepl.Marshal()
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ func (k *KubeWrapper) InitCluster(
|
|||||||
return fmt.Errorf("setting up pod network: %w", err)
|
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 {
|
if err = k.clusterUtil.SetupKMS(k.client, kms); err != nil {
|
||||||
return fmt.Errorf("setting up kms: %w", err)
|
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/dialer"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
"github.com/edgelesssys/constellation/internal/grpc/testdialer"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"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/edgelesssys/constellation/state/keyservice/keyproto"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/coordinator/state"
|
"github.com/edgelesssys/constellation/coordinator/state"
|
||||||
attestationtypes "github.com/edgelesssys/constellation/internal/attestation/types"
|
attestationtypes "github.com/edgelesssys/constellation/internal/attestation/types"
|
||||||
"github.com/edgelesssys/constellation/internal/deploy/ssh"
|
"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"
|
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/ssh"
|
||||||
"github.com/edgelesssys/constellation/internal/deploy/user"
|
"github.com/edgelesssys/constellation/internal/deploy/user"
|
||||||
"github.com/edgelesssys/constellation/internal/logger"
|
"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"
|
"go.uber.org/zap/zapcore"
|
||||||
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
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/peer"
|
||||||
"github.com/edgelesssys/constellation/coordinator/state"
|
"github.com/edgelesssys/constellation/coordinator/state"
|
||||||
"github.com/edgelesssys/constellation/coordinator/store"
|
"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"
|
kubeadm "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,7 +28,12 @@ const (
|
|||||||
VerifyServicePortGRPC = 9090
|
VerifyServicePortGRPC = 9090
|
||||||
VerifyServiceNodePortHTTP = 30080
|
VerifyServiceNodePortHTTP = 30080
|
||||||
VerifyServiceNodePortGRPC = 30081
|
VerifyServiceNodePortGRPC = 30081
|
||||||
|
// KMSPort is the port the KMS server listens on.
|
||||||
KMSPort = 9000
|
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
|
CoordinatorPort = 9000
|
||||||
EnclaveSSHPort = 2222
|
EnclaveSSHPort = 2222
|
||||||
SSHPort = 22
|
SSHPort = 22
|
||||||
@ -53,10 +58,16 @@ const (
|
|||||||
CoreOSAdminConfFilename = "/etc/kubernetes/admin.conf"
|
CoreOSAdminConfFilename = "/etc/kubernetes/admin.conf"
|
||||||
KubeadmCertificateDir = "/etc/kubernetes/pki"
|
KubeadmCertificateDir = "/etc/kubernetes/pki"
|
||||||
|
|
||||||
// Filenames for the Activation service.
|
//
|
||||||
ActivationBasePath = "/var/config"
|
// Filenames for Constellation's micro services.
|
||||||
ActivationMeasurementsFilename = "measurements"
|
//
|
||||||
ActivationIDFilename = "id"
|
|
||||||
|
// 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.
|
// Cryptographic constants.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package validator
|
package watcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
@ -25,8 +25,8 @@ type Updatable struct {
|
|||||||
atls.Validator
|
atls.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
// New initializes a new updatable validator.
|
// NewValidator initializes a new updatable validator.
|
||||||
func New(log *logger.Logger, csp string, fileHandler file.Handler) (*Updatable, error) {
|
func NewValidator(log *logger.Logger, csp string, fileHandler file.Handler) (*Updatable, error) {
|
||||||
var newValidator newValidatorFunc
|
var newValidator newValidatorFunc
|
||||||
switch cloudprovider.FromString(csp) {
|
switch cloudprovider.FromString(csp) {
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
@ -71,7 +71,7 @@ func (u *Updatable) Update() error {
|
|||||||
u.log.Infof("Updating expected measurements")
|
u.log.Infof("Updating expected measurements")
|
||||||
|
|
||||||
var measurements map[uint32][]byte
|
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
|
return err
|
||||||
}
|
}
|
||||||
u.log.Debugf("New measurements: %v", measurements)
|
u.log.Debugf("New measurements: %v", measurements)
|
@ -1,4 +1,4 @@
|
|||||||
package validator
|
package watcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -60,7 +60,7 @@ func TestNewUpdateableValidator(t *testing.T) {
|
|||||||
handler := file.NewHandler(afero.NewMemMapFs())
|
handler := file.NewHandler(afero.NewMemMapFs())
|
||||||
if tc.writeFile {
|
if tc.writeFile {
|
||||||
require.NoError(handler.WriteJSON(
|
require.NoError(handler.WriteJSON(
|
||||||
filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename),
|
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
|
||||||
map[uint32][]byte{
|
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},
|
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),
|
logger.NewTest(t),
|
||||||
tc.provider,
|
tc.provider,
|
||||||
handler,
|
handler,
|
||||||
@ -104,7 +104,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
|
|
||||||
// write measurement config
|
// write measurement config
|
||||||
require.NoError(handler.WriteJSON(
|
require.NoError(handler.WriteJSON(
|
||||||
filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename),
|
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
|
||||||
map[uint32][]byte{
|
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},
|
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(
|
require.NoError(handler.WriteJSON(
|
||||||
filepath.Join(constants.ActivationBasePath, constants.ActivationMeasurementsFilename),
|
filepath.Join(constants.ServiceBasePath, constants.MeasurementsFilename),
|
||||||
map[uint32][]byte{
|
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},
|
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
|
// 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 event.Op&(fsnotify.Write|fsnotify.Chmod|fsnotify.Create|fsnotify.Rename) != 0 {
|
||||||
if err := f.updater.Update(); err != nil {
|
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"
|
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
|
# 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
|
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
|
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
|
ENV PATH ${PATH}:/usr/local/go/bin
|
||||||
|
|
||||||
# Download go dependencies
|
# Download go dependencies
|
||||||
@ -25,6 +27,7 @@ WORKDIR /constellation/kms/server/cmd
|
|||||||
ARG PROJECT_VERSION=0.0.0
|
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}"
|
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
|
COPY --from=build /constellation/build/kmsserver /kmsserver
|
||||||
ENTRYPOINT ["/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"
|
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"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
"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 {
|
type awsS3ClientAPI interface {
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||||
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
|
"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 {
|
type azureContainerAPI interface {
|
@ -1,6 +1,6 @@
|
|||||||
//go:build integration
|
//go:build integration
|
||||||
|
|
||||||
package integration
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
@ -43,7 +42,7 @@ func TestGoogleCloudStorage(t *testing.T) {
|
|||||||
t.Log("Running test...")
|
t.Log("Running test...")
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*50)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*50)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
store, err := storage.NewGoogleCloudStorage(ctx, projectName, bucketName, nil, option.WithoutAuthentication())
|
store, err := NewGoogleCloudStorage(ctx, projectName, bucketName, nil, option.WithoutAuthentication())
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
|
||||||
testDEK1 := []byte("test DEK")
|
testDEK1 := []byte("test DEK")
|
||||||
@ -67,7 +66,7 @@ func TestGoogleCloudStorage(t *testing.T) {
|
|||||||
|
|
||||||
_, err = store.Get(ctx, "invalid:key")
|
_, err = store.Get(ctx, "invalid:key")
|
||||||
assert.Error(err)
|
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) {
|
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/kms"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
"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"
|
awsInterface "github.com/edgelesssys/constellation/kms/kms/aws"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
@ -8,9 +8,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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/kms/azure"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
@ -8,9 +8,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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/kms/gcp"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
@ -11,10 +11,10 @@ import (
|
|||||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
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"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/kms/types"
|
"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"
|
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -16,9 +16,9 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go-v2/aws"
|
"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"
|
||||||
"github.com/aws/aws-sdk-go-v2/service/kms/types"
|
"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"
|
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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/azcore/to"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
|
"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"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets"
|
"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/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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/azidentity"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys"
|
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys/crypto"
|
"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"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type hsmClientAPI interface {
|
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"
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys/crypto"
|
"github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys/crypto"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"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/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -12,10 +12,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
kms "cloud.google.com/go/kms/apiv1"
|
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"
|
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/googleapis/gax-go/v2"
|
"github.com/googleapis/gax-go/v2"
|
||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||||
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
kmsInterface "github.com/edgelesssys/constellation/kms/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/util"
|
"github.com/edgelesssys/constellation/kms/kms/util"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
"github.com/googleapis/gax-go/v2"
|
"github.com/googleapis/gax-go/v2"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.28.0
|
// protoc-gen-go v1.28.0
|
||||||
// protoc v3.20.1
|
// protoc v3.20.1
|
||||||
// source: kmsapi.proto
|
// source: kms.proto
|
||||||
|
|
||||||
package kmsproto
|
package kmsproto
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ type GetDataKeyRequest struct {
|
|||||||
func (x *GetDataKeyRequest) Reset() {
|
func (x *GetDataKeyRequest) Reset() {
|
||||||
*x = GetDataKeyRequest{}
|
*x = GetDataKeyRequest{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_kmsapi_proto_msgTypes[0]
|
mi := &file_kms_proto_msgTypes[0]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ func (x *GetDataKeyRequest) String() string {
|
|||||||
func (*GetDataKeyRequest) ProtoMessage() {}
|
func (*GetDataKeyRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetDataKeyRequest) ProtoReflect() protoreflect.Message {
|
func (x *GetDataKeyRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_kmsapi_proto_msgTypes[0]
|
mi := &file_kms_proto_msgTypes[0]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -58,7 +58,7 @@ func (x *GetDataKeyRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetDataKeyRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetDataKeyRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*GetDataKeyRequest) Descriptor() ([]byte, []int) {
|
func (*GetDataKeyRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_kmsapi_proto_rawDescGZIP(), []int{0}
|
return file_kms_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetDataKeyRequest) GetDataKeyId() string {
|
func (x *GetDataKeyRequest) GetDataKeyId() string {
|
||||||
@ -86,7 +86,7 @@ type GetDataKeyResponse struct {
|
|||||||
func (x *GetDataKeyResponse) Reset() {
|
func (x *GetDataKeyResponse) Reset() {
|
||||||
*x = GetDataKeyResponse{}
|
*x = GetDataKeyResponse{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_kmsapi_proto_msgTypes[1]
|
mi := &file_kms_proto_msgTypes[1]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ func (x *GetDataKeyResponse) String() string {
|
|||||||
func (*GetDataKeyResponse) ProtoMessage() {}
|
func (*GetDataKeyResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetDataKeyResponse) ProtoReflect() protoreflect.Message {
|
func (x *GetDataKeyResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_kmsapi_proto_msgTypes[1]
|
mi := &file_kms_proto_msgTypes[1]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -112,7 +112,7 @@ func (x *GetDataKeyResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetDataKeyResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetDataKeyResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*GetDataKeyResponse) Descriptor() ([]byte, []int) {
|
func (*GetDataKeyResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_kmsapi_proto_rawDescGZIP(), []int{1}
|
return file_kms_proto_rawDescGZIP(), []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetDataKeyResponse) GetDataKey() []byte {
|
func (x *GetDataKeyResponse) GetDataKey() []byte {
|
||||||
@ -122,50 +122,49 @@ func (x *GetDataKeyResponse) GetDataKey() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var File_kmsapi_proto protoreflect.FileDescriptor
|
var File_kms_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_kmsapi_proto_rawDesc = []byte{
|
var file_kms_proto_rawDesc = []byte{
|
||||||
0x0a, 0x0c, 0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
|
0x0a, 0x09, 0x6b, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x6b, 0x6d, 0x73,
|
||||||
0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x22, 0x4b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74,
|
0x22, 0x4b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65,
|
||||||
0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x64,
|
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6b, 0x65,
|
||||||
0x61, 0x74, 0x61, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61,
|
||||||
0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6c,
|
0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18,
|
||||||
0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e,
|
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x2f, 0x0a,
|
||||||
0x67, 0x74, 0x68, 0x22, 0x2f, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65,
|
0x12, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, 0x74,
|
0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6b, 0x65, 0x79, 0x18,
|
||||||
0x61, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x61, 0x74,
|
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x32, 0x44,
|
||||||
0x61, 0x4b, 0x65, 0x79, 0x32, 0x4a, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x43, 0x0a, 0x0a, 0x47,
|
0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x3d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61,
|
||||||
0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x6b, 0x6d, 0x73, 0x61,
|
0x4b, 0x65, 0x79, 0x12, 0x16, 0x2e, 0x6b, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74,
|
||||||
0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71,
|
0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6b, 0x6d,
|
||||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
|
0x73, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70,
|
||||||
0x74, 0x44, 0x61, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x6f, 0x6e, 0x73, 0x65, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||||
0x42, 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65,
|
0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63,
|
||||||
0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6b, 0x6d, 0x73,
|
||||||
0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6b, 0x6d, 0x73, 0x2f, 0x73, 0x65, 0x72,
|
0x2f, 0x6b, 0x6d, 0x73, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
0x76, 0x65, 0x72, 0x2f, 0x6b, 0x6d, 0x73, 0x61, 0x70, 0x69, 0x2f, 0x6b, 0x6d, 0x73, 0x70, 0x72,
|
0x33,
|
||||||
0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_kmsapi_proto_rawDescOnce sync.Once
|
file_kms_proto_rawDescOnce sync.Once
|
||||||
file_kmsapi_proto_rawDescData = file_kmsapi_proto_rawDesc
|
file_kms_proto_rawDescData = file_kms_proto_rawDesc
|
||||||
)
|
)
|
||||||
|
|
||||||
func file_kmsapi_proto_rawDescGZIP() []byte {
|
func file_kms_proto_rawDescGZIP() []byte {
|
||||||
file_kmsapi_proto_rawDescOnce.Do(func() {
|
file_kms_proto_rawDescOnce.Do(func() {
|
||||||
file_kmsapi_proto_rawDescData = protoimpl.X.CompressGZIP(file_kmsapi_proto_rawDescData)
|
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_kms_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||||
var file_kmsapi_proto_goTypes = []interface{}{
|
var file_kms_proto_goTypes = []interface{}{
|
||||||
(*GetDataKeyRequest)(nil), // 0: kmsapi.GetDataKeyRequest
|
(*GetDataKeyRequest)(nil), // 0: kms.GetDataKeyRequest
|
||||||
(*GetDataKeyResponse)(nil), // 1: kmsapi.GetDataKeyResponse
|
(*GetDataKeyResponse)(nil), // 1: kms.GetDataKeyResponse
|
||||||
}
|
}
|
||||||
var file_kmsapi_proto_depIdxs = []int32{
|
var file_kms_proto_depIdxs = []int32{
|
||||||
0, // 0: kmsapi.API.GetDataKey:input_type -> kmsapi.GetDataKeyRequest
|
0, // 0: kms.API.GetDataKey:input_type -> kms.GetDataKeyRequest
|
||||||
1, // 1: kmsapi.API.GetDataKey:output_type -> kmsapi.GetDataKeyResponse
|
1, // 1: kms.API.GetDataKey:output_type -> kms.GetDataKeyResponse
|
||||||
1, // [1:2] is the sub-list for method output_type
|
1, // [1:2] is the sub-list for method output_type
|
||||||
0, // [0:1] is the sub-list for method input_type
|
0, // [0:1] is the sub-list for method input_type
|
||||||
0, // [0:0] is the sub-list for extension type_name
|
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
|
0, // [0:0] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_kmsapi_proto_init() }
|
func init() { file_kms_proto_init() }
|
||||||
func file_kmsapi_proto_init() {
|
func file_kms_proto_init() {
|
||||||
if File_kmsapi_proto != nil {
|
if File_kms_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !protoimpl.UnsafeEnabled {
|
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 {
|
switch v := v.(*GetDataKeyRequest); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@ -191,7 +190,7 @@ func file_kmsapi_proto_init() {
|
|||||||
return nil
|
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 {
|
switch v := v.(*GetDataKeyResponse); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@ -208,18 +207,18 @@ func file_kmsapi_proto_init() {
|
|||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_kmsapi_proto_rawDesc,
|
RawDescriptor: file_kms_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 2,
|
NumMessages: 2,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
GoTypes: file_kmsapi_proto_goTypes,
|
GoTypes: file_kms_proto_goTypes,
|
||||||
DependencyIndexes: file_kmsapi_proto_depIdxs,
|
DependencyIndexes: file_kms_proto_depIdxs,
|
||||||
MessageInfos: file_kmsapi_proto_msgTypes,
|
MessageInfos: file_kms_proto_msgTypes,
|
||||||
}.Build()
|
}.Build()
|
||||||
File_kmsapi_proto = out.File
|
File_kms_proto = out.File
|
||||||
file_kmsapi_proto_rawDesc = nil
|
file_kms_proto_rawDesc = nil
|
||||||
file_kmsapi_proto_goTypes = nil
|
file_kms_proto_goTypes = nil
|
||||||
file_kmsapi_proto_depIdxs = nil
|
file_kms_proto_depIdxs = nil
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
syntax = "proto3";
|
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 {
|
service API {
|
||||||
rpc GetDataKey(GetDataKeyRequest) returns (GetDataKeyResponse);
|
rpc GetDataKey(GetDataKeyRequest) returns (GetDataKeyResponse);
|
@ -2,7 +2,7 @@
|
|||||||
// versions:
|
// versions:
|
||||||
// - protoc-gen-go-grpc v1.2.0
|
// - protoc-gen-go-grpc v1.2.0
|
||||||
// - protoc v3.20.1
|
// - protoc v3.20.1
|
||||||
// source: kmsapi.proto
|
// source: kms.proto
|
||||||
|
|
||||||
package kmsproto
|
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) {
|
func (c *aPIClient) GetDataKey(ctx context.Context, in *GetDataKeyRequest, opts ...grpc.CallOption) (*GetDataKeyResponse, error) {
|
||||||
out := new(GetDataKeyResponse)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ func _API_GetDataKey_Handler(srv interface{}, ctx context.Context, dec func(inte
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: "/kmsapi.API/GetDataKey",
|
FullMethod: "/kms.API/GetDataKey",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(APIServer).GetDataKey(ctx, req.(*GetDataKeyRequest))
|
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,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
var API_ServiceDesc = grpc.ServiceDesc{
|
var API_ServiceDesc = grpc.ServiceDesc{
|
||||||
ServiceName: "kmsapi.API",
|
ServiceName: "kms.API",
|
||||||
HandlerType: (*APIServer)(nil),
|
HandlerType: (*APIServer)(nil),
|
||||||
Methods: []grpc.MethodDesc{
|
Methods: []grpc.MethodDesc{
|
||||||
{
|
{
|
||||||
@ -101,5 +101,5 @@ var API_ServiceDesc = grpc.ServiceDesc{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{},
|
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"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/kms/internal/storage"
|
||||||
"github.com/edgelesssys/constellation/kms/kms"
|
"github.com/edgelesssys/constellation/kms/kms"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/aws"
|
"github.com/edgelesssys/constellation/kms/kms/aws"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/azure"
|
"github.com/edgelesssys/constellation/kms/kms/azure"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/cluster"
|
"github.com/edgelesssys/constellation/kms/kms/cluster"
|
||||||
"github.com/edgelesssys/constellation/kms/kms/gcp"
|
"github.com/edgelesssys/constellation/kms/kms/gcp"
|
||||||
"github.com/edgelesssys/constellation/kms/storage"
|
|
||||||
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
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
|
## key management
|
||||||
WORKDIR /kms
|
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
|
RUN protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative *.proto
|
||||||
|
|
||||||
## activation
|
## activation
|
||||||
@ -64,6 +64,6 @@ COPY --from=build /pubapi/*.go coordinator/pubapi/pubproto/
|
|||||||
COPY --from=build /vpnapi/*.go coordinator/vpnapi/vpnproto/
|
COPY --from=build /vpnapi/*.go coordinator/vpnapi/vpnproto/
|
||||||
COPY --from=build /disk-mapper/*.go state/keyservice/keyproto/
|
COPY --from=build /disk-mapper/*.go state/keyservice/keyproto/
|
||||||
COPY --from=build /service/*.go debugd/service/
|
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 /activation/*.go activation/activationproto/
|
||||||
COPY --from=build /verify/*.go verify/verifyproto/
|
COPY --from=build /verify/*.go verify/verifyproto/
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/edgelesssys/constellation/internal/atls"
|
"github.com/edgelesssys/constellation/internal/atls"
|
||||||
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
"github.com/edgelesssys/constellation/internal/grpc/atlscredentials"
|
||||||
"github.com/edgelesssys/constellation/internal/oid"
|
"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/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/goleak"
|
"go.uber.org/goleak"
|
||||||
|
Loading…
Reference in New Issue
Block a user