@@ -30,13 +30,13 @@ const (
30
30
infoSuccessTitle = "Encryption key escrow"
31
31
infoSuccessText = "Key escrowed successfully."
32
32
maxKeySlots = 8
33
+ userKeySlot = 0 // Key slot 0 is assumed to be the location of the user's passphrase
33
34
)
34
35
35
36
var ErrKeySlotFull = regexp .MustCompile (`Key slot \d+ is full` )
36
37
37
38
func (lr * LuksRunner ) Run (oc * fleet.OrbitConfig ) error {
38
- ctx , cancel := context .WithCancel (context .Background ())
39
- defer cancel ()
39
+ ctx := context .Background ()
40
40
41
41
if ! oc .Notifications .RunDiskEncryptionEscrow {
42
42
return nil
@@ -65,28 +65,38 @@ func (lr *LuksRunner) Run(oc *fleet.OrbitConfig) error {
65
65
}
66
66
67
67
if err := lr .escrower .SendLinuxKeyEscrowResponse (response ); err != nil {
68
+ // If sending the response fails, remove the key slot
69
+ if keyslot != nil {
70
+ if err := removeKeySlot (ctx , devicePath , * keyslot ); err != nil {
71
+ log .Error ().Err (err ).Msg ("failed to remove key slot" )
72
+ }
73
+ }
74
+
75
+ // Show error in dialog
68
76
if err := lr .infoPrompt (ctx , infoFailedTitle , infoFailedText ); err != nil {
69
- log .Debug ().Err (err ).Msg ("failed to show failed escrow key dialog" )
77
+ log .Info ().Err (err ).Msg ("failed to show failed escrow key dialog" )
70
78
}
79
+
71
80
return fmt .Errorf ("escrower escrowKey err: %w" , err )
72
81
}
73
82
74
83
if response .Err != "" {
75
84
if err := lr .infoPrompt (ctx , infoFailedTitle , response .Err ); err != nil {
76
- log .Debug ().Err (err ).Msg ("failed to show failed escrow key dialog" )
85
+ log .Info ().Err (err ).Msg ("failed to show response error dialog" )
77
86
}
78
87
return fmt .Errorf ("error getting linux escrow key: %s" , response .Err )
79
88
}
80
89
81
90
// Show success dialog
82
91
if err := lr .infoPrompt (ctx , infoSuccessTitle , infoSuccessText ); err != nil {
83
- log .Debug ().Err (err ).Msg ("failed to show success escrow key dialog" )
92
+ log .Info ().Err (err ).Msg ("failed to show success escrow key dialog" )
84
93
}
85
94
86
95
return nil
87
96
}
88
97
89
98
func (lr * LuksRunner ) getEscrowKey (ctx context.Context , devicePath string ) ([]byte , * uint , error ) {
99
+ // AESXTSPlain64Cipher is the default cipher used by ubuntu/kubuntu/fedora
90
100
device := luksdevice .New (luksdevice .AESXTSPlain64Cipher )
91
101
92
102
// Prompt user for existing LUKS passphrase
@@ -133,16 +143,16 @@ func (lr *LuksRunner) getEscrowKey(ctx context.Context, devicePath string) ([]by
133
143
return nil , nil , fmt .Errorf ("Failed to generate random passphrase: %w" , err )
134
144
}
135
145
136
- // Create a new key slot, error if all key slots are full
137
- // keySlot 0 is assumed to be the user's passphrase
138
- // so we start at 1
139
- var keySlot uint = 1
146
+ // Create a new key slot and error if all key slots are full
147
+ // Start at slot 1 as keySlot 0 is assumed to be the location of
148
+ // the user's passphrase
149
+ var keySlot uint = userKeySlot + 1
140
150
for {
141
151
if keySlot == maxKeySlots {
142
152
return nil , nil , errors .New ("all LUKS key slots are full" )
143
153
}
144
154
145
- userKey := encryption .NewKey (0 , passphrase )
155
+ userKey := encryption .NewKey (userKeySlot , passphrase )
146
156
escrowKey := encryption .NewKey (int (keySlot ), escrowPassphrase )
147
157
148
158
if err := device .AddKey (ctx , devicePath , userKey , escrowKey ); err != nil {
@@ -286,3 +296,12 @@ func getSaltforKeySlot(ctx context.Context, devicePath string, keySlot uint) (st
286
296
287
297
return slot .KDF .Salt , nil
288
298
}
299
+
300
+ func removeKeySlot (ctx context.Context , devicePath string , keySlot uint ) error {
301
+ cmd := exec .CommandContext (ctx , "cryptsetup" , "luksKillSlot" , devicePath , fmt .Sprintf ("%d" , keySlot ))
302
+ if err := cmd .Run (); err != nil {
303
+ return fmt .Errorf ("Failed to run cryptsetup luksKillSlot: %w" , err )
304
+ }
305
+
306
+ return nil
307
+ }
0 commit comments