Migrate to maintained tink-go (#5886)

This commit is contained in:
Anbraten
2025-12-20 09:23:09 +01:00
committed by GitHub
parent 216878d13d
commit cdefb2842c
12 changed files with 129 additions and 16 deletions

View File

@@ -25,8 +25,8 @@ import (
"strings"
"time"
"github.com/google/tink/go/subtle/random"
"github.com/rs/zerolog/log"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"github.com/urfave/cli/v3"
"go.woodpecker-ci.org/woodpecker/v3/server"

3
go.mod
View File

@@ -31,7 +31,6 @@ require (
github.com/go-viper/mapstructure/v2 v2.4.0
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/google/go-github/v80 v80.0.0
github.com/google/tink/go v1.7.0
github.com/hashicorp/go-hclog v1.6.3
github.com/hashicorp/go-plugin v1.7.0
github.com/jellydator/ttlcache/v3 v3.4.0
@@ -51,6 +50,7 @@ require (
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.1
github.com/swaggo/swag v1.16.6
github.com/tink-crypto/tink-go/v2 v2.5.0
github.com/urfave/cli-docs/v3 v3.1.1-0.20251022123016-72b87d11c482
github.com/urfave/cli/v3 v3.6.1
github.com/xeipuuv/gojsonschema v1.2.0
@@ -216,7 +216,6 @@ require (
golang.org/x/sys v0.39.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.39.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect

4
go.sum
View File

@@ -264,8 +264,6 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
github.com/google/tink/go v1.7.0/go.mod h1:GAUOd+QE3pgj9q8VKIGTCP33c/B7eb4NhxLcgTJZStM=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -562,6 +560,8 @@ github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tink-crypto/tink-go/v2 v2.5.0 h1:B8KLF6AofxdBIE4UJIaFbmoj5/1ehEtt7/MmzfI4Zpw=
github.com/tink-crypto/tink-go/v2 v2.5.0/go.mod h1:2WbBA6pfNsAfBwDCggboaHeB2X29wkU8XHtGwh2YIk8=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=

View File

@@ -24,8 +24,8 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/google/tink/go/subtle/random"
"github.com/rs/zerolog/log"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"go.woodpecker-ci.org/woodpecker/v3/server"
"go.woodpecker-ci.org/woodpecker/v3/server/forge"

View File

@@ -24,8 +24,8 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/google/tink/go/subtle/random"
"github.com/rs/zerolog/log"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"go.woodpecker-ci.org/woodpecker/v3/server"
"go.woodpecker-ci.org/woodpecker/v3/server/forge"

View File

@@ -20,8 +20,8 @@ import (
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/tink/go/subtle/random"
"github.com/rs/zerolog/log"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"go.woodpecker-ci.org/woodpecker/v3/server"
"go.woodpecker-ci.org/woodpecker/v3/server/model"

View File

@@ -22,7 +22,7 @@ import (
"strconv"
"github.com/gin-gonic/gin"
"github.com/google/tink/go/subtle/random"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"go.woodpecker-ci.org/woodpecker/v3/server/model"
"go.woodpecker-ci.org/woodpecker/v3/server/router/middleware/session"

View File

@@ -18,7 +18,7 @@ import (
"encoding/base32"
"fmt"
"github.com/google/tink/go/subtle/random"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"go.woodpecker-ci.org/woodpecker/v3/pipeline"
)

View File

@@ -19,7 +19,7 @@ import (
"encoding/base64"
"fmt"
"github.com/google/tink/go/subtle/random"
"github.com/tink-crypto/tink-go/v2/subtle/random"
"go.woodpecker-ci.org/woodpecker/v3/server/services/encryption/types"
"go.woodpecker-ci.org/woodpecker/v3/server/store"

View File

@@ -15,10 +15,12 @@
package encryption
import (
"encoding/base64"
"testing"
"github.com/google/tink/go/subtle/random"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tink-crypto/tink-go/v2/subtle/random"
)
func TestShortMessageLongKey(t *testing.T) {
@@ -48,3 +50,115 @@ func TestLongMessageShortKey(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, input, output)
}
func TestEncryptDecryptWithAssociatedData(t *testing.T) {
aes := &aesEncryptionService{}
err := aes.loadCipher(string(random.GetRandomBytes(32)))
require.NoError(t, err)
plaintext := "secret-value-12345"
associatedData := "repo:123"
ciphertext, err := aes.Encrypt(plaintext, associatedData)
require.NoError(t, err)
// Decrypt with correct associated data should succeed
decrypted, err := aes.Decrypt(ciphertext, associatedData)
require.NoError(t, err)
assert.Equal(t, plaintext, decrypted)
// Decrypt with wrong associated data should fail
_, err = aes.Decrypt(ciphertext, "repo:456")
assert.Error(t, err, "decryption should fail with wrong associated data")
// Decrypt with empty associated data should fail
_, err = aes.Decrypt(ciphertext, "")
assert.Error(t, err, "decryption should fail with missing associated data")
}
func TestEncryptProducesUniqueCiphertexts(t *testing.T) {
aes := &aesEncryptionService{}
err := aes.loadCipher(string(random.GetRandomBytes(32)))
require.NoError(t, err)
plaintext := "same-message"
ciphertexts := make(map[string]bool)
// Encrypt the same message multiple times
for range 100 {
ct, err := aes.Encrypt(plaintext, "")
require.NoError(t, err)
assert.False(t, ciphertexts[ct], "ciphertext should be unique due to random nonce")
ciphertexts[ct] = true
}
}
func TestDecryptTamperedCiphertext(t *testing.T) {
aes := &aesEncryptionService{}
err := aes.loadCipher(string(random.GetRandomBytes(32)))
require.NoError(t, err)
plaintext := "sensitive-data"
ciphertext, err := aes.Encrypt(plaintext, "")
require.NoError(t, err)
// Decode, tamper, re-encode
decoded, err := base64.StdEncoding.DecodeString(ciphertext)
require.NoError(t, err)
// Tamper with the ciphertext (flip a bit in the middle)
if len(decoded) > AES_GCM_SIV_NonceSize+1 {
decoded[AES_GCM_SIV_NonceSize+1] ^= 0xFF
}
tampered := base64.StdEncoding.EncodeToString(decoded)
_, err = aes.Decrypt(tampered, "")
assert.Error(t, err, "decryption of tampered ciphertext should fail")
}
func TestDecryptInvalidBase64(t *testing.T) {
aes := &aesEncryptionService{}
err := aes.loadCipher(string(random.GetRandomBytes(32)))
require.NoError(t, err)
_, err = aes.Decrypt("not-valid-base64!!!", "")
assert.Error(t, err, "decryption of invalid base64 should fail")
}
func TestDecryptTruncatedCiphertext(t *testing.T) {
aes := &aesEncryptionService{}
err := aes.loadCipher(string(random.GetRandomBytes(32)))
require.NoError(t, err)
plaintext := "test-message"
ciphertext, err := aes.Encrypt(plaintext, "")
require.NoError(t, err)
// Truncate the ciphertext
decoded, err := base64.StdEncoding.DecodeString(ciphertext)
require.NoError(t, err)
truncated := base64.StdEncoding.EncodeToString(decoded[:len(decoded)/2])
_, err = aes.Decrypt(truncated, "")
assert.Error(t, err, "decryption of truncated ciphertext should fail")
}
func TestRandomBytesUniqueness(t *testing.T) {
seen := make(map[string]bool)
for range 1000 {
bytes := random.GetRandomBytes(32)
key := string(bytes)
assert.False(t, seen[key], "random bytes should be unique")
seen[key] = true
}
}
func TestRandomBytesLength(t *testing.T) {
tests := []uint32{1, 12, 16, 32, 64, 128, 256}
for _, length := range tests {
bytes := random.GetRandomBytes(length)
assert.Len(t, bytes, int(length), "random bytes should have requested length")
}
}

View File

@@ -19,7 +19,7 @@ import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/google/tink/go/tink"
"github.com/tink-crypto/tink-go/v2/tink"
"go.woodpecker-ci.org/woodpecker/v3/server/services/encryption/types"
"go.woodpecker-ci.org/woodpecker/v3/server/store"

View File

@@ -20,10 +20,10 @@ import (
"os"
"strconv"
"github.com/google/tink/go/aead"
insecure_clear_text_keyset "github.com/google/tink/go/insecurecleartextkeyset"
"github.com/google/tink/go/keyset"
"github.com/rs/zerolog/log"
"github.com/tink-crypto/tink-go/v2/aead"
insecure_clear_text_keyset "github.com/tink-crypto/tink-go/v2/insecurecleartextkeyset"
"github.com/tink-crypto/tink-go/v2/keyset"
"go.woodpecker-ci.org/woodpecker/v3/server/store/types"
)