Repository: theupdateframework/go-tuf
Pull request #522 (2023-07-21 10:21:53)

fix(localMeta): Ignore deleted delegated targets
https://github.com/theupdateframework/go-tuf/pull/384 didn't fix the whole issue it intended to fix, this PR intends to complete it.


**Types of changes**:
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected). **Please ensure that your PR title** is a [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) breaking change (with a `!`, as in `feat!: change foo`). 

**Description of the changes being introduced by the pull request**:

The way #384 works is that, to add delegated targets to the `localMeta` while verifying them (as requested per https://github.com/theupdateframework/go-tuf/pull/384#discussion_r972099602), it will fetch target files and verify the whole delegation chain to add delegated targets to the `localMeta` (as [loadLocalMetaFromSnapshot](https://github.com/theupdateframework/go-tuf/blob/e95956b14c56b0705f0dc80c154edad81bc91dcc/client/client.go#L604) leverages the `localMeta`). To do so, as the `localMeta` is empty and can't be leveraged, we pull delegated targets and target files from the remote store. 

The problem is that such files can be deleted in the remote store in the mean time, leading to two errors:
- `ErrMissingRemoteMetadata` is the delegated targets file was deleted and removed from the snapshot
- `ErrUnknownTarget` is a target file was deleted

This PR ignores these errors as they are part of the normal behaviour of the `localMeta` load algorithm. Note that it doesn't fix https://github.com/theupdateframework/go-tuf/issues/444.

**Please verify and check that the pull request fulfills the following requirements**:

- [x] Tests have been added for the bug fix or new feature
- [x] Docs have been added for the bug fix or new feature



Patch:
diff --git a/client/client.go b/client/client.go
index 978ebf1..8e99176 100644
--- a/client/client.go
+++ b/client/client.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"encoding/hex"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
 
@@ -493,10 +494,25 @@ func (c *Client) getDelegationPathFromRaw(snapshot *data.Snapshot, delegatedTarg
 		return nil, err
 	}
 	for targetPath := range targets.Targets {
+		// Gets target file from remote store
 		_, resp, err := c.getTargetFileMetaDelegationPath(targetPath, snapshot)
 		// We only need to test one targets file:
 		// - If it is valid, it means the delegated targets has been validated
 		// - If it is not, the delegated targets isn't valid
+		if errors.As(err, &ErrMissingRemoteMetadata{}) {
+			// As this function is used to fill the local store cache, the targets
+			// will be downloaded from the remote store as the local store cache is
+			// empty, meaning that the delegated targets may not exist anymore. In
+			// that case, we can't get the delegation path. Ignore the delegated targets.
+			return nil, nil
+		}
+		if errors.As(err, &ErrUnknownTarget{}) {
+			// As this function is used to fill the local store cache, the target file
+			// will be downloaded from the remote store as the local store cache is
+			// empty, meaning that the target file may not exist anymore. In
+			// that case, ignore the file and try another.
+			continue
+		}
 		return resp, err
 	}
 	return nil, nil


Test patch:
diff --git a/client/delegations_test.go b/client/delegations_test.go
index 6d5a776..cbfc852 100644
--- a/client/delegations_test.go
+++ b/client/delegations_test.go
@@ -251,6 +251,30 @@ func TestPersistedMeta(t *testing.T) {
 	}
 }
 
+func TestGetDelegationPathWithNoTargetFile(t *testing.T) {
+	// In this test, we have created a target file c.txt for a delegation
+	// c.json, then we remove that target file and check if c.json is loaded
+	// in the localMeta. It shouldn't as it has no target file at all and shouldn't
+	// be used.
+	verify.IsExpired = func(t time.Time) bool { return false }
+	client, closer := initTestDelegationClient(t, "testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation")
+	defer closer()
+	_, err := client.Update()
+	assert.Nil(t, err)
+
+	err = client.getLocalMeta()
+	assert.Nil(t, err)
+
+	_, ok := client.localMeta["a.json"]
+	assert.True(t, ok)
+
+	_, ok = client.localMeta["b.json"]
+	assert.True(t, ok)
+
+	_, ok = client.localMeta["c.json"]
+	assert.False(t, ok)
+}
+
 func versionOfStoredTargets(name string, store map[string]json.RawMessage) (int64, error) {
 	rawTargets, ok := store[name]
 	if !ok {
@@ -296,7 +320,7 @@ func initTestDelegationClient(t *testing.T, dirPrefix string) (*Client, func() e
 		}
 		name := f.Name()
 		// ignoring consistent snapshot when loading initial state
-		if len(strings.Split(name, ".")) == 1 && strings.HasSuffix(name, ".json") {
+		if len(strings.Split(name, ".")) < 3 && strings.HasSuffix(name, ".json") {
 			rawFile, err := os.ReadFile(initialStateDir + "/" + name)
 			assert.Nil(t, err)
 			assert.Nil(t, c.local.SetMeta(name, rawFile))
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.a.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.a.json
new file mode 100755
index 0000000..ef485a9
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.a.json
@@ -0,0 +1,74 @@
+{
+ "signatures": [
+  {
+   "keyid": "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b",
+   "sig": "72b215c194090407abc8b7c513d69fd340abbe63037d26cbc2e4dd88c095a14da8d6e4aae0561f265e97d5c658b0260be2031af73c26e157e5f062c5f4aceb00"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "82f52e4503dbb364fabe8e5567f1cf909d4175d45468a021dfe75653db9ac98c"
+     },
+     "scheme": "ed25519"
+    },
+    "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "06e4dee0de7826c8d539a6112940b7459892b4ecaf696e67dc064aea0923f95c"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68"
+     ],
+     "name": "b",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    },
+    {
+     "keyids": [
+      "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b"
+     ],
+     "name": "c",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "a.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985",
+     "sha512": "f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.b.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.b.json
new file mode 100755
index 0000000..b3c9ffd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.b.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68",
+   "sig": "6a4f4bb63d7b6db4b6c09ce081fd229052ca087c98d25653c8d187de04dbedfc219aa9482774b939d84eb404fd51cfe383f9ea65e19a1d3cc79b642701bcff0d"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "b.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e",
+     "sha512": "f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.c.json
new file mode 100755
index 0000000..9305d64
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.c.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "9f0c5ef7e0a11012256c4a47ed757f9e90e930238f6a6e5c758a014f1b768519acb2b7d9aa9bd0456d71ba09b032598086e42d832830391e307c926c16f5b303"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "c.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd",
+     "sha512": "ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.root.json
new file mode 100755
index 0000000..0898610
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "d0bf76a5cfc0aee1b8a1b1bf0ed8ca646a1a6d5f205945c515e8546bfd3c1e6b5e07cc0b93836bd030dd05ba68f177aecb05f6bf90c6702fd178e53310022506"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.snapshot.json
new file mode 100755
index 0000000..dcbd2f4
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.snapshot.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "61db8765350398f7f750853337d9a55c5d6e790812d29146b5b45d5fd43d2a42c474a7a9fab263c3a50a28114a82f79dbf24ff1f99ae737a8d06f332f9f7d103"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "targets.json": {
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.targets.json
new file mode 100755
index 0000000..820691e
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.targets.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "c150e8ed5d352f366a979f4c4b9d556350c414c2da7ef1279045aaed3438c60872142d0dfe5ddbb627fec2d8fb7c5d8e692e04a87230b78d74714c5db035620a"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.timestamp.json
new file mode 100755
index 0000000..aae05fb
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/1.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "1d668531c7a0960cf90825faa684106a8aef0799c1b47e72301bac45d87f2dd42c14f1a3ac7db862323ca5177dd4fd686573ea92aea99638f17414dde561c00b"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "f4ca389c2c9fbc592d91d4e693c31113b8803a11bcb5ecd973581fa0e3d34ce0",
+     "sha512": "92a0989e44c0e9f16d3e56268a3b8dd4e4416ee2ac91a4c871a405f1e426062651ec4effa0078fc4409c8b0422ccad9b1aa197db58f178406f398562b2e98195"
+    },
+    "length": 431,
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.root.json
new file mode 100755
index 0000000..2d5222c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "e911db300e8eb378a2cabc48979e4c8f72beca30335db0579a7a1d81ae90c8bc63c27d92ce5a17846e3b1adb63a45a411bb4308e018e0d3cc4c9908311b5f208"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.snapshot.json
new file mode 100755
index 0000000..428c358
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "699125952eb773b09461a25fee03cf5a00237625e5dcb4e20334a13f09212daf6c97aff36fc1ac09ee302142eaec81447d57ba46d0831becb98d1526cb035106"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 1
+   },
+   "targets.json": {
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.targets.json
new file mode 100755
index 0000000..9f9d94b
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "3b54f35d6c03622b723fe38d0115e9d98d47e147eaaa1d60e2f2925199c19e520a3a0de8842b16b1e4e73c0e71d8ca26169fa2b4063f544fb1613185f616f704"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.timestamp.json
new file mode 100755
index 0000000..82737ad
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/2.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "36db44bdcb33c37f259e8a12098e9a9114f0cffde4a7d4db0d88d04d7c93add316333e671c2c2305b081fe6a9a56f365ee3000ccf8675f43d5c663d66d3edb00"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "35c207d52640e403b9df82386a2258e093091538c7d77a641295e7b0262d6ca0",
+     "sha512": "0a89bb735c8324ff1e661ad25c4017c0c330f09cbd3213ffac7104540c5fa01a35787ae3f517fc2966a89f53f7c91754de852988776cc59b2a574f28a0434139"
+    },
+    "length": 545,
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/a.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/a.json
new file mode 100755
index 0000000..ef485a9
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/a.json
@@ -0,0 +1,74 @@
+{
+ "signatures": [
+  {
+   "keyid": "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b",
+   "sig": "72b215c194090407abc8b7c513d69fd340abbe63037d26cbc2e4dd88c095a14da8d6e4aae0561f265e97d5c658b0260be2031af73c26e157e5f062c5f4aceb00"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "82f52e4503dbb364fabe8e5567f1cf909d4175d45468a021dfe75653db9ac98c"
+     },
+     "scheme": "ed25519"
+    },
+    "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "06e4dee0de7826c8d539a6112940b7459892b4ecaf696e67dc064aea0923f95c"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68"
+     ],
+     "name": "b",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    },
+    {
+     "keyids": [
+      "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b"
+     ],
+     "name": "c",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "a.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985",
+     "sha512": "f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/b.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/b.json
new file mode 100755
index 0000000..b3c9ffd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/b.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68",
+   "sig": "6a4f4bb63d7b6db4b6c09ce081fd229052ca087c98d25653c8d187de04dbedfc219aa9482774b939d84eb404fd51cfe383f9ea65e19a1d3cc79b642701bcff0d"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "b.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e",
+     "sha512": "f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/c.json
new file mode 100755
index 0000000..9305d64
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/c.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "9f0c5ef7e0a11012256c4a47ed757f9e90e930238f6a6e5c758a014f1b768519acb2b7d9aa9bd0456d71ba09b032598086e42d832830391e307c926c16f5b303"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "c.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd",
+     "sha512": "ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/root.json
new file mode 100755
index 0000000..2d5222c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "e911db300e8eb378a2cabc48979e4c8f72beca30335db0579a7a1d81ae90c8bc63c27d92ce5a17846e3b1adb63a45a411bb4308e018e0d3cc4c9908311b5f208"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/snapshot.json
new file mode 100755
index 0000000..428c358
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "699125952eb773b09461a25fee03cf5a00237625e5dcb4e20334a13f09212daf6c97aff36fc1ac09ee302142eaec81447d57ba46d0831becb98d1526cb035106"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 1
+   },
+   "targets.json": {
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/targets.json
new file mode 100755
index 0000000..9f9d94b
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "3b54f35d6c03622b723fe38d0115e9d98d47e147eaaa1d60e2f2925199c19e520a3a0de8842b16b1e4e73c0e71d8ca26169fa2b4063f544fb1613185f616f704"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/timestamp.json
new file mode 100755
index 0000000..82737ad
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/current/timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "36db44bdcb33c37f259e8a12098e9a9114f0cffde4a7d4db0d88d04d7c93add316333e671c2c2305b081fe6a9a56f365ee3000ccf8675f43d5c663d66d3edb00"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "35c207d52640e403b9df82386a2258e093091538c7d77a641295e7b0262d6ca0",
+     "sha512": "0a89bb735c8324ff1e661ad25c4017c0c330f09cbd3213ffac7104540c5fa01a35787ae3f517fc2966a89f53f7c91754de852988776cc59b2a574f28a0434139"
+    },
+    "length": 545,
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.root.json
new file mode 100755
index 0000000..0898610
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "d0bf76a5cfc0aee1b8a1b1bf0ed8ca646a1a6d5f205945c515e8546bfd3c1e6b5e07cc0b93836bd030dd05ba68f177aecb05f6bf90c6702fd178e53310022506"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.snapshot.json
new file mode 100755
index 0000000..dcbd2f4
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.snapshot.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "61db8765350398f7f750853337d9a55c5d6e790812d29146b5b45d5fd43d2a42c474a7a9fab263c3a50a28114a82f79dbf24ff1f99ae737a8d06f332f9f7d103"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "targets.json": {
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.targets.json
new file mode 100755
index 0000000..820691e
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.targets.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "c150e8ed5d352f366a979f4c4b9d556350c414c2da7ef1279045aaed3438c60872142d0dfe5ddbb627fec2d8fb7c5d8e692e04a87230b78d74714c5db035620a"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.timestamp.json
new file mode 100755
index 0000000..aae05fb
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/1.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "1d668531c7a0960cf90825faa684106a8aef0799c1b47e72301bac45d87f2dd42c14f1a3ac7db862323ca5177dd4fd686573ea92aea99638f17414dde561c00b"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "f4ca389c2c9fbc592d91d4e693c31113b8803a11bcb5ecd973581fa0e3d34ce0",
+     "sha512": "92a0989e44c0e9f16d3e56268a3b8dd4e4416ee2ac91a4c871a405f1e426062651ec4effa0078fc4409c8b0422ccad9b1aa197db58f178406f398562b2e98195"
+    },
+    "length": 431,
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/root.json
new file mode 100755
index 0000000..0898610
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "d0bf76a5cfc0aee1b8a1b1bf0ed8ca646a1a6d5f205945c515e8546bfd3c1e6b5e07cc0b93836bd030dd05ba68f177aecb05f6bf90c6702fd178e53310022506"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/snapshot.json
new file mode 100755
index 0000000..dcbd2f4
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/snapshot.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "61db8765350398f7f750853337d9a55c5d6e790812d29146b5b45d5fd43d2a42c474a7a9fab263c3a50a28114a82f79dbf24ff1f99ae737a8d06f332f9f7d103"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "targets.json": {
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/targets.json
new file mode 100755
index 0000000..820691e
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/targets.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "c150e8ed5d352f366a979f4c4b9d556350c414c2da7ef1279045aaed3438c60872142d0dfe5ddbb627fec2d8fb7c5d8e692e04a87230b78d74714c5db035620a"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/timestamp.json
new file mode 100755
index 0000000..aae05fb
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/client/metadata/previous/timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "1d668531c7a0960cf90825faa684106a8aef0799c1b47e72301bac45d87f2dd42c14f1a3ac7db862323ca5177dd4fd686573ea92aea99638f17414dde561c00b"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "f4ca389c2c9fbc592d91d4e693c31113b8803a11bcb5ecd973581fa0e3d34ce0",
+     "sha512": "92a0989e44c0e9f16d3e56268a3b8dd4e4416ee2ac91a4c871a405f1e426062651ec4effa0078fc4409c8b0422ccad9b1aa197db58f178406f398562b2e98195"
+    },
+    "length": 431,
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/hash.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/hash.txt
new file mode 100644
index 0000000..08714f7
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/hash.txt
@@ -0,0 +1,1 @@
+cc7b129f475232ee357a05756746938abe35b652ec9c53a9ffb93d3c67103b20
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.a.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.a.json
new file mode 100755
index 0000000..ef485a9
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.a.json
@@ -0,0 +1,74 @@
+{
+ "signatures": [
+  {
+   "keyid": "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b",
+   "sig": "72b215c194090407abc8b7c513d69fd340abbe63037d26cbc2e4dd88c095a14da8d6e4aae0561f265e97d5c658b0260be2031af73c26e157e5f062c5f4aceb00"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "82f52e4503dbb364fabe8e5567f1cf909d4175d45468a021dfe75653db9ac98c"
+     },
+     "scheme": "ed25519"
+    },
+    "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "06e4dee0de7826c8d539a6112940b7459892b4ecaf696e67dc064aea0923f95c"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68"
+     ],
+     "name": "b",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    },
+    {
+     "keyids": [
+      "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b"
+     ],
+     "name": "c",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "a.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985",
+     "sha512": "f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.b.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.b.json
new file mode 100755
index 0000000..b3c9ffd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.b.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68",
+   "sig": "6a4f4bb63d7b6db4b6c09ce081fd229052ca087c98d25653c8d187de04dbedfc219aa9482774b939d84eb404fd51cfe383f9ea65e19a1d3cc79b642701bcff0d"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "b.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e",
+     "sha512": "f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.c.json
new file mode 100755
index 0000000..9305d64
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.c.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "9f0c5ef7e0a11012256c4a47ed757f9e90e930238f6a6e5c758a014f1b768519acb2b7d9aa9bd0456d71ba09b032598086e42d832830391e307c926c16f5b303"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "c.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd",
+     "sha512": "ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.root.json
new file mode 100755
index 0000000..0898610
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "d0bf76a5cfc0aee1b8a1b1bf0ed8ca646a1a6d5f205945c515e8546bfd3c1e6b5e07cc0b93836bd030dd05ba68f177aecb05f6bf90c6702fd178e53310022506"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.snapshot.json
new file mode 100755
index 0000000..dcbd2f4
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.snapshot.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "61db8765350398f7f750853337d9a55c5d6e790812d29146b5b45d5fd43d2a42c474a7a9fab263c3a50a28114a82f79dbf24ff1f99ae737a8d06f332f9f7d103"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "targets.json": {
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.targets.json
new file mode 100755
index 0000000..820691e
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.targets.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "c150e8ed5d352f366a979f4c4b9d556350c414c2da7ef1279045aaed3438c60872142d0dfe5ddbb627fec2d8fb7c5d8e692e04a87230b78d74714c5db035620a"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.timestamp.json
new file mode 100755
index 0000000..aae05fb
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/1.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "1d668531c7a0960cf90825faa684106a8aef0799c1b47e72301bac45d87f2dd42c14f1a3ac7db862323ca5177dd4fd686573ea92aea99638f17414dde561c00b"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "f4ca389c2c9fbc592d91d4e693c31113b8803a11bcb5ecd973581fa0e3d34ce0",
+     "sha512": "92a0989e44c0e9f16d3e56268a3b8dd4e4416ee2ac91a4c871a405f1e426062651ec4effa0078fc4409c8b0422ccad9b1aa197db58f178406f398562b2e98195"
+    },
+    "length": 431,
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.c.json
new file mode 100755
index 0000000..b328966
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.c.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "c2f5f087f1bb9708f48657789cf8516b3d974e2250d3ec0268e347e89fa6f9eaa9e9441f5402ce32735fe31750013c5dc1b53f4e9a93d748ff060fa94ad3fd07"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.root.json
new file mode 100755
index 0000000..2d5222c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "e911db300e8eb378a2cabc48979e4c8f72beca30335db0579a7a1d81ae90c8bc63c27d92ce5a17846e3b1adb63a45a411bb4308e018e0d3cc4c9908311b5f208"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.snapshot.json
new file mode 100755
index 0000000..428c358
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "699125952eb773b09461a25fee03cf5a00237625e5dcb4e20334a13f09212daf6c97aff36fc1ac09ee302142eaec81447d57ba46d0831becb98d1526cb035106"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 1
+   },
+   "targets.json": {
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.targets.json
new file mode 100755
index 0000000..9f9d94b
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "3b54f35d6c03622b723fe38d0115e9d98d47e147eaaa1d60e2f2925199c19e520a3a0de8842b16b1e4e73c0e71d8ca26169fa2b4063f544fb1613185f616f704"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.timestamp.json
new file mode 100755
index 0000000..82737ad
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/2.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "36db44bdcb33c37f259e8a12098e9a9114f0cffde4a7d4db0d88d04d7c93add316333e671c2c2305b081fe6a9a56f365ee3000ccf8675f43d5c663d66d3edb00"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "35c207d52640e403b9df82386a2258e093091538c7d77a641295e7b0262d6ca0",
+     "sha512": "0a89bb735c8324ff1e661ad25c4017c0c330f09cbd3213ffac7104540c5fa01a35787ae3f517fc2966a89f53f7c91754de852988776cc59b2a574f28a0434139"
+    },
+    "length": 545,
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.root.json
new file mode 100755
index 0000000..85a9f0c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "bd598e8bc29a3eb07aa71caceb0644977d73df87aae8f84c98aff5e87ea2de642c4950232fc2f4065b12a9c19ecf33e511f4e4ac78da7dcd75b3779802f39504"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.snapshot.json
new file mode 100755
index 0000000..9a9a016
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "563e4fa25cf88c0d029ac30608b219f27d9389945c7afd46c118eda1931fb64cae0f376780fee5ddbc66ab768733e2a5b640f3cc19ea687a3e71ae4116e5dd0f"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 2
+   },
+   "targets.json": {
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.targets.json
new file mode 100755
index 0000000..44f4676
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "ced6f3e967a4366731f268a72a0f78aac0025641345a869baa013bb903502d7812ff22086834ab6b45f5c47cb7832139048663549d4e87d9219a0be7145c2807"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.timestamp.json
new file mode 100755
index 0000000..5d64bbd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/3.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "65d615183cd58d8a6df898e8f7d6e886a44ca111d6cce95e9a86414b369703b2e9e897bfde405d0c0688b26a11c8f74217d0e0f62b4307d30919ce0f2cb0f700"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "83d637428ffc782a3f762dc6d983548aad231680f2d0d84270e02b538ecd0f68",
+     "sha512": "3bcc5c70fe8c65d8103dcb60a0773ff436719159854d8d24242fb1f39721e9648b849b2a495487986aba1fdc53382ce604e6ddcd1fde72cbb81f8e8149bfd2f1"
+    },
+    "length": 545,
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/a.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/a.json
new file mode 100755
index 0000000..ef485a9
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/a.json
@@ -0,0 +1,74 @@
+{
+ "signatures": [
+  {
+   "keyid": "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b",
+   "sig": "72b215c194090407abc8b7c513d69fd340abbe63037d26cbc2e4dd88c095a14da8d6e4aae0561f265e97d5c658b0260be2031af73c26e157e5f062c5f4aceb00"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "82f52e4503dbb364fabe8e5567f1cf909d4175d45468a021dfe75653db9ac98c"
+     },
+     "scheme": "ed25519"
+    },
+    "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "06e4dee0de7826c8d539a6112940b7459892b4ecaf696e67dc064aea0923f95c"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68"
+     ],
+     "name": "b",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    },
+    {
+     "keyids": [
+      "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b"
+     ],
+     "name": "c",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "a.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985",
+     "sha512": "f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/b.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/b.json
new file mode 100755
index 0000000..b3c9ffd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/b.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68",
+   "sig": "6a4f4bb63d7b6db4b6c09ce081fd229052ca087c98d25653c8d187de04dbedfc219aa9482774b939d84eb404fd51cfe383f9ea65e19a1d3cc79b642701bcff0d"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "b.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e",
+     "sha512": "f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/c.json
new file mode 100755
index 0000000..b328966
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/c.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "c2f5f087f1bb9708f48657789cf8516b3d974e2250d3ec0268e347e89fa6f9eaa9e9441f5402ce32735fe31750013c5dc1b53f4e9a93d748ff060fa94ad3fd07"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/root.json
new file mode 100755
index 0000000..85a9f0c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "bd598e8bc29a3eb07aa71caceb0644977d73df87aae8f84c98aff5e87ea2de642c4950232fc2f4065b12a9c19ecf33e511f4e4ac78da7dcd75b3779802f39504"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/snapshot.json
new file mode 100755
index 0000000..9a9a016
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "563e4fa25cf88c0d029ac30608b219f27d9389945c7afd46c118eda1931fb64cae0f376780fee5ddbc66ab768733e2a5b640f3cc19ea687a3e71ae4116e5dd0f"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 2
+   },
+   "targets.json": {
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/targets.json
new file mode 100755
index 0000000..44f4676
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "ced6f3e967a4366731f268a72a0f78aac0025641345a869baa013bb903502d7812ff22086834ab6b45f5c47cb7832139048663549d4e87d9219a0be7145c2807"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/timestamp.json
new file mode 100755
index 0000000..5d64bbd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata.staged/timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "65d615183cd58d8a6df898e8f7d6e886a44ca111d6cce95e9a86414b369703b2e9e897bfde405d0c0688b26a11c8f74217d0e0f62b4307d30919ce0f2cb0f700"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "83d637428ffc782a3f762dc6d983548aad231680f2d0d84270e02b538ecd0f68",
+     "sha512": "3bcc5c70fe8c65d8103dcb60a0773ff436719159854d8d24242fb1f39721e9648b849b2a495487986aba1fdc53382ce604e6ddcd1fde72cbb81f8e8149bfd2f1"
+    },
+    "length": 545,
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.a.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.a.json
new file mode 100755
index 0000000..ef485a9
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.a.json
@@ -0,0 +1,74 @@
+{
+ "signatures": [
+  {
+   "keyid": "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b",
+   "sig": "72b215c194090407abc8b7c513d69fd340abbe63037d26cbc2e4dd88c095a14da8d6e4aae0561f265e97d5c658b0260be2031af73c26e157e5f062c5f4aceb00"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "82f52e4503dbb364fabe8e5567f1cf909d4175d45468a021dfe75653db9ac98c"
+     },
+     "scheme": "ed25519"
+    },
+    "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "06e4dee0de7826c8d539a6112940b7459892b4ecaf696e67dc064aea0923f95c"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68"
+     ],
+     "name": "b",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    },
+    {
+     "keyids": [
+      "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b"
+     ],
+     "name": "c",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "a.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985",
+     "sha512": "f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.b.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.b.json
new file mode 100755
index 0000000..b3c9ffd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.b.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68",
+   "sig": "6a4f4bb63d7b6db4b6c09ce081fd229052ca087c98d25653c8d187de04dbedfc219aa9482774b939d84eb404fd51cfe383f9ea65e19a1d3cc79b642701bcff0d"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "b.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e",
+     "sha512": "f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.c.json
new file mode 100755
index 0000000..9305d64
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.c.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "9f0c5ef7e0a11012256c4a47ed757f9e90e930238f6a6e5c758a014f1b768519acb2b7d9aa9bd0456d71ba09b032598086e42d832830391e307c926c16f5b303"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "c.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd",
+     "sha512": "ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.root.json
new file mode 100755
index 0000000..0898610
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "d0bf76a5cfc0aee1b8a1b1bf0ed8ca646a1a6d5f205945c515e8546bfd3c1e6b5e07cc0b93836bd030dd05ba68f177aecb05f6bf90c6702fd178e53310022506"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.snapshot.json
new file mode 100755
index 0000000..dcbd2f4
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.snapshot.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "61db8765350398f7f750853337d9a55c5d6e790812d29146b5b45d5fd43d2a42c474a7a9fab263c3a50a28114a82f79dbf24ff1f99ae737a8d06f332f9f7d103"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "targets.json": {
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.targets.json
new file mode 100755
index 0000000..820691e
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.targets.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "c150e8ed5d352f366a979f4c4b9d556350c414c2da7ef1279045aaed3438c60872142d0dfe5ddbb627fec2d8fb7c5d8e692e04a87230b78d74714c5db035620a"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.timestamp.json
new file mode 100755
index 0000000..aae05fb
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/1.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "1d668531c7a0960cf90825faa684106a8aef0799c1b47e72301bac45d87f2dd42c14f1a3ac7db862323ca5177dd4fd686573ea92aea99638f17414dde561c00b"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "f4ca389c2c9fbc592d91d4e693c31113b8803a11bcb5ecd973581fa0e3d34ce0",
+     "sha512": "92a0989e44c0e9f16d3e56268a3b8dd4e4416ee2ac91a4c871a405f1e426062651ec4effa0078fc4409c8b0422ccad9b1aa197db58f178406f398562b2e98195"
+    },
+    "length": 431,
+    "version": 1
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.c.json
new file mode 100755
index 0000000..b328966
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.c.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "c2f5f087f1bb9708f48657789cf8516b3d974e2250d3ec0268e347e89fa6f9eaa9e9441f5402ce32735fe31750013c5dc1b53f4e9a93d748ff060fa94ad3fd07"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.root.json
new file mode 100755
index 0000000..2d5222c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "e911db300e8eb378a2cabc48979e4c8f72beca30335db0579a7a1d81ae90c8bc63c27d92ce5a17846e3b1adb63a45a411bb4308e018e0d3cc4c9908311b5f208"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.snapshot.json
new file mode 100755
index 0000000..428c358
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "699125952eb773b09461a25fee03cf5a00237625e5dcb4e20334a13f09212daf6c97aff36fc1ac09ee302142eaec81447d57ba46d0831becb98d1526cb035106"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 1
+   },
+   "targets.json": {
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.targets.json
new file mode 100755
index 0000000..9f9d94b
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "3b54f35d6c03622b723fe38d0115e9d98d47e147eaaa1d60e2f2925199c19e520a3a0de8842b16b1e4e73c0e71d8ca26169fa2b4063f544fb1613185f616f704"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.timestamp.json
new file mode 100755
index 0000000..82737ad
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/2.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "36db44bdcb33c37f259e8a12098e9a9114f0cffde4a7d4db0d88d04d7c93add316333e671c2c2305b081fe6a9a56f365ee3000ccf8675f43d5c663d66d3edb00"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "35c207d52640e403b9df82386a2258e093091538c7d77a641295e7b0262d6ca0",
+     "sha512": "0a89bb735c8324ff1e661ad25c4017c0c330f09cbd3213ffac7104540c5fa01a35787ae3f517fc2966a89f53f7c91754de852988776cc59b2a574f28a0434139"
+    },
+    "length": 545,
+    "version": 2
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.root.json
new file mode 100755
index 0000000..85a9f0c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "bd598e8bc29a3eb07aa71caceb0644977d73df87aae8f84c98aff5e87ea2de642c4950232fc2f4065b12a9c19ecf33e511f4e4ac78da7dcd75b3779802f39504"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.snapshot.json
new file mode 100755
index 0000000..9a9a016
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "563e4fa25cf88c0d029ac30608b219f27d9389945c7afd46c118eda1931fb64cae0f376780fee5ddbc66ab768733e2a5b640f3cc19ea687a3e71ae4116e5dd0f"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 2
+   },
+   "targets.json": {
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.targets.json
new file mode 100755
index 0000000..44f4676
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "ced6f3e967a4366731f268a72a0f78aac0025641345a869baa013bb903502d7812ff22086834ab6b45f5c47cb7832139048663549d4e87d9219a0be7145c2807"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.timestamp.json
new file mode 100755
index 0000000..5d64bbd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/3.timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "65d615183cd58d8a6df898e8f7d6e886a44ca111d6cce95e9a86414b369703b2e9e897bfde405d0c0688b26a11c8f74217d0e0f62b4307d30919ce0f2cb0f700"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "83d637428ffc782a3f762dc6d983548aad231680f2d0d84270e02b538ecd0f68",
+     "sha512": "3bcc5c70fe8c65d8103dcb60a0773ff436719159854d8d24242fb1f39721e9648b849b2a495487986aba1fdc53382ce604e6ddcd1fde72cbb81f8e8149bfd2f1"
+    },
+    "length": 545,
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/a.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/a.json
new file mode 100755
index 0000000..ef485a9
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/a.json
@@ -0,0 +1,74 @@
+{
+ "signatures": [
+  {
+   "keyid": "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b",
+   "sig": "72b215c194090407abc8b7c513d69fd340abbe63037d26cbc2e4dd88c095a14da8d6e4aae0561f265e97d5c658b0260be2031af73c26e157e5f062c5f4aceb00"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "82f52e4503dbb364fabe8e5567f1cf909d4175d45468a021dfe75653db9ac98c"
+     },
+     "scheme": "ed25519"
+    },
+    "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "06e4dee0de7826c8d539a6112940b7459892b4ecaf696e67dc064aea0923f95c"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68"
+     ],
+     "name": "b",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    },
+    {
+     "keyids": [
+      "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b"
+     ],
+     "name": "c",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "a.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985",
+     "sha512": "f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/b.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/b.json
new file mode 100755
index 0000000..b3c9ffd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/b.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "718fedad390b4d0d470b890781eb8c94e5a7e975aebe65fc0862246c945fce68",
+   "sig": "6a4f4bb63d7b6db4b6c09ce081fd229052ca087c98d25653c8d187de04dbedfc219aa9482774b939d84eb404fd51cfe383f9ea65e19a1d3cc79b642701bcff0d"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "b.txt": {
+    "custom": {},
+    "hashes": {
+     "sha256": "949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e",
+     "sha512": "f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c"
+    },
+    "length": 15
+   }
+  },
+  "version": 1
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/c.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/c.json
new file mode 100755
index 0000000..b328966
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/c.json
@@ -0,0 +1,19 @@
+{
+ "signatures": [
+  {
+   "keyid": "9ca81f7ff17f6218246474a51b47eb035741bc472557ef5ac493e279f446b85b",
+   "sig": "c2f5f087f1bb9708f48657789cf8516b3d974e2250d3ec0268e347e89fa6f9eaa9e9441f5402ce32735fe31750013c5dc1b53f4e9a93d748ff060fa94ad3fd07"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {},
+   "roles": []
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {},
+  "version": 2
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/root.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/root.json
new file mode 100755
index 0000000..85a9f0c
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/root.json
@@ -0,0 +1,87 @@
+{
+ "signatures": [
+  {
+   "keyid": "d4dab4b4d68b91665a6d0dac5b4e64677aa6d853fc787669168b4b4ba9822129",
+   "sig": "bd598e8bc29a3eb07aa71caceb0644977d73df87aae8f84c98aff5e87ea2de642c4950232fc2f4065b12a9c19ecf33e511f4e4ac78da7dcd75b3779802f39504"
+  }
+ ],
+ "signed": {
+  "_type": "root",
+  "consistent_snapshot": true,
+  "expires": "2020-12-31T05:48:20Z",
+  "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": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/snapshot.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/snapshot.json
new file mode 100755
index 0000000..9a9a016
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/snapshot.json
@@ -0,0 +1,28 @@
+{
+ "signatures": [
+  {
+   "keyid": "77dfdca206c0fe1b8e55d67d21dd0e195a0998a9d2b56c6d3ee8f68d04c21e93",
+   "sig": "563e4fa25cf88c0d029ac30608b219f27d9389945c7afd46c118eda1931fb64cae0f376780fee5ddbc66ab768733e2a5b640f3cc19ea687a3e71ae4116e5dd0f"
+  }
+ ],
+ "signed": {
+  "_type": "snapshot",
+  "expires": "2020-01-08T00:00:00Z",
+  "meta": {
+   "a.json": {
+    "version": 1
+   },
+   "b.json": {
+    "version": 1
+   },
+   "c.json": {
+    "version": 2
+   },
+   "targets.json": {
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/targets.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/targets.json
new file mode 100755
index 0000000..44f4676
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/targets.json
@@ -0,0 +1,51 @@
+{
+ "signatures": [
+  {
+   "keyid": "e4dae3872d28d29f7624a702bfd25f68453544d597229ee9e0a8569d1f940cf4",
+   "sig": "ced6f3e967a4366731f268a72a0f78aac0025641345a869baa013bb903502d7812ff22086834ab6b45f5c47cb7832139048663549d4e87d9219a0be7145c2807"
+  }
+ ],
+ "signed": {
+  "_type": "targets",
+  "delegations": {
+   "keys": {
+    "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b": {
+     "keyid_hash_algorithms": [
+      "sha256",
+      "sha512"
+     ],
+     "keytype": "ed25519",
+     "keyval": {
+      "public": "f758af464295e62a1da4d3267be6d13f4aba9c7d52166d01b6bd5b4559496c9d"
+     },
+     "scheme": "ed25519"
+    }
+   },
+   "roles": [
+    {
+     "keyids": [
+      "05e17c1501d627b2597322f80d33aacec6f30a507552d3326a88913422b0e30b"
+     ],
+     "name": "a",
+     "paths": [
+      "*.txt"
+     ],
+     "terminating": false,
+     "threshold": 1
+    }
+   ]
+  },
+  "expires": "2020-04-01T07:27:10Z",
+  "spec_version": "1.0.0",
+  "targets": {
+   "targets.txt": {
+    "hashes": {
+     "sha256": "6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6",
+     "sha512": "0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a"
+    },
+    "length": 21
+   }
+  },
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/timestamp.json b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/timestamp.json
new file mode 100755
index 0000000..5d64bbd
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/metadata/timestamp.json
@@ -0,0 +1,24 @@
+{
+ "signatures": [
+  {
+   "keyid": "3a05831328273e4b821c3bbe1fed0c5332749d8e071675879af26a401a5c85ae",
+   "sig": "65d615183cd58d8a6df898e8f7d6e886a44ca111d6cce95e9a86414b369703b2e9e897bfde405d0c0688b26a11c8f74217d0e0f62b4307d30919ce0f2cb0f700"
+  }
+ ],
+ "signed": {
+  "_type": "timestamp",
+  "expires": "2020-01-02T00:00:00Z",
+  "meta": {
+   "snapshot.json": {
+    "hashes": {
+     "sha256": "83d637428ffc782a3f762dc6d983548aad231680f2d0d84270e02b538ecd0f68",
+     "sha512": "3bcc5c70fe8c65d8103dcb60a0773ff436719159854d8d24242fb1f39721e9648b849b2a495487986aba1fdc53382ce604e6ddcd1fde72cbb81f8e8149bfd2f1"
+    },
+    "length": 545,
+    "version": 3
+   }
+  },
+  "spec_version": "1.0.0",
+  "version": 3
+ }
+}
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a.targets.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a.targets.txt
new file mode 100644
index 0000000..5f1e603
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/0951c719b5adf26a55700bd1ac6b657fb513b04e4adb335a935a0da7f12f2ac99834b47442d0b832e5f4ffdd365ef538f14d3a52221c0cf81ef7b68ce312476a.targets.txt
@@ -0,0 +1,1 @@
+Contents: targets.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985.a.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985.a.txt
new file mode 100644
index 0000000..3c40561
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/3f90cedf303207851bbdc5f857e018daf93b4c0083306cef17df547b42e4e985.a.txt
@@ -0,0 +1,1 @@
+Contents: a.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6.targets.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6.targets.txt
new file mode 100644
index 0000000..5f1e603
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/6da6f624811b0d7792c57dc9ed58f1af8cbf4ebfaaaa3ea2011b57b4af63f7e6.targets.txt
@@ -0,0 +1,1 @@
+Contents: targets.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd.c.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd.c.txt
new file mode 100644
index 0000000..924df50
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/946e2ea9180de673891ae09ce0edfb207966bc32bd6324ebdad2c50c82075ffd.c.txt
@@ -0,0 +1,1 @@
+Contents: c.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e.b.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e.b.txt
new file mode 100644
index 0000000..976e178
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/949c6a4318dabe8bbd140cef99ea669ba031919ccf9bce0f5b4d0b61d1c0aa2e.b.txt
@@ -0,0 +1,1 @@
+Contents: b.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/a.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/a.txt
new file mode 100644
index 0000000..3c40561
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/a.txt
@@ -0,0 +1,1 @@
+Contents: a.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/b.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/b.txt
new file mode 100644
index 0000000..976e178
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/b.txt
@@ -0,0 +1,1 @@
+Contents: b.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/c.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/c.txt
new file mode 100644
index 0000000..924df50
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/c.txt
@@ -0,0 +1,1 @@
+Contents: c.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9.c.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9.c.txt
new file mode 100644
index 0000000..924df50
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/ddb5fb256a368d778b5fdd03d497ad79944c766245f3cccfc8b098b14c488ec424a68b86a6a2add36db4ef0f0214f15dbe0d63fbc5ca7a9619fb4c39544d78a9.c.txt
@@ -0,0 +1,1 @@
+Contents: c.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd.a.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd.a.txt
new file mode 100644
index 0000000..3c40561
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/f4631ef7ea7b015d7b88e411842fafeb78a72f0181bec72ea9754604ede74ea0e491bf8411659aabc96304fc764d0131ce49ba86066ab5f7b7480dde719e0bfd.a.txt
@@ -0,0 +1,1 @@
+Contents: a.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c.b.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c.b.txt
new file mode 100644
index 0000000..976e178
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/f4cc9ce5c73b37e2a6707af7a0ea614ea5fa428bd2509e3af4528a5d330ce98a09c4dd98c859ad9b27b8aba24e1eacbf1af8393fdbfed899cecb995c87a11e3c.b.txt
@@ -0,0 +1,1 @@
+Contents: b.txt
\ No newline at end of file
diff --git a/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/targets.txt b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/targets.txt
new file mode 100644
index 0000000..5f1e603
--- /dev/null
+++ b/client/testdata/php-tuf-fixtures/TUFTestFixture2LevelDelegation/server/targets/targets.txt
@@ -0,0 +1,1 @@
+Contents: targets.txt
\ No newline at end of file