Skip to content

Commit

Permalink
chore!: Remove deprecated client Init() function (#353)
Browse files Browse the repository at this point in the history
* chore!: Remove deprecated client Init() function

Has been deprecated for a release or so.

This fixes some tests and removes others; the removals are all
justified:

- TestInitRootExpired: testing of InitLocal checks the behavior on
  expired roots (which is *different*; it allows expired roots)
- TestInitRootTooLarge: covered now in TestUpdate

We also add a "RawMeta" function, used to get at the root json. I could
be persuaded that this should be a "RawRoot" instead.

BREAKING CHANGE: remove client.Init() in favor of InitLocal()

Signed-off-by: Zachary Newman <z@znewman.net>

* refactor: replace Repo.RawMeta with Repo.GetMeta

Signed-off-by: Zachary Newman <z@znewman.net>
  • Loading branch information
znewman01 authored Aug 5, 2022
1 parent 1b070ee commit 8124e8a
Show file tree
Hide file tree
Showing 38 changed files with 1,352 additions and 76 deletions.
43 changes: 0 additions & 43 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,49 +106,6 @@ func NewClient(local LocalStore, remote RemoteStore) *Client {
}
}

// Init initializes a local repository.
//
// The latest root.json is fetched from remote storage, verified using rootKeys
// and threshold, and then saved in local storage. It is expected that rootKeys
// were securely distributed with the software being updated.
//
// Deprecated: Use c.InitLocal and c.Update to initialize a local repository.
func (c *Client) Init(rootKeys []*data.PublicKey, threshold int) error {
if len(rootKeys) < threshold {
return ErrInsufficientKeys
}
rootJSON, err := c.downloadMetaUnsafe("root.json", defaultRootDownloadLimit)
if err != nil {
return err
}

// create a new key database, and add all the public `rootKeys` to it.
c.db = verify.NewDB()
rootKeyIDs := make([]string, 0, len(rootKeys))
for _, key := range rootKeys {
for _, id := range key.IDs() {
rootKeyIDs = append(rootKeyIDs, id)
if err := c.db.AddKey(id, key); err != nil {
return err
}
}
}

// add a mock "root" role that trusts the passed in key ids. These keys
// will be used to verify the `root.json` we just fetched.
role := &data.Role{Threshold: threshold, KeyIDs: rootKeyIDs}
if err := c.db.AddRole("root", role); err != nil {
return err
}

// verify that the new root is valid.
if err := c.decodeRoot(rootJSON); err != nil {
return err
}

return c.local.SetMeta("root.json", rootJSON)
}

// InitLocal initializes a local repository from root metadata.
//
// The root's keys are extracted from the root and saved in local storage.
Expand Down
52 changes: 19 additions & 33 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,18 @@ func (s *ClientSuite) addRemoteTarget(c *C, name string) {
s.syncRemote(c)
}

func (s *ClientSuite) rootKeys(c *C) []*data.PublicKey {
rootKeys, err := s.repo.RootKeys()
func (s *ClientSuite) rootMeta(c *C) []byte {
meta, err := s.repo.GetMeta()
c.Assert(err, IsNil)
c.Assert(rootKeys, HasLen, 1)
return rootKeys
rootMeta, ok := meta["root.json"]
c.Assert(ok, Equals, true)
return rootMeta
}

func (s *ClientSuite) newClient(c *C) *Client {
s.local = MemoryLocalStore()
client := NewClient(s.local, s.remote)
c.Assert(client.Init(s.rootKeys(c), 1), IsNil)
c.Assert(client.InitLocal(s.rootMeta(c)), IsNil)
return client
}

Expand Down Expand Up @@ -243,39 +244,21 @@ func (s *ClientSuite) assertErrExpired(c *C, err error, file string) {
c.Assert(expiredErr.Expired.Unix(), Equals, s.expiredTime.Round(time.Second).Unix())
}

func (s *ClientSuite) TestInitRootTooLarge(c *C) {
client := NewClient(MemoryLocalStore(), s.remote)
s.remote.meta["root.json"] = newFakeFile(make([]byte, defaultRootDownloadLimit+1))
c.Assert(client.Init(s.rootKeys(c), 0), Equals, ErrMetaTooLarge{"root.json", defaultRootDownloadLimit + 1, defaultRootDownloadLimit})
}

func (s *ClientSuite) TestInitRootExpired(c *C) {
s.genKeyExpired(c, "targets")
c.Assert(s.repo.Snapshot(), IsNil)
c.Assert(s.repo.Timestamp(), IsNil)
c.Assert(s.repo.Commit(), IsNil)
s.syncRemote(c)
client := NewClient(MemoryLocalStore(), s.remote)
s.withMetaExpired(func() {
s.assertErrExpired(c, client.Init(s.rootKeys(c), 1), "root.json")
})
}

func (s *ClientSuite) TestInit(c *C) {
client := NewClient(MemoryLocalStore(), s.remote)

// check Init() returns keys.ErrInvalidThreshold with an invalid threshold
c.Assert(client.Init(s.rootKeys(c), 0), Equals, verify.ErrInvalidThreshold)

// check Init() returns signed.ErrRoleThreshold when not enough keys
c.Assert(client.Init(s.rootKeys(c), 2), Equals, ErrInsufficientKeys)
// check invalid json
c.Assert(client.InitLocal(make([]byte, 0)), NotNil)
rootJson := `{ "signatures": [], "signed": {"version": "wrongtype"}, "spec_version": "1.0.0", "version": 1}`
err := client.InitLocal([]byte(rootJson))
c.Assert(err.Error(), Matches, "json: cannot unmarshal string.*")

// check Update() returns ErrNoRootKeys when uninitialized
_, err := client.Update()
_, err = client.Update()
c.Assert(err, Equals, ErrNoRootKeys)

// check Update() does not return ErrNoRootKeys after initialization
c.Assert(client.Init(s.rootKeys(c), 1), IsNil)
c.Assert(client.InitLocal(s.rootMeta(c)), IsNil)
_, err = client.Update()
c.Assert(err, IsNil)
}
Expand Down Expand Up @@ -489,6 +472,8 @@ func (s *ClientSuite) TestUpdateRoots(c *C) {
{"testdata/Published2Times_targets_keyrotated", nil, map[string]int64{"root": 2, "timestamp": 2, "snapshot": 2, "targets": 2}},
// timestamp role key rotation increase the timestamp.
{"testdata/Published2Times_timestamp_keyrotated", nil, map[string]int64{"root": 2, "timestamp": 2, "snapshot": 1, "targets": 1}},
//root file size > defaultRootDownloadLimit
{"testdata/Published2Times_roottoolarge", ErrMetaTooLarge{Name: "2.root.json", Size: defaultRootDownloadLimit + 1, MaxSize: defaultRootDownloadLimit}, map[string]int64{}},
}

for _, test := range tests {
Expand Down Expand Up @@ -1053,10 +1038,11 @@ func (s *ClientSuite) TestUpdateHTTP(c *C) {
remote, err := HTTPRemoteStore(fmt.Sprintf("http://%s/%s/repository", addr, dir), nil, nil)
c.Assert(err, IsNil)
client := NewClient(MemoryLocalStore(), remote)
rootKeys, err := repo.RootKeys()
rootMeta, err := repo.SignedMeta("root.json")
c.Assert(err, IsNil)
rootJsonBytes, err := json.Marshal(rootMeta)
c.Assert(err, IsNil)
c.Assert(rootKeys, HasLen, 1)
c.Assert(client.Init(rootKeys, 1), IsNil)
c.Assert(client.InitLocal(rootJsonBytes), IsNil)

// check update is ok
targets, err := client.Update()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"signatures": [
{
"keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
"sig": "481a1bd10fedbe33e88e5f586a8726f558a5ec426bf65d2ba1c449fd1f69148da6af40f1ae18a5be63539dfbf076019db8b28f3f644f7fd4f003b7d06a4c2e09"
}
],
"signed": {
"_type": "root",
"consistent_snapshot": true,
"expires": "2031-09-09T23:13:37Z",
"keys": {
"3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "6bac59b8d9e1aae02fae6fba6e7fe3fc9fe5b4a9fe98c3fca255d8c8ec3e5b35"
},
"scheme": "ed25519"
},
"77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "6400d770c7c1bce4b3d59ce0079ed686e843b6500bbea77d869a1ae7df4565a1"
},
"scheme": "ed25519"
},
"d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "28bf74baa87ed923f8fa27e3292684f8ec4730ce0bdc65150ed58199206ce089"
},
"scheme": "ed25519"
},
"e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "e6ae9d3b67d7b3ce274130291dd90287f32b8fd72bfb4ac5430859ebd1c28a46"
},
"scheme": "ed25519"
}
},
"roles": {
"root": {
"keyids": [
"d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129"
],
"threshold": 1
},
"snapshot": {
"keyids": [
"77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93"
],
"threshold": 1
},
"targets": {
"keyids": [
"e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4"
],
"threshold": 1
},
"timestamp": {
"keyids": [
"3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae"
],
"threshold": 1
}
},
"spec_version": "1.0.0",
"version": 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"signatures": [
{
"keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
"sig": "ecf4d79a88873efb223361e550b8fc35813ad7bf31d9769908d9495cfb930e03db889dc7419897031cadf39437c9f49b085f384fe1c18be3961704062365db0c"
}
],
"signed": {
"_type": "snapshot",
"expires": "2031-09-09T23:13:37Z",
"meta": {
"targets.json": {
"version": 1
}
},
"spec_version": "1.0.0",
"version": 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"signatures": [
{
"keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
"sig": "f2cee9e31bda3f88b25b0153bb48a6cb21237e4c41a34bbae95f152b56975085bc04c4978eed6be76a3ead23ff76a1259ff07e7b45b04fb51865c9601713c905"
}
],
"signed": {
"_type": "targets",
"delegations": {
"keys": {},
"roles": []
},
"expires": "2031-09-09T23:13:37Z",
"spec_version": "1.0.0",
"targets": {},
"version": 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"signatures": [
{
"keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
"sig": "35d1087c4874221bc772c8276bd77415d9366833aad4efc3926a8eda1de053843d2c114ac7448f08e3cfd802857c2ab2569d8be186b3cc36e65e458905f0e10e"
}
],
"signed": {
"_type": "timestamp",
"expires": "2031-09-09T23:13:37Z",
"meta": {
"snapshot.json": {
"hashes": {
"sha256": "d62f650c8097fd4de9e3c8874ef15f7e10fdcc4c32f7a1818e972e8984b8da8a",
"sha512": "d9d0c38df27bc2ccc9523cb8d27623cb40b264053233e5e3261d83e2921c790b21accf9d427e36aa4c1939ddbccaaa5e006267f1cdd451606c514135d178dca5"
},
"length": 431,
"version": 1
}
},
"spec_version": "1.0.0",
"version": 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"signatures": [
{
"keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
"sig": "481a1bd10fedbe33e88e5f586a8726f558a5ec426bf65d2ba1c449fd1f69148da6af40f1ae18a5be63539dfbf076019db8b28f3f644f7fd4f003b7d06a4c2e09"
}
],
"signed": {
"_type": "root",
"consistent_snapshot": true,
"expires": "2031-09-09T23:13:37Z",
"keys": {
"3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "6bac59b8d9e1aae02fae6fba6e7fe3fc9fe5b4a9fe98c3fca255d8c8ec3e5b35"
},
"scheme": "ed25519"
},
"77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "6400d770c7c1bce4b3d59ce0079ed686e843b6500bbea77d869a1ae7df4565a1"
},
"scheme": "ed25519"
},
"d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "28bf74baa87ed923f8fa27e3292684f8ec4730ce0bdc65150ed58199206ce089"
},
"scheme": "ed25519"
},
"e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4": {
"keyid_hash_algorithms": [
"sha256",
"sha512"
],
"keytype": "ed25519",
"keyval": {
"public": "e6ae9d3b67d7b3ce274130291dd90287f32b8fd72bfb4ac5430859ebd1c28a46"
},
"scheme": "ed25519"
}
},
"roles": {
"root": {
"keyids": [
"d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129"
],
"threshold": 1
},
"snapshot": {
"keyids": [
"77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93"
],
"threshold": 1
},
"targets": {
"keyids": [
"e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4"
],
"threshold": 1
},
"timestamp": {
"keyids": [
"3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae"
],
"threshold": 1
}
},
"spec_version": "1.0.0",
"version": 1
}
}
Loading

0 comments on commit 8124e8a

Please sign in to comment.