mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-26 14:01:39 +01:00
Support different providers, not only static file paths. Drop `pcr-signing-key-public.pem` file, as we generate it on the fly now. See https://github.com/siderolabs/image-factory/issues/19 Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
136 lines
3.4 KiB
Go
136 lines
3.4 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
// Package uki creates the UKI file out of the sd-stub and other sections.
|
|
package uki
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/siderolabs/talos/internal/pkg/secureboot"
|
|
"github.com/siderolabs/talos/internal/pkg/secureboot/measure"
|
|
"github.com/siderolabs/talos/internal/pkg/secureboot/pesign"
|
|
)
|
|
|
|
// section is a UKI file section.
|
|
type section struct {
|
|
// Section name.
|
|
Name secureboot.Section
|
|
// Path to the contents of the section.
|
|
Path string
|
|
// Should the section be measured to the TPM?
|
|
Measure bool
|
|
// Should the section be appended, or is it already in the PE file.
|
|
Append bool
|
|
// Size & VMA of the section.
|
|
Size uint64
|
|
VMA uint64
|
|
}
|
|
|
|
// Builder is a UKI file builder.
|
|
type Builder struct {
|
|
// Source options.
|
|
//
|
|
// Arch of the UKI file.
|
|
Arch string
|
|
// Version of Talos.
|
|
Version string
|
|
// Path to the sd-stub.
|
|
SdStubPath string
|
|
// Path to the sd-boot.
|
|
SdBootPath string
|
|
// Path to the kernel image.
|
|
KernelPath string
|
|
// Path to the initrd image.
|
|
InitrdPath string
|
|
// Kernel cmdline.
|
|
Cmdline string
|
|
// SecureBoot certificate and signer.
|
|
SecureBootSigner pesign.CertificateSigner
|
|
// PCR signer.
|
|
PCRSigner measure.RSAKey
|
|
|
|
// Output options:
|
|
//
|
|
// Path to the signed sd-boot.
|
|
OutSdBootPath string
|
|
// Path to the output UKI file.
|
|
OutUKIPath string
|
|
|
|
// fields initialized during build
|
|
sections []section
|
|
scratchDir string
|
|
peSigner *pesign.Signer
|
|
unsignedUKIPath string
|
|
}
|
|
|
|
// Build the UKI file.
|
|
//
|
|
// Build process is as follows:
|
|
// - sign the sd-boot EFI binary, and write it to the OutSdBootPath
|
|
// - build ephemeral sections (uname, os-release), and other proposed sections
|
|
// - measure sections, generate signature, and append to the list of sections
|
|
// - assemble the final UKI file starting from sd-stub and appending generated section.
|
|
func (builder *Builder) Build(printf func(string, ...any)) error {
|
|
var err error
|
|
|
|
builder.scratchDir, err = os.MkdirTemp("", "talos-uki")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if err = os.RemoveAll(builder.scratchDir); err != nil {
|
|
log.Printf("failed to remove scratch dir: %v", err)
|
|
}
|
|
}()
|
|
|
|
printf("signing systemd-boot")
|
|
|
|
builder.peSigner, err = pesign.NewSigner(builder.SecureBootSigner)
|
|
if err != nil {
|
|
return fmt.Errorf("error initializing signer: %w", err)
|
|
}
|
|
|
|
// sign sd-boot
|
|
if err = builder.peSigner.Sign(builder.SdBootPath, builder.OutSdBootPath); err != nil {
|
|
return fmt.Errorf("error signing sd-boot: %w", err)
|
|
}
|
|
|
|
printf("generating UKI sections")
|
|
|
|
// generate and build list of all sections
|
|
for _, generateSection := range []func() error{
|
|
builder.generateOSRel,
|
|
builder.generateCmdline,
|
|
builder.generateInitrd,
|
|
builder.generateSplash,
|
|
builder.generateUname,
|
|
builder.generateSBAT,
|
|
builder.generatePCRPublicKey,
|
|
// append kernel last to account for decompression
|
|
builder.generateKernel,
|
|
// measure sections last
|
|
builder.generatePCRSig,
|
|
} {
|
|
if err = generateSection(); err != nil {
|
|
return fmt.Errorf("error generating sections: %w", err)
|
|
}
|
|
}
|
|
|
|
printf("assembling UKI")
|
|
|
|
// assemble the final UKI file
|
|
if err = builder.assemble(); err != nil {
|
|
return fmt.Errorf("error assembling UKI: %w", err)
|
|
}
|
|
|
|
printf("signing UKI")
|
|
|
|
// sign the UKI file
|
|
return builder.peSigner.Sign(builder.unsignedUKIPath, builder.OutUKIPath)
|
|
}
|