From a58b1add36411e3b452ad7755fc6120655d4ee11 Mon Sep 17 00:00:00 2001 From: ramonskie Date: Tue, 13 Apr 2021 11:03:05 +0200 Subject: [PATCH] add sha256 support if available on bosh.io Signed-off-by: ramonskie --- README.md | 1 + boshio/boshio.go | 32 +++++++++++++++++++++++++------- boshio/boshio_test.go | 30 ++++++++++++++++++++++++++---- boshio/init_test.go | 14 +++++++++----- boshio/stemcells.go | 9 +++++---- boshio/stemcells_test.go | 20 ++++++++++++++++++++ cmd/in/main.go | 22 +++++++++++++++------- 7 files changed, 101 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index ef9dbb3..ae25f66 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Fetches a given stemcell, placing the following files in the destination: * `version`: The version number of the stemcell. * `url`: A URL that can be used to download the stemcell tarball. * `sha1`: The SHA1 of the stemcell +* `sha256`: The SHA256 of the stemcell * `stemcell.tgz`: The stemcell tarball, if the `tarball` param is `true`. #### Parameters diff --git a/boshio/boshio.go b/boshio/boshio.go index 973520a..f880ccb 100644 --- a/boshio/boshio.go +++ b/boshio/boshio.go @@ -2,6 +2,7 @@ package boshio import ( "crypto/sha1" + "crypto/sha256" "encoding/json" "fmt" "io" @@ -99,6 +100,11 @@ func (c *Client) WriteMetadata(stemcell Stemcell, metadataKey string, metadataFi if err != nil { return err } + case "sha256": + _, err := metadataFile.Write([]byte(stemcell.Details().SHA256)) + if err != nil { + return err + } case "version": _, err := metadataFile.Write([]byte(stemcell.Version)) if err != nil { @@ -173,14 +179,26 @@ func (c *Client) DownloadStemcell(stemcell Stemcell, location string, preserveFi c.Bar.Finish() - computedSHA := sha1.New() - _, err = io.Copy(computedSHA, stemcellData) - if err != nil { - return err - } + if stemcell.Details().SHA256 == "" { + computedSHA := sha1.New() + _, err = io.Copy(computedSHA, stemcellData) + if err != nil { + return err + } - if fmt.Sprintf("%x", computedSHA.Sum(nil)) != stemcell.Details().SHA1 { - return fmt.Errorf("computed sha1 %x did not match expected sha1 of %s", computedSHA.Sum(nil), stemcell.Details().SHA1) + if fmt.Sprintf("%x", computedSHA.Sum(nil)) != stemcell.Details().SHA1 { + return fmt.Errorf("computed sha1 %x did not match expected sha1 of %s", computedSHA.Sum(nil), stemcell.Details().SHA1) + } + } else { + computedSHA256 := sha256.New() + _, err = io.Copy(computedSHA256, stemcellData) + if err != nil { + return err + } + + if fmt.Sprintf("%x", computedSHA256.Sum(nil)) != stemcell.Details().SHA256 { + return fmt.Errorf("computed sha256 %x did not match expected sha256 of %s", computedSHA256.Sum(nil), stemcell.Details().SHA256) + } } return nil diff --git a/boshio/boshio_test.go b/boshio/boshio_test.go index 4616773..3d29cca 100644 --- a/boshio/boshio_test.go +++ b/boshio/boshio_test.go @@ -52,10 +52,11 @@ var _ = Describe("Boshio", func() { Name: "a stemcell", Version: "some version", Light: &boshio.Metadata{ - URL: serverPath("path/to/light-different-stemcell.tgz"), - Size: 100, - MD5: "qqqq", - SHA1: "2222", + URL: serverPath("path/to/light-different-stemcell.tgz"), + Size: 100, + MD5: "qqqq", + SHA1: "2222", + SHA256: "4444", }, }, })) @@ -127,6 +128,15 @@ var _ = Describe("Boshio", func() { Expect(string(sha1)).To(Equal("2222")) }) + It("writes the sha256 to disk", func() { + err := client.WriteMetadata(boshio.Stemcell{Regular: &boshio.Metadata{SHA256: "4444"}}, "sha256", fileLocation) + Expect(err).NotTo(HaveOccurred()) + + sha256, err := ioutil.ReadFile(fileLocation.Name()) + Expect(err).NotTo(HaveOccurred()) + Expect(string(sha256)).To(Equal("4444")) + }) + It("writes the version to disk", func() { err := client.WriteMetadata(boshio.Stemcell{Version: "some version", Regular: &boshio.Metadata{}}, "version", fileLocation) Expect(err).NotTo(HaveOccurred()) @@ -330,6 +340,18 @@ var _ = Describe("Boshio", func() { }) }) + Context("when the sha256 cannot be verified", func() { + It("returns an error", func() { + stubStemcell.Regular.SHA256 = "4444" + boshioServer.Start() + location, err := ioutil.TempDir("", "") + Expect(err).NotTo(HaveOccurred()) + + err = client.DownloadStemcell(stubStemcell, location, true) + Expect(err).To(MatchError("computed sha256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 did not match expected sha256 of 4444")) + }) + }) + Context("when the get request is not successful", func() { It("returns an error", func() { ranger.BuildRangeReturns([]string{"0-9"}, nil) diff --git a/boshio/init_test.go b/boshio/init_test.go index 559fb86..d9d13ff 100644 --- a/boshio/init_test.go +++ b/boshio/init_test.go @@ -59,7 +59,7 @@ var _ = BeforeEach(func() { LightAPIHandler: lightAPIHandler, HeavyAPIHandler: heavyAPIHandler, HeavyAndLightAPIHandler: heavyAndLightAPIHandler, - s: testServer, + s: testServer, } }) @@ -100,7 +100,8 @@ func lightAPIHandler(w http.ResponseWriter, req *http.Request) { "url": "%spath/to/light-different-stemcell.tgz", "size": 100, "md5": "qqqq", - "sha1": "2222" + "sha1": "2222", + "sha256": "4444" } }]`, boshioServer.URL()))) } @@ -111,7 +112,8 @@ func heavyAPIHandler(w http.ResponseWriter, req *http.Request) { "url": "%spath/to/heavy-different-stemcell.tgz", "size": 2000, "md5": "zzzz", - "sha1": "asdf" + "sha1": "asdf", + "sha256": "qwerty" } }]`, boshioServer.URL()))) } @@ -122,13 +124,15 @@ func heavyAndLightAPIHandler(w http.ResponseWriter, req *http.Request) { "url": "%spath/to/heavy-different-stemcell.tgz", "size": 2000, "md5": "zzzz", - "sha1": "asdf" + "sha1": "asdf", + "sha256": "qwerty" }, "light": { "url": "%spath/to/light-different-stemcell.tgz", "size": 100, "md5": "qqqq", - "sha1": "2222" + "sha1": "2222", + "sha256": "4444" } }]`, boshioServer.URL(), boshioServer.URL()))) } diff --git a/boshio/stemcells.go b/boshio/stemcells.go index db6e847..8163438 100644 --- a/boshio/stemcells.go +++ b/boshio/stemcells.go @@ -9,10 +9,11 @@ type Stemcell struct { } type Metadata struct { - URL string - Size int64 - MD5 string - SHA1 string + URL string + Size int64 + MD5 string + SHA1 string + SHA256 string } func (s Stemcell) Details() Metadata { diff --git a/boshio/stemcells_test.go b/boshio/stemcells_test.go index 75a1df2..8efe152 100644 --- a/boshio/stemcells_test.go +++ b/boshio/stemcells_test.go @@ -27,6 +27,26 @@ var _ = Describe("Stemcells", func() { })) }) + It("returns regular stemcell metadata with sha256", func() { + stemcell := boshio.Stemcell{ + Regular: &boshio.Metadata{ + URL: "fake-url", + Size: 2000, + MD5: "fake-md5", + SHA1: "fake-sha1", + SHA256: "fake-sha256", + }, + } + metadata := stemcell.Details() + Expect(metadata).To(Equal(boshio.Metadata{ + URL: "fake-url", + Size: 2000, + MD5: "fake-md5", + SHA1: "fake-sha1", + SHA256: "fake-sha256", + })) + }) + It("returns light stemcell metadata", func() { stemcell := boshio.Stemcell{ Light: &boshio.Metadata{ diff --git a/cmd/in/main.go b/cmd/in/main.go index ea9c08a..13040df 100644 --- a/cmd/in/main.go +++ b/cmd/in/main.go @@ -65,7 +65,7 @@ func main() { log.Fatalf("failed to find stemcell matching version: '%s'\n", inRequest.Version.Version) } - dataLocations := []string{"version", "sha1", "url"} + dataLocations := []string{"version", "sha1", "sha256", "url"} for _, name := range dataLocations { fileLocation, err := os.Create(filepath.Join(location, name)) @@ -87,11 +87,19 @@ func main() { } } + metadata := []concourseMetadataField{ + {Name: "url", Value: stemcell.Details().URL}, + {Name: "sha1", Value: stemcell.Details().SHA1}, + } + + if stemcell.Details().SHA256 != "" { + m := concourseMetadataField{Name: "sha256", Value: stemcell.Details().SHA256} + metadata = append(metadata, m) + } + json.NewEncoder(os.Stdout).Encode(concourseInResponse{ - Version: inRequest.Version, - Metadata: []concourseMetadataField{ - {Name: "url", Value: stemcell.Details().URL}, - {Name: "sha1", Value: stemcell.Details().SHA1}, - }, - }) + Version: inRequest.Version, + Metadata: metadata, + }, + ) }