2015-08-21 04:24:30 +00:00
|
|
|
package schema1
|
2015-01-02 23:24:10 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/docker/libtrust"
|
|
|
|
)
|
|
|
|
|
|
|
|
type testEnv struct {
|
2015-11-03 19:03:17 +00:00
|
|
|
name, tag string
|
|
|
|
invalidSigned *SignedManifest
|
|
|
|
signed *SignedManifest
|
|
|
|
pk libtrust.PrivateKey
|
2015-01-02 23:24:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestManifestMarshaling(t *testing.T) {
|
|
|
|
env := genEnv(t)
|
|
|
|
|
2015-08-21 04:50:15 +00:00
|
|
|
// Check that the all field is the same as json.MarshalIndent with these
|
2015-01-02 23:24:10 +00:00
|
|
|
// parameters.
|
manifest: improve test output and use const
Use consts to make clear these values are fixed, and improve the output
to make it clearer which part is the expected output, and which part
the actual.
Before this:
=== RUN TestManifest
manifest_test.go:87: manifest bytes not equal: "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n \"size\": 985,\n \"digest\": \"sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b\",\n \"annotations\": {\n \"apple\": \"orange\"\n }\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n \"size\": 153263,\n \"digest\": \"sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b\",\n \"annotations\": {\n \"lettuce\": \"wrap\"\n }\n }\n ],\n \"annotations\": {\n \"hot\": \"potato\"\n }\n}" != "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n \"size\": 985,\n \"digest\": \"sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b\",\n \"annotations\": {\n \"apple\": \"orange\"\n }\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n \"size\": 153263,\n \"digest\": \"sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b\",\n \"annotations\": {\n \"lettuce\": \"wrap\"\n }\n }\n ],\n \"annotations\": {\n \"hot\": \"potato\"\n }\n}"
--- FAIL: TestManifest (0.00s)
After this:
=== RUN TestManifest
manifest_test.go:72: manifest bytes not equal:
expected:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 985,
"digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 153263,
"digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b"
}
]
}
actual:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 985,
"digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 153263,
"digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b"
}
]
}
--- FAIL: TestManifest (0.00s)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-26 13:00:37 +00:00
|
|
|
expected, err := json.MarshalIndent(env.signed, "", " ")
|
2015-01-02 23:24:10 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error marshaling manifest: %v", err)
|
|
|
|
}
|
|
|
|
|
manifest: improve test output and use const
Use consts to make clear these values are fixed, and improve the output
to make it clearer which part is the expected output, and which part
the actual.
Before this:
=== RUN TestManifest
manifest_test.go:87: manifest bytes not equal: "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n \"size\": 985,\n \"digest\": \"sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b\",\n \"annotations\": {\n \"apple\": \"orange\"\n }\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n \"size\": 153263,\n \"digest\": \"sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b\",\n \"annotations\": {\n \"lettuce\": \"wrap\"\n }\n }\n ],\n \"annotations\": {\n \"hot\": \"potato\"\n }\n}" != "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n \"size\": 985,\n \"digest\": \"sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b\",\n \"annotations\": {\n \"apple\": \"orange\"\n }\n },\n \"layers\": [\n {\n \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n \"size\": 153263,\n \"digest\": \"sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b\",\n \"annotations\": {\n \"lettuce\": \"wrap\"\n }\n }\n ],\n \"annotations\": {\n \"hot\": \"potato\"\n }\n}"
--- FAIL: TestManifest (0.00s)
After this:
=== RUN TestManifest
manifest_test.go:72: manifest bytes not equal:
expected:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 985,
"digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 153263,
"digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b"
}
]
}
actual:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 985,
"digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 153263,
"digest": "sha256:62d8908bee94c202b2d35224a221aaa2058318bfa9879fa541efaecba272331b"
}
]
}
--- FAIL: TestManifest (0.00s)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-26 13:00:37 +00:00
|
|
|
if !bytes.Equal(expected, env.signed.all) {
|
|
|
|
t.Fatalf("manifest bytes not equal:\nexpected:\n%s\nactual:\n%s\n", string(expected), string(env.signed.all))
|
2015-01-02 23:24:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestManifestUnmarshaling(t *testing.T) {
|
|
|
|
env := genEnv(t)
|
|
|
|
|
|
|
|
var signed SignedManifest
|
2015-08-21 04:50:15 +00:00
|
|
|
if err := json.Unmarshal(env.signed.all, &signed); err != nil {
|
2015-01-02 23:24:10 +00:00
|
|
|
t.Fatalf("error unmarshaling signed manifest: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(&signed, env.signed) {
|
|
|
|
t.Fatalf("manifests are different after unmarshaling: %v != %v", signed, env.signed)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestManifestVerification(t *testing.T) {
|
|
|
|
env := genEnv(t)
|
|
|
|
|
2015-01-02 23:46:47 +00:00
|
|
|
publicKeys, err := Verify(env.signed)
|
2015-01-02 23:24:10 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error verifying manifest: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(publicKeys) == 0 {
|
|
|
|
t.Fatalf("no public keys found in signature")
|
|
|
|
}
|
|
|
|
|
|
|
|
var found bool
|
|
|
|
publicKey := env.pk.PublicKey()
|
|
|
|
// ensure that one of the extracted public keys matches the private key.
|
|
|
|
for _, candidate := range publicKeys {
|
|
|
|
if candidate.KeyID() == publicKey.KeyID() {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found {
|
|
|
|
t.Fatalf("expected public key, %v, not found in verified keys: %v", publicKey, publicKeys)
|
|
|
|
}
|
2015-11-03 19:03:17 +00:00
|
|
|
|
|
|
|
// Check that an invalid manifest fails verification
|
|
|
|
_, err = Verify(env.invalidSigned)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Invalid manifest should not pass Verify()")
|
|
|
|
}
|
2015-01-02 23:24:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func genEnv(t *testing.T) *testEnv {
|
|
|
|
pk, err := libtrust.GenerateECP256PrivateKey()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error generating test key: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
name, tag := "foo/bar", "test"
|
|
|
|
|
2015-11-03 19:03:17 +00:00
|
|
|
invalid := Manifest{
|
2015-08-21 04:24:30 +00:00
|
|
|
Versioned: SchemaVersion,
|
|
|
|
Name: name,
|
|
|
|
Tag: tag,
|
2015-01-02 23:24:10 +00:00
|
|
|
FSLayers: []FSLayer{
|
|
|
|
{
|
|
|
|
BlobSum: "asdf",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
BlobSum: "qwer",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2015-11-03 19:03:17 +00:00
|
|
|
valid := Manifest{
|
|
|
|
Versioned: SchemaVersion,
|
|
|
|
Name: name,
|
|
|
|
Tag: tag,
|
|
|
|
FSLayers: []FSLayer{
|
|
|
|
{
|
|
|
|
BlobSum: "asdf",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
History: []History{
|
|
|
|
{
|
|
|
|
V1Compatibility: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
sm, err := Sign(&valid, pk)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error signing manifest: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidSigned, err := Sign(&invalid, pk)
|
2015-01-02 23:24:10 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error signing manifest: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &testEnv{
|
2015-11-03 19:03:17 +00:00
|
|
|
name: name,
|
|
|
|
tag: tag,
|
|
|
|
invalidSigned: invalidSigned,
|
|
|
|
signed: sm,
|
|
|
|
pk: pk,
|
2015-01-02 23:24:10 +00:00
|
|
|
}
|
|
|
|
}
|