cryptManifestList encrypts or decrypts the children of a top level manifest list
(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter, cryptoOp cryptoOp)
| 382 | |
| 383 | // cryptManifestList encrypts or decrypts the children of a top level manifest list |
| 384 | func cryptManifestList(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter, cryptoOp cryptoOp) (ocispec.Descriptor, bool, error) { |
| 385 | // read the index; if any layer is encrypted and any manifests change we will need to rewrite it |
| 386 | b, err := content.ReadBlob(ctx, cs, desc) |
| 387 | if err != nil { |
| 388 | return ocispec.Descriptor{}, false, err |
| 389 | } |
| 390 | |
| 391 | var index ocispec.Index |
| 392 | if err := json.Unmarshal(b, &index); err != nil { |
| 393 | return ocispec.Descriptor{}, false, err |
| 394 | } |
| 395 | |
| 396 | var newManifests []ocispec.Descriptor |
| 397 | modified := false |
| 398 | for _, manifest := range index.Manifests { |
| 399 | if cryptoOp == cryptoOpUnwrapOnly && !isLocalPlatform(manifest.Platform) { |
| 400 | continue |
| 401 | } |
| 402 | newManifest, m, err := cryptChildren(ctx, cs, manifest, cc, lf, cryptoOp, manifest.Platform) |
| 403 | if err != nil || cryptoOp == cryptoOpUnwrapOnly { |
| 404 | return ocispec.Descriptor{}, false, err |
| 405 | } |
| 406 | if m { |
| 407 | modified = true |
| 408 | } |
| 409 | newManifests = append(newManifests, newManifest) |
| 410 | } |
| 411 | if cryptoOp == cryptoOpUnwrapOnly { |
| 412 | return ocispec.Descriptor{}, false, fmt.Errorf("no manifest found for local platform") |
| 413 | } |
| 414 | |
| 415 | if modified { |
| 416 | // we need to update the index |
| 417 | newIndex := ocispec.Index{ |
| 418 | Versioned: index.Versioned, |
| 419 | Manifests: newManifests, |
| 420 | } |
| 421 | |
| 422 | mb, err := json.MarshalIndent(newIndex, "", " ") |
| 423 | if err != nil { |
| 424 | return ocispec.Descriptor{}, false, fmt.Errorf("failed to marshal index: %w", err) |
| 425 | } |
| 426 | |
| 427 | newDesc := ocispec.Descriptor{ |
| 428 | MediaType: ocispec.MediaTypeImageIndex, |
| 429 | Size: int64(len(mb)), |
| 430 | Digest: digest.Canonical.FromBytes(mb), |
| 431 | } |
| 432 | |
| 433 | labels := map[string]string{} |
| 434 | for i, m := range newIndex.Manifests { |
| 435 | labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = m.Digest.String() |
| 436 | } |
| 437 | |
| 438 | ref := fmt.Sprintf("index-%s", newDesc.Digest.String()) |
| 439 | |
| 440 | if err = content.WriteBlob(ctx, cs, ref, bytes.NewReader(mb), newDesc, content.WithLabels(labels)); err != nil { |
| 441 | return ocispec.Descriptor{}, false, fmt.Errorf("failed to write index: %w", err) |
no test coverage detected
searching dependent graphs…