ComputeHash takes the nonce from o, and encrypts the contents of src with it, and calculates the hash given by HashType on the fly Note that we break lots of encapsulation in this function.
(ctx context.Context, o *Object, src fs.Object, hashType hash.Type)
| 813 | // |
| 814 | // Note that we break lots of encapsulation in this function. |
| 815 | func (f *Fs) ComputeHash(ctx context.Context, o *Object, src fs.Object, hashType hash.Type) (hashStr string, err error) { |
| 816 | if f.opt.NoDataEncryption { |
| 817 | return src.Hash(ctx, hashType) |
| 818 | } |
| 819 | |
| 820 | // Read the nonce - opening the file is sufficient to read the nonce in |
| 821 | // use a limited read so we only read the header |
| 822 | in, err := o.Object.Open(ctx, &fs.RangeOption{Start: 0, End: int64(fileHeaderSize) - 1}) |
| 823 | if err != nil { |
| 824 | return "", fmt.Errorf("failed to open object to read nonce: %w", err) |
| 825 | } |
| 826 | d, err := f.cipher.newDecrypter(in) |
| 827 | if err != nil { |
| 828 | _ = in.Close() |
| 829 | return "", fmt.Errorf("failed to open object to read nonce: %w", err) |
| 830 | } |
| 831 | nonce := d.nonce |
| 832 | // fs.Debugf(o, "Read nonce % 2x", nonce) |
| 833 | |
| 834 | // Check nonce isn't all zeros |
| 835 | isZero := true |
| 836 | for i := range nonce { |
| 837 | if nonce[i] != 0 { |
| 838 | isZero = false |
| 839 | } |
| 840 | } |
| 841 | if isZero { |
| 842 | fs.Errorf(o, "empty nonce read") |
| 843 | } |
| 844 | |
| 845 | // Close d (and hence in) once we have read the nonce |
| 846 | err = d.Close() |
| 847 | if err != nil { |
| 848 | return "", fmt.Errorf("failed to close nonce read: %w", err) |
| 849 | } |
| 850 | |
| 851 | return f.computeHashWithNonce(ctx, nonce, src, hashType) |
| 852 | } |
| 853 | |
| 854 | // MergeDirs merges the contents of all the directories passed |
| 855 | // in into the first one and rmdirs the other directories. |