logo_kerberos.gif

Projects/Master Key Migration

From K5Wiki
< Projects
Revision as of 19:16, 2 September 2008 by Wfiveash (talk | contribs)

Jump to: navigation, search

An announcement has been sent to krbdev@mit.edu starting a review of this project. That review will conclude on 2008-09-16.

Comments can be sent to krbdev@mit.edu.


Desired changes

This project will provide the ability to add a new master key (with an enctype differing from the current master key) to the master key principal and stash file and then migrate the encryption of existing principals long term keys to use the new master key. In addition deletion of master keys will be provided.

Functional Requirements

The KDC must be able to deal with multiple master keys and determine which key to use when decrypting a principal's long term secret key. The KDC must be able to access any of the master key (K/M) principal's keys as long as it has access to a master key that is in use.

The administrator must be able re-encrypt principal keys using a specified mkey and be able to specifying the set of principals is to be re-encrypted. The command doing this must be able to determine if a principal's keys are protected by the current master key or not. This implies that some set of principals may be protected with a non-current master key.

Slave KDC's must be able to access all master keys currently protecting principal entries and therefore have access to the principal's secret keys regardless of which master key is used to encrypt the key.

The administrator will be able to:

  • Add a new master key to master key principal and optionally to the masterkey keytab stash.
  • Enable a new master key (make it the current master key used to protect newly created principals or principal rekeys).
  • List all master keys associated with the master key principal.
  • Delete a particular master key from the master key principal and optionally from the masterkey keytab stash.
  • Purge unused master keys (keys not used to protect any principal).

Design of implementation

Fundamentally the current implementation must be changed to support multiple master keys. And possession of any master key stored with the K/M principal allows access to all master keys. In addition, a principal's secret key may be encrypted by any of the master keys in use and the KDC must be able to decrypt that principal's key.

In order to accommodate this, these changes will be made:

  • A new TL-data type, KRB5_TL_MKVNO, would apply to all principals except the K/M, and would store the version number of the master key used to encrypt the keys of that principal. The db2 back end would store it as opaque TL-data, the LDAP back end has a slot for it.
  • The krb5_key_data array in the krb5_db_entry for the K/M principal will hold all master keys in use. All the keys in this array will be encrypted using the most recently created master key.
  • A new TL-data type, KRB5_TL_MKEY_AUX, would apply only to the K/M principal. This new TL data would contain:
    • The current master key version number that should be used when changing database entries. This may not be the latest key and is set by the administrator. If this TL-data type is not found in the K/M record then the default value for this will be 1 which is the default MKVNO.
    • A set of copies of the latest master key, each encrypted by one of the other supported mkeys, in {old-mkvno, keydata} tuples. Thus the "master key" used in DAL (DB abstraction layer) need only be any one of these keys.
    • Trailing stuff is ignored for now, making the structure extensible.
  • kdc_realm_t will be modified to hold all master keys (including KVNO and enctype) associated with a realm. It will also hold the current mkey KVNO that should be used when encrypting a principal's keys. To facilitate this, a new struct will be defined:
 typedef struct _krb5_keylist_node {
       krb5_keyblock *keyblock;
       krb5_kvno      kvno;
       struct _krb5_keylist_node *next;
 } krb5_keyblock_node;

This will be used to create a list of mkeys. kdc_realm_t will also have a current_realm_mkey which will point to the krb5_keyblock_node that contains the current mkey (used when encrypting a principal's keys, does not apply the K/M mkeys).

The initialization of the list of mkeys will occur in init_realm().

Any code needing to decrypt principal keys will need to determine which mkey to use. A function will be created to return the mkey to use for decrypting a principal's keys given the principal's krb5_db_entry and realm_mkeys list as input args. If the principals krb5_db_entry does not contain KRB5_TL_MKVNO TL-data the function will default to choosing the mkey with KVNO 1. If the princ krb5_db_entry does have KRB5_TL_MKVNO data and no matching mkey is found the function will get the K/M princ KDB entry, update the list of mkeys if new mkeys are found and return a matching mkey if found. An error will be returned if a matching mkey is not found.

This function would be called prior to calling krb5_dbekd_decrypt_key_data() to determine which mkey to pass in.

Similarly, any code calling krb5_dbekd_encrypt_key_data() will be modified to pass in the current_realm_mkey (mentioned above).

kdb5_util will be modified to support these new commands:

add_mkey [-s] 
Add a new mkey to K/M. The optional -s will add the mkey to the stash file.
use_mkey <KVNO> 
Set the current mkey KVNO. This controls which mkey is used when encrypting principal keys. The kadmind should be stopped/disabled prior to running this command and enabled after successful completion.
list_mkeys 
Shows all masterkeys from most recent to earliest in K/M principal. The output will show the KVNO, enctype and salt for each mkey similar to kadmin getprinc output. A * following an mkey denotes the current mkey.
purge_mkeys [-f] 
Delete mkeys from K/M princ that are not used to protect any principals. With -f, does not prompt user.
sync_stash [-f] 
Sync up the set of keys in the keytab stash with those in the K/M princ entry in the KDB. Keys in keytab stash not found in K/M will be removed. With -f, does not prompt user.
update_princ_encryption [-f] [expression] 
Use current mkey to encrypt principals (other than K/M) secret keys if not already encrypted by that mkey. Should support either doing all princs if no argument given or a subset specified by expression (supports shell-style globbing, similar to kadmin). Both the principal's secret keys and key history will first be decrypted with the original encrypting mkey then encrypted with the current mkey. If the current mkey kvno is that of the mkey that originaly encrypted the principal's keys the code will stop processing that principal and go on to the next. With -f, does not prompt user.

The kdb5_util dump -mkey_convert will be modified to update the KRB5_TL_MKVNO of all principals except the K/M principal with the KVNO of the mkey used for the conversion. The K/M KRB5_TL_MKEY_AUX TL data will be updated to include the new mkey used for the conversion.

Tasks/milestones

  • project start. Aug 29, 2008
  • project review. ~2 week
  • Implementation. ~8 week
  • test. ~4 week
  • code review. ~2 week
  • documentation. ~3 day

Desired integration and release goals

Testing plan

Unit testing of all new and modified commands will be done to verify they work as specified. This will be done for both the db2 and LDAP KDB plugins.

The kadmind and krb5kdc daemons will be tested to verify they work properly when accessing a KDB some set of principals is protected by one mkey and the other set is protected by another set. Slave KDCs will also be tested after the KDB is propagated both with kprop and kiprop.

Bounds testing will verify the krb utils and daemons work properly when the MKVNO wraps back to 0.

The existing MIT Kerberos test suites will be run to make sure there are no regressions introduced by this project.


Review

This section documents the review of the project according to Project policy. It is divided into multiple sections. First, approvals should be listed. To list an approval type

#~~~~

on its own line. The next section is for discussion. Use standard talk page conventions. In particular, sign comments with

--~~~~

and indent replies.

Members of Krbcore raising Blocking objections should preface their comment with {{project-block}}. The member who raised the objection should remove this markup when their objection is handled.

Approvals

Discussion