5353 secbootDeleteContainerKey = secboot .DeleteContainerKey
5454 secbootSaveCheckResult = (* secboot .PreinstallCheckContext ).SaveCheckResult
5555 secbootCheckResult = (* secboot .PreinstallCheckContext ).CheckResult
56+ secbootIsKeyUsedByKeyring = secboot .IsKeyUsedByKeyring
5657
5758 keysNewProtectorKey = keys .NewProtectorKey
5859 keysCreateProtectedKey = (keys .ProtectorKey ).CreateProtectedKey
@@ -87,6 +88,41 @@ func hookKeyProtectorFactoryImpl(m *DeviceManager, kernelInfo *snap.Info) (secbo
8788
8889var hookKeyProtectorFactory = hookKeyProtectorFactoryImpl
8990
91+ func removeKeyringBackupIfUnused (devicePath , keyslot string ) error {
92+ usedByKeyring , err := secbootIsKeyUsedByKeyring (devicePath , keyslot )
93+ if err != nil {
94+ return fmt .Errorf ("cannot verify if key %s:%s was used to unlock disk: %v" , devicePath , keyslot , err )
95+ } else if ! usedByKeyring {
96+ if err := secbootDeleteContainerKey (devicePath , keyslot ); err != nil {
97+ if ! errors .Is (err , secboot .ErrKeyslotNameNotExist ) {
98+ return err
99+ }
100+ }
101+ }
102+ return nil
103+ }
104+
105+ func safelyRemoveKey (devicePath , keyslot , backup string ) error {
106+ usedByKeyring , err := secbootIsKeyUsedByKeyring (devicePath , keyslot )
107+ if err != nil {
108+ return fmt .Errorf ("cannot verify if key %s:%s was used to unlock disk: %v" , devicePath , keyslot , err )
109+ } else if usedByKeyring {
110+ if err := removeKeyringBackupIfUnused (devicePath , backup ); err != nil {
111+ return err
112+ }
113+ if err := secbootRenameContainerKey (devicePath , keyslot , backup ); err != nil {
114+ return err
115+ }
116+ } else {
117+ if err := secbootDeleteContainerKey (devicePath , keyslot ); err != nil {
118+ if ! errors .Is (err , secboot .ErrKeyslotNameNotExist ) {
119+ return err
120+ }
121+ }
122+ }
123+ return nil
124+ }
125+
90126func (m * DeviceManager ) doReprovision (t * state.Task , _ * tomb.Tomb ) error {
91127 renames := []struct {
92128 // new is the name of latest keyslot if there are 2
@@ -148,6 +184,8 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
148184 return err
149185 }
150186
187+ const backupName = "snapd-active-key-backup"
188+
151189 // revertReprovisionAttempt is called either if we detect that we have already
152190 // called reprovision but did not reach step 6. Or if we
153191 // return with error before step 6.
@@ -179,6 +217,10 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
179217 hasKeySlot [k ] = true
180218 }
181219
220+ if err := removeKeyringBackupIfUnused (disk , backupName ); err != nil {
221+ logger .Debugf ("cannot remove keyring backup key for %s: %v" , disk , err )
222+ }
223+
182224 for _ , rename := range renames {
183225 if hasPlatformKeyslot [rename .old ] && hasPlatformKeyslot [rename .new ] {
184226 nv , err := secbootGetPCRHandleFromToken (disk , rename .new )
@@ -203,7 +245,7 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
203245 if rename .new == "default" && disk == saveDisk .DevPath () {
204246 continue
205247 }
206- if err := secbootDeleteContainerKey (disk , rename .new ); err != nil {
248+ if err := safelyRemoveKey (disk , rename .new , backupName ); err != nil {
207249 logger .Debugf ("cannot remove %s on %s: %v" , rename .new , disk , err )
208250 }
209251 if err := secbootRenameContainerKey (disk , rename .old , rename .new ); err != nil {
@@ -231,7 +273,7 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
231273 // be removed before we try to do step 1 (rename existing key slots). But those
232274 // "new" keys are wrong only if the "snapd-reprovision-default" of save matches
233275 // the protector key file.
234- if err := secbootDeleteContainerKey (saveDisk .DevPath (), "default" ); err != nil {
276+ if err := safelyRemoveKey (saveDisk .DevPath (), "default" , backupName ); err != nil {
235277 logger .Debugf ("could not remove default on %s: %v" , saveDisk .DevPath (), err )
236278 }
237279 if err := secbootRenameContainerKey (saveDisk .DevPath (), "snapd-reprovision-default" , "default" ); err != nil {
@@ -324,7 +366,7 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
324366 }
325367
326368 for _ , rename := range renames {
327- if err := secbootDeleteContainerKey (disk , rename .old ); err != nil {
369+ if err := safelyRemoveKey (disk , rename .old , backupName ); err != nil {
328370 // We do not expect it to exist, we should not fail on error.
329371 // For example due to previous run not cleaned up.
330372 // We know it is not a key that is still in use because we
@@ -500,6 +542,11 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
500542 removedNvIndices := map [uint32 ]bool {}
501543
502544 for _ , disk := range []string {dataDisk .DevPath (), saveDisk .DevPath ()} {
545+ // Since we committed the keyring, we should be able to clean up the keyring backup keys
546+ if err := removeKeyringBackupIfUnused (disk , backupName ); err != nil {
547+ return err
548+ }
549+
503550 recoveryKeyNames , err := secbootListContainerRecoveryKeyNames (disk )
504551 if err != nil {
505552 return err
@@ -508,7 +555,7 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
508555 if key == "default-recovery" {
509556 continue
510557 }
511- if err := secbootDeleteContainerKey (disk , key ); err != nil {
558+ if err := safelyRemoveKey (disk , key , backupName ); err != nil {
512559 return err
513560 }
514561 }
@@ -539,13 +586,13 @@ func (m *DeviceManager) doReprovision(t *state.Task, _ *tomb.Tomb) error {
539586 continue
540587 }
541588
542- if err := secbootDeleteContainerKey (disk , key ); err != nil {
589+ if err := safelyRemoveKey (disk , key , backupName ); err != nil {
543590 return err
544591 }
545592 }
546593 }
547594
548- if err := secbootDeleteContainerKey (saveDisk .DevPath (), "snapd-reprovision-default" ); err != nil {
595+ if err := safelyRemoveKey (saveDisk .DevPath (), "snapd-reprovision-default" , backupName ); err != nil {
549596 return err
550597 }
551598
0 commit comments