Fix kpasswd UDP ping-pong [CVE-2002-2443]

The kpasswd service provided by kadmind was vulnerable to a UDP
"ping-pong" attack [CVE-2002-2443].  Don't respond to packets unless
they pass some basic validation, and don't respond to our own error
packets.

Some authors use CVE-1999-0103 to refer to the kpasswd UDP ping-pong
attack or UDP ping-pong attacks in general, but there is discussion
leading toward narrowing the definition of CVE-1999-0103 to the echo,
chargen, or other similar built-in inetd services.

Thanks to Vincent Danen for alerting us to this issue.

CVSSv2: AV:N/AC:L/Au:N/C:N/I:N/A:P/E:P/RL:O/RC:C

ticket: 7637 (new)
target_version: 1.11.3
tags: pullup
Split pkinit_identity_initialize into two phases

Split part of pkinit_identity_initialize() into a second piece named
pkinit_identity_prompt().  Have each piece pass a new boolean flag to
crypto_load_certs() to indicate if it should defer prompting for a
password/PIN for client identities that require one.  If the flag isn't
set, it should attempt to use a responder-supplied value, or call the
prompter if there isn't one.
Add support for tracking deferred identity prompts

Track a list of deferred identities, for which we want to prompt for
passwords or PINs, in pkinit_identity_crypto_context structures, along
with associated warnings.  These are opaque outside of
pkinit_crypto_openssl and pkinit_crypto_nss, so both need to provide
functions that can be called from elsewhere to populate and query the
lists.
Add support for deferred identity prompting

The password callback which we usually supply to NSS already gets a
pointer to the pkinit_identity_crypto_context structure, but it needs to
be passed the name of the identity for which it's being called.

If it gets a name, and it's deferring prompting, just add the identity
to the list of deferred identity prompts (the password callback wouldn't
have been called if its result wasn't needed).  Otherwise, check for a
password that's been stashed for its use for that identity, and return a
copy of it if one's found.  If none of that works, try to use the
prompter callback to ask for the password.

In various places where we attempt to load identity information, ignore
failures so that we keep going, if we're deferring prompts.
Add support for deferred identity prompting

Add a password to the set of things that we can pass to a PEM password
callback and the function we use for loading PKCS12 bundles.  If we're
meant to defer identity prompts, just store the name of the identity
which we're loading.  Otherwise, if we're passed a password, use it.
Otherwise, use the prompter callback.

Add a password to the set of things that we can pass to the function
that we use for logging in to PKCS11 tokens, too, but if we're deferring
identity prompts, just return the identity name without doing anything
else.  If not, and we're passed a password, use that.  Otherwise, try to
use the prompter callback to get one.
Pass deferred identity prompts to the responder

Use the list of deferred identity prompts and warnings, which we have
after calling pkinit_identity_initialize(), to build a list of questions
for responder callbacks to answer, and before calling
pkinit_identity_prompt() to actually load identities that are protected,
save any passwords and PINs which a responder callback may have
supplied, in case there's no prompter callback.
Pass token warnings flags to the prompter callback

Interpret the token flags and pass a warning about the state of the
token's PIN to the prompter function as part of prompting for the PIN.
Add non-JSON APIs for PKINIT responder items

Add wrappers for the JSON-oriented APIs for PKINIT responder items,
modeled after the API we provide for OTP items:

* krb5_responder_pkinit_get_challenge() returns the list of
  identities for which we need PINs
* krb5_responder_pkinit_challenge_free() frees the structure that
  was returned by krb5_responder_pkinit_get_challenge()
* krb5_responder_pkinit_set_answer() sets the answer to the PIN for
  one of the identities

We might want to change krb5_responder_pkinit_set_answer() to provide a
way of providing multiple PINs before committing to it.
Add a helper for checking responder challenges

This test helper takes multiple options and one argument.

./misc/test_responder [options] principal
 -X preauth_option -> preauth options, as for kinit
 -x challenge      -> expected responder challenge, of the form
                      "question=challenge"
 -r response       -> provide a reponder answer, in the form "question=answer"
 -c                -> print the pkinit challenge
 -p identity=pin   -> provide a pkinit answer, in the form "identity=pin"
 principal         -> client principal name

If the responder callback isn't called, that's treated as an error.

If an expected responder challenge is specified, when the responder
callback is called, the challenge associated with the specified question
is compared against the specified value.  If the value provided to the
callback doesn't parse as JSON, a literal string compare is performed,
otherwise both values are parsed as JSON and then re-encoded before
comparison.  In either case, the comparison must succeed.

Any missing data or mismatches are treated as errors.
Add tests for PKINIT using responder functionality
report initialize errors