Skip to content

Commit

Permalink
overlord/install/install.go: use plainkey for save key
Browse files Browse the repository at this point in the history
  • Loading branch information
valentindavid committed Dec 12, 2024
1 parent 15bf1d4 commit 28a38ec
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 15 deletions.
8 changes: 8 additions & 0 deletions overlord/install/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,11 @@ func MockSysconfigConfigureTargetSystem(f func(mod *asserts.Model, opts *sysconf
sysconfigConfigureTargetSystem = old
}
}

func MockBootUseTokens(f func(model *asserts.Model) bool) (restore func()) {
old := bootUseTokens
bootUseTokens = f
return func() {
bootUseTokens = old
}
}
71 changes: 58 additions & 13 deletions overlord/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ var (

secbootCheckTPMKeySealingSupported = secboot.CheckTPMKeySealingSupported
sysconfigConfigureTargetSystem = sysconfig.ConfigureTargetSystem

bootUseTokens = boot.UseTokens
)

// MockSecbootCheckTPMKeySealingSupported mocks secboot.CheckTPMKeySealingSupported usage by the package for testing.
Expand Down Expand Up @@ -253,26 +255,59 @@ func PrepareEncryptedSystemData(model *asserts.Model, installKeyForRole map[stri
dataBootstrappedContainer := installKeyForRole[gadget.SystemData]
saveBootstrappedContainer := installKeyForRole[gadget.SystemSave]

// make note of the encryption keys
trustedInstallObserver.SetBootstrappedContainersAndPrimaryKey(dataBootstrappedContainer, saveBootstrappedContainer, nil)
var primaryKey []byte

if saveBootstrappedContainer != nil {
// TODO: use plainkey from secboot
saveKey, err := keys.NewEncryptionKey()
if err != nil {
return err
}
if err := saveBootstrappedContainer.AddKey("default", saveKey); err != nil {
return err
}
if err := saveKeys(model, saveKey); err != nil {
return err
if bootUseTokens(model) {
protectorKey, err := keys.NewProtectorKey()
if err != nil {
return err
}

plainKey, generatedPK, diskKey, err := protectorKey.CreateProtectedKey(nil)
if err != nil {
return err
}

if err := saveBootstrappedContainer.AddKey("default", diskKey); err != nil {
return err
}
tokenWriter, err := saveBootstrappedContainer.GetTokenWriter("default")
if err != nil {
return err
}
if err := plainKey.Write(tokenWriter); err != nil {
return err
}

if err := saveKeys(model, protectorKey); err != nil {
return err
}

primaryKey = generatedPK
} else {
saveKey, err := keys.NewEncryptionKey()
if err != nil {
return err
}

if err := saveBootstrappedContainer.AddKey("default", saveKey); err != nil {
return err
}

if err := saveLegacyKeys(model, saveKey); err != nil {
return err
}
}
}
// write markers containing a secret to pair data and save
if err := writeMarkers(model); err != nil {
return err
}

// make note of the encryption keys
trustedInstallObserver.SetBootstrappedContainersAndPrimaryKey(dataBootstrappedContainer, saveBootstrappedContainer, primaryKey)

return nil
}

Expand All @@ -295,7 +330,17 @@ func writeMarkers(model *asserts.Model) error {
return device.WriteEncryptionMarkers(boot.InstallHostFDEDataDir(model), boot.InstallHostFDESaveDir, markerSecret)
}

func saveKeys(model *asserts.Model, saveKey keys.EncryptionKey) error {
func saveKeys(model *asserts.Model, saveKey keys.ProtectorKey) error {
saveKeyPath := device.SaveKeyUnder(boot.InstallHostFDEDataDir(model))

if err := os.MkdirAll(filepath.Dir(saveKeyPath), 0755); err != nil {
return err
}

return saveKey.SaveToFile(saveKeyPath)
}

func saveLegacyKeys(model *asserts.Model, saveKey keys.EncryptionKey) error {
saveKeyPath := device.SaveKeyUnder(boot.InstallHostFDEDataDir(model))

if err := os.MkdirAll(filepath.Dir(saveKeyPath), 0755); err != nil {
Expand Down
65 changes: 63 additions & 2 deletions overlord/install/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -884,13 +884,20 @@ func (s *installSuite) TestPrepareEncryptedSystemData(c *C) {
c.Assert(err, IsNil)
c.Assert(to, NotNil)

restore := install.MockBootUseTokens(func(model *asserts.Model) bool {
return true
})
defer restore()

// We are required to call ObserveExistingTrustedRecoveryAssets on trusted observers
err = to.ObserveExistingTrustedRecoveryAssets(boot.InitramfsUbuntuSeedDir)
c.Assert(err, IsNil)

saveDisk := secboot.CreateMockBootstrappedContainer()

installKeyForRole := map[string]secboot.BootstrappedContainer{
gadget.SystemData: secboot.CreateMockBootstrappedContainer(),
gadget.SystemSave: secboot.CreateMockBootstrappedContainer(),
gadget.SystemSave: saveDisk,
}
err = install.PrepareEncryptedSystemData(mockModel, installKeyForRole, to)
c.Assert(err, IsNil)
Expand All @@ -900,10 +907,64 @@ func (s *installSuite) TestPrepareEncryptedSystemData(c *C) {
c.Check(marker, HasLen, 32)
c.Check(filepath.Join(boot.InstallHostFDESaveDir, "marker"), testutil.FileEquals, marker)

// the assets cache was written to
// Check that the assets cache was written to
l, err := os.ReadDir(filepath.Join(dirs.SnapBootAssetsDir, "trusted"))
c.Assert(err, IsNil)
c.Assert(l, HasLen, 1)

_, err = os.ReadFile(filepath.Join(dirs.GlobalRootDir, "/run/mnt/ubuntu-data/system-data/var/lib/snapd/device/fde", "ubuntu-save.key"))
c.Assert(err, IsNil)

_, hasToken := saveDisk.Tokens["default"]
c.Assert(hasToken, Equals, true)
}

func (s *installSuite) TestPrepareEncryptedSystemDataLegacyKeys(c *C) {
_, gadgetDir := s.mountedGadget(c)
mockModel := s.mockModel(nil)

trustedAssets := true
s.mockBootloader(c, trustedAssets, false)

useEncryption := true
_, to, err := install.BuildInstallObserver(mockModel, gadgetDir, useEncryption)
c.Assert(err, IsNil)
c.Assert(to, NotNil)

restore := install.MockBootUseTokens(func(model *asserts.Model) bool {
return false
})
defer restore()

// We are required to call ObserveExistingTrustedRecoveryAssets on trusted observers
err = to.ObserveExistingTrustedRecoveryAssets(boot.InitramfsUbuntuSeedDir)
c.Assert(err, IsNil)

saveDisk := secboot.CreateMockBootstrappedContainer()

installKeyForRole := map[string]secboot.BootstrappedContainer{
gadget.SystemData: secboot.CreateMockBootstrappedContainer(),
gadget.SystemSave: saveDisk,
}
err = install.PrepareEncryptedSystemData(mockModel, installKeyForRole, to)
c.Assert(err, IsNil)

marker, err := os.ReadFile(filepath.Join(filepath.Join(dirs.GlobalRootDir, "/run/mnt/ubuntu-data/system-data/var/lib/snapd/device/fde"), "marker"))
c.Assert(err, IsNil)
c.Check(marker, HasLen, 32)
c.Check(filepath.Join(boot.InstallHostFDESaveDir, "marker"), testutil.FileEquals, marker)

// Check that the assets cache was written to
l, err := os.ReadDir(filepath.Join(dirs.SnapBootAssetsDir, "trusted"))
c.Assert(err, IsNil)
c.Assert(l, HasLen, 1)

saveKey, err := os.ReadFile(filepath.Join(dirs.GlobalRootDir, "/run/mnt/ubuntu-data/system-data/var/lib/snapd/device/fde", "ubuntu-save.key"))
c.Assert(err, IsNil)

slotKey, hasSlot := saveDisk.Slots["default"]
c.Assert(hasSlot, Equals, true)
c.Check(slotKey, DeepEquals, saveKey)
}

func (s *installSuite) TestPrepareRunSystemDataWritesModel(c *C) {
Expand Down

0 comments on commit 28a38ec

Please sign in to comment.