mirror of
https://github.com/rclone/rclone.git
synced 2024-12-22 23:22:08 +01:00
crypt: add test cases and documentation for base64 and base32768 filename encoding #5801
This commit is contained in:
parent
c217145cae
commit
8c61a09be2
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/Max-Sum/base32768"
|
||||
"github.com/rclone/rclone/backend/crypt/pkcs7"
|
||||
"github.com/rclone/rclone/lib/readers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -45,11 +47,31 @@ func TestNewNameEncryptionModeString(t *testing.T) {
|
||||
assert.Equal(t, NameEncryptionMode(3).String(), "Unknown mode #3")
|
||||
}
|
||||
|
||||
func TestEncodeFileName(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
expected string
|
||||
}{
|
||||
type EncodingTestCase struct {
|
||||
in string
|
||||
expected string
|
||||
}
|
||||
|
||||
func testEncodeFileName(t *testing.T, encoding string, testCases []EncodingTestCase, caseInsensitive bool) {
|
||||
for _, test := range testCases {
|
||||
enc, err := NewNameEncoding(encoding)
|
||||
assert.NoError(t, err, "There should be no error creating name encoder for base32.")
|
||||
actual := enc.EncodeToString([]byte(test.in))
|
||||
assert.Equal(t, actual, test.expected, fmt.Sprintf("in=%q", test.in))
|
||||
recovered, err := enc.DecodeString(test.expected)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", test.expected))
|
||||
if caseInsensitive {
|
||||
in := strings.ToUpper(test.expected)
|
||||
recovered, err = enc.DecodeString(in)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", in))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeFileNameBase32(t *testing.T) {
|
||||
testEncodeFileName(t, "base32", []EncodingTestCase{
|
||||
{"", ""},
|
||||
{"1", "64"},
|
||||
{"12", "64p0"},
|
||||
@ -67,20 +89,56 @@ func TestEncodeFileName(t *testing.T) {
|
||||
{"12345678901234", "64p36d1l6orjge9g64p36d0"},
|
||||
{"123456789012345", "64p36d1l6orjge9g64p36d1l"},
|
||||
{"1234567890123456", "64p36d1l6orjge9g64p36d1l6o"},
|
||||
} {
|
||||
actual := encodeFileName([]byte(test.in))
|
||||
assert.Equal(t, actual, test.expected, fmt.Sprintf("in=%q", test.in))
|
||||
recovered, err := decodeFileName(test.expected)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", test.expected))
|
||||
in := strings.ToUpper(test.expected)
|
||||
recovered, err = decodeFileName(in)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(recovered), test.in, fmt.Sprintf("reverse=%q", in))
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
|
||||
func TestDecodeFileName(t *testing.T) {
|
||||
func TestEncodeFileNameBase64(t *testing.T) {
|
||||
testEncodeFileName(t, "base64", []EncodingTestCase{
|
||||
{"", ""},
|
||||
{"1", "MQ"},
|
||||
{"12", "MTI"},
|
||||
{"123", "MTIz"},
|
||||
{"1234", "MTIzNA"},
|
||||
{"12345", "MTIzNDU"},
|
||||
{"123456", "MTIzNDU2"},
|
||||
{"1234567", "MTIzNDU2Nw"},
|
||||
{"12345678", "MTIzNDU2Nzg"},
|
||||
{"123456789", "MTIzNDU2Nzg5"},
|
||||
{"1234567890", "MTIzNDU2Nzg5MA"},
|
||||
{"12345678901", "MTIzNDU2Nzg5MDE"},
|
||||
{"123456789012", "MTIzNDU2Nzg5MDEy"},
|
||||
{"1234567890123", "MTIzNDU2Nzg5MDEyMw"},
|
||||
{"12345678901234", "MTIzNDU2Nzg5MDEyMzQ"},
|
||||
{"123456789012345", "MTIzNDU2Nzg5MDEyMzQ1"},
|
||||
{"1234567890123456", "MTIzNDU2Nzg5MDEyMzQ1Ng"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestEncodeFileNameBase32768(t *testing.T) {
|
||||
testEncodeFileName(t, "base32768", []EncodingTestCase{
|
||||
{"", ""},
|
||||
{"1", "㼿"},
|
||||
{"12", "㻙ɟ"},
|
||||
{"123", "㻙ⲿ"},
|
||||
{"1234", "㻙ⲍƟ"},
|
||||
{"12345", "㻙ⲍ⍟"},
|
||||
{"123456", "㻙ⲍ⍆ʏ"},
|
||||
{"1234567", "㻙ⲍ⍆觟"},
|
||||
{"12345678", "㻙ⲍ⍆觓ɧ"},
|
||||
{"123456789", "㻙ⲍ⍆觓栯"},
|
||||
{"1234567890", "㻙ⲍ⍆觓栩ɣ"},
|
||||
{"12345678901", "㻙ⲍ⍆觓栩朧"},
|
||||
{"123456789012", "㻙ⲍ⍆觓栩朤ʅ"},
|
||||
{"1234567890123", "㻙ⲍ⍆觓栩朤談"},
|
||||
{"12345678901234", "㻙ⲍ⍆觓栩朤諆ɔ"},
|
||||
{"123456789012345", "㻙ⲍ⍆觓栩朤諆媕"},
|
||||
{"1234567890123456", "㻙ⲍ⍆觓栩朤諆媕䆿"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestDecodeFileNameBase32(t *testing.T) {
|
||||
enc, err := NewNameEncoding("base32")
|
||||
assert.NoError(t, err, "There should be no error creating name encoder for base32.")
|
||||
// We've tested decoding the valid ones above, now concentrate on the invalid ones
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
@ -90,17 +148,65 @@ func TestDecodeFileName(t *testing.T) {
|
||||
{"!", base32.CorruptInputError(0)},
|
||||
{"hello=hello", base32.CorruptInputError(5)},
|
||||
} {
|
||||
actual, actualErr := decodeFileName(test.in)
|
||||
actual, actualErr := enc.DecodeString(test.in)
|
||||
assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncryptSegment(t *testing.T) {
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true)
|
||||
func TestDecodeFileNameBase64(t *testing.T) {
|
||||
enc, err := NewNameEncoding("base64")
|
||||
assert.NoError(t, err, "There should be no error creating name encoder for base32.")
|
||||
// We've tested decoding the valid ones above, now concentrate on the invalid ones
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
expected string
|
||||
in string
|
||||
expectedErr error
|
||||
}{
|
||||
{"64=", base64.CorruptInputError(2)},
|
||||
{"!", base64.CorruptInputError(0)},
|
||||
{"Hello=Hello", base64.CorruptInputError(5)},
|
||||
} {
|
||||
actual, actualErr := enc.DecodeString(test.in)
|
||||
assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeFileNameBase32768(t *testing.T) {
|
||||
enc, err := NewNameEncoding("base32768")
|
||||
assert.NoError(t, err, "There should be no error creating name encoder for base32.")
|
||||
// We've tested decoding the valid ones above, now concentrate on the invalid ones
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
expectedErr error
|
||||
}{
|
||||
{"㼿c", base32768.CorruptInputError(1)},
|
||||
{"!", base32768.CorruptInputError(0)},
|
||||
{"㻙ⲿ=㻙ⲿ", base32768.CorruptInputError(2)},
|
||||
} {
|
||||
actual, actualErr := enc.DecodeString(test.in)
|
||||
assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
|
||||
}
|
||||
}
|
||||
|
||||
func testEncryptSegment(t *testing.T, encoding string, testCases []EncodingTestCase, caseInsensitive bool) {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
for _, test := range testCases {
|
||||
actual := c.encryptSegment(test.in)
|
||||
assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %q", test.in))
|
||||
recovered, err := c.decryptSegment(test.expected)
|
||||
assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", test.expected))
|
||||
assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", test.expected))
|
||||
if caseInsensitive {
|
||||
in := strings.ToUpper(test.expected)
|
||||
recovered, err = c.decryptSegment(in)
|
||||
assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", in))
|
||||
assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", in))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncryptSegmentBase32(t *testing.T) {
|
||||
testEncryptSegment(t, "base32", []EncodingTestCase{
|
||||
{"", ""},
|
||||
{"1", "p0e52nreeaj0a5ea7s64m4j72s"},
|
||||
{"12", "l42g6771hnv3an9cgc8cr2n1ng"},
|
||||
@ -118,26 +224,61 @@ func TestEncryptSegment(t *testing.T) {
|
||||
{"12345678901234", "moq0uqdlqrblrc5pa5u5c7hq9g"},
|
||||
{"123456789012345", "eeam3li4rnommi3a762h5n7meg"},
|
||||
{"1234567890123456", "mijbj0frqf6ms7frcr6bd9h0env53jv96pjaaoirk7forcgpt70g"},
|
||||
} {
|
||||
actual := c.encryptSegment(test.in)
|
||||
assert.Equal(t, test.expected, actual, fmt.Sprintf("Testing %q", test.in))
|
||||
recovered, err := c.decryptSegment(test.expected)
|
||||
assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", test.expected))
|
||||
assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", test.expected))
|
||||
in := strings.ToUpper(test.expected)
|
||||
recovered, err = c.decryptSegment(in)
|
||||
assert.NoError(t, err, fmt.Sprintf("Testing reverse %q", in))
|
||||
assert.Equal(t, test.in, recovered, fmt.Sprintf("Testing reverse %q", in))
|
||||
}
|
||||
}, true)
|
||||
}
|
||||
|
||||
func TestDecryptSegment(t *testing.T) {
|
||||
func TestEncryptSegmentBase64(t *testing.T) {
|
||||
testEncryptSegment(t, "base64", []EncodingTestCase{
|
||||
{"", ""},
|
||||
{"1", "yBxRX25ypgUVyj8MSxJnFw"},
|
||||
{"12", "qQUDHOGN_jVdLIMQzYrhvA"},
|
||||
{"123", "1CxFf2Mti1xIPYlGruDh-A"},
|
||||
{"1234", "RL-xOTmsxsG7kuTy2XJUxw"},
|
||||
{"12345", "3FP_GHoeBJdq0yLgaED8IQ"},
|
||||
{"123456", "Xc4T1Gqrs3OVYnrE6dpEWQ"},
|
||||
{"1234567", "uZeEzssOnDWHEOzLqjwpog"},
|
||||
{"12345678", "8noiTP5WkkbEuijsPhOpxQ"},
|
||||
{"123456789", "GeNxgLA0wiaGAKU3U7qL4Q"},
|
||||
{"1234567890", "x1DUhdmqoVWYVBLD3dha-A"},
|
||||
{"12345678901", "iEyP_3BZR6vvv_2WM6NbZw"},
|
||||
{"123456789012", "4OPGvS4SZdjvS568APUaFw"},
|
||||
{"1234567890123", "Y8c5Wr8OhYYUo7fPwdojdg"},
|
||||
{"12345678901234", "tjQPabXW112wuVF8Vh46TA"},
|
||||
{"123456789012345", "c5Vh1kTd8WtIajmFEtz2dA"},
|
||||
{"1234567890123456", "tKa5gfvTzW4d-2bMtqYgdf5Rz-k2ZqViW6HfjbIZ6cE"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestEncryptSegmentBase32768(t *testing.T) {
|
||||
testEncryptSegment(t, "base32768", []EncodingTestCase{
|
||||
{"", ""},
|
||||
{"1", "詮㪗鐮僀伎作㻖㢧⪟"},
|
||||
{"12", "竢朧䉱虃光塬䟛⣡蓟"},
|
||||
{"123", "遶㞟鋅缕袡鲅ⵝ蝁ꌟ"},
|
||||
{"1234", "䢟銮䵵狌㐜燳谒颴詟"},
|
||||
{"12345", "钉Ꞇ㖃蚩憶狫朰杜㜿"},
|
||||
{"123456", "啇ᚵⵕ憗䋫➫➓肤卟"},
|
||||
{"1234567", "茫螓翁連劘樓㶔抉矟"},
|
||||
{"12345678", "龝☳䘊辄岅較络㧩襟"},
|
||||
{"123456789", "ⲱ苀㱆犂媐Ꮤ锇惫靟"},
|
||||
{"1234567890", "計宁憕偵匢皫╛纺ꌟ"},
|
||||
{"12345678901", "檆䨿鑫㪺藝ꡖ勇䦛婟"},
|
||||
{"123456789012", "雑頏䰂䲝淚哚鹡魺⪟"},
|
||||
{"1234567890123", "塃璶繁躸圅㔟䗃肃懟"},
|
||||
{"12345678901234", "腺ᕚ崚鏕鏥讥鼌䑺䲿"},
|
||||
{"123456789012345", "怪绕滻蕶肣但⠥荖惟"},
|
||||
{"1234567890123456", "肳哀旚挶靏鏻㾭䱠慟㪳ꏆ賊兲铧敻塹魀ʟ"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestDecryptSegmentBase32(t *testing.T) {
|
||||
// We've tested the forwards above, now concentrate on the errors
|
||||
longName := make([]byte, 3328)
|
||||
for i := range longName {
|
||||
longName[i] = 'a'
|
||||
}
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true)
|
||||
enc, _ := NewNameEncoding("base32")
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
expectedErr error
|
||||
@ -145,118 +286,371 @@ func TestDecryptSegment(t *testing.T) {
|
||||
{"64=", ErrorBadBase32Encoding},
|
||||
{"!", base32.CorruptInputError(0)},
|
||||
{string(longName), ErrorTooLongAfterDecode},
|
||||
{encodeFileName([]byte("a")), ErrorNotAMultipleOfBlocksize},
|
||||
{encodeFileName([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize},
|
||||
{encodeFileName([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong},
|
||||
{enc.EncodeToString([]byte("a")), ErrorNotAMultipleOfBlocksize},
|
||||
{enc.EncodeToString([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize},
|
||||
{enc.EncodeToString([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong},
|
||||
} {
|
||||
actual, actualErr := c.decryptSegment(test.in)
|
||||
assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncryptFileName(t *testing.T) {
|
||||
func TestDecryptSegmentBase64(t *testing.T) {
|
||||
// We've tested the forwards above, now concentrate on the errors
|
||||
longName := make([]byte, 2816)
|
||||
for i := range longName {
|
||||
longName[i] = 'a'
|
||||
}
|
||||
enc, _ := NewNameEncoding("base64")
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
expectedErr error
|
||||
}{
|
||||
{"6H=", base64.CorruptInputError(2)},
|
||||
{"!", base64.CorruptInputError(0)},
|
||||
{string(longName), ErrorTooLongAfterDecode},
|
||||
{enc.EncodeToString([]byte("a")), ErrorNotAMultipleOfBlocksize},
|
||||
{enc.EncodeToString([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize},
|
||||
{enc.EncodeToString([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong},
|
||||
} {
|
||||
actual, actualErr := c.decryptSegment(test.in)
|
||||
assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecryptSegmentBase32768(t *testing.T) {
|
||||
// We've tested the forwards above, now concentrate on the errors
|
||||
longName := strings.Repeat("怪", 1280)
|
||||
enc, _ := NewNameEncoding("base32768")
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
expectedErr error
|
||||
}{
|
||||
{"怪=", base32768.CorruptInputError(1)},
|
||||
{"!", base32768.CorruptInputError(0)},
|
||||
{longName, ErrorTooLongAfterDecode},
|
||||
{enc.EncodeToString([]byte("a")), ErrorNotAMultipleOfBlocksize},
|
||||
{enc.EncodeToString([]byte("123456789abcdef")), ErrorNotAMultipleOfBlocksize},
|
||||
{enc.EncodeToString([]byte("123456789abcdef0")), pkcs7.ErrorPaddingTooLong},
|
||||
} {
|
||||
actual, actualErr := c.decryptSegment(test.in)
|
||||
assert.Equal(t, test.expectedErr, actualErr, fmt.Sprintf("in=%q got actual=%q, err = %v %T", test.in, actual, actualErr, actualErr))
|
||||
}
|
||||
}
|
||||
|
||||
func testStandardEncryptFileName(t *testing.T, encoding string, testCasesEncryptDir []EncodingTestCase, testCasesNoEncryptDir []EncodingTestCase) {
|
||||
// First standard mode
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true)
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s-v2001-02-03-040506-123", c.EncryptFileName("1-v2001-02-03-040506-123"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng-v2001-02-03-040506-123", c.EncryptFileName("1/12-v2001-02-03-040506-123"))
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
for _, test := range testCasesEncryptDir {
|
||||
assert.Equal(t, test.expected, c.EncryptFileName(test.in))
|
||||
}
|
||||
// Standard mode with directory name encryption off
|
||||
c, _ = newCipher(NameEncryptionStandard, "", "", false)
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptFileName("1"))
|
||||
assert.Equal(t, "1/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptFileName("1/12"))
|
||||
assert.Equal(t, "1/12/qgm4avr35m5loi1th53ato71v0", c.EncryptFileName("1/12/123"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s-v2001-02-03-040506-123", c.EncryptFileName("1-v2001-02-03-040506-123"))
|
||||
assert.Equal(t, "1/l42g6771hnv3an9cgc8cr2n1ng-v2001-02-03-040506-123", c.EncryptFileName("1/12-v2001-02-03-040506-123"))
|
||||
// Now off mode
|
||||
c, _ = newCipher(NameEncryptionOff, "", "", true)
|
||||
c, _ = newCipher(NameEncryptionStandard, "", "", false, enc)
|
||||
for _, test := range testCasesNoEncryptDir {
|
||||
assert.Equal(t, test.expected, c.EncryptFileName(test.in))
|
||||
}
|
||||
}
|
||||
|
||||
func TestStandardEncryptFileNameBase32(t *testing.T) {
|
||||
testStandardEncryptFileName(t, "base32", []EncodingTestCase{
|
||||
{"1", "p0e52nreeaj0a5ea7s64m4j72s"},
|
||||
{"1/12", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng"},
|
||||
{"1/12/123", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0"},
|
||||
{"1-v2001-02-03-040506-123", "p0e52nreeaj0a5ea7s64m4j72s-v2001-02-03-040506-123"},
|
||||
{"1/12-v2001-02-03-040506-123", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng-v2001-02-03-040506-123"},
|
||||
}, []EncodingTestCase{
|
||||
{"1", "p0e52nreeaj0a5ea7s64m4j72s"},
|
||||
{"1/12", "1/l42g6771hnv3an9cgc8cr2n1ng"},
|
||||
{"1/12/123", "1/12/qgm4avr35m5loi1th53ato71v0"},
|
||||
{"1-v2001-02-03-040506-123", "p0e52nreeaj0a5ea7s64m4j72s-v2001-02-03-040506-123"},
|
||||
{"1/12-v2001-02-03-040506-123", "1/l42g6771hnv3an9cgc8cr2n1ng-v2001-02-03-040506-123"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandardEncryptFileNameBase64(t *testing.T) {
|
||||
testStandardEncryptFileName(t, "base64", []EncodingTestCase{
|
||||
{"1", "yBxRX25ypgUVyj8MSxJnFw"},
|
||||
{"1/12", "yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA"},
|
||||
{"1/12/123", "yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA/1CxFf2Mti1xIPYlGruDh-A"},
|
||||
{"1-v2001-02-03-040506-123", "yBxRX25ypgUVyj8MSxJnFw-v2001-02-03-040506-123"},
|
||||
{"1/12-v2001-02-03-040506-123", "yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA-v2001-02-03-040506-123"},
|
||||
}, []EncodingTestCase{
|
||||
{"1", "yBxRX25ypgUVyj8MSxJnFw"},
|
||||
{"1/12", "1/qQUDHOGN_jVdLIMQzYrhvA"},
|
||||
{"1/12/123", "1/12/1CxFf2Mti1xIPYlGruDh-A"},
|
||||
{"1-v2001-02-03-040506-123", "yBxRX25ypgUVyj8MSxJnFw-v2001-02-03-040506-123"},
|
||||
{"1/12-v2001-02-03-040506-123", "1/qQUDHOGN_jVdLIMQzYrhvA-v2001-02-03-040506-123"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandardEncryptFileNameBase32768(t *testing.T) {
|
||||
testStandardEncryptFileName(t, "base32768", []EncodingTestCase{
|
||||
{"1", "詮㪗鐮僀伎作㻖㢧⪟"},
|
||||
{"1/12", "詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟"},
|
||||
{"1/12/123", "詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟/遶㞟鋅缕袡鲅ⵝ蝁ꌟ"},
|
||||
{"1-v2001-02-03-040506-123", "詮㪗鐮僀伎作㻖㢧⪟-v2001-02-03-040506-123"},
|
||||
{"1/12-v2001-02-03-040506-123", "詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟-v2001-02-03-040506-123"},
|
||||
}, []EncodingTestCase{
|
||||
{"1", "詮㪗鐮僀伎作㻖㢧⪟"},
|
||||
{"1/12", "1/竢朧䉱虃光塬䟛⣡蓟"},
|
||||
{"1/12/123", "1/12/遶㞟鋅缕袡鲅ⵝ蝁ꌟ"},
|
||||
{"1-v2001-02-03-040506-123", "詮㪗鐮僀伎作㻖㢧⪟-v2001-02-03-040506-123"},
|
||||
{"1/12-v2001-02-03-040506-123", "1/竢朧䉱虃光塬䟛⣡蓟-v2001-02-03-040506-123"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestNonStandardEncryptFileName(t *testing.T) {
|
||||
// Off mode
|
||||
c, _ := newCipher(NameEncryptionOff, "", "", true, nil)
|
||||
assert.Equal(t, "1/12/123.bin", c.EncryptFileName("1/12/123"))
|
||||
// Obfuscation mode
|
||||
c, _ = newCipher(NameEncryptionObfuscated, "", "", true)
|
||||
c, _ = newCipher(NameEncryptionObfuscated, "", "", true, nil)
|
||||
assert.Equal(t, "49.6/99.23/150.890/53.!!lipps", c.EncryptFileName("1/12/123/!hello"))
|
||||
assert.Equal(t, "49.6/99.23/150.890/53-v2001-02-03-040506-123.!!lipps", c.EncryptFileName("1/12/123/!hello-v2001-02-03-040506-123"))
|
||||
assert.Equal(t, "49.6/99.23/150.890/162.uryyB-v2001-02-03-040506-123.GKG", c.EncryptFileName("1/12/123/hello-v2001-02-03-040506-123.txt"))
|
||||
assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1"))
|
||||
assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0"))
|
||||
// Obfuscation mode with directory name encryption off
|
||||
c, _ = newCipher(NameEncryptionObfuscated, "", "", false)
|
||||
c, _ = newCipher(NameEncryptionObfuscated, "", "", false, nil)
|
||||
assert.Equal(t, "1/12/123/53.!!lipps", c.EncryptFileName("1/12/123/!hello"))
|
||||
assert.Equal(t, "1/12/123/53-v2001-02-03-040506-123.!!lipps", c.EncryptFileName("1/12/123/!hello-v2001-02-03-040506-123"))
|
||||
assert.Equal(t, "161.\u00e4", c.EncryptFileName("\u00a1"))
|
||||
assert.Equal(t, "160.\u03c2", c.EncryptFileName("\u03a0"))
|
||||
}
|
||||
|
||||
func TestDecryptFileName(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
mode NameEncryptionMode
|
||||
dirNameEncrypt bool
|
||||
in string
|
||||
expected string
|
||||
expectedErr error
|
||||
}{
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize},
|
||||
{NameEncryptionStandard, false, "1/12/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s-v2001-02-03-040506-123", "1-v2001-02-03-040506-123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123.bin", "1/12/123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123.bix", "", ErrorNotAnEncryptedFile},
|
||||
{NameEncryptionOff, true, ".bin", "", ErrorNotAnEncryptedFile},
|
||||
{NameEncryptionOff, true, "1/12/123-v2001-02-03-040506-123.bin", "1/12/123-v2001-02-03-040506-123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123.bin", "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123.txt.bin", "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123.txt", nil},
|
||||
{NameEncryptionObfuscated, true, "!.hello", "hello", nil},
|
||||
{NameEncryptionObfuscated, true, "hello", "", ErrorNotAnEncryptedFile},
|
||||
{NameEncryptionObfuscated, true, "161.\u00e4", "\u00a1", nil},
|
||||
{NameEncryptionObfuscated, true, "160.\u03c2", "\u03a0", nil},
|
||||
{NameEncryptionObfuscated, false, "1/12/123/53.!!lipps", "1/12/123/!hello", nil},
|
||||
{NameEncryptionObfuscated, false, "1/12/123/53-v2001-02-03-040506-123.!!lipps", "1/12/123/!hello-v2001-02-03-040506-123", nil},
|
||||
} {
|
||||
c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt)
|
||||
func testStandardDecryptFileName(t *testing.T, encoding string, testCases []EncodingTestCase, caseInsensitive bool) {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
for _, test := range testCases {
|
||||
// Test when dirNameEncrypt=true
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
actual, actualErr := c.DecryptFileName(test.in)
|
||||
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
|
||||
assert.Equal(t, test.expected, actual, what)
|
||||
assert.Equal(t, test.expectedErr, actualErr, what)
|
||||
assert.NoError(t, actualErr)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
if caseInsensitive {
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
actual, actualErr := c.DecryptFileName(strings.ToUpper(test.in))
|
||||
assert.NoError(t, actualErr)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
}
|
||||
// Add a character should raise ErrorNotAMultipleOfBlocksize
|
||||
actual, actualErr = c.DecryptFileName(enc.EncodeToString([]byte("1")) + test.in)
|
||||
assert.Equal(t, ErrorNotAMultipleOfBlocksize, actualErr)
|
||||
assert.Equal(t, "", actual)
|
||||
// Test when dirNameEncrypt=false
|
||||
noDirEncryptIn := test.in
|
||||
if strings.LastIndex(test.expected, "/") != -1 {
|
||||
noDirEncryptIn = test.expected[:strings.LastIndex(test.expected, "/")] + test.in[strings.LastIndex(test.in, "/"):]
|
||||
}
|
||||
c, _ = newCipher(NameEncryptionStandard, "", "", false, enc)
|
||||
actual, actualErr = c.DecryptFileName(noDirEncryptIn)
|
||||
assert.NoError(t, actualErr)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStandardDecryptFileNameBase32(t *testing.T) {
|
||||
testStandardDecryptFileName(t, "base32", []EncodingTestCase{
|
||||
{"p0e52nreeaj0a5ea7s64m4j72s", "1"},
|
||||
{"p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12"},
|
||||
{"p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123"},
|
||||
}, true)
|
||||
}
|
||||
|
||||
func TestStandardDecryptFileNameBase64(t *testing.T) {
|
||||
testStandardDecryptFileName(t, "base64", []EncodingTestCase{
|
||||
{"yBxRX25ypgUVyj8MSxJnFw", "1"},
|
||||
{"yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA", "1/12"},
|
||||
{"yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA/1CxFf2Mti1xIPYlGruDh-A", "1/12/123"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestStandardDecryptFileNameBase32768(t *testing.T) {
|
||||
testStandardDecryptFileName(t, "base32768", []EncodingTestCase{
|
||||
{"詮㪗鐮僀伎作㻖㢧⪟", "1"},
|
||||
{"詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟", "1/12"},
|
||||
{"詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟/遶㞟鋅缕袡鲅ⵝ蝁ꌟ", "1/12/123"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestNonStandardDecryptFileName(t *testing.T) {
|
||||
for _, encoding := range []string{"base32", "base64", "base32768"} {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
for _, test := range []struct {
|
||||
mode NameEncryptionMode
|
||||
dirNameEncrypt bool
|
||||
in string
|
||||
expected string
|
||||
expectedErr error
|
||||
}{
|
||||
{NameEncryptionOff, true, "1/12/123.bin", "1/12/123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123.bix", "", ErrorNotAnEncryptedFile},
|
||||
{NameEncryptionOff, true, ".bin", "", ErrorNotAnEncryptedFile},
|
||||
{NameEncryptionOff, true, "1/12/123-v2001-02-03-040506-123.bin", "1/12/123-v2001-02-03-040506-123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123.bin", "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123.txt.bin", "1/12/123-v1970-01-01-010101-123-v2001-02-03-040506-123.txt", nil},
|
||||
{NameEncryptionObfuscated, true, "!.hello", "hello", nil},
|
||||
{NameEncryptionObfuscated, true, "hello", "", ErrorNotAnEncryptedFile},
|
||||
{NameEncryptionObfuscated, true, "161.\u00e4", "\u00a1", nil},
|
||||
{NameEncryptionObfuscated, true, "160.\u03c2", "\u03a0", nil},
|
||||
{NameEncryptionObfuscated, false, "1/12/123/53.!!lipps", "1/12/123/!hello", nil},
|
||||
{NameEncryptionObfuscated, false, "1/12/123/53-v2001-02-03-040506-123.!!lipps", "1/12/123/!hello-v2001-02-03-040506-123", nil},
|
||||
} {
|
||||
c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt, enc)
|
||||
actual, actualErr := c.DecryptFileName(test.in)
|
||||
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
|
||||
assert.Equal(t, test.expected, actual, what)
|
||||
assert.Equal(t, test.expectedErr, actualErr, what)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncDecMatches(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
mode NameEncryptionMode
|
||||
in string
|
||||
}{
|
||||
{NameEncryptionStandard, "1/2/3/4"},
|
||||
{NameEncryptionOff, "1/2/3/4"},
|
||||
{NameEncryptionObfuscated, "1/2/3/4/!hello\u03a0"},
|
||||
{NameEncryptionObfuscated, "Avatar The Last Airbender"},
|
||||
} {
|
||||
c, _ := newCipher(test.mode, "", "", true)
|
||||
out, err := c.DecryptFileName(c.EncryptFileName(test.in))
|
||||
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
|
||||
assert.Equal(t, out, test.in, what)
|
||||
assert.Equal(t, err, nil, what)
|
||||
for _, encoding := range []string{"base32", "base64", "base32768"} {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
for _, test := range []struct {
|
||||
mode NameEncryptionMode
|
||||
in string
|
||||
}{
|
||||
{NameEncryptionStandard, "1/2/3/4"},
|
||||
{NameEncryptionOff, "1/2/3/4"},
|
||||
{NameEncryptionObfuscated, "1/2/3/4/!hello\u03a0"},
|
||||
{NameEncryptionObfuscated, "Avatar The Last Airbender"},
|
||||
} {
|
||||
c, _ := newCipher(test.mode, "", "", true, enc)
|
||||
out, err := c.DecryptFileName(c.EncryptFileName(test.in))
|
||||
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
|
||||
assert.Equal(t, out, test.in, what)
|
||||
assert.Equal(t, err, nil, what)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncryptDirName(t *testing.T) {
|
||||
func testStandardEncryptDirName(t *testing.T, encoding string, testCases []EncodingTestCase) {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
// First standard mode
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true)
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s", c.EncryptDirName("1"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", c.EncryptDirName("1/12"))
|
||||
assert.Equal(t, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", c.EncryptDirName("1/12/123"))
|
||||
// Standard mode with dir name encryption off
|
||||
c, _ = newCipher(NameEncryptionStandard, "", "", false)
|
||||
assert.Equal(t, "1/12", c.EncryptDirName("1/12"))
|
||||
assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))
|
||||
// Now off mode
|
||||
c, _ = newCipher(NameEncryptionOff, "", "", true)
|
||||
assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))
|
||||
for _, test := range testCases {
|
||||
assert.Equal(t, test.expected, c.EncryptDirName(test.in))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecryptDirName(t *testing.T) {
|
||||
func TestStandardEncryptDirNameBase32(t *testing.T) {
|
||||
testStandardEncryptDirName(t, "base32", []EncodingTestCase{
|
||||
{"1", "p0e52nreeaj0a5ea7s64m4j72s"},
|
||||
{"1/12", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng"},
|
||||
{"1/12/123", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandardEncryptDirNameBase64(t *testing.T) {
|
||||
testStandardEncryptDirName(t, "base64", []EncodingTestCase{
|
||||
{"1", "yBxRX25ypgUVyj8MSxJnFw"},
|
||||
{"1/12", "yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA"},
|
||||
{"1/12/123", "yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA/1CxFf2Mti1xIPYlGruDh-A"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandardEncryptDirNameBase32768(t *testing.T) {
|
||||
testStandardEncryptDirName(t, "base32768", []EncodingTestCase{
|
||||
{"1", "詮㪗鐮僀伎作㻖㢧⪟"},
|
||||
{"1/12", "詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟"},
|
||||
{"1/12/123", "詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟/遶㞟鋅缕袡鲅ⵝ蝁ꌟ"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestNonStandardEncryptDirName(t *testing.T) {
|
||||
for _, encoding := range []string{"base32", "base64", "base32768"} {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", false, enc)
|
||||
assert.Equal(t, "1/12", c.EncryptDirName("1/12"))
|
||||
assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))
|
||||
// Now off mode
|
||||
c, _ = newCipher(NameEncryptionOff, "", "", true, enc)
|
||||
assert.Equal(t, "1/12/123", c.EncryptDirName("1/12/123"))
|
||||
}
|
||||
}
|
||||
|
||||
func testStandardDecryptDirName(t *testing.T, encoding string, testCases []EncodingTestCase, caseInsensitive bool) {
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
for _, test := range testCases {
|
||||
// Test dirNameEncrypt=true
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, enc)
|
||||
actual, actualErr := c.DecryptDirName(test.in)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
assert.NoError(t, actualErr)
|
||||
if caseInsensitive {
|
||||
actual, actualErr := c.DecryptDirName(strings.ToUpper(test.in))
|
||||
assert.Equal(t, actual, test.expected)
|
||||
assert.NoError(t, actualErr)
|
||||
}
|
||||
actual, actualErr = c.DecryptDirName(enc.EncodeToString([]byte("1")) + test.in)
|
||||
assert.Equal(t, "", actual)
|
||||
assert.Equal(t, ErrorNotAMultipleOfBlocksize, actualErr)
|
||||
// Test dirNameEncrypt=false
|
||||
c, _ = newCipher(NameEncryptionStandard, "", "", false, enc)
|
||||
actual, actualErr = c.DecryptDirName(test.in)
|
||||
assert.Equal(t, test.in, actual)
|
||||
assert.NoError(t, actualErr)
|
||||
actual, actualErr = c.DecryptDirName(test.expected)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
assert.NoError(t, actualErr)
|
||||
// Test dirNameEncrypt=false
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
enc, _ := NewNameEncoding(encoding)
|
||||
for _, test := range []struct {
|
||||
mode NameEncryptionMode
|
||||
dirNameEncrypt bool
|
||||
in string
|
||||
expected string
|
||||
expectedErr error
|
||||
}{
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize},
|
||||
{NameEncryptionStandard, false, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", nil},
|
||||
{NameEncryptionStandard, false, "1/12/123", "1/12/123", nil},
|
||||
} {
|
||||
c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt, enc)
|
||||
actual, actualErr := c.DecryptDirName(test.in)
|
||||
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
|
||||
assert.Equal(t, test.expected, actual, what)
|
||||
assert.Equal(t, test.expectedErr, actualErr, what)
|
||||
}
|
||||
*/
|
||||
|
||||
func TestStandardDecryptDirNameBase32(t *testing.T) {
|
||||
testStandardDecryptDirName(t, "base32", []EncodingTestCase{
|
||||
{"p0e52nreeaj0a5ea7s64m4j72s", "1"},
|
||||
{"p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12"},
|
||||
{"p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123"},
|
||||
}, true)
|
||||
}
|
||||
|
||||
func TestStandardDecryptDirNameBase64(t *testing.T) {
|
||||
testStandardDecryptDirName(t, "base64", []EncodingTestCase{
|
||||
{"yBxRX25ypgUVyj8MSxJnFw", "1"},
|
||||
{"yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA", "1/12"},
|
||||
{"yBxRX25ypgUVyj8MSxJnFw/qQUDHOGN_jVdLIMQzYrhvA/1CxFf2Mti1xIPYlGruDh-A", "1/12/123"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestStandardDecryptDirNameBase32768(t *testing.T) {
|
||||
testStandardDecryptDirName(t, "base32768", []EncodingTestCase{
|
||||
{"詮㪗鐮僀伎作㻖㢧⪟", "1"},
|
||||
{"詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟", "1/12"},
|
||||
{"詮㪗鐮僀伎作㻖㢧⪟/竢朧䉱虃光塬䟛⣡蓟/遶㞟鋅缕袡鲅ⵝ蝁ꌟ", "1/12/123"},
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestNonStandardDecryptDirName(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
mode NameEncryptionMode
|
||||
dirNameEncrypt bool
|
||||
@ -264,18 +658,11 @@ func TestDecryptDirName(t *testing.T) {
|
||||
expected string
|
||||
expectedErr error
|
||||
}{
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s", "1", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "1/12", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeAJ0A5EA7S64M4J72S/L42G6771HNv3an9cgc8cr2n1ng", "1/12", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng/qgm4avr35m5loi1th53ato71v0", "1/12/123", nil},
|
||||
{NameEncryptionStandard, true, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1/qgm4avr35m5loi1th53ato71v0", "", ErrorNotAMultipleOfBlocksize},
|
||||
{NameEncryptionStandard, false, "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", "p0e52nreeaj0a5ea7s64m4j72s/l42g6771hnv3an9cgc8cr2n1ng", nil},
|
||||
{NameEncryptionStandard, false, "1/12/123", "1/12/123", nil},
|
||||
{NameEncryptionOff, true, "1/12/123.bin", "1/12/123.bin", nil},
|
||||
{NameEncryptionOff, true, "1/12/123", "1/12/123", nil},
|
||||
{NameEncryptionOff, true, ".bin", ".bin", nil},
|
||||
} {
|
||||
c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt)
|
||||
c, _ := newCipher(test.mode, "", "", test.dirNameEncrypt, nil)
|
||||
actual, actualErr := c.DecryptDirName(test.in)
|
||||
what := fmt.Sprintf("Testing %q (mode=%v)", test.in, test.mode)
|
||||
assert.Equal(t, test.expected, actual, what)
|
||||
@ -284,7 +671,7 @@ func TestDecryptDirName(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEncryptedSize(t *testing.T) {
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
for _, test := range []struct {
|
||||
in int64
|
||||
expected int64
|
||||
@ -308,7 +695,7 @@ func TestEncryptedSize(t *testing.T) {
|
||||
|
||||
func TestDecryptedSize(t *testing.T) {
|
||||
// Test the errors since we tested the reverse above
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, _ := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
for _, test := range []struct {
|
||||
in int64
|
||||
expectedErr error
|
||||
@ -679,7 +1066,7 @@ func (z *zeroes) Read(p []byte) (n int, err error) {
|
||||
|
||||
// Test encrypt decrypt with different buffer sizes
|
||||
func testEncryptDecrypt(t *testing.T, bufSize int, copySize int64) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
c.cryptoRand = &zeroes{} // zero out the nonce
|
||||
buf := make([]byte, bufSize)
|
||||
@ -749,7 +1136,7 @@ func TestEncryptData(t *testing.T) {
|
||||
{[]byte{1}, file1},
|
||||
{[]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, file16},
|
||||
} {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
c.cryptoRand = newRandomSource(1e8) // nodge the crypto rand generator
|
||||
|
||||
@ -772,7 +1159,7 @@ func TestEncryptData(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewEncrypter(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
c.cryptoRand = newRandomSource(1e8) // nodge the crypto rand generator
|
||||
|
||||
@ -788,13 +1175,12 @@ func TestNewEncrypter(t *testing.T) {
|
||||
fh, err = c.newEncrypter(z, nil)
|
||||
assert.Nil(t, fh)
|
||||
assert.Error(t, err, "short read of nonce")
|
||||
|
||||
}
|
||||
|
||||
// Test the stream returning 0, io.ErrUnexpectedEOF - this used to
|
||||
// cause a fatal loop
|
||||
func TestNewEncrypterErrUnexpectedEOF(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
in := &readers.ErrorReader{Err: io.ErrUnexpectedEOF}
|
||||
@ -823,7 +1209,7 @@ func (c *closeDetector) Close() error {
|
||||
}
|
||||
|
||||
func TestNewDecrypter(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
c.cryptoRand = newRandomSource(1e8) // nodge the crypto rand generator
|
||||
|
||||
@ -866,7 +1252,7 @@ func TestNewDecrypter(t *testing.T) {
|
||||
|
||||
// Test the stream returning 0, io.ErrUnexpectedEOF
|
||||
func TestNewDecrypterErrUnexpectedEOF(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
in2 := &readers.ErrorReader{Err: io.ErrUnexpectedEOF}
|
||||
@ -882,7 +1268,7 @@ func TestNewDecrypterErrUnexpectedEOF(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNewDecrypterSeekLimit(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
c.cryptoRand = &zeroes{} // nodge the crypto rand generator
|
||||
|
||||
@ -1088,7 +1474,7 @@ func TestDecrypterCalculateUnderlying(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDecrypterRead(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Test truncating the file at each possible point
|
||||
@ -1152,7 +1538,7 @@ func TestDecrypterRead(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDecrypterClose(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
cd := newCloseDetector(bytes.NewBuffer(file16))
|
||||
@ -1190,7 +1576,7 @@ func TestDecrypterClose(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPutGetBlock(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
block := c.getBlock()
|
||||
@ -1201,7 +1587,7 @@ func TestPutGetBlock(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestKey(t *testing.T) {
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true)
|
||||
c, err := newCipher(NameEncryptionStandard, "", "", true, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check zero keys OK
|
||||
|
@ -29,7 +29,7 @@ func TestIntegration(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestStandard runs integration tests against the remote
|
||||
func TestStandard(t *testing.T) {
|
||||
func TestStandardBase32(t *testing.T) {
|
||||
if *fstest.RemoteName != "" {
|
||||
t.Skip("Skipping as -remote set")
|
||||
}
|
||||
@ -49,6 +49,48 @@ func TestStandard(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandardBase64(t *testing.T) {
|
||||
if *fstest.RemoteName != "" {
|
||||
t.Skip("Skipping as -remote set")
|
||||
}
|
||||
tempdir := filepath.Join(os.TempDir(), "rclone-crypt-test-standard")
|
||||
name := "TestCrypt"
|
||||
fstests.Run(t, &fstests.Opt{
|
||||
RemoteName: name + ":",
|
||||
NilObject: (*crypt.Object)(nil),
|
||||
ExtraConfig: []fstests.ExtraConfigItem{
|
||||
{Name: name, Key: "type", Value: "crypt"},
|
||||
{Name: name, Key: "remote", Value: tempdir},
|
||||
{Name: name, Key: "password", Value: obscure.MustObscure("potato")},
|
||||
{Name: name, Key: "filename_encryption", Value: "standard"},
|
||||
{Name: name, Key: "filename_encoding", Value: "base64"},
|
||||
},
|
||||
UnimplementableFsMethods: []string{"OpenWriterAt"},
|
||||
UnimplementableObjectMethods: []string{"MimeType"},
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandardBase32768(t *testing.T) {
|
||||
if *fstest.RemoteName != "" {
|
||||
t.Skip("Skipping as -remote set")
|
||||
}
|
||||
tempdir := filepath.Join(os.TempDir(), "rclone-crypt-test-standard")
|
||||
name := "TestCrypt"
|
||||
fstests.Run(t, &fstests.Opt{
|
||||
RemoteName: name + ":",
|
||||
NilObject: (*crypt.Object)(nil),
|
||||
ExtraConfig: []fstests.ExtraConfigItem{
|
||||
{Name: name, Key: "type", Value: "crypt"},
|
||||
{Name: name, Key: "remote", Value: tempdir},
|
||||
{Name: name, Key: "password", Value: obscure.MustObscure("potato")},
|
||||
{Name: name, Key: "filename_encryption", Value: "standard"},
|
||||
{Name: name, Key: "filename_encoding", Value: "base32768"},
|
||||
},
|
||||
UnimplementableFsMethods: []string{"OpenWriterAt"},
|
||||
UnimplementableObjectMethods: []string{"MimeType"},
|
||||
})
|
||||
}
|
||||
|
||||
// TestOff runs integration tests against the remote
|
||||
func TestOff(t *testing.T) {
|
||||
if *fstest.RemoteName != "" {
|
||||
|
@ -373,6 +373,14 @@ total path length which rclone is more likely to breach using
|
||||
characters in length issues should not be encountered, irrespective of
|
||||
cloud storage provider.
|
||||
|
||||
An experimental advanced option `filename_encoding` is now provided to
|
||||
address this problem to a certain degree.
|
||||
For cloud storage systems with case sensitive file names (e.g. Google Drive),
|
||||
`base64` can be used to reduce file name length.
|
||||
For cloud storage systems using UTF-16 to store file names internally
|
||||
(e.g. OneDrive), `base32768` can be used to drastically reduce
|
||||
file name length.
|
||||
|
||||
An alternative, future rclone file name encryption mode may tolerate
|
||||
backend provider path length limits.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user