Decrypt walks over the tree and decrypts all values with the provided cipher, except those whose key ends with the UnencryptedSuffix specified on the Metadata struct, those not ending with EncryptedSuffix, if EncryptedSuffix is provided (by default it is not), those not matching EncryptedRegex, if E
(key []byte, cipher Cipher)
| 585 | // (all values if MACOnlyEncrypted is false, or only over values which end |
| 586 | // up decrypted if MACOnlyEncrypted is true). |
| 587 | func (tree Tree) Decrypt(key []byte, cipher Cipher) (string, error) { |
| 588 | log.Debug("Decrypting tree") |
| 589 | audit.SubmitEvent(audit.DecryptEvent{ |
| 590 | File: tree.FilePath, |
| 591 | }) |
| 592 | hash := sha512.New() |
| 593 | if tree.Metadata.MACOnlyEncrypted { |
| 594 | // We initialize with known set of bytes so that a MAC with this setting |
| 595 | // enabled is always different from a MAC with this setting disabled. |
| 596 | hash.Write(MACOnlyEncryptedInitialization) |
| 597 | } |
| 598 | walk := func(branch TreeBranch) error { |
| 599 | _, err := branch.walkBranch(branch, make([]string, 0), make([][]string, 0), func(in interface{}, path []string, commentsStack [][]string) (interface{}, error) { |
| 600 | c, isComment := in.(Comment) |
| 601 | encrypted := tree.shouldBeEncrypted(path, commentsStack, isComment) |
| 602 | var v interface{} |
| 603 | if encrypted { |
| 604 | var err error |
| 605 | pathString := strings.Join(path, ":") + ":" |
| 606 | if isComment { |
| 607 | v, err = cipher.Decrypt(c.Value, key, pathString) |
| 608 | if err != nil { |
| 609 | // Assume the comment was not encrypted in the first place |
| 610 | log.WithField("comment", c.Value). |
| 611 | Warn("Found possibly unencrypted comment in file. " + |
| 612 | "This is to be expected if the file being " + |
| 613 | "decrypted was created with an older version of " + |
| 614 | "SOPS.") |
| 615 | v = c |
| 616 | } |
| 617 | } else if inStr, inIsStr := in.(string); inIsStr { |
| 618 | v, err = cipher.Decrypt(inStr, key, pathString) |
| 619 | if err != nil { |
| 620 | return nil, fmt.Errorf("Could not decrypt value: %s", err) |
| 621 | } |
| 622 | } else { |
| 623 | return nil, fmt.Errorf("Expected encrypted value as string, but got %T", in) |
| 624 | } |
| 625 | } else { |
| 626 | v = in |
| 627 | } |
| 628 | if !tree.Metadata.MACOnlyEncrypted || encrypted { |
| 629 | // Only add to MAC if not a comment |
| 630 | if !isComment { |
| 631 | bytes, err := ToBytes(v) |
| 632 | if err != nil { |
| 633 | return nil, fmt.Errorf("Could not convert %s to bytes: %s", in, err) |
| 634 | } |
| 635 | hash.Write(bytes) |
| 636 | } |
| 637 | } |
| 638 | return v, nil |
| 639 | }) |
| 640 | return err |
| 641 | } |
| 642 | for _, branch := range tree.Branches { |
| 643 | err := walk(branch) |
| 644 | if err != nil { |