From 9e56163c24d7f718bd68159d433e2dd68bf29425 Mon Sep 17 00:00:00 2001 From: Leonard Cohnen Date: Wed, 7 Dec 2022 13:36:58 +0100 Subject: [PATCH] [no ci] wip --- internal/versions/hash-generator/generate.go | 74 ++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/internal/versions/hash-generator/generate.go b/internal/versions/hash-generator/generate.go index 2df826860bb..412d0d75de5 100644 --- a/internal/versions/hash-generator/generate.go +++ b/internal/versions/hash-generator/generate.go @@ -19,10 +19,15 @@ import ( "log" "net/http" "os" + "regexp" + "strconv" + "github.com/edgelesssys/constellation/v2/internal/sigstore" "golang.org/x/tools/go/ast/astutil" ) +var kuberntesMinorRegex = regexp.MustCompile(`^.*\.(?P\d+)\..*(kubelet|kubeadm|kubectl)+$`) + func mustGetHash(url string) string { // remove quotes around url url = url[1 : len(url)-1] @@ -78,9 +83,78 @@ func mustGetHash(url string) string { panic("hash mismatch") } + // Verify cosign signature if available + // Currently, we verify the signature of kubeadm, kubelet and kubectl with minor version >=1.26. + minorVersion := kuberntesMinorRegex.FindStringSubmatch(url) + if minorVersion == nil { + return fmt.Sprintf("\"sha256:%x\"", fileHash) + } + minorVersionIndex := kuberntesMinorRegex.SubexpIndex("Minor") + if minorVersionIndex != -1 { + minorVersionNumber, err := strconv.Atoi(minorVersion[minorVersionIndex]) + if err != nil { + panic(err) + } + if minorVersionNumber >= 26 { + content, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + if err := verifyCosignSignature(content, url); err != nil { + panic(err) + } + } + } + return fmt.Sprintf("\"sha256:%x\"", fileHash) } +func verifyCosignSignature(content []byte, url string) error { + // Get the signature + req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url+".sig", nil) + if err != nil { + panic(err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + // Check server response + if resp.StatusCode != http.StatusOK { + panic("bad status: " + resp.Status) + } + + sig, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + // Get the certificate + req, err = http.NewRequestWithContext(context.Background(), http.MethodGet, url+".cert", nil) + if err != nil { + panic(err) + } + resp, err = http.DefaultClient.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + // Check server response + if resp.StatusCode != http.StatusOK { + panic("bad status: " + resp.Status) + } + + cert, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + return sigstore.VerifySignature(content, sig, cert) +} + func main() { fmt.Println("Generating hashes...")