diff --git a/pkg/chunked/cache_linux.go b/pkg/chunked/cache_linux.go index 4cfde5c4f4..34d1b92f4e 100644 --- a/pkg/chunked/cache_linux.go +++ b/pkg/chunked/cache_linux.go @@ -897,6 +897,14 @@ func unmarshalToc(manifest []byte) (*internal.TOC, error) { toc.Entries = append(toc.Entries, m) } + case "tarsplitdigest": // strings.ToLower("tarSplitDigest") + s := iter.ReadString() + d, err := digest.Parse(s) + if err != nil { + return nil, fmt.Errorf("Invalid tarSplitDigest %q: %w", s, err) + } + toc.TarSplitDigest = d + default: iter.Skip() } diff --git a/pkg/chunked/compression_linux.go b/pkg/chunked/compression_linux.go index c1042da1fa..5b2c556725 100644 --- a/pkg/chunked/compression_linux.go +++ b/pkg/chunked/compression_linux.go @@ -147,12 +147,10 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di // The tarSplit… values are valid if tarSplitChunk.Offset > 0 var tarSplitChunk ImageSourceChunk var tarSplitLengthUncompressed uint64 - var tarSplitChecksum string if tarSplitInfoKeyAnnotation, found := annotations[internal.TarSplitInfoKey]; found { if _, err := fmt.Sscanf(tarSplitInfoKeyAnnotation, "%d:%d:%d", &tarSplitChunk.Offset, &tarSplitChunk.Length, &tarSplitLengthUncompressed); err != nil { return nil, nil, nil, 0, err } - tarSplitChecksum = annotations[internal.TarSplitChecksumKey] } if manifestType != internal.ManifestTypeCRFS { @@ -217,7 +215,7 @@ func readZstdChunkedManifest(blobStream ImageSourceSeekable, tocDigest digest.Di return nil, nil, nil, 0, err } - decodedTarSplit, err = decodeAndValidateBlob(tarSplit, tarSplitLengthUncompressed, tarSplitChecksum) + decodedTarSplit, err = decodeAndValidateBlob(tarSplit, tarSplitLengthUncompressed, toc.TarSplitDigest.String()) if err != nil { return nil, nil, nil, 0, err } diff --git a/pkg/chunked/internal/compression.go b/pkg/chunked/internal/compression.go index 52c9ce341a..6cb07a60c1 100644 --- a/pkg/chunked/internal/compression.go +++ b/pkg/chunked/internal/compression.go @@ -18,8 +18,9 @@ import ( ) type TOC struct { - Version int `json:"version"` - Entries []FileMetadata `json:"entries"` + Version int `json:"version"` + Entries []FileMetadata `json:"entries"` + TarSplitDigest digest.Digest `json:"tarSplitDigest,omitempty"` } type FileMetadata struct { @@ -84,7 +85,7 @@ func GetType(t byte) (string, error) { const ( ManifestChecksumKey = "io.github.containers.zstd-chunked.manifest-checksum" ManifestInfoKey = "io.github.containers.zstd-chunked.manifest-position" - TarSplitChecksumKey = "io.github.containers.zstd-chunked.tarsplit-checksum" + TarSplitChecksumKey = "io.github.containers.zstd-chunked.tarsplit-checksum" // Deprecated: Use the TOC.TarSplitDigest field instead, this one is not authenticated by ManifestChecksumKey. TarSplitInfoKey = "io.github.containers.zstd-chunked.tarsplit-position" // ManifestTypeCRFS is a manifest file compatible with the CRFS TOC file. @@ -133,8 +134,9 @@ func WriteZstdChunkedManifest(dest io.Writer, outMetadata map[string]string, off manifestOffset := offset + zstdSkippableFrameHeader toc := TOC{ - Version: 1, - Entries: metadata, + Version: 1, + Entries: metadata, + TarSplitDigest: tarSplitData.Digest, } json := jsoniter.ConfigCompatibleWithStandardLibrary