diff --git a/descriptor.md b/descriptor.md index 70bc4fe17..697ad6055 100644 --- a/descriptor.md +++ b/descriptor.md @@ -57,33 +57,46 @@ The following field keys are reserved and MUST NOT be used by other specificatio All other fields may be included in other OCI specifications. Extended _Descriptor_ field additions proposed in other OCI specifications SHOULD first be considered for addition into this specification. -## Digests and Verification +## Digests The _digest_ property of a Descriptor acts as a content identifier, enabling [content addressability](http://en.wikipedia.org/wiki/Content-addressable_storage). It uniquely identifies content by taking a [collision-resistant hash](https://en.wikipedia.org/wiki/Cryptographic_hash_function) of the bytes. -If the digest can be communicated in a secure manner, one can retrieve the content from an insecure source, recalculate the digest independently, and be certain that the correct content was obtained. +If the _digest_ can be communicated in a secure manner, one can verify content from an insecure source by recalculating the digest independently, ensuring the content has not been modified. -The value of the digest property is a string consisting of an _algorithm_ portion (the "algorithm identifier") and a _hex_ portion. -The algorithm identifier specifies the cryptographic hash function used to calculate the digest; the hex portion is the lowercase hex-encoded result of the hash. +The value of the `digest` property is a string consisting of an _algorithm_ portion and an _encoded_ portion. +The _algorithm_ specifies the cryptographic hash function and encoding used for the digest; the _encoded_ portion contains the encoded result of the hash function. -The digest string MUST match the following grammar: +A digest string MUST match the following grammar: ``` -digest := algorithm ":" hex -algorithm := /[a-z0-9_+.-]+/ -hex := /[a-f0-9]+/ +digest := algorithm ":" encoded +algorithm := algorithm-component [algorithm-separator algorithm-component]* +algorithm-component := /[a-z0-9]+/ +algorithm-separator := /[+._-]/ +encoded := /[a-zA-Z0-9=_-]+/ ``` Some example digest strings include the following: -digest string | algorithm | -------------------------------------------------------------------------|---------------------| -sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b | [SHA-256](#sha-256) | +digest | algorithm | Supported | +--------------------------------------------------------------------------|---------------------|-----------| +`sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b` | [SHA-256](#sha-256) | Yes | +`sha512:401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b372742...` | [SHA-256](#sha-512) | Yes | +`multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8` | Multihash | No | +`sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564` | SHA-256 with urlsafe base64 | No| -* Before consuming content targeted by a descriptor from untrusted sources, the byte content SHOULD be verified against the digest string. -* Before calculating the digest, the size of the content SHOULD be verified to reduce hash collision space. -* Heavy processing before calculating a hash SHOULD be avoided. -* Implementations MAY employ [canonicalization](canonicalization.md) of the underlying content to ensure stable content identifiers. +Please see [Registered Algorithms](#registered-identifiers) for a list of supported algorithms. + +Implementations SHOULD allow digests that are unsupported to pass validation if they comply with the above grammar. +While `sha256` will only use hex encoded digests, support for separators in _algorithm_ and alpha numeric in _encoded_ is included to allow for future extension of digest support. +As an example, we can paramterize the encoding and algorithm as `multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8`, which would be considered valid but unsupported by this specification. + +### Verification + +Before consuming content targeted by a descriptor from untrusted sources, the byte content SHOULD be verified against the digest string. +Before calculating the digest, the size of the content SHOULD be verified to reduce hash collision space. +Heavy processing before calculating a hash SHOULD be avoided. +Implementations MAY employ [canonicalization](canonicalization.md) of the underlying content to ensure stable content identifiers. ### Digest calculations @@ -91,24 +104,24 @@ A _digest_ is calculated by the following pseudo-code, where `H` is the selected ``` let ID(C) = Descriptor.digest let C = -let D = ':' + EncodeHex(H(C)) +let D = ':' + Encode(H(C)) let verified = ID(C) == D ``` Above, we define the content identifier as `ID(C)`, extracted from the `Descriptor.digest` field. Content `C` is a string of bytes. -Function `H` returns the hash of `C` in bytes and is passed to function `EncodeHex` and prefixed with the algorithm to obtain the digest. +Function `H` returns the hash of `C` in bytes and is passed to function `Encode` and prefixed with the algorithm to obtain the digest. The result `verified` is true if `ID(C)` is equal to `D`, confirming that `C` is the content identified by `D`. After verification, the following is true: ``` -D == ID(C) == ':' + EncodeHex(H(C)) +D == ID(C) == ':' + Encode(H(C)) ``` The _digest_ is confirmed as the content identifier by independently calculating the _digest_. ### Registered algorithms -While the _algorithm_ portion (the "algorithm identifier") of the digest string allows the use of a variety of cryptographic algorithms, compliant implementations SHOULD use [SHA-256](#sha-256). +While the _algorithm_ component of the digest string allows the use of a variety of cryptographic algorithms, compliant implementations SHOULD use [SHA-256](#sha-256). The following algorithm identifiers are currently defined by this specification: diff --git a/image-layout.md b/image-layout.md index 267d80d80..0aa15199e 100644 --- a/image-layout.md +++ b/image-layout.md @@ -53,8 +53,8 @@ afff3924849e458c5ef237db5f89539274d5e609db5db935ed3959c90f1f2d51 ./blobs/sha256/ ## Blobs * Object names in the `blobs` subdirectories are composed of a directory for each hash algorithm, the children of which will contain the actual content. -* A blob, referenced with digest `:` (per [descriptor](descriptor.md#digests-and-verification)), MUST have its content stored in a file under `blobs//`. -* The character set of the entry name for `` and `` MUST match the respective grammar elements described in [descriptor](descriptor.md#digests-and-verification). +* A blob, referenced with digest `:` (per [descriptor](descriptor.md#digests-and-verification)), MUST have its content stored in a file under `blobs//`. +* The character set of the entry name for `` and `` MUST match the respective grammar elements described in [descriptor](descriptor.md#digests-and-verification). * For example `sha256:5b` will map to the layout `blobs/sha256/5b`. * The blobs directory MAY contain blobs which are not referenced by any of the [refs](#indexjson-file). * The blobs directory MAY be missing referenced blobs, in which case the missing blobs SHOULD be fulfilled by an external blob store. diff --git a/schema/content-descriptor.json b/schema/content-descriptor.json index 1bc47e2a4..69fcea92e 100644 --- a/schema/content-descriptor.json +++ b/schema/content-descriptor.json @@ -13,7 +13,7 @@ "$ref": "defs.json#/definitions/int64" }, "digest": { - "description": "the cryptographic checksum digest of the object, in the pattern ':'", + "description": "the cryptographic checksum digest of the object, in the pattern ':'", "$ref": "defs-descriptor.json#/definitions/digest" }, "urls": { diff --git a/schema/defs-descriptor.json b/schema/defs-descriptor.json index 3d9996ad3..feaea001b 100644 --- a/schema/defs-descriptor.json +++ b/schema/defs-descriptor.json @@ -7,9 +7,9 @@ "pattern": "^[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}/[A-Za-z0-9][A-Za-z0-9!#$&-^_.+]{0,126}$" }, "digest": { - "description": "the cryptographic checksum digest of the object, in the pattern ':'", + "description": "the cryptographic checksum digest of the object, in the pattern ':'", "type": "string", - "pattern": "^[a-z0-9_+.-]+:[a-f0-9]+$" + "pattern": "^[a-z0-9]+(?:[+._-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$" }, "urls": { "description": "a list of urls from which this object may be downloaded", diff --git a/schema/descriptor_test.go b/schema/descriptor_test.go index b1115e063..009614330 100644 --- a/schema/descriptor_test.go +++ b/schema/descriptor_test.go @@ -200,7 +200,6 @@ func TestDescriptor(t *testing.T) { "digest": "sha256:5B0BCABD1ED22E9FB1310CF6C2DEC7CDEF19F0AD69EFA1F392E94A4333501270" } `, - fail: true, }, // expected success: valid URL entry @@ -232,6 +231,66 @@ func TestDescriptor(t *testing.T) { `, fail: true, }, + { + descriptor: `{ + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" +}`, + }, + { + descriptor: `{ + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }`, + }, + { + descriptor: `{ + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }`, + }, + { + descriptor: ` + { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }`, + }, + { + descriptor: `{ + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8" + }`, + }, + { + // fail: repeated separators in algorithm + descriptor: `{ + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }`, + fail: true, + }, + { + descriptor: `{ + "digest": "sha256+b64u:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564", + "size": 1000000, + "mediaType": "application/vnd.oci.image.config.v1+json" + }`, + }, + { + // test for those who cannot use modulo arithmetic to recover padding. + descriptor: `{ + "digest": "sha256+b64u.unknownlength:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564=", + "size": 1000000, + "mediaType": "application/vnd.oci.image.config.v1+json" + }`, + }, } { r := strings.NewReader(tt.descriptor) err := schema.ValidatorMediaTypeDescriptor.Validate(r) diff --git a/schema/fs.go b/schema/fs.go index fa92053df..24c492e06 100644 --- a/schema/fs.go +++ b/schema/fs.go @@ -205,9 +205,9 @@ var _escData = map[string]*_escFile{ "/config-schema.json": { local: "config-schema.json", size: 2771, - modtime: 1489007060, + modtime: 1489087148, compressed: ` -H4sIAAAJbogA/+RWQW/bPAy9+1cYbo9t/R2+U67dbgMyINh2KIZAsemEnSVqFD3MGPLfB8vJZtmym3XI +H4sIAAAAAAAA/+RWQW/bPAy9+1cYbo9t/R2+U67dbgMyINh2KIZAsemEnSVqFD3MGPLfB8vJZtmym3XI aScDFB/f4xMl60eSplkJrmC0gmSyVZqtLZhHMqLQAKePZCrcpxsLBVZYKJ9118FuXXEArTrIQcSu8vzZ kbnvow/E+7xkVcn9f//nfeymx2F5hrhVnpMFU5zZnIf12TlqtYe88Pw9UloLHZZ2z1BIH7NMFlgQXLZK u3bSNCsYlED5KzCAOmE0fTkfr4i1km6lVAL3ghoyv3bsUzLVyIF4oVSYzcUBBQppGC7FkLs08+RFJHvg @@ -222,40 +222,41 @@ b1D07fCyW0vviMlWxN4UcYpZ/Enjdtf+RQ3SGiZ/vj8oANpKu/UTMV9kR1SDMjPzGZ6y5MQwnZvwWfX7 "/content-descriptor.json": { local: "content-descriptor.json", - size: 1091, - modtime: 1489085976, + size: 1085, + modtime: 1493147571, compressed: ` -H4sIAAAJbogA/5yTwW7UMBCG73mKUVqpl27NoeIQVb3AnQPcEAevPY6nJLYZz6oE1HdHjrNsAoiFve2O -/m/mm2j8vQFoLWbDlIRiaDto3yUMb2IQTQEZyi8MAm+XUGR4n9CQI6Nn4ra0uM7G46gL7kVSp9RTjmFX -q3eRe2VZO9m9ule1dlU5skckd0rFhMEcJ+cZq2llf06vnEwJCxn3T2ik1hLHhCyEue2gLAbQjmhJf6jh -Wvp9X/EIc640heigFBgdMgaDFlYzZvya0RXOosu7k9hd2fhKWXQUqPTO6jR9Zl9qizbTt3M+JQIUYD8J -5v90+oMIBXl9v5Ww1GOWMxqGpySxZ508GTAezed8GKGyR63qclt0y9+kRZAD3Dx4nf1j9+Dxq7ZoaNTD -Qj7eXPI1F+PNFgce8l920DBQFS1BcBxHePZkPIinvJjDqCfYI9j4HIaoLdpL7GaTjZsOIcr8RjaK/3ry -NOoeV4ev1v0uEFzj1bNZXFvGLwdiLGIff30365vdnk4D8Kl5aX4EAAD//4LEuuxDBAAA +H4sIAAAAAAAA/5yTwW7UMBCG73mKUVqpl27NoeIQVb3AnQPcEAevPY6nbGwznlW1oL47mniXJoAo3Vsy ++r+Zz8n4RwfQe6yOqQjl1A/QfyiY3uUklhIy6BMmgffHUGb4WNBRIGdn4lpbXFYXcbKKR5EyGPNQc9q0 +6k3m0Xi2QTZvbk2rXTSO/AmpgzG5YHKnyXXGWtr4X9MbJ4eCSubtAzpptcK5IAth7QfQgwH0E3qyn1q4 +lf48r0SEOadNIQfQAmNAxuTQw2LGjF8yBuU8hrp5FrvRE18Yj4ESae9qnqfP7FNr0Vf6/pKPRoASbA+C +9ZVOfxGhJG9v1xKeRqzygobjQ5E8si2RHLiI7mvdT9DYk1ZzuVZdfS1WBDnB1Z3djZlJ4nQ/3OmP9ejv +r875jkfXlf+ed/Uf9hZ21BQ1CIHzBI+RXASJVI/OMNkDbBF8fky7bD36c+xmk5WbTSnLfDtWiv+77DTZ +ERcrb5b9zhBc4s2zO7r2jN/2xKhin3+/McttXS9NB/Cle+p+BgAA///HjexwPQQAAA== `, }, "/defs-descriptor.json": { local: "defs-descriptor.json", - size: 906, - modtime: 1489085976, + size: 922, + modtime: 1493750367, compressed: ` -H4sIAAAJbogA/6STT2/TQBDF7/kUwzaih8Rx4YCEVVVC9M6hnKjSaro79k7x/tHuRCVU+e5obTdJi0Cg -Hmx5RzPvze9p/TgDUIayThyFg1cNqEtq2XM5ZYiYhPWmxwQS4Esk/zl4QfaU4HIaCwmuImluWeOgsRxF -9yqqgeIDoBwZxq/bSPsSgGJTXK1IzE1dh0heP3nkVUhdnbUlhzU77Kg2e9f6oLZ80pJRW2VJ7LtDPaII -pQHv5vpT9Q2rn2fVx/Xh883J/G11c7tarB/Plu/ef9jV/9Y2V4PFbnRShjvKckz3IlyxBDpto4QuYbSs -QVvS3/PGwTgLoYXSFO7uScsS2A/HCQBOzy1me9GcW/qBhjQ77KfJi9P/zGFEul2sqvWiucaqLayLF0Sb -1Oe/8CD0PC5dGqFNwcGDZW1BLOeJAhxu4Y7AhAffBzRkft8UU8LtocxC7tj3z0wAqg3JYUldbRKrqb57 -hoHeB8Hn1/E1d+9Yb7/0PFFb9Ay1eXWfgz+pj36D2mG8GnYf31POs/LsZr8CAAD//1ayPsKKAwAA +H4sIAAAAAAAA/6STX2/TMBTF3/spLl7FgDZN4QFp0Ria2DsP42lTV93ZN/Ed8R/ZrqYy9bsjJ1naFYFA +PCSyj67Pub8b52kCIBRFGdgndlZUIK6oZst5F8FjSCw3LQZIDr56sl+cTciWAlwNx1yAa0+Sa5bYecx7 +09FFVJBzAIQhxfht62mUAASrnKpT8rEqS+fJyueMuHChKaPUZLBkgw2Vakwt927zZ6/Ue4uYAttmr3tM +iUKHd3d7Wdxg8WNZnK32y1cn09fF3XoxWz0t5+8/fNyVf1c2FV3Erk8SihuK6ZDuaLhJE8iw9ck1Ab1m +CVKT/B43Bvqz4GrIRe7+gWSaA9tuOwDA6Tm2jQuctLmozvOoFKmL03+cwMA1e/O5up0t1sVqVN6+q/L6 +srhZFmef1sVqdkS4CW38Ax9Cyz1ELoQ6OAOPmqWGpDkOVGBwC/cEyj3a1qEi9Wv/GAJu9zInMoe5vycF +ELULBvNXEJvAYtB3LzDQWpfw5fX8n7t46Dc2PQ1UZz9FdVw8RGdPyoPfojTor7ve+/cw50l+dpOfAQAA +//8aH/C2mgMAAA== `, }, "/defs.json": { local: "defs.json", size: 1670, - modtime: 1489007060, + modtime: 1489087148, compressed: ` -H4sIAAAJbogA/7STza6bMBCF9zzFyO2S9oJtbGDb7hMpy6oLSiaJq2AjY6RWEe9e8RNChFuJKneRgGc8 +H4sIAAAAAAAA/7STza6bMBCF9zzFyO2S9oJtbGDb7hMpy6oLSiaJq2AjY6RWEe9e8RNChFuJKneRgGc8 3zmeMbcAgByxKa2qnTKa5EC+4klp1a8aaBs8grtY054vpnXgLgi7GvUXo12hNFo41FiqkyqLoTwceTOA 5NBLABClXTqvAIj7XWOvprTDM9qhckhUSquqrUgOn2KaPsLFrykcUzkEu3Amx2IrmlEpfPA+vsIzuhVP Yy55ygT3aczJlZDgW4UyShmTNGIiTbiUIooij6Jn15N0+x/T8enQJFlxN8/GBxZJwtbozXPxoTnNeCYk @@ -267,43 +268,43 @@ fIvD7in0ryMEy+fK1G6UfmdTE+tvpoL+1wV/AgAA//96IpqyhgYAAA== "/image-index-schema.json": { local: "image-index-schema.json", - size: 3157, - modtime: 1489085976, + size: 3151, + modtime: 1493147606, compressed: ` -H4sIAAAJbogA/7yWz27bOBDG736KgRIglyRcLII9GEEuu5ec9tCglyKHCTmyJrVIlaSTuIXfvSBp2ZIo -u4lq9GYPOd98vxH//ZgBFIqctNx4NrqYQ/F/Q/pfoz2yJgv3NS4I7rWiN/jUkOSSJcaplyH33MmKagx5 -lffNXIhnZ/RVil4buxDKYumv/roRKXaW8li1KW4uhGlIy7aki2lptuBQXnAonxL9uqGQap6eSfoUa6xp -yHomV8whIAEUKf8zWZewUjinfajYQcm0VOASHjnwFUGsDLEyJDF4SWqADlADa08LstFCVJ7AJPo2d1It -ZVajZs31qi7m8Pc+hm9tLIY2aaSoUXNJzrsufquM1uK6491T3Z33YZy22H/b9pq96fGvth2x9G3FlkKt -L7toME+K8SGkXXbDjr8PIooX5HyxCz12xEcWRibfH8gXSFgLcXZgAFPGxWGpJEtakoIMKYqcWypDtqLS -XaldT67D7jgTikrWHCo4sXfSUdjk0O/xGSYCa3hae3KTvI4YZO3/uTlsbtv/99iTdt14s7DYVCxBViS/ -ulUNSaG1mzxeBozwt0HvyWq4uK3QVXfz24reUJHkGpfbzLuL6d0frp4h3couh2snZ0NYcgII06G0pobX -imUFPpwuiQhqXMMTgTKvemlQkZruOro66LlZoi+NrXPfH9vSO52Bz4ObGY5s6DiGVlbsSfqVpUEeQGF6 -TL2dDEd3c66dj0+mF0dNd9rhvGW9KAYTNmOYp7Rn3GlMXb9kd+UpzO1kT2OyJAzf4dQt3Osesdm/Mrtl -s8vz3ZAAm19iv6Bl1PkRO6mHxxv4h1Fnh/71DzTU2vj46Bw5iz/2zffHquiqTj6JuyKzMZb216b3NBsn -mvSCHMP4HYBgNNrMT/Ji7LXaeWbOAB5nm9nPAAAA//+x+RVQVQwAAA== +H4sIAAAAAAAA/7yWP2/bPBDGd3+KgxIgSxK+eBF0MIIs7ZKpQ4MuRQaGPFmXWqR6pJO4hb97QTKyJVF2 +E9XoZh95z/2eE//9mgEUGp1iajxZU8yh+Nyg+WiNl2SQ4baWC4Rbo/EFvjSoqCQl49TzkHvqVIW1DHmV +981ciEdnzUWKXlpeCM2y9Bf/XYkUO0l5pNsUNxfCNmhUW9LFtDRbUCgvKJRPiX7dYEi1D4+ofIo1bBtk +T+iKOQRLAEXK/4rskq0Uzt3eVeSgJFxqcMkeOvAVQqwMsTIkMXhKaiAdSANkPC6QI0JUnuBJ9DG3Uq3L +rEZNhupVXczh/11MvrSxGNqkkaKWhkp03nXtt8qSWa477B7r7rx322mLfXptr91Bj3+11xHGHytiDLW+ +baMBHjXJu5B23g07+jmIaFqg88U2dN8RH1kYmXx/IF8gYS3E2cED2DIuDsYSGY1CDZmlKHLKWIZsjaW7 +0NueXIbdcSI0lmQoVHBiR9JR2OSm38IZJgIZeFh7dJNYRwDJ+A9X++Fe+/8WPMXrxtsFy6YiBapC9d2t +akgKLW5iPA82wt9Geo9s4OxaLheWyVf1zfw6rEWN+uZset+H62boa8XL4arJXUlYUkIP06FkW8NzRaoC +H86V5AVquYYHBG2fzdJKjXo6daTay9wspS8t1zn3+zbzVmfAuXcbw4GtHMckq4o8Kr9iHOQBFLbnqbeH +4eA+zrXz8cnuxUHoTjucZzKLYjBhM2bzmHjWHQfq8im7JY8Bt5U9DmSJMnyHY7dwp3sAs39Zdstm1+ab +TQJs/mj7STJJkx+uk3p4uIH/2Ops37/+gSaNsT4+N0fO4vd9892xKrqqk0/irshszEv7a9N7lI07mvR2 +HLPxNwYCaMTMT/Ji7J3aeWDOAO5nm9nvAAAA//8Mp+UwTwwAAA== `, }, "/image-layout-schema.json": { local: "image-layout-schema.json", - size: 414, - modtime: 1485388791, + size: 439, + modtime: 1489792109, compressed: ` -H4sIAAAJbogA/2yPwUrEMBCG732KIXq0TQVPue5pQdiD4EU8xHa2zWKTOJkKi/TdJZlWD91TmD/z8c3/ -UwGoHlNHLrILXhlQp4j+EDxb55HgONkB4dlew8zw0o04WfWQqfskgwE1Mkej9SUFX0vaBBp0T/bMdfuk -JbsTzvUbkozWIaLvNlkqmGxrl8X1ZxELydeImQ0fF+zWLFKISOwwKQO5TTZkUi5+RUpSS/72bb9lA8IZ -eEQ4HY6wMxdusycm54f/HP08KQNv6wygHpu2adU6v5d3qQCWcjDh1+wI+z/k1rlV5pbqNwAA//8bwMuB -ngEAAA== +H4sIAAAAAAAA/2yPQUvEMBCF7/0VQ/Sg4DYVPOW6pwVhD4IX8VDTaTvLNonJVFik/12SaRXRU5g38+W9 +91kBqA6TjRSYvFMG1DGg23vHLTmMcJjaAeGxvfiZ4cmOOLXqLlPXSQYDamQORutT8m4nau3joLvY9rxr +HrRoV8JRtyHJaO0DOruZpYLJtaZsrM/FWEi+BMysfzuhXbUQfcDIhEkZyG2yQyYl8TPGJLVk97fth1yA +74FHhOP+8LvyDbmy8JZ2EgZ6OuNtsS8fbrESR3LDj45unpSBl3UGUPd1UzdqnV/Lu1QAS2kS8X2miN03 +8l+PKnNL9RUAAP//k31n5bcBAAA= `, }, "/image-manifest-schema.json": { local: "image-manifest-schema.json", size: 921, - modtime: 1489085976, + modtime: 1489087148, compressed: ` -H4sIAAAJbogA/5ySMW8iMRCF+/0VI0MJ+O501bZXUZxSJEoTpXB2x7uDWNsZmygo4r9HtnHAkCKifTvv +H4sIAAAAAAAA/5ySMW8iMRCF+/0VI0MJ+O501bZXUZxSJEoTpXB2x7uDWNsZmygo4r9HtnHAkCKifTvv zTdv/dEAiB59x+QCWSNaEHcOzT9rgiKDDOtJDQj/lSGNPsC9w440dSpNL6J97rsRJxWtYwiulXLjrVlm dWV5kD0rHZa//sqszbKP+mLxrZTWoenKVp9seVpSJJDTkSB7w95hdNuXDXZHzbF1yIHQixbiYQAiRzwi +3xclq9vfhjJgybc9uDzheghjAhpOZTlkPPgLQeC8qAMkAk4ICeKFH7bZbKG/Uort16tmcjQtJtEC39O diff --git a/schema/image-index-schema.json b/schema/image-index-schema.json index d1f6e1086..665f0051e 100644 --- a/schema/image-index-schema.json +++ b/schema/image-index-schema.json @@ -31,7 +31,7 @@ "$ref": "defs.json#/definitions/int64" }, "digest": { - "description": "the cryptographic checksum digest of the object, in the pattern ':'", + "description": "the cryptographic checksum digest of the object, in the pattern ':'", "$ref": "defs-descriptor.json#/definitions/digest" }, "urls": { diff --git a/schema/manifest_test.go b/schema/manifest_test.go index 2a6a53529..6c680f53a 100644 --- a/schema/manifest_test.go +++ b/schema/manifest_test.go @@ -92,22 +92,6 @@ func TestManifest(t *testing.T) { fail: true, }, - // expected failure: config.digest is not hex hashed format - { - manifest: ` -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 1470, - "digest": "sha256:c86f7763873b6c0aaehhhhhhhhhhhhhhhhmmmmmmmmmmmmmmmm22d9h3bab59b4f" - }, - "layers": [] -} -`, - fail: true, - }, - // valid manifest with optional fields { manifest: ` @@ -188,6 +172,59 @@ func TestManifest(t *testing.T) { }, "layers": [] } +`, + fail: true, + }, + + // expected pass: test bounds of algorithm field in digest. + { + manifest: ` +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }, + { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256.foo-bar:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }, + { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "multihash+base58:QmRZxt2b1FVZPNqd8hsiykDL3TdBDeTSPX9Kv46HmX4Gx8" + } + ] +} +`, + }, + + // expected failure: push bounds of algorithm field in digest too far. + { + manifest: ` +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+b64:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 1470, + "digest": "sha256+foo+-b:c86f7763873b6c0aae22d963bab59b4f5debbed6685761b5951584f6efb0633b" + } + ] +} `, fail: true, },