Skip to content

Commit

Permalink
Merge pull request #654 from stevvooe/future-proof-digest-constraints
Browse files Browse the repository at this point in the history
schema: allow compound algorithm specifiers in digests
  • Loading branch information
stevvooe authored May 9, 2017
2 parents 93f7ad5 + b52b2bf commit 3690645
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 87 deletions.
51 changes: 32 additions & 19 deletions descriptor.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,58 +57,71 @@ 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

A _digest_ is calculated by the following pseudo-code, where `H` is the selected hash algorithm, identified by string `<alg>`:
```
let ID(C) = Descriptor.digest
let C = <bytes>
let D = '<alg>:' + EncodeHex(H(C))
let D = '<alg>:' + 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) == '<alg>:' + EncodeHex(H(C))
D == ID(C) == '<alg>:' + 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:

Expand Down
4 changes: 2 additions & 2 deletions image-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<alg>:<hex>` (per [descriptor](descriptor.md#digests-and-verification)), MUST have its content stored in a file under `blobs/<alg>/<hex>`.
* The character set of the entry name for `<hex>` and `<alg>` MUST match the respective grammar elements described in [descriptor](descriptor.md#digests-and-verification).
* A blob, referenced with digest `<alg>:<encoded>` (per [descriptor](descriptor.md#digests-and-verification)), MUST have its content stored in a file under `blobs/<alg>/<encoded>`.
* The character set of the entry name for `<encoded>` and `<alg>` 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.
Expand Down
2 changes: 1 addition & 1 deletion schema/content-descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"$ref": "defs.json#/definitions/int64"
},
"digest": {
"description": "the cryptographic checksum digest of the object, in the pattern '<hash>:<hexadecimal digest>'",
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
"$ref": "defs-descriptor.json#/definitions/digest"
},
"urls": {
Expand Down
4 changes: 2 additions & 2 deletions schema/defs-descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<hash>:<hexadecimal digest>'",
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
"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",
Expand Down
61 changes: 60 additions & 1 deletion schema/descriptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ func TestDescriptor(t *testing.T) {
"digest": "sha256:5B0BCABD1ED22E9FB1310CF6C2DEC7CDEF19F0AD69EFA1F392E94A4333501270"
}
`,
fail: true,
},

// expected success: valid URL entry
Expand Down Expand Up @@ -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)
Expand Down
91 changes: 46 additions & 45 deletions schema/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion schema/image-index-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"$ref": "defs.json#/definitions/int64"
},
"digest": {
"description": "the cryptographic checksum digest of the object, in the pattern '<hash>:<hexadecimal digest>'",
"description": "the cryptographic checksum digest of the object, in the pattern '<algorithm>:<encoded>'",
"$ref": "defs-descriptor.json#/definitions/digest"
},
"urls": {
Expand Down
Loading

0 comments on commit 3690645

Please sign in to comment.