Merge pull request #69249 from mikedanese/cpenvelope

refactor envelope to use cryptobytes
pull/58/head
k8s-ci-robot 2018-10-03 04:44:08 -07:00 committed by GitHub
commit 643cad5187
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 17 deletions

View File

@ -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"

View File

@ -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",
],
)

View File

@ -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{}

View File

@ -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
}