Encrypted volume passphrase change or recovery GUI

Goals
Goal is to provide a simple GUI tool that allows an user to change volume encryption passphrases, and to recover from a lost passphrase using a backup passphrase (created using  or the   kickstard directive).

High-level discussion
Changing the user's own passphrase is simple - add the new passphrase into an empty slot, and delete the old passphrase. (Changing the passphrase by overwriting the original slot is possible, but dangerous - if the operation were interrupted, neither the old nor the new passphrase would work. Changing the passphrase in place would be the only option if all slots were full, this is considered unlikely.)

To use a backup passphrase, we must first be able to identify that the provided passphrase is the backup passphrase. This can be done by reserving a specific slot for the backup passphrase, but this has the same disadvantage as changing the user's passphrase in place - the backup passphrase might become corrupted while changing it. Another option is to take advantage of the unencrypted metadata in the default volume_key format when using certificates, which includes slot number of the created backup passphrase. Thus, after creating the backup passphrase, the backup passphrase slot number would be stored locally, and we detect the backup passphrase by checking the slot number.

Using a backup passphrase would delete all other passphrases (to make sure we never run out of key slots), and set up a new user passphrase. Because the backup passphrase was probably communicated by telephone, and written down, it should be discarded and replaced by a new passphrase. There are three possible times for generating a new backup passphrase.


 * 1) As soon as the backup passphrase is used, delete it and generate a new backup passphrase.  Queue the newly created backup passphrase escrow packet for sending to the central escrow server.  This has the disadvantage that if the user forgets their password again before connecting to the escrow server, the IT department can not provide a backup passphrase to the user.
 * 2) When the backup passphrase is used, keep it, but create a new backup passphrase in another slot.  Queue the newly created backup passphrase escrow packet for sending to the central escrow server.  When the central escrow server receives the packet, it queues a task of removing the old backup passphrase on the machine.  This fixes the disadvantage of the previous approach, but requires larger implementation effort to automate the old backup passphrase removal.
 * 3) When the backup passphrase is used, keep it and do not create a new backup passphrase.  Only when the IT department can remotely manage the machine, create a new backup passphrase, escrow it, and delete the old backup passphrase.  (This process can be either automated or completely manual.)  This has the disadvantage that either the escrow recovery mechanism needs to be used twice by the IT department, (when providing the backup passphrase to the user, and when creating the new backup passphrase), or the IT department needs to store the unencrypted backup passphrase as part of the queued request to replace the backup passphrase.  (This was the originally approach considered during volume_key design, with slots implicitly identified using the backup passphrase.)

The second option has the least disadvantages, and can be automated reasonably easily.

Additional concern is identifying which encrypted volume to act upon. In the simplest case, there is only one encrypted volume in the machine (the main hard drive). In other cases, the user needs to be able to select a volume. In theory we could follow the device-mapper/RAID/partition mappings to e.g. find the encrypted volume used for the "/" partition, in practice letting the user choose from all known encrypted volumes (e.g. as listed in  would probably be good enough.

Implementation notes
This section lists in details the necessary steps for the underlying implementation mechanism (ignoring the GUI), and the relevant implementation interfaces (using the  Python module; in addition,   provides a C API, which is more complete and easier to use than the Python API )

Necessary Python routines are pasted at Encrypted volume passphrase change infrastructure.

In permanent, root-only storage (e.g. somewhere in ), store for each encrypted volume (identified by LUKS UUID), the following:
 * number of the slot containing the currently escrowed backup passphrase, if any (" ")
 * number of the slot containing a new backup passphrase, pending escrow, if any (" ")

Post-installation operations
For each backup passphrase escrow packet created by anaconda and stored in :

 Read the escrow packet metadata, extract the volume UUID and passphrase slot. Python implementation is not yet ready, will be provided later.

Store the passphrase slot as  in permanent storage. 

Operations when the user requests a passphrase change
 List all known encrypted volumes. If there is more than one encrypted volume, let the user select one. Read  and the output of.

Given a volume, extract its UUID, and read  and   from permanent storage. Use.

Prompt the user for a passphrase; verify it and get the slot number for this passphrase (" "). If the passphrase is invalid, ask again or exit. See  in the attached code.

 If the, abort - the user should not have known the pending backup passphrase, and should not have been able to guess it.

 If, the user is changing their own passphrase:  Ask for a new passphrase, add it to a free slot. Use.

Delete the old passphrase. Use. 

 Otherwise, the user is using the backup passphrase:  <li> Clear all slots except for. Use  or the C API.

<li>Unset  and delete the queued escrow packet for this volume, if any.

<li>Ask for a new passphrase, add it to a free slot. Use.

<li>Generate a new backup passphrase, add it, and create the corresponding escrow packet. See  in the attached code.

<li>Read metadata of the newly created escrow packet, set  accordingly. Python implementation is not yet ready, will be provided later.

<li>Queue the newly created packet for sending to the escrow server. </ul> </ul>

After the queued escrow packet is stored on the escrow server
(Is this initiated by the client or by the server?)

 <li>Verify that the client does not have an escrow packet queued that is newer than the packet stored on the server. <li>Delete the queued escrow packet (if this was not already done when storing it on the server). <li>Read the value of <current_backup_slot> (" ") <li>Set  to. <li>Unset. <li>Clear Use  or the C API. </ul>

Implementation questions

 * Implementation language: Python, C?
 * Privilege escalation mechanism: D-Bus/policykit, userhelper?

Long-term infrastructure improvements
These are not strictly necessary for the first version, but they would allow a more efficient implementation (starting fewer subprocesses) and probably better error handling.


 * Replace the Python escrow packet metadata parser by a new API in
 * Update python-cryptsetup to expose all of the new libcryptsetup APIs, and not start separate  child processes.