FreeIPA KDB driver stores and allows to retrieve a master key used by the Kerberos realm. This functionality is implemented with ipadb_fetch_master_key() and ipadb_store_master_key_list() but they assume there is only one key stored (to be stored). Additionally, KDB driver does not provide fetch_master_key_list() (none of the in-tree krb5 KDB drivers provide a sensible version either).
ipadb_fetch_master_key()
ipadb_store_master_key_list()
fetch_master_key_list()
Storing more than one master key is needed to allow migration to a different encryption type.
Metadata Update from @abbra: - Issue set to the milestone: KDB improvements (was: Future Releases)
This'd also solve #8628.
Metadata Update from @jrische: - Issue assigned to jrische
Metadata Update from @jrische: - Custom field rhbz adjusted to https://issues.redhat.com/browse/RHEL-49440 https://issues.redhat.com/browse/RHEL-31907 https://issues.redhat.com/browse/RHEL-31906
Metadata Update from @jrische: - Custom field rhbz adjusted to https://issues.redhat.com/browse/RHEL-49440 https://issues.redhat.com/browse/RHEL-31907 https://issues.redhat.com/browse/RHEL-31906 https://issues.redhat.com/browse/RHEL-49451 (was: https://issues.redhat.com/browse/RHEL-49440 https://issues.redhat.com/browse/RHEL-31907 https://issues.redhat.com/browse/RHEL-31906)
After investigating this issue, I think the default implementation of fetch_master_key_list() is enough in this case. We should not need to re-implement it.
The root problem here seems to be about KVNO management in the IPA database. After running the kdb5_util add_mkey -e aes256-sha2 command, the new key is added as new krbMKey attribute (next to the previous one) in cn=$REALM,cn=kerberos,$SUFFIX, but something weird happens with the K/M principal: it is updated to contain both the old and the new key (both encoded with the new master key), but the KVNO of the old master key is replace with the KVNO of the new one. So both the old and new key have the same KVNO in the K/M principal entry.
kdb5_util add_mkey -e aes256-sha2
krbMKey
cn=$REALM,cn=kerberos,$SUFFIX
K/M
This completely breaks the migration process, because the KDC is not able to differentiate the old and new master keys. Hence all the other KDB entries cannot be re-encrypted with the new key, because their attribute with the KVNO of the master key that was used to encrypt them does not refer to any master key any more.
This bug seems to be caused by a design limitation, because since the beginning, the binary encoding of Kerberos keys for the LDAP database has only one KVNO attribute for all the keys. And in the current implementation the KVNO of the first key in the list is used for all of them when the encoding happen.
Novell key-format scheme: KrbKeySet ::= SEQUENCE { attribute-major-vno [0] UInt16, attribute-minor-vno [1] UInt16, kvno [2] UInt32, mkvno [3] UInt32 OPTIONAL, keys [4] SEQUENCE OF KrbKey, ... } KrbKey ::= SEQUENCE { salt [0] KrbSalt OPTIONAL, key [1] EncryptionKey, s2kparams [2] OCTET STRING OPTIONAL, ... } KrbSalt ::= SEQUENCE { type [0] Int32, salt [1] OCTET STRING OPTIONAL } EncryptionKey ::= SEQUENCE { keytype [0] Int32, keyvalue [1] OCTET STRING }
I see to option to fix this problem:
krbPrincipalKey
krbprincipal
@simo is there any history we should be aware of regarding the KVNO limitation? Do you see any other option to deal with this problem?
Side note: I think ipadb_store_master_key_list() should be modified to remove the old krbMKey attribute, because AFAIU this copy of the master key should only be used to decrypt keys of K/M. So once the K/M entry is re-encrypted with the new key, there is no point keeping the old one in the stash.
Hi Julien, the problem is the misuse of the storage, the kvno is the same because this attribute is supposed to store the "same" key generation just for different enctypes. It is not supposed to store different key generations. To support different key generations you are supposed to store different objects. So the problem here is not in the schema but in how the old K/M keys are stored apparently. There should be a separate attribute/object that stores the old key generation.
I added support for multiple krbPrincipalKey attributes in krbprincipal objects (this change seems to be fixing #8628 too): https://github.com/jrisc/freeipa/commit/f89b2117a1e9a32403b46520c3fb9de535067b22
This allowed to add new K/M keys using kdb5_util add_mkey. However, it was impossible to activate the new key using kdb5_util use_mkey. This is actually an upstream krb5 bug, because kdb5_util does not set the KDB entry modification mask when changing the tl-data: https://github.com/krb5/krb5/pull/1364
kdb5_util add_mkey
kdb5_util use_mkey
kdb5_util
These two changes allow to complete the master key upgrade as described in the upstream krb5 documentation.
Metadata Update from @jrische: - Custom field on_review adjusted to https://github.com/freeipa/freeipa/pull/7712
Metadata Update from @jrische: - Custom field blocking adjusted to 8628 - Issue marked as blocking: #8628
Metadata Update from @jrische: - Custom field blocking reset (from 8628)
Log in to comment on this ticket.