mirror of
https://github.com/kopia/kopia.git
synced 2026-01-25 06:48:48 -05:00
Revert "changed JSON encryption key to be base16-encoded instead of base64-encoded"
Instead, changed JSON serialization format for ObjectID to be simple string.
This reverts commit 4ab146e058.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -40,12 +41,30 @@
|
||||
//
|
||||
type ObjectID struct {
|
||||
StorageBlock string `json:"block,omitempty"`
|
||||
EncryptionKey string `json:"encryption,omitempty"`
|
||||
EncryptionKey []byte `json:"encryption,omitempty"`
|
||||
Indirect int32 `json:"indirect,omitempty"`
|
||||
Content []byte `json:"content,omitempty"`
|
||||
Section *ObjectIDSection `json:"section,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON emits ObjectID in standard string format.
|
||||
func (oid *ObjectID) MarshalJSON() ([]byte, error) {
|
||||
s := oid.UIString()
|
||||
return json.Marshal(&s)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals Object ID from a JSON string.
|
||||
func (oid *ObjectID) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*oid, err = ParseObjectID(s)
|
||||
return err
|
||||
}
|
||||
|
||||
// ObjectIDSection represents details about a section of a repository object.
|
||||
type ObjectIDSection struct {
|
||||
Start int64 `json:"start"`
|
||||
@@ -75,7 +94,7 @@ func (oid *ObjectID) UIString() string {
|
||||
var encryptionSuffix string
|
||||
|
||||
if len(oid.EncryptionKey) > 0 {
|
||||
encryptionSuffix = "." + oid.EncryptionKey
|
||||
encryptionSuffix = "." + hex.EncodeToString(oid.EncryptionKey)
|
||||
}
|
||||
|
||||
if oid.Indirect > 0 {
|
||||
@@ -239,13 +258,12 @@ func ParseObjectID(s string) (ObjectID, error) {
|
||||
}
|
||||
|
||||
if firstSeparator > 0 {
|
||||
enc := content[firstSeparator+1:]
|
||||
b, err := hex.DecodeString(enc)
|
||||
b, err := hex.DecodeString(content[firstSeparator+1:])
|
||||
if err == nil && len(b) > 0 {
|
||||
// Valid chunk ID with encryption info.
|
||||
return ObjectID{
|
||||
StorageBlock: content[0:firstSeparator],
|
||||
EncryptionKey: enc,
|
||||
EncryptionKey: b,
|
||||
Indirect: indirectLevel,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -41,18 +42,18 @@ func TestParseMalformedObjectID(t *testing.T) {
|
||||
func TestParseObjectIDEncryptionInfo(t *testing.T) {
|
||||
cases := []struct {
|
||||
objectID string
|
||||
expected string
|
||||
expected []byte
|
||||
}{
|
||||
{"B", ""},
|
||||
{"BAQIDBA", ""},
|
||||
{"Dabcdef", ""},
|
||||
{"I1,abcdef", ""},
|
||||
{"I2,abcdef", ""},
|
||||
{"Dabcdef.00112233", "00112233"},
|
||||
{"I1,abcdef.0011223344", "0011223344"},
|
||||
{"I2,abcdef.0011223344", "0011223344"},
|
||||
{"S1,2,Dabcdef.0011223344", ""},
|
||||
{"S1,2,S3,4,Dabcdef.0011223344", ""},
|
||||
{"B", nil},
|
||||
{"BAQIDBA", nil},
|
||||
{"Dabcdef", nil},
|
||||
{"I1,abcdef", nil},
|
||||
{"I2,abcdef", nil},
|
||||
{"Dabcdef.00112233", []byte{0x00, 0x11, 0x22, 0x33}},
|
||||
{"I1,abcdef.0011223344", []byte{0x00, 0x11, 0x22, 0x33, 0x44}},
|
||||
{"I2,abcdef.0011223344", []byte{0x00, 0x11, 0x22, 0x33, 0x44}},
|
||||
{"S1,2,Dabcdef.0011223344", nil},
|
||||
{"S1,2,S3,4,Dabcdef.0011223344", nil},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@@ -63,8 +64,8 @@ func TestParseObjectIDEncryptionInfo(t *testing.T) {
|
||||
}
|
||||
|
||||
actual := objectID.EncryptionKey
|
||||
if actual != c.expected {
|
||||
t.Errorf("invalid encryption key for %v: %v, expected: %v", c.objectID, actual, c.expected)
|
||||
if !bytes.Equal(actual, c.expected) {
|
||||
t.Errorf("invalid encryption key for %v: %x, expected: %x", c.objectID, actual, c.expected)
|
||||
}
|
||||
|
||||
uiString := objectID.UIString()
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -228,7 +227,7 @@ func (r *Repository) hashEncryptAndWriteMaybeAsync(buffer *bytes.Buffer, prefix
|
||||
|
||||
objectID := ObjectID{
|
||||
StorageBlock: prefix + blockID,
|
||||
EncryptionKey: hex.EncodeToString(encryptionKey),
|
||||
EncryptionKey: encryptionKey,
|
||||
}
|
||||
|
||||
if r.writeBackWorkers > 0 {
|
||||
@@ -276,13 +275,9 @@ func (r *Repository) hashEncryptAndWrite(objectID ObjectID, buffer *bytes.Buffer
|
||||
}
|
||||
|
||||
// Encryption is requested, encrypt the block in-place.
|
||||
if len(objectID.EncryptionKey) > 0 {
|
||||
if objectID.EncryptionKey != nil {
|
||||
atomic.AddInt64(&r.Stats.EncryptedBytes, int64(len(data)))
|
||||
b, err := hex.DecodeString(objectID.EncryptionKey)
|
||||
if err != nil {
|
||||
return NullObjectID, fmt.Errorf("invalid encryption key: %v", err)
|
||||
}
|
||||
data, err = r.formatter.Encrypt(data, b)
|
||||
data, err = r.formatter.Encrypt(data, objectID.EncryptionKey)
|
||||
if err != nil {
|
||||
return NullObjectID, err
|
||||
}
|
||||
@@ -347,11 +342,7 @@ func (r *Repository) newRawReader(objectID ObjectID) (ObjectReader, error) {
|
||||
atomic.AddInt64(&r.Stats.ReadBytes, int64(len(payload)))
|
||||
|
||||
if len(objectID.EncryptionKey) > 0 {
|
||||
b, err := hex.DecodeString(objectID.EncryptionKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid encryption key: %v", err)
|
||||
}
|
||||
payload, err = r.formatter.Decrypt(payload, b)
|
||||
payload, err = r.formatter.Decrypt(payload, objectID.EncryptionKey)
|
||||
atomic.AddInt64(&r.Stats.DecryptedBytes, int64(len(payload)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -163,9 +163,9 @@ func TestIndirection(t *testing.T) {
|
||||
{dataLength: 250, expectedBlockCount: 3, expectedIndirection: 1},
|
||||
{dataLength: 1400, expectedBlockCount: 7, expectedIndirection: 3},
|
||||
{dataLength: 2000, expectedBlockCount: 8, expectedIndirection: 3},
|
||||
{dataLength: 3000, expectedBlockCount: 13, expectedIndirection: 4},
|
||||
{dataLength: 4000, expectedBlockCount: 15, expectedIndirection: 4},
|
||||
{dataLength: 10000, expectedBlockCount: 32, expectedIndirection: 5},
|
||||
{dataLength: 3000, expectedBlockCount: 9, expectedIndirection: 3},
|
||||
{dataLength: 4000, expectedBlockCount: 14, expectedIndirection: 4},
|
||||
{dataLength: 10000, expectedBlockCount: 25, expectedIndirection: 4},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@@ -438,7 +438,7 @@ func TestFormats(t *testing.T) {
|
||||
oids: map[string]ObjectID{
|
||||
"The quick brown fox jumps over the lazy dog": ObjectID{
|
||||
StorageBlock: "d7f4727e2c0b39ae0f1e40cc96f60242",
|
||||
EncryptionKey: "d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237",
|
||||
EncryptionKey: mustParseBase16("d5b7801841cea6fc592c5d3e1ae50700582a96cf35e1e554995fe4e03381c237"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -447,7 +447,7 @@ func TestFormats(t *testing.T) {
|
||||
oids: map[string]ObjectID{
|
||||
"The quick brown fox jumps over the lazy dog": ObjectID{
|
||||
StorageBlock: "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb",
|
||||
EncryptionKey: "82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a",
|
||||
EncryptionKey: mustParseBase16("82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -533,13 +533,14 @@ func TestInvalidEncryptionKey(t *testing.T) {
|
||||
}
|
||||
|
||||
// Key too long
|
||||
rc, err = repo.Open(replaceEncryption(oid, oid.EncryptionKey+"FF"))
|
||||
rc, err = repo.Open(replaceEncryption(oid, append(oid.EncryptionKey, 0xFF)))
|
||||
if err == nil || rc != nil {
|
||||
t.Errorf("expected error when opening malformed object")
|
||||
}
|
||||
|
||||
// Invalid key
|
||||
corruptedKey := oid.EncryptionKey[2:] + oid.EncryptionKey[len(oid.EncryptionKey)-2:]
|
||||
corruptedKey := append([]byte(nil), oid.EncryptionKey...)
|
||||
corruptedKey[0]++
|
||||
rc, err = repo.Open(replaceEncryption(oid, corruptedKey))
|
||||
if err == nil || rc != nil {
|
||||
t.Errorf("expected error when opening malformed object: %v", err)
|
||||
@@ -553,7 +554,15 @@ func TestInvalidEncryptionKey(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func replaceEncryption(oid ObjectID, newEncryption string) ObjectID {
|
||||
func replaceEncryption(oid ObjectID, newEncryption []byte) ObjectID {
|
||||
oid.EncryptionKey = newEncryption
|
||||
return oid
|
||||
}
|
||||
|
||||
func mustParseBase16(s string) []byte {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic("invalid hex literal: " + s)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user