319 lines
8.5 KiB
Go
319 lines
8.5 KiB
Go
package http
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/influxdata/telegraf/config"
|
|
)
|
|
|
|
func TestAES(t *testing.T) {
|
|
keySource := hex.EncodeToString([]byte("0123456789abcdefghijklmnopqrstuvwxyz"))
|
|
expected := "my $ecret-Passw0rd"
|
|
iv := hex.EncodeToString([]byte("0123456789abcdef"))
|
|
tests := []struct {
|
|
cipher string
|
|
encrypted string
|
|
key string
|
|
}{
|
|
{
|
|
cipher: "AES128/CBC/PKCS#5",
|
|
encrypted: "9E36B490B0B1D6CE28550DF9DE65FC0013FF9F0939E24DA4A24324BDB5EABA04",
|
|
key: keySource[:32],
|
|
},
|
|
{
|
|
cipher: "AES192/CBC/PKCS#5",
|
|
encrypted: "D3A5A0004B6783351F89B00C1D4154EDF2321EDAD3111B5551C18836B9FCFD62",
|
|
key: keySource[:48],
|
|
},
|
|
{
|
|
cipher: "AES256/CBC/PKCS#5",
|
|
encrypted: "9751D7FB4B1497DEBC8A95C5D88097ECB1B8E63979E2D41E7ECD304D6B39B808",
|
|
key: keySource[:64],
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.cipher, func(t *testing.T) {
|
|
decrypter := AesEncryptor{
|
|
Variant: strings.Split(tt.cipher, "/"),
|
|
Key: config.NewSecret([]byte(tt.key)),
|
|
Vec: config.NewSecret([]byte(iv)),
|
|
}
|
|
require.NoError(t, decrypter.Init())
|
|
enc, err := hex.DecodeString(tt.encrypted)
|
|
require.NoError(t, err)
|
|
dec, err := decrypter.Decrypt(enc)
|
|
require.NoError(t, err)
|
|
require.Equal(t, expected, string(dec))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAESNoPadding(t *testing.T) {
|
|
keySource := hex.EncodeToString([]byte("0123456789abcdefghijklmnopqrstuvwxyz"))
|
|
expected := "my $ecret-Passw0rd"
|
|
iv := hex.EncodeToString([]byte("0123456789abcdef"))
|
|
tests := []struct {
|
|
cipher string
|
|
encrypted string
|
|
key string
|
|
}{
|
|
{
|
|
cipher: "AES128/CBC",
|
|
encrypted: "9E36B490B0B1D6CE28550DF9DE65FC0013FF9F0939E24DA4A24324BDB5EABA04",
|
|
key: keySource[:32],
|
|
},
|
|
{
|
|
cipher: "AES192/CBC",
|
|
encrypted: "D3A5A0004B6783351F89B00C1D4154EDF2321EDAD3111B5551C18836B9FCFD62",
|
|
key: keySource[:48],
|
|
},
|
|
{
|
|
cipher: "AES256/CBC",
|
|
encrypted: "9751D7FB4B1497DEBC8A95C5D88097ECB1B8E63979E2D41E7ECD304D6B39B808",
|
|
key: keySource[:64],
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.cipher, func(t *testing.T) {
|
|
decrypter := AesEncryptor{
|
|
Variant: strings.Split(tt.cipher, "/"),
|
|
Key: config.NewSecret([]byte(tt.key)),
|
|
Vec: config.NewSecret([]byte(iv)),
|
|
}
|
|
require.NoError(t, decrypter.Init())
|
|
enc, err := hex.DecodeString(tt.encrypted)
|
|
require.NoError(t, err)
|
|
dec, err := decrypter.Decrypt(enc)
|
|
require.NoError(t, err)
|
|
require.Len(t, string(dec), 32)
|
|
require.Contains(t, string(dec), expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAESKDF(t *testing.T) {
|
|
expected := "my $ecret-Passw0rd"
|
|
iv := hex.EncodeToString([]byte("asupersecretiv42"))
|
|
tests := []struct {
|
|
cipher string
|
|
password string
|
|
salt string
|
|
iterations int
|
|
encrypted string
|
|
}{
|
|
{
|
|
cipher: "AES256/CBC/PKCS#5",
|
|
password: "a secret password",
|
|
salt: "somerandombytes",
|
|
iterations: 2000,
|
|
encrypted: "224b169206ce918f167ae0da18f4de45bede0d2c853d45e55f1422d1446037bf",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.cipher, func(t *testing.T) {
|
|
decrypter := AesEncryptor{
|
|
Variant: strings.Split(tt.cipher, "/"),
|
|
KDFConfig: KDFConfig{
|
|
Algorithm: "PBKDF2-HMAC-SHA256",
|
|
Passwd: config.NewSecret([]byte(tt.password)),
|
|
Salt: config.NewSecret([]byte(tt.salt)),
|
|
Iterations: tt.iterations,
|
|
},
|
|
Vec: config.NewSecret([]byte(iv)),
|
|
}
|
|
require.NoError(t, decrypter.Init())
|
|
enc, err := hex.DecodeString(tt.encrypted)
|
|
require.NoError(t, err)
|
|
dec, err := decrypter.Decrypt(enc)
|
|
require.NoError(t, err)
|
|
require.Equal(t, expected, string(dec))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAESInitErrors(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
variant []string
|
|
key string
|
|
iv string
|
|
kdfcfg *KDFConfig
|
|
expected string
|
|
}{
|
|
{
|
|
name: "no mode",
|
|
variant: []string{"AES128"},
|
|
expected: "please specify cipher mode",
|
|
},
|
|
{
|
|
name: "too many elements",
|
|
variant: []string{"AES128", "CBC", "PKCS#5", "superfluous"},
|
|
expected: "too many variant elements",
|
|
},
|
|
{
|
|
name: "no AES",
|
|
variant: []string{"rsa", "cbc"},
|
|
expected: `requested AES but specified "rsa"`,
|
|
},
|
|
{
|
|
name: "no cipher",
|
|
expected: "please specify cipher",
|
|
},
|
|
{
|
|
name: "unsupported cipher",
|
|
variant: []string{"aes64", "cbc"},
|
|
expected: "unsupported AES cipher",
|
|
},
|
|
{
|
|
name: "unsupported mode",
|
|
variant: []string{"aes128", "foo"},
|
|
expected: "unsupported cipher mode",
|
|
},
|
|
{
|
|
name: "unsupported padding",
|
|
variant: []string{"aes128", "cbc", "bar"},
|
|
expected: "unsupported padding",
|
|
},
|
|
{
|
|
name: "missing key",
|
|
variant: []string{"aes128", "cbc", "none"},
|
|
expected: "either key or password has to be specified",
|
|
},
|
|
{
|
|
name: "wrong key length",
|
|
variant: []string{"aes256", "cbc"},
|
|
key: "63238c069e3c5d6aaa20048c43ce4ed0",
|
|
expected: "key length (128 bit) does not match cipher (256 bit)",
|
|
},
|
|
{
|
|
name: "invalid key",
|
|
variant: []string{"aes256", "cbc"},
|
|
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
expected: "decoding key failed: encoding/hex: invalid byte: U+0078 'x'",
|
|
},
|
|
{
|
|
name: "missing IV",
|
|
variant: []string{"aes128", "cbc"},
|
|
key: "63238c069e3c5d6aaa20048c43ce4ed0",
|
|
expected: "'init_vector' has to be specified or derived from password",
|
|
},
|
|
{
|
|
name: "invalid IV",
|
|
variant: []string{"aes128", "cbc"},
|
|
key: "63238c069e3c5d6aaa20048c43ce4ed0",
|
|
iv: "abcd",
|
|
expected: "init vector size must match block size",
|
|
},
|
|
{
|
|
name: "missing salt and iterations",
|
|
variant: []string{"aes128", "cbc", "none"},
|
|
kdfcfg: &KDFConfig{
|
|
Passwd: config.NewSecret([]byte("secret")),
|
|
},
|
|
expected: "salt and iterations required for password-based-keys",
|
|
},
|
|
{
|
|
name: "wrong keygen algorithm",
|
|
variant: []string{"aes128", "cbc", "none"},
|
|
kdfcfg: &KDFConfig{
|
|
Algorithm: "foo",
|
|
Passwd: config.NewSecret([]byte("secret")),
|
|
Salt: config.NewSecret([]byte("salt")),
|
|
Iterations: 2000,
|
|
},
|
|
expected: "unknown key-derivation function",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
require.NotEmpty(t, tt.expected)
|
|
|
|
decrypter := AesEncryptor{
|
|
Variant: tt.variant,
|
|
}
|
|
if tt.key != "" {
|
|
decrypter.Key = config.NewSecret([]byte(tt.key))
|
|
}
|
|
if tt.iv != "" {
|
|
decrypter.Vec = config.NewSecret([]byte(tt.iv))
|
|
}
|
|
if tt.kdfcfg != nil {
|
|
decrypter.KDFConfig = *tt.kdfcfg
|
|
}
|
|
require.ErrorContains(t, decrypter.Init(), tt.expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAESDecryptError(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
encrypted string
|
|
messMode string
|
|
messKey string
|
|
messIV string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "wrong data length",
|
|
encrypted: "abcd",
|
|
expected: "invalid data size",
|
|
},
|
|
{
|
|
name: "mode tampered",
|
|
encrypted: "9E36B490B0B1D6CE28550DF9DE65FC0013FF9F0939E24DA4A24324BDB5EABA04",
|
|
messMode: "tampered",
|
|
expected: `unsupported cipher mode "tampered"`,
|
|
},
|
|
{
|
|
name: "invalid key",
|
|
encrypted: "9E36B490B0B1D6CE28550DF9DE65FC0013FF9F0939E24DA4A24324BDB5EABA04",
|
|
messKey: "tampered",
|
|
expected: "decoding key failed: encoding/hex: invalid byte: U+0074 't'",
|
|
},
|
|
{
|
|
name: "wrong key length",
|
|
encrypted: "9E36B490B0B1D6CE28550DF9DE65FC0013FF9F0939E24DA4A24324BDB5EABA04",
|
|
messKey: "01234567",
|
|
expected: "creating AES cipher failed: crypto/aes: invalid key size",
|
|
},
|
|
{
|
|
name: "invalid key",
|
|
encrypted: "9E36B490B0B1D6CE28550DF9DE65FC0013FF9F0939E24DA4A24324BDB5EABA04",
|
|
messIV: "tampered",
|
|
expected: "decoding init vector failed: encoding/hex: invalid byte: U+0074 't'",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
require.NotEmpty(t, tt.expected)
|
|
|
|
decrypter := AesEncryptor{
|
|
Variant: []string{"AES128", "CBC", "PKCS#5"},
|
|
Key: config.NewSecret([]byte(hex.EncodeToString([]byte("0123456789abcdef")))),
|
|
Vec: config.NewSecret([]byte(hex.EncodeToString([]byte("0123456789abcdef")))),
|
|
}
|
|
require.NoError(t, decrypter.Init())
|
|
enc, err := hex.DecodeString(tt.encrypted)
|
|
require.NoError(t, err)
|
|
|
|
// Mess with the internal values for testing
|
|
if tt.messMode != "" {
|
|
decrypter.mode = tt.messMode
|
|
}
|
|
if tt.messKey != "" {
|
|
decrypter.Key = config.NewSecret([]byte(tt.messKey))
|
|
}
|
|
if tt.messIV != "" {
|
|
decrypter.Vec = config.NewSecret([]byte(tt.messIV))
|
|
}
|
|
_, err = decrypter.Decrypt(enc)
|
|
require.ErrorContains(t, err, tt.expected)
|
|
})
|
|
}
|
|
}
|