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:
Jarek Kowalski
2016-08-28 22:16:30 -07:00
parent 4ab146e058
commit eeacdd1e3d
4 changed files with 58 additions and 39 deletions

View File

@@ -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
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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
}