Projects/Principals without keys
This project adds the ability to have principal entries with no long-term keys.
Traditionally, it was useless for a principal entry to have no long-term keys because you wouldn't be able to authenticate to it, either as a server (in an AS or TGS request) or as a client (in an AS request). Because of this, the KDC and its administrative tools assumed that all principals will have at least one long-term key at all times.
With the addition of PKINIT and later FAST OTP, it became possible to authenticate to a principal as a client without the use of any long-term Kerberos keys. If a principal is only intended to be authenticated to using PKINIT or FAST OTP, then its long-term keys are vestigial, and is usually assigned a random key. Being able to have no keys at all is advantageous because:
- If the principal entry has no keys, the KDC knows that encrypted timestamp and encrypted challenge won't work, so it doesn't have to offer those mechanisms in the hint list.
- It may give the KDC administrator a little peace of mind not to have to worry about someone finding out the client's randomly chosen key and authenticating to it without using the intended preauth mechanism. (Of course the risk here is minimal; someone who can find out the client's randomly chosen key is probably in an equally good position to find out the krbtgt key.)
- It saves a little space in the KDC database.
The following changes are in scope for this project:
- Make the KDC behave appropriately if the KDB returns no keys for a principal.
- Add a kadmin interface for deleting all keys from a principal. It is desirable, but not critical, that this operation allow self-service (a principal can delete all of its own keys).
- Add a kadmin interface for creating a principal with no keys.
This work has already been done in [krbdev.mit.edu #7630]. The changes are:
- Don't offer encrypted timestamp or encrypted challenge if the principal entry has no keys matching the request enctype.
- Don't send an empty etype-info or etype-info2 padata if we have no key enctypes to offer.
- If we cannot choose a default reply key for the client principal during an AS request, give preauth mechanisms a chance to replace the reply key before erroring out.
RPC for deleting keys
There are four existing RPCs which we could conceivably use to delete keys from a principal:
- purgekeys (added in 1.9) will delete all of a principal's keys if given a keepkvno value greater than the maximum current kvno. The purgekeys RPC does not allow for self-service, but there is no reason it should not.
- setkey with an empty keyblocks already clears out the principal's keys. However, there is no command-line interface for setkey, and it does not allow for self-service.
- mprinc with KADM5_KEY_DATA in the mask and n_key_data = 0 could clear out the principal's keys. mprinc is not currently used for key data operations and does not allow self-service.
- chrand3 with an empty keysalt list could clear out the principal's keys. This would be a behavior change; currently, an empty keysalt list means to use the default keysalts. However, we believe that all existing clients use the chrand RPC for this behavior, rather than using the chrand3 RPC with an empty keysalt list. Making this change would mean that chrand3 is no longer a functional superset of chrand.
The ACL checks for mprinc or setkey could be extended to allow self-service for the specific case of deleting all keys, but making ACL checks more complicated could increase the risk of security vulnerabilities.
Of these options, purgekeys seems appears to be most conservative and fitting choice.
RPC for creating a principal without keys
The cprinc RPC does not currently support creating a principal without keys. We could extend it in several ways:
- The client could create the principal with random keys and then delete the keys. This is not a good option because it involves an unwanted intermediate state, and would leave the principal with the random key in place if the kadmin server is too old to support purgekeys
- cprinc3 with an empty keysalt list could create a principal with no keys. This would be the obvious choice if we were to use chrand3 with an empty keysalt list to delete keys.
- Setting KADM5_KEY_DATA in the mask and n_key_data = 0 could create a principal with no keys. This would be the obvious choice if we were to use the analagous form of mprinc to delete keys.
Since we are using purgekeys to delete keys, there is no obvious choice, but the KADM5_KEY_DATA option is more conservative than the empty keysalt list.
purgekeys will be extended with a new option "-all" to delete all keys. It will work against a 1.9 or newer kadmind.
add_principal will be extended with a no option "-nokey" to create the principal with no keys. It will work against a 1.12 or newer kadmind.
t_dump.py will be amended to test dumping and loading a principal with no keys.
A new script t_keydata.py will test:
- Creating a principal with no keys
- Purging all keys from a principal
- kadmin cpw on a principal with no keys
- kadmin cpw -randkey on a principal with no keys
- Encrypted timestamp isn't offered on a principal with no keys (maybe a bit tricky given [krbdev.mit.edu #7672]; also probably requires a C harness to look at the KDC reply)
- Encrypted challenge isn't offered on a principal with no keys
kadmin_local.rst will be modified to document purgekeys -all and addprinc -nokey.
- Add support for having no long-term keys for a principal. This can be useful if the principal is only intended to be used with PKINIT or OTP preauthentication.