/
server.go
120 lines (105 loc) 路 3.24 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright (c) Microsoft and contributors. All rights reserved.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
package plugin
import (
"context"
"fmt"
"time"
"github.com/Azure/kubernetes-kms/pkg/metrics"
"github.com/Azure/kubernetes-kms/pkg/version"
"github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
kmsv1 "k8s.io/kms/apis/v1beta1"
"monis.app/mlog"
)
// KeyManagementServiceServer is a gRPC server.
type KeyManagementServiceServer struct {
kvClient Client
reporter metrics.StatsReporter
encryptionAlgorithm keyvault.JSONWebKeyEncryptionAlgorithm
}
// Config is the configuration for the KMS plugin.
type Config struct {
ConfigFilePath string
KeyVaultName string
KeyName string
KeyVersion string
ManagedHSM bool
ProxyMode bool
ProxyAddress string
ProxyPort int
}
// NewKMSv1Server creates an instance of the KMS Service Server.
func NewKMSv1Server(kvClient Client) (*KeyManagementServiceServer, error) {
statsReporter, err := metrics.NewStatsReporter()
if err != nil {
return nil, fmt.Errorf("failed to create stats reporter: %w", err)
}
return &KeyManagementServiceServer{
kvClient: kvClient,
reporter: statsReporter,
encryptionAlgorithm: keyvault.RSA15,
}, nil
}
// Version of kms.
func (s *KeyManagementServiceServer) Version(_ context.Context, _ *kmsv1.VersionRequest) (*kmsv1.VersionResponse, error) {
return &kmsv1.VersionResponse{
Version: version.KMSv1APIVersion,
RuntimeName: version.Runtime,
RuntimeVersion: version.BuildVersion,
}, nil
}
// Encrypt message.
func (s *KeyManagementServiceServer) Encrypt(ctx context.Context, request *kmsv1.EncryptRequest) (*kmsv1.EncryptResponse, error) {
start := time.Now()
var err error
defer func() {
errors := ""
status := metrics.SuccessStatusTypeValue
if err != nil {
status = metrics.ErrorStatusTypeValue
errors = err.Error()
}
s.reporter.ReportRequest(ctx, metrics.EncryptOperationTypeValue, status, time.Since(start).Seconds(), errors)
}()
mlog.Info("encrypt request started")
encryptResponse, err := s.kvClient.Encrypt(ctx, request.Plain, s.encryptionAlgorithm)
if err != nil {
mlog.Error("failed to encrypt", err)
return &kmsv1.EncryptResponse{}, err
}
mlog.Info("encrypt request complete")
return &kmsv1.EncryptResponse{
Cipher: encryptResponse.Ciphertext,
}, nil
}
// Decrypt message.
func (s *KeyManagementServiceServer) Decrypt(ctx context.Context, request *kmsv1.DecryptRequest) (*kmsv1.DecryptResponse, error) {
start := time.Now()
var err error
defer func() {
errors := ""
status := metrics.SuccessStatusTypeValue
if err != nil {
status = metrics.ErrorStatusTypeValue
errors = err.Error()
}
s.reporter.ReportRequest(ctx, metrics.DecryptOperationTypeValue, status, time.Since(start).Seconds(), errors)
}()
mlog.Info("decrypt request started")
plain, err := s.kvClient.Decrypt(
ctx,
request.Cipher,
s.encryptionAlgorithm,
request.Version,
nil,
"",
)
if err != nil {
mlog.Error("failed to decrypt", err)
return &kmsv1.DecryptResponse{}, err
}
mlog.Info("decrypt request complete")
return &kmsv1.DecryptResponse{Plain: plain}, nil
}