Skip to content
This repository was archived by the owner on Jan 22, 2026. It is now read-only.

Commit a708376

Browse files
committed
[no ci] wip
1 parent 548bb2d commit a708376

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

internal/versions/hash-generator/BUILD.bazel

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ go_library(
66
srcs = ["generate.go"],
77
importpath = "github.com/edgelesssys/constellation/v2/internal/versions/hash-generator",
88
visibility = ["//visibility:private"],
9-
deps = ["@org_golang_x_tools//go/ast/astutil"],
9+
deps = [
10+
"//internal/sigstore",
11+
"@org_golang_x_tools//go/ast/astutil",
12+
],
1013
)
1114

1215
go_binary(

internal/versions/hash-generator/generate.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ import (
1919
"log"
2020
"net/http"
2121
"os"
22+
"regexp"
23+
"strconv"
2224

2325
"golang.org/x/tools/go/ast/astutil"
2426
)
2527

28+
var kuberntesMinorRegex = regexp.MustCompile(`^.*\.(?P<Minor>\d+)\..*(kubelet|kubeadm|kubectl)+$`)
29+
2630
func mustGetHash(url string) string {
2731
// remove quotes around url
2832
url = url[1 : len(url)-1]
@@ -78,9 +82,80 @@ func mustGetHash(url string) string {
7882
panic("hash mismatch")
7983
}
8084

85+
// Verify cosign signature if available
86+
// Currently, we verify the signature of kubeadm, kubelet and kubectl with minor version >=1.26.
87+
minorVersion := kuberntesMinorRegex.FindStringSubmatch(url)
88+
if minorVersion == nil {
89+
return fmt.Sprintf("\"sha256:%x\"", fileHash)
90+
}
91+
minorVersionIndex := kuberntesMinorRegex.SubexpIndex("Minor")
92+
if minorVersionIndex != -1 {
93+
minorVersionNumber, err := strconv.Atoi(minorVersion[minorVersionIndex])
94+
if err != nil {
95+
panic(err)
96+
}
97+
if minorVersionNumber >= 26 {
98+
content, err := io.ReadAll(resp.Body)
99+
if err != nil {
100+
panic(err)
101+
}
102+
if err := verifyCosignSignature(content, url); err != nil {
103+
panic(err)
104+
}
105+
}
106+
}
107+
81108
return fmt.Sprintf("\"sha256:%x\"", fileHash)
82109
}
83110

111+
func verifyCosignSignature(content []byte, url string) error {
112+
// Get the signature
113+
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url+".sig", nil)
114+
if err != nil {
115+
panic(err)
116+
}
117+
resp, err := http.DefaultClient.Do(req)
118+
if err != nil {
119+
panic(err)
120+
}
121+
defer resp.Body.Close()
122+
123+
// Check server response
124+
if resp.StatusCode != http.StatusOK {
125+
panic("bad status: " + resp.Status)
126+
}
127+
128+
sig, err := io.ReadAll(resp.Body)
129+
if err != nil {
130+
panic(err)
131+
}
132+
133+
// Get the certificate
134+
req, err = http.NewRequestWithContext(context.Background(), http.MethodGet, url+".cert", nil)
135+
if err != nil {
136+
panic(err)
137+
}
138+
resp, err = http.DefaultClient.Do(req)
139+
if err != nil {
140+
panic(err)
141+
}
142+
defer resp.Body.Close()
143+
144+
// Check server response
145+
if resp.StatusCode != http.StatusOK {
146+
panic("bad status: " + resp.Status)
147+
}
148+
149+
base64Cert, err := io.ReadAll(resp.Body)
150+
if err != nil {
151+
panic(err)
152+
}
153+
154+
// TODO: implement https://github.com/sigstore/cosign/blob/v2.2.0/cmd/cosign/cli/verify/verify_blob.go keyless verification
155+
156+
return verifier.VerifySignature(content, sig)
157+
}
158+
84159
func main() {
85160
fmt.Println("Generating hashes...")
86161

0 commit comments

Comments
 (0)