From ed1b5a2c5740a3da4f15570b620c35bbab80425a Mon Sep 17 00:00:00 2001 From: Nick Revin Date: Wed, 7 Aug 2019 10:45:19 +0300 Subject: [PATCH] check the input key length for hkdf Signed-off-by: Nick Revin --- README.md | 11 +++++ WORKSPACE | 15 ++----- cmd/cli/BUILD.bazel | 1 + cmd/manager/BUILD.bazel | 3 +- hack/build/test.sh | 2 +- .../xchacha20poly1305/xchacha20poly1305.go | 5 +++ .../xchacha20poly1305_test.go | 40 +++++++++++++++++-- 7 files changed, 59 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index d9d1701..dc349c7 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,12 @@ ## Project status: alpha +### Cryptography API + +Core cryptography API is freezed and is unlikely to be changed. It is open for extension and adding more providers. Thorough independent security audit is badly needed and welcome! + +### Kubernetes API and CLI + The basic features have been completed, and while no breaking API changes are currently planned, the API can change in a backwards incompatible way before the project is declared stable. ## Overview @@ -58,6 +64,10 @@ When used in conjunction with [encrypting Secret Data at Rest][encrypting-secret kubectl apply -f example/k8s_v1alpha1_secretencryptionconfig_cr.yaml ``` +### Getting CLI + +Official Secreter CLI binaries can be found on the [Releases][releases] page. + ### Configuring Secreter The `SecretEncryptionConfig` CRD is used for configuring Secreter. @@ -327,3 +337,4 @@ Providers: [curve25519]: https://godoc.org/github.com/amaizfinance/secreter/pkg/crypto/curve25519 [libsodium-sealed-box]: https://download.libsodium.org/doc/public-key_cryptography/sealed_boxes [nacl-box]: https://nacl.cr.yp.to/box.html +[releases]: https://github.com/amaizfinance/secreter/releases diff --git a/WORKSPACE b/WORKSPACE index 9c05e47..21b403e 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -34,9 +34,9 @@ gazelle_dependencies() # fetch and load rules_docker http_archive( name = "io_bazel_rules_docker", - sha256 = "87fc6a2b128147a0a3039a2fd0b53cc1f2ed5adb8716f50756544a572999ae9a", - strip_prefix = "rules_docker-0.8.1", - urls = ["https://github.com/bazelbuild/rules_docker/archive/v0.8.1.tar.gz"], + sha256 = "e513c0ac6534810eb7a14bf025a0f159726753f97f74ab7863c650d26e01d677", + strip_prefix = "rules_docker-0.9.0", + urls = ["https://github.com/bazelbuild/rules_docker/archive/v0.9.0.tar.gz"], ) load( @@ -52,12 +52,3 @@ load( ) _go_image_repos() - -load("@io_bazel_rules_docker//container:container.bzl", "container_pull") - -container_pull( - name = "distroless_static", - digest = "sha256:9b60270ec0991bc4f14bda475e8cae75594d8197d0ae58576ace84694aa75d7a", - registry = "gcr.io", - repository = "distroless/static", -) diff --git a/cmd/cli/BUILD.bazel b/cmd/cli/BUILD.bazel index 6c415c0..80dac1e 100644 --- a/cmd/cli/BUILD.bazel +++ b/cmd/cli/BUILD.bazel @@ -16,6 +16,7 @@ go_library( go_binary( name = "secreter", embed = [":go_default_library"], + pure = "on", visibility = ["//visibility:public"], ) diff --git a/cmd/manager/BUILD.bazel b/cmd/manager/BUILD.bazel index cd4618b..6ec4ae9 100644 --- a/cmd/manager/BUILD.bazel +++ b/cmd/manager/BUILD.bazel @@ -30,6 +30,7 @@ go_library( go_binary( name = "manager", embed = [":go_default_library"], + pure = "on", visibility = ["//visibility:public"], ) @@ -37,8 +38,8 @@ load("@io_bazel_rules_docker//go:image.bzl", "go_image") go_image( name = "manager_image", - base = "@distroless_static//image", embed = [":go_default_library"], + pure = "on", visibility = ["//visibility:public"], ) diff --git a/hack/build/test.sh b/hack/build/test.sh index c5dbc98..add1411 100755 --- a/hack/build/test.sh +++ b/hack/build/test.sh @@ -5,5 +5,5 @@ set -o nounset set -o pipefail set -x -bazel test //... +bazel test --features=race //... bazel build //... diff --git a/pkg/crypto/xchacha20poly1305/xchacha20poly1305.go b/pkg/crypto/xchacha20poly1305/xchacha20poly1305.go index 0b9e4e2..e8b30bc 100644 --- a/pkg/crypto/xchacha20poly1305/xchacha20poly1305.go +++ b/pkg/crypto/xchacha20poly1305/xchacha20poly1305.go @@ -30,6 +30,7 @@ package xchacha20poly1305 import ( + "errors" "hash" "io" @@ -74,6 +75,10 @@ func Open(key, ciphertext, additionalData []byte) ([]byte, error) { } func deriveKeyAndNonce(inputKeyMaterial, salt []byte) ([]byte, []byte, error) { + if len(inputKeyMaterial) == 0 { + return nil, nil, errors.New("xchacha20poly1305: key cannot be empty") + } + key := make([]byte, chacha20poly1305.KeySize) nonce := make([]byte, chacha20poly1305.NonceSizeX) diff --git a/pkg/crypto/xchacha20poly1305/xchacha20poly1305_test.go b/pkg/crypto/xchacha20poly1305/xchacha20poly1305_test.go index b43abe1..603f049 100644 --- a/pkg/crypto/xchacha20poly1305/xchacha20poly1305_test.go +++ b/pkg/crypto/xchacha20poly1305/xchacha20poly1305_test.go @@ -20,6 +20,7 @@ import ( "encoding/hex" "fmt" "io" + "reflect" "testing" ) @@ -33,7 +34,7 @@ func TestSealOpen(t *testing.T) { want []byte wantErr bool }{ - {name: "empty", want: make([]byte, 0)}, + {name: "empty", wantErr: true}, {name: "bad ciphertext", args: args{ciphertext: []byte("lol")}, wantErr: true}, { name: "random key", @@ -71,7 +72,7 @@ func TestSealOpen(t *testing.T) { return } if !bytes.Equal(got, tt.want) { - t.Errorf("Open() = %v, want %#v", got, tt.want) + t.Errorf("Open() = %v, wantKey %#v", got, tt.want) } }) } @@ -106,7 +107,7 @@ func TestSealOpenDeterministic(t *testing.T) { return } if !bytes.Equal(ciphertext, tt.args.ciphertext) { - t.Errorf("\nSeal():\t%v\nwant\t%v", ciphertext, tt.args.ciphertext) + t.Errorf("\nSeal():\t%v\nwantKey\t%v", ciphertext, tt.args.ciphertext) return } got, err := Open(tt.args.key, tt.args.ciphertext, tt.args.additionalData) @@ -117,7 +118,7 @@ func TestSealOpenDeterministic(t *testing.T) { fmt.Println(tt.args.plaintext) if !bytes.Equal(got, tt.want) { - t.Errorf("Open() = %v, want %#v", got, tt.want) + t.Errorf("Open() = %v, wantKey %#v", got, tt.want) } }) } @@ -151,3 +152,34 @@ func BenchmarkDeriveKeyAndNonce(b *testing.B) { } } } + +func Test_deriveKeyAndNonce(t *testing.T) { + type args struct { + inputKeyMaterial []byte + salt []byte + } + tests := []struct { + name string + args args + wantKey []byte + wantNonce []byte + wantErr bool + }{ + {name: "empty", wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotKey, gotNonce, err := deriveKeyAndNonce(tt.args.inputKeyMaterial, tt.args.salt) + if (err != nil) != tt.wantErr { + t.Errorf("deriveKeyAndNonce() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotKey, tt.wantKey) { + t.Errorf("deriveKeyAndNonce() gotKey = %v, wantKey %v", gotKey, tt.wantKey) + } + if !reflect.DeepEqual(gotNonce, tt.wantNonce) { + t.Errorf("deriveKeyAndNonce() gotNonce = %v, wantNonce %v", gotNonce, tt.wantNonce) + } + }) + } +}