sign bootstrap.tar content

This commit is contained in:
Mikaël Cluseau
2025-07-06 11:11:36 +02:00
parent 6651ff0364
commit 216236c1eb

View File

@ -2,6 +2,8 @@ package main
import ( import (
"archive/tar" "archive/tar"
"bytes"
"crypto"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -93,13 +95,47 @@ func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
arch := tar.NewWriter(out) arch := tar.NewWriter(out)
defer arch.Close() defer arch.Close()
ca, err := getUsableClusterCA(ctx.Host.ClusterName, "boot-signer")
if err != nil {
return
}
signer, err := ca.ParseKey()
if err != nil {
return
}
hash := crypto.SHA512
sign := func(name string, digest []byte) (err error) {
sigBytes, err := signer.Sign(nil, digest, hash)
if err != nil {
err = fmt.Errorf("signing to %s failed: %w", name, err)
return err
}
if err = arch.WriteHeader(&tar.Header{
Name: name,
Size: int64(len(sigBytes)),
Mode: 0o644,
}); err != nil {
return
}
_, err = io.Copy(arch, bytes.NewReader(sigBytes))
return
}
// config // config
cfgBytes, cfg, err := ctx.Config() cfgBytes, cfg, err := ctx.Config()
if err != nil { if err != nil {
return err return err
} }
err = arch.WriteHeader(&tar.Header{Name: "config.yaml", Size: int64(len(cfgBytes))}) err = arch.WriteHeader(&tar.Header{
Name: "config.yaml",
Size: int64(len(cfgBytes)),
Mode: 0o600,
})
if err != nil { if err != nil {
return return
} }
@ -109,10 +145,19 @@ func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
return return
} }
{
h := hash.New()
h.Write(cfgBytes)
err = sign("config.yaml.sig", h.Sum(nil))
if err != nil {
return
}
}
// layers // layers
for _, layer := range cfg.Layers { for _, layer := range cfg.Layers {
if layer == "modules" { if layer == "modules" {
continue // modules are with the kernel in boot v2 continue // modules are in the initrd with boot v2
} }
layerVersion := ctx.Host.Versions[layer] layerVersion := ctx.Host.Versions[layer]
@ -137,14 +182,24 @@ func buildBootstrap(out io.Writer, ctx *renderContext) (err error) {
return err return err
} }
h := hash.New()
reader := io.TeeReader(f, h)
if err = arch.WriteHeader(&tar.Header{ if err = arch.WriteHeader(&tar.Header{
Name: layer + ".fs", Name: layer + ".fs",
Size: stat.Size(), Size: stat.Size(),
Mode: 0o600,
}); err != nil { }); err != nil {
return err return err
} }
_, err = io.Copy(arch, f) _, err = io.Copy(arch, reader)
if err != nil {
return err
}
digest := h.Sum(nil)
err = sign(layer+".fs.sig", digest)
if err != nil { if err != nil {
return err return err
} }