mirror of
https://github.com/go-sigma/sigma.git
synced 2026-10-29 04:05:01 +08:00
Encrypt/Decrypt are AES-CTR without a MAC, so a stored ciphertext can be altered without detection. The only current caller derives a per-build key from the builder and runner IDs, which is fine for the short-lived build environment but cannot be used for values that outlive a process. Add Seal/Open on top of AES-256-GCM (base64(nonce|ciphertext|tag)) next to the existing helpers instead of changing them: the builder image still decrypts the CTR format with crypt.Decrypt. The key is derived with sha256 like Encrypt, so operators only deal with one key convention. Verification: - go test -tags "netgo,timetzdata,exclude_graphdriver_btrfs,containers_image_openpgp" ./pkg/utils/crypt/...
89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
// Copyright 2023 sigma
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package crypt
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSeal(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
plaintext string
|
|
}{
|
|
{name: "common", key: "sigma", plaintext: "sigma"},
|
|
{name: "empty", key: "sigma", plaintext: ""},
|
|
{name: "unicode", key: "sigma", plaintext: "口令-🔐"},
|
|
{name: "long", key: "sigma", plaintext: strings.Repeat("ghp_", 512)},
|
|
{name: "long key", key: strings.Repeat("k", 32), plaintext: "ghp_sigma"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ciphertext, err := Seal(tt.key, tt.plaintext)
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, tt.plaintext, ciphertext)
|
|
|
|
plaintext, err := Open(tt.key, ciphertext)
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.plaintext, plaintext)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSealRandomized(t *testing.T) {
|
|
first, err := Seal("sigma", "ghp_sigma")
|
|
require.NoError(t, err)
|
|
second, err := Seal("sigma", "ghp_sigma")
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, first, second, "seal must use a random nonce")
|
|
}
|
|
|
|
func TestMustSeal(t *testing.T) {
|
|
require.NotPanics(t, func() { MustSeal("sigma", "sigma") })
|
|
}
|
|
|
|
func TestOpenErrors(t *testing.T) {
|
|
ciphertext, err := Seal("sigma", "ghp_sigma")
|
|
require.NoError(t, err)
|
|
|
|
t.Run("wrong key", func(t *testing.T) {
|
|
_, err := Open("another", ciphertext)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("tampered", func(t *testing.T) {
|
|
raw, err := base64.StdEncoding.DecodeString(ciphertext)
|
|
require.NoError(t, err)
|
|
raw[len(raw)-1] ^= 0xff
|
|
_, err = Open("sigma", base64.StdEncoding.EncodeToString(raw))
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("not base64", func(t *testing.T) {
|
|
_, err := Open("sigma", "not-base64!!")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("too short", func(t *testing.T) {
|
|
_, err := Open("sigma", base64.StdEncoding.EncodeToString([]byte("short")))
|
|
require.Error(t, err)
|
|
})
|
|
}
|