From: | ghudson@mit.edu |
Subject: | PKINIT calls responder twice |
Date: | Mon, 09 Mar 2020 15:33:03 -0400 |
To: | rt@krbdev.mit.edu |
During a PKINIT AS-REQ, there are two rounds of client padata processing, one to generate the request and one to validate the KDC response and compute the reply key.
During the first round, pkinit_client_prep_questions() calls pkinit_identity_initialize(), which calls crypto_load_certs() with defer_id_prompts=TRUE. This accumulates a list of identities in id_cryptoctx->deferred_ids. pkinit_client_prep_questions () then generates a PKINIT question containing the list of identities to be prompted for.
During the second round, pkinit_client_prep_questions() is again called. The pkinit_identity_initialize() call is skipped (because reqctx->identity_initialized is true), but the list of deferred identities is still present, so a question is again generated. PKINIT does not need access to client certificates while processing the KDC response, so the question is pointless and creates a bad user experience.
The simplest way to to suppress the second question is probably to check that the padata type is KRB5_PADATA_PK_AS_REQ.
The double-responder behavior is already visible in t_pkinit.py tests, such as the "FILE identity, password on key (responder)". We simply need to count the number of "OK:" messages in the output to see how many responder calls are made.
Reported by Russ Allbery.
During the first round, pkinit_client_prep_questions() calls pkinit_identity_initialize(), which calls crypto_load_certs() with defer_id_prompts=TRUE. This accumulates a list of identities in id_cryptoctx->deferred_ids. pkinit_client_prep_questions () then generates a PKINIT question containing the list of identities to be prompted for.
During the second round, pkinit_client_prep_questions() is again called. The pkinit_identity_initialize() call is skipped (because reqctx->identity_initialized is true), but the list of deferred identities is still present, so a question is again generated. PKINIT does not need access to client certificates while processing the KDC response, so the question is pointless and creates a bad user experience.
The simplest way to to suppress the second question is probably to check that the padata type is KRB5_PADATA_PK_AS_REQ.
The double-responder behavior is already visible in t_pkinit.py tests, such as the "FILE identity, password on key (responder)". We simply need to count the number of "OK:" messages in the output to see how many responder calls are made.
Reported by Russ Allbery.