mirror of
https://github.com/getsops/sops.git
synced 2026-02-05 12:45:21 +01:00
aes decryptor now takes []byte keys
This commit is contained in:
@@ -19,30 +19,30 @@ type EncryptedValue struct {
|
||||
|
||||
var encre = regexp.MustCompile(`^ENC\[AES256_GCM,data:(.+),iv:(.+),tag:(.+),type:(.+)\]`)
|
||||
|
||||
func parse(value string) (*EncryptedValue, error) {
|
||||
matches := encre.FindStringSubmatch(value)
|
||||
func parse(value []byte) (*EncryptedValue, error) {
|
||||
matches := encre.FindSubmatch(value)
|
||||
if matches == nil {
|
||||
return nil, fmt.Errorf("Input string %s does not match sops' data format", value)
|
||||
}
|
||||
data, err := base64.StdEncoding.DecodeString(matches[1])
|
||||
data, err := base64.StdEncoding.DecodeString(string(matches[1]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error base64-decoding data: %s", err)
|
||||
}
|
||||
iv, err := base64.StdEncoding.DecodeString(matches[2])
|
||||
iv, err := base64.StdEncoding.DecodeString(string(matches[2]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error base64-decoding iv: %s", err)
|
||||
}
|
||||
tag, err := base64.StdEncoding.DecodeString(matches[3])
|
||||
tag, err := base64.StdEncoding.DecodeString(string(matches[3]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error base64-decoding tag: %s", err)
|
||||
}
|
||||
datatype := matches[4]
|
||||
datatype := string(matches[4])
|
||||
|
||||
return &EncryptedValue{data, iv, tag, datatype}, nil
|
||||
}
|
||||
|
||||
// Decrypt takes a sops-format value string and a key and returns the decrypted value.
|
||||
func Decrypt(value, key string, additionalAuthData []byte) (interface{}, error) {
|
||||
func Decrypt(value, key []byte, additionalAuthData []byte) (interface{}, error) {
|
||||
encryptedValue, err := parse(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -79,7 +79,7 @@ func Decrypt(value, key string, additionalAuthData []byte) (interface{}, error)
|
||||
}
|
||||
}
|
||||
|
||||
func Encrypt(value interface{}, key string, additionalAuthData []byte) (string, error) {
|
||||
func Encrypt(value interface{}, key []byte, additionalAuthData []byte) (string, error) {
|
||||
aes, err := cryptoaes.NewCipher([]byte(key))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Could not initialize AES GCM encryption cipher: %s", err)
|
||||
|
||||
@@ -21,13 +21,13 @@ type KMSMasterKey struct {
|
||||
CreationDate time.Time
|
||||
}
|
||||
|
||||
func (key *KMSMasterKey) Encrypt(dataKey string) error {
|
||||
func (key *KMSMasterKey) Encrypt(dataKey []byte) error {
|
||||
sess, err := key.createSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
service := kms.New(sess)
|
||||
out, err := service.Encrypt(&kms.EncryptInput{Plaintext: []byte(dataKey), KeyId: &key.Arn})
|
||||
out, err := service.Encrypt(&kms.EncryptInput{Plaintext: dataKey, KeyId: &key.Arn})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -35,29 +35,29 @@ func (key *KMSMasterKey) Encrypt(dataKey string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (key *KMSMasterKey) EncryptIfNeeded(dataKey string) error {
|
||||
func (key *KMSMasterKey) EncryptIfNeeded(dataKey []byte) error {
|
||||
if key.EncryptedKey == "" {
|
||||
return key.Encrypt(dataKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (key *KMSMasterKey) Decrypt() (string, error) {
|
||||
func (key *KMSMasterKey) Decrypt() ([]byte, error) {
|
||||
k, err := base64.StdEncoding.DecodeString(key.EncryptedKey)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error base64-decoding encrypted data key: %s", err)
|
||||
return nil, fmt.Errorf("Error base64-decoding encrypted data key: %s", err)
|
||||
}
|
||||
sess, err := key.createSession()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error creating AWS session: %v", err)
|
||||
return nil, fmt.Errorf("Error creating AWS session: %v", err)
|
||||
}
|
||||
|
||||
service := kms.New(sess)
|
||||
decrypted, err := service.Decrypt(&kms.DecryptInput{CiphertextBlob: k})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error decrypting key: %v", err)
|
||||
return nil, fmt.Errorf("Error decrypting key: %v", err)
|
||||
}
|
||||
return string(decrypted.Plaintext), nil
|
||||
return decrypted.Plaintext, nil
|
||||
}
|
||||
|
||||
func (key *KMSMasterKey) NeedsRotation() bool {
|
||||
|
||||
18
main/main.go
18
main/main.go
@@ -163,7 +163,7 @@ func store(path string) sops.Store {
|
||||
panic("Unknown file type for file " + path)
|
||||
}
|
||||
|
||||
func findKey(keysources []sops.KeySource) (string, error) {
|
||||
func findKey(keysources []sops.KeySource) ([]byte, error) {
|
||||
for _, ks := range keysources {
|
||||
for _, k := range ks.Keys {
|
||||
key, err := k.Decrypt()
|
||||
@@ -172,7 +172,7 @@ func findKey(keysources []sops.KeySource) (string, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Could not get master key")
|
||||
return nil, fmt.Errorf("Could not get master key")
|
||||
}
|
||||
|
||||
func decrypt(c *cli.Context, file string, fileBytes []byte, output io.Writer) error {
|
||||
@@ -194,7 +194,7 @@ func decrypt(c *cli.Context, file string, fileBytes []byte, output io.Writer) er
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Sprintf("Error decrypting tree: %s", err), 8)
|
||||
}
|
||||
originalMac, err := aes.Decrypt(metadata.MessageAuthenticationCode, key, []byte(metadata.LastModified.Format(sops.DateFormat)))
|
||||
originalMac, err := aes.Decrypt([]byte(metadata.MessageAuthenticationCode), key, []byte(metadata.LastModified.Format(sops.DateFormat)))
|
||||
if originalMac != mac && !c.Bool("ignore-mac") {
|
||||
return cli.NewExitError("MAC mismatch.", 9)
|
||||
}
|
||||
@@ -240,11 +240,11 @@ func encrypt(c *cli.Context, file string, fileBytes []byte, output io.Writer) er
|
||||
}
|
||||
for _, ks := range metadata.KeySources {
|
||||
for _, k := range ks.Keys {
|
||||
err = k.Encrypt(string(key))
|
||||
err = k.Encrypt(key)
|
||||
}
|
||||
}
|
||||
tree := sops.Tree{Branch: branch, Metadata: metadata}
|
||||
mac, err := tree.Encrypt(string(key))
|
||||
mac, err := tree.Encrypt(key)
|
||||
metadata.MessageAuthenticationCode = mac
|
||||
out, err := store.DumpWithMetadata(tree.Branch, metadata)
|
||||
_, err = output.Write([]byte(out))
|
||||
@@ -273,7 +273,7 @@ func rotate(c *cli.Context, file string, fileBytes []byte, output io.Writer) err
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Sprintf("Error decrypting tree: %s", err), 8)
|
||||
}
|
||||
originalMac, err := aes.Decrypt(metadata.MessageAuthenticationCode, key, []byte(metadata.LastModified.Format(sops.DateFormat)))
|
||||
originalMac, err := aes.Decrypt([]byte(metadata.MessageAuthenticationCode), key, []byte(metadata.LastModified.Format(sops.DateFormat)))
|
||||
if originalMac != mac && !c.Bool("ignore-mac") {
|
||||
return cli.NewExitError("MAC mismatch.", 9)
|
||||
}
|
||||
@@ -284,10 +284,10 @@ func rotate(c *cli.Context, file string, fileBytes []byte, output io.Writer) err
|
||||
}
|
||||
for _, ks := range metadata.KeySources {
|
||||
for _, k := range ks.Keys {
|
||||
k.Encrypt(string(newKey))
|
||||
k.Encrypt(newKey)
|
||||
}
|
||||
}
|
||||
_, err = tree.Encrypt(string(newKey))
|
||||
_, err = tree.Encrypt(newKey)
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Sprintf("Error encrypting tree: %s", err), 8)
|
||||
}
|
||||
@@ -296,7 +296,7 @@ func rotate(c *cli.Context, file string, fileBytes []byte, output io.Writer) err
|
||||
metadata.AddPGPMasterKeys(c.String("add-pgp"))
|
||||
metadata.RemoveKMSMasterKeys(c.String("rm-kms"))
|
||||
metadata.RemovePGPMasterKeys(c.String("rm-pgp"))
|
||||
metadata.UpdateMasterKeys(string(newKey))
|
||||
metadata.UpdateMasterKeys(newKey)
|
||||
fmt.Println(metadata.KeySources)
|
||||
out, err := store.DumpWithMetadata(tree.Branch, metadata)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ type GPGMasterKey struct {
|
||||
CreationDate time.Time
|
||||
}
|
||||
|
||||
func (key *GPGMasterKey) Encrypt(dataKey string) error {
|
||||
func (key *GPGMasterKey) Encrypt(dataKey []byte) error {
|
||||
ring, err := key.pubRing()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -43,7 +43,7 @@ func (key *GPGMasterKey) Encrypt(dataKey string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = plaintextbuf.Write([]byte(dataKey))
|
||||
_, err = plaintextbuf.Write(dataKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -63,30 +63,30 @@ func (key *GPGMasterKey) Encrypt(dataKey string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (key *GPGMasterKey) EncryptIfNeeded(dataKey string) error {
|
||||
func (key *GPGMasterKey) EncryptIfNeeded(dataKey []byte) error {
|
||||
if key.EncryptedKey == "" {
|
||||
return key.Encrypt(dataKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (key *GPGMasterKey) Decrypt() (string, error) {
|
||||
func (key *GPGMasterKey) Decrypt() ([]byte, error) {
|
||||
ring, err := key.secRing()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Could not load secring: %s", err)
|
||||
return nil, fmt.Errorf("Could not load secring: %s", err)
|
||||
}
|
||||
block, err := armor.Decode(strings.NewReader(key.EncryptedKey))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Armor decoding failed: %s", err)
|
||||
return nil, fmt.Errorf("Armor decoding failed: %s", err)
|
||||
}
|
||||
md, err := openpgp.ReadMessage(block.Body, ring, key.passphrasePrompt, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Reading PGP message failed: %s", err)
|
||||
return nil, fmt.Errorf("Reading PGP message failed: %s", err)
|
||||
}
|
||||
if b, err := ioutil.ReadAll(md.UnverifiedBody); err == nil {
|
||||
return string(b), nil
|
||||
return b, nil
|
||||
}
|
||||
return "", fmt.Errorf("The key could not be decrypted with any of the GPG entries")
|
||||
return nil, fmt.Errorf("The key could not be decrypted with any of the GPG entries")
|
||||
}
|
||||
|
||||
func (key *GPGMasterKey) NeedsRotation() bool {
|
||||
|
||||
14
sops.go
14
sops.go
@@ -72,7 +72,7 @@ func (tree TreeBranch) WalkBranch(in TreeBranch, path []string, onLeaves func(in
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (tree Tree) Encrypt(key string) (string, error) {
|
||||
func (tree Tree) Encrypt(key []byte) (string, error) {
|
||||
hash := sha512.New()
|
||||
_, err := tree.Branch.WalkBranch(tree.Branch, make([]string, 0), func(in interface{}, path []string) (interface{}, error) {
|
||||
bytes, err := toBytes(in)
|
||||
@@ -95,13 +95,13 @@ func (tree Tree) Encrypt(key string) (string, error) {
|
||||
return fmt.Sprintf("%X", hash.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func (tree Tree) Decrypt(key string) (string, error) {
|
||||
func (tree Tree) Decrypt(key []byte) (string, error) {
|
||||
hash := sha512.New()
|
||||
_, err := tree.Branch.WalkBranch(tree.Branch, make([]string, 0), func(in interface{}, path []string) (interface{}, error) {
|
||||
var v interface{}
|
||||
if !strings.HasSuffix(path[len(path)-1], tree.Metadata.UnencryptedSuffix) {
|
||||
var err error
|
||||
v, err = aes.Decrypt(in.(string), key, []byte(strings.Join(path, ":")+":"))
|
||||
v, err = aes.Decrypt([]byte(in.(string)), key, []byte(strings.Join(path, ":")+":"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not decrypt value: %s", err)
|
||||
}
|
||||
@@ -136,9 +136,9 @@ type KeySource struct {
|
||||
}
|
||||
|
||||
type MasterKey interface {
|
||||
Encrypt(dataKey string) error
|
||||
EncryptIfNeeded(dataKey string) error
|
||||
Decrypt() (string, error)
|
||||
Encrypt(dataKey []byte) error
|
||||
EncryptIfNeeded(dataKey []byte) error
|
||||
Decrypt() ([]byte, error)
|
||||
NeedsRotation() bool
|
||||
ToString() string
|
||||
ToMap() map[string]string
|
||||
@@ -171,7 +171,7 @@ func (m *Metadata) RemoveMasterKeys(keys []MasterKey) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Metadata) UpdateMasterKeys(dataKey string) {
|
||||
func (m *Metadata) UpdateMasterKeys(dataKey []byte) {
|
||||
for _, ks := range m.KeySources {
|
||||
for _, k := range ks.Keys {
|
||||
err := k.EncryptIfNeeded(dataKey)
|
||||
|
||||
Reference in New Issue
Block a user