Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
172
plugins/secretstores/http/aes.go
Normal file
172
plugins/secretstores/http/aes.go
Normal file
|
@ -0,0 +1,172 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
|
||||
"github.com/influxdata/telegraf/config"
|
||||
)
|
||||
|
||||
type AesEncryptor struct {
|
||||
Variant []string `toml:"-"`
|
||||
Key config.Secret `toml:"key"`
|
||||
Vec config.Secret `toml:"init_vector"`
|
||||
KDFConfig
|
||||
|
||||
mode string
|
||||
trim func([]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
func (a *AesEncryptor) Init() error {
|
||||
var cipherName, mode, padding string
|
||||
|
||||
switch len(a.Variant) {
|
||||
case 3:
|
||||
padding = strings.ToLower(a.Variant[2])
|
||||
fallthrough
|
||||
case 2:
|
||||
mode = strings.ToLower(a.Variant[1])
|
||||
cipherName = strings.ToLower(a.Variant[0])
|
||||
if !strings.HasPrefix(cipherName, "aes") {
|
||||
return fmt.Errorf("requested AES but specified %q", cipherName)
|
||||
}
|
||||
case 1:
|
||||
return errors.New("please specify cipher mode")
|
||||
case 0:
|
||||
return errors.New("please specify cipher")
|
||||
default:
|
||||
return errors.New("too many variant elements")
|
||||
}
|
||||
|
||||
var keylen int
|
||||
switch cipherName {
|
||||
case "aes128":
|
||||
keylen = 16
|
||||
case "aes192":
|
||||
keylen = 24
|
||||
case "aes256":
|
||||
keylen = 32
|
||||
default:
|
||||
return fmt.Errorf("unsupported AES cipher %q", cipherName)
|
||||
}
|
||||
|
||||
if mode != "cbc" {
|
||||
return fmt.Errorf("unsupported cipher mode %q", a.Variant[1])
|
||||
}
|
||||
a.mode = mode
|
||||
|
||||
// Setup the trimming function to revert padding
|
||||
switch padding {
|
||||
case "", "none":
|
||||
// identity, no padding
|
||||
a.trim = func(in []byte) ([]byte, error) { return in, nil }
|
||||
case "pkcs#5", "pkcs#7":
|
||||
a.trim = PKCS5or7Trimming
|
||||
default:
|
||||
return fmt.Errorf("unsupported padding %q", padding)
|
||||
}
|
||||
|
||||
// Generate the key using password-based-keys
|
||||
if a.Key.Empty() {
|
||||
if a.Passwd.Empty() {
|
||||
return errors.New("either key or password has to be specified")
|
||||
}
|
||||
if a.Salt.Empty() || a.Iterations == 0 {
|
||||
return errors.New("salt and iterations required for password-based-keys")
|
||||
}
|
||||
|
||||
key, iv, err := a.KDFConfig.NewKey(keylen)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generating key failed: %w", err)
|
||||
}
|
||||
a.Key.Destroy()
|
||||
a.Key = key
|
||||
|
||||
if a.Vec.Empty() && !iv.Empty() {
|
||||
a.Vec.Destroy()
|
||||
a.Vec = iv
|
||||
}
|
||||
} else {
|
||||
encodedKey, err := a.Key.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting key failed: %w", err)
|
||||
}
|
||||
key := make([]byte, hex.DecodedLen(len(encodedKey.Bytes())))
|
||||
_, err = hex.Decode(key, encodedKey.Bytes())
|
||||
encodedKey.Destroy()
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding key failed: %w", err)
|
||||
}
|
||||
actuallen := len(key)
|
||||
memguard.WipeBytes(key)
|
||||
|
||||
if actuallen != keylen {
|
||||
return fmt.Errorf("key length (%d bit) does not match cipher (%d bit)", actuallen*8, keylen*8)
|
||||
}
|
||||
}
|
||||
|
||||
if a.Vec.Empty() {
|
||||
return errors.New("'init_vector' has to be specified or derived from password")
|
||||
}
|
||||
|
||||
encodedIV, err := a.Vec.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting IV failed: %w", err)
|
||||
}
|
||||
ivlen := len(encodedIV.Bytes())
|
||||
encodedIV.Destroy()
|
||||
if ivlen != 2*aes.BlockSize {
|
||||
return errors.New("init vector size must match block size")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AesEncryptor) Decrypt(data []byte) ([]byte, error) {
|
||||
if len(data)%aes.BlockSize != 0 {
|
||||
return nil, fmt.Errorf("invalid data size %d", len(data))
|
||||
}
|
||||
if a.mode != "cbc" {
|
||||
return nil, fmt.Errorf("unsupported cipher mode %q", a.mode)
|
||||
}
|
||||
|
||||
// Setup the cipher and return the decoded data
|
||||
encodedKey, err := a.Key.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting key failed: %w", err)
|
||||
}
|
||||
key := make([]byte, hex.DecodedLen(len(encodedKey.Bytes())))
|
||||
_, err = hex.Decode(key, encodedKey.Bytes())
|
||||
encodedKey.Destroy()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding key failed: %w", err)
|
||||
}
|
||||
|
||||
// Setup AES
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating AES cipher failed: %w", err)
|
||||
}
|
||||
|
||||
// Setup the block/stream cipher and decode the data
|
||||
encodedIV, err := a.Vec.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting initialization-vector failed: %w", err)
|
||||
}
|
||||
iv := make([]byte, hex.DecodedLen(len(encodedIV.Bytes())))
|
||||
_, err = hex.Decode(iv, encodedIV.Bytes())
|
||||
encodedIV.Destroy()
|
||||
if err != nil {
|
||||
memguard.WipeBytes(iv)
|
||||
return nil, fmt.Errorf("decoding init vector failed: %w", err)
|
||||
}
|
||||
|
||||
cipher.NewCBCDecrypter(block, iv).CryptBlocks(data, data)
|
||||
return a.trim(data)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue