Provide a nice SignAndSerialize testutil function to export metadata from a repo.

Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
Ying Li 2016-04-20 11:01:02 -07:00
parent be82a0a5f4
commit b2349a0385
2 changed files with 62 additions and 55 deletions

View File

@ -56,9 +56,7 @@ func TestGetTimestampNoPreviousTimestamp(t *testing.T) {
repo, crypto, err := testutils.EmptyRepo("gun")
require.NoError(t, err)
rootJSON, err := json.Marshal(repo.Root)
require.NoError(t, err)
snapJSON, err := json.Marshal(repo.Snapshot)
meta, err := testutils.SignAndSerialize(repo)
require.NoError(t, err)
for _, timestampJSON := range [][]byte{nil, []byte("invalid JSON")} {
@ -66,9 +64,11 @@ func TestGetTimestampNoPreviousTimestamp(t *testing.T) {
// so we know it's not a failure in getting root or snapshot
require.NoError(t,
store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: rootJSON}))
store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0,
Data: meta[data.CanonicalRootRole]}))
require.NoError(t,
store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapJSON}))
store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0,
Data: meta[data.CanonicalSnapshotRole]}))
if timestampJSON != nil {
require.NoError(t,
@ -98,19 +98,17 @@ func TestGetTimestampReturnsPreviousTimestampIfUnexpired(t *testing.T) {
repo, crypto, err := testutils.EmptyRepo("gun")
require.NoError(t, err)
snapJSON, err := json.Marshal(repo.Snapshot)
require.NoError(t, err)
timestampJSON, err := json.Marshal(repo.Timestamp)
meta, err := testutils.SignAndSerialize(repo)
require.NoError(t, err)
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapJSON}))
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: meta[data.CanonicalSnapshotRole]}))
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 0, Data: timestampJSON}))
storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 0, Data: meta[data.CanonicalTimestampRole]}))
_, gottenTimestamp, err := GetOrCreateTimestamp("gun", store, crypto)
require.NoError(t, err, "GetTimestamp should not have failed")
require.True(t, bytes.Equal(timestampJSON, gottenTimestamp))
require.True(t, bytes.Equal(meta[data.CanonicalTimestampRole], gottenTimestamp))
}
func TestGetTimestampOldTimestampExpired(t *testing.T) {
@ -118,9 +116,7 @@ func TestGetTimestampOldTimestampExpired(t *testing.T) {
repo, crypto, err := testutils.EmptyRepo("gun")
require.NoError(t, err)
rootJSON, err := json.Marshal(repo.Root)
require.NoError(t, err)
snapJSON, err := json.Marshal(repo.Snapshot)
meta, err := testutils.SignAndSerialize(repo)
require.NoError(t, err)
// create an expired timestamp
@ -132,9 +128,9 @@ func TestGetTimestampOldTimestampExpired(t *testing.T) {
// set all the metadata
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: rootJSON}))
storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: meta[data.CanonicalRootRole]}))
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapJSON}))
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: meta[data.CanonicalSnapshotRole]}))
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 1, Data: timestampJSON}))
@ -155,9 +151,7 @@ func TestCannotMakeNewTimestampIfNoRootOrSnapshot(t *testing.T) {
repo, crypto, err := testutils.EmptyRepo("gun")
require.NoError(t, err)
rootJSON, err := json.Marshal(repo.Root)
require.NoError(t, err)
snapJSON, err := json.Marshal(repo.Snapshot)
meta, err := testutils.SignAndSerialize(repo)
require.NoError(t, err)
// create an expired timestamp
@ -167,6 +161,9 @@ func TestCannotMakeNewTimestampIfNoRootOrSnapshot(t *testing.T) {
timestampJSON, err := json.Marshal(repo.Timestamp)
require.NoError(t, err)
rootJSON := meta[data.CanonicalRootRole]
snapJSON := meta[data.CanonicalSnapshotRole]
invalids := []struct {
test map[string][]byte
err error
@ -210,9 +207,7 @@ func TestCreateTimestampNoKeyInCrypto(t *testing.T) {
repo, _, err := testutils.EmptyRepo("gun")
require.NoError(t, err)
rootJSON, err := json.Marshal(repo.Root)
require.NoError(t, err)
snapJSON, err := json.Marshal(repo.Snapshot)
meta, err := testutils.SignAndSerialize(repo)
require.NoError(t, err)
// create an expired timestamp
@ -224,9 +219,9 @@ func TestCreateTimestampNoKeyInCrypto(t *testing.T) {
// set all the metadata so we know the failure to sign is just because of the key
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: rootJSON}))
storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: meta[data.CanonicalRootRole]}))
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapJSON}))
storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: meta[data.CanonicalSnapshotRole]}))
require.NoError(t, store.UpdateCurrent("gun",
storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 1, Data: timestampJSON}))

View File

@ -99,41 +99,11 @@ func NewRepoMetadata(gun string, delegationRoles ...string) (map[string][]byte,
return nil, nil, err
}
meta := make(map[string][]byte)
for _, delgName := range delegationRoles {
// is there metadata yet? if empty, it may not be created
if _, ok := tufRepo.Targets[delgName]; ok {
signedThing, err := tufRepo.SignTargets(delgName, data.DefaultExpires("targets"))
if err != nil {
return nil, nil, err
}
metaBytes, err := json.MarshalCanonical(signedThing)
if err != nil {
return nil, nil, err
}
meta[delgName] = metaBytes
}
}
// these need to be generated after the delegations are created and signed so
// the snapshot will have the delegation metadata
rs, tgs, ss, ts, err := Sign(tufRepo)
meta, err := SignAndSerialize(tufRepo)
if err != nil {
return nil, nil, err
}
rf, tgf, sf, tf, err := Serialize(rs, tgs, ss, ts)
if err != nil {
return nil, nil, err
}
meta[data.CanonicalRootRole] = rf
meta[data.CanonicalSnapshotRole] = sf
meta[data.CanonicalTargetsRole] = tgf
meta[data.CanonicalTimestampRole] = tf
return meta, cs, nil
}
@ -174,6 +144,48 @@ func RandomByteSlice(maxSize int) []byte {
return content
}
// SignAndSerialize calls Sign and then Serialize to get the repo metadata out
func SignAndSerialize(tufRepo *tuf.Repo) (map[string][]byte, error) {
meta := make(map[string][]byte)
for delgName := range tufRepo.Targets {
// we'll sign targets later
if delgName == data.CanonicalTargetsRole {
continue
}
signedThing, err := tufRepo.SignTargets(delgName, data.DefaultExpires("targets"))
if err != nil {
return nil, err
}
metaBytes, err := json.MarshalCanonical(signedThing)
if err != nil {
return nil, err
}
meta[delgName] = metaBytes
}
// these need to be generated after the delegations are created and signed so
// the snapshot will have the delegation metadata
rs, tgs, ss, ts, err := Sign(tufRepo)
if err != nil {
return nil, err
}
rf, tgf, sf, tf, err := Serialize(rs, tgs, ss, ts)
if err != nil {
return nil, err
}
meta[data.CanonicalRootRole] = rf
meta[data.CanonicalSnapshotRole] = sf
meta[data.CanonicalTargetsRole] = tgf
meta[data.CanonicalTimestampRole] = tf
return meta, nil
}
// Sign signs all top level roles in a repo in the appropriate order
func Sign(repo *tuf.Repo) (root, targets, snapshot, timestamp *data.Signed, err error) {
root, err = repo.SignRoot(data.DefaultExpires("root"))