mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 02:41:25 +00:00
Merge pull request #116877 from enj/enj/i/validate_encrypt_resp_early
kmsv2: validate encrypt response at DEK generation time
This commit is contained in:
commit
f393e7da7f
@ -84,6 +84,7 @@ type testKMSv2EnvelopeService struct {
|
|||||||
err error
|
err error
|
||||||
keyID string
|
keyID string
|
||||||
encryptCalls int
|
encryptCalls int
|
||||||
|
encryptAnnotations map[string][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testKMSv2EnvelopeService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) {
|
func (t *testKMSv2EnvelopeService) Decrypt(ctx context.Context, uid string, req *kmsservice.DecryptRequest) ([]byte, error) {
|
||||||
@ -101,6 +102,7 @@ func (t *testKMSv2EnvelopeService) Encrypt(ctx context.Context, uid string, data
|
|||||||
return &kmsservice.EncryptResponse{
|
return &kmsservice.EncryptResponse{
|
||||||
Ciphertext: []byte(base64.StdEncoding.EncodeToString(data)),
|
Ciphertext: []byte(base64.StdEncoding.EncodeToString(data)),
|
||||||
KeyID: t.keyID,
|
KeyID: t.keyID,
|
||||||
|
Annotations: t.encryptAnnotations,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,17 +125,17 @@ func newMockErrorEnvelopeService(endpoint string, timeout time.Duration) (envelo
|
|||||||
|
|
||||||
// The factory method to create mock envelope kmsv2 service.
|
// The factory method to create mock envelope kmsv2 service.
|
||||||
func newMockEnvelopeKMSv2Service(ctx context.Context, endpoint, providerName string, timeout time.Duration) (kmsservice.Service, error) {
|
func newMockEnvelopeKMSv2Service(ctx context.Context, endpoint, providerName string, timeout time.Duration) (kmsservice.Service, error) {
|
||||||
return &testKMSv2EnvelopeService{nil, "1", 0}, nil
|
return &testKMSv2EnvelopeService{nil, "1", 0, nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The factory method to create mock envelope kmsv2 service which always returns error.
|
// The factory method to create mock envelope kmsv2 service which always returns error.
|
||||||
func newMockErrorEnvelopeKMSv2Service(endpoint string, timeout time.Duration) (kmsservice.Service, error) {
|
func newMockErrorEnvelopeKMSv2Service(endpoint string, timeout time.Duration) (kmsservice.Service, error) {
|
||||||
return &testKMSv2EnvelopeService{errors.New("test"), "1", 0}, nil
|
return &testKMSv2EnvelopeService{errors.New("test"), "1", 0, nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The factory method to create mock envelope kmsv2 service that always returns invalid keyID.
|
// The factory method to create mock envelope kmsv2 service that always returns invalid keyID.
|
||||||
func newMockInvalidKeyIDEnvelopeKMSv2Service(ctx context.Context, endpoint string, timeout time.Duration, keyID string) (kmsservice.Service, error) {
|
func newMockInvalidKeyIDEnvelopeKMSv2Service(ctx context.Context, endpoint string, timeout time.Duration, keyID string) (kmsservice.Service, error) {
|
||||||
return &testKMSv2EnvelopeService{nil, keyID, 0}, nil
|
return &testKMSv2EnvelopeService{nil, keyID, 0, nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLegacyConfig(t *testing.T) {
|
func TestLegacyConfig(t *testing.T) {
|
||||||
@ -1758,6 +1760,39 @@ func Test_kmsv2PluginProbe_rotateDEKOnKeyIDChange(t *testing.T) {
|
|||||||
`errState=<nil>, errGen=failed to encrypt DEK, error: broken, statusKeyID="5", ` +
|
`errState=<nil>, errGen=failed to encrypt DEK, error: broken, statusKeyID="5", ` +
|
||||||
`encryptKeyID="", stateKeyID="4", expirationTimestamp=` + now.Add(7*time.Minute).Format(time.RFC3339),
|
`encryptKeyID="", stateKeyID="4", expirationTimestamp=` + now.Add(7*time.Minute).Format(time.RFC3339),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid service response, no previous state",
|
||||||
|
service: &testKMSv2EnvelopeService{keyID: "1", encryptAnnotations: map[string][]byte{"panda": nil}},
|
||||||
|
state: envelopekmsv2.State{},
|
||||||
|
statusKeyID: "1",
|
||||||
|
wantState: envelopekmsv2.State{},
|
||||||
|
wantEncryptCalls: 1,
|
||||||
|
wantLogs: []string{
|
||||||
|
`"encrypting content using envelope service" uid="panda"`,
|
||||||
|
},
|
||||||
|
wantErr: `failed to rotate DEK uid="panda", ` +
|
||||||
|
`errState=got unexpected nil transformer, errGen=failed to validate annotations: annotations: Invalid value: "panda": ` +
|
||||||
|
`should be a domain with at least two segments separated by dots, statusKeyID="1", ` +
|
||||||
|
`encryptKeyID="", stateKeyID="", expirationTimestamp=` + (time.Time{}).Format(time.RFC3339),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid service response, with previous state",
|
||||||
|
service: &testKMSv2EnvelopeService{keyID: "3", encryptAnnotations: map[string][]byte{"panda": nil}},
|
||||||
|
state: validState("2", now),
|
||||||
|
statusKeyID: "3",
|
||||||
|
wantState: envelopekmsv2.State{
|
||||||
|
KeyID: "2",
|
||||||
|
ExpirationTimestamp: now,
|
||||||
|
},
|
||||||
|
wantEncryptCalls: 1,
|
||||||
|
wantLogs: []string{
|
||||||
|
`"encrypting content using envelope service" uid="panda"`,
|
||||||
|
},
|
||||||
|
wantErr: `failed to rotate DEK uid="panda", ` +
|
||||||
|
`errState=<nil>, errGen=failed to validate annotations: annotations: Invalid value: "panda": ` +
|
||||||
|
`should be a domain with at least two segments separated by dots, statusKeyID="3", ` +
|
||||||
|
`encryptKeyID="", stateKeyID="2", expirationTimestamp=` + now.Format(time.RFC3339),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@ -278,6 +278,15 @@ func GenerateTransformer(ctx context.Context, uid string, envelopeService kmsser
|
|||||||
return nil, nil, nil, fmt.Errorf("failed to encrypt DEK, error: %w", err)
|
return nil, nil, nil, fmt.Errorf("failed to encrypt DEK, error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := validateEncryptedObject(&kmstypes.EncryptedObject{
|
||||||
|
KeyID: resp.KeyID,
|
||||||
|
EncryptedDEK: resp.Ciphertext,
|
||||||
|
EncryptedData: []byte{0}, // any non-empty value to pass validation
|
||||||
|
Annotations: resp.Annotations,
|
||||||
|
}); err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
cacheKey, err := generateCacheKey(resp.Ciphertext, resp.KeyID, resp.Annotations)
|
cacheKey, err := generateCacheKey(resp.Ciphertext, resp.KeyID, resp.Annotations)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
Loading…
Reference in New Issue
Block a user