mirror of https://github.com/k3s-io/k3s
Merge pull request #69249 from mikedanese/cpenvelope
refactor envelope to use cryptobytespull/58/head
commit
643cad5187
|
@ -626,6 +626,14 @@
|
|||
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||
"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",
|
||||
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||
|
|
|
@ -19,6 +19,7 @@ go_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/hashicorp/golang-lru:go_default_library",
|
||||
"//vendor/golang.org/x/crypto/cryptobyte:go_default_library",
|
||||
"//vendor/google.golang.org/grpc:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -22,13 +22,13 @@ import (
|
|||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/apiserver/pkg/storage/value"
|
||||
|
||||
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.
|
||||
|
@ -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
|
||||
// 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.
|
||||
keyLen := int(binary.BigEndian.Uint16(data[:2]))
|
||||
if keyLen+2 > len(data) {
|
||||
return nil, false, fmt.Errorf("invalid data encountered by envelope transformer, length longer than available bytes: %q", data)
|
||||
var encKey cryptobyte.String
|
||||
s := cryptobyte.String(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.
|
||||
transformer := t.getTransformer(encKey)
|
||||
|
@ -120,21 +121,18 @@ func (t *envelopeTransformer) TransformToStorage(data []byte, context value.Cont
|
|||
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
|
||||
// Append the length of the encrypted DEK as the first 2 bytes.
|
||||
b := cryptobyte.NewBuilder(nil)
|
||||
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
|
||||
b.AddBytes([]byte(encKey))
|
||||
})
|
||||
b.AddBytes(result)
|
||||
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
var _ value.Transformer = &envelopeTransformer{}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/aes"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -201,3 +202,70 @@ func benchmarkRead(b *testing.B, transformer value.Transformer, valueLength int)
|
|||
}
|
||||
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