Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
13073407
Unverified
Commit
13073407
authored
Jun 06, 2017
by
Saksham Sharma
Committed by
Clayton Coleman
Jun 07, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add configuration for AESCBC, Secretbox encryption
Add tests for new transformers
parent
395399ab
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
220 additions
and
53 deletions
+220
-53
BUILD
...8s.io/apiserver/pkg/server/options/encryptionconfig/BUILD
+1
-0
config.go
...o/apiserver/pkg/server/options/encryptionconfig/config.go
+94
-12
encryptionconfig_test.go
.../server/options/encryptionconfig/encryptionconfig_test.go
+113
-39
types.go
...io/apiserver/pkg/server/options/encryptionconfig/types.go
+12
-2
No files found.
staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/BUILD
View file @
13073407
...
...
@@ -21,6 +21,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/storage/value:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/value/encrypt/aes:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/value/encrypt/identity:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/value/encrypt/secretbox:go_default_library",
],
)
...
...
staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/config.go
View file @
13073407
...
...
@@ -18,6 +18,7 @@ package encryptionconfig
import
(
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
"io"
...
...
@@ -30,10 +31,13 @@ import (
"k8s.io/apiserver/pkg/storage/value"
aestransformer
"k8s.io/apiserver/pkg/storage/value/encrypt/aes"
"k8s.io/apiserver/pkg/storage/value/encrypt/identity"
"k8s.io/apiserver/pkg/storage/value/encrypt/secretbox"
)
const
(
aesTransformerPrefixV1
=
"k8s:enc:aes:v1:"
aesCBCTransformerPrefixV1
=
"k8s:enc:aescbc:v1:"
aesGCMTransformerPrefixV1
=
"k8s:enc:aesgcm:v1:"
secretboxTransformerPrefixV1
=
"k8s:enc:secretbox:v1"
)
// GetTransformerOverrides returns the transformer overrides by reading and parsing the encryption provider configuration file
...
...
@@ -102,25 +106,48 @@ func GetPrefixTransformers(config *ResourceConfig) ([]value.PrefixTransformer, e
for
_
,
provider
:=
range
config
.
Providers
{
found
:=
false
if
provider
.
AES
!=
nil
{
transformer
,
err
:=
GetAESPrefixTransformer
(
provider
.
AES
)
found
=
true
var
transformer
value
.
PrefixTransformer
var
err
error
if
provider
.
AESGCM
!=
nil
{
transformer
,
err
=
GetAESPrefixTransformer
(
provider
.
AESGCM
,
aestransformer
.
NewGCMTransformer
,
aesGCMTransformerPrefixV1
)
if
err
!=
nil
{
return
result
,
err
}
result
=
append
(
result
,
transformer
)
found
=
true
}
if
provider
.
Identity
!=
nil
{
if
provider
.
AESCBC
!=
nil
{
if
found
==
true
{
return
result
,
fmt
.
Errorf
(
"more than one provider specified in a single element, should split into different list elements"
)
}
transformer
,
err
=
GetAESPrefixTransformer
(
provider
.
AESCBC
,
aestransformer
.
NewCBCTransformer
,
aesCBCTransformerPrefixV1
)
found
=
true
}
if
provider
.
Secretbox
!=
nil
{
if
found
==
true
{
return
result
,
fmt
.
Errorf
(
"more than one provider specified in a single element, should split into different list elements"
)
}
transformer
,
err
=
GetSecretboxPrefixTransformer
(
provider
.
Secretbox
)
found
=
true
result
=
append
(
result
,
value
.
PrefixTransformer
{
}
if
provider
.
Identity
!=
nil
{
if
found
==
true
{
return
result
,
fmt
.
Errorf
(
"more than one provider specified in a single element, should split into different list elements"
)
}
transformer
=
value
.
PrefixTransformer
{
Transformer
:
identity
.
NewEncryptCheckTransformer
(),
Prefix
:
[]
byte
{},
})
}
found
=
true
}
if
err
!=
nil
{
return
result
,
err
}
result
=
append
(
result
,
transformer
)
if
found
==
false
{
return
result
,
fmt
.
Errorf
(
"invalid provider configuration provided"
)
...
...
@@ -129,8 +156,12 @@ func GetPrefixTransformers(config *ResourceConfig) ([]value.PrefixTransformer, e
return
result
,
nil
}
// GetAESPrefixTransformer returns a prefix transformer from the provided configuration
func
GetAESPrefixTransformer
(
config
*
AESConfig
)
(
value
.
PrefixTransformer
,
error
)
{
// BlockTransformerFunc taske an AES cipher block and returns a value transformer.
type
BlockTransformerFunc
func
(
cipher
.
Block
)
value
.
Transformer
// GetAESPrefixTransformer returns a prefix transformer from the provided configuration.
// Returns an AES transformer based on the provided prefix and block transformer.
func
GetAESPrefixTransformer
(
config
*
AESConfig
,
fn
BlockTransformerFunc
,
prefix
string
)
(
value
.
PrefixTransformer
,
error
)
{
var
result
value
.
PrefixTransformer
if
len
(
config
.
Keys
)
==
0
{
...
...
@@ -160,7 +191,7 @@ func GetAESPrefixTransformer(config *AESConfig) (value.PrefixTransformer, error)
// Create a new PrefixTransformer for this key
keyTransformers
=
append
(
keyTransformers
,
value
.
PrefixTransformer
{
Transformer
:
aestransformer
.
NewGCMTransformer
(
block
),
Transformer
:
fn
(
block
),
Prefix
:
[]
byte
(
keyData
.
Name
+
":"
),
})
}
...
...
@@ -172,7 +203,58 @@ func GetAESPrefixTransformer(config *AESConfig) (value.PrefixTransformer, error)
// Create a PrefixTransformer which shall later be put in a list with other providers
result
=
value
.
PrefixTransformer
{
Transformer
:
keyTransformer
,
Prefix
:
[]
byte
(
aesTransformerPrefixV1
),
Prefix
:
[]
byte
(
prefix
),
}
return
result
,
nil
}
// GetSecretboxPrefixTransformer returns a prefix transformer from the provided configuration
func
GetSecretboxPrefixTransformer
(
config
*
SecretboxConfig
)
(
value
.
PrefixTransformer
,
error
)
{
var
result
value
.
PrefixTransformer
if
len
(
config
.
Keys
)
==
0
{
return
result
,
fmt
.
Errorf
(
"secretbox provider has no valid keys"
)
}
for
_
,
key
:=
range
config
.
Keys
{
if
key
.
Name
==
""
{
return
result
,
fmt
.
Errorf
(
"key with invalid name provided"
)
}
if
key
.
Secret
==
""
{
return
result
,
fmt
.
Errorf
(
"key %v has no provided secret"
,
key
.
Name
)
}
}
keyTransformers
:=
[]
value
.
PrefixTransformer
{}
for
_
,
keyData
:=
range
config
.
Keys
{
key
,
err
:=
base64
.
StdEncoding
.
DecodeString
(
keyData
.
Secret
)
if
err
!=
nil
{
return
result
,
fmt
.
Errorf
(
"could not obtain secret for named key %s: %s"
,
keyData
.
Name
,
err
)
}
if
len
(
key
)
!=
32
{
return
result
,
fmt
.
Errorf
(
"expected key size 32 for aes-cbc provider, got %v"
,
len
(
key
))
}
keyArray
:=
[
32
]
byte
{}
copy
(
keyArray
[
:
],
key
)
// Create a new PrefixTransformer for this key
keyTransformers
=
append
(
keyTransformers
,
value
.
PrefixTransformer
{
Transformer
:
secretbox
.
NewSecretboxTransformer
(
keyArray
),
Prefix
:
[]
byte
(
keyData
.
Name
+
":"
),
})
}
// Create a prefixTransformer which can choose between these keys
keyTransformer
:=
value
.
NewPrefixTransformers
(
fmt
.
Errorf
(
"no matching key was found for the provided Secretbox transformer"
),
keyTransformers
...
)
// Create a PrefixTransformer which shall later be put in a list with other providers
result
=
value
.
PrefixTransformer
{
Transformer
:
keyTransformer
,
Prefix
:
[]
byte
(
secretboxTransformerPrefixV1
),
}
return
result
,
nil
}
staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/encryptionconfig_test.go
View file @
13073407
...
...
@@ -39,22 +39,42 @@ resources:
- namespaces
providers:
- identity: {}
- aes:
- aes
gcm
:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
`
correctConfigWithAesFirst
=
`
correctConfigWithAes
Gcm
First
=
`
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- aes:
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
...
...
@@ -63,6 +83,58 @@ resources:
- identity: {}
`
correctConfigWithAesCbcFirst
=
`
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- identity: {}
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
`
correctConfigWithSecretboxFirst
=
`
kind: EncryptionConfig
apiVersion: v1
resources:
- resources:
- secrets
providers:
- secretbox:
keys:
- name: key1
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
- aescbc:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
- identity: {}
- aesgcm:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
- name: key2
secret: dGhpcyBpcyBwYXNzd29yZA==
`
incorrectConfigNoSecretForKey
=
`
kind: EncryptionConfig
apiVersion: v1
...
...
@@ -71,7 +143,7 @@ resources:
- namespaces
- secrets
providers:
- aes:
- aes
gcm
:
keys:
- name: key1
`
...
...
@@ -84,7 +156,7 @@ resources:
- namespaces
- secrets
providers:
- aes:
- aes
gcm
:
keys:
- name: key1
secret: c2VjcmV0IGlzIHNlY3VyZQ==
...
...
@@ -103,58 +175,60 @@ func TestEncryptionProviderConfigCorrect(t *testing.T) {
t
.
Fatalf
(
"error while parsing configuration file: %s.
\n
The file was:
\n
%s"
,
err
,
correctConfigWithIdentityFirst
)
}
aes
FirstTransformerOverrides
,
err
:=
ParseEncryptionConfiguration
(
strings
.
NewReader
(
correctConfigWithAes
First
))
aes
GcmFirstTransformerOverrides
,
err
:=
ParseEncryptionConfiguration
(
strings
.
NewReader
(
correctConfigWithAesGcm
First
))
if
err
!=
nil
{
t
.
Fatalf
(
"error while parsing configuration file: %s.
\n
The file was:
\n
%s"
,
err
,
correctConfigWithAesFirst
)
t
.
Fatalf
(
"error while parsing configuration file: %s.
\n
The file was:
\n
%s"
,
err
,
correctConfigWithAesGcmFirst
)
}
aesCbcFirstTransformerOverrides
,
err
:=
ParseEncryptionConfiguration
(
strings
.
NewReader
(
correctConfigWithAesCbcFirst
))
if
err
!=
nil
{
t
.
Fatalf
(
"error while parsing configuration file: %s.
\n
The file was:
\n
%s"
,
err
,
correctConfigWithAesCbcFirst
)
}
secretboxFirstTransformerOverrides
,
err
:=
ParseEncryptionConfiguration
(
strings
.
NewReader
(
correctConfigWithSecretboxFirst
))
if
err
!=
nil
{
t
.
Fatalf
(
"error while parsing configuration file: %s.
\n
The file was:
\n
%s"
,
err
,
correctConfigWithSecretboxFirst
)
}
// Pick the transformer for any of the returned resources.
identityFirstTransformer
:=
identityFirstTransformerOverrides
[
schema
.
ParseGroupResource
(
"secrets"
)]
aesFirstTransformer
:=
aesFirstTransformerOverrides
[
schema
.
ParseGroupResource
(
"secrets"
)]
aesGcmFirstTransformer
:=
aesGcmFirstTransformerOverrides
[
schema
.
ParseGroupResource
(
"secrets"
)]
aesCbcFirstTransformer
:=
aesCbcFirstTransformerOverrides
[
schema
.
ParseGroupResource
(
"secrets"
)]
secretboxFirstTransformer
:=
secretboxFirstTransformerOverrides
[
schema
.
ParseGroupResource
(
"secrets"
)]
context
:=
value
.
DefaultContext
([]
byte
(
sampleContextText
))
originalText
:=
[]
byte
(
sampleText
)
testCases
:=
[]
struct
{
WritingTransformer
value
.
Transformer
Name
string
AesStale
bool
IdentityStale
bool
transformers
:=
[]
struct
{
Transformer
value
.
Transformer
Name
string
}{
{
aesFirstTransformer
,
"aesFirst"
,
false
,
true
},
{
identityFirstTransformer
,
"identityFirst"
,
true
,
false
},
{
aesGcmFirstTransformer
,
"aesGcmFirst"
},
{
aesCbcFirstTransformer
,
"aesCbcFirst"
},
{
secretboxFirstTransformer
,
"secretboxFirst"
},
{
identityFirstTransformer
,
"identityFirst"
},
}
for
_
,
testCase
:=
range
t
estCase
s
{
transformedData
,
err
:=
testCase
.
Writing
Transformer
.
TransformToStorage
(
originalText
,
context
)
for
_
,
testCase
:=
range
t
ransformer
s
{
transformedData
,
err
:=
testCase
.
Transformer
.
TransformToStorage
(
originalText
,
context
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: error while transforming data to storage: %s"
,
testCase
.
Name
,
err
)
}
aesUntransformedData
,
stale
,
err
:=
aesFirstTransformer
.
TransformFromStorage
(
transformedData
,
context
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: error while reading using aesFirst transformer: %s"
,
testCase
.
Name
,
err
)
}
if
stale
!=
testCase
.
AesStale
{
t
.
Fatalf
(
"%s: wrong stale information on reading using aesFirst transformer, should be %v"
,
testCase
.
Name
,
testCase
.
AesStale
)
}
identityUntransformedData
,
stale
,
err
:=
identityFirstTransformer
.
TransformFromStorage
(
transformedData
,
context
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: error while reading using identityFirst transformer: %s"
,
testCase
.
Name
,
err
)
}
if
stale
!=
testCase
.
IdentityStale
{
t
.
Fatalf
(
"%s: wrong stale information on reading using identityFirst transformer, should be %v"
,
testCase
.
Name
,
testCase
.
IdentityStale
)
}
if
bytes
.
Compare
(
aesUntransformedData
,
originalText
)
!=
0
{
t
.
Fatalf
(
"%s: aesFirst transformer transformed data incorrectly. Expected: %v, got %v"
,
testCase
.
Name
,
originalText
,
aesUntransformedData
)
}
if
bytes
.
Compare
(
identityUntransformedData
,
originalText
)
!=
0
{
t
.
Fatalf
(
"%s: identityFirst transformer transformed data incorrectly. Expected: %v, got %v"
,
testCase
.
Name
,
originalText
,
aesUntransformedData
)
for
_
,
transformer
:=
range
transformers
{
untransformedData
,
stale
,
err
:=
transformer
.
Transformer
.
TransformFromStorage
(
transformedData
,
context
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: error while reading using %s transformer: %s"
,
testCase
.
Name
,
transformer
.
Name
,
err
)
}
if
stale
!=
(
transformer
.
Name
!=
testCase
.
Name
)
{
t
.
Fatalf
(
"%s: wrong stale information on reading using %s transformer, should be %v"
,
testCase
.
Name
,
transformer
.
Name
,
testCase
.
Name
==
transformer
.
Name
)
}
if
bytes
.
Compare
(
untransformedData
,
originalText
)
!=
0
{
t
.
Fatalf
(
"%s: %s transformer transformed data incorrectly. Expected: %v, got %v"
,
testCase
.
Name
,
transformer
.
Name
,
originalText
,
untransformedData
)
}
}
}
}
// Throw error if key has no secret
...
...
staging/src/k8s.io/apiserver/pkg/server/options/encryptionconfig/types.go
View file @
13073407
...
...
@@ -37,8 +37,12 @@ type ResourceConfig struct {
// ProviderConfig stores the provided configuration for an encryption provider.
type
ProviderConfig
struct
{
// aes is the configuration for the AEAD-GCM transformer.
AES
*
AESConfig
`json:"aes,omitempty"`
// aesgcm is the configuration for the AES-GCM transformer.
AESGCM
*
AESConfig
`json:"aesgcm,omitempty"`
// aescbc is the configuration for the AES-CBC transformer.
AESCBC
*
AESConfig
`json:"aescbc,omitempty"`
// secretbox is the configuration for the Secretbox based transformer.
Secretbox
*
SecretboxConfig
`json:"secretbox,omitempty"`
// identity is the (empty) configuration for the identity transformer.
Identity
*
IdentityConfig
`json:"identity,omitempty"`
}
...
...
@@ -49,6 +53,12 @@ type AESConfig struct {
Keys
[]
Key
`json:"keys"`
}
// SECRETBOXConfig contains the API configuration for an Secretbox transformer.
type
SecretboxConfig
struct
{
// keys is a list of keys to be used for creating the Secretbox transformer.
Keys
[]
Key
`json:"keys"`
}
// Key contains name and secret of the provided key for AES transformer.
type
Key
struct
{
// name is the name of the key to be used while storing data to disk.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment