mirror of https://github.com/docker/docs.git
Merge pull request #540 from docker/downloads-backwards-compatible-metadata
Downloads backwards compatible metadata
This commit is contained in:
commit
a9164e66ec
|
@ -14,7 +14,8 @@ import (
|
|||
"github.com/docker/notary/client/changelist"
|
||||
"github.com/docker/notary/passphrase"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/docker/notary/tuf/store"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// recursively copies the contents of one directory into another - ignores
|
||||
|
@ -63,10 +64,10 @@ func Test0Dot1RepoFormat(t *testing.T) {
|
|||
// and publishing will modify the files
|
||||
tmpDir, err := ioutil.TempDir("", "notary-backwards-compat-test")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, recursiveCopy("../fixtures/compatibility/notary0.1", tmpDir))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, recursiveCopy("../fixtures/compatibility/notary0.1", tmpDir))
|
||||
|
||||
gun := "docker.io/notary0.1/samplerepo"
|
||||
gun := "docker.com/notary0.1/samplerepo"
|
||||
passwd := "randompass"
|
||||
|
||||
ts := fullTestServer(t)
|
||||
|
@ -74,28 +75,62 @@ func Test0Dot1RepoFormat(t *testing.T) {
|
|||
|
||||
repo, err := NewNotaryRepository(tmpDir, gun, ts.URL, http.DefaultTransport,
|
||||
passphrase.ConstantRetriever(passwd))
|
||||
assert.NoError(t, err, "error creating repo: %s", err)
|
||||
require.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
// targets should have 1 target, and it should be readable offline
|
||||
targets, err := repo.ListTargets()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, targets, 1)
|
||||
require.Equal(t, "LICENSE", targets[0].Name)
|
||||
|
||||
// delete the timestamp metadata, since the server will ignore the uploaded
|
||||
// one and try to create a new one from scratch, which will be the wrong version
|
||||
require.NoError(t, repo.fileStore.RemoveMeta(data.CanonicalTimestampRole))
|
||||
|
||||
// rotate the timestamp key, since the server doesn't have that one
|
||||
timestampPubKey, err := getRemoteKey(ts.URL, gun, data.CanonicalTimestampRole, http.DefaultTransport)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(
|
||||
require.NoError(t, err)
|
||||
require.NoError(
|
||||
t, repo.rootFileKeyChange(data.CanonicalTimestampRole, changelist.ActionCreate, timestampPubKey))
|
||||
|
||||
assert.NoError(t, repo.Publish())
|
||||
require.NoError(t, repo.Publish())
|
||||
|
||||
targets, err := repo.ListTargets()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, targets, 1)
|
||||
assert.Equal(t, "v1", targets[0].Name)
|
||||
targets, err = repo.ListTargets()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, targets, 2)
|
||||
|
||||
// Also check that we can add/remove keys by rotating keys
|
||||
oldTargetsKeys := repo.CryptoService.ListKeys(data.CanonicalTargetsRole)
|
||||
assert.NoError(t, repo.RotateKey(data.CanonicalTargetsRole, false))
|
||||
assert.NoError(t, repo.Publish())
|
||||
require.NoError(t, repo.RotateKey(data.CanonicalTargetsRole, false))
|
||||
require.NoError(t, repo.Publish())
|
||||
newTargetsKeys := repo.CryptoService.ListKeys(data.CanonicalTargetsRole)
|
||||
|
||||
assert.Len(t, oldTargetsKeys, 1)
|
||||
assert.Len(t, newTargetsKeys, 1)
|
||||
assert.NotEqual(t, oldTargetsKeys[0], newTargetsKeys[0])
|
||||
require.Len(t, oldTargetsKeys, 1)
|
||||
require.Len(t, newTargetsKeys, 1)
|
||||
require.NotEqual(t, oldTargetsKeys[0], newTargetsKeys[0])
|
||||
}
|
||||
|
||||
// Ensures that the current client can download metadata that is published from notary 0.1 repos
|
||||
func TestDownloading0Dot1RepoFormat(t *testing.T) {
|
||||
gun := "docker.com/notary0.1/samplerepo"
|
||||
passwd := "randompass"
|
||||
|
||||
metaCache, err := store.NewFilesystemStore(
|
||||
filepath.Join("../fixtures/compatibility/notary0.1/tuf", filepath.FromSlash(gun)),
|
||||
"metadata", "json")
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := readOnlyServer(t, metaCache, http.StatusNotFound, gun)
|
||||
defer ts.Close()
|
||||
|
||||
repoDir, err := ioutil.TempDir("", "notary-backwards-compat-test")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(repoDir)
|
||||
|
||||
repo, err := NewNotaryRepository(repoDir, gun, ts.URL, http.DefaultTransport,
|
||||
passphrase.ConstantRetriever(passwd))
|
||||
require.NoError(t, err, "error creating repo: %s", err)
|
||||
|
||||
_, err = repo.Update(true)
|
||||
require.NoError(t, err, "error updating repo: %s", err)
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func bumpVersions(t *testing.T, s *testutils.MetadataSwizzler, offset int) {
|
|||
}
|
||||
|
||||
// create a server that just serves static metadata files from a metaStore
|
||||
func readOnlyServer(t *testing.T, cache store.MetadataStore, notFoundStatus int) *httptest.Server {
|
||||
func readOnlyServer(t *testing.T, cache store.MetadataStore, notFoundStatus int, gun string) *httptest.Server {
|
||||
m := mux.NewRouter()
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
|
@ -72,8 +72,8 @@ func readOnlyServer(t *testing.T, cache store.MetadataStore, notFoundStatus int)
|
|||
w.Write(metaBytes)
|
||||
}
|
||||
}
|
||||
m.HandleFunc("/v2/docker.com/notary/_trust/tuf/{role:.*}.{checksum:.*}.json", handler)
|
||||
m.HandleFunc("/v2/docker.com/notary/_trust/tuf/{role:.*}.json", handler)
|
||||
m.HandleFunc(fmt.Sprintf("/v2/%s/_trust/tuf/{role:.*}.{checksum:.*}.json", gun), handler)
|
||||
m.HandleFunc(fmt.Sprintf("/v2/%s/_trust/tuf/{role:.*}.json", gun), handler)
|
||||
return httptest.NewServer(m)
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ func TestUpdateSucceedsEvenIfCannotWriteNewRepo(t *testing.T) {
|
|||
serverMeta, _, err := testutils.NewRepoMetadata("docker.com/notary", metadataDelegations...)
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := readOnlyServer(t, store.NewMemoryStore(serverMeta), http.StatusNotFound)
|
||||
ts := readOnlyServer(t, store.NewMemoryStore(serverMeta), http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
for role := range serverMeta {
|
||||
|
@ -138,7 +138,7 @@ func TestUpdateSucceedsEvenIfCannotWriteExistingRepo(t *testing.T) {
|
|||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
serverMeta, serverSwizzler := newServerSwizzler(t)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
// download existing metadata
|
||||
|
@ -215,7 +215,7 @@ func TestUpdateReplacesCorruptOrMissingMetadata(t *testing.T) {
|
|||
serverMeta, cs, err := testutils.NewRepoMetadata("docker.com/notary", metadataDelegations...)
|
||||
require.NoError(t, err)
|
||||
|
||||
ts := readOnlyServer(t, store.NewMemoryStore(serverMeta), http.StatusNotFound)
|
||||
ts := readOnlyServer(t, store.NewMemoryStore(serverMeta), http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
|
@ -259,7 +259,7 @@ func TestUpdateFailsIfServerRootKeyChangedWithoutMultiSign(t *testing.T) {
|
|||
serverMeta, serverSwizzler := newServerSwizzler(t)
|
||||
origMeta := testutils.CopyRepoMetadata(serverMeta)
|
||||
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
|
@ -607,7 +607,7 @@ func TestUpdateNonRootRemote50XCannotUseLocalCache(t *testing.T) {
|
|||
|
||||
func testUpdateRemoteNon200Error(t *testing.T, opts updateOpts, errExpected interface{}) {
|
||||
_, serverSwizzler := newServerSwizzler(t)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, opts.notFoundCode)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, opts.notFoundCode, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
|
@ -719,7 +719,7 @@ func TestUpdateRemoteChecksumWrongCannotUseLocalCache(t *testing.T) {
|
|||
|
||||
func testUpdateRemoteFileChecksumWrong(t *testing.T, opts updateOpts, errExpected bool) {
|
||||
_, serverSwizzler := newServerSwizzler(t)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
|
@ -948,7 +948,7 @@ func TestUpdateNonRootRemoteCorruptedCannotUseLocalCache(t *testing.T) {
|
|||
|
||||
func testUpdateRemoteCorruptValidChecksum(t *testing.T, opts updateOpts, expt swizzleExpectations, shouldErr bool) {
|
||||
_, serverSwizzler := newServerSwizzler(t)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
|
@ -1031,7 +1031,7 @@ func TestUpdateLocalAndRemoteRootCorrupt(t *testing.T) {
|
|||
|
||||
func testUpdateLocalAndRemoteRootCorrupt(t *testing.T, forWrite bool, localExpt, serverExpt swizzleExpectations) {
|
||||
_, serverSwizzler := newServerSwizzler(t)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound)
|
||||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
|
|
|
@ -49,7 +49,7 @@ func TestImport0Dot1Zip(t *testing.T) {
|
|||
}
|
||||
|
||||
func get0Dot1(t *testing.T) (*trustmanager.KeyFileStore, passphrase.Retriever, string) {
|
||||
gun := "docker.io/notary0.1/samplerepo"
|
||||
gun := "docker.com/notary0.1/samplerepo"
|
||||
ret := passphrase.ConstantRetriever("randompass")
|
||||
|
||||
// produce the zip file
|
||||
|
|
|
@ -5,13 +5,13 @@ Notary client makes no guarantees of future-compatibility though (that is, repos
|
|||
Relevant information for repositories:
|
||||
|
||||
- `notary0.1`
|
||||
- GUN: `docker.io/notary0.1/samplerepo`
|
||||
- GUN: `docker.com/notary0.1/samplerepo`
|
||||
- key passwords: "randompass"
|
||||
- targets:
|
||||
|
||||
```
|
||||
NAME DIGEST SIZE (BYTES)
|
||||
------------------------------------------------------------------------------------------
|
||||
v1 454fd6f9e5a71c34902a673f66cc73be5890785b55014afb0eee6cbbe784cca9 243
|
||||
---------------------------------------------------------------------------------------------
|
||||
LICENSE 9395bac6fccb26bcb55efb083d1b4b0fe72a1c25f959f056c016120b3bb56a62 11309
|
||||
```
|
||||
- `timestamp.json` has been removed - when testing the metadata, we'll have to rotate the timestamp key in order for the server to be able to sign the timestamp. The `timestamp.json` generated by a new server will be version 1, since as far as it knows this is a new repo. If we kept the `timestamp.json` with the higher version number, we would not be able to publish.
|
||||
- It also has a changelist to add a `.gitignore` target, that hasn't been published.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,c17103e653765be6081c0cf337b934f7
|
||||
|
||||
w4wq3SV4ACyI6S3ICSyVp3Gs5DvGmJaZESuLlJRjOCJwmGtycRsEgqzWX6xvkJ8h
|
||||
oSuAtrk7dhyp3HZ19u3wxctl6Qhaq+DuNVUr4S2gkgB/GtU+YR0oQfvyyE7ZTR5k
|
||||
fmll4Xc66sMqaJPrYLiAEKBaItM/urN/YViB1XAqjCQ=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -1,8 +0,0 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,6879ce0bef77e947fe4ac3ab99d17984
|
||||
|
||||
FMq/I/3nv6FDKpX3rEvttoQXtRAG4V0vbXc4nPY05tOl2HF/hCRCRQLNfmZj3Ntx
|
||||
qpCpFmGZfsV8qcLM03OHIp83Q5YEIxWXixD19z2/ssNCVZiGcsQrL9ZDbJv8xFNa
|
||||
n59yGpNKBcXGR9Z59r4vm8lPI+F6I2WbFOjINUejpfE=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,f549dc9305bfcf8c695c12cd0742329b
|
||||
|
||||
l2eb1N0wlvFxzE0saMmr50keO3jGuFYUZUU4o5Rnh5x0yIMIZAjpUulWfAmJ5qg8
|
||||
axCSN6cTosDIzkapTQYyUUsI8bwjHz7cF0vCFEDpmY4ApelWt9U249IILNQgta8T
|
||||
HwEKkEE1Wr7dGJVsFJp/aVT98ZEzKfc/qo2M0W4d1Ck=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,3e9302d39a83d09ea5574af4baa3f392
|
||||
|
||||
UPPr0U4bdjZgiy9dOFaNI3e/SUwCw6B+Ketee/aXZokxSr5kD7QsWEJ1zhns4DZ6
|
||||
XjqOlSvZZF95QrnBYYgtu/A0rvIsIUAXKwX9YMCg0CSMQutjuWjxmKbtBDiC6Ybt
|
||||
22Cj9hsmMPd9AM0eJLKHdjqa9DbnCFwoWVrMum8EzEE=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -1,8 +0,0 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,1bdbbacf2765e3002c84f4820583a050
|
||||
|
||||
nob6ZaPbVAuHymluL4Ah1eWvgW2ntllUSVaX+IiPuKGsdDvd0+45y9k/zSd+Y36r
|
||||
yGuAwQihwPvD2RAKPKHIPexsfeeV56sioTTKSMIYJilm1OE1V7X+pJF7qfYSCK4q
|
||||
+DbTyGHbK1NHVmJZ1RXxHBgyagDEjm4qfzLsWxo6BxQ=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -1,8 +0,0 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,f3854d625845d284b59b87bdf9af3d39
|
||||
|
||||
/cqlxBZA3rTOEBmE4HtDuBuHRysrXLk86YI2NJMptBNEym5Ylf1Q2Fv7dxjX23zC
|
||||
qc1i6/Z42aUhsVsp4+GmV7dWcPbxtb8jigEp1ysPZFlg1KKW113NNFwPa3kUPzzi
|
||||
4tmpSSkYChOi0kWJAH9aeSvWYremENFFN8lU8kXt4rk=
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,11 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhzCCAS2gAwIBAgIQC5uz6i6Pb7VG0KipYJFW/TAKBggqhkjOPQQDAjAqMSgw
|
||||
JgYDVQQDEx9kb2NrZXIuY29tL25vdGFyeTAuMS9zYW1wbGVyZXBvMB4XDTE2MDIw
|
||||
MzIzMjEyN1oXDTI2MDEzMTIzMjEyN1owKjEoMCYGA1UEAxMfZG9ja2VyLmNvbS9u
|
||||
b3RhcnkwLjEvc2FtcGxlcmVwbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLjY
|
||||
StmW3W+q2Kjnse7xevzgrnxZ5D52gmSp/LCBhpZWQbXgmrjrQUGzSpHF4Z24dbJ0
|
||||
mLctRqB2+lWaNp1v7YajNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
|
||||
BgEFBQcDAzAMBgNVHRMBAf8EAjAAMAoGCCqGSM49BAMCA0gAMEUCIDTYKBRf57oy
|
||||
lME36VQvKmPKvM13NBBrvWdm0CQduOonAiEAocaiw08vklmaS//DVh14fHmP6KG4
|
||||
Get+3dl4AerZy5s=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,11 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhjCCASygAwIBAgIRAMUvnJ2qaLRCuIwutGwtGNEwCgYIKoZIzj0EAwIwKTEn
|
||||
MCUGA1UEAxMeZG9ja2VyLmlvL25vdGFyeTAuMS9zYW1wbGVyZXBvMB4XDTE1MTIy
|
||||
MzAwNTgzNloXDTI1MTIyMzAwNTgzNlowKTEnMCUGA1UEAxMeZG9ja2VyLmlvL25v
|
||||
dGFyeTAuMS9zYW1wbGVyZXBvMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEx5lx
|
||||
It8KXzE2q4XeUyQT3lsFZU/dHP7Kpz1e0QJ418c9ZctvcCWDuvHLaASCtaC9hP1Q
|
||||
Ucw8mn7KoEbDm8lOfqM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG
|
||||
AQUFBwMDMAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0EAwIDSAAwRQIhAK6fuy2O2It5
|
||||
002w9PNRV0fzewo6HPH47aRtVROjZyjeAiBewHNvUeIPwGhAm9NwDKPR/GKuXSLR
|
||||
eVRlj1QmTz5CYw==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1 @@
|
|||
{"action":"create","role":"targets","type":"target","path":".gitignore","data":"eyJsZW5ndGgiOjE2MSwiaGFzaGVzIjp7InNoYTI1NiI6IkxITTJUMXZqMDZKVzJDM29jdXdBWXFvRExuc0FYeFFkeVZRZi9ucXA2TVE9In19"}
|
|
@ -0,0 +1 @@
|
|||
{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2026-01-31T15:21:30.452296074-08:00","keys":{"01305346e99b0e997fc97e626095835e99b076d9fa3c52d8fbaea6c093e28c2f":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDGXKI4nXaeSB7y8D1O0pSBesC/xxkdY1dWNzR1+hOApwL34/Sp2E65vGrHUXf7otN3NuX7EV5GWDazQv0T5DBA=="}},"1daab254a2b730ddd7cb728fb91bd319972f6d0a597bbcfcd9e3782b891925b4":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtxNO6bdXYOXw/DTlaMVfjKG8e7N48s3/alk/U4M0rhUAy5PYkgKupA5+Yw2/fZKbWqE4ecZ/AeZ3xB6ThQQudQ=="}},"3860144e902fa14e0590e149f735ace9287b0e5fdd43de3620811c70f00ffa12":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvvzReoPrAeDwCPOXsTqVIGlfZGHXGYoajoJ4hiYsnqOBT97LoVw8XoOk7T53sbAjLMe7C74hufUtuKqUaLBp5Q=="}},"e49372530f68d233a66fa27470dc5dcb64baca1054a7fd8bf9814db36ad6ed6b":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJoekNDQVMyZ0F3SUJBZ0lRQzV1ejZpNlBiN1ZHMEtpcFlKRlcvVEFLQmdncWhrak9QUVFEQWpBcU1TZ3cKSmdZRFZRUURFeDlrYjJOclpYSXVZMjl0TDI1dmRHRnllVEF1TVM5ellXMXdiR1Z5WlhCdk1CNFhEVEUyTURJdwpNekl6TWpFeU4xb1hEVEkyTURFek1USXpNakV5TjFvd0tqRW9NQ1lHQTFVRUF4TWZaRzlqYTJWeUxtTnZiUzl1CmIzUmhjbmt3TGpFdmMyRnRjR3hsY21Wd2J6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJMalkKU3RtVzNXK3EyS2puc2U3eGV2emdybnhaNUQ1MmdtU3AvTENCaHBaV1FiWGdtcmpyUVVHelNwSEY0WjI0ZGJKMAptTGN0UnFCMitsV2FOcDF2N1lhak5UQXpNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQXpBTUJnTlZIUk1CQWY4RUFqQUFNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJRFRZS0JSZjU3b3kKbE1FMzZWUXZLbVBLdk0xM05CQnJ2V2RtMENRZHVPb25BaUVBb2NhaXcwOHZrbG1hUy8vRFZoMTRmSG1QNktHNApHZXQrM2RsNEFlclp5NXM9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}}},"roles":{"root":{"keyids":["e49372530f68d233a66fa27470dc5dcb64baca1054a7fd8bf9814db36ad6ed6b"],"threshold":1},"snapshot":{"keyids":["3860144e902fa14e0590e149f735ace9287b0e5fdd43de3620811c70f00ffa12"],"threshold":1},"targets":{"keyids":["01305346e99b0e997fc97e626095835e99b076d9fa3c52d8fbaea6c093e28c2f"],"threshold":1},"timestamp":{"keyids":["1daab254a2b730ddd7cb728fb91bd319972f6d0a597bbcfcd9e3782b891925b4"],"threshold":1}},"version":1},"signatures":[{"keyid":"e49372530f68d233a66fa27470dc5dcb64baca1054a7fd8bf9814db36ad6ed6b","method":"ecdsa","sig":"FgE/chh0r5H+UF8K4gr6nCQIswzYH1JPMZwozc7C5Bw+JuktglPaXeBh682CMBa+UqwLz3VGtf+UZHd/y9AM8w=="}]}
|
|
@ -0,0 +1 @@
|
|||
{"signed":{"_type":"Snapshot","expires":"2019-02-02T15:22:32.080388473-08:00","meta":{"root":{"hashes":{"sha256":"hE632rKsFq7oDQmh16hLfyvNrZFxctnpQKg5eCRne+c="},"length":2421},"targets":{"hashes":{"sha256":"eOBO3guGHxxUVwFxPnOK23+Hod8m0XIyukE2YRVC5OM="},"length":439}},"version":2},"signatures":[{"keyid":"3860144e902fa14e0590e149f735ace9287b0e5fdd43de3620811c70f00ffa12","method":"ecdsa","sig":"6bODiJeca9pC6wdyRQknZLeEsTXbSy1KGO9LjqTvoOuSNlJldkKvcmzu4hSotPZrFYVzTjUqOHRLuSUovqZovA=="}]}
|
|
@ -0,0 +1 @@
|
|||
{"signed":{"_type":"Targets","delegations":{"keys":{},"roles":[]},"expires":"2019-02-02T15:22:29.471548194-08:00","targets":{"LICENSE":{"hashes":{"sha256":"k5W6xvzLJry1XvsIPRtLD+cqHCX5WfBWwBYSCzu1amI="},"length":11309}},"version":2},"signatures":[{"keyid":"01305346e99b0e997fc97e626095835e99b076d9fa3c52d8fbaea6c093e28c2f","method":"ecdsa","sig":"7PIlxcFxEQZDQWqOPC5rDVnxkPYesLeQfoxuxjCmYWrkzzhqWOfWpH3KHqdsbWBsLIb4QwyosVNzlH59xF8ojQ=="}]}
|
|
@ -0,0 +1 @@
|
|||
{"signed":{"_type":"Timestamp","expires":"2016-02-17T23:22:35.661611395Z","meta":{"snapshot":{"hashes":{"sha256":"6XfQcrYxEkJR4pSjtmF+VNgw4J3C9Ds5ncONGLEBy20="},"length":488}},"version":1},"signatures":[{"keyid":"1daab254a2b730ddd7cb728fb91bd319972f6d0a597bbcfcd9e3782b891925b4","method":"ecdsa","sig":"dD4A81CJhQiB7piyaZK1XahESYyhFnZEnGZTLM2yRhUmVYs6c5XTduMPrsaofPYnOW6NbmEYTtO+4QtFwpVm7A=="}]}
|
|
@ -1 +0,0 @@
|
|||
{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2025-12-19T16:59:16.729830584-08:00","keys":{"1195069fbd818c69e2f9d77fbc1c6d231fa5b647fd6477776eb78d9abe5eaa67":{"keytype":"ed25519","keyval":{"private":null,"public":"zcdBCrGzZoRVxvdeX/RBJkpLBvM7hyX95ipEEUI1GyA="}},"2295c999789d08596c29010acc659d2084b7aac0e340f28fee6edd3a290ae83a":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJoakNDQVN5Z0F3SUJBZ0lSQU1Vdm5KMnFhTFJDdUl3dXRHd3RHTkV3Q2dZSUtvWkl6ajBFQXdJd0tURW4KTUNVR0ExVUVBeE1lWkc5amEyVnlMbWx2TDI1dmRHRnllVEF1TVM5ellXMXdiR1Z5WlhCdk1CNFhEVEUxTVRJeQpNekF3TlRnek5sb1hEVEkxTVRJeU16QXdOVGd6Tmxvd0tURW5NQ1VHQTFVRUF4TWVaRzlqYTJWeUxtbHZMMjV2CmRHRnllVEF1TVM5ellXMXdiR1Z5WlhCdk1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRXg1bHgKSXQ4S1h6RTJxNFhlVXlRVDNsc0ZaVS9kSFA3S3B6MWUwUUo0MThjOVpjdHZjQ1dEdXZITGFBU0N0YUM5aFAxUQpVY3c4bW43S29FYkRtOGxPZnFNMU1ETXdEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHCkFRVUZCd01ETUF3R0ExVWRFd0VCL3dRQ01BQXdDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSzZmdXkyTzJJdDUKMDAydzlQTlJWMGZ6ZXdvNkhQSDQ3YVJ0VlJPalp5amVBaUJld0hOdlVlSVB3R2hBbTlOd0RLUFIvR0t1WFNMUgplVlJsajFRbVR6NUNZdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}},"4b5e9d6bddcc87f4ad54e3bfce02ecb001d28a8438314c4f07865d3b0c286965":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbt2tSzomjTxjKUhMcVBRJ/musqcRiHuPVm+pQHjnLoRPAPrr919P+7aUpXMBihg6nydHrM1b/y/aSBF5JSZKew=="}},"a05d4028f80035d2cf4a944cc453b392873e1e1ad251eb223732ac74ec146822":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6bBpt8h1MBmNu+rxel+P3Sek7TEB38Pi/mZ6+le0uikDbI3HANES764Z+XPcnkc6TEbE5ZHowselc/eMUmBiLA=="}}},"roles":{"root":{"keyids":["2295c999789d08596c29010acc659d2084b7aac0e340f28fee6edd3a290ae83a"],"threshold":1},"snapshot":{"keyids":["a05d4028f80035d2cf4a944cc453b392873e1e1ad251eb223732ac74ec146822"],"threshold":1},"targets":{"keyids":["4b5e9d6bddcc87f4ad54e3bfce02ecb001d28a8438314c4f07865d3b0c286965"],"threshold":1},"timestamp":{"keyids":["1195069fbd818c69e2f9d77fbc1c6d231fa5b647fd6477776eb78d9abe5eaa67"],"threshold":1}},"version":2},"signatures":[{"keyid":"2295c999789d08596c29010acc659d2084b7aac0e340f28fee6edd3a290ae83a","method":"ecdsa","sig":"bImxkykdYQYlRBr7nwpcvUOa1dJId750qh7bJU8sK3WWBfyP08JZMNh+zCyNNHN3g5CZAh2EqvhePpPJgGt3EQ=="}]}
|
|
@ -1 +0,0 @@
|
|||
{"signed":{"_type":"Snapshot","expires":"2025-12-19T17:05:12.44851106-08:00","meta":{"root":{"hashes":{"sha256":"autn8ojolebQBDaFeXRrSO+5BKMLlWd5S11mqhyEEu0="},"length":2343},"targets":{"hashes":{"sha256":"tSRCsYJZHV93+WHhtzlisjel5dGXWyYAhGo7qhj8qKQ="},"length":432}},"version":5},"signatures":[{"keyid":"a05d4028f80035d2cf4a944cc453b392873e1e1ad251eb223732ac74ec146822","method":"ecdsa","sig":"9TlGMm3Oz4NNmtvMOCtOB5lYTKqPZ3sTS59LUPisUIOzWKu9gn/OlwEeEYWmvcWRscbMSRt9xwA0/DiPnSmXJg=="}]}
|
|
@ -1 +0,0 @@
|
|||
{"signed":{"_type":"Targets","delegations":{"keys":{},"roles":[]},"expires":"2025-12-19T17:04:54.077551355-08:00","targets":{"v1":{"hashes":{"sha256":"RU/W+eWnHDSQKmc/ZsxzvliQeFtVAUr7Du5su+eEzKk="},"length":243}},"version":4},"signatures":[{"keyid":"4b5e9d6bddcc87f4ad54e3bfce02ecb001d28a8438314c4f07865d3b0c286965","method":"ecdsa","sig":"Y0nykOq8yeOiOwj6hGnFub6BbWDf4z3MKZCYITipLsSFdnFj2Pwk9Raml/Oy7FDRSKIS0/b4GUPIAqYYfWZonQ=="}]}
|
Loading…
Reference in New Issue