From c94312758f4fb78322c1845f73e9be26297c83a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Tue, 1 Aug 2017 16:22:01 +0200 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20load=20the=20manifest=20in=20Ge?= =?UTF-8?q?tSignatures=20if=20the=20digest=20is=20known?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we are supplied a digested reference, use it instead of possibly fetching the manifest. This allows using signatures which are not protected even if the manifest is, in some situations; in ordinary operation accessing the whole image, this does not make any difference because we are fetching the manifest either way. To ensure consistent behavior, only use the reference digest if it uses the digest.Canonical algorithm, which has been used so far. This could be perhaps relaxed in the future. Note that this does not promise that GetSignatures will never need authentication—e.g. for X-Registry-Supports-Signatures this already depends on the server, and for the sigstore lookaside authentication support may be added in the future. Signed-off-by: Miloslav Trmač --- docker/docker_image_src.go | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/docker/docker_image_src.go b/docker/docker_image_src.go index ebc5cfabd7..cb48086963 100644 --- a/docker/docker_image_src.go +++ b/docker/docker_image_src.go @@ -206,13 +206,24 @@ func (s *dockerImageSource) GetSignatures() ([][]byte, error) { } } +// manifestDigest returns a digest of the manifest, either from the supplied reference or from a fetched manifest. +func (s *dockerImageSource) manifestDigest() (digest.Digest, error) { + if digested, ok := s.ref.ref.(reference.Digested); ok { + d := digested.Digest() + if d.Algorithm() == digest.Canonical { + return d, nil + } + } + if err := s.ensureManifestIsLoaded(); err != nil { + return "", err + } + return manifest.Digest(s.cachedManifest) +} + // getSignaturesFromLookaside implements GetSignatures() from the lookaside location configured in s.c.signatureBase, // which is not nil. func (s *dockerImageSource) getSignaturesFromLookaside() ([][]byte, error) { - if err := s.ensureManifestIsLoaded(); err != nil { - return nil, err - } - manifestDigest, err := manifest.Digest(s.cachedManifest) + manifestDigest, err := s.manifestDigest() if err != nil { return nil, err } @@ -277,10 +288,7 @@ func (s *dockerImageSource) getOneSignature(url *url.URL) (signature []byte, mis // getSignaturesFromAPIExtension implements GetSignatures() using the X-Registry-Supports-Signatures API extension. func (s *dockerImageSource) getSignaturesFromAPIExtension() ([][]byte, error) { - if err := s.ensureManifestIsLoaded(); err != nil { - return nil, err - } - manifestDigest, err := manifest.Digest(s.cachedManifest) + manifestDigest, err := s.manifestDigest() if err != nil { return nil, err }