mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-14 06:15:45 +00:00
refactor envelope to use cryptobytes
This commit is contained in:
parent
0787715978
commit
36ab52b428
8
staging/src/k8s.io/apiserver/Godeps/Godeps.json
generated
8
staging/src/k8s.io/apiserver/Godeps/Godeps.json
generated
@ -626,6 +626,14 @@
|
|||||||
"ImportPath": "golang.org/x/crypto/blowfish",
|
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||||
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/crypto/cryptobyte",
|
||||||
|
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/crypto/cryptobyte/asn1",
|
||||||
|
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "golang.org/x/crypto/ed25519",
|
"ImportPath": "golang.org/x/crypto/ed25519",
|
||||||
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||||
|
@ -19,6 +19,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||||
|
"//vendor/golang.org/x/crypto/cryptobyte:go_default_library",
|
||||||
"//vendor/google.golang.org/grpc:go_default_library",
|
"//vendor/google.golang.org/grpc:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -22,13 +22,13 @@ import (
|
|||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/storage/value"
|
"k8s.io/apiserver/pkg/storage/value"
|
||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
"golang.org/x/crypto/cryptobyte"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultCacheSize is the number of decrypted DEKs which would be cached by the transformer.
|
// defaultCacheSize is the number of decrypted DEKs which would be cached by the transformer.
|
||||||
@ -80,12 +80,13 @@ func (t *envelopeTransformer) TransformFromStorage(data []byte, context value.Co
|
|||||||
// Read the 16 bit length-of-DEK encoded at the start of the encrypted DEK. 16 bits can
|
// Read the 16 bit length-of-DEK encoded at the start of the encrypted DEK. 16 bits can
|
||||||
// represent a maximum key length of 65536 bytes. We are using a 256 bit key, whose
|
// represent a maximum key length of 65536 bytes. We are using a 256 bit key, whose
|
||||||
// length cannot fit in 8 bits (1 byte). Thus, we use 16 bits (2 bytes) to store the length.
|
// length cannot fit in 8 bits (1 byte). Thus, we use 16 bits (2 bytes) to store the length.
|
||||||
keyLen := int(binary.BigEndian.Uint16(data[:2]))
|
var encKey cryptobyte.String
|
||||||
if keyLen+2 > len(data) {
|
s := cryptobyte.String(data)
|
||||||
return nil, false, fmt.Errorf("invalid data encountered by envelope transformer, length longer than available bytes: %q", data)
|
if ok := s.ReadUint16LengthPrefixed(&encKey); !ok {
|
||||||
|
return nil, false, fmt.Errorf("invalid data encountered by envelope transformer: failed to read uint16 length prefixed data")
|
||||||
}
|
}
|
||||||
encKey := data[2 : keyLen+2]
|
|
||||||
encData := data[2+keyLen:]
|
encData := []byte(s)
|
||||||
|
|
||||||
// Look up the decrypted DEK from cache or Envelope.
|
// Look up the decrypted DEK from cache or Envelope.
|
||||||
transformer := t.getTransformer(encKey)
|
transformer := t.getTransformer(encKey)
|
||||||
@ -120,21 +121,18 @@ func (t *envelopeTransformer) TransformToStorage(data []byte, context value.Cont
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the length of the encrypted DEK as the first 2 bytes.
|
|
||||||
encKeyLen := make([]byte, 2)
|
|
||||||
encKeyBytes := []byte(encKey)
|
|
||||||
binary.BigEndian.PutUint16(encKeyLen, uint16(len(encKeyBytes)))
|
|
||||||
|
|
||||||
prefix := append(encKeyLen, encKeyBytes...)
|
|
||||||
|
|
||||||
prefixedData := make([]byte, len(prefix), len(data)+len(prefix))
|
|
||||||
copy(prefixedData, prefix)
|
|
||||||
result, err := transformer.TransformToStorage(data, context)
|
result, err := transformer.TransformToStorage(data, context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
prefixedData = append(prefixedData, result...)
|
// Append the length of the encrypted DEK as the first 2 bytes.
|
||||||
return prefixedData, nil
|
b := cryptobyte.NewBuilder(nil)
|
||||||
|
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
|
||||||
|
b.AddBytes([]byte(encKey))
|
||||||
|
})
|
||||||
|
b.AddBytes(result)
|
||||||
|
|
||||||
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ value.Transformer = &envelopeTransformer{}
|
var _ value.Transformer = &envelopeTransformer{}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -201,3 +202,70 @@ func benchmarkRead(b *testing.B, transformer value.Transformer, valueLength int)
|
|||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove after 1.13
|
||||||
|
func TestBackwardsCompatibility(t *testing.T) {
|
||||||
|
envelopeService := newTestEnvelopeService()
|
||||||
|
envelopeTransformerInst, err := NewEnvelopeTransformer(envelopeService, testEnvelopeCacheSize, aestransformer.NewCBCTransformer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to initialize envelope transformer: %v", err)
|
||||||
|
}
|
||||||
|
context := value.DefaultContext([]byte(testContextText))
|
||||||
|
originalText := []byte(testText)
|
||||||
|
|
||||||
|
transformedData, err := oldTransformToStorage(envelopeTransformerInst.(*envelopeTransformer), originalText, context)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("envelopeTransformer: error while transforming data to storage: %s", err)
|
||||||
|
}
|
||||||
|
untransformedData, _, err := envelopeTransformerInst.TransformFromStorage(transformedData, context)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not decrypt Envelope transformer's encrypted data even once: %v", err)
|
||||||
|
}
|
||||||
|
if bytes.Compare(untransformedData, originalText) != 0 {
|
||||||
|
t.Fatalf("envelopeTransformer transformed data incorrectly. Expected: %v, got %v", originalText, untransformedData)
|
||||||
|
}
|
||||||
|
|
||||||
|
envelopeService.SetDisabledStatus(true)
|
||||||
|
// Subsequent read for the same data should work fine due to caching.
|
||||||
|
untransformedData, _, err = envelopeTransformerInst.TransformFromStorage(transformedData, context)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not decrypt Envelope transformer's encrypted data using just cache: %v", err)
|
||||||
|
}
|
||||||
|
if bytes.Compare(untransformedData, originalText) != 0 {
|
||||||
|
t.Fatalf("envelopeTransformer transformed data incorrectly using cache. Expected: %v, got %v", originalText, untransformedData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove after 1.13
|
||||||
|
func oldTransformToStorage(t *envelopeTransformer, data []byte, context value.Context) ([]byte, error) {
|
||||||
|
newKey, err := generateKey(32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
encKey, err := t.envelopeService.Encrypt(newKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
transformer, err := t.addTransformer(encKey, newKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the length of the encrypted DEK as the first 2 bytes.
|
||||||
|
encKeyLen := make([]byte, 2)
|
||||||
|
encKeyBytes := []byte(encKey)
|
||||||
|
binary.BigEndian.PutUint16(encKeyLen, uint16(len(encKeyBytes)))
|
||||||
|
|
||||||
|
prefix := append(encKeyLen, encKeyBytes...)
|
||||||
|
|
||||||
|
prefixedData := make([]byte, len(prefix), len(data)+len(prefix))
|
||||||
|
copy(prefixedData, prefix)
|
||||||
|
result, err := transformer.TransformToStorage(data, context)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
prefixedData = append(prefixedData, result...)
|
||||||
|
return prefixedData, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user