mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-07-26 16:55:19 -04:00
image: allow toggling secure boot in image upload
This commit is contained in:
parent
c6ea596eb9
commit
3543fe140e
9 changed files with 74 additions and 41 deletions
|
@ -83,20 +83,24 @@ func runAWS(cmd *cobra.Command, _ []string) error {
|
||||||
out = outF
|
out = outF
|
||||||
}
|
}
|
||||||
|
|
||||||
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadReq := &osimage.UploadRequest{
|
uploadReq := &osimage.UploadRequest{
|
||||||
Provider: flags.provider,
|
Provider: flags.provider,
|
||||||
Version: flags.version,
|
Version: flags.version,
|
||||||
AttestationVariant: flags.attestationVariant,
|
AttestationVariant: flags.attestationVariant,
|
||||||
SBDatabase: sbDatabase,
|
SecureBoot: flags.secureBoot,
|
||||||
UEFIVarStore: uefiVarStore,
|
|
||||||
Size: size,
|
Size: size,
|
||||||
Timestamp: flags.timestamp,
|
Timestamp: flags.timestamp,
|
||||||
Image: file,
|
Image: file,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flags.secureBoot {
|
||||||
|
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
uploadReq.SBDatabase = sbDatabase
|
||||||
|
uploadReq.UEFIVarStore = uefiVarStore
|
||||||
|
}
|
||||||
|
|
||||||
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,20 +84,24 @@ func runAzure(cmd *cobra.Command, _ []string) error {
|
||||||
out = outF
|
out = outF
|
||||||
}
|
}
|
||||||
|
|
||||||
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadReq := &osimage.UploadRequest{
|
uploadReq := &osimage.UploadRequest{
|
||||||
Provider: flags.provider,
|
Provider: flags.provider,
|
||||||
Version: flags.version,
|
Version: flags.version,
|
||||||
AttestationVariant: flags.attestationVariant,
|
AttestationVariant: flags.attestationVariant,
|
||||||
SBDatabase: sbDatabase,
|
SecureBoot: flags.secureBoot,
|
||||||
UEFIVarStore: uefiVarStore,
|
|
||||||
Size: size,
|
Size: size,
|
||||||
Timestamp: flags.timestamp,
|
Timestamp: flags.timestamp,
|
||||||
Image: file,
|
Image: file,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flags.secureBoot {
|
||||||
|
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
uploadReq.SBDatabase = sbDatabase
|
||||||
|
uploadReq.UEFIVarStore = uefiVarStore
|
||||||
|
}
|
||||||
|
|
||||||
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ type commonFlags struct {
|
||||||
pki string
|
pki string
|
||||||
provider cloudprovider.Provider
|
provider cloudprovider.Provider
|
||||||
attestationVariant string
|
attestationVariant string
|
||||||
|
secureBoot bool
|
||||||
version versionsapi.Version
|
version versionsapi.Version
|
||||||
timestamp time.Time
|
timestamp time.Time
|
||||||
region string
|
region string
|
||||||
|
@ -49,6 +50,10 @@ func parseCommonFlags(cmd *cobra.Command) (commonFlags, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return commonFlags{}, err
|
return commonFlags{}, err
|
||||||
}
|
}
|
||||||
|
secureBoot, err := cmd.Flags().GetBool("secure-boot")
|
||||||
|
if err != nil {
|
||||||
|
return commonFlags{}, err
|
||||||
|
}
|
||||||
version, err := cmd.Flags().GetString("version")
|
version, err := cmd.Flags().GetString("version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return commonFlags{}, err
|
return commonFlags{}, err
|
||||||
|
@ -97,6 +102,7 @@ func parseCommonFlags(cmd *cobra.Command) (commonFlags, error) {
|
||||||
rawImage: rawImage,
|
rawImage: rawImage,
|
||||||
pki: pki,
|
pki: pki,
|
||||||
attestationVariant: attestationVariant,
|
attestationVariant: attestationVariant,
|
||||||
|
secureBoot: secureBoot,
|
||||||
version: ver,
|
version: ver,
|
||||||
timestamp: timestmp,
|
timestamp: timestmp,
|
||||||
region: region,
|
region: region,
|
||||||
|
|
|
@ -84,20 +84,24 @@ func runGCP(cmd *cobra.Command, _ []string) error {
|
||||||
out = outF
|
out = outF
|
||||||
}
|
}
|
||||||
|
|
||||||
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadReq := &osimage.UploadRequest{
|
uploadReq := &osimage.UploadRequest{
|
||||||
Provider: flags.provider,
|
Provider: flags.provider,
|
||||||
Version: flags.version,
|
Version: flags.version,
|
||||||
AttestationVariant: flags.attestationVariant,
|
AttestationVariant: flags.attestationVariant,
|
||||||
SBDatabase: sbDatabase,
|
SecureBoot: flags.secureBoot,
|
||||||
UEFIVarStore: uefiVarStore,
|
|
||||||
Size: size,
|
Size: size,
|
||||||
Timestamp: flags.timestamp,
|
Timestamp: flags.timestamp,
|
||||||
Image: file,
|
Image: file,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flags.secureBoot {
|
||||||
|
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
uploadReq.SBDatabase = sbDatabase
|
||||||
|
uploadReq.UEFIVarStore = uefiVarStore
|
||||||
|
}
|
||||||
|
|
||||||
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ func NewImageCmd() *cobra.Command {
|
||||||
cmd.SetOut(os.Stdout)
|
cmd.SetOut(os.Stdout)
|
||||||
|
|
||||||
cmd.PersistentFlags().String("raw-image", "", "Path to os image in CSP specific format that should be uploaded.")
|
cmd.PersistentFlags().String("raw-image", "", "Path to os image in CSP specific format that should be uploaded.")
|
||||||
|
cmd.PersistentFlags().Bool("secure-boot", false, "Enables secure boot support.")
|
||||||
cmd.PersistentFlags().String("pki", "", "Base path to the PKI (secure boot signing) files.")
|
cmd.PersistentFlags().String("pki", "", "Base path to the PKI (secure boot signing) files.")
|
||||||
cmd.PersistentFlags().String("attestation-variant", "", "Attestation variant of the image being uploaded.")
|
cmd.PersistentFlags().String("attestation-variant", "", "Attestation variant of the image being uploaded.")
|
||||||
cmd.PersistentFlags().String("version", "", "Shortname of the os image version.")
|
cmd.PersistentFlags().String("version", "", "Shortname of the os image version.")
|
||||||
|
|
|
@ -67,20 +67,24 @@ func runNOP(cmd *cobra.Command, provider cloudprovider.Provider, _ []string) err
|
||||||
out = outF
|
out = outF
|
||||||
}
|
}
|
||||||
|
|
||||||
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadReq := &osimage.UploadRequest{
|
uploadReq := &osimage.UploadRequest{
|
||||||
Provider: flags.provider,
|
Provider: flags.provider,
|
||||||
Version: flags.version,
|
Version: flags.version,
|
||||||
AttestationVariant: flags.attestationVariant,
|
AttestationVariant: flags.attestationVariant,
|
||||||
SBDatabase: sbDatabase,
|
SecureBoot: flags.secureBoot,
|
||||||
UEFIVarStore: uefiVarStore,
|
|
||||||
Size: size,
|
Size: size,
|
||||||
Timestamp: flags.timestamp,
|
Timestamp: flags.timestamp,
|
||||||
Image: file,
|
Image: file,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flags.secureBoot {
|
||||||
|
sbDatabase, uefiVarStore, err := loadSecureBootKeys(flags.pki)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
uploadReq.SBDatabase = sbDatabase
|
||||||
|
uploadReq.UEFIVarStore = uefiVarStore
|
||||||
|
}
|
||||||
|
|
||||||
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
return uploadImage(cmd.Context(), archiveC, uploadC, uploadReq, out)
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ func (u *Uploader) Upload(ctx context.Context, req *osimage.UploadRequest) ([]ve
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("importing snapshot: %w", err)
|
return nil, fmt.Errorf("importing snapshot: %w", err)
|
||||||
}
|
}
|
||||||
primaryAMIID, err := u.createImageFromSnapshot(ctx, req.Version, imageName, snapshotID, req.UEFIVarStore)
|
primaryAMIID, err := u.createImageFromSnapshot(ctx, req.Version, imageName, snapshotID, req.SecureBoot, req.UEFIVarStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating image from snapshot: %w", err)
|
return nil, fmt.Errorf("creating image from snapshot: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -297,16 +297,21 @@ func (u *Uploader) ensureSnapshotDeleted(ctx context.Context, snapshotName, regi
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Uploader) createImageFromSnapshot(ctx context.Context, version versionsapi.Version, imageName, snapshotID string, uefiVarStore secureboot.UEFIVarStore) (string, error) {
|
func (u *Uploader) createImageFromSnapshot(ctx context.Context, version versionsapi.Version, imageName, snapshotID string, enableSecureBoot bool, uefiVarStore secureboot.UEFIVarStore) (string, error) {
|
||||||
u.log.Debugf("Creating image %s in %s", imageName, u.region)
|
u.log.Debugf("Creating image %s in %s", imageName, u.region)
|
||||||
ec2C, err := u.ec2(ctx, u.region)
|
ec2C, err := u.ec2(ctx, u.region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("creating ec2 client: %w", err)
|
return "", fmt.Errorf("creating ec2 client: %w", err)
|
||||||
}
|
}
|
||||||
uefiData, err := uefiVarStore.ToAWS()
|
var uefiData *string
|
||||||
|
if enableSecureBoot {
|
||||||
|
awsUEFIData, err := uefiVarStore.ToAWS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("creating uefi data: %w", err)
|
return "", fmt.Errorf("creating uefi data: %w", err)
|
||||||
}
|
}
|
||||||
|
uefiData = toPtr(awsUEFIData)
|
||||||
|
}
|
||||||
|
|
||||||
createReq, err := ec2C.RegisterImage(ctx, &ec2.RegisterImageInput{
|
createReq, err := ec2C.RegisterImage(ctx, &ec2.RegisterImageInput{
|
||||||
Name: &imageName,
|
Name: &imageName,
|
||||||
Architecture: ec2types.ArchitectureValuesX8664,
|
Architecture: ec2types.ArchitectureValuesX8664,
|
||||||
|
@ -324,7 +329,7 @@ func (u *Uploader) createImageFromSnapshot(ctx context.Context, version versions
|
||||||
EnaSupport: toPtr(true),
|
EnaSupport: toPtr(true),
|
||||||
RootDeviceName: toPtr("/dev/xvda"),
|
RootDeviceName: toPtr("/dev/xvda"),
|
||||||
TpmSupport: ec2types.TpmSupportValuesV20,
|
TpmSupport: ec2types.TpmSupportValuesV20,
|
||||||
UefiData: &uefiData,
|
UefiData: uefiData,
|
||||||
VirtualizationType: toPtr("hvm"),
|
VirtualizationType: toPtr("hvm"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -82,7 +82,7 @@ func (u *Uploader) Upload(ctx context.Context, req *osimage.UploadRequest) ([]ve
|
||||||
u.log.Errorf("post-cleaning: deleting blob: %v", err)
|
u.log.Errorf("post-cleaning: deleting blob: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
imageRef, err := u.createImage(ctx, req.Version, imageName, blobName, req.SBDatabase)
|
imageRef, err := u.createImage(ctx, req.Version, imageName, blobName, req.SecureBoot, req.SBDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating image: %w", err)
|
return nil, fmt.Errorf("creating image: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -134,10 +134,18 @@ func (u *Uploader) ensureBlobDeleted(ctx context.Context, blobName string) error
|
||||||
return u.bucket.Object(blobName).Delete(ctx)
|
return u.bucket.Object(blobName).Delete(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Uploader) createImage(ctx context.Context, version versionsapi.Version, imageName, blobName string, sbDatabase secureboot.Database) (string, error) {
|
func (u *Uploader) createImage(ctx context.Context, version versionsapi.Version, imageName, blobName string, enableSecureBoot bool, sbDatabase secureboot.Database) (string, error) {
|
||||||
u.log.Debugf("Creating image %s", imageName)
|
u.log.Debugf("Creating image %s", imageName)
|
||||||
blobURL := u.blobURL(blobName)
|
blobURL := u.blobURL(blobName)
|
||||||
family := u.imageFamily(version)
|
family := u.imageFamily(version)
|
||||||
|
var initialState *computepb.InitialStateConfig
|
||||||
|
if enableSecureBoot {
|
||||||
|
initialState = &computepb.InitialStateConfig{
|
||||||
|
Pk: pk(&sbDatabase),
|
||||||
|
Keks: keks(&sbDatabase),
|
||||||
|
Dbs: dbs(&sbDatabase),
|
||||||
|
}
|
||||||
|
}
|
||||||
req := computepb.InsertImageRequest{
|
req := computepb.InsertImageRequest{
|
||||||
ImageResource: &computepb.Image{
|
ImageResource: &computepb.Image{
|
||||||
Name: &imageName,
|
Name: &imageName,
|
||||||
|
@ -154,11 +162,7 @@ func (u *Uploader) createImage(ctx context.Context, version versionsapi.Version,
|
||||||
{Type: toPtr("VIRTIO_SCSI_MULTIQUEUE")},
|
{Type: toPtr("VIRTIO_SCSI_MULTIQUEUE")},
|
||||||
{Type: toPtr("UEFI_COMPATIBLE")},
|
{Type: toPtr("UEFI_COMPATIBLE")},
|
||||||
},
|
},
|
||||||
ShieldedInstanceInitialState: &computepb.InitialStateConfig{
|
ShieldedInstanceInitialState: initialState,
|
||||||
Pk: pk(&sbDatabase),
|
|
||||||
Keks: keks(&sbDatabase),
|
|
||||||
Dbs: dbs(&sbDatabase),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Project: u.project,
|
Project: u.project,
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ type UploadRequest struct {
|
||||||
Provider cloudprovider.Provider
|
Provider cloudprovider.Provider
|
||||||
Version versionsapi.Version
|
Version versionsapi.Version
|
||||||
AttestationVariant string
|
AttestationVariant string
|
||||||
|
SecureBoot bool
|
||||||
SBDatabase secureboot.Database
|
SBDatabase secureboot.Database
|
||||||
UEFIVarStore secureboot.UEFIVarStore
|
UEFIVarStore secureboot.UEFIVarStore
|
||||||
Size int64
|
Size int64
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue