PKINIT null pointer deref [CVE-2013-1415]

Don't dereference a null pointer when cleaning up.

The KDC plugin for PKINIT can dereference a null pointer when a
malformed packet causes processing to terminate early, leading to
a crash of the KDC process.  An attacker would need to have a valid
PKINIT certificate or have observed a successful PKINIT authentication,
or an unauthenticated attacker could execute the attack if anonymous
PKINIT is enabled.

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

This is a minimal commit for pullup; style fixes in a followup.
[kaduk@mit.edu: reformat and edit commit message]

(cherry picked from commit c773d3c775e9b2d88bcdff5f8a8ba88d7ec4e8ed)

ticket: 7570
version_fixed: 1.11.1
status: resolved
decode_data(unsigned char **out_data, unsigned int *out_data_len,
            unsigned char *data, unsigned int data_len,
            EVP_PKEY *pkey, X509 *cert)
{
    krb5_error_code retval = ENOMEM;
    unsigned char *buf = NULL;
    int buf_len = 0;

    if (cert && !X509_check_private_key(cert, pkey)) {
        pkiDebug("private key does not match certificate\n");
        goto cleanup;
    }

    buf_len = EVP_PKEY_size(pkey);
    buf = malloc((size_t) buf_len + 10);
    if (buf == NULL)
        goto cleanup;

#if OPENSSL_VERSION_NUMBER >= 0x00909000L
    retval = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
#else
    retval = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
#endif
    if (retval <= 0) {
        pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
        goto cleanup;
    }
    *out_data = buf;
    *out_data_len = retval;

cleanup:
    if (retval == ENOMEM)
        free(buf);

    return retval;
}

decode_data(unsigned char **out_data, unsigned int *out_data_len,
            unsigned char *data, unsigned int data_len,
            EVP_PKEY *pkey, X509 *cert)
{
    krb5_error_code retval = ENOMEM;
    unsigned char *buf = NULL;
    int buf_len = 0;

    if (cert && !X509_check_private_key(cert, pkey)) {
        pkiDebug("private key does not match certificate\n");
        goto cleanup;
    }

    buf_len = EVP_PKEY_size(pkey);
    buf = malloc((size_t) buf_len + 10);
    if (buf == NULL)
        goto cleanup;

#if OPENSSL_VERSION_NUMBER >= 0x00909000L
    retval = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
#else
    retval = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
#endif
    if (retval <= 0) {
        pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
        goto cleanup;
    }
    *out_data = buf;
    *out_data_len = retval;

cleanup:
    if (retval == ENOMEM)
        free(buf);

    return retval;
}
